簡體   English   中英

為什么縮放后的HTML5畫布上的“像素”奇怪地對齊?

[英]Why are the 'pixels' on my scaled HTML5 canvas strangely aligned?

我目前正在寫一些基於HTML5 canvas / JS的蛇形克隆,類似於經典的諾基亞蛇。 (這是我的第一個HTML5 canvas / JS游戲,也是我的第一個游戲,我仍然是新手程序員;))

為了簡單起見,我決定將蛇和櫻桃的每個部分都設為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縮放像素)似乎相互重疊。 如此處所示:

故障的第一張圖片故障的第二張圖片故障的第三個圖像

不幸的是,我完全不知道為什么會這樣,因為如前所述,我對HTML5 canvas / JS還是很陌生,之前我只用Qt / QML / C ++和Python編程。 我在Firefox 26(在Linux上)和Konqueror(在KDE 4.11)(WebKit)上都試用了我的游戲,兩個瀏覽器似乎都存在問題,因此我認為這與Gecko無關。

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

您的櫻桃以隨機值放置在板上。 隨機值的問題在於它是一個浮點值,因此將Cherry偏移一些小數,因此瀏覽器將其子像素化。

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

為了解決這個問題,只需將cherry的x和y位置強制為整數,例如這樣:

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

在這里擺弄

| 是按位或運算符,它首先將數字強制為整數,以便能夠使用按位或。 由於我們對0進行OR運算,所以輸出是相同的(除了切掉浮點小數)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM