2015-11-10 36 views
-2

我正在嘗試製作一款帶有球和玩家(平臺)的磚塊遊戲。如果球擊中球員,它應該像乒乓球一樣朝另一個方向飛去。但是,它沒有檢測到碰撞。如何檢查玩家和球的碰撞?

下面的代碼

HTML:

<canvas id="canvas" width= "400" height= "400"></canvas> 

CSS:

#canvas{border:1px solid black} 

JS:

var width = 400 
var height = 400 

var drawRect = function (x, y) { 
    ctx.fillRect(x, y, 30, 5) 
}; 

// The Ball constructor 
var Player = function() { 
    this.x = 395 
    this.y = 395 
    this.xSpeed = 5; 
    this.ySpeed = 0; 
}; 

// Update the ball's position based on its speed 
Player.prototype.move = function() { 
    this.x += this.xSpeed; 
    this.y += this.ySpeed; 

    if (this.x < 0) { 
    this.x = width; 
    } else if (this.x > width) { 
    this.x = 0; 
    } else if (this.y < 0) { 
    this.y = height; 
    } else if (this.y > height) { 
    this.y = 0; 
    } 
}; 

// Draw the ball at its current position 
Player.prototype.draw = function() { 
    drawRect(this.x, this.y); 
}; 

// Set the ball's direction based on a string 
Player.prototype.setDirection = function (direction) { 
    if (direction === "left") { 
    this.xSpeed = -5; 
    this.ySpeed = 0; 
    } else if (direction === "right") { 
    this.xSpeed = 5; 
    this.ySpeed = 0; 
    } else if (direction === "stop") { 
    this.xSpeed = 0; 
    this.ySpeed = 0; 
    } 
}; 

// Create the ball object 
var player = new Player(); 

// An object to convert keycodes into action names 
var keyActions = { 
    32: "stop", 
    37: "left", 
    38: "up", 
    39: "right", 
    40: "down" 
}; 

// The keydown handler that will be called for every keypress 
$("html").keydown(function (event) { 
    var direction = keyActions[event.keyCode]; 
    player.setDirection(direction); 
}); 



var Ball = function() { 
    this.x = 100; 
    this.y = 100; 
    this.xSpeed = -2 
    this.ySpeed = 3; 
}; 
var circle = function (x, y, radius, fillCircle) { 
    ctx.beginPath(); 
    ctx.arc(x, y, radius, 0, Math.PI * 2, false) 
    if (fillCircle) { 
     ctx.fill(); 
    } else { 
     ctx.stroke(); 
    } 
} 
Ball.prototype.move = function() { 
    this.x += this.xSpeed 
    this.y += this.ySpeed 
}; 

Ball.prototype.draw = function() { 
    circle(this.x, this.y, 3, true); 
}; 

Ball.prototype.checkCollision = function() { 
    if (this.x < 0 || this.x > 400) { 
     this.xSpeed = -this.xSpeed 
    } 

    if (this.y < 0) { 
     this.ySpeed = -this.ySpeed 

    } 
}; 

Ball.prototype.checkCollisionPlayer = function() { 
    if (this.x === Player.x || this.y === player.y) { 
    this.ySpeed = -this.ySpeed 
    this.xSpeed = -this.xSpeed 
    } 
} 
var canvas = document.getElementById("canvas"); 
var ctx = canvas.getContext("2d"); 
setInterval(function() { 
    ctx.clearRect(0, 0, 400, 400); 
    player.draw(); 
    player.move(); 
    ball.draw(); 
    ball.move(); 
    ball.checkCollision(); 
    ball.checkCollisionPlayer(); 
}, 40); 
var ball = new Ball(); 

感謝您的支持。 :)

+2

爲什麼叫球構造'播放器()'? –

+0

球員是矩形和球是球 –

+0

有什麼不對嗎? –

回答

1

我已經添加了一個簡單的箱子碰撞和更新類有球和球員的盒子尺寸。請記住,球盒必須調整半徑偏移量。

更新

那種需要你要知道,被擊中邊或角框碰撞檢測。我更新了這個例子作爲這個的起點,但它需要添加角落,我也不知道最佳檢測。這些塊被設置爲測試。我希望這有幫助。

var width = 400 
 
