2011-05-08 51 views
1

喲大家!HTML5動畫在持久刷新的畫布上

我一直在HTML5 /畫布等軸測瓷磚遊戲引擎的一小會兒,現在我有一個完整的工作遊戲。今天早些時候,我回頭一看在我的代碼,心想:「嗯,讓我們設法把這個平滑的動態...」

從那時起,這是所有我試圖做的事。

問題
我想從瓷磚到瓷磚的角色實際上是「滑」 - 但在畫布上重繪不允許這一點 - 沒有任何人有任何想法....?代碼及以下小提琴...

撥弄它!http://jsfiddle.net/neuroflux/n7VAu/

<html> 
<head> 
<title>tileEngine - Isometric</title> 
<style type="text/css"> 
* { margin: 0px; padding: 0px; font-family: arial, helvetica, sans-serif; font-size: 12px; cursor: default; } 
</style> 
<script type="text/javascript"> 
var map = Array(//land 
    [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]], 
    [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]], 
    [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]], 
    [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]], 
    [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]], 
    [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]], 
    [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]], 
    [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]], 
    [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]], 
    [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]] 
); 
var tileDict = Array("http://www.wikiword.co.uk/release-candidate/canvas/tileEngine/land.png"); 
var charDict = Array("http://www.wikiword.co.uk/release-candidate/canvas/tileEngine/mario.png"); 
var objectDict = Array("http://www.wikiword.co.uk/release-candidate/canvas/tileEngine/rock.png"); //last is one more 
var objectImg = new Array(); 

var charImg = new Array(); 
var tileImg = new Array(); 

var loaded = 0; 
var loadTimer; 
var ymouse; 
var xmouse; 
var eventUpdate = 0; 

var playerX = 0; 
var playerY = 0; 

function loadImg(){ //preload images and calculate the total loading time 
    for(var i=0;i<tileDict.length;i++){ 
     tileImg[i] = new Image(); 
     tileImg[i].src = tileDict[i]; 
     tileImg[i].onload = function(){ 
      loaded++; 
     } 
    } 
    i = 0; 
    for(var i=0;i<charDict.length;i++){ 
     charImg[i] = new Image(); 
     charImg[i].src = charDict[i]; 
     charImg[i].onload = function(){ 
      loaded++; 
     } 
    } 
    i = 0; 
    for(var i=0;i<objectDict.length;i++){ 
     objectImg[i] = new Image(); 
     objectImg[i].src = objectDict[i]; 
     objectImg[i].onload = function(){ 
      loaded++; 
     } 
    } 
} 

function checkKeycode(event) { //key pressed 
    var keycode; 
    if(event == null) { 
     keyCode = window.event.keyCode; 
    } else { 
     keyCode = event.keyCode; 
    } 
    switch(keyCode) { 
     case 38: //left 
      if(!map[playerX-1][playerY][1] > 0){ 
       playerX--; 
      } 
      break; 
     case 40: //right 
      if(!map[playerX+1][playerY][1] > 0){ 
       playerX++; 
      } 
      break; 
     case 39: //up 
      if(!map[playerX][playerY-1][1] > 0){ 
       playerY--; 
      } 
      break; 
     case 37: //down 
      if(!map[playerX][playerY+1][1] > 0){ 
       playerY++; 
      } 
      break; 
     default: 
      break; 
    } 
} 

function loadAll(){ //load the game 
    if(loaded == tileDict.length + charDict.length + objectDict.length){ 
     clearInterval(loadTimer); 
     loadTimer = setInterval(gameUpdate,100); 
    } 
} 

function drawMap(){ //draw the map (in intervals) 
    var tileH = 25; 
    var tileW = 50; 
    mapX = 80; 
    mapY = 10; 
    for(i=0;i<map.length;i++){ 
     for(j=0;j<map[i].length;j++){ 
      var drawTile= map[i][j][0]; 
      var xpos = (i-j)*tileH + mapX*4.5; 
      var ypos = (i+j)*tileH/2+ mapY*3.0; 
      ctx.drawImage(tileImg[drawTile],xpos,ypos); 

      if(i == playerX && j == playerY){ 
       you = ctx.drawImage(charImg[0],xpos,ypos-(charImg[0].height/2)); 
      } 
     } 
    } 
} 

function init(){ //initialise the main functions and even handlers 
    ctx = document.getElementById('main').getContext('2d'); 
    loadImg(); 
    loadTimer = setInterval(loadAll,10); 
    document.onkeydown = checkKeycode; 
} 

function gameUpdate() { //update the game, clear canvas etc 
    ctx.clearRect(0,0,904,460); 
    ctx.fillStyle = "rgba(255, 255, 255, 1.0)"; //assign color 
    drawMap(); 
} 
</script> 
</head> 
<body align="center" style="text-align: center;" onload="init()"> 
    <canvas id="main" width="904" height="465"> 
     <h1 style="color: white; font-size: 24px;">I'll be damned, there be no HTML5 &amp; canvas support on this 'ere electronic machine!<sub>This game, jus' plain ol' won't work!</sub></h1> 
    </canvas> 
</body> 
</html> 

編輯:
請...?

+0

你會強烈建議重新設計整個應用程序使用一個單一的canvas元素,除非你有一個非常強有力的理由不這樣做。從長遠來看,它可能會讓你更加頭疼。 – ninjagecko 2011-05-08 10:06:27

+0

我的應用程序確實使用了一個畫布 - 我只是說有兩個畫布「是我能想到的唯一方法。有任何想法嗎? :( – 2011-05-08 11:31:33

+0

嘿我會給這個裂縫當我有一個自由的時刻 – 2011-05-09 02:31:09

回答

1

爲了用帆布製作動畫,你必須重新繪製整個受影響的部分中的每個幀,或者你的對象會留下痕跡,他們身後。每個動畫幀在精靈移動之前,必須重新繪製他後面的三個或四個貼圖。

我會建議增加一些額外的狀態到您的繪圖功能,因此,對於每一幀,一些臨時的距離進行更新和相關的地磚和精靈重繪。全局變量會在動畫運行時阻止鍵輸入。

我懶得自己寫,但你應該沒問題。玩的開心!

+0

啊,我想我明白了 - 有什麼機會我可以懇請你重新考慮過於懶惰?^ _^ – 2011-05-08 15:16:07

+1

對不起,但我沒有時間寫它 – 2011-05-08 20:24:18

+0

好吧,所以我嘗試了,我仍然無法得到這個工作... – 2011-05-09 10:52:24

0

Here's an example.這是不是太準確,因爲我做到了真正的快速。

基本上,當用戶按下一個按鈕,你想開始一個倒計時,其中每個時鐘的連續滴答移動它(+ 1,+ 2)等朝向其目標。經過一些滴答後,它停止移動。

編輯使用Nick的修改示例。看評論。

+1

修復了一些繪製錯誤http://jsfiddle.net/tTyFB/8/ – 2011-05-10 15:30:40

+0

+1!謝謝尼克! – 2011-05-10 17:16:15