Let’s see about reducing a Singleton or two, and maybe some more modern graphics.

I thought I’d come back to work this afternoon and take a look at some of the Singleton logic, since we’ve seen some of the issues that occur with it. Let’s begin with Ship, since we’ve been working with it.

It turns out that there’s only one reference to Ship:instance():

function Saucer:fireMissile()
    local ship = Ship:instance()
    if self.firstShot or not ship or math.random() > self:accuracyFraction() then 
        self.firstShot = false
        return SaucerMissile:randomFromSaucer(self) 
    else
        return SaucerMissile:aimedFromSaucer(self,ship)
    end
end

So that’s really not terrible, and there’d be no advantage that I can see to registering the ship separately to Universe and referencing it there. I’m going to let that ride.

How about Score?

There are about seven calls to Score:instance(). Four of them are in tests. We could get rid of all of them by having the Universe hold the score, and then people would ask for U.score or U:score() instead. Half of one, six a dozen of the other, though, isn’t it? I don’t want to change something like this just on principle. We’ll wait until we have evidence that we need it.

Saucer has an instance method, but it’s only used in Universe. So we could eliminate it by just giving the Saucer to Universe, but then the die function would require a separate entry.

So. No. Despite that there are issues with Singleton, I don’t see a pressing need to change our current design. If we encountered more issues, we can always change our mind. Right now any change seems gratuitous.

Moving Right Along …

OK, that quick review in hand, let’s see about making something else fancy.

I noticed some missile sprites in the Space Art asset pack.

function Missile:draw()
    pushStyle()
    pushMatrix()
    fill(255)
    stroke(255)
    ellipse(self.pos.x, self.pos.y, 6)
    popMatrix()
    popStyle()
end

We can remove the pushes and pops:

function Missile:draw()
    fill(255)
    stroke(255)
    ellipse(self.pos.x, self.pos.y, 6)
end

And let’s see about drawFancy:

red stuff

I see the red bullet thing, which is long and would require some special handling if we wanted it to align with flight, and the red explosion. Let’s try a very small version of that:

function Missile:drawFancy()
    translate(self.pos.x, self.pos.y)
    sprite(asset.builtin.Space_Art.Red_Explosion)
end

That’s a bit large, though amusing:

large-missile

I think I’ll take that down to about 1/3 size. No, half is better:

function Missile:drawFancy()
    translate(self.pos.x, self.pos.y)
    scale(0.5)
    sprite(asset.builtin.Space_Art.Red_Explosion)
end

half missile

Now I think it’d be nice if the SaucerMissiles were a different color, and I think there is a green explosion in there as well. We should be able to override drawFancy:

function SaucerMissile:drawFancy()
    translate(self.pos.x, self.pos.y)
    scale(0.5)
    sprite(asset.builtin.Space_Art.Green_Explosion)
end

That works nicely too:

red green missiles

Commit: Fancy missiles and saucer missiles.

We could get fancy and make them spin. But no, let’s march forward with simple solutions first.

I thought I saw something that would work for the Saucer, let’s look at it.

function Saucer:draw()
   pushMatrix()
   pushStyle()
   translate(self.pos.x%WIDTH, self.pos.y%HEIGHT)
   scale(4*self.size)
   stroke(255)
   strokeWidth(1)
   line(-2,1, 2,1)
   line(2,1, 5,-1)
   line(5,-1, -5,-1)
   line(-5,-1, -2,-3)
   line(-2,-3, 2,-3)
   line(2,-3, 5,-1)
   line(5,-1, 2,1)
   line(2,1, 1,3)
   line(1,3, -1,3)
   line(-1,3, -2,1)
   line(-2,1, -5,-1)
   popStyle()
   popMatrix()
end

I factored out all the line drawing before but this time let’s not do that and see which we prefer the look of. I also think that width and height checking may be redundant, but I’m not going to mess with that now.

Ah yes, UFO:

function Saucer:drawFancy()
    translate(self.pos.x%WIDTH, self.pos.y%HEIGHT)
    sprite(asset.builtin.Space_Art.UFO)
end

ufo

That’s a bit large. Let’s see about scaling that down.

function Saucer:drawFancy()
    translate(self.pos.x%WIDTH, self.pos.y%HEIGHT)
    scale(0.25)
    sprite(asset.builtin.Space_Art.UFO)
end

round ufo

That’s a bit round. Let’s scale the two axes differently.

function Saucer:drawFancy()
    translate(self.pos.x%WIDTH, self.pos.y%HEIGHT)
    scale(0.33, 0.25)
    sprite(asset.builtin.Space_Art.UFO)
end

scaled ufo

That’s nearly good. Commit: Fancy UFO.

Enough for now.

Summing Up

Well. We looked into our Singleton usage and found it to be good enough for now. Then we added fancy missiles, saucer missiles, and a fancy saucer.

It’s clear, I hope, that when the graphic artists get back with new Sprites, we will be able to plug them in easily and adjust any scaling and such. This is going very nicely so far.

We have asteroids to do, and perhaps a backdrop. Life is good!

Asteroids.zip