var height = 400 
 

 
function Brick(x, y, w, h, color) { 
 
    this.x = x; 
 
    this.y = y; 
 
    this.color = color; 
 
    this.w = w; 
 
    this.h = h; 
 
    this.hits = 0; 
 
} 
 

 
Brick.prototype.draw = function() { 
 
    ctx.save(); 
 
    ctx.fillStyle = this.color; 
 
    ctx.fillRect(this.x, this.y, this.w, this.h); 
 
    ctx.fillStyle = "white"; 
 
    ctx.fillText(this.hits, this.x + 2, this.y + 10); 
 
    ctx.restore(); 
 
}; 
 

 
var bricks = [ 
 
    new Brick(80, 120, 15, 15, 'red'), 
 
    new Brick(220, 90, 15, 15, 'blue'), 
 
    new Brick(340, 100, 50, 20, 'green') 
 
]; 
 

 

 

 

 
// The Ball constructor 
 
var Player = function() { 
 
    this.x = 395 
 
    this.y = 395 
 
    this.xSpeed = 5; 
 
    this.ySpeed = 0; 
 
    this.w = 30; 
 
    this.h = 5; 
 
}; 
 

 

 
// Update the ball's position based on its speed 
 
Player.prototype.move = function() { 
 
    this.x += this.xSpeed; 
 
    this.y += this.ySpeed; 
 

 
    if (this.x < 0) { 
 
    this.x = width; 
 
    } else if (this.x > width) { 
 
    this.x = 0; 
 
    } else if (this.y < 0) { 
 
    this.y = height; 
 
    } else if (this.y > height) { 
 
    this.y = 0; 
 
    } 
 
}; 
 

 
// Draw the ball at its current position 
 
Player.prototype.draw = function() { 
 
    ctx.fillRect(this.x, this.y, this.w, this.h); 
 
}; 
 

 
// Set the ball's direction based on a string 
 
Player.prototype.setDirection = function(direction) { 
 
    if (direction === "left") { 
 
    this.xSpeed = -5; 
 
    this.ySpeed = 0; 
 
    } else if (direction === "right") { 
 
    this.xSpeed = 5; 
 
    this.ySpeed = 0; 
 
    } else if (direction === "stop") { 
 
    this.xSpeed = 0; 
 
    this.ySpeed = 0; 
 
    } 
 
}; 
 

 
// Create the ball object 
 
var player = new Player(); 
 

 
// An object to convert keycodes into action names 
 
var keyActions = { 
 
    32: "stop", 
 
    37: "left", 
 
    38: "up", 
 
    39: "right", 
 
    40: "down" 
 
}; 
 

 
// The keydown handler that will be called for every keypress 
 
$("html").keydown(function(event) { 
 
    var direction = keyActions[event.keyCode]; 
 
    player.setDirection(direction); 
 
}); 
 

 

 

 
var Ball = function() { 
 
    this.x = 100; 
 
    this.y = 100; 
 
    this.xSpeed = -2 
 
    this.ySpeed = 3; 
 
    this.radius = 3; 
 
}; 
 
var circle = function(x, y, radius, fillCircle) { 
 
    ctx.beginPath(); 
 
    ctx.arc(x, y, radius, 0, Math.PI * 2, false) 
 
    if (fillCircle) { 
 
    ctx.fill(); 
 
    } else { 
 
    ctx.stroke(); 
 
    } 
 
} 
 
Ball.prototype.move = function() { 
 
    this.x += this.xSpeed 
 
    this.y += this.ySpeed 
 
    if ((this.y + this.radius) > ctx.canvas.height) { 
 
    // floor to ceiling 
 
    this.y = 0; 
 
    } 
 
}; 
 

 
Ball.prototype.draw = function() { 
 
    circle(this.x, this.y, this.radius, true); 
 
}; 
 

 
Ball.prototype.getBox = function() { 
 
    return { 
 
    x: this.x - this.radius, 
 
    y: this.y - this.radius, 
 
    w: this.radius * 2, 
 
    h: this.radius * 2 
 
    }; 
 
}; 
 

 
Ball.prototype.checkCollision = function() { 
 

 

 

 

 
    if (this.x < 0 || this.x > 400) { 
 
    this.xSpeed = -this.xSpeed 
 
    } 
 

 
    if (this.y < 0) { 
 
    this.ySpeed = -this.ySpeed 
 
    } else { 
 
    var boxA = this.getBox(); 
 

 
    switch (boxCollide(boxA, player)) { 
 
     case 1: 
 
     case 3: 
 
     this.ySpeed = -this.ySpeed; 
 
     break; 
 
     case 2: 
 
     case 4: 
 
     this.xSpeed = -this.xSpeed; 
 
     break; 
 
    } 
 
    } 
 

 

 
}; 
 

 
// does box a collide with box b 
 
