callidus Posted April 27, 2020 Share Posted April 27, 2020 I have a cannon and bubbles that spawn at random points from the top of the screen. The cannon currently faces the bubble that's closest to it. The issue is the bullet itself shoots in a straight line regardless of the angle of the cannon, I want the bullet to shoot in the same angle. I've tried using velocityFromAngle and such but can't seem to figure it out. If you look at my fireCannon() code on line 130 you can see my attempts commented out. Thank you for any assistance. // Initialize the Phaser Game object and set default game window size const game = new Phaser.Game(325, 600, Phaser.CANVAS, '', { preload: preload, create: create, update: update,}) scaleRatio = window.devicePixelRatio / 3; //LEAVE SCALLING WILL BE IMPLEMENTED AT END //Scaling Examples //game.world.height - 50 //game.add.sprite(game.world.centerX, game.world.centerY, 'mySprite'); function preload (){ game.load.spritesheet('buttons', 'assets/buttons/spritesheetSmall.png', 61,54,8); game.load.spritesheet('bubbles', 'assets/bubbles/bubbleSpritesheet.png', 93,93,6); game.load.image('finishLine', 'assets/finishLine.png'); game.load.image('bullet','assets/bullet.png'); game.load.image('cannon','assets/cannon/cannon.png'); } function create () { game.physics.startSystem(Phaser.Physics.ARCADE); //VARIABLES //bubbles CBUBBLE = 0; //current target bubble BVALUES = []; //contains all the bubble values VELOCITY = 20; //Speed of the bubbles BUBBLESPAWNTIME = 5; BUBBLEBULLETSPEED = -700; //cannon TARGET = 0; TARGETx = 0; TARGETy = 0; ROTATION = 0; //button currButton = 0; //0 = 2, 1 = 3, etc. Index represents number on numpad //ENVIRONMENT game.stage.backgroundColor = "#D076E7" mainButton = game.add.button(game.width/2 - 30, 500, 'buttons', buttonPressOne, this, 0 , 0, 0, 0); bubbles = game.add.group(); bubbles.enableBody = true; bubbles.createMultiple(50,'bubbles'); cannon = game.add.sprite(game.width/2 , 415, 'cannon'); cannon.anchor.setTo(0.5,0.5); cannonBullet = game.add.group(); cannonBullet.enableBody = true; cannonBullet.physicsBodyType = Phaser.Physics.ARCADE; cannonBullet.createMultiple(1, 'bullet'); cannonBullet.setAll('anchor.x', 0.5); cannonBullet.setAll('anchor.y', 0.5); cannonBullet.setAll('outOfBoundsKill', true); cannonBullet.setAll('checkWorldBounds', true); //CONTROLS cursors = game.input.keyboard.createCursorKeys(); game.input.keyboard.addKeyCapture([ Phaser.Keyboard.SPACEBAR ]); //TIME BASED EVENTS game.time.events.loop(Phaser.Timer.SECOND * BUBBLESPAWNTIME, spawnCoord, this); //INITIAL SPAWN spawnCoord() } function update () { //CENTERS SCREEN game.scale.pageAlignHorizontally = true; game.scale.pageAlignVertically = true; game.scale.refresh(); //CURR BUBBLE VALUE if(bubbles.countLiving() > 0){ currValue = BVALUES[CBUBBLE]; } else{ currValue = 0; } //CANNONS DIRECTION if(bubbles.countLiving() > 0){ TARGETx = bubbles.getAt(0).x; TARGETy = bubbles.getAt(0).y; ROTATION = game.math.angleBetween(cannon.x, cannon.y, TARGETx, TARGETy) cannon.angle = ROTATION; } else{ TARGET = 0; cannon.angle = TARGET; } game.physics.arcade.overlap(cannonBullet, bubbles, popBubble); } //BUTTON HANDLERS-------------------- function buttonPressOne(){ fireCannon() } //SPAWNING BUBBLES-------------------- function spawnCoord(){ //random frame (color) and coordinate for each bubble xCoord = game.rnd.integerInRange(93,game.world.width-93); frame = game.rnd.integerInRange(0,5); createBubble(xCoord,frame); } function createBubble(xCoord, frame){ bubbleInstance = bubbles.getFirstDead(); bubbleInstance.reset(xCoord,0); bubbleInstance.anchor.setTo(0.5, 0.5); bubbleInstance.body.velocity.y = VELOCITY; bubbleInstance.frame = frame; } //CANNON VARIABLE-------------------- function fireCannon() { if (bubbles.countLiving() > 0){ bubbleBullet = cannonBullet.getFirstExists(false); if (bubbleBullet) { bubbleBullet.enableBody; bubbleBullet.reset(cannon.x - 2.5, cannon.y - 50); bubbleBullet.anchor.setTo(0.5,0.5); bubbleBullet.rotation = cannon.rotation; //angle = game.math.angleBetween(cannon.x, cannon.y, bubbles.getAt(0).x, bubbles.getAt(0).y) //game.scene.physics.velocityFromAngle(angle, 700, bubbleBullet.body.velocity); bubbleBullet.body.velocity.y = BUBBLEBULLETSPEED; bubbleBullet.outOfBoundsKill = true; } } } function popBubble(bulletInstance, bubbleInstance){ bubbleInstance.kill() } Link to comment Share on other sites More sharing options...
Sky Alpha Posted April 29, 2020 Share Posted April 29, 2020 (edited) Hey @callidus, You can use the Phaser included Mathematics to set an Angle between your target (Mouse Pointer) and your Cannon like this. // Sets the Rotation of a Sprite to a given angle. this.rotation = Phaser.Math.Angle.Between( this.shooter.x, this.shooter.y, this.target.container.x, this.target.container.y ); This is a Class called Arrow that I use to hit a given target. this.rotation is a Phaser Graphics Property. Here is the Full implementation export class Arrow extends Phaser.GameObjects.Graphics { constructor(scene, x, y, shooter, target, width = 7, height = 1) { super(scene, x, y, width, height); this.x = x; this.y = y; this.scene = scene; this.shooter = shooter; this.target = target; scene.add.existing(this); this.rotateToTarget(width, height); } // Rotates the arrow to the Target rotateToTarget(width, height) { this.clear(); this.lineStyle(1, 0x000000, 1); this.beginPath(); this.moveTo(0, 0); this.lineTo(width, height); // this.lineStyle(1, color, 1); // Debug line this.closePath(); this.strokePath(); // Rotates player to face towards reticle this.rotation = Phaser.Math.Angle.Between( this.shooter.x, this.shooter.y, this.target.container.x, this.target.container.y ); } // Shoot the arrow to the Target. shoot() { let distance = Phaser.Math.Distance.Between( this.shooter.x, this.shooter.y, this.target.container.x, this.target.container.y ); this.scene.tweens.add({ targets: this, x: { value: this.target.container.x, ease: this.shooter.y >= this.target.container.y ? "Quadratic" : "Quad", }, y: { value: this.target.container.y, ease: this.shooter.y < this.target.container.y ? "Quadratic" : "Quad", }, duration: distance * 2, onComplete: () => { this.target.takeDamage(this.shooter); this.destroy(); }, }); } } Edited April 29, 2020 by Sky Alpha callidus 1 Link to comment Share on other sites More sharing options...
callidus Posted April 30, 2020 Author Share Posted April 30, 2020 Thank you your implementation has been helpful. I noticed you used tweens, is there any way to do this with velocity? I'd prefer to implement the bullets movement with an x and y velocity based on the angle between the cannon and the bullet. Link to comment Share on other sites More sharing options...
callidus Posted May 1, 2020 Author Share Posted May 1, 2020 After looking through the docs I realized there's a function that solves my problem. I called: game.physics.arcade.moveToObject(bubbleBullet, bubbles.getAt(0), 800); this grabs the first spawned bubble (therefore closest to the cannon) and has the bullet move towards it. Sky Alpha 1 Link to comment Share on other sites More sharing options...
Recommended Posts