Why isnt collision detection working? (p5 js frame work) - javascript

I created a collision detection between Snake and BasicEnemy. I created a for loop to make five different enemies but the collision detection doesn't get called on any of the enemies that were created from the for loop. The collision only works with the one BasicEnemy object. Why isn't collision function being called for all of the enemies inside the array? Thank you.
Sketch.js
var snake;
var food;
var basicEnemy;
var scl = 20;
var enemies = [];
function setup() {
createCanvas(600, 500);
snake = new Snake();
basicEnemy = new BasicEnemy();
//** CREATE FIVE ENEMIES **
for (var i = 0; i < 5; i++) {
enemies[i] = new BasicEnemy();
}
}
// **FUNCTION WHEN SNAKE HITS ENEMY**
function collision() {
console.log("hit!");
}
function draw() {
background(51);
//Draw snake
snake.update();
snake.show();
//Draw basicEnemy
basicEnemy.update();
basicEnemy.show();
//** LOOP THROUGH ENEMIES AND UPDATE AND SHOW **
for (var i = 0; i < enemies.length; i++) {
enemies[i].show();
enemies[i].update();
if (enemies[i].hits(snake)) {
collision();
}
}
}
function keyPressed() {
if (keyCode === UP_ARROW){
snake.dir(0, -1);
} else if (keyCode === DOWN_ARROW) {
snake.dir(0, 1);
} else if (keyCode === LEFT_ARROW) {
snake.dir(-1 , 0);
} else if (keyCode === RIGHT_ARROW) {
snake.dir(1 , 0);
}
}
BasicEnemy.js
function BasicEnemy() {
this.x = random(700);
this.y = random(700);
this.velX = 15;
this.velY = 15;
}
//** FUNCTION TO CHECK IF ENEMY AND SNAKE ARE IN THE SAME LOCATION **
this.hits = function (pos) {
var = d = dist(this.x, this.y, pos.x, pos.y);
if(d < 1) {
return true;
} else {
return false;
}
}
this.show = function () {
fill(255, 0, 100);
rect(this.x, this.y, scl, scl);
}
Snake.js
function Snake() {
this.x = 0;
this.y = 0;
this.xspeed = 1;
this.yspeed = 0;
this.update = function() {
this.x = this.x + this.xspeed * scl;
this.y = this.y + this.yspeed * scl;
this.x = constrain(this.x, 0, width - scl);
this.y = constrain(this.y, 0, height - scl);
}
this.show = function() {
fill(255);
rect(this.x, this.y, scl, scl);
}
this.dir = function (x , y) {
this.xspeed = x;
this.yspeed = y;
}
}

Because you're essentially checking for the distance between the top left corners of the snake and the enemy, this'll only return true, if they completely overlap.
Use an AABB collision detection instead:
return this.x + scl >= pos.x && this.x <= pos.x + scl && this.y + scl >= pos.y && this.y <= pos.y + scl;
This returns true, if the first rectangle contains the second rectangle.
MDN says:
One of the simpler forms of collision detection is between two rectangles that are axis aligned — meaning no rotation. The algorithm works by ensuring there is no gap between any of the 4 sides of the rectangles. Any gap means a collision does not exist.

Related

Rotate the user character on mouse position

