Jump to content

2D perspective game with Phaser


Recommended Posts

Hi guys,


I would like to know before I get more and more into Phaser, that is I will be able to do everything I would like to do.


My goal is to create a kind of shooting game in 2D with some perspective, a little bit like the RPG game like that :




(but I don't want to use a pixel world)


So far I manage to develop a kind of prototype for the main character, the movement aren't great, but you will get the idea of the gameplay I would like to have :

( I forgot to mention that you have to use the 'WASD' key of your keyboard for the movement ;) )

The diagonal animations aren't done yet, I must say that it's a bit complex to do, and I'm not event sure I'm doing it the right way.


Most likely the world would be seen in perspective, I think I would use the collisions of Phaser because my map would display in tile (Just for the trees, I would just need to have the bottom of the trees collide, I would like that the player can walk behind it).


So yes, most likely my biggest concern is the movement of my character. So far, I'm using a sprite that I found on the web, because doing it one by myself would take a long time, and it was just to create a kind of prototype of it.

I think that when I will create the new sprite, I will have 16 different direction to make the rotation of my character smoother like this :




So far I have 8 and it was kind of tricky to manage when to use each animations depending of the position of the mouse.


Do you think I can achieve what I want do do with Phaser ? Because it will involve guns, and shooting too.


Thanks for your answser and advice :) !

Link to comment
Share on other sites

16 different face angles? Even when you mirror 7 of them, that is still 9 different angles.

Now if you want smooth movement, then you need at least 4 frames per direction.

That's already 36 frames just for 1 character. 


And you will probably have more than just 1 character + different weapons/clothing.

I'm not saying that it isn't possible but you will end up with huge spritesheets and many of them. Probably not worth it.

Link to comment
Share on other sites

If your main worry is moving the character, you should be fine, especially if the only character with that much movement is the player. The layering of trees and other objects will take a little more planning, I think - Phaser's designed for 2D and while 3D emulation is possible, it just takes a bit more work. Take a look at this to see an example of some basic 3D functionality - we extended the Phaser.Sprite class and added a z value that controlled scale and Y movement speed. I know yours is a different variety of 3D, but it'd take the same kind of legwork and extensions.


I say go for it! It'll be fun experiment and (someone correct me if I'm wrong) there shouldn't be a problem with the sprites.


[edit: forgot the link]

Link to comment
Share on other sites

To be perfectly honest about the intention of the game, I will - if that's possible - to make it multiplayer too, but this is an other problem. :)


I will continue to develop it then, but I think I need some help for the movement, because, I'm not sure how to handle when two keys are pressed. So far I did the four cardinal point like this :

if (key_w.isDown) {    sprite.y -= 2;} else if (key_s.isDown) {    sprite.y += 2;} [...]

But to handle the event when the player is pressing W and D, so the player will go up right, should I put the conditional inside the 'if (key_w.isDown)" of inside the key_d one.


