使用Canvas + CSS动画制作棋盘游戏

时间:2018-12-13 22:51:59

标签: javascript css css-animations

嗨,我正在尝试建立一个棋盘游戏,在该游戏中您掷骰子(math.random),并且令牌根据掷骰的结果移动空格。我决定使用画布来绘制画板本身,但是我仍然坚持如何使令牌移动。我已经绘制了每个图块的坐标(底部:”,​​左侧:”),并且还创建了一个数组供骰子掷骰结果收集。我想我的问题是如何使这些结果相加,以及如何使“总计”代表董事会上的坐标。要遵循的代码。

var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var tokenSum = [];
var tknSum = [];
var element = document.getElementById('rollbtnid');

if (canvas.getContext) {
  make_base();

  function make_base() {
    base_image = new Image();
    base_image.src = '0.5x/SymBoardBrdr_1@0.5x.png';
    base_image.onload = function() {
      ctx.drawImage(base_image, 0, 0);
    }
  }
} else {
  alert('Your browser doesnt support HTML canvas please upgrade it');
}

window.addEventListener('DOMContentLoaded', function() {
  const buttonDiceroll = document.querySelector('.rollbtn');

  function rollDice() {
    const dice = document.getElementById('dice');
    const status = document.getElementById('rollWords');

    const rollTotal = Math.floor(Math.random() * 6) + 1;
    const diceTotal = rollTotal;
    tokenSum.push(rollTotal);
    console.log(tokenSum);

    status.innerHTML = 'You rolled ' + diceTotal + '.';
  }

  buttonDiceroll.addEventListener('click', rollDice, false);
}, false);
.redtoken {
  position: relative;
  bottom: 500px;
  left: 850px;
}

.bluetoken {
  position: relative;
  bottom: 790px;
  left: 200px;
}

body {
  background-image: url("0.5x/dragonscaleSmall@0.5x.png");
  background-repeat: repeat;
}

#myCanvas {
  position: relative;
  left: 10%;
  background-color: white;
}

#rollWords {
  position: relative;
  margin-left: 20px;
  font-size: 36pt;
}

.actionBx {
  height: 80%;
  width: 20%;
}

.statusbx {
  position: relative;
  bottom: 50%;
  left: 65%;
  height: 20%;
  width: 20%;
}

.narratebox {
  position: relative;
  left: 15%;
  bottom: 38%;
  width: 40%;
  height: 100px;
}

.rollbtn {
  position: absolute;
  bottom: 80%;
  right: 20%;
  color: white;
  background-color: black;
  border: 1.5px solid white;
  box-shadow: 2px 3px 2px 0px grey;
  width: 125px;
  height: 30px;
}
<body>
  <canvas id="myCanvas" width="1200" height="575" style="border:2px solid 
      #000000;"></canvas>
  <button class="rollbtn" id='rollbtnid'>
         <h5> Roll</h5>
      </button>
  <div class="statusbx" id="statusbxid">
    <h6 id='rollWords'></h6>
  </div>
  <div class="narratebox" id="narrateboxid">
    <h7 id='narrateWords'></h7>
  </div>
  <div class='redtoken' id='redtokenid'><img src='0.5x/SmLvTkn@0.5x.png'>
  </div>
  <div class='bluetoken' id='bluetokenid'><img src='0.5x/SmWhtTkn@0.5x.png'>
  </div>
  <script src="GoT_Canvas_test.js"></script>
</body>

2 个答案:

答案 0 :(得分:0)

您需要获取每个图块的像素位置,并将随时间推移的玩家片段转换为相应的图块位置。根据不同的开发板,您也可以完全使用运行时数学来完成此操作,但是对于初学者,我建议您存储它们。由于它是画布,因此您必须在每个帧之后清除并重新绘制整个画布,否则它将继续添加到当前帧中。理想情况下,您应该将png存储为base64,并且不要每次都重新请求。

答案 1 :(得分:0)

要以100%的准确率回答这个问题非常困难,因为您没有提供有效的示例,但是我可能会这样做(如果我正确理解了您的游戏):

  • 将图块存储在数组[{left: 0, top: 0}, {/* ... */}, /* ... */]
  • 将当前位置存储为变量(与tile数组中的tile索引相关)
  • 如果用户滚动,则将滚动量添加到当前位置,然后您将获得新的图块位置

// meta code
const tiles = [
  {left: 0, top: 0},
  {left: 10, top: 10},
  {left: 20, top: 20},
  {left: 30, top: 30},
  {left: 40, top: 40},
  {left: 50, top: 50},
  {left: 60, top: 60},
  {left: 70, top: 70},
  {left: 80, top: 80},
  {left: 90, top: 90},
  {left: 100, top: 100},
  {left: 110, top: 110},
  {left: 120, top: 120},
];

let rollHistory = [];
let currentPosition = 0; // starting positon

function rollDice() {
  return Math.floor(Math.random() * 6) + 1;
}

// show roll history
const el = document.getElementById('roll-history');

function updateHistory(roll) {
  rollHistory.push(roll);
  el.innerHTML = '';
  rollHistory.forEach((record, i) => {
    const recordDiv = document.createElement('div');
    recordDiv.innerHTML = `${(i + 1)}: ${record}`;
    el.appendChild(recordDiv);
  });
}

// draw tiles
const tilesWrapper = document.getElementById('tiles-wrapper');

tiles.forEach(tile => {
  const tileDiv = document.createElement('div');
  tileDiv.className = 'tile';
  tileDiv.style.left = tile.left + 'px';
  tileDiv.style.top = tile.top + 'px';
  tilesWrapper.appendChild(tileDiv);
});


// button and position logic
const button = document.getElementById('roll-button');
const piece = document.getElementById('piece');

button.addEventListener('click', (e) => {
  const roll = rollDice();
  updateHistory(roll);

  if (currentPosition + roll >= tiles.length) {
    // not enought tiles left, go to last
    currentPosition = tiles.length - 1;
  } else {
    currentPosition += roll;
  }
  
  piece.style.left = tiles[currentPosition].left + 'px';
  piece.style.top = tiles[currentPosition].top + 'px';
  
  // if on last, WIN!
  if (currentPosition === tiles.length - 1) {
    setTimeout(() => alert('You win!'), 1);
  }
});
#roll-button {
  position: absolute;
  right: 50%;
  top: 10px;
}

#piece {
  position: absolute;
  top: 0;
  left: 0;
  height: 10px;
  width: 10px;
  border-radius: 50%;
  background: #000;
}

.tile {
  position: absolute;
  height: 10px;
  width: 10px;
  border: 1px solid red;
}

.history {
  position: absolute;
  right: 10px;
  top: 10px;
  width: 150px;
  background: #eee;
}
<button id="roll-button">Roll</button>

<div class="history">
  History (move: roll) <br /> <br />
  <div id="roll-history"></div>
</div>

<div id="piece"></div>
<div id="tiles-wrapper"></div>