Jump to content

Sprite Picking Up Another Sprite


Dower
 Share

Recommended Posts

So, I'm still getting used to Phaser, and my question for the community is what would you do to get a sprite to pick up another sprite.

So, example. The player is a helicopter, and the ground has crates, I want the chopper to make contact with the crate, and pick it up; in essence, the crate becomes attached to the chopper sprite, so it will move wherever the chopper goes.

Of course, I'll need the player to drop the crate too.

So, would I make the player into a group, and then add the collided crate into this group?

 

What do you all think?

Thanks,

Dower

Link to comment
Share on other sites

Here's my code in an all-in-one file.

The player.png file is just a 50x50 box, and I'm repurposing it for testing, so I've not made sprites for the crate. I'm also just manually creating a ground sprite from a bitmap.

The chopperHit function is where I attempt to addChild.

 

Maybe this isn't the right approach, maybe I should just manually move the crate to the chopper position in the update function?

 

<!DOCTYPE html><html>   <head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" /><title>PickUp Test</title><script type="text/javascript" src="js/phaser.min.js"></script><style>body {padding: 0px;margin: 0px;background: black;}</style>  <script>var chopper;  var mainState = {init: function() {this.stage.backgroundColor = "#111111";},preload: function() {game.load.image("chopper", "assets/images/player.png");},create: function() {game.physics.startSystem(Phaser.Physics.ARCADE);// create the groundvar floorBmp = game.add.bitmapData(480,5);floorBmp.ctx.fillStyle="#AAAAAA";floorBmp.ctx.fillRect(0,0,480,5);this.floor = game.add.sprite(0,315,floorBmp); // Add chopperchopper = game.add.sprite(game.world.centerX, game.world.centerY, "chopper");chopper.anchor.setTo(0.5);chopper.scale.setTo(1,-0.25);chopper.collideWorldBounds = true;// Add cratethis.crate = game.add.sprite(300,50,"chopper");this.crate.scale.setTo(-0.5);this.crate.anchor.setTo(0.5,0.5);this.crate.attached = false;// Define Physicsgame.physics.arcade.enable([chopper, this.floor, this.crate]);this.floor.body.immovable = true;this.floor.allowGravity - false;this.crate.body.bounce.y = 0.5;this.crate.body.gravity.y = 300;this.crate.collideWorldBounds = true;// setup the viewport cameragame.world.setBounds(0, 0, 1920, 320); game.camera.follow(chopper);game.camera.deadzone = new Phaser.Rectangle(0,0,480,320);this.cursors = game.input.keyboard.createCursorKeys();},update: function() {game.physics.arcade.collide(chopper, this.crate, this.chopperHit, null, this);game.physics.arcade.collide(this.crate, this.floor);chopper.body.velocity.x = 0;chopper.body.velocity.y = 0;if (this.cursors.up.isDown){chopper.body.velocity.y = -200;}else if (this.cursors.down.isDown){chopper.body.velocity.y = 200;}if (this.cursors.left.isDown){chopper.body.velocity.x = -200;}else if (this.cursors.right.isDown){chopper.body.velocity.x = 200;}},render: function() {game.debug.body(chopper);game.debug.body(this.crate); game.debug.body(this.floor);},chopperHit: function(body, bodyB, shapeA, shapeB, equation) {if (!this.crate.attached) { this.crate.x = chopper.x;this.crate.y = chopper.y + 50;chopper.addChild(this.crate);this.crate.attached = true;}}}var game = new Phaser.Game(480, 320, Phaser.AUTO);game.state.add("main", mainState);game.state.start("main");</script>   </head>   <body>     </body></html>
 

 

 

 

Link to comment
Share on other sites

This is my suggestion to resolve the issue. Have the two elements and when the helicopter collides with the create have a call back to a function and see if you can use the anchor point? I think anchor points could be the solution here - 
http://phaser.io/examples/v2/sprites/anchor


Like this - 

create.x = chopper.x;create.y = chopper.y;create.angle = chopper.angle;
Link to comment
Share on other sites

After some messing around, I came up with this solution, but I don't know how well it will scale.

So, in the chopperHit function, I check to see if the crate.attached = true, if not, I set that, and I position the crate to the chopper's x and y+30 position. I also figured out that I had to turn the gravity.y off on the crate, because it would continue to slide down.

Then i put in the update function a check if crate.attached, then I set the position to the chopper's x and y+30...

I seems to work... But I don't know if this would scale once I converted the crate into a group and had a bunch on the screen...

I still don't quite get the addChild, since once I try to addChild(crate). It just disappears.

 

