Jump to content

Asteroid movement on a Group of Sprites.


symof
 Share

Recommended Posts

Hello,

I'm now to Html5 game development (well game development in general not just html5) and phaser. I've decided on the phaser library because it gives me more control over the code and I find it more sustainable for me to know how things work.

What I am looking for, is to make space games. Yes space game with player controlled ships, and for that I am experimenting with different types of controls.

The easiest so far for me was to get a basic 8 direction movement(duh), which did not take long to make as everything was pretty straight forward.

var game = new Phaser.Game(800, 600, Phaser.auto, 'phaser-example', { preload: preload, create: create, update: update, render: render });

var result = 'Press a key';

function preload() {
	//load assets
    game.load.image("shipbox", "/img/box.png");
}

function create() {
	//Add keybinds
	pauseKey = game.input.keyboard.addKey(Phaser.Keyboard.P);
	
	UP = game.input.keyboard.addKey(Phaser.Keyboard.W);
	DOWN = game.input.keyboard.addKey(Phaser.Keyboard.S);
	RIGHT = game.input.keyboard.addKey(Phaser.Keyboard.D);
	LEFT = game.input.keyboard.addKey(Phaser.Keyboard.A);
	
	TURN_LEFT = game.input.keyboard.addKey(Phaser.Keyboard.Q);
	TURN_RIGHT = game.input.keyboard.addKey(Phaser.Keyboard.E);
    
    ship = game.add.group();
  	
  	ship.create(200,200, 'shipbox');
  	ship.create(190,195, 'shipbox');
  	ship.create(190,205, 'shipbox');
  	ship.x = 200;
  	ship.y = 200;
  	
  	ship.pivot.x = ship.x+ship.width/2;
  	ship.pivot.y = ship.y+ship.height/2;
  	
}

function update() {
	if (pauseKey.isDown){
		result = "Paused";
	}else if(RIGHT.isDown && UP.isDown){
		ship.x +=1;
		ship.y -=1;
		result = "RIGHT+UP";
	}else if(RIGHT.isDown && DOWN.isDown){
		ship.x +=1;
		ship.y +=1;
		result = "RIGHT+DOWN";
	}else if(LEFT.isDown && UP.isDown){
		ship.x -=1;
		ship.y -=1;
		result = "LEFT+UP";
	}else if(LEFT.isDown && DOWN.isDown){
		ship.x -=1;
		ship.y +=1;
		result = "LEFT+DOWN";
	}else if (RIGHT.isDown){
		result = "RIGHT";
		ship.x +=1;
	}else if (LEFT.isDown){
		result = "LEFT";
		ship.x -=1;
	}else if (UP.isDown){
		result = "UP";
		ship.y -=1;
	}else if (DOWN.isDown){
		result = "DOWN";
		ship.y +=1;
	}else if (TURN_LEFT.isDown){
		result = "TURN LEFT";
		ship.angle -=0.2;
		game.debug.text(ship.angle, 32, 64);
	}else if (TURN_RIGHT.isDown){
		result = "TURN RIGHT";
		ship.angle +=0.2;
		game.debug.text(ship.angle, 32, 64);
	}else {
		result = 'Press a key';
	};
}

function render(){
	game.debug.text(result, 32, 32);
}

So with that out of the way I proceeded on doing asteroids movement, of which I found the asteriods movement example at http://phaser.io/examples/v2/arcade-physics/asteroids-movement ,and this brings me to my problem.

I do not know if it's a software limitation or just me being new but when I try to use the same code but for a group all I get in return is a black screen. What I basically did was instead of :

//  Our player ship
sprite = game.add.sprite(300, 300, 'ship');
sprite.anchor.set(0.5);

I changed to 

//  Our player ship
    
sprite = game.add.group();
    
sprite.create(300, 300, 'ship');
sprite.create(290, 295, 'ship');
sprite.create(310, 305, 'ship');

My logic says this should be working, so why isn't it?

 

I am trying to avoid using complicated math to calculate heading based on orientation and that's the reason for using the arcade physics. I was basically hoping for something along the lines of pressing "W" and the "ship group" moves forward (the forward direction based on current orientation angle).

 

Any thoughts on this?

Link to comment
Share on other sites

You can not just for example change the X value of a group to move all ships as a group has its own value. If you want to manipulate multiple (all) items in a group you need to loop through the group and apply the change to each child.

Something like this:

function create() {
   //Create group
   sprite = game.add.group();

   //Create three ships
   sprite.create(300,300,'ship');
   sprite.create(290,295,'ship');
   sprite.create(310,305,'ship');
}

function update() {
   //Loop through the group
   for (var i = 0; i < sprite.length; i++) {
      //Get each child
      ship = sprite.children[i];
      //Manage movement in this section
      if (RIGHT.isDown && UP.isDown) {
         ship.x += 1;
         ship.y -= 1;
      }
      //Other directions ...
   }
}

If you want smooth movement in all directions and clean code I highly recommend to implement the "accelerationFromRotation" from the asteroids example.

Link to comment
Share on other sites

That seems way too intensive to just loop all the time. I would have proffered for it to have a more simple solution, so I decided to drop arcade physics altogether and use p2js instead.

