Hackathon winner code + iTunes link

My app Polar Wing, which won the Corona Hackathon, is now available in iTunes at http://itunes.apple.com/us/app/polar-wing/id460912561?ls=1&mt=8

My submission video, which explains the game, can be viewed here: http://www.youtube.com/user/xggsx1?feature=mhee#p/a/u/0/RaPzZK49vbQ

If you would like a copy I can hand out promo codes until I do not have them. A free version supported by inMobi ads is waiting to be reviewed. I believe from the contest rules I am supposed to post the code so what follows is the code for the game:

main.lua module:

  
display.setStatusBar( display.HiddenStatusBar )  
  
system.activate( "multitouch" )  
  
local physics = require("physics")  
physics.start()  
physics.setGravity( 0, 0)  
--physics.setDrawMode( "hybrid" )  
  
math.randomseed(os.time())  
dummy = math.random(0,255)  
  
laserSound = audio.loadSound("Laser.wav")  
btnSound = audio.loadSound("Button.wav")  
btntwoSound = audio.loadSound("Buttontwo.wav")  
expSound = audio.loadSound("Explosion.wav")  
--song = audio.loadSound( "song.mp3" )  
song = audio.loadSound( "newsong.mp3" )  
audio.play( song )  
  
local function replay()  
  
 audio.play( song )  
  
end  
  
timer.performWithDelay( 16000, replay, 0 )  
  
local menu = require("menu")  
menu.main()  
  

menu module:

  
module(..., package.seeall)  
  
local game = require("game")  
local gameNetwork = require "gameNetwork"  
  