<!DOCTYPE html><html>   <head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" /><title>PickUp Test</title><script type="text/javascript" src="js/phaser.min.js"></script><style>body {padding: 0px;margin: 0px;background: black;}</style>  <script>var chopper;  var crate;var mainState = {init: function() {this.stage.backgroundColor = "#111111";},preload: function() {game.load.image("chopper", "assets/images/player.png");},create: function() {game.physics.startSystem(Phaser.Physics.ARCADE);// create the groundvar floorBmp = game.add.bitmapData(480,5);floorBmp.ctx.fillStyle="#AAAAAA";floorBmp.ctx.fillRect(0,0,480,5);this.floor = game.add.sprite(0,315,floorBmp); // Add chopperchopper = game.add.sprite(game.world.centerX, game.world.centerY, "chopper");chopper.anchor.setTo(0.5);chopper.scale.setTo(1,-0.25);chopper.collideWorldBounds = true;// Add cratecrate = game.add.sprite(300,50,"chopper");crate.scale.setTo(-0.5);crate.anchor.setTo(0.5,0.5);crate.attached = false;// Define Physicsgame.physics.arcade.enable([chopper, this.floor, crate]);this.floor.body.immovable = true;this.floor.allowGravity - false;crate.body.bounce.y = 0.5;crate.body.gravity.y = 300;crate.collideWorldBounds = true;// setup the viewport cameragame.world.setBounds(0, 0, 1920, 320); game.camera.follow(chopper);game.camera.deadzone = new Phaser.Rectangle(0,0,480,320);this.cursors = game.input.keyboard.createCursorKeys();},update: function() {game.physics.arcade.collide(chopper, crate, this.chopperHit, null, this);game.physics.arcade.collide(crate, this.floor);chopper.body.velocity.x = 0;chopper.body.velocity.y = 0;if (this.cursors.up.isDown){chopper.body.velocity.y = -200;}else if (this.cursors.down.isDown){chopper.body.velocity.y = 200;}if (this.cursors.left.isDown){chopper.body.velocity.x = -200;}else if (this.cursors.right.isDown){chopper.body.velocity.x = 200;}if (crate.attached) {crate.x = chopper.x;crate.y = chopper.y+30;}},render: function() {game.debug.body(chopper);game.debug.body(crate); game.debug.body(this.floor);},chopperHit: function(body, bodyB, shapeA, shapeB, equation) {if (!crate.attached) { crate.x = chopper.x;crate.y = chopper.y+30;crate.body.gravity.y = 0;crate.attached = true;}}}var game = new Phaser.Game(480, 320, Phaser.AUTO);game.state.add("main", mainState);game.state.start("main");</script>   </head>   <body>     </body></html>
Link to comment
Share on other sites

Looks like I was able to do this with a group, and having each group with an "attached" attribute.

Phaser group collisions are nice enough to know what element in the group is being collided and I'm able to make that one follow the chopper sprite. It's a bit more work, since I need to have a check in the update function for any in the entire group that has an "attached" of true, and then set that to the chopper location... I need to put more work into only allowing one to be picked up though... 

In the end, it works, but I'm still not sure if how I did it is the best way to handle it.

 

Here's the latest code. I added a new sprite, 25x25 blue box, for the crates.

I'm open to suggestions for improvement. Thanks.

 

<!DOCTYPE html><html>   <head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" /><title>PickUp Test</title><script type="text/javascript" src="js/phaser.min.js"></script><style>body {padding: 0px;margin: 0px;background: black;}</style>  <script>var chopper;  var crates;var mainState = {init: function() {this.stage.backgroundColor = "#111111";},preload: function() {game.load.image("chopper", "assets/images/player.png");game.load.image("crate", "assets/images/crate.png");},create: function() {game.physics.startSystem(Phaser.Physics.ARCADE);// create the groundvar floorBmp = game.add.bitmapData(480,5);floorBmp.ctx.fillStyle="#AAAAAA";floorBmp.ctx.fillRect(0,0,480,5);this.floor = game.add.sprite(0,315,floorBmp); // Add chopperchopper = game.add.sprite(game.world.centerX, game.world.centerY, "chopper");chopper.anchor.setTo(0.5);chopper.scale.setTo(1,-0.25);chopper.collideWorldBounds = true;// Add cratescrates = game.add.group(); crates.enableBody = true;for (var i=0; i<5; i++) {var c = crates.create(100+ (i*80),290,"crate");c.body.bounce.y = 0.5;c.body.gravity.y = 300;c.collideWorldBounds = true;c.name = "crate" + i;c.anchor.setTo(0.5);}crates.enableBodyDebug = true;crates.setAll("attached", false);// Define Physicsgame.physics.arcade.enable([chopper, this.floor, crates]);this.floor.body.immovable = true;this.floor.allowGravity - false;// setup the viewport cameragame.world.setBounds(0, 0, 480, 320); game.camera.follow(chopper);game.camera.deadzone = new Phaser.Rectangle(0,0,480,320);this.cursors = game.input.keyboard.createCursorKeys();},update: function() {game.physics.arcade.collide(chopper, crates, this.chopperHit, null, this);game.physics.arcade.collide(crates, this.floor);chopper.body.velocity.x = 0;chopper.body.velocity.y = 0;if (this.cursors.up.isDown){chopper.body.velocity.y = -200;}else if (this.cursors.down.isDown){chopper.body.velocity.y = 200;}if (this.cursors.left.isDown){chopper.body.velocity.x = -200;}else if (this.cursors.right.isDown){chopper.body.velocity.x = 200;}crates.forEach(function(i) {if (i.attached) {i.x = chopper.x;i.y = chopper.y + 30;}});},render: function() {game.debug.body(chopper);//game.debug.body(crates); game.debug.body(this.floor);crates.forEach(function(i) {game.debug.body(i);});},chopperHit: function(body, crateHit) {console.log("HIT CRATE = " + crateHit.name);crateHit.attached = true;crateHit.x = chopper.x;crateHit.y = chopper.y+30;crateHit.body.gravity.y = 0;}}var game = new Phaser.Game(480, 320, Phaser.AUTO);game.state.add("main", mainState);game.state.start("main");</script>   </head>   <body>     </body></html>
Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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