We’re nearly done here!
What I’d like to do in this article is to review some past lists of things to do and see what may need doing before declaring this thing done. (I really don’t want to do that: I’m having too much fun.)
One thing I am sure of is that the saucer accuracy isn’t right.
function Saucer:accuracyFraction() if PerfectSaucerShots then return 1 end return self.size == 1 and 1/20 or 4/20 end
The small saucer is supposed to be accurate on every shot after the first. So that should read:
function Saucer:accuracyFraction() if PerfectSaucerShots then return 1 end return self.size == 1 and 1/20 or 20/20 end
Strictly, it should be 0/20 and 20/20, but I think it’s nice if the large saucer gets off a good one once in a while.
Commit: small saucer perfect aim.
One of the biggest problems in Scrum, in my opinion and the opinions of some of my betters, is the “Backlog”. Too often, this become a list of non-negotiable demands, without any of which the product cannot be shipped. This thinking gets in the way of incremental development and release.
We did not have that problem with this program, releasing it almost every day since we started. But we do have some lists of things in the old program that we want in ours, and some other changes we had in mind. I’ll move some of the items here, and see what we want to say about them.
From Article 46:
- Ship Spawning
- DONE: The game is supposed to start you off with three or four ships, and when your last ship is destroyed, GAME OVER. You earn a new ship every 10,000 points.
- DONE: There should be a hyperspace button that you can press when the going gets too tough. Your ship disappears, then after an interval, appears somewhere randomly, hopefully better.
- Missiles Destroy Saucer Missiles
- NOT DONE: I don’t know that the original game supported this but yesterday I could have saved myself with this feature. Maybe.
- Small Saucer
- DONE: There are two saucer sizes. The larger one is supposed to fire randomly, the smaller more accurately. Right now, when the “fire accurately” occurs, you’re a goner. There is just about no escaping accurate fire.
- Less Accurate “Accurate”
- DONE, to my satisfaction: We could invent a semi-accurate way of deciding where to fire saucer missiles. That might be fun, but mostly it is a paper exercise, though perhaps the code would be interesting as well.
- Improved Timing Logic
- DEPRIORITIZED, satisfied with it now I think: Timed behaviors are a bit ad hoc. Some use tweens, which I really like except when they fire after its too late. And they are hard to interlock. Some timing is done in line here and there, based on storing a time and comparing it to current time during the display cycle. I think there is more than one way of doing it now. We could probably build a nice centralized timing mechanism.
- Game Adjustments
- DONE: There might be some value to some control switches and sliders for the game, to set general speed, and so on.
- Portrait Mode
- NOT DONE, perhaps worth doing. The game might be better in portrait mode on the iPad, where the play area could remain square and controls could be outside the play area.
- Turn control
- NOT DONE, no better ideas really. I’m not entirely happy with the current control for rotating the ship, which instantly sets ship rotation to the position of your finger on a big disc. The original game had a fixed rate of rotation left or right, and two buttons. That might be better if we can find an easy-to-play scheme. User reports are mostly playing with two thumbs, so single controls are perhaps better.
- Pluggable Controls
- NOT DONE, worthwhile if we’re going to work on enhanced controls: The controls are already fairly isolated, and a bit more work might make it easy for people to plug in alternative control mechanisms. Not that many people would. But there could be a few built in, see Game Adjustments above.
One new idea, not directly related:
- Improve CodeaUnit
- Make a template for starting new projects with CodeaUnit. Look to see if we need any other enhancements, though none spring right to mind.
From article 43:
- Ship Explosion Sound
- DONE: When the ship encounters an asteroid, there is the asteroid’s sound, but when hit by the Saucer, nothing other than the visual effect we did yesterday. I’d like to add a ship explosion sound. My plan is to use an existing sound at a lower pitch.
- Small Saucer Targeting
- DONE: We don’t have a small saucer yet, but that’s a matter of a constant. However, the small saucer in the original game actually targeted the ship rather than firing randomly. It would be fun to implement that. I’m a bit inclined to work on that in a separate workspace.
- DONE in a few places, not very important: Various key aspects of the system are stored in the Universe as member variables, and there is a certain amount of direct access to values in other objects, such as
step. It’s usually considered better practice not to mess with other object’s variables directly. We might want to look at that, but it hasn’t been a problem so far.
- NOT DONE. Important? Buttons aren’t drawn or otherwise handled like other objects. But they are different in kind and access, so maybe that’s OK. We could take a look.
- DONE: Score is also not a drawn object, and it readily could be.
- Scoring and Ships
- DONE: In the real game, you get three or four ships (a dip switch setting), and when your last ship is destroyed, game over. We should do that. You also get a free ship every time your score rolls over 10,000. It seems only fair to do that as well.
- OPEN: I’ve been using the direct angular control wheel button for a while: the ship instantly points wherever your finger is on the circle. It’s different from the original game, where you had two buttons and a fixed rate of rotation, but it’s not bad. We might experiment with some alternatives. I’d be running it from the keyboard if that were possible, but the current Codea can’t access the keyboard much, if at all.
- Control Positioning
- OPEN: I play with the iPad in landscape position, controls at the bottom. However, if we put the pad in portrait position, we could have a 1000x1000 screen and have the controls not obscure the screen at all. Might be worth trying.
- DONE: The original game had a “hyperspace” button. When you pressed it, your ship disappeared from where it was and reappeared a bit later at some random location. You could use hyperspace as an emergency escape when you were about to be destroyed. I believe that hyperspace was always safe, in the sense that you would always return alive, but I’m not certain of that. It was certainly possible to return too near to an asteroid and be destroyed that way. We should read the code a bit and then figure out how to do it.
- Two Player Game
- NOT DONE, no user requirement: The original game could be played with two players taking turns. I don’t think we’ll do that, unless there is user demand for it.
- Screen Scaling
- NOT DONE, no user requirement: I program and play on a 12.9 inch iPad Pro. There are smaller iPads, and I think Codea may actually work on the iPhone. We could adjust things based on screen scale. Here again, I see no user demand for this feature.
What to do?
Looking at these, I can imagine some code cleanup, like making the buttons into real objects, We’ll address that with a code review right before our official “end”.
Better controls would be nice, and if I’m to do that, I would want to make adding new controls easier for other programmers, and switching between control styles done with switches.
And I do think “portrait mode” might be a good idea, as we could provide a full view of the screen, unmasked by our buttons and fingers.
Except for things forgotten entirely, I think that’s about it. Oh, speaking of forgotten, according to the 6502 code, the bonus for shooting the large saucer is 200. I think we have 250. Also it appears that the small saucer bonus is 990, but I think there is some tricky code there to make it 1000 as advertised. Let’s settle that:
function Saucer:score(anObject) if anObject:is_a(Missile) then return self.size == 1 and 250 or 1000 else return 0 end end
function Saucer:score(anObject) if anObject:is_a(Missile) then return self.size == 1 and 200 or 1000 else return 0 end end
Commit: Large saucer score 200.
It really looks to me as if we’re quite close to done. We could refine the controls. We could make a portrait mode. We could certainly tune the timing and speed and perhaps scale of things.
But it seems quite done and in my experience, it’s rather playable. Definitely worth a quarter.
There is one Very Big Thing that we could in principle do. Codea programs can export as XCode and be compiled as iOS Apps. I really don’t think I want to do that, certainly not without a pair who understands XCode and iOS.
And one Not Quite So Big Thing to spring on myself.
Beyond that, we could use a good review of the code and the project. Overall, it has gone well. What have we learned, that sort of thing.
But as for replicating 1979 Asteroids, I think we’ve just about done it.
Stay tuned, I’m sure there’s more to come.