I am making a game. I want the player to not go outside the circular game region. the player should not cross the red circular line. It should remain inside and could move along the boundary.
I have written a simple function for collision detection between circles. I have found a bug in it too. I am getting a console.log() message of outside even if I am inside the game area.
It's happening when the player is at [x < 0]. Help me out please.
var Game = (function(window) {
var canvas = document.getElementById("game"),
ctx = canvas.getContext("2d");
var SCREEN_WIDTH = window.innerWidth,
SCREEN_HEIGHT = window.innerHeight;
canvas.width = SCREEN_WIDTH;
canvas.height = SCREEN_HEIGHT;
var ROCK = "rock",
PAPER = "paper",
SCISSOR = "scissor";
var BG_IMAGE = document.getElementById("bg");
// this is the game area Radius
var GAME_R = 500;
var offsetX = 0,
offsetY = 0;
var player;
// circle collision detection
function checkCollision(x1, y1, r1, x2, y2, r2) {
var x = x1-x2;
var y = y1-y2;
var d = Math.hypot(x, y);
return d < r1 + r2;
}
function start() {
player = new Entity();
addEventListener("mousemove", function(e) {
var angle = Math.atan2(e.clientY - SCREEN_HEIGHT/2, e.clientX - SCREEN_WIDTH/2);
player.setAngle(angle);
}, true);
animLoop();
}
function update() {
offsetX = player.x - SCREEN_WIDTH/2;
offsetY = player.y - SCREEN_HEIGHT/2;
player.update();
}
function draw() {
ctx.save();
ctx.translate(-offsetX, -offsetY);
// bg
ctx.fillStyle = ctx.createPattern(BG_IMAGE, "repeat");
ctx.fillRect(offsetX, offsetY, SCREEN_WIDTH, SCREEN_HEIGHT);
// game area border
ctx.beginPath();
ctx.arc(0, 0, GAME_R, 0, Math.PI * 2);
ctx.closePath();
ctx.lineWidth = 5;
ctx.strokeStyle = "red";
ctx.stroke();
// player
player.draw();
ctx.restore();
}
function gameLoop() {
update();
// here
if(checkCollision(player.x, player.y, player.x, 0, 0, GAME_R)) {
console.log("inside");
} else {
console.log("outside");
}
draw();
}
function animLoop() {
window.requestAnimationFrame(animLoop);
gameLoop();
}
// player
function Entity() {
var self = {
x: 0,
y: 0,
r: 50,
entityType: PAPER,
angle: 0,
speed: 5
}
self.setSpeed = function(speed) {
this.speed = speed;
}
self.setAngle = function(angle) {
this.angle = angle;
}
self.update = function() {
this.x += this.speed * Math.cos(this.angle);
this.y += this.speed * Math.sin(this.angle);
}
self.draw = function() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
ctx.closePath();
ctx.fillStyle = "grey";
ctx.fill();
ctx.fillStyle = "#fff";
ctx.font = "30px Arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(this.entityType, this.x, this.y);
}
return self;
}
start();
})(window);
<canvas id="game"></canvas>
<div style="display: none;">
<img id="bg" src="https://i.imgur.com/9qjEwiz.png">
</div>
This will check if the inner Circle inside the outer
function checkCollision(cxInner, cyInner, rInner, cxOuter, cyOuter, rOuter) {
return Math.sqrt(Math.pow(cxInner-cxOuter, 2) + Math.pow(cyInner-cyOuter, 2)) < rOuter - rInner;
}
complete code:
var Game = (function(window) {
var canvas = document.getElementById("game"),
ctx = canvas.getContext("2d");
var SCREEN_WIDTH = window.innerWidth,
SCREEN_HEIGHT = window.innerHeight;
canvas.width = SCREEN_WIDTH;
canvas.height = SCREEN_HEIGHT;
var ROCK = "rock",
PAPER = "paper",
SCISSOR = "scissor";
var BG_IMAGE = document.getElementById("bg");
// this is the game area Radius
var GAME_R = 500;
var offsetX = 0,
offsetY = 0;
var player;
// circle collision detection
function checkCollision(cxInner, cyInner, rInner, cxOuter, cyOuter, rOuter) {
return Math.sqrt(Math.pow(cxInner-cxOuter, 2) + Math.pow(cyInner-cyOuter, 2)) < rOuter - rInner;
}
function start() {
player = new Entity();
addEventListener("mousemove", function(e) {
var angle = Math.atan2(e.clientY - SCREEN_HEIGHT/2, e.clientX - SCREEN_WIDTH/2);
player.setAngle(angle);
}, true);
animLoop();
}
function update() {
offsetX = player.x - SCREEN_WIDTH/2;
offsetY = player.y - SCREEN_HEIGHT/2;
player.update();
}
function draw() {
ctx.save();
ctx.translate(-offsetX, -offsetY);
// bg
ctx.fillStyle = ctx.createPattern(BG_IMAGE, "repeat");
ctx.fillRect(offsetX, offsetY, SCREEN_WIDTH, SCREEN_HEIGHT);
// game area border
ctx.beginPath();
ctx.arc(0, 0, GAME_R, 0, Math.PI * 2);
ctx.closePath();
ctx.lineWidth = 5;
ctx.strokeStyle = "red";
ctx.stroke();
// player
player.draw();
ctx.restore();
}
function gameLoop() {
update();
// here
if(!checkCollision(player.x, player.y, player.r, 0, 0, GAME_R)) {
player.back();
}
draw();
}
function animLoop() {
window.requestAnimationFrame(animLoop);
gameLoop();
}
// player
function Entity() {
var self = {
x: 0,
y: 0,
r: 50,
entityType: PAPER,
angle: 0,
speed: 5
};
self.setSpeed = function(speed) {
this.speed = speed;
};
self.setAngle = function(angle) {
this.angle = angle;
};
self.update = function() {
this.x += this.speed * Math.cos(this.angle);
this.y += this.speed * Math.sin(this.angle);
};
self.back = function() {
this.x -= this.speed * Math.cos(this.angle);
this.y -= this.speed * Math.sin(this.angle);
};
self.draw = function() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
ctx.closePath();
ctx.fillStyle = "grey";
ctx.fill();
ctx.fillStyle = "#fff";
ctx.font = "30px Arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(this.entityType, this.x, this.y);
};
return self;
}
start();
})(window);
<canvas id="game"></canvas>
<div style="display: none;">
<img id="bg" src="https://i.imgur.com/9qjEwiz.png">
</div>
Related
So I have an integer variable, and it's supposed to represent the angle that I want this object to move along, it looks like this:
const Degree = 90
Now obviously we need a object to move in this angle, so we can easily draw this to the canvas.
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
// ...
ctx.beginPath();
ctx.arc(0, 0, 3.75, 0, 2 * Math.PI);
ctx.fillStyle = 'black';
ctx.fill();
How can I move this little circle along the axis I set in the degrees variable?
I tried to implement John Pavek's code into my code, and the little pebble does not pop up. Here is my code:
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var keydown = false
const kbd = {
ArrowLeft: false,
ArrowUp: false,
ArrowRight: false,
ArrowDown: false,
};
const noHoldDown = {
Space: false,
}
const ship = {
angle: 0,
color: "white",
x: canvas.width / 2,
y: canvas.height / 2,
width: 10,
height: 12,
drag: 0.9,
accSpeed: 0.025,
rotSpeed: 0.007,
rotv: 0,
ax: 0,
ay: 0,
vx: 0,
vy: 0,
rotateLeft() {
this.rotv -= this.rotSpeed;
},
rotateRight() {
this.rotv += this.rotSpeed;
},
accelerate() {
this.ax += this.accSpeed;
this.ay += this.accSpeed;
},
decelerate() {
this.ax -= this.accSpeed;
this.ay -= this.accSpeed;
},
shoot() {
var circle = new MovableCircle();
function DegreesToRadians(degrees) {
return degrees * (Math.PI / 180);
}
setInterval(function() {
ctx.beginPath();
ctx.clearRect(0, 0, canvas.width, canvas.height)
circle.draw();
circle.x += Math.cos(DegreesToRadians(circle.direction)) * circle.speed;
circle.y += Math.sin(DegreesToRadians(circle.direction)) * circle.speed;
}, 1000 / 60)
},
move() {
this.angle += this.rotv;
this.rotv *= this.drag;
this.vx += this.ax;
this.vy += this.ay;
this.ax *= this.drag;
this.ay *= this.drag;
this.vx *= this.drag;
this.vy *= this.drag;
this.x += Math.cos(this.angle) * this.vx;
this.y += Math.sin(this.angle) * this.vy;
},
draw(ctx) {
ctx.save();
ctx.lineWidth = 3;
ctx.translate(this.x, this.y);
ctx.rotate(this.angle);
ctx.beginPath();
ctx.moveTo(this.height, 0);
ctx.lineTo(-this.height, this.width);
ctx.lineTo(-this.height, -this.width);
ctx.closePath();
ctx.strokeStyle = this.color;
ctx.stroke();
ctx.restore();
}
};
function MovableCircle() {
this.x = ship.x;
this.y = ship.y;
this.speed = 1;
this.direction = convertToRadians(ship.angle);
this.draw = () => {
ctx.arc(this.x, this.y, 20, 0, 2 * Math.PI);
ctx.fillStyle = 'white';
ctx.fill();
}
}
document.addEventListener("keydown", event => {
if (event.code in kbd) {
event.preventDefault();
kbd[event.code] = true;
}
});
function convertToRadians(degree) {
if (((degree / Math.PI) * 180) > 360 || ((degree / Math.PI) * 180) < -360) {
ship.angle = 0
return (degree / Math.PI) * 180;
} else {
return (degree / Math.PI) * 180;
}
}
document.addEventListener("keydown", event => {
if (event.code in noHoldDown) {
if (!keydown) {
keydown = true;
ship.shoot();
}
}
});
document.addEventListener('keyup', event => {
if (event.code in noHoldDown) {
keydown = false;
}
});
document.addEventListener("keyup", event => {
if (event.code in kbd) {
event.preventDefault();
kbd[event.code] = false;
}
});
(function update() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
const shipActions = {
ArrowLeft: "rotateLeft",
ArrowUp: "accelerate",
ArrowDown: "decelerate",
ArrowRight: "rotateRight",
};
for (const key in shipActions) {
if (kbd[key]) {
ship[shipActions[key]]();
}
}
ship.move();
ship.draw(ctx);
requestAnimationFrame(update);
})();
One common option for learning about canvas animations is using Algebra (sin/cos) to calculate the distance to add for each value. Here is a very simple, non interactive example.
const canvas = document.createElement("canvas");
canvas.height = 400;
canvas.width = 400;
const ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
var circle = new MovableCircle();
setInterval(function() {
// This is our "game loop", the easiest way, not the best way
ctx.beginPath();
ctx.clearRect(0, 0, canvas.width, canvas.height)
circle.draw();
circle.x += Math.cos(DegreesToRadians(circle.direction)) * circle.speed;
circle.y += Math.sin(DegreesToRadians(circle.direction)) * circle.speed;
}, 1000 / 60)
function MovableCircle() {
this.x = 10;
this.y = 10;
this.speed = 1;
this.direction = 45;
this.draw = () => {
ctx.arc(this.x, this.y, 20, 0, 2 * Math.PI);
ctx.fillStyle = 'black';
ctx.fill();
}
}
function DegreesToRadians(degrees) {
return degrees * (Math.PI / 180);
}
I have a html5 canvas that I'm drawing circles with. These circles need images in the center of them, but also need to update. With the help of this SO question
I have come up with this code to draw everything:
var Circle1 = new Circle((c.width / 8) + (c.width / 2), 200, eighthWidth / 2.5, Color1, "1");
var Circle2 = new Circle(c.width - eighthWidth, 200, eighthWidth / 2.5, Color2, "2");
function Circle(x, y, radius, color, name) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.name = name;
this.draw = function () {
var MiddleImage = new Image();
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = this.color;
ctx.fill();
ctx.closePath();
ctx.drawImage(MiddleImage, this.x - MiddleImage.width / 2, this.y - MiddleImage.height / 2);
MiddleImage.src = "/Images/" + this.name + ".png";
}
this.update = function () {
this.x += 1;
this.draw();
}
this.update();
}
This isn't drawing the image like I hope it would, but if I take it out this method like below, it does work?
function drawCircle() {
var MiddleImage = new Image();
MiddleImage.onload = function () {
var X = c.width - eighthWidth;
var Y = 200;
ctx.beginPath();
ctx.arc(X, Y, eighthWidth / 2.5, 0, 2 * Math.PI);
ctx.clip;
ctx.fillStyle = Color1;
ctx.fill();
ctx.closePath();
ctx.drawImage(MiddleImage, X - MiddleImage.width / 2, Y - MiddleImage.height / 2);
};
BankImage.src = "/Images/1.png";
requestAnimationFrame(drawCircle);
}
I have also tried using the Image.onLoad method, as I have copied the working method into the new loop.
The console is showing no errors.
You can see a JSFiddle here
The problem you're having is that you're loading the image within the draw function at every frame and not waiting for it to be loaded.
I've tweaked your code slightly so it will load and attach the image to your circle as you wish.
var c = document.getElementById('canvas');
c.width = window.innerWidth;
c.height = 400;
var ctx = c.getContext("2d");
var eighthWidth = c.width / 8;
var Color1 = "#9c9c9b";
var Color2 = "#9c9c9b";
var Circle1 = new Circle((c.width / 8) + (c.width / 2), 200, eighthWidth / 2.5, Color1, "1");
var Circle2 = new Circle(c.width - eighthWidth, 200, eighthWidth / 2.5, Color2, "2");
function Circle(x, y, radius, color, name) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.name = name;
this.image = new Image();
this.image.src = "https://www.gstatic.com/webp/gallery3/1.png";
var _this = this;
this.image_loaded = false;
this.image.addEventListener('load', function() {
_this.image_loaded = true;
} );
this.draw = function() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = this.color;
ctx.fill();
ctx.closePath();
ctx.save();
ctx.clip();
ctx.drawImage(this.image, this.x - this.image.width / 2, this.y - this.image.height / 2);
ctx.restore();
}
this.update = function() {
//if(!this.image_loaded) return;
this.x += 1;
this.draw();
}
}
function animate() {
ctx.clearRect(0, 0, window.innerWidth, 400);
Circle1.update();
Circle2.update();
requestAnimationFrame(animate);
}
animate();
<canvas id="canvas" style="width:100%;"></canvas>
Is this what you want?
var car;
var front;
var back;
var img = new Image();
img.src = 'https://cdn4.iconfinder.com/data/icons/transportation-2-4/60/transportation-2-flat-036-racing-car-top-512.png';
function startGame() {
car = new move(12, 20, "red", 600, 300);
pg.start();
}
var pg = {
canvas: document.createElement("canvas"),
start: function() {
this.canvas.width = 1200;
this.canvas.height = 600;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.frameNo = 0;
this.interval = setInterval(updateframe, 20);
window.addEventListener('keydown', function(e) {
e.preventDefault();
pg.keys = (pg.keys || []);
pg.keys[e.keyCode] = (e.type == "keydown");
})
window.addEventListener('keyup', function(e) {
pg.keys[e.keyCode] = (e.type == "keydown");
})
},
stop: function() {
clearInterval(this.interval);
},
clear: function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}
function move(width, height, color, x, y, type) {
this.type = type;
this.width = width;
this.height = height;
this.speed = 0;
this.angle = 0;
this.moveAngle = 0;
this.x = x;
this.y = y;
this.update = function() {
ctx = pg.context;
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(this.angle);
ctx.drawImage(img, this.width / -2, this.height / -2,20,40);
ctx.beginPath();
ctx.moveTo(this.width / -2, this.height / -2);
ctx.lineTo(this.width / -2, 30);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(this.width / -2, 30);
ctx.lineTo(13, (this.height / -2)+40);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(14, (this.height / -2)+40);
ctx.lineTo(14, this.height / -2);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(14, this.height / -2);
ctx.lineTo(this.width / -2, this.height / -2);
ctx.stroke();
ctx.restore();
ctx.beginPath();
ctx.moveTo(300, 150);
ctx.lineTo(600, 800);
ctx.stroke();
}
this.newPos = function() {
this.angle += this.moveAngle * Math.PI / 180;
this.x += this.speed * Math.sin(this.angle);
this.y -= this.speed * Math.cos(this.angle);
}
}
function updateframe() {
pg.clear();
car.moveAngle = 0;
car.speed = 0;
if (pg.keys && pg.keys[37]) {
if (pg.keys && pg.keys[40]) {
car.moveAngle = 5;
}
if (pg.keys && pg.keys[38]) {
car.moveAngle = -5;
}
}
if (pg.keys && pg.keys[39]) {
if (pg.keys && pg.keys[40]) {
car.moveAngle = -5;
}
if (pg.keys && pg.keys[38]) {
car.moveAngle = 5;
}
}
if (pg.keys && pg.keys[38]) {
car.speed = 5;
}
if (pg.keys && pg.keys[40]) {
car.speed = -5;
}
car.newPos();
car.update();
}
startGame();
canvas {
border: 1px solid #d3d3d3;
background-color: #f1f1f1;
}
There is a car and a line, now i want to make an alert whenever the car get touched by the the line.
I know how to do this logically. like if i convert the car image in four lines (border) then use line intersection formula to get if there is a intersection but i am new to this canvas drawing and i cant figure how to get the border line equation of car.
update: i have made lines of border around the car, now i just need help with getting if these lines intersects with each other...
code is updated plz check it now...
one more thing, at this point there is only one line and i am going to add more lines in it... so i need a function to call it more often and get if the lines are intersecting with car border...
Note : use arrow keys to move car in snippet
I am trying to detect if two balls are intersecting on a HTML5 canvas.
I need a function called intersect as a part of a constructor object called Ball.
This function will take one Ball object as an argument and return true if the two balls on the canvas are touching/ intersecting. and false otherwise.
I cant figure out how to pass in a new instance of a ball to the intersect function and then compare it to another ball on the canvas.
The function I'm working on the is the final function intersect at the end of the Ball Object.
Please see below for the code i have so far.
Any help would be greatly appreciated.
<!DOCTYPE html>
<hmtl>
<head>
<meta charset="UTF-8">
<title>Canvas</title>
<style type="text/css">
canvas{
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="canvasOne" ></canvas>
<script type="text/javascript">
// Gets a handle to the element with id canvasOne.
var canvas = document.getElementById("canvasOne");
// Set the canvas up for drawing in 2D.
var ctx = canvas.getContext("2d");
canvas.width = 500;
canvas.height = 500;
function Ball(xpos,ypos,r) {
this.xpos = xpos;
this.ypos = ypos;
this.r = r;
this.move = function(addx,addy){
this.xpos = this.xpos + addx;
this.ypos = this.ypos + addy;
};
this.resize = function(setr){
this.r = setr;
};
this.draw = function(){
for (var i = 0; i < 7; i++) {
ctx.beginPath();
ctx.moveTo(ball.xpos, ball.ypos);
ctx.arc(ball.xpos, ball.ypos, ball.r, i*(2 * Math.PI / 7), (i+1)*(2 * Math.PI / 7));
ctx.lineWidth = 2;
ctx.strokeStyle = '#444';
ctx.stroke();
}
ctx.beginPath();
ctx.moveTo(ball.xpos, ball.ypos);
ctx.arc(ball.xpos,ball.ypos,ball.r-10,0,2*Math.PI);
ctx.lineWidth = 2;
ctx.strokeStyle = '#444';
ctx.stroke();
};
this.rotate = function(){
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Move registration point to the center of the canvas
ctx.translate(ball.xpos, ball.ypos);
// Rotate 1 degree
ctx.rotate(Math.PI / 180);
// Move registration point back to the top left corner of canvas
ctx.translate(-ball.xpos, -ball.ypos);
ball.draw();
ctx.restore();
};
this.contains = function(x, y){
this.x = this.x;
this.y = this.y;
if(Math.sqrt((x-ball.xpos)*(x-ball.xpos) + (y-ball.ypos)*(y-ball.ypos)) <= ball.r)
{
return true;
}else{
return false;
}
};
this.intersect = function(){
this.ball1 = this.ball1;
var distance = (ball.xpos * ball.xpos) + (ball.ypos *ball.ypos);
if(distance <= (ball.r + ball.r)*(ball.r + ball.r)){
return true;
}else{
return false;
}
};
}
var ball = new Ball(100,100,100);
ball.draw();
</script>
</body>
</html>
First off, if you aren't going to use the this keyword in your class, then why make it a class?
You can setup your intersect to take a Ball as a parameter. From here you can calculate the collision between this and the parameter Ball.
You distance function was off, as it only looked on the this object, and i fixed the this problem in your code:
var canvas = document.body.appendChild(document.createElement("canvas"));
// Set the canvas up for drawing in 2D.
var ctx = canvas.getContext("2d");
canvas.width = 500;
canvas.height = 500;
function Ball(xpos, ypos, r) {
this.xpos = xpos;
this.ypos = ypos;
this.r = r;
this.move = function(addx, addy) {
this.xpos = this.xpos + addx;
this.ypos = this.ypos + addy;
};
this.resize = function(setr) {
this.r = setr;
};
this.draw = function() {
for (var i = 0; i < 7; i++) {
ctx.beginPath();
ctx.moveTo(this.xpos, this.ypos);
ctx.arc(this.xpos, this.ypos, this.r, i * (2 * Math.PI / 7), (i + 1) * (2 * Math.PI / 7));
ctx.lineWidth = 2;
ctx.stroke();
}
ctx.beginPath();
ctx.moveTo(this.xpos, this.ypos);
ctx.arc(this.xpos, this.ypos, this.r - 10, 0, 2 * Math.PI);
ctx.lineWidth = 2;
ctx.stroke();
};
this.rotate = function() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Move registration point to the center of the canvas
ctx.translate(this.xpos, this.ypos);
// Rotate 1 degree
ctx.rotate(Math.PI / 180);
// Move registration point back to the top left corner of canvas
ctx.translate(-this.xpos, -this.ypos);
this.draw();
ctx.restore();
};
this.contains = function(x, y) {
this.x = this.x;
this.y = this.y;
if (Math.sqrt((x - this.xpos) * (x - this.xpos) + (y - this.ypos) * (y - this.ypos)) <= this.r) {
return true;
} else {
return false;
}
};
//put "ball" as a paremeter
//ball will be the foreign Ball to test intersection against
this.intersect = function(ball) {
var productX = this.xpos - ball.xpos;
var productY = this.ypos - ball.ypos;
var distance = Math.sqrt(productX * productX + productY * productY);
if (distance <= (this.r + ball.r)) {
return true;
} else {
return false;
}
};
}
var ball1 = new Ball(100, 100, 100);
var ball2 = new Ball(240, 140, 40);
function update(evt) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (evt !== void 0) {
ball2.xpos = evt.offsetX;
ball2.ypos = evt.offsetY;
}
//Pass the ball as an argument to the method
ctx.strokeStyle = ball1.intersect(ball2) ? "red" : '#444';
ball1.draw();
ball2.draw();
}
update();
canvas.onmousemove = update;
I cant figure out how to pass in a new instance of a ball to the
intersect function
Well to pass anything really it should have an argument.
this.intersect = function(otherball){
// then compare the two ball objects
Then...
var ball1 = new Ball(100,100,100);
var ball2 = new Ball(100,100,100);
ball1.draw();
ball2.draw();
console.log(ball1.intersect(ball2));
So I'm trying to make a pong game in JavaScript. I've tried lots of stuff, but whatever I do won't get the ball to move.
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var Game = {};
var Player = function(x, y) {
this.x = x;
this.y = y;
}
Player.prototype.draw = function() {
ctx.beginPath();
ctx.rect(this.x, this.y, 20, 80);
ctx.fillStyle = "#000";
ctx.fill();
ctx.closePath();
}
var Ball = function(x, y, diam) {
this.x = x;
this.y = y;
this.diam = diam;
this.xvel = 5;
this.yvel = 5;
}
Ball.prototype.draw = function() {
ctx.beginPath();
ctx.rect(canvas.width/2 - 10, canvas.height/2 - 10, 20, 20);
ctx.fillStyle = "#000";
ctx.fill();
ctx.closePath();
};
Ball.prototype.moveBall = function() {
this.x = this.x + this.xvel;
this.y = this.y + this.yvel;
};
var p1 = new Player(20, canvas.height/2 - 40);
var p2 = new Player(canvas.width-20-20, canvas.height/2 - 40);
var ball = new Ball(canvas.width/2 - 10, canvas.height/2 - 10, 20);
Game.draw = function() { p1.draw(); p2.draw(); ball.draw(); };
Game.update = function() { ball.moveBall(); };
Game.run = function() { Game.update(); Game.draw(); };
Game.fps = 50;
Game._intervalId = setInterval(Game.run, 1000 / Game.fps);
I can't get the ball to move. Any Ideas? Also, what the neater way of classes? Is there a different way to do it than with functions?
Maybe like
class Apple {
function draw() {
//draw here
}
}
You are always drawing the ball in the same place, dead-center:
ctx.rect(canvas.width/2 - 10, canvas.height/2 - 10, 20, 20);
You're updating this.x and this.y elsewhere, but not using them. Try:
ctx.rect(this.x, this.y, 20, 20);
Now you have the problem of knowing when to stop moving, but that's a separate question.
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var Game = {};
var Player = function(x, y) {
this.x = x;
this.y = y;
}
Player.prototype.draw = function() {
ctx.beginPath();
ctx.rect(this.x, this.y, 20, 80);
ctx.fillStyle = "#000";
ctx.fill();
ctx.closePath();
}
var Ball = function(x, y, diam) {
this.x = x;
this.y = y;
this.diam = diam;
this.xvel = 5;
this.yvel = 5;
}
Ball.prototype.draw = function() {
ctx.beginPath();
ctx.rect(this.x, this.y, 20, 20);
ctx.fillStyle = "#000";
ctx.fill();
ctx.closePath();
};
Ball.prototype.moveBall = function() {
this.x = this.x + this.xvel;
this.y = this.y + this.yvel;
};
var p1 = new Player(20, canvas.height/2 - 40);
var p2 = new Player(canvas.width-20-20, canvas.height/2 - 40);
var ball = new Ball(canvas.width/2 - 10, canvas.height/2 - 10, 20);
Game.draw = function() { p1.draw(); p2.draw(); ball.draw(); };
Game.update = function() { ball.moveBall(); };
Game.run = function() { Game.update(); Game.draw(); };
Game.fps = 50;
Game._intervalId = setInterval(Game.run, 1000 / Game.fps);
<canvas id="myCanvas" height="300px" width="300px" />
I got your ball moving. you had just forgot to set the position to this.x and this.y in the draw function.
you'll notice it leaves a streak. So you'll need to either (1) clear everything and redraw everything on each frame, or (2), keep an oldx and oldy and draw white over oldx oldy before drawing black at x and y. Happy coding.
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var Game = {};
var Player = function(x, y) {
this.x = x;
this.y = y;
}
Player.prototype.draw = function() {
ctx.beginPath();
ctx.rect(this.x, this.y, 20, 80);
ctx.fillStyle = "#000";
ctx.fill();
ctx.closePath();
}
var Ball = function(x, y, diam) {
this.x = x;
this.y = y;
this.diam = diam;
this.xvel = 5;
this.yvel = 5;
}
Ball.prototype.draw = function() {
ctx.beginPath();
ctx.rect(this.x, this.y, 20, 20);
ctx.fillStyle = "#000";
ctx.fill();
ctx.closePath();
};
Ball.prototype.moveBall = function() {
this.x = this.x + this.xvel;
this.y = this.y + this.yvel;
};
var p1 = new Player(20, canvas.height/2 - 40);
var p2 = new Player(canvas.width-20-20, canvas.height/2 - 40);
var ball = new Ball(canvas.width/2 - 10, canvas.height/2 - 10, 20);
Game.draw = function() { p1.draw(); p2.draw(); ball.draw(); };
Game.update = function() { ball.moveBall(); };
Game.run = function() {console.log("hi"); Game.update(); Game.draw(); };
Game.fps = 5;
Game._intervalId = setInterval(Game.run, 1000 / Game.fps);
#myCanvas{width:200px;height:200px}
<canvas id="myCanvas"></canvas>
Here's a good html canvas game instructions that follows the style you're doing pretty well:
http://www.html5rocks.com/en/tutorials/canvas/notearsgame/