Howdy, Stranger!

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

Craft game. Ship and walls.

dave1707dave1707 Mod
edited August 11 in General Posts: 8,674

I took one on my Craft games and modified it slightly. The previous game was to destroy the green and yellow balls while avoiding the red balls. The object of this game it to fly thru each green ball to destroy it. Sounds easy, but for each green ball you destroy, a wall is create at a random position and length. So the more balls you destroy, the more walls you need to avoid. If you haven’t played my previous Craft game, hold the iPad like a steering wheel and tilt it right or left to fly the ship. You have 5 ships to try and destroy the 100 green balls. Odds are you won’t get them all because I’m sure some walls will be created over a green ball. Have fun trying. This is a stripped down version so it hasn’t been tested too well.

PS. Made some changes to sounds.
PS. Added code for low score.

Update version below

Comments

  • Posts: 762

    neat, thanks!

  • dave1707dave1707 Mod
    Posts: 8,674

    Made more changes. There is now a wall surrounding the games area so you can’t go zooming off into space and coming back in. There is a buffer area so you have a little room off the edges. Also, I changed the way the green ball move. Instead of choosing if you want them to move or not, they are stationary until you destroy 50 of them. The last 50 will move. That way you’ll have a chance at any balls inside or too close to a wall. If you have any suggestions, let me know and if it’s doable, I’ll give it a try.

    displayMode(FULLSCREEN)
    
    function setup()
        sound(SOUND_PICKUP, 11696)
        assert(craft, "Please include Craft as a dependency")
        setup1()
    end
    
    function setup1() 
        maxSpeed=.5
        count=100
        ships=4
        parameter.action("reset low score",resetLowScore)
        youWon,hitWall,youLost=false,false,false
        greenBalls=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    -- green
            xx=math.random(-10,10)/200
            zz=math.random(-10,10)/200
            if xx==0 and zz==0 then
                xx=.1
                zz=.1
            end
            createSphere(math.random(-200,200),math.random(-200,200),.5,0,255,0,xx,zz)
            greenBalls=greenBalls+1
        end
    
        mtl = craft.material(asset.builtin.Materials.Standard)
        img = readImage(asset.builtin.Surfaces.Basic_Bricks_AO)
    
        createFloor()
        wallTab={}
        outsideWall(0,210,420,2)
        outsideWall(210,0,2,420)
        outsideWall(0,-210,420,2)
        outsideWall(-210,0,2,420)
        lowScore=readProjectData("Low_Score",count)
    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 hitWall then
            hitWallFunc()
        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)
                text("Low Score  "..string.format("%d",lowScore),80,HEIGHT-60)
                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
                    setup1()
                elseif youLost then
                    setup1()
                elseif hitWall then
                    hitWall=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+150)
        text("Balls left "..greenBalls,WIDTH/2,HEIGHT/2+100)
        text("Low score   "..string.format("%d",lowScore),WIDTH/2,HEIGHT/2+50)
        text("Hold the ipad level then",WIDTH/2,HEIGHT/2)
        text("Double tap the screen to play again.",WIDTH/2,HEIGHT/2-50)
    end
    
    function hitWallFunc()
        sprite(asset.builtin.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(asset.builtin.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    -- green balls
            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)
                greenBalls=greenBalls-1
                createWall()
                if greenBalls<lowScore then
                    lowScore=greenBalls
                    saveProjectData("Low_Score",greenBalls)
                end
            end
        end
        for a,b in pairs(wallTab) do    -- walls
            if cameraX>b.x-(b.z)/2 and cameraX<b.x+(b.z)/2 and 
                    cameraZ>b.y-(b.w)/2 and cameraZ<b.y+(b.w)/2 then
                if ships==0 then
                    sound(SOUND_POWERUP, 20465)
                    youLost=true
                else
                    sound(SOUND_EXPLODE, 20445)
                    hitWall=true
                end
            end
        end
        if greenBalls==0 then
            youWon=true
        end
        if speed==0 then
            text("Tap screen to start.",WIDTH/2,HEIGHT*.75)
        end
    
        if count<50 then
            for a,b in pairs(tab) do
                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
    
    function resetLowScore()
        clearLocalData()
        lowScore=count
    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(asset.builtin.Tyrian_Remastered.Boss_A,0,0,300)
        fill(0,255,0)
        text(greenBalls,0,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(asset.builtin.Materials.Standard)
        c1.material.map = readImage(asset.builtin.Surfaces.Desert_Cliff_Color)
        c1.material.offsetRepeat=vec4(0,0,50,50)
    end
    
    function createSphere(x,z,size,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(asset.builtin.Materials.Specular)
        sphere1.material.diffuse=color(r,g,b)
        table.insert(tab,{ent=sphere1,xv=xv,zv=zv,size=size})
    end
    
    function createWall()
        local c1=scene:entity()
        local xPos=math.random(-175,175)
        local zPos=math.random(-175,175)
        local xSize=50
        local zSize=2
        if math.random(100)<51 then
            xSize=2
            zSize=50
        end
        c1.material=mtl
        c1.material.map=img
        c1.model=craft.model.cube(vec3(xSize,4,zSize))
        c1.position=vec3(xPos,2,zPos)
        table.insert(wallTab,vec4(xPos,zPos,xSize,zSize))
    end
    
    function outsideWall(xp,zp,xs,zs)
        local c2=scene:entity()
        local xPos=xp
        local zPos=zp
        local xSize=xs
        local zSize=zs
        c2.material=mtl
        c2.material.map=img
        c2.model=craft.model.cube(vec3(xSize,4,zSize))
        c2.position=vec3(xPos,2,zPos)
        table.insert(wallTab,vec4(xPos,zPos,xSize,zSize))
    end
    
  • Posts: 791
    Nice! What about a map in the corner?
  • dave1707dave1707 Mod
    Posts: 8,674

    @West I was thinking about that early on. But then if you knew where the balls were and where they were going you wouldn’t fly around searching for them. The purpose I want is more of a search and destroy feeling. I want you to weave in and out of the walls and force you down dead ends.

  • dave1707dave1707 Mod
    Posts: 8,674

    @West Maybe I can do a map that shows just the ship and the walls. That way you still won’t know where the balls are and you’ll have to search for them.

  • dave1707dave1707 Mod
    edited August 13 Posts: 8,674

    Here’s another version. I added a fuel gauge. As you fly around, you use fuel. Each green ball you hit, you get some fuel back. Each ship comes with a full tank, so when you crash into a wall, the new ship has a full tank. When you run out of fuel, you get the same response as running into a wall. The other thing I added was at @West suggestion. There is a map in the upper right corner that shows the position of the ship and the walls. If you look at the map, you might be able to avoid dead end walls. I didn’t add the balls to the map because I want you to search for them. I haven’t tried this on a larger screen iPad, so I’m not sure how it all looks. Maybe I’ll do that next.

    displayMode(FULLSCREEN)
    
    function setup()
        sound(SOUND_PICKUP, 11696)
        assert(craft, "Please include Craft as a dependency")
        setup1()
    end
    
    function setup1() 
        pct=1
        maxSpeed=.5
        count=100
        ships=4
        parameter.action("reset low score",resetLowScore)
        youWon,hitWall,youLost=false,false,false
        greenBalls=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    -- green
            xx=math.random(-10,10)/200
            zz=math.random(-10,10)/200
            if xx==0 and zz==0 then
                xx=.1
                zz=.1
            end
            createSphere(math.random(-200,200),math.random(-200,200),.5,0,255,0,xx,zz)
            greenBalls=greenBalls+1
        end
    
        mtl = craft.material(asset.builtin.Materials.Standard)
        img = readImage(asset.builtin.Surfaces.Basic_Bricks_AO)
    
        createFloor()
        wallTab={}
        outsideWall(0,210,420,2)
        outsideWall(210,0,2,420)
        outsideWall(0,-210,420,2)
        outsideWall(-210,0,2,420)
        lowScore=readProjectData("Low_Score",count)
    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 hitWall then
            hitWallFunc()
        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)
                text("Low Score  "..string.format("%d",lowScore),80,HEIGHT-60)
                updateCameraPos()        
                checkCollisions()
                checkTilt()  
                drawShip()
                drawShipLevels()
                drawFuelLevel()
                drawMap()
            end
        end
    end
    
    function drawMap()
        fill(255)
        strokeWidth(1)
        rect(WIDTH-220,HEIGHT-220,210,210)
        fill(255,0,0)
        ellipse(WIDTH-10-(cameraX+210)/2,(cameraZ+210)/2+HEIGHT-220,8)
        stroke(0)
        strokeWidth(1)
        for a,b in pairs(wallTab) do
            xPos=b.x+210
            yPos=b.y+210
            xLen=b.z/2
            if xLen==1 then
                xLen=0
            end
            yLen=b.w/2
            if yLen==1 then
                yLen=0
            end
            line(WIDTH-10-(xPos-xLen)/2,(yPos-yLen)/2+HEIGHT-220,
                    WIDTH-10-(xPos+xLen)/2,(yPos+yLen)/2+HEIGHT-220)
        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
                    setup1()
                elseif youLost then
                    setup1()
                elseif hitWall then
                    hitWall=false
                    hgx=Gravity.x
                    cameraX,cameraZ=-205,-205
                    ships=ships-1
                    speed,ey,ang=0,45,0
                    pct=1
                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+150)
        text("Balls left "..greenBalls,WIDTH/2,HEIGHT/2+100)
        text("Low score   "..string.format("%d",lowScore),WIDTH/2,HEIGHT/2+50)
        text("Hold the ipad level then",WIDTH/2,HEIGHT/2)
        text("Double tap the screen to play again.",WIDTH/2,HEIGHT/2-50)
    end
    
    function hitWallFunc()
        sprite(asset.builtin.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(asset.builtin.Tyrian_Remastered.Boss_A,z*50,HEIGHT-30,40)
        end
    end
    
    function drawFuelLevel()
        if speed>0 then
            pct=pct-.0002
        end
        fill(255)
        rect(20,HEIGHT/2+100,20,200)
        if pct<.1 then
            fill(255, 0, 0)
        elseif pct<.25 then
            fill(255, 255, 0)
        else
            fill(0,255,0)
        end
        rect(20,HEIGHT/2+100,20,200*pct)
        fill(0, 0, 255)
        text(string.format("%3.1f",pct*100),30,HEIGHT/2+90)
        if pct<=0 then
            hitWall=true
        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    -- green balls
            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)
                greenBalls=greenBalls-1
                createWall()
                if pct<1 then
                    pct=pct+.02
                end
                if greenBalls<lowScore then
                    lowScore=greenBalls
                    saveProjectData("Low_Score",greenBalls)
                end
            end
        end
        for a,b in pairs(wallTab) do    -- walls
            if cameraX>b.x-(b.z)/2 and cameraX<b.x+(b.z)/2 and 
                    cameraZ>b.y-(b.w)/2 and cameraZ<b.y+(b.w)/2 then
                if ships==0 then
                    sound(SOUND_POWERUP, 20465)
                    youLost=true
                else
                    sound(SOUND_EXPLODE, 20445)
                    hitWall=true
                end
            end
        end
        if greenBalls==0 then
            youWon=true
        end
        if speed==0 then
            text("Tap screen to start.",WIDTH/2,HEIGHT*.75)
        end
    
        if count<50 then
            for a,b in pairs(tab) do
                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
    
    function resetLowScore()
        clearLocalData()
        lowScore=count
    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(asset.builtin.Tyrian_Remastered.Boss_A,0,0,300)
        fill(0,255,0)
        text(greenBalls,0,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(asset.builtin.Materials.Standard)
        c1.material.map = readImage(asset.builtin.Surfaces.Desert_Cliff_Color)
        c1.material.offsetRepeat=vec4(0,0,50,50)
    end
    
    function createSphere(x,z,size,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(asset.builtin.Materials.Specular)
        sphere1.material.diffuse=color(r,g,b)
        table.insert(tab,{ent=sphere1,xv=xv,zv=zv,size=size})
    end
    
    function createWall()
        local c1=scene:entity()
        local xPos=math.random(-175,175)
        local zPos=math.random(-175,175)
        local xSize=50
        local zSize=2
        if math.random(100)<51 then
            xSize=2
            zSize=50
        end
        c1.material=mtl
        c1.material.map=img
        c1.model=craft.model.cube(vec3(xSize,4,zSize))
        c1.position=vec3(xPos,2,zPos)
        table.insert(wallTab,vec4(xPos,zPos,xSize,zSize))
    end
    
    function outsideWall(xp,zp,xs,zs)
        local c2=scene:entity()
        local xPos=xp
        local zPos=zp
        local xSize=xs
        local zSize=zs
        c2.material=mtl
        c2.material.map=img
        c2.model=craft.model.cube(vec3(xSize,4,zSize))
        c2.position=vec3(xPos,2,zPos)
        table.insert(wallTab,vec4(xPos,zPos,xSize,zSize))
    end
    
  • edited August 13 Posts: 762

    i can nearly do it at about 1/4 speed. :)

  • Posts: 1,867
    @dave1707 - moved on with this game, the walls, fuel display and map add a neat touch to it.
  • dave1707dave1707 Mod
    Posts: 8,674

    Made more changes. I added a Menu screen that allows you to turn off the Fuel Level and Wall Map. You can also choose your Speed from slow to fast or reset the Low Score. I like playing without the Fuel Level or Wall Map just so I can zip around the screen chasing the green balls and avoiding the walls. The code got too big to post as text, so I had to zip it.

    game9.zip 3.8K
  • dave1707dave1707 Mod
    edited August 16 Posts: 8,674

    Made more changes. In this version, I added an option to let you fly. When selected, you can fly above the game area to get a birds eye view or avoid the walls. To turn flying on, tap the button in the menu. This also comes with limits. To hit a green ball, you have to fly at an altitude of .5 to 1.5. To avoid walls, fly above 4. If you’re below .5, you’ll hear a low altitude warning. If you fly at 0, you crash into the ground. Your altitude shows on the ship above the green ball count. I keep telling myself that I’m not going to add more, but then I think of something else that sounds fun.

    PS. Flying is controlled by the forward, backward tilt of the iPad. Before you start the actual game, hold the iPad at a comfortable position. Once the game starts, tilt the iPad towards you to go up, away from you to go down. While playing, you can tap the screen to reset the forward/backward origin position.

    game9b.zip 4.2K
  • dave1707dave1707 Mod
    edited August 18 Posts: 8,674

    More changes. When you do the fly option, the balls and walls are at different heights.

    game9d.zip 4.3K
  • dave1707dave1707 Mod
    Posts: 8,674

    Another change. I modified the camera a little. Now when you’re flying over walls and you dive down after a green ball, I tilt the camera down so it feels like you’re diving down instead of floating down. When you go up, I tilt the camera up, but it’s not the same feeling as going down. I keep thinking I’m done adding more options, but then I think of something else. I also fixed the map. It wasn’t drawing the wall positions correct after a previous change.

    game9e.zip 4.3K
  • dave1707dave1707 Mod
    edited October 7 Posts: 8,674

    Here’s another update. I added the ability to fly instead of staying close to the ground. In the menu, select “allow flying”. Before pressing “play”, hold the iPad level and tilt the iPad a little away from you. Tilting the iPad left or right turns the ship left or right. Tilting the iPad away from you causes the ship to go down. Tilting towards you causes the ship to go up. Max height is 40. Just like in the original game, the object is to fly through the green balls to remove them. There are 100 balls at various stationary positions and height. Once the ball count is less than 50, the remaining balls will start to move. Each time you run through a ball, 10 buildings of random size will appear at random positions. If you run into them, you explode. The more balls you hit, the more buildings you have to avoid. Anytime during play, you can tap the screen 1 time to reset the forward/backward tilt.

    Tap the zip file below to send it to the Files app into the Download folder. Tap the zip file there to create a Codea file. Tap the Codea file to run the code in Codea.

    PS. Corrected an error when you lose the game and try to play again. It’s was crashing when restarted.

Sign In or Register to comment.