// box = {x:num,y:num,w:num,h:num} 
 
function boxCollide(a, b) { 
 

 
    var ax2 = a.x + a.w; 
 
    var ay2 = a.y + a.h; 
 
    var bx2 = b.x + b.w; 
 
    var by2 = b.y + b.h; 
 

 
    // simple hit true, false 
 
    //if (ax2 < b.x || a.x > bx2 || ay2 < b.y || a.y > by2) return false; 
 
    // return true 
 

 
    var xInRange = (a.x >= b.x && a.x <= bx2 || ax2 >= b.x && ax2 <= bx2); 
 
    var yInRange = (a.y >= b.y && a.y <= by2 || ay2 >= b.y && ay2 <= by2); 
 
    // Clockwise hit from top 1,2,3,4 or -1 
 
    if (ay2 > b.y && a.y < by2 && xInRange) return 1; // A hit the top of B 
 
    if (a.x < bx2 && ax2 > b.x && yInRange) return 2; // A hit the right of B 
 
    if (a.y < by2 && ay2 > b.y && xInRange) return 3; // A hit the bottom of B 
 
    if (ax2 > b.x && a.x < bx2 && yInRange) return 4; // A hit the right of B 
 
    return -1; // nohit 
 
} 
 

 

 
Ball.prototype.checkCollisionPlayer = function() { 
 
    if (this.x === Player.x || this.y === player.y) { 
 
    this.ySpeed = -this.ySpeed 
 
    this.xSpeed = -this.xSpeed 
 
    } 
 
} 
 
var canvas = document.getElementById("canvas"); 
 
var ctx = canvas.getContext("2d"); 
 
setInterval(function() { 
 
    ctx.clearRect(0, 0, 400, 400); 
 
    player.draw(); 
 
    player.move(); 
 
    ball.draw(); 
 
    ball.move(); 
 
    ball.checkCollision(); 
 
    ball.checkCollisionPlayer(); 
 
    var boxA = ball.getBox(); 
 
    for (var i = 0; i < bricks.length; i++) { 
 
     switch (boxCollide(boxA, bricks[i])) { 
 
     case 1: 
 
      ball.y = bricks[i].y - ball.radius - 1; 
 
      ball.ySpeed = -ball.ySpeed; 
 
      bricks[i].hits++; 
 
      break; 
 
     case 3: 
 
      ball.y = bricks[i].y + ball.radius + bricks[i].h + 1; 
 
      ball.ySpeed = -ball.ySpeed; 
 
      bricks[i].hits++; 
 
      break; 
 
     case 2: 
 
      ball.x = bricks[i].x + ball.radius + bricks[i].w + 1; 
 
      ball.xSpeed = -ball.xSpeed; 
 
      bricks[i].hits++; 
 
      break; 
 
     case 4: 
 
      ball.x = bricks[i].x - ball.radius - 1; 
 
      ball.xSpeed = -ball.xSpeed; 
 
      bricks[i].hits++; 
 
      break; 
 
     } 
 

 

 
     bricks[i].draw(); 
 
    } 
 
    }, 
 
    40); 
 
var ball = new Ball();
#canvas { 
 
    border: 1px solid black 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<canvas id="canvas" width="400" height="400"></canvas>

+0

現在這就是我的男孩 –

+0

你能解釋它是如何工作的? –

+0

當盒子不可能相交時,碰撞檢測器通過返回false來嘗試快速失敗。它應該像'如果A的右側沒有到達B的左側 - 或 - A的左側超出B的右側 - 或 - A的底部沒有到達B的頂部 - 或者 - A的頂部超出了B -THEN的底部 - 這些盒子不會被隔離 - 因爲盒子可以互相隔開。這是一個滿嘴。製作一些隨機的座標並繪製出來! – wolfhammer