I am trying to make a webpage to store all my games on i just started and i've been trying to make a button to load my pong game but when I press the button nothing happens here's my code
<!DOCTYPE html>
<html lang = "en">
<head>
<title>Title</title>
<meta charset="UTF-8">
<style>
canvas {
position: absolute;
margin: auto;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
</style>
</head>
<body>
<center>
<h1>Games</h1>
button code
<input id="Pong" type="button" value="Pong" onclick="go();" />
pong code
<script>
function go(){
var WIDTH = 700, HEIGHT = 600, pi = Math.PI;
var UpArrow = 38, DownArrow = 40;
var canvas, ctx, keystate;
var player, ai, ball, score;
player = {
x: null,
y: null,
width: 20,
height: 100,
update: function(){
if(keystate[UpArrow]) this.y -= 7;
if(keystate[DownArrow]) this.y += 7;
},
draw: function(){
ctx.fillRect(this.x, this.y, this.width, this.height);
}
};
ai = {
x: null,
y: null,
width: 20,
height: 100,
update: function(){
var desty = ball.y - (this.height - ball.side)*0.5;
this.y += (desty - this.y) * 0.1;
},
draw: function(){
ctx.fillRect(this.x, this.y, this.width, this.height);
}
};
ball = {
x: null,
y: null,
vel: null,
side: 20,
speed: 9,
serve: function(side){
var r = Math.random();
this.x = side===1 ? player.x : ai.x - this.side;
this.y = (HEIGHT - this.side)*r;
score.count += 1;
var phi = 0.1*pi*(1 - 2*r);
this.vel = {
x: side*this.speed*Math.cos(phi),
y: this.speed*Math.sin(phi)
};
score = {
x: null,
y: null,
count: 0,
width: 10,
height: 10,
update: function(){
Console.log(this.count);
},
draw: function(){
ctx.fillRect(this.x, this.y, this.width, this.height);
}
};
},
update: function(){
this.x += this.vel.x;
this.y += this.vel.y;
if(0 > this.y || this.y+this.side > HEIGHT){
var offset = this.vel.y < 0 ? 0 - this.y : HEIGHT - (this.y+this.side);
this.y += 2*offset;
this.vel.y *= -1;
}
var AABBIntersect = function(ax, ay, aw, ah, bx, by, bw, bh){
return ax < bx+bw && ay < by+bh && bx < ax+aw && by < ay+ah;
};
var pdle = this.vel.x < 0 ? player : ai;
if(AABBIntersect(pdle.x, pdle.y, pdle.width, pdle.height, this.x, this.y, this.side, this.side)){
this.x = pdle===player ? player.x+player.width : ai.x - this.side;
var n = (this.y + this.side - pdle.y)/(pdle.height+this.side);
var phi = 0.25*pi*(2*n - 1);
var smash = Math.abs(phi) > 0.2*pi ? 1.5 : 1;
this.vel.x = smash*(pdle === player ? 1 : -1)*this.speed*Math.cos(phi);
this.vel.y = smash*this.speed*Math.sin(phi);
}
if(0 > this.x+this.side || this.x > WIDTH){
this.serve(pdle === player ? 1 : -1);
}
},
draw: function(){
ctx.fillRect(this.x, this.y, this.side, this.side);
}
};
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(){
player.x = player.width;
player.y = (HEIGHT - player.height)/2;
ai.x = WIDTH - (player.width + ai.width);
ai.y = (HEIGHT - ai.height)/2;
ball.serve(1);
}
function update(){
ball.update();
player.update();
ai.update();
}
function draw(){
ctx.fillRect(0, 0, WIDTH, HEIGHT);
ctx.save();
ctx.fillStyle = "#fff";
ball.draw();
player.draw();
ai.draw();
var w = 4;
var x = (WIDTH - w) * 0.5;
var y = 0;
var step = HEIGHT/15;
while (y < HEIGHT){
ctx.fillRect(x, y + step * 0.25, w, step * 0.5);
y += step;
}
ctx.restore();
}
main();
}
</script>
end of pong code
</center>
</body>
</html>
I merely took #Xufox's solutions and wrote them out. Also serperated the JS, CSS, and HTML. Enjoy
function go(){
score = {
x: null,
y: null,
count: 0,
width: 10,
height: 10,
update: function(){
console.log(this.count);
},
draw: function(){
ctx.fillRect(this.x, this.y, this.width, this.height);
}
};
var WIDTH = 700, HEIGHT = 600, pi = Math.PI;
var UpArrow = 38, DownArrow = 40;
var canvas, ctx, keystate;
var player, ai, ball, score;
player = {
x: null,
y: null,
width: 20,
height: 100,
update: function(){
if(keystate[UpArrow]) this.y -= 7;
if(keystate[DownArrow]) this.y += 7;
},
draw: function(){
ctx.fillRect(this.x, this.y, this.width, this.height);
}
};
ai = {
x: null,
y: null,
width: 20,
height: 100,
update: function(){
var desty = ball.y - (this.height - ball.side)*0.5;
this.y += (desty - this.y) * 0.1;
},
draw: function(){
ctx.fillRect(this.x, this.y, this.width, this.height);
}
};
ball = {
x: null,
y: null,
vel: null,
side: 20,
speed: 9,
serve: function(side){
var r = Math.random();
this.x = side===1 ? player.x : ai.x - this.side;
this.y = (HEIGHT - this.side)*r;
score.count += 1;
var phi = 0.1*pi*(1 - 2*r);
this.vel = {
x: side*this.speed*Math.cos(phi),
y: this.speed*Math.sin(phi)
};
},
update: function(){
this.x += this.vel.x;
this.y += this.vel.y;
if(0 > this.y || this.y+this.side > HEIGHT){
var offset = this.vel.y < 0 ? 0 - this.y : HEIGHT - (this.y+this.side);
this.y += 2*offset;
this.vel.y *= -1;
}
var AABBIntersect = function(ax, ay, aw, ah, bx, by, bw, bh){
return ax < bx+bw && ay < by+bh && bx < ax+aw && by < ay+ah;
};
var pdle = this.vel.x < 0 ? player : ai;
if(AABBIntersect(pdle.x, pdle.y, pdle.width, pdle.height, this.x, this.y, this.side, this.side)){
this.x = pdle===player ? player.x+player.width : ai.x - this.side;
var n = (this.y + this.side - pdle.y)/(pdle.height+this.side);
var phi = 0.25*pi*(2*n - 1);
var smash = Math.abs(phi) > 0.2*pi ? 1.5 : 1;
this.vel.x = smash*(pdle === player ? 1 : -1)*this.speed*Math.cos(phi);
this.vel.y = smash*this.speed*Math.sin(phi);
}
if(0 > this.x+this.side || this.x > WIDTH){
this.serve(pdle === player ? 1 : -1);
}
},
draw: function(){
ctx.fillRect(this.x, this.y, this.side, this.side);
}
};
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(){
player.x = player.width;
player.y = (HEIGHT - player.height)/2;
ai.x = WIDTH - (player.width + ai.width);
ai.y = (HEIGHT - ai.height)/2;
ball.serve(1);
}
function update(){
ball.update();
player.update();
ai.update();
}
function draw(){
ctx.fillRect(0, 0, WIDTH, HEIGHT);
ctx.save();
ctx.fillStyle = "#fff";
ball.draw();
player.draw();
ai.draw();
var w = 4;
var x = (WIDTH - w) * 0.5;
var y = 0;
var step = HEIGHT/15;
while (y < HEIGHT){
ctx.fillRect(x, y + step * 0.25, w, step * 0.5);
y += step;
}
ctx.restore();
}
main();
}
canvas {
position: absolute;
margin: auto;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
<!DOCTYPE html>
<html lang = "en">
<head>
<title>Title</title>
<meta charset="UTF-8">
</head>
<body>
<center>
<h1>Games</h1>
<input id="Pong" type="button" value="Pong" onclick="go();" />
</center>
<script type="text/javascript" src="javascript.js"></script>
</body>
</html>
Related
Im new to this area and hope some off you can help me.
I am super inspired be this site and the particle animation / function they have http://www.giantstepsmedias.com/
I found this one that are close to the inspiration. But i can't figure out how to change it to an images instead of the value in the input field.
var canvas = document.querySelector("#scene"),
ctx = canvas.getContext("2d"),
particles = [],
amount = 0,
mouse = {x:0,y:0},
radius = 1;
var colors = ["rgba(255,255,255,1)","rgba(255,255,255,.5)", "rgba(255,255,255,.25)","rgba(255,255,255,.1)"];
var copy = document.querySelector("#copy");
var ww = canvas.width = window.innerWidth;
var wh = canvas.height = window.innerHeight;
function Particle(x,y){
this.x = Math.random()*ww;
this.y = Math.random()*wh;
this.dest = {
x : x,
y: y
};
this.r = Math.random()*5 + 2;
this.vx = (Math.random()-0.5)*20;
this.vy = (Math.random()-0.5)*20;
this.accX = 0;
this.accY = 0;
this.friction = Math.random()*0.05 + 0.94;
this.color = colors[Math.floor(Math.random()*6)];
}
Particle.prototype.render = function() {
this.accX = (this.dest.x - this.x)/1000;
this.accY = (this.dest.y - this.y)/1000;
this.vx += this.accX;
this.vy += this.accY;
this.vx *= this.friction;
this.vy *= this.friction;
this.x += this.vx;
this.y += this.vy;
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, Math.PI * 2, false);
ctx.fill();
var a = this.x - mouse.x;
var b = this.y - mouse.y;
var distance = Math.sqrt( a*a + b*b );
if(distance<(radius*70)){
this.accX = (this.x - mouse.x)/100;
this.accY = (this.y - mouse.y)/100;
this.vx += this.accX;
this.vy += this.accY;
}
}
function onMouseMove(e){
mouse.x = e.clientX;
mouse.y = e.clientY;
}
function onTouchMove(e){
if(e.touches.length > 0 ){
mouse.x = e.touches[0].clientX;
mouse.y = e.touches[0].clientY;
}
}
function onTouchEnd(e){
mouse.x = -9999;
mouse.y = -9999;
}
function initScene(){
ww = canvas.width = window.innerWidth;
wh = canvas.height = window.innerHeight;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.font = "bold "+(ww/10)+"px sans-serif";
ctx.textAlign = "center";
ctx.fillText(copy.value, ww/2, wh/2);
var data = ctx.getImageData(0, 0, ww, wh).data;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = "screen";
particles = [];
for(var i=0;i<ww;i+=Math.round(ww/150)){
for(var j=0;j<wh;j+=Math.round(ww/150)){
if(data[ ((i + j*ww)*4) + 3] > 150){
particles.push(new Particle(i,j));
}
}
}
amount = particles.length;
}
function onMouseClick(){
radius++;
if(radius ===5){
radius = 0;
}
}
function render(a) {
requestAnimationFrame(render);
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < amount; i++) {
particles[i].render();
}
};
copy.addEventListener("keyup", initScene);
window.addEventListener("resize", initScene);
window.addEventListener("mousemove", onMouseMove);
window.addEventListener("touchmove", onTouchMove);
window.addEventListener("click", onMouseClick);
window.addEventListener("touchend", onTouchEnd);
initScene();
requestAnimationFrame(render);
canvas{
background: black;
width: 100vw;
height: 100vh;
}
<canvas id="scene"></canvas>
<input id="copy" type="text" value="Hello Codepen ♥" />
The animation is based on whatever has been rendered to the canvas.
In your code that is
ctx.font = "bold "+(ww/10)+"px sans-serif";
ctx.textAlign = "center";
ctx.fillText(copy.value, ww/2, wh/2);
instead, change this to render an image:
const img = document.getElementById('img');
ctx.drawImage(img, ww/2, wh/2);
you might like to adjust the positions for .drawImage: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage
Using HTML:
<canvas id="scene"></canvas>
<div style="display:none;">
<img id="img"
src="http://www.giantstepsmedias.com/img/logos/giant_steps_small.png">
</div>
However, rendering an image from a different server to your ctx gives The canvas has been tainted by cross-origin data so I can't give you a working snippet.
Use an image that is on the same server as the page or, as suggested, use a data: url:
var canvas = document.querySelector("#scene"),
ctx = canvas.getContext("2d"),
particles = [],
amount = 0,
mouse = {
x: 0,
y: 0
},
radius = 1;
var colors = ["rgba(255,255,255,1)", "rgba(255,255,255,.5)", "rgba(255,255,255,.25)", "rgba(255,255,255,.1)"];
var ww = canvas.width = window.innerWidth;
var wh = canvas.height = window.innerHeight;
function Particle(x, y) {
this.x = Math.random() * ww;
this.y = Math.random() * wh;
this.dest = {
x: x,
y: y
};
this.r = Math.random() * 5 + 2;
this.vx = (Math.random() - 0.5) * 20;
this.vy = (Math.random() - 0.5) * 20;
this.accX = 0;
this.accY = 0;
this.friction = Math.random() * 0.05 + 0.94;
this.color = colors[Math.floor(Math.random() * 6)];
}
Particle.prototype.render = function() {
this.accX = (this.dest.x - this.x) / 1000;
this.accY = (this.dest.y - this.y) / 1000;
this.vx += this.accX;
this.vy += this.accY;
this.vx *= this.friction;
this.vy *= this.friction;
this.x += this.vx;
this.y += this.vy;
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, Math.PI * 2, false);
ctx.fill();
var a = this.x - mouse.x;
var b = this.y - mouse.y;
var distance = Math.sqrt(a * a + b * b);
if (distance < (radius * 70)) {
this.accX = (this.x - mouse.x) / 100;
this.accY = (this.y - mouse.y) / 100;
this.vx += this.accX;
this.vy += this.accY;
}
}
function onMouseMove(e) {
mouse.x = e.clientX;
mouse.y = e.clientY;
}
function onTouchMove(e) {
if (e.touches.length > 0) {
mouse.x = e.touches[0].clientX;
mouse.y = e.touches[0].clientY;
}
}
function onTouchEnd(e) {
mouse.x = -9999;
mouse.y = -9999;
}
function initScene() {
ww = canvas.width = window.innerWidth;
wh = canvas.height = window.innerHeight;
ctx.clearRect(0, 0, canvas.width, canvas.height);
//ctx.font = "bold "+(ww/10)+"px sans-serif";
//ctx.textAlign = "center";
//ctx.fillText(copy.value, ww/2, wh/2);
const img = document.getElementById('img');
ctx.drawImage(img, ww / 2 - 75, (wh / 2) - 75, 150, 150);
var data = ctx.getImageData(0, 0, ww, wh).data;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = "screen";
particles = [];
for (var i = 0; i < ww; i += Math.round(ww / 150)) {
for (var j = 0; j < wh; j += Math.round(ww / 150)) {
if (data[((i + j * ww) * 4) + 3] > 150) {
particles.push(new Particle(i, j));
}
}
}
amount = particles.length;
}
function onMouseClick() {
radius++;
if (radius === 5) {
radius = 0;
}
}
function render(a) {
requestAnimationFrame(render);
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < amount; i++) {
particles[i].render();
}
};
window.addEventListener("resize", initScene);
window.addEventListener("mousemove", onMouseMove);
window.addEventListener("touchmove", onTouchMove);
window.addEventListener("click", onMouseClick);
window.addEventListener("touchend", onTouchEnd);
initScene();
requestAnimationFrame(render);
canvas {
background: black;
width: 100vw;
height: 100vh;
}
<canvas id="scene"></canvas>
<div style="display:none;">
<img id="img" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAsCAYAAAAJpsrIAAAC9UlEQVR42syZSWgUQRSGezJJ0IhLwIDLRQkumEMOihdFPOghcd9QEEREiIokHkQRISAKRsUdEUxAL2pGxV08iQt40QgexAUNiBgFSQY0EjEzk/J/8kqHobvrRat76sE3E7prar55vdTrl4RS6oXneaNBzvsbSdAPjoATYMCzFw3gAMj6zEvf2w2mlOJlPBgVMAmJTQY7Qa8lsQowMmR/iX7JhAxKgM0gBSZaEjNlP/PHThB14BaY48UUJYMYW8NyG1wToxgB2sA+MNQlMX3e7QZnwTiXxHSsBjfBTNfEKKaDa2BF3GIK/DSMocN5ke91ZXGKHQPthnEk1ALO8CoSuRjtfwvWg1bBfDTuMpgaxzk2nA8nrXHbQZ9h/FxwG8yPWkzlvR/mrHwyfKaaM7clzquSvnAZeG4YRwv1KXAcDItCrN9n2xOwiA+ZKRr5qtVFQLktsTVgks/2j7zvqKBioB9xndfbPlHKUCh+UeZ4DWYDL4BG0CuYpxPcAwMhY8hHLEbRAzaGyNWBD+r/Y9Biin/pQVARIFcLOoohpuMSGBsgNwakiiWmODMzAuTKwH6QKYYYRRdYFXLeNYCvxRCjyIJmzpKf3Dy+Gq2K0cmeFk7YBqoC5GrAA9sZo2zsEU76kCX85CrBOc6wFbFtPHET+C6QewfqA+SSoFUiJlmS9NMQLcZrhZVFe0BlQW2IDltrZTbv7xtgMXgqqOGosjjp0w4YYkussOZ/BpaAq4LPbgXnwYQoyp6Ez7bPXFkcKsioXywAd/LaCyrqxzdqfuzgeuubYew0cAXUgx+SyUstPNCcBu/5fKoOGVcFLvDYHPfCInvg1XGXL4rHgnK71iRlU4ziJculXGgRFEYarAN7DQ3B2MX0w0sz32DTLonpoD7aSvDGNTGK+3wfe+SaGEUnWM4ZdEqMogdsArsEba1YxXRl0cK9j26JmKnZlrQsSCXRUvAqpNf2e0nq4vTmfBbvcsE6+C9BK8RCbi/Myju8+l823i8BBgAb0AQfHTBwWAAAAABJRU5ErkJggg=="
alt="" />
</div>
The ball seems to bounce off one side of the paddle, but when it comes from the side it glitches through the paddle. I just can't find a way behind it and it really bothers me. I am using some logic gates to define where the ball's direction is need to be invereted
function startGame() {
GameArea.start();
Ball1 = new CircleComp('white' , window.innerWidth - 200 , window.innerHeight - 20);
Ball1.ySpeed = 13.5;
Ball1.xSpeed = 6;
Paddle1 = new PaddleComp( 87, 83, 0, window.innerHeight / 2.5, 10, 70);
Paddle2 = new PaddleComp( 38, 40, window.innerWidth - 10, window.innerHeight / 2.5, 10 , 70);
}
var GameArea = {
canvas : canvas = document.querySelector("canvas"),
start : function (){
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;
this.ctx = this.canvas.getContext('2d');
this.interval = setInterval(updateGameArea, 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;
})
},
clear : function() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}
function CircleComp(color, x , y){
this.x = x;
this.y = y;
this.width = 8;
this.height = 8;
var context1 = GameArea.ctx;
this.update = function(){
context1.beginPath();
context1.fillStyle = color;
context1.fillRect(this.x, this.y, this.width, this.height);
context1.fill();
context1.stroke();
this.updatePosition();
}
this.updatePosition = function(){
this.y += this.ySpeed;
this.x += this.xSpeed;
if(this.x + this.width > GameArea.canvas.width){
this.xSpeed = -this.xSpeed;
}
if(this.y + this.height > GameArea.canvas.height){
this.ySpeed = -this.ySpeed;;
}
if(this.x - this.width < 0){
this.xSpeed = -this.xSpeed;
}
if(this.y - this.height < 0){
this.ySpeed = -this.ySpeed;
}
if(this.y + this.height > Paddle2.y && this.y - this.width < (Paddle2.y + 130) && this.x + this.width > Paddle2.x ){
this.xSpeed = -this.xSpeed;
}
if(this.y + this.height > Paddle1.y && this.y - this.width < (Paddle1.y + 70) && this.x - this.height < Paddle1.x + 10){
this.xSpeed = -this.xSpeed;
}
}
}
function PaddleComp(Upkey, Downkey, x, y, width, height){
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.ySpeed = 0;
var context2 = GameArea.ctx;
this.update = function(){
context2.fillStyle = 'white';
context2.fillRect(x,this.y,this.width,this.height);
this.updatePosition();
}
this.updatePosition = function() {
this.ySpeed = 0;
if (GameArea.keys && GameArea.keys[Upkey]) {
this.ySpeed = -15; //console.log('Up');
}
if (GameArea.keys && GameArea.keys[Downkey]) {
this.ySpeed = 15; //console.log('Down');
}
if ((GameArea.keys && GameArea.keys[Downkey]) && this.y + 130 > window.innerHeight){
this.ySpeed = this.ySpeed -15 ;
}
if ((GameArea.keys && GameArea.keys[Upkey]) && this.y < 0 ){
this.ySpeed = this.ySpeed +15 ;
}
this.y += this.ySpeed;
}
}
function updateGameArea(){
GameArea.clear();
Paddle1.update();
Paddle2.update();
Ball1.update();
}
<html>
<head>
<meta charset='urf-8'>
<style>
canvas{
border: 0px solid black;
background-color: black;
}
body{
margin: 0;
overflow: hidden;
}
</style>
</head>
<body onload='startGame()'>
<canvas></canvas>
<script src='Pong.js'></script>
</body>
</html>
Could not see directly what the problem was with your code so i just rewrote the code with the ball, bat (paddle) test function in the ball Object and called from the players object. ball.checkPad(player); tests if the ball has hit the players bat. To help picture what is happening I have slowed it all down and made the bats real phat. When the ball hits the bat it will turn yellow and the bat red for a second or so.
There is plenty of comments in the parts you asked about,
Hope it helps
Demo copied from OP question.
const setting = {
speed : 2, // of ball
left : 0,
width : 400,
height : 200,
padWidth : 50,
padHeight : 80,
padSpeed : 4, // double balls
hitPauseCount : 30, // nuber of frames to hold when there is a collisiotn so you
// can check all is good
}
const keys = {
ArrowUp : false,
ArrowDown : false,
ArrowLeft : false,
ArrowRight : false,
keyEvent(e) { // dont use keyCode it has depreciated
if (keys[e.code] !== undefined) {
keys[e.code] = e.type === "keydown";
e.preventDefault();
}
}
}
var ctx;
var ball1, paddle1, paddle2;
var gameArea = {
start() {
canvas.width = setting.width;
canvas.height = setting.height;
ctx = canvas.getContext('2d');
requestAnimationFrame(updateGameArea);
},
clear() {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
}
}
gameArea.start();
ball = new CircleComp('white', window.innerWidth - 200, window.innerHeight - 20);
ball.ySpeed = setting.speed;
ball.xSpeed = setting.speed;
paddle1 = new PaddleComp("ArrowUp", "ArrowDown", setting.left, setting.height / 2, setting.padWidth, setting.padHeight);
paddle2 = new PaddleComp("ArrowLeft", "ArrowRight", setting.width - setting.padWidth, setting.height / 2, setting.padWidth, setting.padHeight);
window.addEventListener('keydown', keys.keyEvent);
window.addEventListener('keyup', keys.keyEvent);
function CircleComp(color, x, y) {
this.x = x;
this.y = y;
this.width = 8;
this.height = 8;
this.xSpeed = setting.speed;
var hit = 0;
var restartCount;
var serveDirection;
this.reset = function(){
this.x = ctx.canvas.width /2;
this.y = ctx.canvas.height / 2;
this.xSpeed = -this.xSpeed
this.ySpeed = setting.speed * Math.sign(Math.random() - 0.5);
restartCount = 60;
}
this.draw = function () {
if(hit > 0){
hit -= 1;
ctx.fillStyle = "yellow";
}else{
ctx.fillStyle = color;
}
ctx.fillRect(this.x, this.y, this.width, this.height);
}
// next funtion is called by the player objects
this.checkPad = function (player) {
if (player.x > canvas.width / 2) { // is player on left or right
if (this.xSpeed > 0) { // player on right only check if ball moving rigth
if (this.x + this.width > player.x) { // ball is in paddles zone
//if not bottom of ball above top of bat or top of ball bellow bottom of bat
if (!(this.y + this.height <= player.y || this.y >= player.y + player.height)) {
// ball and bat in contact
// is ball moving down and the balls top edge above the player
// then ball has hit the top side of the bat
if(this.ySpeed > 0 && this.y <= player.y){
this.y = player.y - this.width;
this.ySpeed = -setting.speed;
}else if(this.ySpeed < 0 && this.y + this.height >= player.y + player.height){ // do bottom check
this.y = player.y + player.height;
this.ySpeed = setting.speed;
}else{ // ball hit front of bat
this.x = player.x - this.width;
this.xSpeed = - setting.speed;
}
player.hit = setting.hitPauseCount; // counters to show FX when a hit happens
hit = setting.hitPauseCount;
}
}
}
} else { // player must be left
if (this.xSpeed < 0) { // ball must move left
if (this.x < player.x + player.width) { // ball is in paddles zone
if (!(this.y + this.height <= player.y || this.y >= player.y + player.height)) {
// ball and bat in contact
// ball and bat in contact
// is ball moving down and the balls top edge above the player
// then ball has hit the top side of the bat
if(this.ySpeed > 0 && this.y <= player.y){
this.y = player.y - this.width;
this.ySpeed = -setting.speed;
}else if(this.ySpeed < 0 && this.y + this.height >= player.y + player.height){ // do bottom check
this.y = player.y + player.height;
this.ySpeed = setting.speed;
}else{ // ball hit front of bat
this.x = player.x + player.width;
this.xSpeed = setting.speed;
}
player.hit = setting.hitPauseCount; // counters to show FX when a hit happens
hit = setting.hitPauseCount;
}
}
}
}
}
this.update = function () {
if(restartCount > 0){ // wait for restart pause
restartCount -= 1;
}else{
if(hit > 0){ // do nothing if paused
return;
}
this.y += this.ySpeed;
this.x += this.xSpeed;
if (this.x + this.width >= canvas.width) {
this.reset(); // point
} else if (this.x < 0) {
this.reset(); // point
}
if (this.y + this.height >= canvas.height) {
this.y = canvas.height - this.height;
this.ySpeed = -setting.speed;
} else if (this.y < 0) {
this.y = 0;
this.ySpeed = setting.speed;
}
}
}
this.reset();
}
function PaddleComp(upKey, downKey, x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.hit = 0;
this.draw = function () {
if(this.hit > 0){
this.hit -= 1;
ctx.fillStyle = "red";
}else{
ctx.fillStyle = '#9CF';
}
ctx.fillRect(this.x, this.y, this.width, this.height);
}
this.update = function () {
if (keys[upKey]) {
this.y -= setting.padSpeed;
};
if (keys[downKey]) {
this.y += setting.padSpeed;
};
if (this.y < 0) {
this.y = 0;
}
if (this.y + this.height >= canvas.height) {
this.y = canvas.height - this.height;
}
ball.checkPad(this);
}
}
function updateGameArea() {
gameArea.clear();
paddle1.update();
paddle2.update();
ball.update();
paddle1.draw();
paddle2.draw();
ball.draw();
requestAnimationFrame(updateGameArea);
}
<canvas id=canvas style='background:#69C;border:2px blue solid'></canvas>
I recently made a JS Pong game. It works well, but the ball rarely gets stuck at the bottom or top. It looks like it is halfway through the wall and constantly bouncing. Video of the issue happening. You can try the game here. I do not know why this issue is happening because the logic seems right and works 90% of the time correctly. Here are the main two functions of my program:
function moveAll() {
if (showingWinScreen) {
return;
}
computerMovement();
ballX += ballSpeedX;
ballY += ballSpeedY;
if (ballY <= 10) {
ballSpeedY = -ballSpeedY;
} else if (ballY >= HEIGHT - 10) {
ballSpeedY = -ballSpeedY;
}
if (ballX >= WIDTH - 10) {
if ((ballY > paddleY) && (ballY < paddleY + 100)) {
ballSpeedX = -ballSpeedX;
var deltaY = ballY - paddleY - 50;
ballSpeedY = deltaY / 5;
} else {
player1Score++;
ballReset();
}
} else if (ballX <= 10) {
if ((ballY > mouseY - 50) && (ballY < mouseY + 50)) {
ballSpeedX = -ballSpeedX;
deltaY = ballY - mouseY;
ballSpeedY = deltaY / 6;
} else {
player2Score++;
ballReset();
}
}
}
function drawAll() {
if (showingWinScreen) {
colorRect(0, 0, WIDTH, HEIGHT, "black");
canvas.fillStyle = "yellow";
canvas.fillText("Click to continue!", 300, 300);
if (player1Score == WINNING_SCORE) {
canvas.fillText("You won!", 360, 500);
} else if (player2Score == WINNING_SCORE) {
canvas.fillText("The computer beat you!", 280, 500);
}
return;
}
colorRect(0, 0, WIDTH, HEIGHT, "black");
drawNet();
makeCircle(ballX, ballY, 10, 0, Math.PI * 2, "red");
colorRect(790, paddleY, 10, 100, "cyan");
colorRect(0, mouseY - 50, 10, 100, "yellow");
canvas.fillStyle = "white";
canvas.fillText(player1Score + " " + player2Score, 360, 100);
}
Thank you for your help!
I think there's only one case in which this could happen: when, in a colliding frame, you decrease the speed.
When the speed remains the same, no matter what, your ball will always bounce back to the previous' frames position:
var cvs = document.querySelector("canvas");
var ctx = cvs.getContext("2d");
var balls = [
Ball(50, 50, 0, 5, 5, "red"),
Ball(100, 50, 0, 5, 10, "blue"),
Ball(150, 50, 0, 5, 15, "green"),
Ball(200, 50, 0, 5, 20, "yellow")
];
var next = () => {
updateFrame(balls);
drawFrame(balls);
}
var loop = () => {
requestAnimationFrame(() => {
next();
loop();
});
}
next();
function Ball(x, y, vx, vy, r, color) {
return {
x: x,
y: y,
vx: vx,
vy: vy,
r: r,
color: color
}
};
function updateBall(b) {
b.x += b.vx;
b.y += b.vy;
if (b.y <= b.r ||
b.y >= cvs.height - b.r) {
b.vy *= -1;
}
};
function drawBall(b) {
ctx.beginPath();
ctx.fillStyle = b.color;
ctx.arc(b.x, b.y, b.r, 0, 2 * Math.PI, false);
ctx.fill();
}
function updateFrame(balls) {
balls.forEach(updateBall);
}
function drawFrame(balls) {
ctx.clearRect(0, 0, cvs.width, cvs.height);
balls.forEach(drawBall);
};
<canvas width="300" height="150" style="background: #454545"></canvas>
<button onclick="next()">next</button>
<button onclick="loop()">run</button>
But when the speed changes, things get stuck:
var cvs = document.querySelector("canvas");
var ctx = cvs.getContext("2d");
var balls = [
Ball(50, 50, 0, 10, 5, "red"),
Ball(100, 50, 0, 10, 10, "blue"),
Ball(150, 50, 0, 10, 15, "green"),
Ball(200, 50, 0, 10, 20, "yellow")
];
var next = () => {
updateFrame(balls);
drawFrame(balls);
}
var loop = () => {
requestAnimationFrame(() => {
next();
loop();
});
}
next();
function Ball(x, y, vx, vy, r, color) {
return {
x: x,
y: y,
vx: vx,
vy: vy,
r: r,
color: color
}
};
function updateBall(b) {
b.x += b.vx;
b.y += b.vy;
if (b.y <= b.r ||
b.y >= cvs.height - b.r) {
b.vy *= -0.5;
}
};
function drawBall(b) {
ctx.beginPath();
ctx.fillStyle = b.color;
ctx.arc(b.x, b.y, b.r, 0, 2 * Math.PI, false);
ctx.fill();
}
function updateFrame(balls) {
balls.forEach(updateBall);
}
function drawFrame(balls) {
ctx.clearRect(0, 0, cvs.width, cvs.height);
balls.forEach(drawBall);
};
<canvas width="300" height="150" style="background: #454545"></canvas>
<button onclick="next()">next</button>
<button onclick="loop()">run</button>
In your case, I'm thinking this can only happen when there's a paddle collision AND a wall collision simultaneously.
A quick-to-implement solution would be to check if the new position is valid before translating the ball position. If you don't want the precise location, you can place the ball at the point of collision. Note that this will produce a slightly off frame.
E.g.:
var newY = ballY + ballSpeedY;
// Top wall
if(newY <= 10) {
ballY = 10;
ballSpeedY = -ballSpeedY;
}
// Bottom wall
else if(newY >= HEIGHT-10){
ballY = HEIGHT - 10;
ballSpeedY = -ballSpeedY;
}
// No collision
else {
ballY = newY;
}
Update: a more detailed description of what can happen
Let's say your ball collides with the top border of your canvas and with your paddle in the same frame.
First, you move the ball to the colliding position: ballY += ballSpeedY; Say your ballY is 4, and your ballSpeedY is -5, you'll position the ball to -1, inside the wall.
If this were to be the only collision, you should be okay. You flip the speed (ballSpeedY = -ballSpeedY), so in the next frame, your ball should be back at -1 + 5 = 4, so ballY will be 4 again, and your ball will move towards 4 + 5 = 9 in the next frame.
Now a problem arises, when in the -1 positioned frame, you collide with the paddle as well! When the paddle hits the ball, you modify the ballspeed: ballSpeedY = deltaY / 5;. If this turns out to be < 1, your ball won't be able to exit the wall in the next frame. Instead of -1 + 5 = 4, your ball will, for example, move to: -1 + 0.5 = -0.5.
Now, your ball won't be able to get back in to play, since the next frame will, again, calculate a collision and flip the speed. This results in the bouncy, trembling effect you see when the ball gets stuck.
A naive but pretty decent solution, is to only update the position of the ball to a valid position. I.e.: never to a colliding coordinate.
var animate = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback) {
window.setTimeout(callback, 1000 / 60)
};
var canvas = document.createElement("canvas");
var width = 400;
var height = 600;
canvas.width = width;
canvas.height = height;
var context = canvas.getContext('2d');
var player = new Player();
var computer = new Computer();
var ball = new Ball(200, 300);
var keysDown = {};
var render = function () {
context.fillStyle = "#FF00FF";
context.fillRect(0, 0, width, height);
player.render();
computer.render();
ball.render();
};
var update = function () {
player.update();
computer.update(ball);
ball.update(player.paddle, computer.paddle);
};
var step = function () {
update();
render();
animate(step);
};
function Paddle(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.x_speed = 0;
this.y_speed = 0;
}
Paddle.prototype.render = function () {
context.fillStyle = "#0000FF";
context.fillRect(this.x, this.y, this.width, this.height);
};
Paddle.prototype.move = function (x, y) {
this.x += x;
this.y += y;
this.x_speed = x;
this.y_speed = y;
if (this.x < 0) {
this.x = 0;
this.x_speed = 0;
} else if (this.x + this.width > 400) {
this.x = 400 - this.width;
this.x_speed = 0;
}
};
function Computer() {
this.paddle = new Paddle(175, 10, 50, 10);
}
Computer.prototype.render = function () {
this.paddle.render();
};
Computer.prototype.update = function (ball) {
var x_pos = ball.x;
var diff = -((this.paddle.x + (this.paddle.width / 2)) - x_pos);
if (diff < 0 && diff < -4) {
diff = -5;
} else if (diff > 0 && diff > 4) {
diff = 5;
}
this.paddle.move(diff, 0);
if (this.paddle.x < 0) {
this.paddle.x = 0;
} else if (this.paddle.x + this.paddle.width > 400) {
this.paddle.x = 400 - this.paddle.width;
}
};
function Player() {
this.paddle = new Paddle(175, 580, 50, 10);
}
Player.prototype.render = function () {
this.paddle.render();
};
Player.prototype.update = function () {
for (var key in keysDown) {
var value = Number(key);
if (value == 37) {
this.paddle.move(-4, 0);
} else if (value == 39) {
this.paddle.move(4, 0);
} else {
this.paddle.move(0, 0);
}
}
};
function Ball(x, y) {
this.x = x;
this.y = y;
this.x_speed = 0;
this.y_speed = 3;
}
Ball.prototype.render = function () {
context.beginPath();
context.arc(this.x, this.y, 5, 2 * Math.PI, false);
context.fillStyle = "#000000";
context.fill();
};
Ball.prototype.update = function (paddle1, paddle2) {
this.x += this.x_speed;
this.y += this.y_speed;
var top_x = this.x - 5;
var top_y = this.y - 5;
var bottom_x = this.x + 5;
var bottom_y = this.y + 5;
if (this.x - 5 < 0) {
this.x = 5;
this.x_speed = -this.x_speed;
} else if (this.x + 5 > 400) {
this.x = 395;
this.x_speed = -this.x_speed;
}
if (this.y < 0 || this.y > 600) {
this.x_speed = 0;
this.y_speed = 3;
this.x = 200;
this.y = 300;
}
if (top_y > 300) {
if (top_y < (paddle1.y + paddle1.height) && bottom_y > paddle1.y && top_x < (paddle1.x + paddle1.width) && bottom_x > paddle1.x) {
this.y_speed = -3;
this.x_speed += (paddle1.x_speed / 2);
this.y += this.y_speed;
}
} else {
if (top_y < (paddle2.y + paddle2.height) && bottom_y > paddle2.y && top_x < (paddle2.x + paddle2.width) && bottom_x > paddle2.x) {
this.y_speed = 3;
this.x_speed += (paddle2.x_speed / 2);
this.y += this.y_speed;
}
}
};
document.body.appendChild(canvas);
animate(step);
window.addEventListener("keydown", function (event) {
keysDown[event.keyCode] = true;
});
window.addEventListener("keyup", function (event) {
delete keysDown[event.keyCode];
});
http://jsfiddle.net/kHJr6/2/
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Pong Game by Zach</title>
<style>
canvas {
display: block;
position: absolute;
margin: auto;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
</style>
</head>
<body>
<script>
function playGame(form) {
var canvas;
var ctx;
var keystate;
var canvasWidth = form.cWidth.value;
var canvasHeight = form.cHeight.value;
var ballSpeed = form.bSpeed.value;
var playerSpeed = form.pSpeed.value;
var playerWidth = form.pWidth.value;
var playerHeight = form.pHeight.value;
var movePlayer1Up = form.movePlayer1Up.value.charCodeAt(0) - 32;
var movePlayer1Down = form.movePlayer1Down.value.charCodeAt(0) - 32;
if (form.movePlayer2Up.value == "UpArrow") {
var movePlayer2Up = 38;
} else {
var movePlayer2Up = form.movePlayer2Up.value.charCodeAt(0) - 32;
}
if (form.movePlayer2Down.value == "DownArrow") {
var movePlayer2Down = 40;
} else {
var movePlayer2Down = form.movePlayer2Down.value.charCodeAt(0) - 32;
}
var player1 = {
x: null,
y: null,
score: null,
width: playerWidth,
height: playerHeight,
update: function() {
if (keystate[movePlayer1Up]) this.y -= playerSpeed;
if (keystate[movePlayer1Down]) this.y -= -playerSpeed;
this.y = Math.max(Math.min(this.y, canvasHeight - this.height), 0);
},
draw: function() {
ctx.fillRect(this.x, this.y, this.width, this.height);
}
};
var player2 = {
x: null,
y: null,
score: null,
width: playerWidth,
height: playerHeight,
update: function() {
if (keystate[movePlayer2Up]) this.y -= 7;
if (keystate[movePlayer2Down]) this.y += 7;
this.y = Math.max(Math.min(this.y, canvasHeight - this.height), 0);
},
draw: function() {
ctx.fillRect(this.x, this.y, this.width, this.height);
}
};
var ball = {
x: null,
y: null,
vel: null,
side: 20,
serve: function(side) {
var r = Math.random();
this.x = canvasWidth / 2;
this.y = (canvasHeight - this.side) * r;
var phi = 0.1 * Math.PI * (1 - 2 * r);
this.vel = {
x: side * ballSpeed * Math.cos(phi),
y: ballSpeed * Math.sin(phi)
}
},
update: function() {
this.x += this.vel.x;
this.y += this.vel.y;
if (0 > this.y || this.y + this.side > canvasHeight) {
var offset = this.vel.y < 0 ? 0 - this.y : canvasHeight - (this.y + this.side);
this.y += 2 * offset;
this.vel.y *= -1;
}
var AABBIntersect = function(ax, ay, aw, ah, bx, by, bw, bh) {
return ax < bx + bw && ay < by + bh && bx < ax + aw && by < ay + ah;
};
var pdle = this.vel.x < 0 ? player1 : player2;
if (AABBIntersect(pdle.x, pdle.y, pdle.width, pdle.height,
this.x, this.y, this.side, this.side)) {
this.x = pdle === player1 ? player1.x + player1.width : player2.x - this.side;
var n = (this.y + this.side - pdle.y) / (pdle.height + this.side);
var phi = 0.25 * Math.PI * (2 * n - 1);
var smash = Math.abs(phi) > 0.2 * Math.PI ? 1.5 : 1;
this.vel.x = smash * (pdle === player1 ? 1 : -1) * ballSpeed * Math.cos(phi);
this.vel.y = smash * ballSpeed * Math.sin(phi);
}
if (0 > this.x + this.side || this.x > canvasWidth) {
ballSpeed = 12;
var isplayer1 = pdle === player1;
player1.score += isplayer1 ? 0 : 1;
player2.score += isplayer1 ? 1 : 0;
this.serve(pdle === player1 ? 1 : -1);
}
},
draw: function() {
ctx.fillRect(this.x, this.y, this.side, this.side);
}
};
function mplayer2n() {
canvas = document.createElement("canvas");
canvas.width = canvasWidth;
canvas.height = canvasHeight;
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() {
player1.x = player1.width;
player1.y = (canvasHeight - player1.height) / 2;
player2.x = canvasWidth - (player1.width + player2.width);
player2.y = (canvasHeight - player2.height) / 2;
player1.score = 0;
player2.score = 0;
ball.serve(1);
}
function update() {
if (player1.score < 10 && player2.score < 10) {
ball.update();
player1.update();
player2.update();
}
}
function draw() {
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
ctx.save();
ctx.fillStyle = "red";
player1.draw();
ctx.fillStyle = "blue";
player2.draw();
ctx.fillStyle = "white";
ball.draw();
var w = 4;
var x = (canvasWidth - w) * 0.5;
var y = 0;
var step = canvasHeight / 20;
while (y < canvasHeight) {
ctx.fillStyle = "white"
ctx.fillRect(x, y + step * 0.25, w, step * 0.5);
y += step;
}
ctx.font = "150px Georgia"
var t = player1.score
var v = player2.score
ctx.fillText(t, canvas.width / 2 - ctx.measureText(t).width - 20, 100);
ctx.fillText(v, canvas.width / 2 + 20, 100)
if (player1.score > 9) {
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
ctx.fillStyle = "Black"
ctx.font = "100px Georgia"
var u = t + " - " + v
var w = "Player 1 wins"
ctx.fillText(w, canvas.width / 2 - ctx.measureText(w).width / 2, 130);
ctx.font = "150px Georgia"
ctx.fillText(u, canvas.width / 2 - ctx.measureText(u).width / 2, 300);
} else if (player2.score > 9) {
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
ctx.fillStyle = "Black"
ctx.font = "100px Georgia"
var u = t + " - " + v
var w = "Player 2 wins"
ctx.fillText(w, canvas.width / 2 - ctx.measureText(w).width / 2, 130);
ctx.font = "150px Georgia"
ctx.fillText(u, canvas.width / 2 - ctx.measureText(u).width / 2, 300);
}
ctx.restore();
}
mplayer2n();
}
</script>
<form action="">
Settings:
<br>Canvas Width:
<br>
<input type="text" name="cWidth" value="1200">
<br>Canvas Height:
<br>
<input type="text" name="cHeight" value="600">
<br>Ball Speed:
<br>
<input type="text" name="bSpeed" value="12">
<br>Player Speed:
<br>
<input type="text" name="pSpeed" value="8">
<br>Player Width:
<br>
<input type="text" name="pWidth" value="20">
<br>Player Height:
<br>
<input type="text" name="pHeight" value="100">
<br>Move Player 1 Up:
<br>
<input type="text" name="movePlayer1Up" value="w">
<br>Move Player 1 Down:
<br>
<input type="text" name="movePlayer1Down" value="s">
<br>Move Player 2 Up:
<br>
<input type="text" name="movePlayer2Up" value="UpArrow">
<br>Move Player 2 Down:
<br>
<input type="text" name="movePlayer2Down" value="DownArrow">
<br>Save Settings and start game:
<br>
<input type="button" name="Start" value="Start" onClick="playGame(this.form)">
<br>
</form>
</body>
</html>
Above is the code that I have so far.
The part in question is the bottom part with the form and the part near the top where I am defining the variables for the settings.
I was making a pong game and it was working as expected until I tried to add a <form> so the player could customise the settings and controls.
I then set the variables I had used before to the values from this form. The problem was that when I when I added in the "player width" and "player height" variables. The game glitched out. Eg. The ball would bounce early, a paddle was missing etc.
Any ideas why this would occur when the data entered into the form was the same as the constants I had had before which worked perfectly fine.
You are reading the player width and player height in as text. You need to convert to integers. Do the same for player2.
var player1 = {
x: null,
y: null,
score: null,
width: parseInt(playerWidth),
height: parseInt(playerHeight),
I've been trying to make objects scroll through the canvas, like when it goes down, it will come out of the top. I have got it working for the bottom and right sides, but it just gets stuck on the left and top side.
Here is what the code looks like in action
http://output.jsbin.com/gavuqo/
Here is my javascript code:
var count = 1;
var myGamePiece;
var myObstacle;
var myHealth;
var myScore;
function startGame() {
myGamePiece = new component(40, 40, "http://www.link", 10, 120, "image");
myObstacle = new component(60, 60, "http://www.link", 300, 120, "image");
myHealth = new component(60, 60, "http://www.link", 300, 100, "image");
myGameArea.start();
}
var myGameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 600;
this.canvas.height = 400;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.frameNo = 0;
this.interval = setInterval(updateGameArea, 20);
},
clear : function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
},
stop : function() {
clearInterval(this.interval);
}
};
function component(width, height, color, x, y, type) {
this.type = type;
if (type == "image") {
this.image = new Image();
this.image.src = color;
}
this.width = width;
this.height = height;
this.angle = Math.floor(Math.random() * 360) + 0 ;
this.speed = 1;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.update = function() {
ctx = myGameArea.context;
if (type == "image") {
ctx.drawImage(this.image,
this.x,
this.y,
this.width, this.height);
} else {
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
this.newPos = function() {
if( this.x<=0 || this.x>=600){this.x = -this.speed * Math.sin(this.angle);}else{ this.x += this.speed * Math.sin(this.angle);
}
if( this.y<=0 || this.y>=400) {this.y = -this.speed * Math.cos(this.angle);}else{
this.y += this.speed * Math.cos(this.angle);}
}
//myObstacle.newPos();
this.newPosmain = function() {
this.x += this.speedX;
this.y += this.speedY;
};
this.crashWith = function(otherobj) {
var myleft = this.x;
var myright = this.x + (this.width);
var mytop = this.y;
var mybottom = this.y + (this.height);
var otherleft = otherobj.x;
var otherright = otherobj.x + (otherobj.width);
var othertop = otherobj.y;
var otherbottom = otherobj.y + (otherobj.height);
var crash = true;
if ((mybottom < othertop) ||
(mytop > otherbottom) ||
(myright < otherleft) ||
(myleft > otherright)) {
crash = false;
}
return crash;
};
}
function updateGameArea() {
if (myGamePiece.crashWith(myObstacle) && count==1) {
myObstacle = new component(60, 60, "http://www.link", 300, 120, "image");
count++;
myGamePiece = new component(80, 80, "http://www.link", 10, 120, "image");
} else {
myGameArea.clear();
myObstacle.update();
//myObstacle.wallBounce();
myObstacle.newPos();
myHealth.update();
myHealth.newPos();
//myHealth.wallBounce();
myGamePiece.newPosmain();
myGamePiece.update();
}
if(myGamePiece.crashWith(myObstacle) && count==2){
myObstacle = new component(60, 60, "http://www.link", 300, 120, "image");
myGamePiece = new component(100, 100, "http://www.link", 10, 120, "image");
count++;
}
if(myGamePiece.crashWith(myObstacle) && count==3){
myGamePiece = new component(500, 500, "#", 0, 0, "image");
myeGameArea.stop();
document.body.style.backgroundImage = "url('#')";
count=0;
}
if(myGamePiece.crashWith(myHealth) && count==1){
myGamePiece = new component(100, 100, "http://www.link", 10, 120, "image");
count=0;
count--;
}
if(myGamePiece.crashWith(myHealth) && count==2){
myGamePiece = new component(40, 40, "http://www.link", 10, 120, "image");
count--;
}
if(myGamePiece.crashWith(myObstacle) && count==0){
myObstacle = new component(60, 60, "http://www.link", 300, 120, "image");
myGamePiece = new component(100, 100, "http://www.link", 10, 120, "image");
count++;
}
if(myGamePiece.crashWith(myHealth) && count==0){
myGamePiece = new component(500, 500, "http://example.com", 0, 0, "image");
}
}
function moveup() {
myGamePiece.speedY = -2;
}
function movedown() {
myGamePiece.speedY = 2;
}
function moveleft() {
myGamePiece.speedX = -2;
}
function moveright() {
myGamePiece.speedX = 2;
}
function clearmove() {
myGamePiece.speedX = 0;
myGamePiece.speedY = 0;
}
Simply adjust either the x or y position to be opposite of the exit point. If it exits at the bottom then reset it to top minus diameter of the object without adjusting x, and so forth.
In generic code:
// dia = diameter of object (you may have to use different values for width/height)
if (x < -dia) x = width;
else if (x >= width) x = -dia;
if (y < -dia) y = height;
else if (y >= height) y = -dia;
Example
(click run again to change direction)
var ctx = c.getContext("2d"),
x = c.width * 0.5, y = c.height * 0.5,
dx = Math.max(2, Math.random() * 4),
dy = Math.max(2, Math.random() * 4),
dia = 10;
dx *= Math.random() < 0.5 ? -1 : 1;
dy *= Math.random() < 0.5 ? -1 : 1;
(function loop() {
ctx.clearRect(0,0,c.width,c.height);
ctx.fillRect(x, y, dia, dia);
x += dx;
y += dy;
if (x < -dia) x = c.width;
else if (x >= c.width) x = -dia;
if (y < -dia) y = c.height;
else if (y >= c.height) y = -dia;
requestAnimationFrame(loop)
})()
#c {border:1px solid #999}
<canvas id=c>