I'm trying to get the character to rotate the character object based on where the mouse is.
So far I got it to rotate incrementally without mouse position. I was checking if it effected my zombie's chasing capabilities.
My script
let player, zombie, mouseX, mouseY;;
let bgCanvas = document.getElementById('backgroundCan');
function startGame() {
document.getElementById("startScreen").style.display = "none";
player = new playerComponent(350, 220);
zombie = new zombieComponent(750, 220);
gameArea.start();
}
let gameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 800;
this.canvas.height = 500;
this.canvas.style = "position: absolute";
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[2]);
this.interval = setInterval(updateArea, 20);
window.addEventListener('keydown', function (e) {
gameArea.keys = (gameArea.keys || []);
gameArea.keys[e.keyCode] = true;
})
window.addEventListener('keyup', function (e) {
gameArea.keys[e.keyCode] = false;
});
this.canvas.addEventListener("mousemove", function(e){
mouseX = e.clientX - ctx.canvas.offsetLeft;
mouseY = e.clientY - ctx.canvas.offsetTop;
});
this.canvas.addEventListener("mousedown", function(e){
let gShot = new Audio('assets/shot.mp3');
gShot.play();
var mX = e.clientX - ctx.canvas.offsetLeft;
var mY = e.clientY - ctx.canvas.offsetTop;
if(mX >= zombie.x && mX < zombie.x+zombie.w && mY >= zombie.y && mY < zombie.y+zombie.h){
if(zombie.health > 0){
zombie.health += -1;
zombie.speedX += 10;
zombie.newPos();
zombie.update();
}
else {
zombie.status = "dead";
}
}
});
},
clear : function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}
function playerComponent(x, y){
this.x = x;
this.y = y;
this.speedX = 0;
this.speedY = 0;
this.health = 10;
this.status = "alive";
let rotNum = 1;
this.update = function(){
ctx = gameArea.context;
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(rotNum * Math.PI / 180);
playerSprite = new Image();
playerSprite.src = "assets/playerGun.png";
ctx.drawImage(playerSprite, 0, 0);
ctx.restore();
rotNum++;
}
this.newPos = function() {
this.x += this.speedX;
this.y += this.speedY;
}
}
function updateArea() {
gameArea.clear();
if(player.status == "alive"){
player.speedX = 0;
player.speedY = 0;
if (gameArea.keys && gameArea.keys[65]) {
if(player.x > 20){
player.speedX = -3;
}
}
if (gameArea.keys && gameArea.keys[68]) {
if(player.x < 740){
player.speedX = 3;
}
}
if (gameArea.keys && gameArea.keys[87]) {
if(player.y > 20){
player.speedY = -3;
}
}
if (gameArea.keys && gameArea.keys[83]) {
if(player.y < 445){
player.speedY = 3;
}
}
player.newPos();
player.update();
}
if(zombie.status == "alive"){
if(zombie.x > player.x){
zombie.speedX = -1;
}
else{
zombie.speedX = 1;
}
if(zombie.y > player.y){
zombie.speedY = -1;
}
else{
zombie.speedY = 1;
}
zombie.newPos();
zombie.update();
}
else{
zombie.update();
}
}
So far, I have the mouse position on the canvas and am able to rotate the character, but I just don't how to connect the two. How should use the mouse position and the character position to rotate towards the mouse? The character is initially facing right (i think?), at least the sprite initially is.
Here's an image illustrating the situation:
You have the mouseY, playerY and mouseX, playerX
Therefore you can calculate the height and base of the triangle,
Thus the angle with
However, since in the second and third quadrants y/x will return an angle in the first and fourth quadrants, you need to use the Math.atan2(y,x) function in Javascript, not Math.atan(y/x). This will give you an angle between -180 and 180 instead of between -90 and 90.
Atan Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2
Then all you have to do is rotate based on the angle!
(P.S. Remember that you will have to convert between radians and degrees)

Particle (made with constructor) expand and fade upon collision

