任何人都可以在一般层面上建议如何使用Phaser 3实现以下目标:

我需要能够以更新的方式控制敌人精灵的瓷砖或地形属性. idea 是更新角色动画,如果它在水上或陆地.我试过console.log(this.streetLayer.getTileAtWorldXY(this.enemy.x, this.enemy.y, true);,但world map在update()方法中未定义.或者有更简单的方法来实现这一点?我的游戏是一个自上而下的RPG.下面是完整的代码:

import "./style.css";
import Phaser from "phaser";

const sizes = {
  width: 960,
  height: 640,
};
let last_direction;
let enemy_terrain;


class GameScene extends Phaser.Scene {
  constructor() {
    super("scene-game");
  }

  preload() {
    // Load spritesheet for the protagonist
    this.load.spritesheet('protagonist', '/assets/mainCH.png', { frameWidth: 100, frameHeight: 100 });
    this.load.spritesheet('enemy', '/assets/waterspirit.png', { frameWidth: 150, frameHeight: 150 });
    
  
    // Load tileset and tilemap
    this.load.tilemapTiledJSON('map', '/assets/maps/testmap.json');

    this.load.image('tiles', 'assets/maps/terrain.png');
  }

  create() {
    console.log('create method executed');
    this.protagonist = this.physics.add.sprite(200, 550, 'protagonist');
    this.enemy = this.physics.add.sprite(200, 100, 'enemy');
    
    // Set up properties for the enemy
    this.enemy.speed = 100; // Adjust the speed as needed
    this.protagonist.setDepth(1);
    this.enemy.setDepth(1);
    const map = this.make.tilemap({ key: 'map' });



    // Add tilesets for each layer
    const Tileset = map.addTilesetImage('test-tiles', 'tiles');
  
    
    // Create layers from tilemap data
    const streetLayer = map.createLayer('street', Tileset, 0, 0); 
    const waterLayer = map.createLayer('water', Tileset, 0, 0); 

    console.log('Street Layer:', streetLayer); // Log the street layer object to check if it's properly created
    console.log('Water Layer:', waterLayer); // Log the street layer object to check if it's properly created
  
    // Adjust the depth of layers as needed
    streetLayer.setDepth(0);
    waterLayer.setDepth(0);
    map.setCollisionBetween(188, 188, true, waterLayer);
    map.setCollisionBetween(0, 0, true, streetLayer);

 /////////////////////////BUNCH OF ANIMATIONS START///////////////////////////////////
 /////////////////////////BUNCH OF ANIMATIONS END///////////////////////////////////
    this.cursors = this.input.keyboard.createCursorKeys();
    // Enable physics for the protagonist
    this.physics.world.setBounds(0, 0, map.widthInPixels, map.heightInPixels);
    this.physics.add.collider(this.protagonist, streetLayer);
    this.physics.add.collider(this.enemy, streetLayer);
 
  
    if(this.enemy.y >= 350){
        enemy_terrain = "street"
      this.enemy.play('enemy_move_street');
  
     } else {
        enemy_terrain = "water"
    
     }
 
 // Play the appropriate animation based on the collision result
 if (enemy_terrain == "street") {
     this.enemy.play('enemy_move_street');
     console.log("enemy on street");
  
 } else {
     this.enemy.play('enemy_move_water');
     console.log("enemy on water");
 }


 
  }

  update() {
    // Reset velocity
    this.protagonist.setVelocity(0);
   
    // Handle keyboard input
        XXXX
    this.physics.moveToObject(this.enemy, this.protagonist, this.enemy.speed);
 // Call updateInfo method
    this.updateInfo();
  }
  updateInfo() {
    let timedEvent = this.time.addEvent({ 
      delay: 1000, // once every second = 1000ms
      callback: () => console.log(this.waterLayer.getTileAtWorldXY(this.enemy.x, this.enemy.y, true)), 
      loop: true });
}
}


const config = {
  type: Phaser.WEBGL,
  width: sizes.width,
  height: sizes.height,
  canvas: gameCanvas,
  physics: {
    default: "arcade",
    arcade: {
      debug: true, // Set to true to enable debugging (displays collision bodies)
    },
  },
  scene: [GameScene],
};

const game = new Phaser.Game(config);

推荐答案

你不知道你的代码(the relevant parts of the code),因为你分享的太少了.我只能说,你可以简单地在create函数中添加一个计时器.类似于这样:

   let timedEvent = this.time.addEvent({ 
       delay: 1000, // once every second = 1000ms
       callback: () => console.log(this.streetLayer.getTileAtWorldXY(this.enemy.x, this.enemy.y, true), 
       loop: true });

这将每秒输出tile/properties.

我不建议将其用于生产,但在不了解代码的相关部分的情况下,这是一个解决方案,应该工作(如果代码中没有其他错误).判断browserConsole以确定).

如果这仍然是undefined/null,则该层可能无效,敌人的坐标可能是null或在 map 之外.

Update:

因为你发布了你的代码,我可以看到真正的问题,this.waterLayer/this.streetLayer没有定义,他们创建为常数.

The solution is:create函数的末尾定义this.streetLayer(或this.waterLayer),如下所示:

create(){
    // ... your current code
    this.streetLayer = streetLayer;
    //this.waterLayer = waterLayer;
}

这个范围的问题应该得到解决.

像这样修复代码,上面提到的time的"解决方案"就不再需要了.

Javascript相关问答推荐

在卡信息之间切换

如何为GrapesJS模板编辑器创建自定义撤销/重复按钮?

通过使用100%间隔时间来代表我们还剩多少时间来倒计时

硬币兑换运行超时

使用Java脚本根据按下的按钮更改S文本

阿波罗返回的数据错误,但在网络判断器中是正确的

JS—删除对象数组中对象的子对象

保持物品顺序的可变大小物品分配到平衡组的算法

如何在ASP.NET中使用Google Charts API JavaScript将条形图标签显示为绝对值而不是负值

使用ThreeJ渲染的形状具有抖动/模糊的边缘

DOM不自动更新,尽管运行倒计时TS,JS

将异步回调转换为异步生成器模式

是否可以将Select()和Sample()与Mongoose结合使用?

背景动画让网站摇摇欲坠

判断函数参数的类型

如何使用抽屉屏幕及其子屏幕/组件的上下文?

表单数据中未定义的数组键

计算对象数组中属性的滚动增量

使用props 将VUE 3组件导入JS文件

在此div中添加一个类,并在一段时间后在Java脚本中将其删除