Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

starter game 22

dave1707dave1707 Mod
edited November 26 in Code Sharing Posts: 7,155

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.

Comments

  • dave1707dave1707 Mod
    Posts: 7,155

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

  • Posts: 1,014

    @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.

  • dave1707dave1707 Mod
    edited November 26 Posts: 7,155

    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.
    
  • Posts: 148

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

  • dave1707dave1707 Mod
    edited November 26 Posts: 7,155

    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.
    
  • dave1707dave1707 Mod
    edited December 2017 Posts: 7,155

    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.

    displayMode(FULLSCREEN)
    
    function setup() 
        assert(craft, "Please include Craft as a dependency")
        parameter.number("maxSpeed",.1,1.2,.5)
        parameter.watch("Gravity.x")
        parameter.watch("fps")
        setup1()
    end
    
    function setup1()
        mx,mz=0,0
        gameOver=false
        hgx=Gravity.x
        st=os.time()
        speed,ey,ang=0,45,0
        cameraX,cameraZ=-205,-205
        count=200
        yellow=0
        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.sky = color(252, 255, 0, 255)
        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)
        end
        for z=1,count do    -- 2=green
            createSphere(math.random(-200,200),math.random(-200,200),.25,2,0,255,0,0,0)
        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()
        fps=1/DeltaTime//1
        background(0)
        if gameOver then
            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 restart",WIDTH/2,HEIGHT/2)
            text(200-count.." hits in "..en-st.." seconds",WIDTH/2,HEIGHT/2-50)
            val=string.format("%5.2f",(200-count)/(en-st))
            text(val.." hits per second",WIDTH/2,HEIGHT/2-100)
            return
        end
        en=os.time()
        update(DeltaTime)
        scene:draw()
        if speed>maxSpeed then
            speed=maxSpeed
        elseif speed<=0 then
            speed=0
        end
        ey=ey-ang
        x=speed*math.sin(math.rad(ey))
        z=speed*math.cos(math.rad(ey)) 
        cameraX=cameraX+x
        cameraZ=cameraZ+z
        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
                    gameOver=true
                    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)
                    yellow=yellow+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)
                    yellow=yellow-1
                    sound(SOUND_POWERUP, 19422)
                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
        gx=Gravity.x
        ang=ang+(gx-hgx)*4
        hgx=gx
        pushMatrix()
        translate(WIDTH/2,HEIGHT/2-100)
        rotate(ang*-30)
        sprite("Tyrian Remastered:Boss A",0,0,300)
        fill(255)
        text(count.."  ".."  "..yellow.."  "..string.format("%2.1f",speed),0,0)
        translate()
        popMatrix()
        if speed==0 then
            text("Slide your finger up/down to + or - the speed",WIDTH/2,HEIGHT-50)
        end
    end
    
    function touched(t)
        if t.state==BEGAN then
            if t.tapCount==2 and gameOver then
                setup1()
                return
            else
                ang=0
            end
        elseif t.state==MOVING then
            speed=speed+t.deltaY/80
        end
    end
    
    function createFloor(x,z)
        c1=scene:entity()
        w=c1:add(craft.rigidbody,STATIC)
        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("Blocks:Cactus Top")
        c1.material.offsetRepeat=vec4(0,0,50,50)
    end
    
    function createSphere(x,z,size,type,r,g,b,xv,zv)
        sphere1=scene:entity()
        s1=sphere1:add(craft.rigidbody,KINEMATIC)
        sphere1.position=vec3(x,1,z)
        sphere1:add(craft.shape.sphere,size)
        sphere1.model = craft.model.icosphere(size,1)
        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
    
  • dave1707dave1707 Mod
    edited November 27 Posts: 7,155

    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.
    
  • Posts: 1,014

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

  • dave1707dave1707 Mod
    Posts: 7,155

    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
    
  • dave1707dave1707 Mod
    edited November 28 Posts: 7,155

    @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.

  • Posts: 1,014
    @dave1707 - smooth, given me some ideas for later. Thanks.
Sign In or Register to comment.