Skip to content

Instantly share code, notes, and snippets.

@dermotbalson
Created January 20, 2014 08:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dermotbalson/8516584 to your computer and use it in GitHub Desktop.
Save dermotbalson/8516584 to your computer and use it in GitHub Desktop.
Asteroid cannon
--# Main
--Asteroid run
INTRO,PLAY,END=1,2,3
function setup()
displayMode(FULLSCREEN)
LoadImages() --read in all the images we will use
CreateSights() --create gunsight image to save us drawing it each time
Settings() --set up games
state=INTRO
end
function Settings()
--min/max positions of asteroids, and position of ship, on screen
minX,maxX,minY,maxY,shipX,shipY=-WIDTH/2,WIDTH/2,-HEIGHT/2,HEIGHT/2,0,0
--all asteroids start from the same distance away
--you can set how many are created per second
--alreadyCreated keeps track of how many have been created so far
startDist,asteroidRate,timer,alreadyCreated,A=100,20,0,0,{}
laserRange=25 --how far the laser can shoot
--HitRadius calculates how far from the centre of the screen an asteroid can be before it misses the ship
local s=startDist^.5
HitRadius=vec2(WIDTH/2/s,HEIGHT/2/s)
warning={s=1} --a tween is used to make dangerous asteroids pulse by changing the ellipse size
wt=tween(2,warning,{s=6},{easing=tween.easing.linear,loop = tween.loop.pingpong } )
end
function LoadImages()
Rocks={} for i=1,9 do
Rocks[#Rocks+1]=readImage("Tyrian Remastered:Space Ice "..i) end
for i=1,7 do Rocks[#Rocks+1]=readImage("Tyrian Remastered:Rock "..i) end
end
--start game when screen is touched
function touched(t)
if t.state==ENDED then Start() end
end
--start playing
function Start() --triggered by touch on screen
state=PLAY
timer=0
Shields=100 --health!
end
function AddAsteroid()
local a={}
--a.x, a.y = position on screen, a.rs=rotation direction
a.x,a.y,a.rs=math.random(minX,maxX),math.random(minY,maxY),math.random(-1,1)
--a.s=size, a.d=start distance, a.img=sprite
a.s,a.d,a.r,a.img=math.random(1,3),startDist,0,Rocks[math.random(#Rocks)]
--if it will hit ship, pre-calculate damage
if math.abs(a.x)<HitRadius.x and math.abs(a.y)<HitRadius.y then
a.h=5*a.s
end
table.insert(A,a) --add to table
end
function draw()
background(0)
if state==INTRO then DrawIntro()
elseif state==PLAY then DrawPlay()
elseif state==END then DrawEnd() end
end
function DrawPlay()
timer=timer+DeltaTime
local a=timer*asteroidRate --calculate how many asteroids should have been created so far
for i=1,a-alreadyCreated do AddAsteroid() end --add any that haven't been created
alreadyCreated=math.floor(a)
--set aim using Gravity to measure iPad tilt
--you can make the aim more or less sensitive by varying sensitivity
sensitivity=3
aim=vec2((Gravity.x*sensitivity+1)*WIDTH/2,(Gravity.y*sensitivity+1)*HEIGHT/2)
sprite(sights,aim.x,aim.y) --draw aiming circle
--draw asteroids and check if exploded
local n=0
fill(255,255,0,50) --warning colour
for i,a in pairs(A) do
n,a.d=n+1,a.d-.1 --adjust distance from ship
if a.d==0 then table.remove(A,i) --delete when they pass the ship
else
a.r=a.r+a.rs --rotate
--this formula is a rather arbitrary way of figuring out how asteroids spread out as they approach
local v=(startDist/a.d)^.5
local xx,yy=WIDTH/2+a.x*v,HEIGHT/2+a.y*v
--remove asteroids that go off the screen
if xx<0 or xx>WIDTH or yy<0 or yy>HEIGHT then
table.remove(A,i)
else
--check if it is very close and hit the ship
if a.d<1 and a.h then
Shields=Shields-a.h
sound(SOUND_EXPLODE, 39100+math.random(0,100))
table.remove(A,i)
if Shields<0 then state=END end
else
local w=a.img.width*a.s/a.d --visible size of asteroid
--check if we have hit it with the laser
if a.d<laserRange and vec2(xx,yy):dist(aim)<w then
sound(SOUND_SHOOT, 39124)
table.remove(A,i)
else --draw asteroid
if a.h and a.d<laserRange then ellipse(xx,yy,w*warning.s) end
if w>3 then
pushMatrix()
translate(xx,yy)
rotate(a.r)
sprite(a.img,0,0,w)
popMatrix()
else sprite(a.img,xx,yy,w) end
end
end
end
end
end
pushStyle()
fill(255,255,0)
textMode(CORNER)
text("Shields "..Shields,50,HEIGHT-70)
text("Time "..math.floor(timer),50,HEIGHT-90)
popStyle()
end
--note DrawTextScreen is used to give consistent look to text screens
--this function only provides the text needed for the intro
function DrawIntro()
local t="You are passing through a band of asteroids, and the automatic cannon has broken down.\n\n"
t=t.."You have to destroy all asteroids that may hit the ship, by tilting the iPad until the gunsights are over an asteroid. The gun will shoot automatically if the asteroid is in range.\n\n"
t=t.."Watch out for the asteroids which pulse in yellow. The ship has tagged these as dangerous.\n\n"
t=t.."Good luck, and try to survive as long as possible before your shields are destroyed.\n\n"
DrawTextScreen(t)
end
function DrawEnd()
local t="You survived for "..math.floor(timer).." seconds."
DrawTextScreen(t)
end
function DrawTextScreen(txt)
pushStyle()
--title
font("MarkerFelt-Wide")
fontSize(48)
fill(255)
text("Asteroid Run",WIDTH/2,HEIGHT*0.8)
font("ArialMT")
textWrapWidth(500)
fontSize(18)
text(txt,WIDTH/2,HEIGHT/2)
fill(255,255,0)
text("Press the screen to start playing",WIDTH/2,HEIGHT/4)
popStyle()
end
--create gunsight image
function CreateSights()
sights=image(120,120)
setContext(sights)
pushStyle()
stroke(255,255,0,200)
strokeWidth(1)
fill(0,0,0,0)
ellipse(60,60,100)
ellipse(60,60,50)
ellipse(60,60,10)
line(0,60,120,60)
line(60,0,60,120)
popStyle()
setContext()
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment