Jump to content

Issue shooting bullet from same angle as weapon


callidus
 Share

Recommended Posts

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

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 by Sky Alpha
Link to comment
Share on other sites

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

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. 

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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