Improving Movement in 2D HTML5 Games

Share this article

Recently, I released Empty Black, my 2D shooter/puzzler/platformer. In this article, I’ll describe how I made the player movement deft and intuitive. Play the game before you read on, so you’ll know what I’m talking about. My general approach was to change something, then try it out. I took the ideas for adjustments from several sources. One. I examined the parameters affecting the movement of the player characters in other 2D platformers. Is the floor slippy? What is the ratio of sideways movement to jump height? Does the character accelerate as it moves? Is the character’s jump height affected by the length of time the player holds the jump button? Is the character slowed when it bumps into a moveable object? Two. I examined the unusual behaviours of the player characters in other 2D platformers. Super Meat Boy makes the character leap away from the wall automatically when wall-jumping. Spelunky lets the character pull himself up and over ledges. In Castlevania, the character can do an extra jump while in mid-air. Three. I got people to play test. Kemal told me that the character movement should be effortless. Specifically, if the character hits a wall near the top, it should slip up and over. Ricky told me it was weird that the player had no control over the height of the character’s jump. He showed me how, when hopping over an obstacle in a room with a low ceiling, he bumped his head. Ricky also pointed out the jarring effect of the initial slow down of the character when it lands after a jump. Everyone told me that airborne movement was too sensitive. Everyone told me that wall-jumping was too finicky. Four. I read pieces written by programmers about their character movement algorithms. These pieces were mostly confined to short comments, rather than in-depth analyses. Hence, this article. To the algorithm. The short version: a pile of hacks. The long version: The player presses the jump key. The first question is: can the character jump? Which means: is the character in contact with anything that can be used as a place to jump from? Empty Black uses Box2D to control the physics of the game world. Any movements are subject to Box2D’s models of the forces of friction and gravity. Further, Box2D handles the reactions of objects that collide: bounces, shoves, spins and slides. The game can interrogate Box2D and ask what objects a particular object is touching. If the character is currently touching something solid, the character may jump. Except, it’s not quite that simple. As well as leaping from the ground, the character can wall-jump. This means landing and clinging onto a wall, then jumping again, away from the wall. jump away from the wall This technique is used frequently as a way for the player to get the character up a narrow shaft. They jump it back and forth between the vertical, parallel walls of the shaft, ascending with each jump. jump up the wall This ability is bounded. The player may jump the character out from a wall and land it on the same wall. At this point, it may not jump again. If the player tries to make it jump, the character will fall. This bound is there to improve the gameplay. It is easier to design fun levels if I can rely on the unscalable nature of a solitary wall. The bound makes it harder to decide if the character has a solid footing. The character should be able to jump from the ground as many times as the player likes. But it should not be able to jump from the same wall twice in a row. Fortunately, Box2D has a metaphysical object that complements the corporeal walls, enemies and bullets: the sensor. This spiritual creature has no physical presence. It has a location in the world and it registers collisions. The programmer can interrogate it about such collisions, just as with physical objects. What I did was to attach a wide, short sensor to the bottom of the character. It would look like this, if you could see it: sensor on bottom Notice how the sensor overlaps the ground. Now, instead of asking the character object about collisions, the game asks the character’s bottom sensor. How does that help? It doesn’t. But I can attach two more sensors to the character, one on each of its sides. sensors on sides This means that the game can ask each sensor if it is touching anything. If the bottom sensor is touching some solid footing, jumps are always allowed. If only a side sensor is touching a solid footing, the game must investigate further. Jumps will be allowed in all cases but two. One. The character lands against the wall it has just jumped from. jump to same wall The game keeps a record of the last sensor that registered the solid footing for a jump. If it was a side sensor, and the character is using the same sensor for registration of the current solid footing, the jump is not allowed. If the player loses control during a wall-jump ascent, the character will begin to fall. The player might manage to press jump as it hits a wall on its way down. It is possible that this wall will be the one they most recently jumped from. If it is, the jump would be prevented. However, there is an exception that permits the jump if the character is lower than it was when it jumped the time before. This exception allows the player to recover from their mistake. It makes the controls more forgiving. Two. The character lands and sticks to the wall. The player continues to press the direction key that holds the character against the wall. They press jump again. The jump is not allowed. If it were, the character would slide up the wall like this: sliding up the wall To stop this, the game only allows the jump if the player is not pressing the character into the wall. There is an exception. If the character is near the top of a wall, it may jump. This lets it slip up and over the wall. over the wall The game now knows if the character is allowed to jump. To enact the jump, upward force is applied for a single instant. The character’s velocity is high when it first starts moving. It is progressively attenuated by gravity. Some distance into the air, all the character’s momentum will be gone and it will begin falling. If the player releases the jump button before the character has reached its peak in the jump, the character will immediately begin falling. I stole this idea from Super Meat Boy. The effect is that of a glass ceiling being inserted above the character’s head. This allows the player to control the height of the jump. It stops Ricky getting a sore head. The magnitude of the force of the jump is usually constant. However, it is increased in two situations. First, when the character is carrying a crate. This stops the weighted character’s jumps turning into lame little bunny hops. Second, when the character is falling faster than usual. Imagine the character is wall-jumping and, because of a player fumble, it hits the next wall at a point lower than the point it jumped from. To help the player recover, their next attempt at a jump from a wall will lift the character with a force greater than normal. The difference from the normal force is proportional to the disparity between the normal and actual force of falling. Now: sideways movement. The player presses the left arrow key. What happens? A leftward force is continually applied until the player releases the key. The magnitude of the force depends on how fast the character is currently moving. If it is at top speed, no force is applied. If it is stationary, a large force is applied. The idea is to get the character to top speed as fast as possible, then hold it at that speed. This makes the movement more predictable. It also solves Ricky’s second problem. The character immediately regains top speed after it lands a jump. The player releases the key that moves the character left. What happens? The character immediately stops. There is no slippiness. Thus, the character is easier to control. When I was designing the character movement, it was hard to keep the code tidy. I tried to find the smallest number of rules that required the least subsequent modification with hacks. Two examples. One. I tried to eliminate the slippiness of the floor by setting the friction very high. But this had many undesired consequences. It was hard to get the player moving sideways at top speed without also making airborne movement too sensitive. Crates could no longer be shoved, and mis-throws would leave them perched on ledges. I added code to immediately stop the character upon release of the move key. Two. Slipping up and over a ledge was just a matter of the player pressing the jump key near the top of a wall. But if the character was only half way up a wall, such a jump would mean it slid upwards and got stranded. I could have left that behaviour as it was. But that would have made wall-jumping harder. I could have automatically jumped the character away from the wall. But that seemed too nannyish. So, I prevented jumps when the player was pressing into the wall but was not near the top of it. In both cases, it was worth slightly modifying a generally correct behaviour with an ugly but small hack that had no repercussions. The general approach was to try stuff to explore the options. But the goal was a few broad rules. I did this by only deciding on a permanent change after a careful check of the ramifications. And I sometimes entirely remade the rules, as with the addition of the sensors to the character. Here is a pocket-sized summary for you. Examine the overall behaviours and specific parameters of other games. Get as much player feedback as you can. Make many changes. Tidy up after yourself. This article originally appeared on BuildNewGames.com, a collaboration by the teams at Bocoup and Internet Explorer.