function main()  
  
 local bgone = display.newImage( "bgone.png", true )  
 local bgtwo = display.newImage( "bgtwo.png", true )  
 local highscore  
 local ofe = 0  
 local path = system.pathForFile( "highscore.txt", system.DocumentsDirectory )   
 local file = io.open( path, "r" )  
  
 if file then  
  
 highscore = file:read( "\*number" )  
 io.close( file )  
  
 if highscore == nil then  
  
 highscore = 0  
  
 end  
  
 else  
  
 highscore = 0  
 file = io.open( path, "w+" )  
 file:write( highscore )  
 io.close( file )  
  
 end  
  
 local menugroup = display.newGroup()  
 local ofgroup = display.newGroup()  
 local titlegroup = display.newGroup()  
  
 local title = display.newImage( "title.png" )  
 title.x = 320  
 title.y = 225  
 titlegroup:insert( title )  
  
 local startbtn = display.newImage( "playbtn.png" )  
 startbtn.x = 320  
 startbtn.y = 450  
 menugroup:insert( startbtn )  
  
 local scoretext = display.newText( "High Score: " .. highscore, 320, 880, "M18\_CHALLENGES", 48 )  
 scoretext.x = 320  
 scoretext:setTextColor( 255, 255, 255 )  
 titlegroup:insert( scoretext )  
  
 local function switch()  
  
 if bgtwo ~= nil then  
  
 if bgtwo.alpha == 1 then  
  
 bgtwo.alpha = 0  
 scoretext:setTextColor( 0, 0, 0 )  
  
 else  
  
 bgtwo.alpha = 1  
 scoretext:setTextColor( 255, 255, 255 )  
  
 end  
  
 end  
  
 end  
  
 local switchtimer = timer.performWithDelay( 1000, switch, 0 )  
  
 menugroup.x = 640  
 transition.to( menugroup, { time = 600, x = 0 } )  
 titlegroup.x = 640  
 transition.to( titlegroup, { time = 600, x = 0 } )  
  
 local function tl( event )  
  
 if event.phase == "ended" then  
  
 audio.play( btnSound )  
 startbtn:removeEventListener( "touch", tl )  
  
 local function remmenu()  
  
  
 if menugroup ~= nil then  
  
 display.remove( menugroup )  
  
 end  
 --game.main()  
  
 end  
  
 transition.to( menugroup, { time = 600, x = 960, onComplete = remmenu } )  
  
 local offrame = display.newImage( "offrame.png" )  
 offrame.x = 320  
 offrame.y = 525  
 ofgroup:insert( offrame )  
  
 local yesbtn = display.newImage( "yesbtn.png" )  
 yesbtn.x = offrame.x - 75  
 yesbtn.y = offrame.y + 50  
 ofgroup:insert( yesbtn )  
  
 local nobtn = display.newImage( "nobtn.png" )  
 nobtn.x = offrame.x + 75  
 nobtn.y = offrame.y + 50  
 ofgroup:insert( nobtn )  
  
 ofgroup.x = 960  
  
 transition.to( ofgroup, { time = 600, x = 0 } )  
  
 local function gotogame()  
  
 display.remove( bgone )  
 display.remove( bgtwo )  
 timer.cancel( switchtimer )   
 display.remove( titlegroup )  
 display.remove( ofgroup )  
 game.main( ofe )  
  
 end  
  
 local function nolis( event )  
  
 if event.phase == "began" then  
  
 audio.play( btnSound )  
 nobtn:removeEventListener( "touch", nolis )  
 transition.to( titlegroup, { time = 600, x = 960, onComplete = gotogame } )  
 transition.to( ofgroup, { time = 600, x = 960 } )  
  
 end  
  
 end  
  
 nobtn:addEventListener( "touch", nolis )  
  
 local function yeslis( event )  
  
 if event.phase == "began" then  
  
 audio.play( btnSound )  
  
 yesbtn:removeEventListener( "touch", yeslis )  
 nobtn:removeEventListener( "touch", nolis )  
 transition.to( ofgroup, { time = 600, x = 960 } )  
  
 gameNetwork.init( "openfeint", "OFInfo")  
 gameNetwork.show( "leaderboards" )  
 ofe = 1  
  
 local startbtn = display.newImage( "playbtn.png" )  
 startbtn.x = 960  
 startbtn.y = 450  
 titlegroup:insert( startbtn )  
 transition.to( startbtn, { time = 600, x = 320 } )  
  
 local function playlis( event )  
  
 if event.phase == "began" then  
  
 audio.play( btnSound )  
 nobtn:removeEventListener( "touch", nolis )  
 transition.to( titlegroup, { time = 600, x = 960, onComplete = gotogame } )  
  
 end  
  
 end  
  
 startbtn:addEventListener( "touch", playlis )  
  
 end  
  
 end  
  
 yesbtn:addEventListener( "touch", yeslis )  
  
 end  
  
 end  
  
 startbtn:addEventListener( "touch", tl )  
  
end  
  

game module:

[code]

module(…, package.seeall)

local bggroup = display.newGroup()
local uigroup = display.newGroup()
local bullgroup = display.newGroup()
local shipgroup = display.newGroup()
local barriergroup = display.newGroup()
local enemygroup = display.newGroup()
local endgroup = display.newGroup()

local bg, ship, shipgraphic, scoretext, nltext, highscoretext
local bullets = {}
local enemies = {}
local barriers = {}
local exps = {}
local gamepos = 0
local gamerev = 30
local enemyspeed = 5
local barrierspeed = 3
local mr = math.random
local blean
local score = 0
local scorestore
local endgame = 0
local storex, storey, storebool
local motionx = 0
local nlscore = 500
local level = 1
local erand = 1
local highscore = 0
local randomizer
local ofg
local path = system.pathForFile( “highscore.txt”, system.DocumentsDirectory )
local file = io.open( path, “r” )

function bglis( event )

if event.phase == “began” and ship ~= nil then

audio.play( btntwoSound )
display.remove( shipgraphic )

if ship.bool == 0 then

ship.bool = 1
shipgraphic = display.newImage( “wship.png” )
shipgraphic.x = ship.x
shipgraphic.y = ship.y
shipgroup:insert( shipgraphic )
scoretext:setTextColor( 255, 255, 255 )
nltext:setTextColor( 255, 255, 255 )
highscoretext:setTextColor( 255, 255, 255 )