I mean, so far I really don't like my code how to handle this, and if I may, this is what its looks like :

	update: function() {		if (this.key_w.isUp && this.key_a.isUp && this.key_s.isUp && this.key_d.isUp) {			this.mouseFollow();			} else {			this.charMovement();		}		},	charMovement: function(d) {		var d = this.mouseDirection();		var s = this.sprite.animations;		if (this.key_w.isDown) { // GO UP			this.sprite.y -= 2;			if (d == dir[2]) { // N				this.sprite.animations.play('up');			} else if (d == dir[6]) { // S				this.sprite.animations.play('rev_down');			} else if (d == dir[7]) { // SW				this.sprite.animations.play('rev_downLeft');			} else if (d == dir[5]) { // SE				this.sprite.animations.play('rev_downRight');			} else if (d == dir[3]) { // NE				this.sprite.animations.play('upRight');			} else if (d == dir[1]) { // NW				this.sprite.animations.play('upLeft');			}					} else if (this.key_s.isDown) { // GO DOWN			this.sprite.y += 2;			if (d == dir[2]) { // N				this.sprite.animations.play('rev_up');			} else if (d == dir[6]) { // S				this.sprite.animations.play('down');			} else if (d == dir[7]) { // SW				this.sprite.animations.play('downLeft');			} else if (d == dir[5]) { // SE				this.sprite.animations.play('downRight');			} else if (d == dir[3]) { // NE				this.sprite.animations.play('rev_upRight');			} else if (d == dir[1]) { // NW				this.sprite.animations.play('rev_upLeft');			}				}		if (this.key_a.isDown) { // GO LEFT			this.sprite.x -= 2;			if (d == dir[0]) { // W				this.sprite.animations.play('left');			} else if (d == dir[4]) { // E				this.sprite.animations.play('rev_right');			} else if (d == dir[2]) { // N				this.sprite.animations.play('rev_upRight');			} else if (d == dir[6]) { // S				this.sprite.animations.play('rev_downRight');			} else if (d == dir[1]) {				this.sprite.animations.play('upLeft');			} else if (d == dir[3]) {				this.sprite.animations.play('rev_upRight');			} else if (d == dir[5]) {				this.sprite.animations.play('rev_downRight');			} else if (d == dir[7]) {				this.sprite.animations.play('downLeft');			}		} else if (this.key_d.isDown) { // GO RIGHT			this.sprite.x += 2;			if (d == dir[4]) { // E				this.sprite.animations.play('right');			} else if (d == dir[0]) { // W				this.sprite.animations.play('rev_left');			} else if (d == dir[2]) { // N				this.sprite.animations.play('rev_upLeft');			} else if (d == dir[6]) { // S				this.sprite.animations.play('rev_downLeft');			} else if (d == dir[1]) {				this.sprite.animations.play('rev_upLeft');			} else if (d == dir[3]) {				this.sprite.animations.play('upRight');			} else if (d == dir[5]) {				this.sprite.animations.play('downRight');			} else if (d == dir[7]) {				this.sprite.animations.play('rev_downLeft');			}		}	},	mouseFollow: function() {		var d = this.mouseDirection();		var s = this.sprite;		switch(d) {			case dir[0]:				this.sprite.frame = 44;				break;			case dir[1]:				this.sprite.frame = 8;				break;			case dir[2]:				this.sprite.frame = 17;				break;			case dir[3]:				this.sprite.frame = 25;				break;			case dir[4]:				this.sprite.frame = 35;				break;			case dir[5]:				this.sprite.frame = 63;				break;			case dir[6]:				this.sprite.frame = 62;				break;			case dir[7]:				this.sprite.frame = 45;				break;		}	},	mouseDirection: function() {		var s = this.sprite;		var m = this.game.input.mousePointer;		var angle = Math.atan2(m.y - s.y, m.x - s.x) * (180/Math.PI);		// TODO: Switch instead of IF		if (angle < -111.5 && angle > -156.5) {			return dir[1];		} else if (angle < -66.5 && angle > -111.5) {			return dir[2];		} else if (angle < -22.5 && angle > -66.5){			return dir[3];		} else if (angle > -22.5 && angle < 22.5) {			return dir[4];		} else if ( angle > 22.5 && angle < 66.5) {			return dir[5];		} else if ( angle > 66.5 && angle < 111.5) {			return dir[6];		} else if ( angle > 111.5 && angle < 156.5) {			return dir[7];		} else if (angle < -156.5 || angle > 156.5) {			return dir[0];		}	}

If you have any idea how I can simplify this code, I would be more than happy, because for now, I don't know how I can manage the diagonal animations...


Thanks !

Link to comment
Share on other sites

Actually, I will change the way of the how my character is moving. I just saw the brillant game nuclear throne, and I must say that the character movement inspired me a lot and its what I wanted to do (almost).


So finally, the char will have 4 directions state, (left, right, up and down), with 4 or 5 sprite animations for each direction, but I will mirror 2 so, finally, I will have less sprite and this might solve my movement animations problem.


I will do an other prototype and I come back here :)

Link to comment
Share on other sites

I'm sorry for triple post, but I have made an other prototype but I need some help with a small bug.


You can have a look at it here :


My problem is that when I press 2 button key and put my cursor at the opposite direction of where my sprite goes, it doesn't do any animations.


E.G :


- Press W and A (it will goes up left) with the cursor at the bottom right = no animations.

- Press the same key and put the cursor at the top left = animations playing.


Is there is anything to do when we presse two direction key at the same time ?


Here is my sprite movement code :

var dir = ["W", "N", "E", "S"];	charMovement: function(d) {		//TODO Separate leg to upperbody for mouvement		var d = this.mouseDirection();		var s = this.sprite;		var speed = 1;		if (this.key_w.isDown) {			s.y -= speed;			if (d == dir[1]) { // N				s.animations.play('up');			} else if (d == dir[3]) { // S				s.animations.play('rev_down');			} else if (d == dir[0]) { // W				s.animations.play('left');			} else if (d == dir[2]) { // E				s.animations.play('right');			}		} else if (this.key_s.isDown) {			s.y += speed;			if (d == dir[1]) { // N				this.sprite.animations.play('rev_up');			} else if (d == dir[3]) { // S				this.sprite.animations.play('down');			} else if (d == dir[0]) { // W				s.animations.play('left');			} else if (d == dir[2]) { // E				s.animations.play('right');			}		}		if (this.key_a.isDown) {			s.x -= speed;			if (d == dir[0]) { // W				s.animations.play('left');			} else if (d == dir[2]) { // E				s.animations.play('rev_right');			} else if (d == dir[1]) { // N				s.animations.play('up');			} else if (d == dir[3]) { // S				s.animations.play('down');			}		} else if (this.key_d.isDown) {			s.x += speed;			if (d == dir[0]) { // W				s.animations.play('rev_left');			} else if (d == dir[2]) { // E				s.animations.play('right');			} else if (d == dir[1]) { // N				s.animations.play('up');			} else if (d == dir[3]) { // S				s.animations.play('down');			}		}			},
Link to comment
Share on other sites

Just at a glance, it looks like the sprite is receiving conflicting animations.play() calls.


For example, if we're pressing S and the cursor is N, it says to play 'rev_up'

and if we're pressing D and the cursor is N, it says to play 'up'.


Make sure your animations aren't getting in each others' way  :)


As an aside, I usually save input values and check the combined total rather than add in too many individual checks - for example:

var moveDirection: Phaser.Point = new Phaser.Point(0, 0);if (this.key_w.isDown)    moveDirection.y = 1;else if (this.key_s.isDown)    moveDirection.y = -1;if (this.key_a.isDown)    moveDirection.x = -1;else if (this.key_d.isDown)    moveDirection.x = 1;

Then you'll have a Phaser.Point saying which direction you're moving, and you can compare that to the cursor position.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...