Asteroids 53
Let’s put in some options.
When I’m testing the game, I often patch in changes to make the testing easier. Last night I patched the asteroids to be non-destructive, so I could watch the saucer shoot at me. I even patched in a slow-down to make the game run slower. And I’d like to have a mode where the player gets unlimited ships.
Codea has a feature, parameters, that lets you set up simple action buttons and switches on the side panel. I’m thinking I’ll put them there. There is one little issue to deal with. You may have noticed a few light widgets in the lower left of the screen. Those are Codea buttons to stop the program, restart it, take a picture or movie, or the like. You’d like to play with those turned off, so you don’t accidentally press them. But if the program starts up with them off, you can’t see the tests running or set other switches. So I guess I’ll have to make a button that you press when you’re done pressing buttons. We’ll see.
Parameters are all kind of like this one:
parameter.boolean("InfiniteShips", false)
This will display a toggle switch like this:
And this when on:
We now have a global named InfiniteShips that we can test somewhere useful, like in Score:
function Score:spawnShip()
if self.shipCount <= 0 then
self:stopGame()
return false
else
self.shipCount = self.shipCount - 1
Ship()
return true
end
end
What if we did this …
function Score:spawnShip()
if InfiniteShips then self.shipCount = self.shipCount + 1 end
if self.shipCount <= 0 then
self:stopGame()
return false
else
self.shipCount = self.shipCount - 1
Ship()
return true
end
end
Well, what would happen is that every time we go to spawn a ship, we increase the ship count, so that when it decreases, it stays the same. No more Game Over.
For people who want a bit of a challenge, how about setting a different number of ships? Score initializes like this:
function Score:init(shipCount)
self.shipCount = shipCount or 1
self.gameIsOver = false
self.totalScore = 0
self.nextFreeShip = U.freeShipPoints
Instance = self
U:addIndestructible(self)
end
The init is called from Universe:
function Universe:startGame(currentTime)
self.currentTime = currentTime
self.saucerTime = currentTime
self.attractMode = false
self.objects = {}
self.indestructibles = {}
self.waveSize = nil
self.lastBeatTime = self.currentTime
createButtons()
Score(4):spawnShip() -- <---
self:newWave()
end
What if there was a global variable NumberOfShips:
parameter.integer("NumberOfShips", 2,5,4)
And in Universe:
function Universe:startGame(currentTime)
self.currentTime = currentTime
self.saucerTime = currentTime
self.attractMode = false
self.objects = {}
self.indestructibles = {}
self.waveSize = nil
self.lastBeatTime = self.currentTime
createButtons()
Score(NumberOfShips):spawnShip()
self:newWave()
end
Then we can set the number of ships between 2 and 5. Could make it some other range, of course.
Finally, what if we wanted asteroids to be harmless, so that they can’t hurt us, or to turn them off entirely so that we can just play with and observe the saucer? Let’s do both. We’ll call it NoAsteroids, but we can’t readily make it be that there aren’t any, because there’s all that spawn logic about what happens when you’re down to the last one. Instead, let’s make them harmless where they are, and invisible.
parameter.boolean("NoAsteroids", false)
function Asteroid:killDist()
if NoAsteroids then return -1000 end
local s = self.scale
if s == 16 then return 64 elseif s == 8 then return 32 else return 16 end
end
function Asteroid:draw()
if NoAsteroids then return end
pushMatrix()
pushStyle()
stroke(255)
...
Nice. Let’s do the one that turns off the screen widgets. We’ll call it FullScreen, yet another boolean:
parameter.boolean("FullScreen", false)
Now the question is how to implement it. Right now the full screen setting is commented out, I believe, in Universe:
function Universe:draw(currentTime)
self:applyAdditions()
self:checkBeat()
self:checkSaucer()
self:checkNewWave()
self:adjustTimeValues(currentTime)
--displayMode(FULLSCREEN_NO_BUTTONS)
background(40, 40, 50)
checkButtons()
drawButtons()
self:drawEverything()
self:moveEverything()
self:findCollisions()
end
What if we do this:
function Universe:draw(currentTime)
self:applyAdditions()
self:checkBeat()
self:checkSaucer()
self:checkNewWave()
self:adjustTimeValues(currentTime)
if FullScreen then
displayMode(FULLSCREEN_NO_BUTTONS)
end
background(40, 40, 50)
checkButtons()
drawButtons()
self:drawEverything()
self:moveEverything()
self:findCollisions()
end
This makes it happen a bit frequently, but it seems to be harmless.
So there we are, four new options, pip pop pip bam boom.
Commit: “options, number of ships, infinite ships, no asteroids, full screen”