昆图斯JavaScript编程GUI

Quintus JavaScript Programming GUI

本文关键字:编程 GUI JavaScript      更新时间:2023-09-26

在我的简单JavaScript/HTML 5游戏中,我有一个我认为是更新错误,我不知道如何修复。问题是没有真正的错误,它只是没有像我想要的那样响应代码。问题是,我希望屏幕GUI能够显示地图上杀死的敌人数量。到目前为止,我只使用了GUI。这是游戏的图片:

https://i.stack.imgur.com/0rx4d.png[这显示了屏幕上的3个敌人,右上角的GUI和玩家。]

现在的问题是,每当我杀死一个敌人,这个数字应该上升,但当然它没有。下面是我的代码:

window.addEventListener("load",function() {
var EKL1 = 0; // Enemies Killed Level 1
var Q = window.Q = Quintus()
        .include("Sprites, Scenes, Input, 2D, Anim, Touch, UI, TMX")
        .setup({ maximize: true })
        .controls().touch()
Q.Sprite.extend("Player",{
  init: function(p){
    this._super(p, {
      sprite: "player",
      sheet: "player",
      speed: 150,
      x: 410,
      y: 90
    });
    this.add('2d, platformerControls, animation');

    },
    step: function(dt){
      if(this.p.vx > 0){
        this.play("walk_right");
        this.p.direction = "right";
      } else if(this.p.vx < 0){
        this.play("walk_left");
        this.p.direction = "left";
      } else {
        this.play("stand_" + this.p.direction);// + this.p.direction > 0 ? "right" : "left");
      }
    }

});
Q.Sprite.extend("Enemy",{
  init: function(p) {
    this._super(p, { 
      sprite: "enemy",
      sheet: "enemy",
      vx: 100 
    });
    // Enemies use the Bounce AI to change direction 
    // whenver they run into something.
    this.add('2d, aiBounce');
    // Listen for a sprite collision, if it's the player,
    // end the game unless the enemy is hit on top
    this.on("bump.left,bump.right,bump.bottom",function(collision) {
      if(collision.obj.isA("Player")) { 
        //Q.stageScene("endGame",1, { label: "You Died" }); 
        collision.obj.destroy();
      }
    });
    // If the enemy gets hit on the top, destroy it
    // and give the user a "hop"
    this.on("bump.top",function(collision) {
      if(collision.obj.isA("Player")) { 
        this.destroy();
          collision.obj.p.vy = -300;
          //Increasing Enemies killed on destroy
          EKL1++;
        }
    });
  }
});
Q.scene("UIContainers", function(stage){
  var container = stage.insert(new Q.UI.Container({
      fill: "gray",
      border: 2,
      shadow: 3,
      shadowColor: "rgba(0,0,0,0.5)",
      y: Q.height/10,
      x: Q.width/1.25
    }));
   stage.insert(new Q.UI.Text({ 
      label: "Enemies killed: " + EKL1.toString(),
      color: "black",
      x: 0,
      y: 0
    }),container);
    container.fit(20,20);
});
Q.scene("level1", function(stage){
  stage.insert(new Q.Repeater({ asset: "background-wall.png", speedX: 0.5, speedY: 0.5 }));
  Q.stageScene("UIContainers", 1);
  stage.collisionLayer(new Q.TileLayer({ dataAsset: 'level.json', sheet: 'tiles' }));

  var player = stage.insert(new Q.Player());
  stage.insert(new Q.Enemy({ x: 700, y: 0 }));
  stage.insert(new Q.Enemy({ x: 800, y: 0 }));
  stage.insert(new Q.Enemy({ x: 500, y: 0 }));
  stage.add("viewport").follow(player);
});
Q.load("sprites.png, sprites.json, enemy.png, enemy.json, level.json, tiles.png, background-wall.png",  function(){
  Q.sheet("tiles","tiles.png", { tilew: 32, tileh: 32 });
  Q.compileSheets("sprites.png", "sprites.json");
  Q.compileSheets("enemy.png", "enemy.json");
  Q.animations("player", {
    walk_right: {frames: [0, 1, 2, 3], rate: 1 / 4, flip: false, loop: true }, 
    walk_left: {frames: [0, 1, 2, 3], rate: 1 / 4, flip:"x", loop: true },
    stand_right: {frames: [0], rate: 1 / 4, flip: false, loop: true},
    stand_left: {frames: [0], rate: 1 / 4, flip: "x", loop: true}

  });
  Q.stageScene("level1");
});


});