When a user clicks on any particle I want it to expand and fade and upon collision with any other particle and that particle will also expand and fade. Now my problem is that I want to know if there is a way in which I can get those particles (made with constructor in this case) to effect each other when they get collide. Link to Codepen
var bubbles = [];
function setup() {
frameRate(25);
// Creates Canvas
createCanvas(windowWidth, windowHeight);
//Genrates 100 Particles with random a & y
for (var i = 0; i < 80; i++) {
var x = random(width);
var y = random(height);
bubbles[i] = new Bubble(x, y);
}
}
function mousePressed() {
for (var i = 0; i < bubbles.length; i++) {
bubbles[i].clicked();
}
}
function draw() {
clear();
//Adds color and motion
for (var bubble of bubbles) {
fill(bubble.color.red, bubble.color.green, bubble.color.blue);
bubble.move();
bubble.display();
}
}
function Bubble(x, y) {
this.x = x;
this.y = y;
this.wh = 15;
this.speedX = random(1, 5);
this.speedY = random(1, 5);
//Individual Particle Creation
this.display = function() {
noStroke();
ellipse(this.x, this.y, this.wh, this.wh);
};
//Interactivity
this.clicked = function() {
var d = dist(this.x, this.y, mouseX, mouseY);
if (d < 8) {
this.wh = 100;
}
};
//Randomizes colors
this.color = {
red: random(255),
green: random(255),
blue: random(255)
};
//Particle Motion
this.move = function() {
//Motion in X direction
this.x += this.speedX;
//Bouncing back on X-axis
if (this.x > windowWidth || this.x < 0) {
this.speedX = -this.speedX;
}
//Motion in Y Direction
this.y += this.speedY;
//Bouncing back on Y-axis
if (this.y > windowHeight || this.y < 0) {
this.speedY = -this.speedY;
}
};
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
}
::-webkit-scrollbar{
display:none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.10/p5.js"></script>
Use a nested for loop.
Step 1: Loop over the bubbles. Do this with a for loop.
Step 2: For each bubble, loop over the rest of the bubbles (if you're on bubble 4, start with bubble 5). Do this with another for loop inside the first one.
Step 3: Now that you have two bubbles, do the collision between them.
If you're having trouble getting that working, then please start smaller. Start with a simpler program that just shows two hard-coded bubbles and does collision detection between them.

Target Smooth Following [duplicate]

This question already has an answer here:
Comparing x/y of two positions on a canvas
(1 answer)
how to make a canvas element follow another canvas element smoothly at the same speed [duplicate]
Closed 6 years ago.
I'm wondering today how to make a canvas element follow another canvas element smoothly. For example, I'm trying to make a game where a canvas element continually follows the player (which can be moved using W, A, S, & D) smoothly. I had an idea to use the Pythagorean theorem to check for the closest & fastest way to move from Point A (the canvas element) to Point B (the player). However, I have no physical way to do this. Does anyone have any ideas or answers of how I could make a canvas element constantly follow a player as smoothly as possible so it reaches the player the fastest?
Here I have an example of a very bad way of following:
<!DOCTYPE html>
<html>
<head>
<title>Target Following Test</title>
</head>
<body>
<script src="https://code.jquery.com/jquery-2.1.0.js"></script>
<center>
<canvas id="canvas" width="800" height="500"></canvas>
</center>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var width = canvas.width;
var height = canvas.height;
var circle = function(x, y, radius, fillCircle, color) {
ctx.beginPath();
ctx.fillStyle = color;
ctx.arc(x, y, radius, 0, Math.PI * 2, false);
if (fillCircle) {
ctx.fill();
} else {
ctx.stroke();
}
};
var drawRect = function(x, y, color) {
ctx.fillStyle = color;
ctx.fillRect(x, y, 20, 20)
}
//Moving Obstacle
var Obstacle = function(x, y) {
this.x = x;
this.y = y;
this.vSpeed = 0;
this.hSpeed = 0;
}
Obstacle.prototype.drawOb = function(color) {
drawRect(this.x, this.y, "Red")
}
Obstacle.prototype.follow = function() {
this.y += this.vSpeed
this.x += this.hSpeed
if (this.x < ball.x - 9) {
this.hSpeed = 1;
}
if (this.x > ball.x - 10) {
this.hSpeed = -1;
}
if (this.y > ball.y - 10) {
this.vSpeed = -1;
}
if (this.y < ball.y - 9) {
this.vSpeed = 1;
}
}
Obstacle.prototype.checkCollision = function(direction) {
return (ball.x - ball.radius < this.x + 20) &&
(ball.x + ball.radius > this.x) &&
(ball.y - ball.radius < this.y + 20) &&
(ball.y + ball.radius > this.y);
}
// The Ball constructor
var Ball = function() {
this.x = 20
this.y = 20
this.xSpeed = 0;
this.ySpeed = 0;
this.radius = 10;
};
// Draw the ball at its current position
Ball.prototype.draw = function() {
circle(this.x, this.y, 10, true, "Black");
};
Ball.prototype.reposition = function(reX, reY) {
this.x = reX;
this.y = reY;
}
// Update the ball's position based on its speed
Ball.prototype.move = function() {
this.x += this.xSpeed;
this.y += this.ySpeed;
if (this.x < 11) {
this.x = 11;
} else if (this.x > width - 11) {
this.x = width - 11;
} else if (this.y < 11) {
this.y = 11;
} else if (this.y > height - 11) {
this.y = height - 11;
}
};
// Set the ball's direction based on a string
Ball.prototype.setDirection = function(direction) {
if (direction === "up") {
this.xSpeed = 0;
this.ySpeed = -2;
} else if (direction === "down") {
this.xSpeed = 0;
this.ySpeed = 2;
} else if (direction === "left") {
this.xSpeed = -2;
this.ySpeed = 0;
} else if (direction === "right") {
this.xSpeed = 2;
this.ySpeed = 0;
} else if (direction === "stop") {
this.xSpeed = 0;
this.ySpeed = 0;
}
};
function simulate() {
var prev_ball_x = ball.x;
var prev_ball_y = ball.y;
var prev_fol_x = follower.x;
var prev_fol_y = follower.y;
ball.move();
follower.follow()
if (follower.checkCollision()) {
ball.setDirection('stop');
follower.vSpeed = 0;
follower.hSpeed = 0;
follower.x = prev_fol_x;
follower.y = prev_fol_y;
ball.x = prev_ball_x;
ball.y = prev_ball_y;
}
}
function draw() {
ctx.clearRect(0, 0, width, height);
ball.draw();
follower.drawOb();
ctx.strokeRect(0, 0, width, height);
}
// An object to convert keycodes into action names
var keyActions = {
37: "left",
38: "up",
39: "right",
40: "down"
};
// The keydown handler that will be called for every keypress
$("body").keydown(function(event) {
var direction = keyActions[event.keyCode];
ball.setDirection(direction);
});
$("body").keyup(function(event) {
ball.setDirection('stop');
})
setInterval(function() {
// separate drawing and simulating phases
simulate();
draw();
}, 10);
// Create all the Objects!
var ball = new Ball();
var follower = new Obstacle(400, 100);
</script>
</body>
</html>
Note: i haven't really inspected your code...
But hopefully I understand your question correctly. And if I do, the solution could be pretty simple.
The most simple and fast way is to move the canvas element in a straight line to the player, without the help of mr Pythagoras. For that you need to know the player's position (x, y), which you do.
I took an easing function from an AS3 question, but it's the same for JS: AS 3 simple ease
On every update, ease the follower to the position of the player:
follower.x += (player.x - follower.x) / delay;
follower.y += (player.y - follower.y) / delay;
Example: Fiddle
It isn't a drop-in fix for your script, but hopefully it's helpful

Collision detection not working for canvas

I've been trying to make a game but there are obstacles. I have a (ball) player and a square (obstacle) and I can't figure out how to make a collision detection thing to work. Here's my code so far:
<!DOCTYPE html>
<html>
<head>
<title>Ball Race</title>
</head>
<body>
<script src="https://code.jquery.com/jquery-2.1.0.js"></script>
<canvas id="canvas" width="800" height="200"></canvas>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var width = canvas.width;
var height = canvas.height;
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();
}
};
var drawRect = function (x, y) {
ctx.fillRect(x, y, 20, 20)
}
var Object = function () {
this.x = width / 4;
this.y = height / 4;
}
// The Ball constructor
var Ball = function () {
this.x = width / 2;
this.y = height / 2;
this.xSpeed = 5;
this.ySpeed = 0;
};
// Update the ball's position based on its speed
Ball.prototype.move = function () {
this.x += this.xSpeed;
this.y += this.ySpeed;
if (this.x < 11) {
this.x = 11;
} else if (this.x > width - 11) {
this.x = width - 11;
} else if (this.y < 11) {
this.y = 11;
} else if (this.y > height - 11) {
this.y = height - 11;
}
};
// Draw the ball at its current position
Ball.prototype.draw = function () {
circle(this.x, this.y, 10, true);
};
Object.prototype.draw = function () {
drawRect(this.x, this.y)
}
//collision types
Object.prototype.checkCollision = function () {
var col1 = this.x == ball.x && this.y == ball.y;
var col2 = this.x + 1 == ball.x && this.y == ball.y;
var col3 = this.x + 2 == ball.x && this.y == ball.y;
var col4 = this.x + 3 == ball.x && this.y == ball.y;
if (col1 || col2 || col3 || col4) {
alert("COLLISION!");
}
}
// Set the ball's direction based on a string
Ball.prototype.setDirection = function (direction) {
if (direction === "up") {
this.xSpeed = 0;
this.ySpeed = -5;
} else if (direction === "down") {
this.xSpeed = 0;
this.ySpeed = 5;
} else 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 ball = new Ball();
var object = new Object();
// 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
$("body").keydown(function (event) {
var direction = keyActions[event.keyCode];
ball.setDirection(direction);
});
// The animation function, called every 30 ms
setInterval(function () {
ctx.clearRect(0, 0, width, height);
ball.draw();
ball.move();
object.draw();
ctx.strokeRect(0, 0, width, height);
}, 30);
setInterval(function () {
object.checkCollision();
}, 1)
</script>
</body>
</html>
How would you code this? Please give an example similar to mine.
It seems like most of the functionality is there you're just missing the correct logic in the checkCollision. I would change it to something like:
Object.prototype.checkCollision = function() {
var colx = (ball.x-ball.radius<this.x&&ball.x+ball.radius>this.x)||(ball.x-ball.radius<this.x+20&&ball.x+ball.radius>this.x+20);
var coly = (ball.y-ball.radius<this.y&&ball.y+ball.radius>this.y)||(ball.y-ball.radius<this.y+20&&ball.y+ball.radius>this.y+20);
if(colx&&coly){
console.log('collision');
}
}
colx checks the x collision, to see if the ball is in between the objects position. coly does the same thing but for the y variable. If both are true then there is a collision.
I added radius variable to Ball
var Ball = function() {
this.x = width / 2;
this.y = height / 2;
this.xSpeed = 5;
this.ySpeed = 0;
this.radius = 10;
};
Here is a fiddle

Remove object on collision with ball

I know you can fillRect right? And you can clearRect. But what happens if there's an animation and you have to remove an object although it would be redrawn from setInterval. How would you remove the fillRect?
Here's an example:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var width = canvas.width;
var height = canvas.height;
var circle = function (x, y, radius, fillCircle, color) {
ctx.beginPath();
ctx.fillStyle = color;
ctx.arc(x, y, radius, 0, Math.PI * 2, false);
if (fillCircle) {
ctx.fill();
} else {
ctx.stroke();
}
};
var drawRect = function (x, y, color) {
ctx.fillStyle = color;
ctx.fillRect(x, y, 20, 20)
}
var Object = function (xPos, yPos) {
this.x = xPos;
this.y = yPos;
}
// The Ball constructor
var Ball = function () {
this.x = width / 2;
this.y = height / 2;
this.xSpeed = 0;
this.ySpeed = 0;
this.radius = 10;
};
// Update the ball's position based on its speed
Ball.prototype.move = function () {
this.x += this.xSpeed;
this.y += this.ySpeed;
if (this.x < 11) {
this.x = 11;
} else if (this.x > width - 11) {
this.x = width - 11;
} else if (this.y < 11) {
this.y = 11;
} else if (this.y > height - 11) {
this.y = height - 11;
}
};
// Draw the ball at its current position
Ball.prototype.draw = function () {
circle(this.x, this.y, 10, true, "Black");
};
Object.prototype.draw = function () {
drawRect(this.x, this.y, "Black")
}
Object.prototype.drawKey = function (color) {
drawRect(this.x, this.y, "Yellow")
}
Object.prototype.checkCollision = function (direction) {
return (ball.x-ball.radius < this.x + 20)
&& (ball.x+ball.radius > this.x)
&& (ball.y-ball.radius < this.y + 20)
&& (ball.y+ball.radius > this.y)
;
}
function draw() {
ctx.clearRect(0, 0, width, height);
ball.draw();
object1.draw("Blue");
object2.draw();
object3.draw();
object4.draw();
object5.draw();
key.drawKey();
ctx.strokeRect(0, 0, width, height);
}
function simulate() {
for (z = 0; z < 5; z++) {
var prev_ball_x = ball.x;
var prev_ball_y = ball.y;
ball.move();
// handle collision here
if (object1.checkCollision() || object2.checkCollision() || object3.checkCollision() || object4.checkCollision() || object5.checkCollision()) {
ball.setDirection('stop');
// reset ball's position so they do not overlap
ball.x = prev_ball_x;
ball.y = prev_ball_y;
}
if (key.checkCollision()) {
ball.x = prev_ball_x;
ball.y = prev_ball_y;
}
}
$("body").keyup(function (event) {
ball.setDirection('stop');
})
}
setInterval(function () {
// separate drawing and simulating phases
simulate();
draw();
}, 30);
// Set the ball's direction based on a string
Ball.prototype.setDirection = function (direction) {
if (direction === "up") {
this.xSpeed = 0;
this.ySpeed = -1;
} else if (direction === "down") {
this.xSpeed = 0;
this.ySpeed = 1;
} else if (direction === "left") {
this.xSpeed = -1;
this.ySpeed = 0;
} else if (direction === "right") {
this.xSpeed = 1;
this.ySpeed = 0;
} else if (direction === "stop") {
this.xSpeed = 0;
this.ySpeed = 0;
}
};
// Create the ball object
var ball = new Ball();
var object1 = new Object(50, 0);
var object2 = new Object(50, 20);
var object3 = new Object(50, 40);
var object4 = new Object(50, 60);
var object5 = new Object(50, 80);
var key = new Object(70, 70);
// An object to convert keycodes into action names
var keyActions = {
37: "left",
38: "up",
39: "right",
40: "down"
};
// The keydown handler that will be called for every keypress
$("body").keydown(function (event) {
var direction = keyActions[event.keyCode];
ball.setDirection(direction);
});
<script src="https://code.jquery.com/jquery-2.1.0.js"></script>
<canvas id="canvas" width="800" height="200"></canvas>
You move around a ball with your arrow keys. When I collide with the yellow block, I want it to disappear. Using clearRect would not work simply because it would be redrawn in the setInterval. How would I make it disappear?
Generally when you have several items in a game you place them into a sort of objects array, then when you draw you loop through and call .draw() on each item. Doing it this way allows you to remove items you do not want (such as key), and as such it will no longer be drawn. In your case one thing we could do (assuming there is only a single key) is give your ball a hasKey property. And on collision set it from false to true. Then inside draw, if you wish to also remove the collisions you would do !ball.hasKey && key.checkCollision() inside your collision conditional for the key:
if(!ball.hasKey) key.drawKey();
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var width = canvas.width;
var height = canvas.height;
var circle = function (x, y, radius, fillCircle, color) {
ctx.beginPath();
ctx.fillStyle = color;
ctx.arc(x, y, radius, 0, Math.PI * 2, false);
if (fillCircle) {
ctx.fill();
} else {
ctx.stroke();
}
};
var drawRect = function (x, y, color) {
ctx.fillStyle = color;
ctx.fillRect(x, y, 20, 20)
}
var Object = function (xPos, yPos) {
this.x = xPos;
this.y = yPos;
}
// The Ball constructor
var Ball = function () {
this.x = width / 2;
this.y = height / 2;
this.xSpeed = 0;
this.ySpeed = 0;
this.radius = 10;
this.hasKey = false;
};
// Update the ball's position based on its speed
Ball.prototype.move = function () {
this.x += this.xSpeed;
this.y += this.ySpeed;
if (this.x < 11) {
this.x = 11;
} else if (this.x > width - 11) {
this.x = width - 11;
} else if (this.y < 11) {
this.y = 11;
} else if (this.y > height - 11) {
this.y = height - 11;
}
};
// Draw the ball at its current position
Ball.prototype.draw = function () {
circle(this.x, this.y, 10, true, "Black");
};
Object.prototype.draw = function () {
drawRect(this.x, this.y, "Black")
}
Object.prototype.drawKey = function (color) {
drawRect(this.x, this.y, "Yellow")
}
Object.prototype.checkCollision = function (direction) {
return (ball.x-ball.radius < this.x + 20)
&& (ball.x+ball.radius > this.x)
&& (ball.y-ball.radius < this.y + 20)
&& (ball.y+ball.radius > this.y)
;
}
function draw() {
ctx.clearRect(0, 0, width, height);
ball.draw();
object1.draw("Blue");
object2.draw();
object3.draw();
object4.draw();
object5.draw();
if(!ball.hasKey) key.drawKey();
ctx.strokeRect(0, 0, width, height);
}
function simulate() {
for (z = 0; z < 5; z++) {
var prev_ball_x = ball.x;
var prev_ball_y = ball.y;
ball.move();
// handle collision here
if (object1.checkCollision() || object2.checkCollision() || object3.checkCollision() || object4.checkCollision() || object5.checkCollision()) {
ball.setDirection('stop');
// reset ball's position so they do not overlap
ball.x = prev_ball_x;
ball.y = prev_ball_y;
}
if (!ball.hasKey && key.checkCollision()) {
ball.x = prev_ball_x;
ball.y = prev_ball_y;
ball.hasKey = true;
}
}
$("body").keyup(function (event) {
ball.setDirection('stop');
})
}
setInterval(function () {
// separate drawing and simulating phases
simulate();
draw();
}, 30);
// Set the ball's direction based on a string
Ball.prototype.setDirection = function (direction) {
if (direction === "up") {
this.xSpeed = 0;
this.ySpeed = -1;
} else if (direction === "down") {
this.xSpeed = 0;
this.ySpeed = 1;
} else if (direction === "left") {
this.xSpeed = -1;
this.ySpeed = 0;
} else if (direction === "right") {
this.xSpeed = 1;
this.ySpeed = 0;
} else if (direction === "stop") {
this.xSpeed = 0;
this.ySpeed = 0;
}
};
// Create the ball object
var ball = new Ball();
var object1 = new Object(50, 0);
var object2 = new Object(50, 20);
var object3 = new Object(50, 40);
var object4 = new Object(50, 60);
var object5 = new Object(50, 80);
var key = new Object(70, 70);
// An object to convert keycodes into action names
var keyActions = {
37: "left",
38: "up",
39: "right",
40: "down"
};
// The keydown handler that will be called for every keypress
$("body").keydown(function (event) {
var direction = keyActions[event.keyCode];
ball.setDirection(direction);
});
<script src="https://code.jquery.com/jquery-2.1.0.js"></script>
<canvas id="canvas" width="800" height="200"></canvas>

Categories

Resources