Again, starting with the easy stuff, I wanted the four directional keys to move the Player around. But in Frenzy, you can only move (as opposed to draw) along the boundaries of the game area and on lines you have already drawn. So if we look at my first iteration of the code in GameArea to handle a request to move the Player left, it's something like this:
update = () => { if (this.keyListener.isDown(this.keyListener.LEFT)) { this.moveLeft(); } }; moveLeft = () => { if (this.canMove(Direction.LEFT)) { this.setState({ playerX : this.state.playerX -1 }); } }I ended up bundling quite a lot of smarts into the Direction enumeration in order to make the logic less "iffy" and more declarative. That one Direction.LEFT key encapsulates everything that is needed to check whether a) the player is on a line that has the correct orientation (horizontal) and b) there is room on that line to go further to the left.
A line looks like this:
[Orientation.HORIZONTAL, 0, 0, 478, 0], // startX, startY, endX, endYand Direction looks like this:
export const Direction = { LEFT: { orientation: Orientation.HORIZONTAL, primaryCoord: (x, y) => y, lineToPrimaryCoord: (line) => line[2], secondaryCoord: (x, y) => x, testSecondary: (c, line) => c > Math.min(line[1], line[3]) }, ... }
My test for whether I can move in a certain direction is:
static canPlayerMoveOnExistingLine = (playerX, playerY, direction, lines) => { const candidates = lines.filter(line => { return (line[0] === direction.orientation) }); const pri = direction.primaryCoord(playerX, playerY); const primaryLines = candidates.filter(candidateLine => { return direction.lineToPrimaryCoord(candidateLine) === pri; }); if (primaryLines.length > 0) { const sec = direction.secondaryCoord(playerX, playerY); const found = primaryLines.find(line => { return direction.testSecondary(sec, line); }); return typeof found !== 'undefined'; } return false; }Declared static for ease of testing - easy and well worth doing for something like this where actually moving the player around is time-consuming and tedious. It's working well as it stands, although as we all know, naming things is hard. It's pretty easy to follow the process though. At this point I'm holding a lines array in this.state and doing filter and find operations on it as you can see above. We'll have to wait and see whether that will be fast enough. It may well be a good idea to keep a currentLine in state, as most of the time it will be unchanged from the last player movement. Next up, it's time to start drawing some new lines on the screen!
No comments:
Post a Comment
Comments welcome - spam is not. Spam will be detected, deleted and the source IP blocked.