2009-10-01 55 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"; 
}