else

ship.bool = 0
shipgraphic = display.newImage( “bship.png” )
shipgraphic.x = ship.x
shipgraphic.y = ship.y
shipgroup:insert( shipgraphic )
scoretext:setTextColor( 0, 0, 0 )
nltext:setTextColor( 0, 0, 0 )
highscoretext:setTextColor( 0, 0, 0 )

end

end

end

local function makeship()

ship = display.newCircle( 320, 650, 25 )
ship.alpha = 0
ship.bool = 0
ship.x = 320
ship.type = “ship”
ship.shoot = 0
ship.shootmax = 10
shipgroup:insert( ship )
physics.addBody( ship, { isSensor = true } )

shipgraphic = display.newImage( “bship.png” )
shipgraphic.x = ship.x
shipgraphic.y = ship.y
shipgroup:insert( shipgraphic )

shipgroup.y = 900
transition.to( shipgroup, { time = 900, y = 0 } )

end

local function makegraphics()

bg = display.newImage( “bg.png”, true )
bggroup:insert( bg )

makeship()

bg:addEventListener( “touch”, bglis )

scoretext = display.newText( "Score: " … score, 320, 815, “M18_CHALLENGES”, 48 )
scoretext.x = 320
scoretext:setTextColor( 0, 0, 0 )
uigroup:insert( scoretext )

highscoretext = display.newText( "High Score: " … highscore, 320, 880, “M18_CHALLENGES”, 48 )
highscoretext.x = 320
highscoretext:setTextColor( 0, 0, 0 )
uigroup:insert( highscoretext )

sethighscore()

nltext = display.newText( “Next Level”, 320, 450, “M18_CHALLENGES”, 144 )
nltext.x = 320
nltext.alpha = 0
nltext:setTextColor( 0, 0, 0 )
uigroup:insert( nltext )

end

function sethighscore()

if file then

file = io.open( path, “r” )

highscore = file:read( “*number” )
io.close( file )

if highscore == nil then

highscore = 0

end

else

highscore = 0
file = io.open( path, “w+” )
file:write( highscore )
io.close( file )

end

if score > highscore then

highscore = score
highscoretext.text = "High Score: " … highscore
highscoretext.x = 320
file = io.open( path, “w+” )
file:write( highscore )
io.close( file )

if ofg == 1 then

gameNetwork.request( “setHighScore”, { leaderboardID=“leaderboardID”, score=highscore } )
gameNetwork.show( “leaderboards” )

end

else

highscoretext.text = "High Score: " … highscore

end

end

local function shoot()

if ship ~= nil then

audio.play( laserSound )

