Can someone help me, I can't seem to get my collision detection between an array of balls and a rectangle object to work.
var balls = [];
var obstacle;
function setup() {
createCanvas(windowWidth, windowHeight);
obstacle = new Obstacle();
}
function draw() {
background(75);
obstacle.display();
for(var i = 0; i < balls.length; i++) {
balls[i].display();
balls[i].update();
balls[i].edges();
}
}
function mousePressed() {
balls.push(new Ball(mouseX, mouseY));
}
function Ball(x, y) {
this.x = x;
this.y = y;
this.r = 15;
this.gravity = 0.5;
this.velocity = 0;
this.display = function() {
fill(255, 0 , 100);
stroke(255);
ellipse(this.x, this.y, this.r*2);
}
this.update = function() {
this.velocity += this.gravity;
this.y += this.velocity;
}
this.edges = function() {
if (this.y >= windowHeight - this.r*2) {
this.y = windowHeight - this.r*2;
this.velocity = this.velocity* -1;
this.gravity = this.gravity * 1.1;
}
}
}
function Obstacle() {
this.x = windowWidth - windowWidth;
this.y = windowHeight / 2;
this.w = 200;
this.h = 25;
this.display = function() {
fill(0);
stroke(255);
rect(this.x, this.y, this.w, this.h);
}
}
function RectCircleColliding(Ball, Obstacle) {
var distX = Math.abs(Ball.x - Obstacle.x - Obstacle.w / 2);
var distY = Math.abs(Ball.y - Obstacle.y - Obstacle.h / 2);
if (distX > (Obstacle.w / 2 + Ball.r)) {
return false;
console.log("no hit");
}
if (distY > (Obstacle.h / 2 + Ball.r)) {
return false;
console.log("no hit");
}
if (distX <= (Obstacle.w / 2)) {
return true;
console.log("hit");
}
if (distY <= (Obstacle.h / 2)) {
return true;
console.log("hit");
}
var dx = distX - Obstacle.w / 2;
var dy = distY - Obstacle.h / 2;
return (dx * dx + dy * dy <= (Ball.r * Ball.r));
}
I can't seem to get it to detect anything, I would appreciate any help. I'm using the p5.js library. I can't seem to get it to detect anything.
In the code you provided the function that checks the collision is never called and when it is, it doesn't work.
Here's my attempt at it. Changed the RectCircleColliding method and called it inside draw.
var balls = [];
var obstacle;
function setup() {
createCanvas(windowWidth, windowHeight);
obstacle = new Obstacle();
}
function draw() {
background(75);
obstacle.display();
for(var i = 0; i < balls.length; i++) {
balls[i].display();
balls[i].update();
balls[i].edges();
console.log(RectCircleColliding(balls[i], obstacle));
}
}
function mousePressed() {
balls.push(new Ball(mouseX, mouseY));
}
function Ball(x, y) {
this.x = x;
this.y = y;
this.r = 15;
this.gravity = 0.5;
this.velocity = 0;
this.display = function() {
fill(255, 0 , 100);
stroke(255);
ellipse(this.x, this.y, this.r*2);
}
this.update = function() {
this.velocity += this.gravity;
this.y += this.velocity;
}
this.edges = function() {
if (this.y >= windowHeight - this.r*2) {
this.y = windowHeight - this.r*2;
this.velocity = this.velocity* -1;
this.gravity = this.gravity * 1.1;
}
}
}
function Obstacle() {
this.x = windowWidth - windowWidth;
this.y = windowHeight / 2;
this.w = 200;
this.h = 25;
this.display = function() {
fill(0);
stroke(255);
rect(this.x, this.y, this.w, this.h);
}
}
function RectCircleColliding(Ball, Obstacle) {
// define obstacle borders
var bRight = Obstacle.x + Obstacle.w;
var bLeft = Obstacle.x;
var bTop = Obstacle.y;
var bBottom = Obstacle.y + Obstacle.h;
//compare ball's position (acounting for radius) with the obstacle's border
if(Ball.x + Ball.r > bLeft)
if(Ball.x - Ball.r < bRight)
if(Ball.y + Ball.r > bTop)
if(Ball.y - Ball.r < bBottom)
return(true);
return false;
}
Related
i have a simple pong game where i can shot the ball and check for colisions at the moment. I had the colisions with X and Y working, but since i added angles to the ball trajectory the colisions at X coordinate sometimes fail, dunno why. So this is what i have at the moment, the colisions checking is handled by the ballMovementHandler function.
var canvas;
var ctx;
var player;
var ball;
var gameStarted;
var flagY;
var flagX;
var angle;
function init() {
canvas = document.getElementById('myCanvas')
if (canvas.getContext) {
ctx = canvas.getContext('2d')
setCanvasSize(ctx)
player = new Player()
ball = new Ball()
attachKeyboardListeners()
reset();
animate();
}
}
function reset() {
flagX = -1;
flagY = -1;
angle = 90;
gameStarted = false
player = new Player();
ball = new Ball();
}
function animate () {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
drawIce()
player.drawPlayer();
ball.drawBall();
playerMovementeHandler()
if(gameStarted) {
ballMovementHandler();
}
window.requestAnimationFrame(animate);
}
function playerMovementeHandler() {
if(player.left === true) {
if(player.x > 0) {
player.movePlayer(-SPEED);
if(!gameStarted) {
ball.moveBallWithPlayer(-SPEED);
}
}
}
if(player.right === true) {
if(player.x + player.width < ctx.canvas.width) {
player.movePlayer(SPEED);
if(!gameStarted) {
ball.moveBallWithPlayer(SPEED);
}
}
}
}
function ballMovementHandler() {
if(ball.y - ball.radius <= 0) {
flagY = 1;
}
if(ball.y + ball.radius === player.y) {
if(ball.x + ball.radius >= player.x && ball.x < player.x + player.width) {
angle = playerAngleHandler()
flagY = -1;
}
else {
reset();
}
}
if(ball.x - ball.radius <= 0) {
flagX = 1;
}
if(ball.x + ball.radius >= ctx.canvas.width) {
flagX = -1;
}
radians = angle * Math.PI/ 180;
ball.moveBallY(Math.sin(radians) * ball.speed * flagY);
ball.moveBallX(Math.cos(radians) * ball.speed * flagX);
}
function playerAngleHandler() {
var angle = 90;
if(ball.x + ball.radius <= player.x + 25) {
angle = 35;
} else if(ball.x + ball.radius >= player.x + player.width - 25) {
angle = 135;
} else if(ball.x + ball.radius >= player.x + player.width - 50) {
angle = 120
} else if(ball.x + ball.radius <= player.x + 50 ) {
angle = 50;
} else if(ball.x + ball.radius <= player.x + 75) {
angle = 75;
} else if( ball.x + ball.radius >= player.x + player.width - 75 ) {
angle = 100;
}
return angle;
}
function drawIce() {
ctx.fillStyle = 'rgb(134,214,216)'
ctx.fillRect(0,ctx.canvas.height - Y_OFFSET + player.height + 10, ctx.canvas.width, Y_OFFSET)
}
function setCanvasSize() {
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
}
function keyboardEvent(keyCode, keyStatus) {
switch(keyCode) {
case 37:
player.left = keyStatus;
break;
case 39:
player.right = keyStatus;
break;
case 32:
gameStarted = true;
break;
}
}
function attachKeyboardListeners() {
document.addEventListener('keydown', function(e) {
keyboardEvent(e.keyCode, true)
})
document.addEventListener('keyup', function(e) {
keyboardEvent(e.keyCode, false)
})
}
init();
ball.js
// defines player configuration behaviour
const BALL_POSITION_Y = 100;
const RADIUS = 12;
const BALL_SPEED = 10;
function Ball(x = ctx.canvas.width/2, y = ctx.canvas.height - Y_OFFSET - RADIUS, radius = RADIUS, color = 'rgb(100,149,237)', speed = BALL_SPEED) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.speed = speed;
this.drawBall = function() {
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x,this.y,this.radius,0,2*Math.PI);
ctx.fill();
}
// for inital game started
this.moveBallWithPlayer = function(deltaX) {
this.x += deltaX;
}
this.moveBallY = function(flag) {
this.y = this.y + flag;
}
this.moveBallX = function(flag) {
this.x = this.x + flag;
}
}
player.js
// defines player configuration behaviour
const PLAYER_WIDTH = 200;
const Y_OFFSET = 100;
const PLAYER_HEIGHT = 30;
const SPEED = 6;
function Player(x = ctx.canvas.width/2 - PLAYER_WIDTH/2, y = ctx.canvas.height - Y_OFFSET, width = PLAYER_WIDTH, height = PLAYER_HEIGHT, color = 'rgba(0,0,0)') {
this.left = false;
this.right = false;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.color = color;
this.movePlayer = function(deltaX) {
this.x += deltaX;
}
this.drawPlayer = function() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
Following the collision between a ball from an array and an object (rectangle), the ball doesn't seem to have the same bounce affect as it has when it hits the ground.
When coming into contact with the object, it seems to pick up speed and suddenly glitches through and comes to rest on the ground.
Questions:
Why does it seem to want to rest on the ground and not on the object itself?
How can I make the ball have the same bounce affect when coming into contact with the object as it has when coming into contact with the ground?
Code:
var balls = [];
var obstacle;
function setup() {
createCanvas(400, 400);
obstacle = new Obstacle();
}
function draw() {
background(75);
obstacle.display();
for (var i = 0; i < balls.length; i++) {
balls[i].display();
balls[i].update();
balls[i].edges();
RectCircleColliding(balls[i], obstacle);
//console.log(RectCircleColliding(balls[i], obstacle));
}
}
function mousePressed() {
balls.push(new Ball(mouseX, mouseY));
}
function Ball(x, y) {
this.x = x;
this.y = y;
this.r = 15;
this.gravity = 0.5;
this.velocity = 0;
this.display = function() {
fill(255, 0, 100);
stroke(255);
ellipse(this.x, this.y, this.r * 2);
}
this.update = function() {
this.velocity += this.gravity;
this.y += this.velocity;
}
this.edges = function() {
if (this.y >= height - this.r) {
this.y = height - this.r;
this.velocity = this.velocity * -1;
this.gravity = this.gravity * 1.1;
}
}
}
function Obstacle() {
this.x = width - width;
this.y = height / 2;
this.w = 200;
this.h = 25;
this.display = function() {
fill(0);
stroke(255);
rect(this.x, this.y, this.w, this.h);
}
}
function RectCircleColliding(Ball, Obstacle) {
// define obstacle borders
var oRight = Obstacle.x + Obstacle.w;
var oLeft = Obstacle.x;
var oTop = Obstacle.y;
var oBottom = Obstacle.y + Obstacle.h;
//compare ball's position (acounting for radius) with the obstacle's border
if (Ball.x + Ball.r > oLeft) {
if (Ball.x - Ball.r < oRight) {
if (Ball.y + Ball.r > oTop) {
if (Ball.y - Ball.r < oBottom) {
Ball.y = Obstacle.y - Ball.r * 2;
Ball.velocity = Ball.velocity * -1;
Ball.gravity = Ball.gravity * 1.1;
Ball.velocity += Ball.gravity;
Ball.y += Ball.velocity;
return (true);
}
}
}
}
return false;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.min.js"></script>
The main issue with this question's code is that we need to check for collisions and only allow updates when the ball is not colliding. Another issue was that when collisions occur we must cap the gravity to prevent the ball from plunging all the way to the ground.
Here is the corrected code:
var balls = [];
var obstacle;
function setup() {
createCanvas(400, 400);
obstacle = new Obstacle();
}
function draw() {
background(75);
obstacle.display();
for (var i = 0; i < balls.length; i++) {
balls[i].display();
if (!RectCircleColliding(balls[i], obstacle)){
balls[i].update();
balls[i].edges();
}
//console.log(RectCircleColliding(balls[i], obstacle));
}
}
function mousePressed() {
balls.push(new Ball(mouseX, mouseY));
}
function Ball(x, y) {
this.x = x;
this.y = y;
this.r = 15;
this.gravity = 0.5;
this.velocity = 0;
this.display = function() {
fill(255, 0, 100);
stroke(255);
ellipse(this.x, this.y, this.r * 2);
}
this.update = function() {
this.velocity += this.gravity;
this.y += this.velocity;
}
this.edges = function() {
if (this.y >= height - this.r) {
this.y = height - this.r;
this.velocity = this.velocity * -1;
this.gravity = this.gravity * 1.1;
}
}
}
function Obstacle() {
this.x = width - width;
this.y = height / 2;
this.w = 200;
this.h = 25;
this.display = function() {
fill(0);
stroke(255);
rect(this.x, this.y, this.w, this.h);
}
}
function RectCircleColliding(Ball, Obstacle) {
// define obstacle borders
var oRight = Obstacle.x + Obstacle.w;
var oLeft = Obstacle.x;
var oTop = Obstacle.y;
var oBottom = Obstacle.y + Obstacle.h;
//compare ball's position (acounting for radius) with the obstacle's border
if (Ball.x + Ball.r > oLeft) {
if (Ball.x - Ball.r < oRight) {
if (Ball.y + Ball.r > oTop) {
if (Ball.y - Ball.r < oBottom) {
let oldY = Ball.y;
Ball.y = oTop - Ball.r;
Ball.velocity = Ball.velocity * -1;
if (Ball.gravity < 2.0){
Ball.gravity = Ball.gravity * 1.1;
} else {
Ball.velocity = 0;
Ball.y = oldY;
}
return (true);
}
}
}
}
return false;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.min.js"></script>
I'm having trouble with how I remove bricks. The bricks are part of an array, and the ball continuously runs a for loop checking to see if it's hit any bricks. If it does, it splices that brick from the array. But the bricks don't disappear!
//Helper Functions
function AABBIntersect(ax, ay, aw, ah, bx, by, bw, bh) {
return ax < bx+bw && ay < by+bh && bx < ax+aw && by < ay+ah;
}
var ball = {
//A few of the basic variables called by the upcoming function
update: function() {
this.x += this.vel.x;
this.y += this.vel.y;
if (0 > this.y) {
var offset = 0 - this.y;
this.y += 2*offset;
this.vel.y *= -1;
}
if (this.y+this.height > HEIGHT) {
this.serve();
}
if (0 > this.x || this.x+this.size > WIDTH) {
var offset = this.vel.x < 0 ? 0 - this.x : WIDTH - (this.x+this.size);
this.x += 2*offset;
this.vel.x *= -1;
}
if (AABBIntersect(this.x, this.y, this.size, this.size, player.x, player.y, player.width, player.height)) {
var offset = player.y - (this.y+this.size);
this.y += 2*offset;
var n = (this.x+this.size - player.x)/(player.width+this.size);
var phi = 0.25*pi*(2*n - 1);
var smash = Math.abs(phi) > 0.2*pi ? 1.5 : 1;
this.vel.x = smash*this.speed*Math.sin(phi);
this.vel.y = smash*-1*this.speed*Math.cos(phi);
}
for (var i = 0; i < bricks.length; i++) {
var b = bricks[i];
if (AABBIntersect(this.x, this.y, this.width, this.height, b.x, b.y, b.width, b.height)) {
bricks.splice(i, 1);
i--;
bricks.length--;
continue;
}
}
}
}
var bricks = [];
function main() {
canvas = document.createElement("canvas");
canvas.width = WIDTH;
canvas.height = HEIGHT;
ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
keystate = {};
document.addEventListener("keydown", function(evt) {
keystate[evt.keyCode] = true;
});
document.addEventListener("keyup", function(evt) {
delete keystate[evt.keyCode];
} );
init();
var loop = function() {
update();
draw();
window.requestAnimationFrame(loop, canvas);
};
window.requestAnimationFrame(loop, canvas);
}
function init() {
var cols = WIDTH / 40;
player.x = (WIDTH - player.width) / 2;
player.y = HEIGHT - (player.height * 2);
ball.x = (WIDTH - ball.size) / 2;
ball.y = player.y - ball.size;
ball.width = ball.size;
ball.height = ball.size;
ball.serve();
for (var i = 0; i < 7; i++) {
for (var j = 0; j < cols; j++) {
bricks.push({
color: "#f00",
x: 2 + j*40,
y: 2 + i*20,
w: 36,
h: 16
});
}
}
}
function update() {
frames++;
player.update();
ball.update();
}
function draw() {
ctx.fillRect(0, 0, WIDTH, HEIGHT);
ctx.save();
ctx.fillStyle = "#fff";
player.draw();
ball.draw();
for (var i = 0; i < bricks.length; i++) {
ctx.fillStyle = bricks[i].color;
ctx.fillRect(bricks[i].x, bricks[i].y, bricks[i].w, bricks[i].h);
}
ctx.restore();
}
main();
A few issues:
The brick objects do not have width or height properties, but w and h;
The splice should not happen on a brick element (b), but on the array of bricks (bricks);
The length of bricks should not be decremented after the splice, as that operation already reduces the length.
So use this loop:
for (var i = 0; i < bricks.length; i++) {
var b = bricks[i];
if (AABBIntersect(this.x, this.y, this.width, this.height, b.x, b.y, b.w, b.h)) {
bricks.splice(i, 1);
i--;
}
}
I'm trying to make 2 rows and 5 columns of bricks using an object, but It doesn't seem to be working. I tried looking it up and using arrays, but It still didn't seem to work.
The bricks have a class of Brick
Demo
Here's the JavaScript
let canvas = $("#canvas")[0];
let ctx = canvas.getContext("2d");
let mouseX = 0;
let mouseY = 0;
class Paddle {
constructor(x, y, w, h, color) {
this.x = canvas.width / 2 - 100 / 2;
this.y = canvas.height - 60;
this.w = 100;
this.h = 10;
this.color = "#fff";
}
draw() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.w, this.h);
}
}
class Ball {
constructor (x, y, r, speedX, speedY, color) {
this.x = canvas.width / 2 - 10 / 2;
this.y = canvas.height / 2 - 10 / 2;
this.r = 10;
this.speedX = 3;
this.speedY = 3;
this.color = "#fff";
}
draw() {
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
ctx.fill();
}
animate() {
this.x += this.speedX;
this.y += this.speedY;
}
collision() {
if(this.x >= canvas.width) {
this.speedX *= -1;
}
if(this.x <= 0) {
this.speedX *= -1;
}
if(this.y >= canvas.height) {
this.reset();
}
if(this.y <= 0) {
this.speedY *= -1;
}
let paddleTop = paddle.y;
let paddleBottom = paddleTop + paddle.h;
let paddleLeft = paddle.x;
let paddleRight = paddle.x + paddle.w;
if(ball.x >= paddleLeft &&
ball.x <= paddleRight &&
ball.y >= paddleTop &&
ball.y <= paddleBottom) {
ball.speedY *= -1;
ballControl();
}
}
reset() {
this.speedX = 3;
this.speedY = 3;
this.x = canvas.width / 2 - 10 / 2;
this.y = canvas.height / 2 - 10 / 2;
}
}
class Brick {
constructor(x, y, w, h, col, row, gap, color) {
this.x = 0;
this.y = 0;
this.w = 100;
this.h = 50;
this.col = 5; //# of brick columns
this.row = 2; //# of brick rows
this.gap = 2; //gap betweeb each brick
this.color = "#0000ff";
}
draw() {
for(let brickRow = 0; brickRow < this.row; brickRow++) {
for(let brickCol = 0; brickCol < this.col; brickCol++) {
ctx.fillStyle = this.color;
ctx.fillRect(this.x * brickCol, this.y * brickRow, this.w - this.gap, this.h - this.gap);
}
}
}
}
let paddle = new Paddle(this.x, this.y, this.w, this.h, this.color);
let ball = new Ball(this.x, this.y, this.r, this.speedX, this.speedY, this.color);
let brick = new Brick(this.x, this.y, this.w, this.h, this.col, this.row, this.gap, this.color);
// START
$(document).ready(() => {
let fps = 120;
setInterval(init, 1000 / fps);
$(canvas).bind("mousemove", paddleControl);
})
// INIT
let init = () => {
draw();
animate();
collision();
}
// DRAW
let draw = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
paddle.draw();
ball.draw();
brick.draw();
}
// ANIMATE
let animate = () => {
ball.animate();
}
// COLLISION
let collision = () => {
ball.collision();
}
// BALL CONTROL
let ballControl = () => {
let paddleCenter = paddle.x + paddle.w / 2;
let ballDistFromPaddleCenter = ball.x - paddleCenter;
ball.speedX = ballDistFromPaddleCenter * 0.15;
}
// PADDLE CONTROL
let paddleControl = (e) => {
let rect = canvas.getBoundingClientRect();
let root = document.documentElement;
mouseX = e.pageX - rect.left - root.scrollLeft;
mouseY = e.pageY - rect.top - root.scrollTop;
paddle.x = mouseX;
}
"Doesn't seem to work" is insufficient when describing your problem. You need to say what you expect and what you observe. Failing to do so has attracted 2 close votes for the reason that the question is unclear.
One of your problems is the way that you calculate the position of each brick.
Another potential problem is that you have one object representing all bricks, a better way would be for each brick to be it's own object - this will simplify collision detection (a lot!)
Your code also relies upon the script element appearing after all of the HTML - while functional, this is a broken paradigm. While it is good practise to put it after the html, so that the content is first rendered as soon as possible, having code that only works when it's put there is not so good. For instance - the classes wont initialise before the canvas has been located (since they rely on it's width - a better option would be to have them rely on a separate width variable, which is set to the width of the canvas during page init)
Couldn't get the fiddle to work, nor a snippet for that matter. But here's your code reworked a little. I can now see 2 rows of 5 blue bricks.
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<style>
#canvas {
position: absolute;
background-color: #000;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
</style>
<head>
<body>
<canvas id="canvas" width="600" height="500"></canvas>
<script>
var canvas, ctx, mouseX=0, mouseY=0;
canvas = $("#canvas")[0];
ctx = canvas.getContext("2d");
mouseX = 0;
mouseY = 0;
class Paddle
{
constructor(x, y, w, h, color)
{
this.x = canvas.width / 2 - 100 / 2;
this.y = canvas.height - 60;
this.w = 100;
this.h = 10;
this.color = "#fff";
}
draw()
{
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.w, this.h);
}
}
class Ball {
constructor (x, y, r, speedX, speedY, color) {
this.x = canvas.width / 2 - 10 / 2;
this.y = canvas.height / 2 - 10 / 2;
this.r = 10;
this.speedX = 3;
this.speedY = 3;
this.color = "#fff";
}
draw() {
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
ctx.fill();
}
animate() {
this.x += this.speedX;
this.y += this.speedY;
}
collision() {
if(this.x >= canvas.width) {
this.speedX *= -1;
}
if(this.x <= 0) {
this.speedX *= -1;
}
if(this.y >= canvas.height) {
this.reset();
}
if(this.y <= 0) {
this.speedY *= -1;
}
let paddleTop = paddle.y;
let paddleBottom = paddleTop + paddle.h;
let paddleLeft = paddle.x;
let paddleRight = paddle.x + paddle.w;
if(ball.x >= paddleLeft &&
ball.x <= paddleRight &&
ball.y >= paddleTop &&
ball.y <= paddleBottom) {
ball.speedY *= -1;
ballControl();
}
}
reset() {
this.speedX = 3;
this.speedY = 3;
this.x = canvas.width / 2 - 10 / 2;
this.y = canvas.height / 2 - 10 / 2;
}
}
class Brick {
constructor(x, y, w, h, col, row, gap, color) {
this.x = 0;
this.y = 0;
this.w = 100;
this.h = 50;
this.col = 5; //# of brick columns
this.row = 2; //# of brick rows
this.gap = 2; //gap betweeb each brick
this.color = "#0000ff";
}
draw() {
for(let brickRow = 0; brickRow < this.row; brickRow++)
{
for(let brickCol = 0; brickCol < this.col; brickCol++)
{
ctx.fillStyle = this.color;
ctx.fillRect( (this.w+this.gap) * brickCol, (this.h+this.gap) * brickRow, this.w, this.h );
}
}
}
}
let paddle = new Paddle(this.x, this.y, this.w, this.h, this.color);
let ball = new Ball(this.x, this.y, this.r, this.speedX, this.speedY, this.color);
let brick = new Brick(this.x, this.y, this.w, this.h, this.col, this.row, this.gap, this.color);
// START
$(document).ready(() => {
let fps = 120;
setInterval(init, 1000 / fps);
$(canvas).bind("mousemove", paddleControl);
})
// INIT
let init = () => {
draw();
animate();
collision();
}
// DRAW
let draw = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
paddle.draw();
ball.draw();
brick.draw();
}
// ANIMATE
let animate = () => {
ball.animate();
}
// COLLISION
let collision = () => {
ball.collision();
}
// BALL CONTROL
let ballControl = () => {
let paddleCenter = paddle.x + paddle.w / 2;
let ballDistFromPaddleCenter = ball.x - paddleCenter;
ball.speedX = ballDistFromPaddleCenter * 0.15;
}
// PADDLE CONTROL
let paddleControl = (e) => {
let rect = canvas.getBoundingClientRect();
let root = document.documentElement;
mouseX = e.pageX - rect.left - root.scrollLeft;
mouseY = e.pageY - rect.top - root.scrollTop;
paddle.x = mouseX;
}
</script>
</body>
</html>
Been trying to animate an object on canvas by putting it in an array but it wont seem to work.
Only have one object drawn at the moment but the thought is to add several more objects to the canvas hence the array.
Is there something wrong with the functions im using to draw and animate the object?
var draw;
function Canvas(canvas, ctx) {
this.canvas = canvas;
this.ctx = ctx;
}
function Direction(x, y) {
this.x = x;
this.y = y;
}
function Measures(cW, cH, radius, hR, degree, dirX, dirY, degree) {
this.cW = cW;
this.cH = cH;
this.radius = radius;
this.hR = hR;
this.dirX = dirX;
this.dirY = dirY;
this.degree = degree;
}
function Drawing(cW, cH, width, height, radius, hR, color) {
this.cW = canvas.width;
this.cH = canvas.height;
this.width = width;
this.height = height;
this.radius = height / 2;
this.hR = width - this.radius;
this.color = color;
this.render = function() {
ctx.fillStyle = this.color;
ctx.strokeStyle = this.color;
ctx.lineWidth = 1;
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(this.degree * Math.PI / 180);
ctx.translate(-this.x, -this.y);
ctx.beginPath();
ctx.moveTo(this.x, this.y);
ctx.lineTo(x + this.hR, this.y);
ctx.arc(this.x + this.hR, this.y + this.radius, this.radius, - Math.PI / 2, Math.PI / 2);
ctx.lineTo(this.x, this.y + height);
ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.restore();
}
this.move = function(multiplier) {
var multiplier = 2;
var borders = 5;
if(this.dirX > 0 && this.x > this.cW - borders - width){
this.degree = 90;
this.dirX = 0;
this.dirY = 1;
this.x = cW - borders;
}
else if(this.dirY > 0 && this.y > this.cH - borders - width){
this.degree = 180;
this.dirX = -1;
this.dirY = 0;
this.y = this.cH - borders;
}
else if(this.dirX < 0 && this.x < borders + width){
this.degree = -90;
this.dirX = 0;
this.dirY = -1;
this.x = borders;
}
else if(this.dirY < 0 && this.y < borders + width){
this.degree = 0;
this.dirX = 1;
this.dirY = 0;
this.y = borders;
}
this.x += this.dirX * multiplier;
this.y += this.dirY * multiplier;
this.render();
}
}
function animate() {
ctx.clearRect(0, 0, this.cW, this.cH);
draw.forEach(function(object) {
object.render(2);
});
requestAnimationFrame(animate);
}
function init() {
this.canvas = document.getElementById("my_canvas");
this.ctx = canvas.getContext("2d");
this.degree = Math.PI / 2;
draw = [];
draw.push(new Drawing(5, 5, 80, 60, new Direction(1,0), "#E5E5E5"));
animate();
}
window.onload = init;
</script>
<canvas id="my_canvas" width="1000" height="800" style="background-color:#33CC33"></canvas>