請問為什麼在程式碼裡面加了這段
ctx.beginPath();
ctx.arc(Ball.x, Ball.y, Ball.ballRadius, 0, Math.PI * 2);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
之後新增的磚塊都會變成只有一塊...
可是我是想寫出磚塊每隔一段時間就出現一排,
而且有時候球也會自己亂跑,請問是我哪裡寫錯了嗎?
以下是我全部的程式碼
<script>
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
let brick = {
width: 75,
height: 20,
padding: 10,
top: 30,
left: 20
}
let Board = {
x: (canvas.width - 75) / 2,
y: canvas.height - 10,
width: 75,
height: 10,
speed: 10
}
let Ball = {
x: canvas.width / 2,
y: canvas.height - 30,
ballRadius: 10,
dx: 2,
dy: -2
}
let blocks = []
for (let r = 0; r < 5; r++) {
blocks[r] = []
for (let c = 0; c < 9; c++) {
blocks[r][c] = {
x: 0,
y: 0,
hidden: false
}
}
}
let interval = setInterval(startGame, 10);
let newB = setInterval(addBlocks, 1000);
function drawBlocks() {
for (let r = 0; r < blocks.length; r++) {
for (let c = 0; c < blocks[r].length; c++) {
if (!blocks[r][c].hidden) {
const brickX = (c * (brick.width + brick.padding)) + brick.left;
const brickY = (r * (brick.height + brick.padding)) + brick.top;
blocks[r][c].x = brickX;
blocks[r][c].y = brickY;
ctx.rect(brickX, brickY, brick.width, brick.height);
ctx.fillStyle = "#0095DD";
ctx.fill();
}
}
}
}
function drawBoard() {
ctx.fillRect(Board.x, Board.y, Board.width, Board.height);
ctx.fillStyle = "0095DD";
ctx.fill();
}
function drawBall() {
ctx.beginPath();
ctx.arc(Ball.x, Ball.y, Ball.ballRadius, 0, Math.PI * 2);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
function addBlocks() {
let newBlocks = [];
newBlocks[0] = [];
for (let c = 0; c < 9; c++) {
newBlocks[0][c] = {
x: 5,
y: 5,
hidden: false
}
}
blocks.unshift(newBlocks);
}
window.onload = onPageLoaded
function onPageLoaded() {
document.addEventListener('keydown', moveBoard)
}
function moveBoard(event) {
if (event.keyCode === 37) { // left arrow
Board.x -= Board.speed;
}
if (event.keyCode === 39) { // right arrow
Board.x += Board.speed;
}
if (Board.x + Board.width > canvas.width) {
Board.x -= Board.speed;
}
if (Board.x < 0) {
Board.x += Board.speed;
}
}
function moveBall() {
if (Ball.x + Ball.dx > canvas.width - Ball.ballRadius || Ball.x + Ball.dx < Ball.ballRadius) {
Ball.dx = -Ball.dx;
}
if (Ball.y + Ball.dy < Ball.ballRadius) {
Ball.dy = -Ball.dy;
}
if (Ball.y + Ball.dy + 10 > canvas.height - Ball.ballRadius) {
if (Ball.x >= Board.x && Ball.x <= Board.x + Board.width) {
Ball.dy = -Ball.dy;
}
}
if (Ball.y > canvas.height - Ball.ballRadius) {
alert("GAME OVER");
clearInterval(interval);
}
for (let r = 0; r < blocks.length; r++) {
for (let c = 0; c < blocks[r].length; c++) {
const bk = blocks[r][c];
if (Ball.x >= bk.x && Ball.x <= bk.x + brick.width && Ball.y >= bk.y && Ball.y <= bk.y + brick.height) {
Ball.dy = -Ball.dy;
bk.hidden = true;
}
}
}
Ball.x += Ball.dx;
Ball.y += Ball.dy;
}
function GameOver() {
for (let r = 0; r < blocks.length; r++) {
for (let c = 0; c < blocks[r].length; c++) {
let bk = blocks[r][c];
if (bk.y > canvas.height - brick.top && bk.hidden === false) {
clearInterval(interval);
clearInterval(newB);
alert("GameOver");
}
}
}
}
function startGame() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBlocks()
drawBoard()
drawBall()
moveBall()
GameOver()
}
</script>
先說好像有蠻多地方必須要修正的
但我改了addBlocks的function後會變成插入一排
建議程式碼很多地方需要注意...
只能先就你的問題解決
//newBlocks=[{..} ...] 插入blocks好像才對的樣子?
//你寫的會變成[[{..} ...]]插入blocks
function addBlocks() {
let newBlocks = [];
for (let c = 0; c < 9; c++) {
newBlocks[c] = {
x: 5, //這裡沒用到喔,會被你邏輯覆蓋
y: 5, //這裡沒用到喔,會被你邏輯覆蓋
hidden: false
}
}
blocks.unshift(newBlocks);
}
了解,謝謝你
聽說寫小遊戲可以訓練邏輯,聽起來很容易....可是做起來好難啊
我也深有同感
主旨:改成讓 Board 滑順
加上 direction 屬性,代表向左或向右鍵按下的狀態
bit 0 被設定時,代表向左鍵按下
bit 1 被設定時,代表向右鍵按下
const MOVE = {
LEFT: 1,
RIGHT: 2
};
let Board = {
x: (canvas.width - 75) / 2,
y: canvas.height - 10,
width: 75,
height: 10,
speed: 3,
direction: 0
}
當使用者按下(或放開)左或右時,只設定 Board.direction
function onPageLoaded() {
document.addEventListener('keydown', function(event) {
if (event.code === 'ArrowLeft') {
Board.direction |= MOVE.LEFT;
} else if (event.code === 'ArrowRight') {
Board.direction |= MOVE.RIGHT;
}
});
document.addEventListener('keyup', function(event) {
if (event.code === 'ArrowLeft') {
Board.direction &= ~MOVE.LEFT;
} else if (event.code === 'ArrowRight') {
Board.direction &= ~MOVE.RIGHT;
}
});
}
讓每次畫面更新時,都依據鍵盤按下的狀態更新 Board
function moveBoard() {
let d = Board.direction;
if (d & MOVE.LEFT) {
Board.x -= Board.speed;
}
if (d & MOVE.RIGHT) {
Board.x += Board.speed;
}
if (Board.x + Board.width > canvas.width) {
Board.x -= Board.speed;
}
if (Board.x < 0) {
Board.x += Board.speed;
}
}
function startGame() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBlocks()
drawBoard()
drawBall()
moveBall()
moveBoard() // 加上這行
GameOver()
}
謝謝你的回答!!!
小弟這裡有個問題想請教...
function onPageLoaded() {
document.addEventListener('keydown', function(event) {
if (event.code === 'ArrowLeft') {
Board.direction |= MOVE.LEFT;
} else if (event.code === 'ArrowRight') {
Board.direction |= MOVE.RIGHT;
}
});
document.addEventListener('keyup', function(event) {
if (event.code === 'ArrowLeft') {
Board.direction &= ~MOVE.LEFT;
} else if (event.code === 'ArrowRight') {
Board.direction &= ~MOVE.RIGHT;
}
});
}
裡面的
Board.direction |= MOVE.LEFT;
跟
Board.direction &= ~MOVE.LEFT;
這個是做什麼用的呢!!!
有稍微在網路上看了一下,但是不理解為什麼要用這個,大神能教教我嗎
|
跟 &
是位元運算MOVE.LEFT
我前面設定為 1
用二進位表示為 0001
(javascript的整數是 32bit,為了方便說明,這邊假設整數是 4bit)
而 ~MOVE.LEFT
是取反運算,二進位是 1110
當某個數 x
與 MOVE.LEFT
做 |
運算時
會把 x
的最低位設為 1。
當 x
與 ~MOVE.LEFT
做 &
運算時
會把 x
的最低位設為 0。
例如
|x
|x | MOVE.LEFT
| x & ~MOVE.LEFT
|
|---|---|---|
| 0000 | 0001 | 0000 |
| 0001 | 0001 | 0000 |
| 0010 | 0011 | 0010 |
| 0100 | 0101 | 0100 |
| 0101 | 0101 | 0100 |
原來如此!!! 感謝大神詳細的解說!