javascript 玩家精灵没有与游戏对象交互来改变Map

fivyi3re  于 2023-04-19  发布在  Java
关注(0)|答案(1)|浏览(84)

我对Phaser 3非常陌生,我一直在尝试创建一个玩家精灵与游戏对象碰撞的示例,将玩家带到另一个Map。现在我正在尝试让玩家将场景从房屋1切换到房屋2,但是当我把玩家精灵移到游戏对象上的时候,什么都没有发生。没有错误出现,告诉我什么东西没有定义。就好像改变场景的触发器从来不存在一样。
下面是Player.js文件

export default class Player {
  constructor(scene, x, y) {
    this.scene = scene;

    const anims = scene.anims;
        anims.create({
            key: 'turn1',
            frames: [ { key: 'dude', frame: 32 } ],
            frameRate: 20
        });
        anims.create({
            key: 'rdown',
            frames: anims.generateFrameNumbers('dude', { start: 0, end: 7 }),
            frameRate: 16,
            repeat: -1
        });
        anims.create({
            key: 'rright',
            frames: anims.generateFrameNumbers('dude', { frames: [ 8, 9, 10, 11, 12, 13, 14, 15 ] }),
            frameRate: 16,
            repeat: -1
        });
        anims.create({
            key: 'rup',
            frames: anims.generateFrameNumbers('dude', { frames: [ 16, 17, 18, 19, 20, 21, 21, 23 ] }),
            frameRate: 16,
            repeat: -1
        });
        anims.create({
            key: 'rleft',
            frames: anims.generateFrameNumbers('dude', { frames: [ 24, 25, 26, 27, 28, 29, 30, 31 ] }),
            frameRate: 16,
            repeat: -1
        });

    this.sprite = scene.physics.add.sprite(x, y, "dude", 0).setSize(16, 16).setOffset(0, 8);

    this.sprite.anims.play("rdown");

    this.gamepad = scene.input.gamepad.once('down', function (pad, button, index) {
        this.gamepad = pad;
    }, this);
  }

  update() {
    const gamepad = this.gamepad;
    const sprite = this.sprite;
    const speed = 90;
    const prevVelocity = sprite.body.velocity.clone();
    sprite.body.setVelocity(0);
    if (gamepad.right && gamepad.up) {
      sprite.body.setVelocityX(speed);
      sprite.body.setVelocityY(-speed);
    } else if (gamepad.right && gamepad.down) {
      sprite.body.setVelocityX(speed);
      sprite.body.setVelocityY(speed);
    } else if (gamepad.left && gamepad.up) {
      sprite.body.setVelocityX(-speed);
      sprite.body.setVelocityY(-speed);
    } else if (gamepad.left && gamepad.down) {
      sprite.body.setVelocityX(-speed);
      sprite.body.setVelocityY(speed);
    } else if (gamepad.left) {
      sprite.body.setVelocityX(-speed);
    } else if (gamepad.right) {
      sprite.body.setVelocityX(speed);
    } else if (gamepad.up) {
      sprite.body.setVelocityY(-speed);
    } else if (gamepad.down) {
      sprite.body.setVelocityY(speed);
    }
    sprite.body.velocity.normalize().scale(speed);
    if (gamepad.left) {
      sprite.anims.play("rleft", true);
    } else if (gamepad.left && gamepad.down) {
      sprite.anims.play("rleft", true);
    } else if (gamepad.left && gamepad.up) {
      sprite.anims.play("rleft", true);
    } else if (gamepad.right && gamepad.down) {
      sprite.anims.play("rright", true);
    } else if (gamepad.right && gamepad.up) {
      sprite.anims.play("rright", true);
    } else if (gamepad.up) {
      sprite.anims.play("rup", true);
    } else if (gamepad.right) {
      sprite.anims.play("rright", true);
    } else if (gamepad.down) {
      sprite.anims.play("rdown", true);
    } else {
      sprite.stopOnFrame(sprite.anims.currentAnim.getFrameAt(0))
    }
  }
}

