One Step Back, Two Steps Forward

Frustration with my lack of artistic ability and a weird bug forced me to rethink the direction I was heading and ultimately change course.

Finch Masters
6 min readFeb 26, 2017

Where I Left Off

The last time I worked on this game, I was having an issue with the animations used with the player’s sprite. It seemed that no matter what I did, I could not get the sprites to line up appropriately and there always seemed to be a “jump” of a about a pixel in one of the frames of the animation.

I spent an inordinate amount of time attempting to find a solution to this problem to no avail. I counted the pixels in each frame repeatedly, I tried moving each frame programmatically, I tried switching to using a Texture Atlas instead of a sprite sheet, and nothing seemed to work.

So what did I do? I said screw it. No more sprites. The game mechanics don’t care what the character looks like and neither should I. So I went back to my little white block for a character and began making the game work as I wanted it to.

What about the other problems?

The other major problems all basically boiled down to incorrect handling of collisions with jumping. My original method for creating the walls and floors of the game world was to create multiple small blocks and put them next to or on top of each other.

Try as I might, I could not figure out why the player could jump straight up just fine next to a stack of world blocks but when pressing the left or right button at the same time, the player would seem to bump into the bottom of a world block that should be flush with the player’s x position. I’m going to assume it was some weird fractional pixel math error.

Nevertheless, I decided that if I can’t fix it then I should work around it. So if you’ve got a ton of physics bodies that aren’t colliding right, what’s the easiest way to get things working? If you said, “reduce the number of physics bodies,” you’d be right! I converted the level building logic into this:

Instead of making 100 blocks for the floor, ceiling, and each side, I’m now only making 4 blocks and scaling each one to take up the full width or height of the area. What do you know, no more weird jumping collision problems!

The Other Jump Problem

Once the collisions were working better, I turned my attention to the “sticky” jumping issue.

As a refresher, the jump logic was checking whether or not the player’s y position was less than or equal to the block’s y position. This had the unintended side effect of allowing the player to jump up next to a ledge, touch it, and then be able to jump again.

What I was attempting to do was solved by finding the touching object on the physics body of the player’s sprite. The touching object has four parameters that I could check (up, down, left, and right), but in this case I wanted to check if the player.body.touching.down was true and if so, then allow the jump. The this.jumping boolean that I was maintaining could be completely remove and all the jump logic was reduced to this:

Okay so you fixed the bugs, but what kind of new stuff did you add?

Good question. The new additions to this version include general cleanup and organization, fullscreen (well, full browser window) support, shooting, and a new “knockdown” block that will fall after being shot at.

Organization++

In order to efficiently organize this project as it grows, I’ve been gradually adding functionality and then pulling it out into its own function or set of functions as needed.

One of the first things I did is move player movement and jumping out of the update method into a handlePlayerMovement function that is called in update.

I also moved the block creation out of the create function and into a buildLevel function that will eventually be updated to read from a file or some other store for the levels or rooms or however I decide to expand the game.

One of the most useful changes I made was to switch out from using a Map to track the blocks and instead using a group that Phaser provides:

The most immediate advantage that I was able to make use of was the ability to shrink the collision handling loop that I had constructed into just one line:

As you can see, there’s now one line for handling player/block collisions. The collide function accepts both individual sprites and group of sprites to run multiple collision tests. The third parameter used in the next two collision checks is an optional callback to run when a collision occurs.

Since the bulletHitBlock is a little interesting, I’ll explain it:

Here we can see that upon collision with the block, I’m calling the bullet sprite’s kill method to remove it from the group it is in and free up memory. I’m also checking the key of the block sprite (like I did in Breakout) to see if it is the new “knockout” block that I’ve created. If so, I want to decrease the health of the block sprite. If the health hits 0, I want the block the fall so I give it a gravity value and turn off it’s ability to be immovable.

Speaking of Bullets

Adding the ability to shoot was not terribly complicated. The first thing I did was start tracking the button that I wanted to use to initiate the shot and then I checked if it was down in the update method.

From there, I had to implement the pewpew method to create and fire the bullet. I also added some rate limiting in there to slow down how fast the player can fire:

The createBullet method introduced me to the velocityFromRotation method in the game.physics.arcade object. This method allowed me to provide a rotation (in radians), a speed, and velocity object to have the speed applied to the velocity in the direction given by the rotation. The rotation that I provided came from the game.physics.arcade.angleToPointer method which, as you can guess, gave me to the angle (in radians) to where the mouse pointer was. I sent the player’s sprite to the angleToPointer method to give me the angle from the player’s sprite to the mouse pointer. If that sounds confusing, don’t worry. It’s really not a lot of code and there are a lot of examples laying around. Check it out:

What about the fullscreen stuff?

Oh that? That’s almost not even worth talking about. All I did was update the Phaser constructor line to include the innerHeight and innerWidth from the window object.

Is that it?

For now, yes. I’ve decided to scale back what I’m attempting to do each week to be 1–3 new features and to fix as many bugs/do as much housekeeping as possible. Next week I’m committing to having at least one enemy type show up on the map and I’ve got a running list of features/bugs that I’ll be using to guide me from here on out.

As usual, the code can be found here and you can play it here. Enjoy!

If you have any questions, comments, or concerns just let me know. I’ll be happy to respond to anything and everything. Like, share, and follow and eventually, we’ll all be game devs.

--

--