How To Allow Gravity On An Animated Sprite In Phaser
Breathing Spritesheets in a Phaser Game
When it comes to second game development, sprite animations are going to be a critical role of the game experience. No one wants to play a game with a static unappealing image that moves around on the screen. They are going to want vibrant animations that add a sure realism to the game-play feel, even with it existence second.
At that place are a few ways to accomplish animations in game development. You could develop complex logic that swaps images on a sprite every time the render role updates, or you could work from a single spritesheet and iterate over the frames in that spritesheet.
One of the main benefits to spritesheets, across them being piece of cake to breathing in mod game development frameworks, is they are easy on the computing resources. Loading one prototype file is less resource intensive than loading several image files, and when information technology comes to smooth performance in games, how you manage your resources can brand or break your game.
In this tutorial, we're going to meet how to animate 2D sprites in a Phaser iii.x game using uncomplicated spritesheets with JavaScript.
To get a better idea of what we promise to attain in this tutorial, take a look at the following animated paradigm:
We accept ii things happening in the above paradigm. We have a crude looking plane that looks similar information technology is flying, hence the jet-stream behind information technology. We also take a crude looking explosion that triggers after a certain amount of time. These are both animations with several frames within the same spritesheet.
So what do we have to do to achieve this effect?
Create a Phaser 3.x Project with HTML and JavaScript
Earlier nosotros look at creating, using, and animating a spritesheet, let's focus on getting started with some boilerplate Phaser 3.10 code. On your computer, create a new directory with an index.html file in it. Within this index.html file, include the following code:
<!DOCTYPE html> < html > < head > < script src = "//cdn.jsdelivr.net/npm/phaser@iii.24.one/dist/phaser.min.js" ></ script > </ head > < trunk > < div id = "game" ></ div > < script > const phaserConfig = { type : Phaser . AUTO , parent : "game" , width : 1280 , pinnacle : 720 , scene : { init : initScene , preload : preloadScene , create : createScene , update : updateScene } }; const game = new Phaser . Game ( phaserConfig ); function initScene () {} part preloadScene () {} role createScene () {} part updateScene () {} </ script > </ body > </ html >
The above HTML markup and JavaScript code volition create a sheet for rendering our game. Because we are using Phaser.Auto
, we might not really exist using a sheet, but instead WebGL, but I'yard going to refer to it as a canvass.
For the residual of this tutorial, we're going to be spending our time in the preloadScene
and createScene
functions. However, the initScene
and updateScene
functions would probably be used in a more extensive tutorial.
Defining Blitheness Frames and Animating a Spritesheet
With Phaser configured and gear up to go, we can work towards getting our animations working. There are a few ways to make a spritesheet for game development, and a few different ways to format a spritesheet.
To make life easier and keep us consequent, we're going to be using the post-obit spritesheet:
There are a few things worth mentioning regarding the higher up spritesheet.
In the above spritesheet, every frame has the same dimensions and the same padding. In other words, if I were to intermission this prototype into six images based on the frame, they would have the same size and same position. I fabricated this spritesheet with TexturePacker, but it tin hands be reproduced with a general image editing tool like Analogousness Photo or Adobe Photoshop. In a later tutorial nosotros're going to explore sprite atlases, where the spritesheets are compressed and of not the same size per frame.
With the spritesheet nether control, lets work towards adding it to Phaser. Copy the image file to the same directory as your index.html file. I'g calling the image file aeroplane.png, only feel free to call it whatever you want.
Inside the preloadScene
role of the alphabetize.html file add the post-obit line:
function preloadScene () { this . load . spritesheet ( "plane" , "aeroplane.png" , { frameWidth : 512 , frameHeight : 512 }); }
The preloadScene
is where yous should load all of your media assets prior to the game being created. In this example, we're loading our spritesheet and naming information technology plane
for futurity use throughout the game. The spritesheet name does non need to match the actual file name. Information technology is important nosotros define the frameWidth
and frameHeight
as it tells our animator how large each frame is in our spritesheet.
Inside the createScene
part, at present we can define the animations. Have a look at the following:
function createScene () { this . anims . create ({ key : "wing" , frameRate : 7 , frames : this . anims . generateFrameNumbers ( "plane" , { showtime : 3 , end : 5 }), repeat : - 1 }); this . anims . create ({ key : "explode" , frameRate : seven , frames : this . anims . generateFrameNumbers ( "plane" , { get-go : 0 , finish : ii }), repeat : ii }); }
In the above function we have ii different animations using the same spritesheet media asset. Allow's look at the animation that I'm calling fly
in our code:
this . anims . create ({ key : "fly" , frameRate : 7 , frames : this . anims . generateFrameNumbers ( "plane" , { commencement : 3 , end : 5 }), repeat : - 1 });
For this particular blitheness, we are cycling through our frames at a rate of seven frames per second. The frames in our spritesheet for this particular animation are defined by the start
and end
fields. If we await back at our image, we know that the actual plane is the 3rd through 5th image if looking at the spritesheet from left to correct, top to bottom. The index of these frames starts at zero and non ane. For this detail animation nosotros are repeating until we specifically tell it to stop.
Now let's revisit the other animation:
this . anims . create ({ key : "explode" , frameRate : 7 , frames : this . anims . generateFrameNumbers ( "airplane" , { commencement : 0 , end : 2 }), repeat : two });
Rather than repeating the animation until we tell it to stop, this animation volition echo twice and then cease.
It is important to annotation that stopping an animation does non remove the sprite. We'll get to that after. Then this ways when an blitheness stops, the sprite volition stay in that location appearing frozen on the screen.
With two different animations defined, we need to acquaintance them to an bodily sprite game object. To do this, permit'south create the following variable to correspond our plane:
The above variable should exist outside of whatsoever scene functions then that way it tin can be used throughout the game with the correct scope.
Inside the createScene
office, below the blitheness definitions, let's initialize our sprite and start the fly
blitheness:
function createScene () { // Animation definitions hither ... plane = this . add together . sprite ( 640 , 360 , "plane" ); plane . play ( "fly" ); }
In the higher up code, the sprite is using the airplane
spritesheet and the fly
animation associated to that spritesheet. Given the dimensions of our game canvas, the sprite is centered.
This is corking and then far, but when we run our game we only see a plane flying forever. We need to meet how to change animations and know when animations cease.
Changing Animations and Reacting to Blitheness Events on a Sprite
Being able to change an animation is important considering eventually you lot'll want to respond to interactions within the game. For example, if our plane were to crash, we'd probably desire it to explode, hence the explode
blitheness. This isn't the just scenario, but it works for our example.
Rather than complicating this example with collisions and things similar that, let's change the animation based on a timer. Within the alphabetize.html file and the createScene
office, add the following:
function createScene () { // Animation definitions here ... aeroplane = this . add . sprite ( 640 , 360 , "airplane" ); plane . play ( "fly" ); setTimeout (() => { airplane . play ( "explode" ); }, 3000 ); }
In the in a higher place code, we're using a setTimeout
in JavaScript to expect three seconds before playing a unlike blitheness on our sprite. If we wanted to exercise things in the spirit of Phaser, we could utilize a special form for this similar the following:
function createScene () { // Blitheness definitions hither ... plane = this . add . sprite ( 640 , 360 , "plane" ); plane . play ( "wing" ); this . time . addEvent ({ delay : 3000 , callback : () => { plane . play ( "explode" ); } }); }
Both should achieve the same thing. However, because of frame rate considerations, the this.time.addEvent
may be the proper way to go as it might practice calculations that the setTimeout
does not.
So we know how to change sprite animations now. The adjacent step is to figure out when an animation ends and potentially even remove the sprite. To do this, nosotros could take a look at the following:
plane . once ( Phaser . Animations . Events . SPRITE_ANIMATION_COMPLETE , () => { plane . destroy (); });
The above code says that once the animation stops, the plane should be destroyed, which means it is removed from the game.
To put things into perspective, our index.html file might await like the following every bit of at present:
<!DOCTYPE html> < html > < head > < script src = "//cdn.jsdelivr.net/npm/phaser@3.24.one/dist/phaser.min.js" ></ script > </ caput > < body > < div id = "game" ></ div > < script > const phaserConfig = { blazon : Phaser . AUTO , parent : "game" , width : 1280 , height : 720 , scene : { init : initScene , preload : preloadScene , create : createScene , update : updateScene } }; const game = new Phaser . Game ( phaserConfig ); var plane ; function initScene () { } function preloadScene () { this . load . spritesheet ( "plane" , "plane.png" , { frameWidth : 512 , frameHeight : 512 }); } office createScene () { this . anims . create ({ key : "fly" , frameRate : 7 , frames : this . anims . generateFrameNumbers ( "airplane" , { start : 3 , cease : five }), repeat : - one }); this . anims . create ({ key : "explode" , frameRate : 7 , frames : this . anims . generateFrameNumbers ( "aeroplane" , { start : 0 , end : 2 }), repeat : two }); plane = this . add . sprite ( 640 , 360 , "plane" ); airplane . play ( "fly" ); this . fourth dimension . addEvent ({ delay : 3000 , callback : () => { plane . play ( "explode" ); plane . one time ( Phaser . Animations . Events . SPRITE_ANIMATION_COMPLETE , () => { plane . destroy (); }); } }); } part updateScene () {} </ script > </ torso > </ html >
Only to reiterate, we probably could have used setTimeout
, but since functionality in Phaser three.x exists, information technology probably makes sense to use that instead.
There are other animation events, but for this example knowing when to remove our sprite makes SPRITE_ANIMATION_COMPLETE
a great choice.
Conclusion
You but saw how to animate a spritesheet in a Phaser 3.x powered game. Just a few points to reiterate on regarding the approach that we used.
- We used a uniformly spaced and sized sheet of sprite images that accept not been optimized.
- We used a spritesheet, non a sprite atlas.
In a future tutorial we'll explore the sprite atlas option for more than optimized spritesheets and animations.
While yous tin create a spritesheet using pretty much any image editing software, if you desire to make it easier on yourself, you tin can consider TexturePacker which is what I used. Substantially you but driblet some images into the software and it generates a spritesheet for you.
Nic Raboy
Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Coffee, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.
Source: https://www.thepolyglotdeveloper.com/2020/07/animate-spritesheets-phaser-game/
Posted by: ortizfirembles.blogspot.com
0 Response to "How To Allow Gravity On An Animated Sprite In Phaser"
Post a Comment