Initial commit
This commit is contained in:
commit
c45f3fd3c8
5 changed files with 590 additions and 0 deletions
BIN
ball.mp3
Normal file
BIN
ball.mp3
Normal file
Binary file not shown.
BIN
dimrain47_-_twilight_techno.mp3
Normal file
BIN
dimrain47_-_twilight_techno.mp3
Normal file
Binary file not shown.
BIN
edge.mp3
Normal file
BIN
edge.mp3
Normal file
Binary file not shown.
108
index.html
Normal file
108
index.html
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width">
|
||||||
|
<title>Particles</title>
|
||||||
|
<style type="text/css" media="all">
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
background: linear-gradient(#eeeeee, #e4e4e4);
|
||||||
|
color: #999;
|
||||||
|
text-align: center;
|
||||||
|
font-family: sans-serif;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
margin-top: 0;
|
||||||
|
padding-top: 50px;
|
||||||
|
position: relative;
|
||||||
|
color: #777;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
h1:before {
|
||||||
|
content: 'Particles';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
color: #888;
|
||||||
|
height: 1.3ex;
|
||||||
|
padding-top: 50px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
#gamecontainer {
|
||||||
|
position:relative;
|
||||||
|
width: 602px;
|
||||||
|
height: 602px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
#gamecontainer > * {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#message, #playbutton {
|
||||||
|
padding-top: 50px;
|
||||||
|
margin: 0 auto;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 5px;
|
||||||
|
font-size: 150%;
|
||||||
|
}
|
||||||
|
#message div {
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 1s;
|
||||||
|
margin-top: 40px;
|
||||||
|
line-height: 2;
|
||||||
|
}
|
||||||
|
#message div.visible {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
#playbutton {
|
||||||
|
font-size: 200%;
|
||||||
|
color: #888;
|
||||||
|
cursor: pointer;
|
||||||
|
padding-top: 275px;
|
||||||
|
}
|
||||||
|
#playbutton:hover {
|
||||||
|
color: #222;
|
||||||
|
}
|
||||||
|
#background {
|
||||||
|
background: linear-gradient(#ffffff, #f4f4f4);
|
||||||
|
box-shadow: #f2f2f2 5px -5px 5px inset, #f2f2f2 -5px 5px 5px inset;
|
||||||
|
position: absolute;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
.gameon gamecontainer, .gameon canvas {
|
||||||
|
cursor: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Particles</h1>
|
||||||
|
<div id="gamecontainer">
|
||||||
|
<div id="background"></div>
|
||||||
|
<div id="message"></div>
|
||||||
|
<canvas id="game" width="600" height="600"></canvas>
|
||||||
|
<div id="playbutton">Play</div>
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
<p>A reimplementation by Midgard of the <a href="https://www.newgrounds.com/portal/view/357700">Flash game</a> of yore by Matteo Guarnieri</p>
|
||||||
|
<p>Music: <a href="https://dimrain47.newgrounds.com/">Dimrain47</a> – <a href="https://www.newgrounds.com/audio/listen/30208">Twilight Techno</a></p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<audio id="music" src="dimrain47_-_twilight_techno.mp3"></audio>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
482
main.js
Normal file
482
main.js
Normal file
|
@ -0,0 +1,482 @@
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var canvas = document.getElementById("game");
|
||||||
|
if (!canvas.getContext) {
|
||||||
|
alert("Your browser is unsupported (does not support canvas.getContext).");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var ctx = canvas.getContext("2d");
|
||||||
|
var playfieldWidth = canvas.width;
|
||||||
|
var playfieldHeight = canvas.height;
|
||||||
|
|
||||||
|
var BALL_RADIUS = 20;
|
||||||
|
var GRAVITY_ACCELERATION = 10;
|
||||||
|
|
||||||
|
|
||||||
|
function message(text, expire) {
|
||||||
|
document.getElementById("message").innerHTML = "";
|
||||||
|
|
||||||
|
var div = document.createElement("div");
|
||||||
|
div.innerText = text;
|
||||||
|
document.getElementById("message").appendChild(div);
|
||||||
|
div.className = "visible";
|
||||||
|
|
||||||
|
if (expire === false) { return; }
|
||||||
|
if (!expire) { expire = 2000; }
|
||||||
|
|
||||||
|
window.setTimeout(function() {
|
||||||
|
div.className = "";
|
||||||
|
window.setTimeout(function() {
|
||||||
|
try {
|
||||||
|
div.parentNode.removeChild(div);
|
||||||
|
} catch(e) {}
|
||||||
|
}, 1000);
|
||||||
|
}, expire);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function Vector(x, y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
Vector.prototype.add = function(other) {
|
||||||
|
return new Vector(
|
||||||
|
this.x + other.x,
|
||||||
|
this.y + other.y
|
||||||
|
);
|
||||||
|
};
|
||||||
|
Vector.prototype.iadd = function(other) {
|
||||||
|
this.x += other.x;
|
||||||
|
this.y += other.y;
|
||||||
|
};
|
||||||
|
Vector.prototype.sub = function(other) {
|
||||||
|
return new Vector(
|
||||||
|
this.x - other.x,
|
||||||
|
this.y - other.y
|
||||||
|
);
|
||||||
|
};
|
||||||
|
Vector.prototype.mul = function(scalar) {
|
||||||
|
return new Vector(
|
||||||
|
this.x * scalar,
|
||||||
|
this.y * scalar
|
||||||
|
);
|
||||||
|
};
|
||||||
|
Vector.prototype.dot = function(other) {
|
||||||
|
return this.x * other.x + this.y * other.y;
|
||||||
|
};
|
||||||
|
Vector.prototype.normSquared = function() {
|
||||||
|
return this.dot(this);
|
||||||
|
};
|
||||||
|
Vector.prototype.norm = function() {
|
||||||
|
return Math.sqrt(this.normSquared(this));
|
||||||
|
};
|
||||||
|
Vector.prototype.distance_squared = function(other) {
|
||||||
|
var diffX = this.x - other.x;
|
||||||
|
var diffY = this.y - other.y;
|
||||||
|
return diffX * diffX + diffY * diffY;
|
||||||
|
};
|
||||||
|
Vector.prototype.toString = function() {
|
||||||
|
return "Vector(" + this.x + ", " + this.y + ")";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function Circle(centre, radius) {
|
||||||
|
this.centre = centre;
|
||||||
|
this.radius = radius;
|
||||||
|
}
|
||||||
|
Circle.prototype.intersects = function(other) {
|
||||||
|
return (
|
||||||
|
this.centre.distance_squared(other.centre)
|
||||||
|
<=
|
||||||
|
2 * this.radius * 2 * this.radius
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Circle.prototype.toString = function(other) {
|
||||||
|
return "Circle(centre=" + this.centre.toString() + ", radius=" + this.radius + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function Ball(outline, velocity, colour, ghost) {
|
||||||
|
this.outline = outline;
|
||||||
|
this.velocity = velocity;
|
||||||
|
this.colour = colour;
|
||||||
|
this.ghost = ghost;
|
||||||
|
this.audioBall = new Audio("ball.mp3");
|
||||||
|
this.audioEdge = new Audio("edge.mp3");
|
||||||
|
}
|
||||||
|
Ball.prototype.toString = function() {
|
||||||
|
return (
|
||||||
|
"Ball(outline=" + this.outline.toString() + "," +
|
||||||
|
"velocity=" + this.velocity.toString() + ", " +
|
||||||
|
"colour=" + this.colour + ", ghost=" + this.ghost + ")"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function intersectsExistingBall(circle) {
|
||||||
|
for (var i = 0; i < balls.length; i++) {
|
||||||
|
if (circle.intersects(balls[i].outline)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function bogoGenerateNewBallOutline() {
|
||||||
|
var circle;
|
||||||
|
do {
|
||||||
|
circle = new Circle(
|
||||||
|
new Vector(
|
||||||
|
Math.random() * (playfieldWidth - 2*BALL_RADIUS) + BALL_RADIUS,
|
||||||
|
Math.random() * (playfieldHeight - 2*BALL_RADIUS) + BALL_RADIUS
|
||||||
|
),
|
||||||
|
BALL_RADIUS
|
||||||
|
);
|
||||||
|
} while (intersectsExistingBall(circle));
|
||||||
|
return circle;
|
||||||
|
}
|
||||||
|
|
||||||
|
function bogoGenerateVelocity() {
|
||||||
|
var vec;
|
||||||
|
do {
|
||||||
|
vec = new Vector(
|
||||||
|
Math.random() * 10 - 2,
|
||||||
|
Math.random() * 10 - 2
|
||||||
|
);
|
||||||
|
} while (vec.normSquared < 2);
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
var playerBall;
|
||||||
|
var balls = [];
|
||||||
|
|
||||||
|
function addBall(ghost) {
|
||||||
|
var newBall = new Ball(
|
||||||
|
bogoGenerateNewBallOutline(),
|
||||||
|
bogoGenerateVelocity(),
|
||||||
|
"red",
|
||||||
|
ghost
|
||||||
|
);
|
||||||
|
balls.push(newBall);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var isGameOver = true;
|
||||||
|
|
||||||
|
function advanceBall(ball, timePassed) {
|
||||||
|
if (ball.ghost != 0) {
|
||||||
|
ball.ghost -= timePassed / 1000;
|
||||||
|
if (ball.ghost <= 0) {
|
||||||
|
ball.ghost = 0;
|
||||||
|
}
|
||||||
|
if (!isGameOver) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ball.outline.centre.iadd(
|
||||||
|
ball.velocity.mul(timePassed / 20)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function bounceBalls(ball1, ball2) {
|
||||||
|
var x1 = ball1.outline.centre;
|
||||||
|
var x2 = ball2.outline.centre;
|
||||||
|
var v1 = ball1.velocity;
|
||||||
|
var v2 = ball2.velocity;
|
||||||
|
var x_diff1 = x1.sub(x2);
|
||||||
|
var x_diff2 = x2.sub(x1);
|
||||||
|
|
||||||
|
var collisionForce = v1.sub(v2).norm();
|
||||||
|
ball1.audioBall.pause();
|
||||||
|
ball1.audioBall.currentTime = 0;
|
||||||
|
ball1.audioBall.volume = clamp(collisionForce / 10 + 0.1, 0, 1);
|
||||||
|
ball1.audioBall.play();
|
||||||
|
|
||||||
|
// https://en.wikipedia.org/w/index.php?title=Elastic_collision&oldid=1057236793#Two-dimensional_collision_with_two_moving_objects
|
||||||
|
ball1.velocity = v1.sub(x_diff1.mul((v1.sub(v2).dot(x_diff1)) / x_diff1.normSquared()));
|
||||||
|
ball2.velocity = v2.sub(x_diff2.mul((v2.sub(v1).dot(x_diff2)) / x_diff2.normSquared()));
|
||||||
|
|
||||||
|
// Make balls non-intersecting
|
||||||
|
var c = x1.add(x2).mul(1/2)
|
||||||
|
ball1.outline.centre = c.add(x1.sub(c).mul((ball1.outline.radius + 0.05) / x1.sub(c).norm()));
|
||||||
|
ball2.outline.centre = c.add(x2.sub(c).mul((ball2.outline.radius + 0.05) / x2.sub(c).norm()));
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleBounceEdge(ball, ignoreBottom) {
|
||||||
|
var bounce = false;
|
||||||
|
|
||||||
|
if (ball.outline.centre.x <= ball.outline.radius) {
|
||||||
|
ball.velocity.x *= -1;
|
||||||
|
ball.outline.centre.x = ball.outline.radius + (ball.outline.radius - ball.outline.centre.x);
|
||||||
|
bounce = true;
|
||||||
|
}
|
||||||
|
if (ball.outline.centre.y <= ball.outline.radius) {
|
||||||
|
ball.velocity.y *= -1;
|
||||||
|
ball.outline.centre.y = ball.outline.radius + (ball.outline.radius - ball.outline.centre.y);
|
||||||
|
bounce = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var maxX = playfieldWidth - ball.outline.radius;
|
||||||
|
var maxY = playfieldHeight - ball.outline.radius;
|
||||||
|
|
||||||
|
if (ball.outline.centre.x >= maxX) {
|
||||||
|
ball.velocity.x *= -1;
|
||||||
|
ball.outline.centre.x = maxX + (maxX - ball.outline.centre.x);
|
||||||
|
bounce = true;
|
||||||
|
}
|
||||||
|
if (ball.outline.centre.y >= maxY && !ignoreBottom) {
|
||||||
|
ball.velocity.y *= -1;
|
||||||
|
ball.outline.centre.y = maxY + (maxY - ball.outline.centre.y);
|
||||||
|
bounce = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bounce) {
|
||||||
|
ball.audioEdge.pause();
|
||||||
|
ball.audioEdge.currentTime = 0;
|
||||||
|
ball.audioEdge.volume = clamp(ball.velocity.norm() / 3 + 0.1, 0, 1);
|
||||||
|
ball.audioEdge.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkPlayerCollision() {
|
||||||
|
for (var i = 1; i < balls.length; i++) {
|
||||||
|
if (balls[i].ghost == 0 && playerBall.outline.intersects(balls[i].outline)) {
|
||||||
|
bounceBalls(playerBall, balls[i]);
|
||||||
|
gameOver();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkBallCollision(includingPlayerBall) {
|
||||||
|
var start = includingPlayerBall ? 0 : 1;
|
||||||
|
|
||||||
|
for (var i = start; i < balls.length; i++)
|
||||||
|
for (var j = i + 1; j < balls.length; j++) {
|
||||||
|
if (
|
||||||
|
balls[i].outline.intersects(balls[j].outline) &&
|
||||||
|
(
|
||||||
|
(balls[i].ghost == 0 && balls[j].ghost == 0) ||
|
||||||
|
isGameOver
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
bounceBalls(balls[i], balls[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function gravity(ball, timePassed) {
|
||||||
|
ball.velocity.y += GRAVITY_ACCELERATION * timePassed / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
function allFallen() {
|
||||||
|
for (var i = 0; i < balls.length; i++) {
|
||||||
|
if (balls[i].outline.centre.y < playfieldHeight + balls[i].outline.radius) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var colorGradients = {
|
||||||
|
"blue": [
|
||||||
|
[0, "#2b2bff"],
|
||||||
|
[0.5, "#1212eb"],
|
||||||
|
[1, "#000092"]
|
||||||
|
],
|
||||||
|
"red": [
|
||||||
|
[0, "#ff2b2b"],
|
||||||
|
[0.5, "#eb1212"],
|
||||||
|
[1, "#920000"]
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
function drawBall(ball) {
|
||||||
|
var x = ball.outline.centre.x;
|
||||||
|
var y = ball.outline.centre.y;
|
||||||
|
var r = ball.outline.radius;
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.globalAlpha = 1 - ball.ghost;
|
||||||
|
ctx.arc(x, y, ball.outline.radius, 0, Math.PI * 2, true);
|
||||||
|
|
||||||
|
var gradient = ctx.createRadialGradient(x+r*.75,y-r*.75,0, x,y,r*1.1);
|
||||||
|
for (var i in colorGradients[ball.colour]) {
|
||||||
|
gradient.addColorStop(
|
||||||
|
colorGradients[ball.colour][i][0],
|
||||||
|
colorGradients[ball.colour][i][1]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ctx.fillStyle = gradient;
|
||||||
|
|
||||||
|
ctx.closePath();
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw() {
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
for (var i = balls.length - 1; i >= 0; i--) {
|
||||||
|
drawBall(balls[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var gameStarted = null;
|
||||||
|
var previousTime = -1;
|
||||||
|
function gameLoop(timestamp) {
|
||||||
|
if (previousTime == -1) {
|
||||||
|
previousTime = timestamp;
|
||||||
|
}
|
||||||
|
var timePassed = timestamp - previousTime;
|
||||||
|
|
||||||
|
checkPlayerCollision();
|
||||||
|
for (var i = 1; i < balls.length; i++) {
|
||||||
|
advanceBall(balls[i], timePassed);
|
||||||
|
handleBounceEdge(balls[i]);
|
||||||
|
}
|
||||||
|
checkBallCollision(false);
|
||||||
|
|
||||||
|
draw();
|
||||||
|
|
||||||
|
previousTime = timestamp;
|
||||||
|
if (!isGameOver) {
|
||||||
|
requestAnimationFrame(gameLoop);
|
||||||
|
} else {
|
||||||
|
requestAnimationFrame(gameOverLoop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function gameOver() {
|
||||||
|
console.log("Game over");
|
||||||
|
var gameDuration = new Date() - gameStarted;
|
||||||
|
message(
|
||||||
|
"You reached " + (balls.length - 1) + " balls\n" +
|
||||||
|
"You lasted " + Math.floor(gameDuration / 1000) + " seconds",
|
||||||
|
false);
|
||||||
|
document.getElementById("playbutton").innerHTML = "Play again";
|
||||||
|
if (ballAddTimeout !== null) {
|
||||||
|
window.clearTimeout(ballAddTimeout);
|
||||||
|
}
|
||||||
|
isGameOver = true;
|
||||||
|
|
||||||
|
fadeOutMusic();
|
||||||
|
|
||||||
|
document.body.className = "gameover";
|
||||||
|
}
|
||||||
|
function fadeOutMusic() {
|
||||||
|
if (!isGameOver) return;
|
||||||
|
if (document.getElementById("music").volume > 0.01) {
|
||||||
|
document.getElementById("music").volume *= 0.8;
|
||||||
|
window.setTimeout(fadeOutMusic, 100);
|
||||||
|
} else {
|
||||||
|
document.getElementById("music").pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function gameOverLoop(timestamp) {
|
||||||
|
var timePassed = timestamp - previousTime;
|
||||||
|
|
||||||
|
for (var i = 0; i < balls.length; i++) {
|
||||||
|
gravity(balls[i], timePassed);
|
||||||
|
advanceBall(balls[i], timePassed);
|
||||||
|
handleBounceEdge(balls[i], true);
|
||||||
|
}
|
||||||
|
checkBallCollision(true);
|
||||||
|
|
||||||
|
draw();
|
||||||
|
|
||||||
|
previousTime = timestamp;
|
||||||
|
if (!allFallen(balls)) {
|
||||||
|
requestAnimationFrame(gameOverLoop);
|
||||||
|
} else {
|
||||||
|
prepareStartButton();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clamp(value, min, max) {
|
||||||
|
return Math.max(min, Math.min(max, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveMouseCallback(event) {
|
||||||
|
if (isGameOver) return;
|
||||||
|
// move player
|
||||||
|
var previousPosition = playerBall.outline.centre;
|
||||||
|
|
||||||
|
var newPosition = new Vector(
|
||||||
|
clamp(event.clientX - document.getElementById("gamecontainer").offsetLeft, BALL_RADIUS, playfieldWidth - BALL_RADIUS),
|
||||||
|
clamp(event.clientY - document.getElementById("gamecontainer").offsetTop, BALL_RADIUS, playfieldHeight - BALL_RADIUS)
|
||||||
|
);
|
||||||
|
playerBall.outline.centre = newPosition;
|
||||||
|
playerBall.velocity = newPosition.sub(previousPosition).mul(0.1);
|
||||||
|
}
|
||||||
|
document.body.addEventListener("mousemove", moveMouseCallback);
|
||||||
|
document.body.addEventListener("mousein", moveMouseCallback);
|
||||||
|
|
||||||
|
var ballAddTimeout = null;
|
||||||
|
var ballAddMessages = [
|
||||||
|
["3 balls\nEasy peasy", 15],
|
||||||
|
["4 balls\nStill quite easy", 20],
|
||||||
|
["5 balls\nFun begins now", 30],
|
||||||
|
["6 balls\nQuite challenging", 35],
|
||||||
|
["7 balls\nPretty tough", 40],
|
||||||
|
["8 balls\nVery tricky", 50],
|
||||||
|
["9 balls\nTerribly hard", 60],
|
||||||
|
["10 balls\nIncredibly tough", 60],
|
||||||
|
["11 balls\nInsanely difficult", 60],
|
||||||
|
["12 balls\nAbsolutely crazy", 60],
|
||||||
|
["13 balls\nCompletely mad", 60],
|
||||||
|
["14 balls\nAlmost impossible", 60],
|
||||||
|
["15 balls\nMaxed out", 60]
|
||||||
|
];
|
||||||
|
function ballAddTimeoutFunction() {
|
||||||
|
if (balls.length - 2 > ballAddMessages.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
addBall(1);
|
||||||
|
var addMessage = ballAddMessages[balls.length - 4];
|
||||||
|
message(addMessage[0]);
|
||||||
|
ballAddTimeout = window.setTimeout(ballAddTimeoutFunction, addMessage[1] * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function startGame() {
|
||||||
|
document.getElementById("music").currentTime = 0;
|
||||||
|
document.getElementById("music").volume = 0.5;
|
||||||
|
document.getElementById("music").play();
|
||||||
|
document.getElementById("playbutton").style.display = "none";
|
||||||
|
|
||||||
|
playerBall = new Ball(
|
||||||
|
new Circle(
|
||||||
|
new Vector(
|
||||||
|
canvas.width / 2 - BALL_RADIUS,
|
||||||
|
canvas.height / 2 - BALL_RADIUS
|
||||||
|
),
|
||||||
|
BALL_RADIUS
|
||||||
|
),
|
||||||
|
new Vector(0, 0),
|
||||||
|
"blue",
|
||||||
|
0
|
||||||
|
);
|
||||||
|
balls = [playerBall];
|
||||||
|
|
||||||
|
for (var i = 0; i < 2; i++) {
|
||||||
|
addBall(1);
|
||||||
|
}
|
||||||
|
console.log(`${balls.length} balls`);
|
||||||
|
ballAddTimeoutFunction();
|
||||||
|
|
||||||
|
|
||||||
|
isGameOver = false;
|
||||||
|
previousTime = -1;
|
||||||
|
requestAnimationFrame(gameLoop);
|
||||||
|
gameStarted = new Date();
|
||||||
|
document.body.className = "gameon";
|
||||||
|
}
|
||||||
|
|
||||||
|
function prepareStartButton() {
|
||||||
|
document.getElementById("playbutton").style.display = "block";
|
||||||
|
document.getElementById("playbutton").onclick = startGame;
|
||||||
|
}
|
||||||
|
|
||||||
|
prepareStartButton();
|
||||||
|
|
||||||
|
})();
|
Loading…
Reference in a new issue