Doing so I ended up having to use math :( because p2js doesn't have what I wanted either.

function update() {
	if (pauseKey.isDown){
		result = "Paused";
	}else if (TURN_LEFT.isDown){
		ship.angle -= turnrate;
		game.debug.text(ship.angle, 32, 64);
	}else if (TURN_RIGHT.isDown){
		ship.angle += turnrate;
		game.debug.text(ship.angle, 32, 64);
	}else if (UP.isDown	){
		if (speed < speedMax){
			speed += speedInc;
			
		}else{
			speed = speedMax;
		}		
	}else if (DOWN.isDown){
		if (speed > 0){
			speed -= speedInc;			
		}else{
			speed = 0;
		}
	}else {
		result = 'Press a key';
	};
	result = speed;
	ship.x += speed * Math.sin((ship.angle+90)*(Math.PI/180));
	ship.y -= speed * Math.cos((ship.angle+90)*(Math.PI/180));
}

This gave me a different movement from asteroids as it works more like a car then a spaceship.

Link to comment
Share on other sites

1 hour ago, symof said:

That seems way too intensive to just loop all the time. I would have proffered for it to have a more simple solution, so I decided to drop arcade physics altogether and use p2js instead.

Groups also exist in P2JS and they do not particularly "belong" to arcade. It is a global Phaser option. Dropping arcade to avoid groups doesn't really change anything.

Having such loops is okay. I used it quite a few times and as long as you don't have a ridiculous amount of objects it works fine. The game I currently work on uses this to move boxes across the screen. I would say like anywhere between 20-50 are on the screen at any given time and the game runs fine.

Link to comment
Share on other sites

23 hours ago, Taggrin said:

Groups also exist in P2JS and they do not particularly "belong" to arcade. It is a global Phaser option. Dropping arcade to avoid groups doesn't really change anything.

Having such loops is okay. I used it quite a few times and as long as you don't have a ridiculous amount of objects it works fine. The game I currently work on uses this to move boxes across the screen. I would say like anywhere between 20-50 are on the screen at any given time and the game runs fine.

I never intended on dropping groups, just the arcade physics. I am still having issues with this. The code bellow is my current iteration of it.

var game = new Phaser.Game(1024, 600, Phaser.auto, 'phaser-example', { preload: preload, create: create, update: update, render: render });

var result;
var speedMax = 3;
var speedInc = 0.1;
var speed = 0;
var turnrate = 0.4;
var shipbase = [
		[0, 0, 1, 0, 0],
		[0, 0, 1, 1, 0],
		[0, 1, 0, 1, 0],
		[0, 0, 0, 0, 0],
		[0, 0, 0, 0, 0]
	];
var shipgroup;
var ship;

function preload() {
	//load assets
    game.load.image("hexagon-1", "./img/hexagon_64x64_01.png");
}

function create() {
	//start physics
	game.physics.startSystem(Phaser.Physics.P2JS);
	
	//Add keybinds
	pauseKey = game.input.keyboard.addKey(Phaser.Keyboard.P);
	
	UP = game.input.keyboard.addKey(Phaser.Keyboard.W);
	DOWN = game.input.keyboard.addKey(Phaser.Keyboard.S);	
	TURN_LEFT = game.input.keyboard.addKey(Phaser.Keyboard.A);
	TURN_RIGHT = game.input.keyboard.addKey(Phaser.Keyboard.D);
	
	//create ship
	shipgroup = game.add.group();
	
	for (i=0; i<shipbase.length; i++){
  		for (j=0; j<shipbase[i].length; j++){
	  		if (shipbase[i][j] != 0){
	  			if (i & 1){
		  			shipgroup.create(200+j*64-32, 200+i*64-i*16, 'hexagon-1');
		  		}else{
		  			shipgroup.create(200+j*64, 200+i*64-i*16, 'hexagon-1');
		  		}
		  	}
  		}
  	}
  	
	//enable psysics on all items and enable debugged
	game.physics.p2.enable(shipgroup, true);
	
	shipgroup.forEach(function (item){
		item.body.setCircle(4);
		item.body.mass = 9999999999999;
	}, this);
}

function update() {
    if (pauseKey.isDown){
		result = "Paused";
	}else if (TURN_LEFT.isDown){
		result = "TURN_LEFT";
		shipgroup.forEach(function (item){
			item.body.angle -=1;
		}, this);
	}else if (TURN_RIGHT.isDown){
		result = "TURN_RIGHT";
		shipgroup.forEach(function (item){
			item.body.angle +=1;
		}, this);
	}else if (UP.isDown	){
		result = "UP";
		shipgroup.forEach(function (item){
			item.body.moveForward(50);
		}, this);
	}else if (DOWN.isDown){
		result = "DOWN";
		shipgroup.forEach(function (item){
			item.body.moveBackward(50);
		}, this);
	}else {
		result = 'Press a key';
	};
}

function render(){
	game.debug.text(result, 32, 32);
}

The group as a whole moves as intended forward, backwards and turning. The problem is that I cannot find a way to change the angle of the group, instead of the individual items in the group, so that the group as a whole rotates around a pivot point, instead of each cell rotating individually.

I have tried using physics groups but that didn't work either.

I basically need a way to code this

result = "TURN_RIGHT";
shipgroup.forEach(function (item){
    item.body.angle +=1;
}, this);

Such that it rotates the group alone.

result = "TURN_RIGHT";
shipgroup.angle += 1;

Changing the angle directly on the group is what naturally comes to my mind. However this only rotates the sprites and not the physics body.

 

Any thoughts on how I can get this to work? 

Link to comment
Share on other sites

6 minutes ago, glantucan said:

Can you try to:


shipgroup.enableBody = true

an see if that solves it?

 

enableBody does not make the group have a physical body, it only makes the sprites in the group have physical bodies. 

If true all Sprites created with #create or #createMulitple will have a 
physics body created on them. Change the body type with #physicsBodyType.

I would like for the cells to keep their individual physics to use them for collisions but at the same time some sort of group control to rotate the group.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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