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