一旦箭头与目标碰撞,如何使箭头停止?

问题描述 投票:1回答:1

我正在使用JavaScript和Phaser 3框架创建游戏。我已经编辑了目标的点击框,但是当箭头被点击时,它刚从屏幕上掉下来。我如何像现实生活中的那样使箭头粘住?

var physicsConfig = {
  default: 'arcade',
  arcade: {
    debug: false //CHANGE THIS TO TRUE TO SEE LINES
  }
}

var config = {
  type: Phaser.AUTO,
  width: 800,
  height: 600,
  physics: physicsConfig,
  scene: {
    preload: preload,
    create: create,
    update: update,
    render: render
  }
};

//Start the game
var game = new Phaser.Game(config);

function preload() {
  this.load.image('sky', 'assets/sky.png');
  this.load.spritesheet('archer', 'assets/archer_sprites.png', {
    frameWidth: 128,
    frameHeight: 128
  });
  this.load.image('target', 'assets/target.png');
  this.load.image('ground', 'assets/ground.png');
  this.load.image('rings', 'assets/rings.png');
  this.load.image('arrow', 'assets/arrow.png');
  this.load.audio('arrow_shot', 'assets/arrow_shooting.mp3');

}

function create() {
  //Load all the images
  this.add.image(400, 300, 'sky');
  this.add.image(200, 200, 'ground');
  this.add.image(300, 100, 'rings');
  //Create the archer/player
  this.player = this.physics.add.sprite(100, 410, 'archer');
  this.player.setBounce(0.2);
  this.player.setCollideWorldBounds(true);
  //Shooting animation
  this.anims.create({
    key: 'shoot',
    frames: this.anims.generateFrameNumbers('archer', {
      start: 0,
      end: 4
    }),
    frameRate: 20,
    repeat: 0
  });

  //Create the target
  this.target = this.physics.add.sprite(530, 365, 'target');
  this.target.setSize(115, 95).setOffset(70, 130); //TARGET HITBOX
  this.target.enableBody = true;
  this.target.setImmovable();
  //Create an array for arrows later
  this.arrows = [];
  //Get keypresses
  this.cursors = this.input.keyboard.createCursorKeys();
  //Assign input for spacebar
  this.spacebar = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE);
  //Play sound when the arrow is shot
  this.arrowSound = this.sound.add('arrow_shot');

}

function update() {
  //Declare constants for movement
  const playerMoveAmt = 200;
  const arrowMoveAmt = 1750;
  this.player.setDrag(2000);

  //Rotation of the player
  if (this.cursors.up.isDown && this.player.angle > -45) {
    this.player.angle -= 1;
  }
  if (this.cursors.down.isDown && this.player.angle < 0) {
    this.player.angle += 1;
  }

  //Shooting with the spacebar
  if (Phaser.Input.Keyboard.JustDown(this.spacebar)) {
    //Animate the shooting
    this.player.anims.play('shoot', true);
    //Arrow shooting
    var arrow = this.physics.add.sprite(this.player.x, (this.player.y + 20), 'arrow');
    arrow.enableBody = true;
    arrow.body.immovable = false;
    arrow.setGravityY(4000); //Gravity will affect the arrows
    arrow.angle = this.player.angle //Angle the arrows with the player
    arrow.setVelocityX(arrowMoveAmt);
    arrow.setVelocityY((this.player.angle * 50));
    this.arrows.push(arrow);
    this.arrowSound.play();
  }

}

function render() {}
body {
  margin: 0;
}
<script src="//cdn.jsdelivr.net/npm/[email protected]/dist/phaser.js"></script>

[我尝试在没有点击框的情况下执行此操作,并在箭头通过目标的x值后将其速度设置为0,但我需要正确地进行碰撞处理。

javascript collision-detection game-engine game-physics phaser-framework
1个回答
1
投票

我已经找到一种解决方案,可以完成您想要的行为:

  • 首先,我们检查是否从左侧触摸了target sprite

  • 如果条件评估为true,我们将箭头sprite重力和速度的值设置为0;

您可以使用此代码段(它在this.arrowSound.play()之后开始):

function update () {   
    //Declare constants for movement
    const playerMoveAmt = 200;
    const arrowMoveAmt = 1500;
    this.player.setDrag(2000); 

    //Move the player left or right
    if (this.cursors.right.isDown) 
    this.player.setVelocityX(playerMoveAmt);
    if (this.cursors.left.isDown)
    this.player.setVelocityX(-playerMoveAmt);

    //Rotation of the player
    if (this.cursors.up.isDown && this.player.angle > -45) {
        this.player.angle -= 1;}
    if (this.cursors.down.isDown && this.player.angle < 0) {
        this.player.angle += 1;}

    //Shooting with the spacebar
    if (Phaser.Input.Keyboard.JustDown(this.spacebar)) {
        //Animate the shooting
        this.player.anims.play('shoot', true);
        //Arrow shooting
        let arrow = this.physics.add.sprite(this.player.x, (this.player.y + 20), 'arrow');
        arrow.enableBody = true;
        arrow.body.immovable = false;
        arrow.setGravityY(4000);    //Gravity will affect the arrows
        arrow.angle = this.player.angle //Angle the arrows with the player
        arrow.setVelocityX(arrowMoveAmt);
        arrow.setVelocityY((this.player.angle * 50));
        this.arrows.push(arrow);
        this.arrowSound.play();
    } else if(this.target.body.touching.left) {

        var i;

        for (i = 0; i < this.arrows.length; i++) {
          newArrows = this.arrows[i];

          newArrows.setGravityY(0);
          newArrows.setVelocityX(0);
          newArrows.setVelocityY(0);
        } 
    }
}

我也建议您减小箭头sprite Hitbox的大小,以便看起来它实际上击中了[[target sprite。您可以通过设置debug: true来检查当前的hitbox的大小,如下所示:

var physicsConfig = { default: 'arcade', arcade: { debug: true } }
让我知道是否有帮助,请确保接受我的回答!
© www.soinside.com 2019 - 2024. All rights reserved.