下面是TestLevel.js文件

import Player from "./Player.js";
import TestRoom2 from "./TestRoom2.js";

export default class TestRoom extends Phaser.Scene {
  map;
  player;
    constructor() {
        super()
    }
    
    text;
    
    preload() {
        this.load.image('tiles', 'assets/tilemaps/tiles/house1.png');
        this.load.spritesheet('dude', 'assets/images/link.png', { frameWidth: 16, frameHeight: 24 });
        this.load.tilemapTiledJSON('map', 'assets/tilemaps/maps/TestRoom.json');
        this.load.image('exit', 'assets/tilemaps/tiles/exit.png');
    }
create()
{
    this.map = this.make.tilemap({ key: 'map' });
    this.map.landscape = this.map.addTilesetImage('house', 'tiles');
    this.map.createLayer("ground", [this.map.landscape], 0, 0);
    this.player = new Player(this, 128, 112);
    this.map.createLayer("above", [this.map.landscape], 0, 0);
    this.cameras.main.setSize(256,224);
    this.cameras.main.setBounds(0, 0, this.map.widthInPixels, this.map.heightInPixels);
    this.cameras.main.startFollow(this.player.sprite);
    this.cameras.main.setDeadzone(4,4);
    this.exited = this.physics.add.sprite(112, 220, 'exit').setOrigin(0,0);
    this.exitBox= this.physics.add.group({
            key: 'exit'});
    this.physics.add.collider(this.player, this.exitBox, function(player, exitBox) { this.scene.start('TestRoom2')});
  }
update() {
this.player.update();
    this.physics.collide(this.player, this.exitBox, function(player, exitBox) { this.scene.start('TestRoom2')});
    
  }
}

另一个Map是相同的,但是用TestRoom替换了TestRoom2。
这里的主要场景,有游戏的配置

import TestRoom from "./TestRoom.js";
import TestRoom2 from "./TestRoom2.js";

var config = {
    type: Phaser.AUTO,
    width: 256,
    height: 224,
    backgroundColor: '#000000',
    pixelArt: true,
    input: {
      gamepad: true
    },
    physics: {
        default: 'arcade',
        arcade: {
            gravity: { y: 0 },
            debug: true
        }
    },
    scene: TestRoom, TestRoom2
};
var game = new Phaser.Game(config);

一切正常。唯一不正常的是启动场景切换。
我能做些什么来解决这个问题?

5cnsuln7

5cnsuln71#

首先,config不是100%正确的,所有场景都必须在一个数组中(或稍后手动添加)。这里缺少方括号**[]**

var config = {
    type: Phaser.AUTO,
    width: 256,
    height: 224,
    ...
    scene: [TestRoom, TestRoom2] // <-- missing brackets
};

接下来,可以从update函数中删除***下面的行***,create函数中的collider就足够了:

// remove this line from "update" function
this.physics.collide(this.player, this.exitBox, function(player, exitBox) { this.scene.start('TestRoom2')});

create函数中,更改以下行以传递回调函数的上下文(链接到文档):

// added to parameters ( for details check documnetation )
this.physics.add.collider(this.player, this.exitBox, function(player, exitBox) { this.scene.start('TestRoom2')}, null, this);

或者使用 * 箭头函数(link to documentation)*:

// altered with to an arrow function
this.physics.add.collider(this.player, this.exitBox, (player, exitBox) => { this.scene.start('TestRoom2')});

我认为这应该涵盖了所有的错误,我可以找到,通过阅读代码。

**btw.:**检查浏览器控制台是否有错误,这有助于发现和解决问题。
更新:

我认为create函数中的行应该是exited而不是exitBox,因为 * 空 * 组永远不会与玩家冲突:

this.physics.add.collider(this.player, this.exited, (player, exited) => { this.scene.start('TestRoom2')});
  • 您可以查看this answer的示例,以查看播放器/场景切换的简短工作示例。

相关问题