I want to create a game where enemies spawn, fly toward the player's ship, and stick to the side of it. The player can then rotate the ship and the stuck enemies will rotate with it.
The way I have this working now, the ship and the enemies are each part of a group and a collision group; when an enemy collides with the ship, it leaves its old group and collision group and joins those of the ship. The player is then able to rotate the ship's group, including the stuck enemies.
But from there, things get weird. If you rotate the ship 90 degrees to the left and then stick an enemy to its right edge, the enemy vanishes and appears at the top edge of the ship. Try to stick another enemy to the same point on the right edge, and it too will teleport to the top of the circle, colliding with the other enemy there. Also, enemies that have been "stuck" won't collide with those that have not.
If I move everything into one collision group, rotating the ship with enemies stuck to it will be reflected onscreen but not in the physics. You can spin the ship around all you like, and the enemies stuck to it will appear to rotate around it, but the non-stuck enemies will act as if they aren't moving.
How can I get a group of physics bodies to act like one body, rotating together and colliding with other objects in the gameworld? Code is below; try it out here.
var game = new Phaser.Game("100%", "100%", Phaser.AUTO, '', { preload: preload, create: create, update: update, render: render });
var debug = false;
var ship, enemy, enemies, shipCollisionGroup, enemyCollisionGroup, spawnEnemy;
function preload() {
game.load.image('ship', 'simple-ship.svg');
game.load.image('enemy', 'square-enemy.svg');
}
function create() {
game.physics.startSystem(Phaser.Physics.P2JS);
game.physics.p2.setImpactEvents(true);
game.physics.p2.updateBoundsCollisionGroup();
game.stage.backgroundColor = '#1C1C1C';
shipCollisionGroup = game.physics.p2.createCollisionGroup();
enemyCollisionGroup = game.physics.p2.createCollisionGroup();
enemies = game.add.group();
enemies.enableBody = true;
enemies.physicsBodyType = Phaser.Physics.P2JS;
ship = game.add.sprite(200, 200, 'ship');
shipGroup = game.add.group();
shipGroup.enableBody = true;
shipGroup.addChild(ship);
shipGroup.x = 200;
shipGroup.y = 200;
shipGroup.pivot.x = 200;
shipGroup.pivot.y = 200;
spawn();
game.physics.p2.enable([ship, enemies], debug);
ship.body.setCircle(200);
ship.body.setCollisionGroup(shipCollisionGroup);
ship.body.collides([shipCollisionGroup, enemyCollisionGroup], collision);
cursors = game.input.keyboard.addKeys({
'left': Phaser.KeyCode.A,
'right': Phaser.KeyCode.D,
'space': Phaser.KeyCode.SPACEBAR
});
}
function update() {
ship.body.setZeroVelocity();
ship.body.setZeroRotation();
if (cursors.left.isDown) {
shipGroup.rotation -= .1;
} else if (cursors.right.isDown) {
shipGroup.rotation += .1;
} else if (cursors.space.isDown) {
spawnEnemy = true;
} else if (cursors.space.isUp && spawnEnemy) {
spawn();
spawnEnemy = false;
}
}
function render() {
game.debug.text('A and D to rotate; spacebar to spawn enemies', 32, 32);
}
function collision(shipBody, impactorBody) {
var enemy = impactorBody.sprite;
// enemies.remove(enemy);
shipGroup.addChild(enemy);
enemy.body.removeCollisionGroup(enemyCollisionGroup);
enemy.body.setCollisionGroup(shipCollisionGroup);
enemy.body.setZeroVelocity();
enemy.body.setZeroRotation();
}
function spawn() {
var enemy = enemies.create(700, 200, 'enemy');
enemy.body.velocity.x = -100;
enemy.body.setCollisionGroup(enemyCollisionGroup);
enemy.body.collides([shipCollisionGroup, enemyCollisionGroup]);
enemy.body.sprite = enemy;
enemy.anchor.x = 0.5;
enemy.anchor.y = 0.5;
}