starter game 22

I haven’t done this for awhile, but here’s another starter game for anyone who wants to take it and add whatever bells and whistles they want to it. This uses simple Craft graphics and draws 200 red balls and 200 green balls. The object is to run thru the green balls, but avoid the red balls. To move, place your finger on the screen. Slide up to go forward, down to reverse, left to go left and right to go right. The more you move up, the faster you go. There’s a count to show how many green balls remain. I didn’t add any checking, so a red and green ball can occupy the same spot. If you hit a red ball, game over. Double tap to restart. It takes a second or so to start the game. If you run thru all the green balls, nothing happens. You can add that if you want.

Code removed. See updated code below.

I added some counts plus a ship and I tilt the ship when you turn.

@dave1707 - neat, interesting and engrossing. Also in so few lines !!! Impressed. No time to play at moment but can see a few variants on this.

Here’s an updated version. The flying direction is now controlled by tilting the iPad. I tried to control the speed by tilt also, but I didn’t like the way it worked so there’s a slider to limit the max speed. To control the speed, slide your finger up or down but most of the time you’ll just keep it at the max speed you set. Before starting or restarting the game, make sure the iPad is level side to side or the ships tilt will be off. You might have trouble controlling the steering, but after awhile it will be easy. If you want, you can change the max speed while the game is in progress, just hit the > icon to show the parameter panel.

Code removed. See updated code below.

Very cool and hypnotic game :slight_smile:
I only stopped playing when my son wrestled the iPad from me

Here’s another updated version. There’s a problem where the ship and the tilt of the iPad seem to get out of sync when doing a lot of fast turns. To correct this while the game is still in progress, with the iPad level, just tap the screen and the ships tilt will level out. Other changes are the green balls are half the size and the red balls are twice the size. Also, when you hit a green ball, I create a yellow ball that you also have to avoid. So as the game progresses, the green balls get harder to find and you have more larger balls to avoid. There isn’t any end game because I haven’t added any code so that the red and yellow balls don’t occupy the same space as a green ball. You might see a green ball sticking out of the side of a red or yellow ball. You could try skimming the green ball without hitting the larger ones, but odds are you’ll lose.

Code removed. See updated code below.

@dave1707 - that’s more like it. Much more manouverable and a decent target. Yellow spheres difficult to catch. Good demo game this!!!

Here’s another update. I added code to pause the game. Triple tap to pause and unpause.

displayMode(FULLSCREEN)

function setup() 
    assert(craft, "Please include Craft as a dependency")
    
    maxSpeed=.5
    count=100
    ships=4
    youWon,hitRed,youLost=false,false,false
    redBalls,greenBalls,yellowBalls=0,0,0
    hgx=Gravity.x
    speed,ey,ang=0,45,0
    cameraX,cameraZ=-205,-205
    
    scene = craft.scene()
    scene.camera.position = vec3(cameraX,0,cameraZ)
    scene.camera.eulerAngles=vec3(ex,ey,ez)
    scene.sun.rotation = quat.eulerAngles(45,0,45)
    scene.ambientColor = color(90,90,90)
    
    skyMaterial = scene.sky.material
    skyMaterial.horizon = color(0, 203, 255, 255)    
    
    tab={}
    for z=1,count do    -- 1=red
        createSphere(math.random(-200,200),math.random(-200,200),2,1,255,0,0,0,0)
        redBalls=redBalls+1
    end
    for z=1,count do    -- 2=green
        createSphere(math.random(-200,200),math.random(-200,200),.5,2,0,255,0,0,0)
        greenBalls=greenBalls+1
    end
    
    createFloor()
end

function update(dt)
    scene:update(dt)
    scene.camera.position = vec3(cameraX,1,cameraZ)
    scene.camera.eulerAngles=vec3(0,ey,0)
end

