Recently, i made a game on codepen.io called flappy bird an it was working fine there but when i tried to show it on my website it doesn't show up anything.
Can someone tell what's missing or what is the problem in my code.
here is the code ( sorry it's too long , i know but i need help ):
<html>
<head>
<style type="text/css">
#stage {
display:block;
border:solid 1px #000;
margin:auto;
}
body{
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background:#333;
}
</style>
<script type="text/javascript">
window.requestAnimationFrame = (function(){
return window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(cb){
return setTimeout(cb, 1000/60);
};
})()
var can = document.getElementById("stage"),
ctx = can.getContext('2d'),
wid = can.width,
hei = can.height,
player, floor, pillars, gravity, thrust, running,
rainbows, colider, score, gPat, pPat, trans, termVel, pillGap,
pillWid, pillSpace, speed, stars, high,
sprite = document.createElement("img");
sprite.src = "http://www.cutmypic.com/uploads/title85083782.png";
//sprite.src = "http://i.stack.imgur.com/Vy3qB.gif";
sprite.onload = function(){
sprite.style.height = 0;
loop();
};
sprite.width = 34;
sprite.height = 21;
document.body.appendChild(sprite);
function init() {
high = localStorage.getItem("high") || 0;
player = {
x: 1 / 3 * wid,
y: 2 / 5 * hei,
r: 13,
v: 0
};
speed = 2.5;
floor = 4 / 5 * hei;
pillars = [];
rainbows = [];
stars = [];
gravity = .30;
thrust = gravity * -21;
termVel = -thrust + 2;
running = false;
colider = false;
score = 0;
trans = 0;
pillGap = 135;
pillWid = 55;
pillSpace = pillWid*3;
pPat = ctx.createPattern((function(){
var can = document.createElement("canvas"),
ctx = can.getContext("2d");
can.width = 60;
can.height = 60;
["green", "green", "green",
"#3b5998", "green", "#3b5998"].forEach(function(color, i){
ctx.fillStyle = color;
ctx.beginPath();
ctx.moveTo(i*10, 0);
ctx.lineTo(i*10+10, 0);
ctx.lineTo(0, i*10+10);
ctx.lineTo(0, i*10);
ctx.closePath();
ctx.fill();
ctx.beginPath();
ctx.moveTo(i*10, 60);
ctx.lineTo(i*10+10, 60);
ctx.lineTo(60, i*10+10);
ctx.lineTo(60, i*10);
ctx.closePath();
ctx.fill();
});
return can;
})(), "repeat");
gPat = ctx.createPattern((function(){
var can = document.createElement("canvas"),
ctx = can.getContext("2d");
can.width = 32;
can.height = 32;
ctx.save();
ctx.translate(16,16);
ctx.rotate(Math.PI/4);
ctx.fillStyle = "#79CDCD";
ctx.fillRect(-64,-64,128,128);
ctx.fillStyle = "#528B8B";
ctx.fillRect(-8,-64,8,128);
ctx.fillRect(14.5,-64,8,128);
ctx.restore();
return can;
})(), "repeat");
}
function render() {
trans -= speed;
rainbows = rainbows.filter(function(r){
r.x -= speed;
return r.x > -speed;
});
if (trans % speed === 0){
rainbows.push({x:player.x-10, y:player.y - (trans%50/25|0)*2 - 1});
}
stars = stars.filter(function(s){
trans % 10 || (s.r += 1);
s.x -= speed;
return s.x > -speed && s.r < 10;
});
if(trans % 20 === 0){
stars.push({
x: Math.round(Math.random()*(wid-50)+100),
y:Math.round(Math.random()*floor),
r:0
});
}
// backdrop
ctx.fillStyle = "#418bbc";
ctx.fillRect(0, 0, wid, hei);
//stars
ctx.fillStyle = "white";
stars.forEach(function (s){
ctx.fillRect(s.x, s.y - s.r-2, 2, s.r/2);
ctx.fillRect(s.x - s.r-2, s.y, s.r/2, 2);
ctx.fillRect(s.x, s.y+s.r + 2, 2, s.r/2);
ctx.fillRect(s.x+s.r + 2, s.y, s.r/2, 2);
ctx. fillRect(s.x + s.r, s.y + s.r, 2, 2);
ctx. fillRect(s.x - s.r, s.y - s.r, 2, 2);
ctx. fillRect(s.x + s.r, s.y - s.r, 2, 2);
ctx. fillRect(s.x - s.r, s.y + s.r, 2, 2);
});
//ground
ctx.fillStyle = "#2F4F4F";
ctx.fillRect(0, floor, wid, hei-floor);
ctx.save();
ctx.translate(trans, 0);
//pillars
ctx.fillStyle = pPat;
ctx.strokeStyle = "#ccc";
ctx.lineWidth = 2;
for (var i = 0; i < pillars.length; i++){
var pill = pillars[i];
ctx.fillRect(pill.x, pill.y, pill.w, pill.h);
ctx.strokeRect(pill.x, pill.y, pill.w, pill.h);
}
// stripe
ctx.fillStyle = gPat;
ctx.fillRect(-trans, floor+2, wid, 15);
ctx.restore();
//rainbowwwwws
rainbows.forEach(function(r){
["red","orange","blue","green","blue","indigo"].forEach(function(color, i){
ctx.fillStyle = color;
ctx.fillRect(r.x - speed, r.y-9 + i*3, speed+1, 3);
});
});
//player
ctx.save();
ctx.translate(player.x, player.y);
ctx.rotate(player.v*Math.PI/18);
ctx.drawImage(sprite, - 17, - 10);
ctx.restore();
ctx.fillStyle = "#97FFFF";
ctx.fillRect(0, floor, wid, 2);
ctx.fillStyle = "#2F4F4F";
ctx.fillRect(0, floor+1, wid, 1);
ctx.fillStyle = "#97FFFF";
ctx.fillRect(0, floor+17, wid, 2);
ctx.fillStyle = "#2F4F4F";
ctx.fillRect(0, floor+17, wid, 1);
//score
ctx.font = "bold 30px monospace";
var hScore = "best:" + (score > high ? score : high),
sWid = ctx.measureText(hScore).width,
sY = 50;
ctx.fillStyle = "black";
ctx.fillText(score, 12, floor + sY + 2);
ctx.fillText(hScore, wid - sWid - 10, floor + sY + 2);
ctx.fillStyle = "white";
ctx.fillText(score, 10, floor + sY);
ctx.fillText(hScore, wid - sWid - 12, floor + sY);
}
function adjust() {
if (trans%pillSpace === 0){
var h;
pillars.push({
x: -trans + wid,
y: 0,
w: pillWid,
h: (h = Math.random() * (floor - 300) + 100)
});
pillars.push({
x: -trans + wid,
y: h + pillGap,
w: pillWid,
h: floor - h - pillGap
});
}
pillars = pillars.filter(function(pill){
return -trans < pill.x + pill.w;
});
player.v += gravity;
if (player.v > termVel){
player.v = termVel;
}
player.y += player.v;
if (player.y < player.r) {
player.y = player.r;
player.v = 0;
}
for(var i = 0; i < pillars.length; i++){
var pill = pillars[i];
if (pill.x + trans < player.x + player.r &&
pill.x + pill.w + trans > player.x - player.r){
if (player.y - player.r > pill.y &&
player.y - player.r < pill.y + pill.h){
colider = true
running = false;
render();
break;
}
if (player.y + player.r < pill.y + pill.h &&
player.y + player.r > pill.y){
colider = true
running = false;
render();
break;
}
if (!pill.passed && i%2 == 1){
score++;
pill.passed = true;
}
}
}
if (player.y + player.r - player.v > floor) {
player.y = floor - player.r;
running = false;
colider = true;
render();
}
}
document.onmousedown = function () {
if (running) {
player.v = thrust;
} else if (!colider) {
running = true;
} else {
if (score > high){
localStorage.setItem("high", score);
}
init();
}
};
</script>
</head>
<body>
<canvas id="stage" width="400" height="600"></canvas>
</body>
Your calling document.getElementById('stage') before #stage exists in the DOM.
Javascript is run in the order that it is loaded into the page. So, you could either move the Javascript to the bottom of your HTML document, or us an onload event listener.
In detail, as the page loads, things at the top of the page are pulled in and parsed first. When a <script> tag is encountered, the browser automatically runs the Javascript immediately -- before it has reached the body of the page. Your CodePen was likely set to run the code after the page had loaded completely, but when you moved it all to it's own page you were now running it before load.
Related
I want to complete polygon when starting point of polygon clicked, i think i need to hide or set opacity of last line which is linking to first point of line.
goal is to achieve exactly what is happening in this GIF.
also i want to show angles and length on each line while drawing just like exactly same as GIF.
var bw = window.innerWidth -20;
var bh = window.innerHeight -20;
var p = 10;
var cw = bw + (p*2) + 1;
var ch = bh + (p*2) + 1;
var canvas = document.getElementById("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var context = canvas.getContext("2d");
function drawBoard(){
for (var x = 0; x <= bw; x += 30) {
context.moveTo(0.5 + x + p, p);
context.lineTo(0.5 + x + p, bh + p);
}
for (var x = 0; x <= bh; x += 30) {
context.moveTo(p, 0.5 + x + p);
context.lineTo(bw + p, 0.5 + x + p);
}
context.lineWidth = 0.5;
context.strokeStyle = 'rgba(0, 122, 204,0.7)';
context.stroke();
}
drawBoard();
//---------------------------------------------
requestAnimationFrame(update)
mouse = {x : 0, y : 0, button : 0, lx : 0, ly : 0, update : true};
function mouseEvents(e){
const bounds = canvas.getBoundingClientRect();
mouse.x = e.pageX - bounds.left - scrollX;
mouse.y = e.pageY - bounds.top - scrollY;
mouse.button = e.type === "mousedown" ? true : e.type === "mouseup" ? false : mouse.button;
mouse.update = true;
}
["mousedown","mouseup","mousemove"].forEach(name => document.addEventListener(name,mouseEvents));
context.lineWidth = 2;
context.strokeStyle = "red";
const point = (x,y) => ({x,y});
const poly = () => ({
points : [],
addPoint(p){ this.points.push(point(p.x,p.y)) },
draw() {
context.lineWidth = 2;
context.strokeStyle = "red";
context.fillStyle = 'rgba(255, 0, 0, 0.3)';
context.beginPath();
for (const p of this.points) { context.lineTo(p.x,p.y) }
context.closePath();
context.stroke();
context.fill();
context.fillStyle = 'rgba(0, 0, 0, 0.3)';
context.strokeStyle = 'rgba(0, 0, 0, 0.8)';
for (const p of this.points) {
context.beginPath();
context.moveTo(p.x + 10,p.y);
context.arc(p.x,p.y,10,0,Math.PI *2);
context.fill();
context.stroke();
}
},
closest(pos, dist = 8) {
var i = 0, index = -1;
dist *= dist;
for (const p of this.points) {
var x = pos.x - p.x;
var y = pos.y - p.y;
var d2 = x * x + y * y;
if (d2 < dist) {
dist = d2;
index = i;
}
i++;
}
if (index > -1) { return this.points[index] }
}
});
function drawCircle(pos,color="black",size=8){
context.strokeStyle = color;
context.beginPath();
context.arc(pos.x,pos.y,size,0,Math.PI *2);
context.stroke();
}
const polygon = poly();
var activePoint,cursor;
var dragging= false;
function update(){
if (mouse.update) {
cursor = "crosshair";
context.clearRect(0,0,canvas.width,canvas.height);
drawBoard();
if (!dragging) { activePoint = polygon.closest(mouse) }
if (activePoint === undefined && mouse.button) {
polygon.addPoint(mouse);
mouse.button = false;
} else if(activePoint) {
if (mouse.button) {
if(dragging) {
activePoint.x += mouse.x - mouse.lx;
activePoint.y += mouse.y - mouse.ly;
} else { dragging = true }
} else { dragging = false }
}
polygon.draw();
if (activePoint) {
drawCircle(activePoint);
cursor = "move";
}
mouse.lx = mouse.x;
mouse.ly = mouse.y;
canvas.style.cursor = cursor;
mouse.update = false;
}
requestAnimationFrame(update)
}
<html>
<body style=" background: lightblue;">
<canvas id="canvas" style="background: #fff; magrin:20px;"></canvas>
</body>
</html>
Drawing part of code i copied from: https://stackoverflow.com/a/53437943/3877726
You can use ctx.setTransform to to align text to a line.
First normalize the vector between the end points and use that normalized vector to build the transform. See example.
To prevent text from reading back to front you need to check the x component of the normalized vector. If it is < 0 then reverse the vector.
Almost the same for the angle. See example.
Example
Snippets contain the functions drawLineText and drawAngleText (near top) that implement the additional features.
var bw = innerWidth - 20, bh = innerHeight - 20;
var cw = bw + (p * 2) + 1, ch = bh + (p * 2) + 1;
var p = 10;
var activePoint, cursor, dragging = false;
const mouse = {x: 0, y: 0, button: 0, lx: 0, ly: 0, update: true};
const TEXT_OFFSET = 5;
const TEXT_COLOR = "#000";
const TEXT_SIZE = 16;
const FONT = "arial";
const TEXT_ANGLE_OFFSET = 25;
const DEG = "°";
canvas.width = bw;
canvas.height = bh;
var ctx = canvas.getContext("2d");
function drawLineText(p1, p2, text, textOffset = TEXT_OFFSET, textColor = TEXT_COLOR, textSize = TEXT_SIZE, font = FONT) {
var x = p1.x, y = p1.y;
var nx = p2.x - x, ny = p2.y - y, len = (nx * nx + ny * ny) ** 0.5;
nx /= len;
ny /= len;
ctx.font = textSize + "px " + font;
ctx.textAlign = "center";
ctx.fillStyle = textColor;
if (nx < 0) {
ctx.textBaseline = "top";
x = p2.x;
y = p2.y;
nx = -nx;
ny = -ny;
textOffset = -textOffset;
} else { ctx.textBaseline = "bottom" }
len /= 2;
ctx.setTransform(nx, ny, -ny, nx, x, y);
ctx.fillText(text, len, -textOffset);
}
// angle between p2-p1 and p2-p3
function drawAngleText(p1, p2, p3, textAngleOffset = TEXT_ANGLE_OFFSET, textColor = TEXT_COLOR, textSize = TEXT_SIZE, font = FONT) {
var ang;
var x = p2.x, y = p2.y;
var nx1 = p1.x - x, ny1 = p1.y - y, len1 = (nx1 * nx1 + ny1 * ny1) ** 0.5;
var nx2 = p3.x - x, ny2 = p3.y - y, len2 = (nx2 * nx2 + ny2 * ny2) ** 0.5;
nx1 /= len1;
ny1 /= len1;
nx2 /= len2;
ny2 /= len2;
const cross = nx1 * ny2 - ny1 * nx2;
const dot = nx1 * nx2 + ny1 * ny2;
if (dot < 0) {
ang = cross < 0 ? -Math.PI - Math.asin(cross) : Math.PI - Math.asin(cross);
} else {
ang = Math.asin(cross);
}
const angDeg = Math.abs(ang * (180 / Math.PI)).toFixed(0) + DEG;
ctx.font = textSize + "px " + font;
ctx.fillStyle = textColor;
ctx.textBaseline = "middle";
const centerAngle = Math.atan2(ny1, nx1) + ang / 2;
const nx = Math.cos(centerAngle);
const ny = Math.sin(centerAngle);
if (nx < 0) {
ctx.textAlign = "right";
ctx.setTransform(-nx, -ny, ny, -nx, x, y);
textAngleOffset = -textAngleOffset;
} else {
ctx.textAlign = "left";
ctx.setTransform(nx, ny, -ny, nx, x, y);
}
ctx.fillText(angDeg, textAngleOffset, 0);
}
//---------------------------------------------
requestAnimationFrame(update)
function mouseEvents(e) {
const bounds = canvas.getBoundingClientRect();
mouse.x = e.pageX - bounds.left - scrollX;
mouse.y = e.pageY - bounds.top - scrollY;
mouse.button = e.type === "mousedown" ? true : e.type === "mouseup" ? false : mouse.button;
mouse.update = true;
}
["mousedown", "mouseup", "mousemove"].forEach(name => document.addEventListener(name, mouseEvents));
ctx.lineWidth = 2;
ctx.strokeStyle = "red";
const point = (x, y) => ({x, y});
const poly = () => ({
points: [],
closed: false,
addPoint(p) { this.points.push(point(p.x, p.y)) },
draw() {
ctx.lineWidth = 2;
ctx.strokeStyle = "red";
ctx.fillStyle = 'rgba(255, 0, 0, 0.3)';
ctx.beginPath();
for (const p of this.points) { ctx.lineTo(p.x, p.y) }
this.closed && ctx.closePath();
ctx.stroke();
this.closed && ctx.fill();
ctx.fillStyle = 'rgba(0, 0, 0, 0.3)';
ctx.strokeStyle = 'rgba(0, 0, 0, 0.8)';
for (const p of this.points) {
ctx.beginPath();
ctx.moveTo(p.x + 10, p.y);
ctx.arc(p.x, p.y, 10, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
}
this.points.length > 1 && this.drawLengthText();
this.points.length > 2 && this.drawAngleText();
},
drawLengthText() {
const len = this.points.length;
var p1, i = 0;
p1 = this.points[i];
while (i < len -(this.closed ? 0 : 1)) {
const p2 = this.points[((i++) + 1) % len];
const lineLength = ((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2) ** 0.5
drawLineText(p1, p2, lineLength.toFixed(0) + "px");
if (len < 3) { break }
p1 = p2;
}
ctx.setTransform(1, 0, 0, 1, 0, 0);
},
drawAngleText() {
const len = this.points.length;
var p1, p2, i = this.closed ? 0 : 1;
p1 = this.points[(i + len - 1) % len];
p2 = this.points[i];
while (i < len -(this.closed ? 0 : 1)) {
const p3 = this.points[((i++) + 1) % len];
drawAngleText(p1, p2, p3);
p1 = p2;
p2 = p3;
}
ctx.setTransform(1, 0, 0, 1, 0, 0);
},
closest(pos, dist = 8) {
var i = 0,
index = -1;
dist *= dist;
for (const p of this.points) {
var x = pos.x - p.x;
var y = pos.y - p.y;
var d2 = x * x + y * y;
if (d2 < dist) {
dist = d2;
index = i;
}
i++;
}
if (index > -1) { return this.points[index] }
}
});
const polygon = poly();
function drawCircle(pos, color = "black", size = 8) {
ctx.strokeStyle = color;
ctx.beginPath();
ctx.arc(pos.x, pos.y, size, 0, Math.PI * 2);
ctx.stroke();
}
function update() {
if (mouse.update) {
cursor = "crosshair";
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (!dragging) { activePoint = polygon.closest(mouse) }
if (activePoint === undefined && mouse.button) {
polygon.addPoint(mouse);
mouse.button = false;
} else if (activePoint) {
if (mouse.button) {
if (dragging) {
activePoint.x += mouse.x - mouse.lx;
activePoint.y += mouse.y - mouse.ly;
} else {
if (!polygon.closed && polygon.points.length > 2 && activePoint === polygon.points[0]) {
polygon.closed = true;
}
dragging = true
}
} else { dragging = false }
}
polygon.draw();
if (activePoint) {
drawCircle(activePoint);
cursor = "move";
}
mouse.lx = mouse.x;
mouse.ly = mouse.y;
canvas.style.cursor = cursor;
mouse.update = false;
}
requestAnimationFrame(update)
}
Click to add points
<canvas id="canvas" style="background: #fff; magrin:20px;"></canvas>
Note though not mandatory it is customarily considered polite to include attributions when copying code.
I am trying to create a blackhole simulation, where all the balls that are outside of it go away from it at a given speed and those that fall on it are dragged towards the circle until they reach the center of it, where they would stop and disappear, here is my code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>blackhole simulation escape velocity</title>
<script>
var canvas, ctx;
var blackhole;
var circle;
var circles = new Array();
var G = 6.67e-11, //gravitational constant
pixel_G = G / 1e-11,
c = 3e8, //speed of light (m/s)
M = 12e31, // masseof the blackhole in kg (60 solar masses)
pixel_M = M / 1e32
Rs = (2 * G * M) / 9e16, //Schwarzchild radius
pixel_Rs = Rs / 1e3, // scaled radius
ccolor = 128;
function update() {
var pos, i, distance, somethingMoved = false;
for (i = 0; i < circles.length; i++) {
pos = circles[i].position;
distance = Math.sqrt(((pos.x - 700) * (pos.x - 700)) + ((pos.y - 400) * (pos.y - 400)));
if (distance > pixel_Rs-5 ) {
var delta = new Vector2D(0, 0);
var forceDirection = Math.atan2(pos.y - 400, pos.x - 700);
var evelocity = Math.sqrt((2 * pixel_G * pixel_M) / (distance * 1e-2));
delta.x += Math.cos(forceDirection) * evelocity;
delta.y += Math.sin(forceDirection) * evelocity;
pos.x += delta.x;
pos.y += delta.y;
somethingMoved = true;
} else {
var delta2 = new Vector2D (0,0);
var forceDirection2 = Math.atan2(pos.y - 400, pos.x - 700);
var g = (pixel_G*pixel_M)/(distance*distance*1e2);
delta2.x += Math.cos(forceDirection2)*g;
delta2.y += Math.sin(forceDirection2)*g;
pos.x -= delta2.x;
pos.y -= delta2.y;
somethingMoved = true;
circles[i].color -= 1;
if (pos.x == 700 && pos.y == 400){
somethingMoved = false;
};
}
}
if (somethingMoved) {
drawEverything();
requestAnimationFrame(update);
};
}
function drawEverything() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
blackhole.draw(ctx);
for (var i = 0; i < circles.length; i++) {
circles[i].draw(ctx);
}
}
function init(event) {
canvas = document.getElementById("space");
ctx = canvas.getContext('2d');
blackhole = new Ball(pixel_Rs, { x: 700,
y: 400 }, 0);
for (var i = 0; i < 200; i++) {
var vec2D = new Vector2D(Math.floor(Math.random() * 1400), Math.floor(Math.random() * 800));
circle = new Ball(5, vec2D, ccolor);
circles.push(circle);
}
drawEverything();
requestAnimationFrame(update);
}
function Ball(radius, position, color) {
this.radius = radius;
this.position = position;
this.color = color;
}
Ball.prototype.draw = function(ctx) {
var c=parseInt(this.color);
ctx.fillStyle = 'rgba(' + c + ',' + c + ',' + c + ',1)';
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.radius, 0, 2 * Math.PI);
ctx.closePath();
ctx.fill();
};
function Vector2D(x, y) {
this.x = x;
this.y = y;
}
function onClick (){
canvas = document.getElementById ('space');
ctx = canvas.getContext ('2d')
canvas.addEventListener ("mousedown", init, false)
blackhole = new Ball (5, {x: 700,
y: 400 }, 0);
blackhole.draw (ctx) ;
}
window.onload = onClick;
</script>
<style>
body {
background-color:#021c36 ;
margin: 0px;
}
</style>
</head>
<body>
<canvas id = "space", width = "1400", height = "800">
</canvas>
</body>
</html>
Now as you can see, I created a second variable called delta2, but the problem is that it can't update the position of the circles, which in term makes it impossible to move the circle, can someone tell me what is wrong. Also, how can I make the big black circle after a certain amount of time, i know i probably should create a timer, but i don't know how they work
The gravity is too weak. I put a pseudo gravity to demonstrate.
var canvas, ctx;
var blackhole;
var circle;
var circles = new Array();
var bh = {
w:500,
h:300
};
bh.cx = Math.floor(bh.w/2);
bh.cy = Math.floor(bh.h/2)
var G = 6.67e-11, //gravitational constant
pixel_G = G / 1e-11,
c = 3e8, //speed of light (m/s)
M = 12e31, // masseof the blackhole in kg (60 solar masses)
pixel_M = M / 1e32
Rs = (2 * G * M) / 9e16, //Schwarzchild radius
pixel_Rs = Rs / 1e3, // scaled radius
ccolor = 128;
function update() {
var pos, i, distance, somethingMoved = false;
for (i = 0; i < circles.length; i++) {
pos = circles[i].position;
distance = Math.sqrt(((pos.x - bh.cx) * (pos.x - bh.cx)) + ((pos.y - bh.cy) * (pos.y - bh.cy)));
if (distance > pixel_Rs - 5) {
var delta = new Vector2D(0, 0);
var forceDirection = Math.atan2(pos.y - bh.cy, pos.x - bh.cx);
var evelocity = Math.sqrt((2 * pixel_G * pixel_M) / (distance * 1e-2));
delta.x += Math.cos(forceDirection) * evelocity;
delta.y += Math.sin(forceDirection) * evelocity;
pos.x += delta.x;
pos.y += delta.y;
somethingMoved = true;
} else {
var delta2 = new Vector2D(0, 0);
var forceDirection2 = Math.atan2(pos.y - bh.cy, pos.x - bh.cx);
// FIX THIS!!!
var g = 1;//(pixel_G * pixel_M) / (distance * distance * 1e2);
delta2.x += Math.cos(forceDirection2) * g;
delta2.y += Math.sin(forceDirection2) * g;
pos.x -= delta2.x;
pos.y -= delta2.y;
somethingMoved = true;
circles[i].color -= 1;
if (pos.x == bh.cx && pos.y == bh.cy) {
somethingMoved = false;
};
}
}
if (somethingMoved) {
drawEverything();
requestAnimationFrame(update);
};
}
function drawEverything() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
blackhole.draw(ctx);
for (var i = 0; i < circles.length; i++) {
circles[i].draw(ctx);
}
}
function init(event) {
canvas = document.getElementById("space");
canvas.width = bh.w;
canvas.height = bh.h;
ctx = canvas.getContext('2d');
blackhole = new Ball(5, { //pixel_Rs, {
x: bh.cx,
y: bh.cy
}, 0);
for (var i = 0; i < 200; i++) {
var vec2D = new Vector2D(Math.floor(Math.random() * bh.w), Math.floor(Math.random() * bh.h));
circle = new Ball(5, vec2D, ccolor);
circles.push(circle);
}
drawEverything();
requestAnimationFrame(update);
}
function Ball(radius, position, color) {
this.radius = radius;
this.position = position;
this.color = color;
}
Ball.prototype.draw = function(ctx) {
var c = parseInt(this.color);
ctx.fillStyle = 'rgba(' + c + ',' + c + ',' + c + ',1)';
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.radius, 0, 2 * Math.PI);
ctx.closePath();
ctx.fill();
};
function Vector2D(x, y) {
this.x = x;
this.y = y;
}
function onClick() {
canvas = document.getElementById('space');
ctx = canvas.getContext('2d')
canvas.addEventListener("mousedown", init, false)
blackhole = new Ball(5, {
x: bh.cx,
y: bh.cy
}, 0);
blackhole.draw(ctx);
}
window.onload = onClick;
body {
background-color: #021c36;
margin: 0px;
}
<canvas id="space" , width="700" , height="400"></canvas>
I have eyesore flickering in my canvas animation. I have no idea what causes the flicker and the Google is not offering help on the transition global element I added to my text. On separate canvases, they work fine. It's only when I add them to the main code do I run into the flicker.
var canvas,
context,
ox = 60,
oy = 60,
ux = Math.random(),
uy = Math.random();
var drops = [];
var squares = [];
var clouds = [];
var text, step = 190, steps = 255;
delay = 180;
var rgbstep = 120;
function Drop(x,y,color){
this.x = x;
this.y = y;
this.color = color;
this.dy = Math.random();
}
function Square(x,y,w,color){
this.sx = x;
this.sy = y;
this.sw = w;
this.color = color;
this.qy = Math.random();
}
function init(){
canvas = document.getElementById('canvas');
context = canvas.getContext('2d');
//alert("Hello!\nClick on the screen for rain drops!");
window.addEventListener('resize', resizeCanvas, false);
window.addEventListener('orientationchange', resizeCanvas, false);
resizeCanvas()
Textfadeup();
canvas.onclick = function(event){
handleClick(event.clientX, event.clientY);
};
setInterval(handleClick,50);
setInterval(draw, 1);
}
addEventListener("keydown", function(event) {
if (event.keyCode == 32)
document.body.style.background = "yellow";
});
addEventListener("keyup", function(event) {
if (event.keyCode == 32)
document.body.style.background = "";
});
function handleClick(x,y,w){
var found = false;
for(var i = 0; i<drops.length; i++){
d = Math.sqrt((drops[i].x-x)*(drops[i].x-x) + (drops[i].y-y)*(drops[i].y-y));
if(d<=5){
drops.splice(i,1);
found = true;
}
}
fillBackgroundColor();
if(!found){
var colors = ["#000080", "#add8e6", "blue"];
var color = colors[Math.floor(Math.random()*colors.length)];
drops.push(new Drop(x,y,color));
squares.push(new Square(x,y,w,color));
}
for(var i = 0; i<drops.length; i++){
drawDrop(drops[i]);
}
for(var i = 0; i<squares.length; i++){
drawSquare(squares[i]);
}
}
function Textfadeup() {
rgbstep++;
//context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = "rgb(" + rgbstep + "," + rgbstep + "," + rgbstep + ")"
context.fillText("Drip, drip, drop, little April shower...", 500, canvas.height);
context.font= "40px Arial";
if (rgbstep < 255)
var t = setTimeout('Textfadeup()', 10);
if (rgbstep == 255) {
Textfadedown();
}
}
function Textfadedown() {
rgbstep=rgbstep-1;
// context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = "rgb(" + rgbstep + "," + rgbstep + "," + rgbstep + ")"
context.fillText("Drip, drip, drop, little April shower...", 500, canvas.height);
context.font= "40px Arial";
if (rgbstep > 30)
var t = setTimeout('Textfadedown()', 10);
if (rgbstep == 30) {
Textfadeup();
}
}
/* function drawDrop(drop){
context.beginPath();
context.moveTo(drop.x,drop.y);
context.lineTo(drop.x+10,drop.y+25);
context.lineTo(drop.x+13,drop.y+32);
context.lineTo(drop.x+46,drop.y+50);
context.lineTo(drop.x+72,drop.y+51);
context.lineTo(drop.x+81,drop.y+43);
context.lineTo(drop.x+104,drop.y+52);
context.lineTo(drop.x+111,drop.y+46);
context.lineTo(drop.x+83,drop.y+40);
context.lineTo(drop.x+75,drop.y+20);
context.lineTo(drop.x+57,drop.y+8);
context.closePath();
context.fillStyle = 'orange';
context.fill();
if (drop.y + drop.dy > canvas.height || drop.y + drop.dy < 0)
drop.dy != -drop.dy;
drop.y += drop.dy;
};
function drawDrop(drop){
context.beginPath();
context.moveTo(drop.x,drop.y);
context.beginPath();
context.moveTo(drop.x,drop.y);
context.lineTo(drop.x+24,drop.y);
context.lineTo(drop.x-2,drop.y+25);
context.lineTo(drop.x+17,drop.y+25);
context.lineTo(drop.x-18,drop.y+53);
context.lineTo(drop.x-3,drop.y+54);
context.lineTo(drop.x-47,drop.y+77);
context.lineTo(drop.x-31,drop.y+59);
context.lineTo(drop.x-40,drop.y+59);
context.moveTo(drop.x-40,drop.y+59);
context.moveTo(drop.x-14,drop.y+33);
context.lineTo(drop.x-30,drop.y+32);
context.closePath();
context.fillStyle = 'yellow';
context.fill();
if (drop.y + drop.dy > canvas.height || drop.y + drop.dy < 0)
drop.dy != -drop.dy;
drop.y += drop.dy;
};*/
function drawDrop(drop){
context.beginPath();
context.arc(drop.x, drop.y, 5, 0, Math.PI);
context.fillStyle = drop.color;
context.moveTo(drop.x - 5, drop.y);
context.lineTo(drop.x, drop.y - 7);
context.lineTo(drop.x + 5, drop.y);
context.closePath();
context.fill();
if (drop.y + drop.dy > canvas.height || drop.y + drop.dy < 0)
drop.dy != -drop.dy;
drop.y += drop.dy;
};
function drawSquare(square){
var sw = Math.floor(4);
var sx = Math.floor(Math.random() * canvas.width);
var sy = Math.floor(Math.random() * canvas.height);
context.beginPath();
context.rect(sx, sy, sw, sw);
context.fillStyle = '#add8e6';
context.fill();
};
function drawCloud(ox,oy) {
context.beginPath();
context.moveTo(ox,oy);
context.bezierCurveTo(ox-40, oy+20, ox-40, oy+70, ox+60, oy+70);
context.bezierCurveTo(ox+80, oy+100, ox+150, oy+100, ox+170, oy+70);
context.bezierCurveTo(ox+250, oy+70, ox+250, oy+50, ox+220, oy+20);
context.bezierCurveTo(ox+260, oy-40, ox+200, oy-50, ox+170, oy-30);
context.bezierCurveTo(ox+150, oy-75, ox+80, oy-10, ox+170, oy+5);
context.bezierCurveTo(ox+30, oy-75, ox-20, oy-60, ox, oy);
context.closePath();
context.fillStyle = 'white';
context.fill();
};
function fillBackgroundColor(){
context.fillStyle = 'gray';
context.fillRect(0,0,canvas.width,canvas.height);
}
function resizeCanvas(){
canvas.width = window.innerWidth - 20;
canvas.height = window.innerHeight - 20;
for(var i = 0; i<drops.length; i++){
drawDrop(drops[i]);
}
for(var i = 0; i<squares.length; i++){
drawSquare(squares[i]);
}
}
function draw() {
drawCloud(ox, oy, 500);
if (ox + ux > canvas.width || ox + ux < 0)
ux = -ux;
if (oy + uy > canvas.height || oy + uy < 0)
uy = -uy;
ox += ux;
}
function degreesToRadians(degrees) {
return (degrees * Math.PI)/180;
}
window.onload = init;
</script>
<body>
<canvas id='canvas' width=500 height=500></canvas>
</body>
You should not use setInterval to render to the canvas. You have set the time to 10 which is quicker than the screen refresh rate. There is no easy fix to your code as it's a little convoluted.
What you need to do is set up a main loop. From that function you do everything you need to do per animation frame. At the end of that function you use window.requestAnimationFrame(mainLoop) to request the next frame. It syncs the animation with the display refresh rate and stops the flicker.
Example
function mainLoop(){
drawCloud(); // draw your cloud
// other stuff did not get a chance to see what else you did.
// request the next animation frame that should occur in 1/60th of a second.
requestAnimationFrame(mainLoop);
}
To start it all call mainLoop from the init function
mainLoop(); // starts it all happening
You should NEVER use setInterval for anything but very short simple functions or long time periods. It caused your jsFiddle to crash the tab each time I looked.
Hi I try to create an animation with a circle. The function drawRandom(drawFunctions) should pic one of the three drawcircle functions and should bring it on the canvas. Now the problem is that this function become executed every second (main loop) and the circle change his colour. How can I fix that?
window.onload = window.onresize = function() {
var C = 1; // canvas width to viewport width ratio
var el = document.getElementById("myCanvas");
var viewportWidth = window.innerWidth;
var viewportHeight = window.innerHeight;
var canvasWidth = viewportWidth * C;
var canvasHeight = viewportHeight;
el.style.position = "fixed";
el.setAttribute("width", canvasWidth);
el.setAttribute("height", canvasHeight);
var x = canvasWidth / 100;
var y = canvasHeight / 100;
var ballx = canvasWidth / 100;
var n;
window.ctx = el.getContext("2d");
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
// draw triangles
function init() {
ballx;
return setInterval(main_loop, 1000);
}
function drawcircle1()
{
var radius = x * 5;
ctx.beginPath();
ctx.arc(ballx * 108, canvasHeight / 2, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'yellow';
ctx.fill();
}
function drawcircle2()
{
var radius = x * 5;
ctx.beginPath();
ctx.arc(ballx * 108, canvasHeight / 2, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'blue';
ctx.fill();
}
function drawcircle3()
{
var radius = x * 5;
ctx.beginPath();
ctx.arc(ballx * 105, canvasHeight / 2, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'orange';
ctx.fill();
}
function draw() {
var counterClockwise = false;
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
//first halfarc
ctx.beginPath();
ctx.arc(x * 80, y * 80, y * 10, 0 * Math.PI, 1 * Math.PI, counterClockwise);
ctx.lineWidth = y * 1;
ctx.strokeStyle = 'black';
ctx.stroke();
// draw stop button
ctx.beginPath();
ctx.moveTo(x * 87, y * 2);
ctx.lineTo(x * 87, y * 10);
ctx.lineWidth = x;
ctx.stroke();
ctx.beginPath();
ctx.moveTo(x * 95, y * 2);
ctx.lineTo(x * 95, y * 10);
ctx.lineWidth = x;
ctx.stroke();
function drawRandom(drawFunctions){
//generate a random index
var randomIndex = Math.floor(Math.random() * drawFunctions.length);
//call the function
drawFunctions[randomIndex]();
}
drawRandom([drawcircle1, drawcircle2, drawcircle3]);
}
function update() {
ballx -= 0.1;
if (ballx < 0) {
ballx = -radius;
}
}
function main_loop() {
draw();
update();
collisiondetection();
}
init();
function initi() {
console.log('init');
// Get a reference to our touch-sensitive element
var touchzone = document.getElementById("myCanvas");
// Add an event handler for the touchstart event
touchzone.addEventListener("mousedown", touchHandler, false);
}
function touchHandler(event) {
// Get a reference to our coordinates div
var can = document.getElementById("myCanvas");
// Write the coordinates of the touch to the div
if (event.pageX < x * 50 && event.pageY > y * 10) {
ballx += 1;
} else if (event.pageX > x * 50 && event.pageY > y * 10 ) {
ballx -= 1;
}
console.log(event, x, ballx);
draw();
}
initi();
draw();
}
Take a look at my code that I wrote:
var lastTime = 0;
function requestMyAnimationFrame(callback, time)
{
var t = time || 16;
var currTime = new Date().getTime();
var timeToCall = Math.max(0, t - (currTime - lastTime));
var id = window.setTimeout(function(){ callback(currTime + timeToCall); }, timeToCall);
lastTime = currTime + timeToCall;
return id;
}
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
canvas.width = window.innerWidth - 20;
canvas.height = window.innerHeight - 20;
canvas.style.width = canvas.width + "px";
canvas.style.height = canvas.height + "px";
var circles = [];
var mouse =
{
x: 0,
y: 0
}
function getCoordinates(x, y)
{
return "(" + x + ", " + y + ")";
}
function getRatio(n, d)
{
// prevent division by 0
if (d === 0 || n === 0)
{
return 0;
}
else
{
return n/d;
}
}
function Circle(x,y,d,b,s,c)
{
this.x = x;
this.y = y;
this.diameter = Math.round(d);
this.radius = Math.round(d/2);
this.bounciness = b;
this.speed = s;
this.color = c;
this.deltaX = 0;
this.deltaY = 0;
this.drawnPosition = "";
this.fill = function()
{
context.beginPath();
context.arc(this.x+this.radius,this.y+this.radius,this.radius,0,Math.PI*2,false);
context.closePath();
context.fill();
}
this.clear = function()
{
context.fillStyle = "#ffffff";
this.fill();
}
this.draw = function()
{
if (this.drawnPosition !== getCoordinates(this.x, this.y))
{
context.fillStyle = this.color;
// if commented, the circle will be drawn if it is in the same position
//this.drawnPosition = getCoordinates(this.x, this.y);
this.fill();
}
}
this.keepInBounds = function()
{
if (this.x < 0)
{
this.x = 0;
this.deltaX *= -1 * this.bounciness;
}
else if (this.x + this.diameter > canvas.width)
{
this.x = canvas.width - this.diameter;
this.deltaX *= -1 * this.bounciness;
}
if (this.y < 0)
{
this.y = 0;
this.deltaY *= -1 * this.bounciness;
}
else if (this.y+this.diameter > canvas.height)
{
this.y = canvas.height - this.diameter;
this.deltaY *= -1 * this.bounciness;
}
}
this.followMouse = function()
{
// deltaX/deltaY will currently cause the circles to "orbit" around the cursor forever unless it hits a wall
var centerX = Math.round(this.x + this.radius);
var centerY = Math.round(this.y + this.radius);
if (centerX < mouse.x)
{
// circle is to the left of the mouse, so move the circle to the right
this.deltaX += this.speed;
}
else if (centerX > mouse.x)
{
// circle is to the right of the mouse, so move the circle to the left
this.deltaX -= this.speed;
}
else
{
//this.deltaX = 0;
}
if (centerY < mouse.y)
{
// circle is above the mouse, so move the circle downwards
this.deltaY += this.speed;
}
else if (centerY > mouse.y)
{
// circle is under the mouse, so move the circle upwards
this.deltaY -= this.speed;
}
else
{
//this.deltaY = 0;
}
this.x += this.deltaX;
this.y += this.deltaY;
this.x = Math.round(this.x);
this.y = Math.round(this.y);
}
}
function getRandomDecimal(min, max)
{
return Math.random() * (max-min) + min;
}
function getRoundedNum(min, max)
{
return Math.round(getRandomDecimal(min, max));
}
function getRandomColor()
{
// array of three colors
var colors = [];
// go through loop and add three integers between 0 and 255 (min and max color values)
for (var i = 0; i < 3; i++)
{
colors[i] = getRoundedNum(0, 255);
}
// return rgb value (RED, GREEN, BLUE)
return "rgb(" + colors[0] + "," + colors[1] + ", " + colors[2] + ")";
}
function createCircle(i)
{
// diameter of circle
var minDiameter = 25;
var maxDiameter = 50;
// bounciness of circle (changes speed if it hits a wall)
var minBounciness = 0.2;
var maxBounciness = 0.65;
// speed of circle (how fast it moves)
var minSpeed = 0.3;
var maxSpeed = 0.45;
// getRoundedNum returns a random integer and getRandomDecimal returns a random decimal
var x = getRoundedNum(0, canvas.width);
var y = getRoundedNum(0, canvas.height);
var d = getRoundedNum(minDiameter, maxDiameter);
var c = getRandomColor();
var b = getRandomDecimal(minBounciness, maxBounciness);
var s = getRandomDecimal(minSpeed, maxSpeed);
// create the circle with x, y, diameter, bounciness, speed, and color
circles[i] = new Circle(x,y,d,b,s,c);
}
function makeCircles()
{
var maxCircles = getRoundedNum(2, 5);
for (var i = 0; i < maxCircles; i++)
{
createCircle(i);
}
}
function drawCircles()
{
var ii = 0;
for (var i = 0; ii < circles.length; i++)
{
if (circles[i])
{
circles[i].draw();
ii++;
}
}
}
function clearCircles()
{
var ii = 0;
for (var i = 0; ii < circles.length; i++)
{
if (circles[i])
{
circles[i].clear();
ii++;
}
}
}
function updateCircles()
{
var ii = 0;
for (var i = 0; ii < circles.length; i++)
{
if (circles[i])
{
circles[i].keepInBounds();
circles[i].followMouse();
ii++;
}
}
}
function update()
{
requestMyAnimationFrame(update,10);
updateCircles();
}
function draw()
{
requestMyAnimationFrame(draw,1000/60);
context.clearRect(0,0,canvas.width,canvas.height);
drawCircles();
}
window.addEventListener("load", function()
{
window.addEventListener("mousemove", function(e)
{
mouse.x = e.layerX || e.offsetX;
mouse.y = e.layerY || e.offsetY;
});
makeCircles();
update();
draw();
});
I found a pong game online and wanted to change it around a bit. I want to put a dashed line in the middle of the screen.
if I take out the dashed line the game works. It will work in Chrome but locks up on the Firefox OS simulator.
****Question: Why would this be the case?"****
Code:
function drawDashedLine() {
ctx.beginPath();
ctx.fillStyle = '#eee';
ctx.setLineDash([1,2]);
ctx.moveTo(0,H/2);
ctx.lineTo(320,H/2);
ctx.closePath();
ctx.stroke();
}
HTML:
<html>
<head>
<title>Firefox OS</title>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
// RequestAnimFrame: a browser API for getting smooth animations
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( callback ){
return window.setTimeout(callback, 1000 / 60);
};
})();
window.cancelRequestAnimFrame = ( function() {
return window.cancelAnimationFrame ||
window.webkitCancelRequestAnimationFrame ||
window.mozCancelRequestAnimationFrame ||
window.oCancelRequestAnimationFrame ||
window.msCancelRequestAnimationFrame ||
clearTimeout
} )();
//all global variables
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d"); // Create canvas context
//W = window.innerWidth, // Window's width
//H = window.innerHeight, // Window's height
var W = 310;
var H = 440;
var particles = []; // Array containing particles
var ball = {}; // Ball object
var paddles = [2]; // Array containing two paddles
var mouse = {}; // Mouse object to store it's current position
var points = 0; // Varialbe to store points
var fps = 60; // Max FPS (frames per second)
var flag = 0; // Flag variable which is changed on collision
var particlePos = {}; // Object to contain the position of collision
var multipler = 1; // Varialbe to control the direction of sparks
var startBtn = {}; // Start button object
var restartBtn = {}; // Restart button object
var over = 0; // flag varialbe, cahnged when the game is over
var init; // variable to initialize animation
var paddleHit;
// Add mousemove and mousedown events to the canvas
canvas.addEventListener("mousemove", trackPosition, true);
canvas.addEventListener("mousedown", btnClick, true);
// Set the canvas's height and width to full screen
canvas.width = W;
canvas.height = H;
// Ball object
ball = {
x: 50,
y: 50,
r: 5,
c: "red",
vx: 3,
vy: 7,
// Function for drawing ball on canvas
draw: function() {
ctx.beginPath();
ctx.fillStyle = this.c;
ctx.arc(this.x, this.y, this.r, 0, Math.PI*2, false);
ctx.fill();
}
};
// Start Button object
startBtn = {
w: 100,
h: 50,
x: W/2 - 50,
y: H/2 - 25,
draw: function() {
ctx.strokeStyle = "white";
ctx.lineWidth = "2";
ctx.strokeRect(this.x, this.y, this.w, this.h);
ctx.font = "18px Arial, sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStlye = "white";
ctx.fillText("Start", W/2, H/2 );
}
};
// Restart Button object
restartBtn = {
w: 100,
h: 50,
x: W/2 - 50,
y: H/2 - 50,
draw: function() {
ctx.strokeStyle = "white";
ctx.font = "18px Arial, sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("Tap Center Screen To Play Again!", W/2, H/2 - 25 );
}
};
// Function to paint canvas
function paintCanvas() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, 310, 440);
}
// Function for creating paddles
function Paddle(pos) {
// Height and width
this.h = 8;
this.w = 55;
// Paddle's position
this.x = W/2 - this.w/2;
this.y = (pos == "top") ? 0 : H - this.h;
}
function draw() {
paintCanvas();
for(var i = 0; i < paddles.length; i++) {
p = paddles[i];
ctx.fillStyle = "white";
ctx.fillRect(p.x, p.y, p.w, p.h);
}
ball.draw();
update();
}
function increaseSpd() {
if(points % 2 == 33) {
if(Math.abs(ball.vx) < 15) {
ball.vx += (ball.vx < 0) ? -1 : 1;
ball.vy += (ball.vy < 0) ? -2 : 2;
}
}
}
function trackPosition(e) {
mouse.x = e.pageX;
mouse.y = e.pageY;
}
function movePaddles() {
if(mouse.x && mouse.y) {
for(var i = 1; i < paddles.length; i++) {
p = paddles[i];
p.x = mouse.x - p.w/2;
}
}
}
function collisions() {
if(collides(ball, p1)) {
collideAction(ball, p1);
}
else if(collides(ball, p2)) {
collideAction(ball, p2);
} else {
// Collide with walls, If the ball hits the top/bottom,
// walls, run gameOver() function
if(ball.y + ball.r > H) {
ball.y = H - ball.r;
gameOver(); //the game is over
} else if(ball.y < 0) {
ball.y = ball.r;
gameOver(); //the game is over
}
if(ball.x + ball.r > W) {
ball.vx = -ball.vx;
ball.x = W - ball.r;
} else if(ball.x -ball.r < 0) {
ball.vx = -ball.vx;
ball.x = ball.r;
}
}
}
function drawDashedLine() {
ctx.beginPath();
ctx.fillStyle = '#eee';
ctx.setLineDash([1,2]);
ctx.moveTo(0,H/2);
ctx.lineTo(320,H/2);
ctx.closePath();
ctx.stroke();
}
function update() {
updateScore();
movePaddles();
drawDashedLine()
ball.x += ball.vx;
ball.y += ball.vy;
p1 = paddles[1];
p2 = paddles[2];
collisions();
flag = 0;
}
function collides(b, p) {
if(b.x + ball.r >= p.x &&
b.x - ball.r <=p.x + p.w) {
if(b.y >= (p.y - p.h) && p.y > 0){
paddleHit = 1;
return true;
} else if(b.y <= p.h && p.y == 0) {
paddleHit = 2;
return true;
} else {
return false;
}
}
}
function collideAction(ball, p) {
ball.vy = -ball.vy;
if(paddleHit == 1) {
ball.y = p.y - p.h;
particlePos.y = ball.y + ball.r;
multiplier = -1;
} else if(paddleHit == 2) {
ball.y = p.h + ball.r;
particlePos.y = ball.y - ball.r;
multiplier = 1;
}
points++;
if(collision) {
if(points > 0) {
collision.pause();
}
collision.currentTime = 0;
collision.play();
}
particlePos.x = ball.x;
flag = 1;
}
// Function for updating score
function updateScore() {
ctx.fillStlye = "green";
ctx.font = "20px Arial, sans-serif";
ctx.textAlign = "left";
ctx.textBaseline = "top";
ctx.fillText(points, 20, 20 );
}
// Function to run when the game overs
function gameOver() {
ctx.fillStlye = "white";
ctx.font = "20px Arial, sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("Game Over! ("+points+")", W/2, H/2 + 25 );
cancelRequestAnimFrame(init); //stops the animation frame
over = 1;
restartBtn.draw(); //This will allow the user to restart the game
}
// Function for running the whole animation
function animloop() {
init = requestAnimFrame(animloop);
draw();
}
// Function to execute at startup
function startScreen() {
draw();
startBtn.draw();
}
// On button click (Restart and start)
function btnClick(e) {
var mx = e.pageX;
var my = e.pageY;
if(mx >= startBtn.x && mx <= startBtn.x + startBtn.w) {
animloop();
startBtn = {};
}
// If the game is over, and the restart button is clicked
if(over == 1) {
if(mx >= restartBtn.x && mx <= restartBtn.x + restartBtn.w) {
ball.x = 20;
ball.y = 20;
points = 0;
ball.vx = 4;
ball.vy = 8;
animloop();
over = 0;
}
}
}
paddles.push(new Paddle("bottom"));
paddles.push(new Paddle("top"));
startScreen();
</script>
</body>
</html>