代码当然是用JavaScript编写的,但它是由Quintus游戏引擎运行的,可以在这里找到:http://html5quintus.com/

这就是我如何做到这一点,所以我制作了一个名为EKL1(敌人杀死第1级)的全局变量,返回/等于0。这个全局变量是在玩家与敌人发生碰撞的底部敌人函数中访问的。它说,如果玩家击中敌人的顶部,敌人被摧毁。所以我所做的就是在if语句中添加ekl1++来摧毁敌人。我将其转换为字符串并将其运行到控制台,它工作了!我杀死了一个敌人,它显示1,杀死了另一个,然后2,最后我杀死了最后一个,它显示3。当然,现在我必须在屏幕上的GUI中实现它。我做的是做一个UIContainer函数来保存所有GUI。我在容器上插入了一个标签你可以看到然后将标签文本设置为:

"敌人死亡:" + EKL1.toString();

在不需要字符串变量的情况下,将整型转换为字符串。我以为这能行,但当我杀死一个怪物时,它不会升起来。我相信这样做的原因是容器在屏幕上绘制了一次,所以它不会更新。也就是说当我杀死怪物时它不会更新容器。我不知道如何实现一个更新功能或其他东西来让这个正常工作。

如果有人知道解决这个问题的答案,请回复!我希望这不是一个很难解决的问题。

谢谢你的时间,

~Jackson Vandy

您的字符串"Enemies killed: " + ELK1.toString()将被评估,在此评估之后对ELK的任何更改都不会对标签产生影响。但是不用担心,有一个解决办法。Quintus拥有一个名为Q.state的"游戏状态"存储。还有一些事件处理,以防你的游戏状态发生变化。我在下面添加了一些代码,这应该给你一个大致的方向,在哪里修改你的代码。

var Q = // ...
// 1. after initialization of Q, create Q.state containing 'enemiesKilled'
Q.state.reset({
  enemiesKilled: 0
});
// ...
// 2. one change in your Enemy Sprite is needed...
Q.Sprite.extend("Enemy",{
  // ...
  this.on("bump.top",function(collision) {
    if(collision.obj.isA("Player")) { 
      this.destroy();
      collision.obj.p.vy = -300;
      // 3. increment your state variable
      Q.state.inc("enemiesKilled");
    }
  });
}
// ...
// 4. extend Q.UI.Text class...
Q.UI.Text.extend("EnemiesKilledLabel", {
  init: function(p) {
    this._super({
      label: "Enemies Killed: 0",
      // ...
    });
    // 5. add a listener for changes on your state...
    Q.state.on("change.enemiesKilled",this,"enemiesKilledChange");
  },
  // 6. ...and the handler
  enemiesKilledChange: function(enemiesKilled) {
    this.p.label = "Enemies Killed: " + enemiesKilled;
  }
};  
// ... etc.

请注意始终使用Q.state.set(...), Q.state.get(...)Q.state.inc(...)等方便方法,以便Quintus可以触发change.<state>事件。

你最好看看http://html5quintus.com/guide/core.md,"游戏状态"部分

我完全不熟悉Quintus,所以我不确定这是否有效,但我看了一下他们的网站,认为我有一个解决方案。我将不处理ELK字符串,而是直接处理UI。文本组件。一旦你有了这个,你应该能够相应地更新包含的文本。

//1) Add this at the top of your code block, where ELK is now. (In the global space)
var killedLabel = new Q.UI.Text({ 
  label: "Enemies killed: 0",
  color: "black",
  x: 0,
  y: 0
});
//2) When you define your scene, just add the previously created label reference.
stage.insert(killedLabel ,container);
//3) Later on in code....  Update the following code to use the label instead of ELK
//   If the enemy gets hit on the top, destroy it
//   and give the user a "hop"
this.on("bump.top",function(collision) {
  if(collision.obj.isA("Player")) { 
    this.destroy();
      collision.obj.p.vy = -300;
      //Increasing Enemies killed on destroy
      EKL1++;
      //Add this line....
      killedLabel.p.label = "Enemies Killed: " + ELK;
    }
});

我还想补充一点,如果我是你,我会使用一个更强大/流行的引擎。例如Construct 2 (https://www.scirra.com/)或Impact.js.