function draw()
    background(0)
    if youLost then
        youLostFunc()
    elseif hitRed then
        hitRedFunc()
    elseif youWon then
        youWonFunc()
    else  
        update(DeltaTime)
        scene:draw()  
        if paused then  
            text("PAUSED",WIDTH/2,HEIGHT*.7)
            text("Triple tap to restart.",WIDTH/2,HEIGHT*.7-20)
        else
            text("Triple tap to pause.",WIDTH/2,HEIGHT-10)
            updateCameraPos()        
            checkCollisions()
            checkTilt()  
            drawShip()
            drawShipLevels()
        end
    end
end

function touched(t)
    if t.state==BEGAN then
        if t.tapCount==3 then
            ang=0
            paused=not paused
        end
        if t.tapCount==2 then
            if youWon then
                setup()
            elseif youLost then
                setup()
            elseif hitRed then
                hitRed=false
                hgx=Gravity.x
                cameraX,cameraZ=-205,-205
                ships=ships-1
                speed,ey,ang=0,45,0
            end
        else
            ang=0
            if speed==0 then
                speed=maxSpeed
            end
        end
    end
end

function youLostFunc()
    fill(255,0,0)
    text("YOU LOST!",WIDTH/2,HEIGHT/2+100)
    text("Hold the ipad level then",WIDTH/2,HEIGHT/2+50)
    text("Double tap the screen to play again.",WIDTH/2,HEIGHT/2)
end

function hitRedFunc()
    sprite("Tyrian Remastered:Explosion Huge",WIDTH/2,HEIGHT/2,500,500)
    fill(255,0,0)
    text("Hold the ipad level then",WIDTH/2,HEIGHT/2+50)
    text("Double tap the screen to continue.",WIDTH/2,HEIGHT/2)
end

function youWonFunc()
    fill(255,0,0)
    text("YOU WON!",WIDTH/2,HEIGHT/2+100)
    text("Hold the ipad level then",WIDTH/2,HEIGHT/2+50)
    text("Double tap the screen to play again.",WIDTH/2,HEIGHT/2)
end

function drawShipLevels()
    for z=1,ships do
        sprite("Tyrian Remastered:Boss A",z*50,HEIGHT-30,40)
    end
end

function updateCameraPos()
    ey=ey-ang
    x=speed*math.sin(math.rad(ey))
    z=speed*math.cos(math.rad(ey)) 
    cameraX=cameraX+x
    cameraZ=cameraZ+z
end

function checkCollisions()
    for a,b in pairs(tab) do
        if b.type==1 then
            if cameraX>=b.ent.position.x-b.size and 
                    cameraX<=b.ent.position.x+b.size and 
                    cameraZ>=b.ent.position.z-b.size and
                    cameraZ<=b.ent.position.z+b.size then
                if ships==0 then
                    youLost=true
                else
                    hitRed=true
                end                
                sound(SOUND_EXPLODE, 27037)
            end
        end
        if b.type==2 then
            if cameraX>b.ent.position.x-b.size and 
                    cameraX<b.ent.position.x+b.size and
                    cameraZ>b.ent.position.z-b.size and 
                    cameraZ<b.ent.position.z+b.size then
                b.ent:destroy()
                table.remove(tab,a)
                count=count-1
                sound(SOUND_HIT, 19423)
                createSphere(math.random(-200,200),math.random(-200,200),.5,3,255,255,0,.2,.2)
                yellowBalls=yellowBalls+1
                greenBalls=greenBalls-1
            end
        end
        if b.type==3 then
            if cameraX>=b.ent.position.x-b.size and 
                    cameraX<=b.ent.position.x+b.size and 
                    cameraZ>=b.ent.position.z-b.size and
                    cameraZ<=b.ent.position.z+b.size then
                b.ent:destroy()
                table.remove(tab,a)
                yellowBalls=yellowBalls-1
                sound(SOUND_POWERUP, 19422)
                yellowHit=true
            else
                xx=b.ent.position.x
                zz=b.ent.position.z
                xx=xx+b.xv
                zz=zz+b.zv
                if xx<-200 or xx>200 then
                    b.xv=-b.xv
                end
                if zz<-200 or zz>200 then
                    b.zv=-b.zv
                end
                b.ent.position=vec3(xx,1,zz)
            end
        end
    end
    if yellowHit then   -- remove a red ball
        yellowHit=false
        for z=#tab,1,-1 do
            if tab[z].type==1 then
                tab[z].ent:destroy()
                table.remove(tab,z)
                redBalls=redBalls-1
                break
            end
        end
    end
    if redBalls+greenBalls+yellowBalls==0 then
        youWon=true
    end
    if speed==0 then
        text("Tap screen to start.",WIDTH/2,HEIGHT*.75)
    end