local bullet = display.newCircle( ship.x, ship.y, 5 )
bullet.x = ship.x - 10
bullet.type = “bullet”
bullets[#bullets + 1] = bullet
bullgroup:insert( bullet )
physics.addBody( bullet, { isSensor = true } )

if ship.bool == 0 then

bullet:setFillColor( 0, 0, 0 )
bullet.bool = 0

else

bullet.bool = 1

end

local bullet = display.newCircle( ship.x, ship.y, 5 )
bullet.x = ship.x + 10
bullet.type = “bullet”
bullets[#bullets + 1] = bullet
bullgroup:insert( bullet )
physics.addBody( bullet, { isSensor = true } )

if ship.bool == 0 then

bullet:setFillColor( 0, 0, 0 )
bullet.bool = 0

else

bullet.bool = 1

end

end

end

local function spawnunderlings()

local enemy
blean = mr( 0, 1 )

if blean == 0 then

enemy = display.newImage( “ben.png” )
enemy.bool = 0

else

enemy = display.newImage( “wen.png” )
enemy.bool = 1

end

enemy.type = “enemy”
enemy.x = storex + 33
enemy.y = storey
enemy.check = 0
enemy.score = 50
enemy.speed = enemyspeed
enemies[#enemies + 1] = enemy
physics.addBody( enemy, { isSensor = true } )
enemygroup:insert( enemy )

local enemy

if blean == 0 then

enemy = display.newImage( “ben.png” )
enemy.bool = 0

else

enemy = display.newImage( “wen.png” )
enemy.bool = 1

end

enemy.type = “enemy”
enemy.x = storex - 33
enemy.y = storey
enemy.check = 0
enemy.score = 50
enemy.speed = enemyspeed
enemies[#enemies + 1] = enemy
physics.addBody( enemy, { isSensor = true } )
enemygroup:insert( enemy )

end

local function makebarrier()

local barrier = display.newImage( “barrier.png” )
barrier.x = mr( 50, 590 )
barrier.y = -100
barrier.type = “barrier”
barriers[#barriers + 1] = barrier
physics.addBody( barrier, { isSensor = true } )
barriergroup:insert( barrier )

end

local function makeenemy()

if level < 3 then

erand = 1

elseif level >= 3 and level < 5 then

erand = 2

elseif level >= 5 and level < 7 then

erand = 3

elseif level >= 7 then

erand = 4

end

randomizer = mr( 1, erand )

if randomizer == 1 then

local enemy
blean = mr( 0, 1 )

if blean == 0 then

enemy = display.newImage( “ben.png” )
enemy.bool = 0

else

enemy = display.newImage( “wen.png” )
enemy.bool = 1

end

enemy.type = “enemy”
enemy.x = mr( 50, 590 )
enemy.y = -100
enemy.check = 0
enemy.score = 50
enemy.speed = enemyspeed
enemies[#enemies + 1] = enemy
physics.addBody( enemy, { isSensor = true } )
enemygroup:insert( enemy )

elseif randomizer == 2 then

local enemy
blean = mr( 0, 1 )

if blean == 0 then

enemy = display.newImage( “balt.png” )
enemy.bool = 0

else

enemy = display.newImage( “walt.png” )
enemy.bool = 1

end

enemy.type = “enemy”
enemy.x = mr( 50, 590 )
enemy.y = -100
enemy.check = 0
enemy.score = 100
enemy.speed = enemyspeed * 1.75
enemies[#enemies + 1] = enemy
physics.addBody( enemy, { isSensor = true } )
enemygroup:insert( enemy )

elseif randomizer == 3 then

makebarrier()

elseif randomizer == 4 then

local enemy
blean = mr( 0, 1 )

if blean == 0 then

enemy = display.newImage( “bigben.png” )
enemy.bool = 0

else

enemy = display.newImage( “bigwen.png” )
enemy.bool = 1

end

enemy.type = “enemy”
enemy.x = mr( 50, 590 )
enemy.y = -100
enemy.check = 0
enemy.score = 150
enemy.spawn = 1
enemy.speed = enemyspeed * 0.5
enemies[#enemies + 1] = enemy
physics.addBody( enemy, { isSensor = true } )
enemygroup:insert( enemy )

end

end

local function endthegame()

endgame = 0
sethighscore()

collectgarbage(“collect”)
print("System Memory : "…collectgarbage(“count”))

local playagain = display.newImage( “playagainbtn.png” )
playagain.x = 320
playagain.y = -100

local function addlis()

local function playagainlis( event )

if event.phase == “ended” then

audio.play( btnSound )

playagain:removeEventListener( “touch”, playagainlis )
display.remove( playagain )
playagain = nil

gamepos = 0
gamerev = 30
enemyspeed = 5
level = 1
erand = 1
motionx = 0
score = 0
nlscore = 500
scoretext:setTextColor( 0, 0, 0 )
highscoretext:setTextColor( 0, 0, 0 )
scoretext.text = "Score " … score

makeship()

return true

end

end

playagain:addEventListener( “touch”, playagainlis )

end

transition.to( playagain, { time = 600, y = 500, onComplete = addlis } )

end

function rtl( event )

if endgame == 1 then

for i, enemy in pairs( enemies ) do

if enemy ~= nil and enemy.x ~= nil and enemy.check == 0 then

enemy.check = 1
display.remove( enemy )
storex = enemy.x
storey = enemy.y
storebool = enemy.bool
makeexp()

end

end

for i, barrier in pairs ( barriers ) do

if barrier ~= nil and barrier.x ~= nil then

display.remove( barrier )
storex = barrier.x
storey = barrier.y
storebool = mr( 0, 1 )
makeexp()

end

end

endthegame()

end

if ship ~= nil and ship.x == nil then

ship = nil
display.remove( shipgraphic )
shipgraphic = nil
endgame = 1

end

if ship ~= nil and shipgraphic ~= nil then

shipgraphic.x = ship.x
shipgraphic.y = ship.y

end

if ship ~= nil and ship.x ~= nil then

ship.x = ship.x + motionx

if ship.x < 0 then

ship.x = 0

elseif ship.x > 640 then

ship.x = 640

end

end

if ship ~= nil then

ship.shoot = ship.shoot + 1

if ship.shoot == ship.shootmax then

ship.shoot = 0
shoot()

end

end

for i, barrier in pairs( barriers ) do

if barrier ~= nil and barrier.x ~= nil and barrier.y < 1060 then

barrier.y = barrier.y + barrierspeed

elseif barrier ~= nil and barrier.x ~= nil and barrier.y >= 1060 then

display.remove( barrier )
barrier = nil
barriers[i] = nil

else

barrier = nil
barriers[i] = nil

end

end

for i, enemy in pairs( enemies ) do

if enemy ~= nil and enemy.x ~= nil and enemy.y < 1060 then

enemy.y = enemy.y + enemy.speed

elseif enemy ~= nil and enemy.x ~= nil and enemy.y >= 1060 and enemy.check == 0 then

display.remove( enemy )
enemy = nil
enemies[i] = nil

else

enemy = nil
enemies[i] = nil

end

end

for i, bullet in pairs( bullets ) do

if bullet ~= nil and bullet.x ~= nil and bullet.y >= -100 then

bullet.y = bullet.y - 15

elseif bullet ~= nil and bullet.x ~= nil and bullet.y < -100 then

display.remove( bullet )
bullet = nil
bullets[i] = nil

else

bullet = nil
bullets[i] = nil

end

end

if ship ~= nil then

gamepos = gamepos + 1

if gamepos >= gamerev then

gamepos = 0
makeenemy()

end

end

for i, exp in pairs( exps ) do

if exp ~= nil and exp.alpha > 0.15 then

exp.alpha = exp.alpha - .1

elseif exp ~= nil and exp.alpha <= 0.15 then

display.remove( exp )
exp = nil
exps[i] = nil

end

end

if nltext ~= nil and nltext.alpha > 0 then

nltext.alpha = nltext.alpha - 0.025

end

end

function makeexp()

audio.play( expSound )

local exp
if storebool == 0 then

exp = display.newImage( “bexp.png” )

else

exp = display.newImage( “wexp.png” )

end

exp.x = storex
exp.y = storey
exps[#exps + 1] = exp

end

local function nextlevel()

level = level + 1

gamerev = gamerev * 0.9
enemyspeed = enemyspeed * 1.15
barrierspped = barrierspeed * 1.15

end

local function updatescore()

score = score + scorestore
scoretext.text = "Score " … score

if score >= nlscore then

nlscore = nlscore + ( nlscore * 1.25 )
nltext.alpha = 1
nextlevel()

end

end

function onCollision(event)

local doCollision = function()

if event.object1.x ~= nil and event.object2.x ~= nil and event.object1.type == “bullet” and event.object2.type == “enemy” and event.object2.y > 0 and event.object1.bool == event.object2.bool and event.phase == “began” then

if event.object2.check == 0 then

event.object2.check = 1
scorestore = event.object2.score
storex = event.object2.x
storey = event.object2.y

if event.object2.spawn == 1 then

spawnunderlings()

end

storebool = event.object2.bool
display.remove( event.object1 )
display.remove( event.object2 )
updatescore()
makeexp()

end

elseif event.object1.x ~= nil and event.object2.x ~= nil and event.object2.type == “bullet” and event.object1.type == “enemy” and event.object1.y > 0 and event.object1.bool == event.object2.bool and event.phase == “began” then

if event.object1.check == 0 then

event.object1.check = 1
scorestore = event.object1.score
storex = event.object1.x
storey = event.object1.y

if event.object1.spawn == 1 then

spawnunderlings()

end

storebool = event.object1.bool
display.remove( event.object1 )
display.remove( event.object2 )
updatescore()
makeexp()

end

elseif event.object1.x ~= nil and event.object2.x ~= nil and event.object2.type == “ship” and event.object1.type == “enemy” and event.object1.y > 0 and event.object1.bool ~= event.object2.bool and event.phase == “began” then

if event.object1.check == 0 then

event.object1.check = 1
storex = event.object1.x
storey = event.object1.y
storebool = event.object1.bool
makeexp()
storex = event.object2.x
storey = event.object2.y
storebool = event.object2.bool
makeexp()
display.remove( event.object1 )
display.remove( event.object2 )

end

elseif event.object1.x ~= nil and event.object2.x ~= nil and event.object1.type == “ship” and event.object2.type == “enemy” and event.object1.y > 0 and event.object1.bool ~= event.object2.bool and event.phase == “began” then

if event.object2.check == 0 then

event.object2.check = 1
storex = event.object1.x
storey = event.object1.y
storebool = event.object1.bool
makeexp()
storex = event.object2.x
storey = event.object2.y
storebool = event.object2.bool
makeexp()
display.remove( event.object1 )
display.remove( event.object2 )

end

elseif event.object1.x ~= nil and event.object2.x ~= nil and event.object2.type == “ship” and event.object1.type == “barrier” and event.phase == “began” then

storex = event.object2.x
storey = event.object2.y
storebool = event.object2.bool
makeexp()
display.remove( event.object2 )

elseif event.object1.x ~= nil and event.object2.x ~= nil and event.object1.type == “ship” and event.object2.type == “barrier” and event.phase == “began” then

storex = event.object1.x
storey = event.object1.y
storebool = event.object1.bool
makeexp()
display.remove( event.object1 )

end

end

local collisionTimer = timer.performWithDelay( 0, doCollision, 1 )

end

function main( ofe )

ofg = ofe
makegraphics()
Runtime:addEventListener( “enterFrame”, rtl )
Runtime:addEventListener( “collision”, onCollision )

local dirtext = display.newText( “Tilt to move”, 320, 350, “M18_CHALLENGES”, 72 )
dirtext.x = 320
dirtext:setTextColor( 0, 0, 0 )
uigroup:insert( dirtext )

local function removedt()

display.remove( dirtext )
dirtext = nil
print( “removed” )

end

transition.to( dirtext, { time = 10000, alpha = 0, onComplete = removedt } )

local dirtwotext = display.newText( “tap to change color”, 320, 450, “M18_CHALLENGES”, 72 )
dirtwotext.x = 320
dirtwotext:setTextColor( 255, 255, 255 )
uigroup:insert( dirtwotext )

local function removedtt()

display.remove( dirtwotext )
dirtwotext = nil
print( “removed” )

end

transition.to( dirtwotext, { time = 10000, alpha = 0, onComplete = removedtt } )

end

local function onAccelerate(event)

motionx = 45 * event.xGravity

end

Runtime:addEventListener( “accelerometer”, onAccelerate )

[import]uid: 10903 topic_id: 14684 reply_id: 314684[/import]

Just wanted to bump this with a blog post from InMobi about the app:

http://www.inmobi.com/inmobiblog/2011/09/26/check-out-the-grand-prize-winning-app-from-the-ansca-mobile-hackathon-polar-wing-free/ [import]uid: 10903 topic_id: 14684 reply_id: 58134[/import]