【问题标题】:Javascript for loop to use array of images as enemiesJavascript for循环使用图像数组作为敌人
【发布时间】:2014-06-15 18:21:53
【问题描述】:

我有一个 html 文件,它设置从 xml 文件解析的图像数组。

var states = xmlDoc.getElementsByTagName("random_state");

for(var i=0; i<states.length;i++)
{
    var xx = states[i].getElementsByTagName("random_image");

    for(var j=0; j<xx.length;j++)
    {

        randomurl = xx[j].childNodes[j].nodeValue
        }
    }

在我的 game.js 文件中我有这个

I.sprite  = Sprite(randomurl);

设置敌人的形象。 randomurl 是 html 文件中的全局变量

我的问题是,它不是在屏幕上显示图像数组,而是只显示数组中的最后一张图像。我尝试了多种方法来做到这一点,每次我都失败了。 我正在尝试使用整个图像数组来显示为敌人。

xml 代码只返回 4 个图像,这是存储在数据库中的图像数组。代码太全面,无法添加。但是我已经测试了我的图像是否可以正确返回,因为我可以让它们出现在 div 中。我的问题是它们将作为敌人出现,因此只有数组中的最后一个图像显示为精灵,尽管我需要所有返回的图像来填充这个精灵?

XML 代码

$obj2 = StatesCollection::GetRandomStateImages($_GET['state_abbreviation']);
foreach($obj2 as $row2)             
{
    $random_url="./images/" . $row2['state_image']; 
    $response .= '<random_state><random_image>' . htmlentities($random_url, ENT_QUOTES) . '</random_image></random_state>';
}

它从数据库中的方法返回图像。

还有game.js的抓敌功能

 function Enemy(I) {
          I = I || {};

          I.active = true;
          I.age = Math.floor(Math.random() * 128);

          I.color = "#A2B";

          I.x = width / 4 + Math.random() * width / 2;
          I.y = 0;
          I.xVelocity = 0
          I.yVelocity = 2;

          I.width = 32;
          I.height = 32;

          I.inBounds = function() {
            return I.x >= 0 && I.x <= width &&
              I.y >= 0 && I.y <= height;
          };

            I.sprite  = Sprite(randomurl);

          I.draw = function() {
            this.sprite.draw(canvas, this.x, this.y);
          };

          I.update = function() {
            I.x += I.xVelocity;
            I.y += I.yVelocity;

            I.xVelocity = 3 * Math.sin(I.age * Math.PI / 64);

            I.age++;

            I.active = I.active && I.inBounds();
          };

          I.explode = function() {
            Sound.play("explosion");

            this.active = false;
            // Extra Credit: Add an explosion graphic
          };

          return I;
        };

控制精灵的精灵类

(function() {
  function LoaderProxy() {
    return {
      draw: $.noop,
      fill: $.noop,
      frame: $.noop,
      update: $.noop,
      width: null,
      height: null
    };
  }

  function Sprite(image, sourceX, sourceY, width, height) {
    sourceX = sourceX || 0;
    sourceY = sourceY || 0;
    width = width || image.width;
    height = height || image.height;

    return {
      draw: function(canvas, x, y) {
        canvas.drawImage(
          image,
          sourceX,
          sourceY,
          width,
          height,
          x,
          y,
          width,
          height
        );
      },

      fill: function(canvas, x, y, width, height, repeat) {
        repeat = repeat || "repeat";
        var pattern = canvas.createPattern(image, repeat);
        canvas.fillColor(pattern);
        canvas.fillRect(x, y, width, height);
      },

      width: width,
      height: height
    };
  };

  Sprite.load = function(url, loadedCallback) {
    var img = new Image();
    var proxy = LoaderProxy();

    img.onload = function() {
      var tile = Sprite(this);

      $.extend(proxy, tile);

      if(loadedCallback) {
        loadedCallback(proxy);
      }
    };

    img.src = url;

    return proxy;
  };

  window.Sprite = function(name, callback) {
    return Sprite.load(name, callback);
  };
  window.Sprite.EMPTY = LoaderProxy();
  window.Sprite.load = Sprite.load;
}());

【问题讨论】:

  • 您是否在任何地方将 randomurl 声明为 var?我在上面的代码块中没有看到它。此外,您需要在 nodeValue 后加一个分号...等等,不要介意将 randomurl 声明为 var
  • 显然randomurl 将被分配到您节点的最后一个值,即xx[xx.length-1].childNodes[xx.length-1].nodeValue;
  • 那么你对它应该做什么有任何额外的帮助吗?您的评论有助于发现问题,但不完全是答案?
  • 所以你想让一个精灵包含所有四个图像?您的Sprite 课程如何运作?是来自你没有提到的某个图书馆吗?
  • 谢谢,但您没有回答我的第一个问题。您是否希望一个精灵包含所有四个图像?看起来Sprite 构造函数只允许指定一个图像。图片应该如何相对排列?

标签: javascript arrays image loops for-loop


【解决方案1】:

好的,所以我想我终于明白你想要一组 URL,并且每次创建敌人时都要遍历它们并使用不同的 URL。为了做到这一点,我建议保留一个全局的 url 数组而不是一个。我会称之为enemyUrls。你可以这样填充它:

var states = xmlDoc.getElementsByTagName("random_state"), 
    imgUrlNode, i;
enemyUrls = [];

for(i = 0; i < states.length;i++) {
    imgUrlNode = states[i].getElementsByTagName("random_image")[0];

    if (imgUrlNode) {
        enemyUrls.push(imgUrlNode.nodeValue);
    }
}

再添加一个名为currentImg的全局变量并将其初始化为0:

var currentImg = 0;

然后当你创建你的敌人时,这样做:

I.sprite  = Sprite(enemyUrls[currentImg]);
currentImg = (currentImg + 1) % enemyUrls.length;

【讨论】:

  • 我有一组图像。我不希望从这个数组中显示随机图像。我希望显示所有图像。所以我的问题是它只显示数组的最后一个?没有必要显示 xml,因为到目前为止我已经测试了所有内容。 XML 只返回 4 个图像。这些是我想要显示的图像。我试过你的代码,它可以工作,但它只显示一个随机图像,但我希望显示所有 4 个图像
  • @Samir_K_92 在这种情况下,您需要向我们展示更多代码。除了您给我们的那条线之外,我们不知道图像是如何添加到您的游戏中的。您现在拥有的代码将覆盖randomUrl,直到它到达最后一个,这就是循环结束时它将具有的值。无论您是否认为有必要,请向我们提供您的 XML。
  • 好吧,我为你编辑了我的问题。感谢您的宝贵时间
  • 天哪,我要过来吻你!伙计,我已经被困了好几天了!!我不得不对您的代码进行一些编辑,但我明白了!你是男人!
猜你喜欢
  • 2020-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-11
  • 2012-02-18
相关资源
最近更新 更多