2013-12-21 36 views
2

我目前正在寫一個類似於經典諾基亞Snake的基於HTML5 canvas/JS的蛇克隆。 (這是我第一個HTML5 canvas/JS遊戲以及我的第一個遊戲,我仍然是一個新手程序員))爲什麼我縮放的HTML5畫布上的「像素」奇怪地對齊?

爲了保持簡單,我決定讓蛇的每一段和櫻桃只有1個像素但是,這通常會導致一個非常小的蛇和櫻桃! ;)所以我決定用.scale(8,8)來縮放畫布,所以每個像素都是8 * 8。

var snake = { 
    length: 4, 
    direction: "right", 
    color: "#9A9A92", 
    location: [{x: 32, y: 32}, {x: 31, y: 32}, {x: 30, y: 32}, {x: 29, y: 32}] 
} 
var cherry = { 
    color: "#B1001D", 
    x: Math.random()*65, 
    y: Math.random()*65 
} 
var ToDrawOrNotToDraw; //limits the speed of the snake 
function moveSnake(eventinfo){ 
    if(eventinfo.keyCode === 38){ 
    if(snake.direction === "left" || snake.direction === "right"){ 
     snake.direction = "up"; 
    } 
    } 
    else if(eventinfo.keyCode === 40){ 
    if(snake.direction === "left" || snake.direction === "right"){ 
     snake.direction = "down"; 
    } 
    } 
    else if(eventinfo.keyCode === 37){ 
    if(snake.direction === "up" || snake.direction === "down"){ 
     snake.direction = "left"; 
    } 
    } 
    else if(eventinfo.keyCode === 39){ 
    if(snake.direction === "up" || snake.direction === "down"){ 
     snake.direction = "right"; 
    } 
    } 
} 
function draw(){ 
    requestAnimationFrame(draw); 
    if(ToDrawOrNotToDraw === true){ 
    var snakeDrawerCount = 0; 
    ctx.fillStyle = "#006C00"; 
    ctx.fillRect(0, 0, 64, 64); 
    ctx.fillStyle = cherry.color; 
    ctx.fillRect(cherry.x, cherry.y, 1, 1); 
    ctx.fillStyle = snake.color; 
    if(snake.direction === "up"){ 
     if(snake.location[0].y > 0){ 
     snake.location.unshift({x: snake.location[0].x, y: snake.location[0].y-1}); 
     snake.location.pop(); 
     } 
     else { 
     snake.location.unshift({x: snake.location[0].x, y: 64}); 
     snake.location.pop(); 
     } 
    } 
    else if(snake.direction === "down"){ 
     if(snake.location[0].y < 64){ 
     snake.location.unshift({x: snake.location[0].x, y: snake.location[0].y+1}); 
     snake.location.pop(); 
     } 
     else { 
     snake.location.unshift({x: snake.location[0].x, y: 0}); 
     snake.location.pop(); 
     } 
    } 
    else if(snake.direction === "left"){ 
     if(snake.location[0].x > 0){ 
     snake.location.unshift({x: snake.location[0].x-1, y: snake.location[0].y}); 
     snake.location.pop(); 
     } 
     else { 
     snake.location.unshift({x: 64, y: snake.location[0].y}); 
     snake.location.pop(); 
     } 
    } 
    else { 
     if(snake.location[0].x < 64){ 
     snake.location.unshift({x: snake.location[0].x+1, y: snake.location[0].y}); 
     snake.location.pop(); 
     } 
     else { 
     snake.location.unshift({x: 0, y: snake.location[0].y}); 
     snake.location.pop(); 
     } 
    } 
    var snakeDrawerCount = 0; 
    while(snakeDrawerCount < snake.location.length){ 
     ctx.fillRect(snake.location[snakeDrawerCount].x, snake.location[snakeDrawerCount].y, 1, 1); 
     snakeDrawerCount++; 
    } 
    ToDrawOrNotToDraw = false; 
    } 
    else { 
    ToDrawOrNotToDraw = true; 
    } 
} 

var cnvs = document.getElementById("cnvs"); 
window.addEventListener("keydown", moveSnake, false); 
var ctx = cnvs.getContext("2d"); 
ctx.scale(8,8); //actual size of the canvas is 512 * 512, this gives the 'pixels'/blocks on the canvas a size of 8 * 8, so the canvas will get a size of 64 * 64 'pixels'/blocks 
draw(); 

但由於一些奇怪的原因,那些'大像素'(8 * 8縮放像素)似乎彼此重疊。由於可以在這裏看到:

1st image of the glitch 2nd image of the glitch 3rd image of the glitch

不幸的是我絕對不知道爲什麼發生這種情況,因爲正如我前面提到的,我還是很新的HTML5畫布/ JS的東西,我之前只有在Qt/QML/C++和Python中編程。我在Firefox 26(在Linux上)和Konqueror(在KDE 4.11上)(WebKit)都嘗試過我的遊戲,兩種瀏覽器似乎都有這個問題,所以我不認爲它與壁虎有關。

+2

將您的代碼的相關部分添加到您的問題。 –

+0

*「關於您編寫​​代碼問題的問題必須描述具體問題 - 並在問題本身中包含有效代碼以再現問題**,請參閱http://SSCCE.org以獲取指導。」* –

回答

1

問題來自抗鋸齒/亞像素化。

你的櫻桃放在隨機值的董事會。隨機值的問題在於它是一個浮點值,所以櫻桃將被放置與一些小數位偏移,並因此被瀏覽器子像素化。

當使用縮放比例時,也會縮放此子像素的結果(將顏色更改爲例如白色時更清晰),結果是它與網格不匹配。

爲了解決這個簡單地迫使櫻桃到整數的x和y位置,例如是這樣的:

var cherry = { 
    color: "#B1001D", 
    x: Math.random()*65|0, 
    y: Math.random()*65|0 
} 

Fiddle here

|是第一迫使數位OR運算符到一個整數,以便能夠使用按位或。由於我們的OR與0相同,所以輸出是相同的(除了減小浮點數)。