For many projects using phaser ce there will come a time now and then where it will be necessary to set some air resistance or drag for physics enabled display objects. In this post I will be coving the use of the body.drag property of the arcade physics engine in phaser ce, as a way to set drag for a physics body.
In this post I am writing about an example that I made that makes use of drag using the built in arcade physics engine in phaser ce. This is not a getting started post on the arcade physics engine, or phaser in general. There are many aspects of the phaser ce game framework that are used in this post, and I will not be covering all of them. The drag property is an instance of Phaser.Point so I can use the set method or user the x and y properties to set the values for drag.
In this post I am using phaser community edition 2.11.1 of phaser.
For an example of using drag in phaser ce I thought a simple game prototype that is the beginnings of a cannon launch type game. You know one of those many games that have come out over the years that involve shooting something at a certain angle, and starting velocity. Where the object is typically to get what it is that is begging launched as far of a distance as possible. As such making a prototype of that kind of game might prove to be a good example of not just using drag, but other aspects of physics as well such as gravity, and velocity.
Here I have a method that I worked out that will be used to update drag on each frame tick. There are a few methods that will be called before this is used, so when calling this method in the update method of the game state it will not be grabbing at undefined values for the cannon ball and so forth.
I could just set drag in a way in which it is just fixed, always coming from one direction. The nice thing about game development is that all that really matters is how game play turns out, and realism is not always that important, unless for some reason it is. Still I decided that if I am going to make a post in which I am writing about drag I should make some complex example that updates drag on each tick, changing the direction of drag as the ball changes direction.
So I get the current body angle of the ball via Sprite.body.angle, and use that with its speed via Sprite.body.speed to set the drag of the ball. However in the event that the ball is rolling along the floor I do make sure that the drag is coming directly from the right using the onFloor method to find out if that should happen or not.
So in this project when a cannon sprite is clicked it will cause the ball to launch from the cannon. So I will need a launchBall handler that will fire when the canon is clicked or when whatever cause the cannon to fire when making a user interface.
So then in this method I set the position of the ball to the position of the cannon, revive the ball if it is in a dead state, have the camera follow the ball, and set the velocity of the ball based on certain values that are set before hand elsewhere.
This is a method that makes a sprite that just serves as part of the user interface.
Here I have a method that creates the cannon sprite. The way I have the user interface designed for this example the ball will launch when the cannon is clicked to the cannon sprite is input enabled.
So then I need to make the ball sprite as well. Here I enable physics for the ball sprite, and set gravity, and bounce for the sprite as well.
So I will want to draw some lines so I know the current direction and angle that I will be launching the ball, so I will want to make a graphics object for that. Graphics objects are great for drawing on the fly graphics that involve drawing lines, and simple shapes that need to be updated on a per frame basic rather than just a single still image. So in this project a Graphics display object will work great for drawing the lines that will show the direction, and current launch power of the ball when it will be launched.
This draw method will be used with the graphics object when the ball is launched. It draws grid lines so that I know that the ball is in motion, otherwise it will just be a black background. Because I am using a graphics object I went with this draw method that will be used with the graphics object rather than the create.grid method that could be used to create a texture that could be used with a sprite. In any case this grid solution will help to show reduction in speed as a result of the drag taking effect once that ball launches.
This draw method draws lines that show me the current direction and angle that the ball will be launched. Here is use Math.cos, and Math.sin to find the x and y positions that I need to to draw the lines from the position of the canvas out a given distance, as well as the lines that will indicate launch power as well.
This method sets up and object that contains properties for the state of the launched ball including the angle and distance values that will be used to set initial velocity of the ball.
So I will need to create some sprite sheets to use with the sprites as well. For simple examples like this I often use a canvas solution rather than bothering with external assets. With this kind of solution I just need to create a canvas element, draw to the 2d context, and then use game.cache.addSpriteSheet to convert the canvas to a sprite sheet that can be used when making sprites.
So now it is time to get this project working with a Phaser.Game instance. Here in the create method of the state object I create my sprite sheets, and call my create launcher method. I also set up a text object to display the state of some values in my drag update method.
Here I also set the camera bounds to null so that the camera will leave the bounds of the set game world when I have it follow the ball that goes out of bounds. I need to do this because this is the kind of game where there is no set limit on how far the ball can potential go, so I need to camera to leave the bounds of the game world.
I also of course call my updateDrag method for each frame tick, and draw the gird lines when the launch is active.
So setting drag is just a matter of coming up with the proper x and y values that can then be set to a sprites physics body. Coming up with those values depends on how it is that I want drag to behave. With some projects just setting simple static values will work just fine, for other projects in which I want to simulate wind or something to that effect a more complex solution will need to be used.
This project could use a fair amount of fine tuning, and maybe I will get around to it if this post gets some traction. If you would like for me to give this project some more attention, or if you have any questions or concerns be sure to let me know in the comments. In any case thank you for reading, and have fun with physics and phaser.