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:

inf-off

And this when on:

inf-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.

all-four

Commit: “options, number of ships, infinite ships, no asteroids, full screen”

Asteroids.zip