【问题标题】:Synced animated tiles in a 2d web game2d 网页游戏中的同步动画图块
【发布时间】:2012-01-02 05:46:04
【问题描述】:

我从 2 年前开始就在浏览器中构建策略游戏。它已经被一小群人积极玩过,所以它是一个有效的游戏。 我们的问题是它的资源匮乏。基本上你想要歌剧或铬。 IE9 或多或少无法播放,firefox 在某些地图上可能会很慢。

该游戏是一款基于图块的自上而下的游戏,地图使用 64x64 像素 DIV。

我们目前处于结束阶段,我们正专注于优化。消耗资源的东西之一是我们的动画水。我们将 32 块不同的水块分成 15 帧。因此,一个 1.1 mb 的 .gif 文件中有 480 个 64x64 图像。

这里是水的链接:http://www.warbarons.com/beta5/terrain/water/water2.gif

我们的游戏使用战争迷雾来隐藏你看不到的敌方单位和城堡,就像任何 RTS 游戏一样。所以在 .gif 之上通常有一个带有透明 PNG 的图层。

看起来这个解决方案对浏览器要求很高。当我滚动地图以在 FireFox 中显示水时,CPU 会上升 25%,而当看不到水时,它会在 4-5% 左右。

我已经在谷歌上搜索了几天,试图了解一种更好的技术。我发现了另外两种方法,或者使用遍历电子表格的画布标签,或者使用 CSS 循环遍历电子表格。

我看到这两个选项的问题是所有水砖必须保持同步。如果一个在另一个之前开始播放,波浪将不会同步,这会破坏无缝的外观。

我想知道是否有人有解决这个问题的想法?我知道拥有多个 gif 动画会导致不同步问题。

有没有一些更巧妙的方法来使用画布来做到这一点?甚至可以将画布与 div 混合使用,还是需要我们更改整个地图引擎?

任何帮助将不胜感激。

【问题讨论】:

  • “所以在 .gif 之上通常有一个带有透明 PNG 的图层”——这不是很容易作弊吗?
  • 当您加载游戏时,只会从服务器获取您知道的信息。当您进入 FOW 时,对数据库的 ajax 调用正在检查您在移动期间将发现的所有图块。因此,客户没有关于他不应该知道的事情的信息。 PNG 只是为了表明您看不到该区域的内容。

标签: animation canvas map gif tile


【解决方案1】:

有点新手的工作和远景,但是: 为了准备,制作所有不同类型水砖的精灵表,第一帧在左侧,每种类型都有一个新行,向下下降。

  • 创建一个<div>,在画布后面使用“隐藏”的“溢出”属性
  • 使画布的背景透明
  • 在 div 内部,您可以使用 <div>s 来设置水贴,并调整它们的“边距”属性以匹配地图的位置
  • 给他们一个类名称“水”,以及一个与水砖类型相匹配的类(如“dockleft”、“beachtop”等)
  • 在您的 <style> 元素中,创建一个类规则“.water”
  • 为规则赋予“背景图像”属性,链接到您的精灵表所在的任何位置
  • 对于每种类型的水瓦,创建一个与每种瓦片类型对应的类规则,并为它们提供一个匹配的精灵表 y 位置
  • 创建一个带有 id 的新 <style> 元素,该 id 将包含所有帧的背景位置
  • 创建一个 javascript 变量以包含所有背景的 x 位置
  • 在您的游戏循环中,每当您希望精灵更改时,将变量递减 64(直到等于 960,然后将其设置为 0)
  • 当变量发生变化时,使用变量将新的 <style> 元素的内容设置为其“背景位置-x”的新 CSS 规则

嗯。有点多,我知道,但比遍历数组并吞噬系统资源、单独更改每个元素要好(至少我是这样认为的)。这是一个简化的代码示例:

<script type="text/javascript">
    var pos = 0; // background-position-x variable

    function loop() {
        document.getElementById('changeMe').innerHTML = ".water{background-position-x:" + pos + "px;}"; //changes the contents of the <style> with the id 'changeMe'
        //changes the <style> with id 'Change'
        pos -= (pos == 960) ? -960 : 64; //assuming your sprite-sheet is oriented horizontally
        setTimeout('loop();', 100);
    }
</script>


<style type="text/css">
    /* Remains unchanged */
    .water {
        width: 64px;
        height: 64px;
    background-image: url('spriteSheet.png');
    }
    .dockleft{
        background-position-y: 420px;

        /* If all of your sprites are on one sheet, you can set the
        'background-position-y' attribute for each type of water tile and 
        give the 'water' class one sprite-sheet url for all of the types */
    }
</style>


<style id="changeMe" type="text/css">
    /* Changed by 'loop()' */
</style>


<body onload="loop();">
    <div class="water dockleft"></div>
</body>

【讨论】:

    猜你喜欢
    • 2013-02-04
    • 2013-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多