2009-10-01 54 views
0

我正在Facebook Javascript中编写基于火车的游戏。我有一个倒三角形,代表了连接欧洲城市的火车和虚线。火车沿着轨道移动,从一个城市到另一个城市。目前,我每刷新一次页面都会重新绘制游戏板。这具有始终将该列车展示在赛道上的最新位置的效果。但是,使用页面刷新来重新绘制游戏板会导致CPU密集度太高,并且我的应用程序性能也因此受到影响。因此我需要实现Ajax和火车的某种精灵动画。关于JavaScript图形动画的问题:保存和恢复“精灵”背景

当列车在轨道上改变位置时,我需要将列车标记清除到原来的位置,并将其重新绘制在新位置。我知道如何重绘它,但是将它抹去旧的位置,并且恢复背景图形就是我需要帮助的地方。我不知道如何做到这一点。事实上,我根本不知道在JavaScript中操作图形(除了创建1px div的基本PlotPixel()例程)请记住,Facebook JS与现有的JS库和框架不兼容。

任何人都可以提供一些帮助吗?我非常感谢它。谢谢!

下面是相关代码:

function drawTrack(x1, y1, x2, y2, c, trains) { 
if(c == '#444') new Dialog().showMessage('dialog', 'in drawTrack: x1='+x1+', y1='+y1+', x2='+x2+', y2='+y2); 
/** 
if(trains[0]) { 
var train_dump = dump(trains[0], 2); 
new Dialog().showMessage('dialog', 'td='+train_dump); 
} 
**/ 
    var xs1 = x1; 
    var ys1 = y1; 
    var xs2 = x2; 
    var ys2 = y2; 
    var step = 1; 
    var dashlen = 4; 
    var middash = parseInt(dashlen/2); 
    var count = 1; 
    var steep = Math.abs(y2 - y1) > Math.abs(x2 - x1); 
    if (steep) { 
     var t = y1; 
     y1 = x1; 
     x1 = t; 
     t = y2; 
     y2 = x2; 
     x2 = t; 
    } 
    var deltaX = Math.abs(x2 - x1); 
    var deltaY = Math.abs(y2 - y1); 
    var error = 0; 
    var deltaErr = deltaY; 
    var xStep; 
    var yStep; 
    var x = x1; 
    var y = y1; 
    var drewDash; 
    if (x1 < x2) { 
     xStep = step; 
    } 
    else { 
     xStep = -step; 
    } 

    if(y1 < y2) { 
     yStep = step; 
    } 

    else { 
     yStep = -step; 
    } 
    var points = 0; 
    var drawFlag = false; 
    while(x != x2) { 
     x = x + xStep; 
     if(xStep > 0) { 
      if(x > x2) { 
      break; 
      } 
      // do not draw dashes near the city markers 
      if(x >= x2-dashlen) { 
      drawFlag = false; 
      } 
     } 
     if(xStep < 0) { 
      if(x < x2) { 
      break; 
      } 
      // do not draw dashes near the city markers 
      if(x <= x2+dashlen) { 
      drawFlag = false; 
      } 
     } 
     error = error + deltaErr; 
     if(2 * error >= deltaX) { 
      y = y + yStep; 
      error = error - deltaX; 
     } 
     if(points < dashlen) { 
      if(drawFlag) { 
      if(steep) { 
       PlotPixel(y, x, c); 
       drewDash = true; 
      } 
      else { 
       PlotPixel(x, y, c); 
       drewDash = true; 
      } 
      if(points == middash) { 
       if(trains[0]) { 
       for(var key = 0; key < trains.length; key++) { 
        if(trains[key]['track_unit'] == count) { 
        if(steep) { 
         trainMarker(y, x, trains[key]); 
        } else { 
         trainMarker(x, y, trains[key]); 
        } 
        } 
       } 
       } 
      } 
      } 
      points++; 
     } else { 
      drawFlag = !drawFlag; 
      if(drewDash) count++; 
      points = 0; 
      drewDash = false; 
     } 
    } 

    if(trains[0]) { 
     for(var key = 0; key < trains.length; key++) { 
     if(trains[key]['status'] == 'ARRIVED') { 
      if(trains[key]['direction'] == '+') { 
      trainMarker(xs2, ys2, trains[key]); 
      } else { 
      trainMarker(xs1, ys1, trains[key]); 
      } 
     } 
     } 
    } 
    return count; 
} 

function trainMarker(x, y, trainData) { 
    var train = document.createElement('div'); 
    train.setClassName('train'); 
    y -= trainMarkerHeight; 
    x -= parseInt(trainMarkerWidth/2); 
    var trainId = 'train-'+trainData['line'].toLowerCase()+'-'+trainData['player_number']; 
    train.setId(trainId); 
    train.setStyle('left', x + 'px'); 
    train.setStyle('top', y + 'px'); 

    var trainImg = document.createElement('img'); 
    trainImg.setSrc(publicURL + '/images/train_marker_red.gif'); 
    train.appendChild(trainImg); 

    var trainPlayerNum = document.createElement('div'); 
    trainPlayerNum.setClassName('train-player-num'); 
    trainPlayerNum.setId('train-player-'+trainData['player_number']); 
    trainPlayerNum.setTextValue(trainData['player_number']); 
    trainPlayerNum.setStyle('left', '8px'); 
    trainPlayerNum.setStyle('top', '1px'); 
    trainPlayerNum.addEventListener('mouseover', myEventHandler); 
    trainPlayerNum.addEventListener('mouseout', myEventHandler); 
    trainPlayerNum.appendChild(setTrainTooltip(trainData)); 
    train.appendChild(trainPlayerNum); 

    var parentObj = document.getElementById('map'); 
    parentObj.appendChild(train); 
} 

该代码绘制从一个城市的×道(虚线),Y COORDS到另一个城市的x,y COORDS。如果有一列火车出现在该线路上,它也会吸引火车​​。如果列车出现在其中一个城市,它将在城市中列车。

游戏本身在http://apps.facebook.com/rails_dev

回答

2

也许不是操纵图像本身,您可以使用z-index和绝对定位的div将列车图像移动到位置顶部(地图图像?)上方?这可能比尝试在javascript中创建或修改实际图像数据更容易实现并且性能更高。

[编辑:显示或隐藏图像,JavaScript的样子:

(给出了一些HTML一样:)

<img src="train.jpg" id="trainImg" /> 
<img src="background.jpg" id="backgroundImg" /> 

JavaScript的样子:

function getTrain() { 
    document.getElementById("trainImg"); 
} 

function showTrain() { 
    getTrain().style.display = ""; 
} 

function hideTrain() { 
    getTrain().style.display = "none"; 
} 

]

+0

可能甚至不需要玩z-index绝对定位。为了更加方便用户使用,您可以将列车不断地放在div的中心,因此只需要用简单的CSS滚动来移动背景(如果您愿意的话,可以使用城市和轨道)。 – jakeisonline 2009-10-01 22:05:23

+0

请参阅上面的代码,并帮助我理解您的建议可能适用于代码的方式。谢谢。 – 2009-10-01 22:50:28

+0

如果我带上我的火车div并调用removeChild(),它会摆脱它并恢复背景吗? – 2009-10-02 01:02:40

1

绝对把你的“游戏世界”变成一个带有地图和轨迹的div ound图像。然后你可以操纵一个<img>元素(你的火车)来改变它的位置:

var train = document.createElement("img"); 
train.srx = "..."; 
train.style.position = "absolute"; 
document.getElementById("gameboard").appendChild(train);  

function moveTrainTo(x, y) { 
    train.style.left = x + "px"; 
    train.style.top = y + "px"; 
}