Frequently Asked Questions about Improving Movement in 2D HTML5 Games

How can I improve the movement of characters in my 2D HTML5 game?

Improving the movement of characters in a 2D HTML5 game involves understanding the basics of game physics and implementing them correctly. This includes concepts like velocity, acceleration, and friction. You can use JavaScript to create these effects. For instance, you can use the ‘requestAnimationFrame’ method for smooth animation, and manipulate the ‘x’ and ‘y’ coordinates of the character for movement. Remember, the key to smooth movement is to ensure that the game runs at a consistent frame rate across different devices.

What is the role of physics in 2D HTML5 games?

Physics plays a crucial role in 2D HTML5 games. It is responsible for how objects move and interact within the game. This includes everything from gravity affecting a character’s jump to collision detection between objects. By understanding and implementing game physics, you can create more realistic and engaging games.

How can I implement collision detection in my 2D HTML5 game?

Collision detection in 2D HTML5 games can be implemented using the ‘intersects’ method. This method checks if the bounding boxes of two objects overlap. If they do, a collision is detected. You can then define what should happen when a collision occurs, such as bouncing off an object or losing a life.

How can I make my 2D HTML5 game responsive?

Making a 2D HTML5 game responsive involves ensuring that it scales and runs well on different devices and screen sizes. This can be achieved by using relative units for game elements, and adjusting the canvas size based on the window size. You can use the ‘window.innerWidth’ and ‘window.innerHeight’ properties to get the viewport size.

How can I optimize my 2D HTML5 game for better performance?

Optimizing a 2D HTML5 game for better performance involves several strategies. This includes minimizing the use of global variables, using sprite sheets for animations, and optimizing your code for efficiency. You should also consider using a game engine, which can handle many of these optimizations for you.

What are some common challenges in developing 2D HTML5 games?

Some common challenges in developing 2D HTML5 games include handling different screen sizes and resolutions, optimizing for performance, and dealing with browser compatibility issues. Additionally, implementing game physics and collision detection can be complex.

How can I add sound effects to my 2D HTML5 game?

Sound effects can be added to a 2D HTML5 game using the ‘Audio’ object in JavaScript. You can create a new ‘Audio’ object, set its ‘src’ property to the location of your sound file, and then call the ‘play’ method to play the sound. Remember to consider the file size and format for optimal performance and compatibility.

How can I add animations to my 2D HTML5 game?

Animations in a 2D HTML5 game can be created using sprite sheets. A sprite sheet is a single image file that contains multiple frames of an animation. You can then use JavaScript to change the displayed frame at regular intervals, creating the illusion of movement.

How can I test my 2D HTML5 game across different browsers and devices?

Testing a 2D HTML5 game across different browsers and devices is crucial to ensure a consistent gaming experience. You can use browser developer tools to simulate different devices and screen sizes. Additionally, you should test your game on actual devices and browsers whenever possible.

How can I monetize my 2D HTML5 game?

There are several ways to monetize a 2D HTML5 game. This includes in-game advertising, in-app purchases, selling the game outright, or offering a freemium model where the game is free to play but users can pay for additional features or content.

Mary Rose CookMary Rose Cook
View Author

Mary Rose Cook likes to hack, make music and do political things. She’s currently doing Hacker School in NYC.

gamesHTML5 Dev Center
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week