end

function checkTilt()
    gx=Gravity.x
    ang=ang+(gx-hgx)*4
    hgx=gx
    if gx>-.001 and gx<.001 then
        ang=0
    end
end

function drawShip()
    pushMatrix()
    translate(WIDTH/2,HEIGHT/2-100)
    rotate(ang*-30)
    sprite("Tyrian Remastered:Boss A",0,0,300)
    fill(255,0,0)
    text(redBalls,-40,0)
    fill(0,255,0)
    text(greenBalls,0,0)
    fill(255,255,0)
    text(yellowBalls,40,0)    
    translate()
    popMatrix()
end

function createFloor(x,z)
    c1=scene:entity()
    c1.model = craft.model.cube(vec3(400,1,400))
    c1.position=vec3(x,-.5,z)
    c1.material = craft.material("Materials:Standard")
    c1.material.map = readImage("Surfaces:Desert Cliff Color")
    c1.material.offsetRepeat=vec4(0,0,50,50)
end

function createSphere(x,z,size,type,r,g,b,xv,zv)
    sphere1=scene:entity()
    sphere1.model = craft.model.icosphere(size,1)
    sphere1.position=vec3(x,1,z)
    sphere1.material = craft.material("Materials:Specular")
    sphere1.material.diffuse=color(r,g,b)
    table.insert(tab,{ent=sphere1,xv=xv,zv=zv,size=size,type=type})
end

Here’s an updated version. Things added. Parameter.watch for Gravity.x and FPS. It looks like Gravity.x gets out of sync with the iPad after a lot of turns and twists which affects the tilt of the ship. To correct the ship tilt while the game is running, you can tap the screen when the iPad is level or you can swipe down to to make the speed 0. Then tap the > icon to show the parameters to see the value of Gravity.x when the iPad is level. Other things changed are yellow spheres are created when a green sphere is destroyed. Instead of having to avoid the yellow spheres, you need to hit them like the green spheres to destroy them. But unlike the green spheres, the yellow spheres are in constant motion which makes them harder to hit. On the back of the ship is a count of green spheres, yellow spheres, and ship speed. There is still no end game, but I think it will take a long time to hit all the green and yellow spheres.

Removed the code. See updated code below.

I used this code as an example in another discussion and it got me playing it again. I decided to modify the game a little, so here it is. You now have 5 ships before the game ends. You start with 100 red and green balls. You try to avoid the red balls while hitting the stationary green balls. Each time you hit a green ball, a yellow moving ball is created. Each time you hit a yellow ball, a red ball disappears. There is a count on the ship that shows the number of red, green, and yellow balls remaining. You win when all of the balls are gone.

Removed the code. See updated code below.

@Simeon I ran into a minor glitch with my above program. This happens with both ver 118 and 120 on my iPad Air and iPad Pro. When I start Codea and run the above program, the first time I run into a green ball, there’s a slight delay before the sound plays. You’ll see the delay because the green ball will remain on the screen longer then it should. That doesn’t happen with the other balls after the first one is hit or if I close the program and restart it. It always happens on the first ball after starting Codea. Does the sound function need time to initialize stuff the first time sound is called after Codea is started.

PS. I can eliminate the glitch by putting an empty sound() call in setup() so it does whatever it needs to do there.

@dave1707 - smooth, given me some ideas for later. Thanks.