Jump to content

Graphics, Sprite and game.physics.arcade.collide


wog
 Share

Recommended Posts

Hi,

First, the Arcade physics system can only manage collisions between "rectangles" (for performance), so if you want accurate collision detection with your ground, you will have to use the P2 physics system ; you will then be able to define a polygon as the physic body of your ground. There is an example here : http://examples.phaser.io/_site/view_full.html?d=p2%20physics&f=load+polygon+2.js&t=load%20polygon%202

About the fact that you can't collide ground and bullet, could you be more precise ? or show some code ?

Link to comment
Share on other sites

This is my code. I want when I shot bullet collision do with bullet and graphics ground. Not sprite ground.

 

function Play() {}    PlayState = {    preload: function() {        this.game.load.image('Trunk', 'assets/trunk.png');        this.game.load.image('landskype', 'assets/background.png');        this.game.load.image('bullet', 'assets/bullet.png');        this.game.load.image('ground', 'assets/background.png');        this.game.load.spritesheet('explosion', '/assets/explosion.png', 128, 128);        // load the physics data json        game.load.physics('physicsData', 'json/ground.json');    },    create: function() {        // Set stage background color        this.game.stage.backgroundColor = 0x4488cc;        // Define constants        this.SHOT_DELAY = 300; // milliseconds (10 bullets/3 seconds)        this.BULLET_SPEED = 800; // pixels/second        this.NUMBER_OF_BULLETS = 1;        this.GRAVITY = 980; // pixels/second/second        // Create an object representing our gun        this.gun = this.game.add.sprite(50, this.game.height - 332, 'bullet');        this.points = this.groundGenerator();        this.poly = new Phaser.Polygon(this.points);        this.graphics = this.game.add.graphics(0, 0);        this.graphics.beginFill(0x006633);        this.graphics.drawPolygon(this.poly.points);        this.graphics.endFill();        // Set the pivot point to the center of the gun        this.gun.anchor.setTo(0.5, 0.5);        // Create an object pool of bullets        this.bulletPool = this.game.add.group();        for(var i = 0; i < this.NUMBER_OF_BULLETS; i++) {            // Create each bullet and add it to the group.            var bullet = this.game.add.sprite(0, 0, 'bullet');            this.bulletPool.add(bullet);            // Set its pivot point to the center of the bullet            bullet.anchor.setTo(0.5, 0.5);            // Enable physics on the bullet            this.game.physics.enable(bullet, Phaser.Physics.ARCADE);            // Set its initial state to "dead".            bullet.kill();        }        // Turn on gravity        game.physics.arcade.gravity.y = this.GRAVITY;        // Create some ground        this.ground = this.game.add.group();        for(var x = 0; x < this.game.width; x += 32) {            // Add the ground blocks, enable physics on each, make them immovable            var groundBlock = this.game.add.sprite(x, this.game.height - 50, 'ground');            this.game.physics.enable(groundBlock, Phaser.Physics.ARCADE);            groundBlock.body.immovable = true;            groundBlock.body.allowGravity = false;            this.ground.add(groundBlock);        }        // Create a group for explosions        this.explosionGroup = this.game.add.group();        // Simulate a pointer click/tap input at the center of the stage        // when the example begins running.        this.game.input.activePointer.x = this.game.width/2;        this.game.input.activePointer.y = this.game.height/2 - 100;        // Show FPS        this.game.time.advancedTiming = true;        this.fpsText = this.game.add.text(            20, 20, '', { font: '16px Arial', fill: '#ffffff' }        );    },    update: function() {        if (this.game.time.fps !== 0) {            this.fpsText.setText(this.game.time.fps + ' FPS');        }        // Check if bullets have collided with the ground        this.game.physics.arcade.collide(this.bulletPool, this.ground, function(bullet, ground) {            // Create an explosion            this.getExplosion(bullet.x, bullet.y);            // Kill the bullet            bullet.kill();        }, null, this);        // Rotate all living bullets to match their trajectory        this.bulletPool.forEachAlive(function(bullet) {            bullet.rotation = Math.atan2(bullet.body.velocity.y, bullet.body.velocity.x);        }, this);        // Aim the gun at the pointer.        // All this function does is calculate the angle using        // Math.atan2(yPointer-yGun, xPointer-xGun)        this.gun.rotation = this.game.physics.arcade.angleToPointer(this.gun);        // Shoot a bullet        if (this.game.input.activePointer.isDown) {            this.shootBullet();        }    },    render: function() {        this.game.debug.text(this.game.input.x + ' x ' + this.game.input.y, 32, 32);    },    clickListener: function() {//      this.game.state.start('gameover');    },    shootBullet: function() {        // Enforce a short delay between shots by recording        // the time that each bullet is shot and testing if        // the amount of time since the last shot is more than        // the required delay.        if (this.lastBulletShotAt === undefined) this.lastBulletShotAt = 0;        if (this.game.time.now - this.lastBulletShotAt < this.SHOT_DELAY) return;        this.lastBulletShotAt = this.game.time.now;        // Get a dead bullet from the pool        var bullet = this.bulletPool.getFirstDead();        // If there aren't any bullets available then don't shoot        if (bullet === null || bullet === undefined) return;        // Revive the bullet        // This makes the bullet "alive"        bullet.revive();        // Bullets should kill themselves when they leave the world.        // Phaser takes care of this for me by setting this flag        // but you can do it yourself by killing the bullet if        // its x,y coordinates are outside of the world.        bullet.checkWorldBounds = true;//        bullet.outOfBoundsKill = true;        // Set the bullet position to the gun position.        bullet.reset(this.gun.x, this.gun.y);        bullet.rotation = this.gun.rotation;        // Shoot it in the right direction        bullet.body.velocity.x = Math.cos(bullet.rotation) * this.BULLET_SPEED;        bullet.body.velocity.y = Math.sin(bullet.rotation) * this.BULLET_SPEED;    },    getExplosion: function(x, y) {        // Get the first dead explosion from the explosionGroup        var explosion = this.explosionGroup.getFirstDead();        // If there aren't any available, create a new one        if (explosion === null) {            explosion = this.game.add.sprite(0, 0, 'explosion');            explosion.anchor.setTo(0.5, 0.5);            // Add an animation for the explosion that kills the sprite when the            // animation is complete            var animation = explosion.animations.add('boom', [0,1,2,3], 60, false);            animation.killOnComplete = true;            // Add the explosion sprite to the group            this.explosionGroup.add(explosion);        }        // Revive the explosion (set it's alive property to true)        // You can also define a onRevived event handler in your explosion objects        // to do stuff when they are revived.        explosion.revive();        // Move the explosion to the given coordinates        explosion.x = x;        explosion.y = y;        // Set rotation of the explosion at random for a little variety        explosion.angle = this.game.rnd.integerInRange(0, 360);        // Play the animation        explosion.animations.play('boom');        // Return the explosion itself in case we want to do anything else with it        return explosion;    },    groundGenerator: function (){        var points = [];        points.push(new Phaser.Point(0, this.game.height));        for(var x = 0; x < this.game.width; x+=this.getRandomInt(10, 200)) {            var Yposition = this.getRandomInt(this.game.height/2+200, this.game.height/2-100);//            console.log(x, Yposition);            points.push(new Phaser.Point(x, Yposition));        }        points.push(new Phaser.Point(x, this.game.height/2));        points.push(new Phaser.Point(this.game.width, this.game.height));        return points;    },    getRandomInt: function(min, max) {        return Math.floor(Math.random() * (max - min + 1)) + min    }  };
Link to comment
Share on other sites

Unfortunately, like it is said in the doc (http://docs.phaser.io/Phaser.Physics.Arcade.html#collide), arcade.collide() work with Sprite, Group, or Tilemap Layer objects, but not with Graphics objects.
I saw that you create a this.ground group containing blocks and, obviously, the bullets collide with it, not with the graphics.

 

So first, you will have to stop using this group.

Then, you can create a sprite that uses the Graphics you have drawn (see here: http://www.html5gamedevs.com/topic/6476-collision-with-gameaddgraphics-and-a-sprite/) ; thus you will have something that can be used for collision.

But then, like I said in my first reply, Arcade physics system will only allow you to collide using "rectangles" ; even if you create a Sprite with your graphics, the physic body of this sprite can only be a rectangle, and that's not what you want.

So you will have to stop using Arcade physics system, and instead use P2 physics system. This one will allow you to give your sprite a physic body that is a polygon : you will juste have to assign to the sprite's body the same points you used to create your graphics. The example I gave you in my first post (http://examples.phaser.io/_site/view_full.html?d=p2%20physics&f=load+polygon+2.js&t=load%20polygon%202) shows how to do that.

 

Your bullets will then be able to collide with the physic body associated to your sprite (itself created from your graphics), and you will see them colliding with what is drawn, because the shape of the physic body and the shape of the graphics are the same (they use the same points).

 

Are my explanations clear enough ?
 

Link to comment
Share on other sites

Yes your explanation good. But I don't want create images with ground. I want build ground dynamic.

I check some variant use bitmapData  but don't know how in bitmapData draw custom shape.

If I add bitmapData to sprite collision good work.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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