crazy_ball 3.0 audio extended with hiscore table
#myCanvas {
border: 1px solid black;
float:center;
}
.button {
background-color: #4CAF50; /* Green */
border: none;
color: white;
padding: 16px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
-webkit-transition-duration: 0.4s; /* Safari */
transition-duration: 0.4s;
cursor: pointer;
}
.button1 {
background-color: white;
color: black;
border: 2px solid #4CAF50;
}
.button1:hover {
background-color: #4CAF50;
color: white;
}
table {
width:100%;
border:1px solid;
border-collapse: collapse;
}
tr, th, td {
border:1px solid;
font-family:courier;
}
td {
text-align:center;
padding:10px;
}
fieldset {
padding:10px;
border-radius:10px;
}
label {
display:inline-block;
margin-bottom:10px;
}
#input:invalid {
background-color:pink;
}
#input:valid {
background-color:lightgreen;
}
#sub{
visibility:hidden;
}
// useful to have them as global variables
var canvas, ctx, w, h;
var points =0;
var keyTyped;
var mousePos;
var bolaRosa=0;
var level=1;
var animationFlag;
// an empty array!
var balls = [];
var initialNumberOfBalls;
var globalSpeedMultiplier = 0.7;
var colorToEat = 'red';
var wrongBallsEaten = goodBallsEaten = 0;
var numberOfGoodBalls;
var contador = 0;
var player = {
x:10,
y:10,
width:40,
height:40,
color:'red'
}
var soundBolaBuena;
var soundBolaMala;
var soundFinDeJuego;
var percentLoaded=0;
var arraySounds=[];
var arrayPercent;
window.onload=preInit;
function preInit(){
arraySounds = [soundBolaBuena = new Howl({
urls: ['http://www.freesfx.co.uk/rx2/mp3s/2/13651_1459784563.mp3'],
onload: function () {
percentLoaded+=(1/arraySounds.length)*100;
console.log("Loaded asset "+soundBolaBuena.urls);
document.getElementById("loadingText").innerHTML+="bolabuena sound loaded..."+Math.round(percentLoaded)+"%"+"<br />";
}
}),
soundBolaMala = new Howl({
urls: ['http://www.freesfx.co.uk/rx2/mp3s/5/16892_1461333024.mp3'],
onload: function () {
percentLoaded+=(1/arraySounds.length)*100;
console.log("Loaded asset "+soundBolaMala.urls);
document.getElementById("loadingText").innerHTML+="bolamala sound loaded..."+Math.round(percentLoaded)+"%"+"<br />";
}
}),
soundFinDeJuego = new Howl({
urls: ['http://www.freesfx.co.uk/rx2/mp3s/6/17820_1462215855.mp3'],
onload: function () {
percentLoaded+=(1/arraySounds.length)*100;
console.log("Loaded asset "+soundFinDeJuego.urls);
document.getElementById("loadingText").innerHTML+="ending sound loaded..."+Math.round(percentLoaded)+"%"+"<br />";
}
})];
//document.getElementById("myCanvas").style.visibility="hidden";
document.getElementById("myCanvas").style.display="none";
document.getElementById("myTable").style.display="none";
}
function init() {
document.getElementById("loadingText").innerHTML="";
//document.getElementById("myCanvas").style.visibility="visible";
document.getElementById("myCanvas").style.display="initial";
document.getElementById("start").style.visibility="hidden";
// called AFTER the page has been loaded
canvas = document.querySelector("#myCanvas");
// often useful
w = canvas.width;
h = canvas.height;
// important, we will draw with this object
ctx = canvas.getContext('2d');
// start game with 10 balls, balls to eat = red balls
startGame(10);
// add a mousemove event listener to the canvas
canvas.addEventListener('mousemove', mouseMoved);
// ready to go !
mainLoop();
};
function restart(){
soundFinDeJuego.stop();
document.getElementById("points").innerHTML="";
document.getElementById("myCanvas").style.display="initial";
document.getElementById("myTable").style.display="none";
//console.log(balls[0].speedX);
console.log("el multiplicador vale: "+globalSpeedMultiplier);
// called AFTER the page has been loaded
canvas = document.querySelector("#myCanvas");
// often useful
w = canvas.width;
h = canvas.height;
// important, we will draw with this object
ctx = canvas.getContext('2d');
// start game with 10 balls, balls to eat = red balls
startGame(9+level);
// add a mousemove event listener to the canvas
canvas.addEventListener('mousemove', mouseMoved);
// ready to go !
}
function startGame(nb) {
do {
balls = createBalls(nb);
initialNumberOfBalls = nb;
numberOfGoodBalls = countNumberOfGoodBalls(balls, colorToEat);
} while(numberOfGoodBalls === 0);
wrongBallsEaten = goodBallsEaten = 0;
}
function countNumberOfGoodBalls(balls, colorToEat) {
var nb = 0;
balls.forEach(function(b) {
if(b.color === colorToEat)
nb++;
});
return nb;
}
function changeNbBalls(nb) {
startGame(nb);
}
function changeColorToEat(color) {
colorToEat = color;
}
function changePlayerColor(color) {
player.color = color;
}
function changeBallSpeed(coef) {
globalSpeedMultiplier = coef;
}
function mouseMoved(evt) {
mousePos = getMousePos(canvas, evt);
}
function getMousePos(canvas, evt) {
// necessary work in the canvas coordinate system
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
function movePlayerWithMouse() {
if(mousePos !== undefined) {
player.x = mousePos.x;
player.y = mousePos.y;
}
}
function mainLoop() {
// 1 - clear the canvas
ctx.clearRect(0, 0, w, h);
// draw the ball and the player
drawFilledRectangle(player);
drawAllBalls(balls);
if(wrongBallsEaten!=-1){
drawBallNumbers(balls);
}
// animate the ball that is bouncing all over the walls
moveAllBalls(balls);
movePlayerWithMouse();
// ask for a new animation frame
animationFlag=requestAnimationFrame(mainLoop);
}
function stopGame(){
wrongBallsEaten=-1;
balls=[];
bolaRosa=[];
level = 1;
console.log("fin del juego");
soundFinDeJuego.play();
document.getElementById("points").innerHTML+="GAME OVER!"+"<br />";
document.getElementById("points").innerHTML+="Final Points: "+points+"<br />";
document.getElementById("points").innerHTML+="press BackSpace to restart game";
document.getElementById("myCanvas").style.display="none";
document.getElementById("myTable").style.display="initial";
processScore();
window.onkeydown = function(evt) {
keyTyped = evt.keyCode;
console.log(keyTyped);
if(keyTyped==32){
globalSpeedMultiplier=0.7;
level=1;
points =0;
restart();
}
}
//cancelAnimationFrame(animationFlag);
}
// Collisions between rectangle and circle
function circRectsOverlap(x0, y0, w0, h0, cx, cy, r) {
var testX=cx;
var testY=cy;
if (testX < x0) testX=x0;
if (testX > (x0+w0)) testX=(x0+w0);
if (testY < y0) testY=y0;
if (testY > (y0+h0)) testY=(y0+h0);
return (((cx-testX)*(cx-testX)+(cy-testY)*(cy-testY))< r*r);
}
function createBalls(n) {
// empty array
var ballArray = [];
// create n balls
for(var i=0; i < n; i++) {
var b = {
x:w*Math.random(),
y:h*Math.random(),
radius: 15 + 5 * Math.random(), // between 5 and 35
speedX: -3+6* Math.random(), // between -5 and + 5
speedY: -3+6* Math.random(), // between -5 and + 5
color:getARandomColor(),
}
// add ball b to the array
ballArray.push(b);
}
// returns the array full of randomly created balls
return ballArray;
}
function getARandomColor() {
var colors = ['red', 'blue', 'cyan', 'purple', 'pink', 'green', 'yellow', 'lime'];
// a value between 0 and color.length-1
// Math.round = rounded value
// Math.random() a value between 0 and 1
var colorIndex = Math.round((colors.length-1)*Math.random());
var c = colors[colorIndex];
// return the random color
return c;
}
function drawBallNumbers(balls) {
ctx.font="20px Arial";
if(wrongBallsEaten!=(-1)){
if(wrongBallsEaten>=5) {
console.log("if");
stopGame();
} else if(goodBallsEaten === numberOfGoodBalls) {
globalSpeedMultiplier= globalSpeedMultiplier+(level/100);
points = points + ((level*10*goodBallsEaten)-(5*wrongBallsEaten));
level++;
restart();
console.log("elseif");
} else {
ctx.fillText("POINTS: " + points, 270, 30);
ctx.fillText("LIFES: " + (5-wrongBallsEaten), 270, 50);
ctx.fillText("LEVEL: "+level,270,70);
console.log("else");
}
}
console.log("bolasmalas distintas de -1");
ctx.restore();
}
function drawAllBalls(ballArray) {
for(i=0;i<ballArray.length;i++){
if(ballArray[i].color=='pink'){
drawFilledCircle(ballArray[i]);
}
else{
drawFilledCircle(ballArray[i]);
}
}
}
function moveAllBalls(ballArray) {
// iterate on all balls in array
balls.forEach(function(b, index) {
// b is the current ball in the array
b.x += (b.speedX * globalSpeedMultiplier);
b.y += (b.speedY * globalSpeedMultiplier);
if(b.color=='red'){
var comp=0;
do{
var radioInicial=b.radius;
var radioGrande=0;
if(contador<200){
b.radius = Math.abs(radioInicial +0.1);
radioInicial = b.radius;
contador+=1;
}
else if(contador<399){
b.radius = Math.abs(radioInicial - 0.1);
contador+=1;
}
else{
contador=0;
}
}while(comp=0);
}
testCollisionBallWithWalls(b);
testCollisionWithPlayer(b, index);
});
//console.log(ballArray[0].speedX);
}
function testCollisionWithPlayer(b, index) {
if(circRectsOverlap(player.x, player.y,
player.width, player.height,
b.x, b.y, b.radius)) {
// we remove the element located at index
// from the balls array
// splice: first parameter = starting index
// second parameter = number of elements to remove
if(b.color === colorToEat) {
// Yes, we remove it and increment the score
goodBallsEaten += 1;
soundBolaBuena.play();
} else {
soundBolaMala.play();
wrongBallsEaten += 1;
}
balls.splice(index, 1);
}
}
function testCollisionBallWithWalls(b) {
// COLLISION WITH VERTICAL WALLS ?
if((b.x + b.radius) > w) {
// the ball hit the right wall
// change horizontal direction
b.speedX = -b.speedX;
// put the ball at the collision point
b.x = w - b.radius;
} else if((b.x -b.radius) < 0) {
// the ball hit the left wall
// change horizontal direction
b.speedX = -b.speedX;
// put the ball at the collision point
b.x = b.radius;
}
// COLLISIONS WTH HORIZONTAL WALLS ?
// Not in the else as the ball can touch both
// vertical and horizontal walls in corners
if((b.y + b.radius) > h) {
// the ball hit the right wall
// change horizontal direction
b.speedY = -b.speedY;
// put the ball at the collision point
b.y = h - b.radius;
} else if((b.y -b.radius) < 0) {
// the ball hit the left wall
// change horizontal direction
b.speedY = -b.speedY;
// put the ball at the collision point
b.Y = b.radius;
}
}
function drawFilledRectangle(r) {
// GOOD practice: save the context, use 2D trasnformations
ctx.save();
// translate the coordinate system, draw relative to it
ctx.translate(r.x, r.y);
ctx.fillStyle = r.color;
// (0, 0) is the top left corner of the monster.
ctx.fillRect(0, 0, r.width, r.height);
var img = document.getElementById("jugador");
ctx.drawImage(img,0,0,40,40);
// GOOD practice: restore the context
ctx.restore();
}
function drawFilledCircle(c) {
// GOOD practice: save the context, use 2D trasnformations
ctx.save();
// translate the coordinate system, draw relative to it
ctx.translate(c.x, c.y);
var grd = ctx.createRadialGradient(0, 0, c.radius, 2*Math.PI, 2*Math.PI, 0);
grd.addColorStop(0, c.color);
grd.addColorStop(1, "white");
ctx.fillStyle = grd;
// (0, 0) is the top left corner of the monster.
ctx.beginPath();
ctx.arc(0, 0, c.radius, 0, 2*Math.PI);
ctx.fill();
// GOOD practice: restore the context
ctx.restore();
}
function playSound(sonido) {
var audio = document.getElementById(sonido);
if (audio != null && audio.canPlayType && audio.canPlayType("audio/mpeg"))
{
audio.play();
} }
function reloadSound(sonido){
var audio = document.getElementById(sonido);
console.log("reload el audio")
if (audio != null && audio.canPlayType && audio.canPlayType("audio/mpeg"))
{
audio.pause();
audio.load();
} }
document.addEventListener('play', function(e){
var audios = document.getElementsByTagName('audio');
for(var i = 0, len = audios.length; i < len;i++){
if(audios[i] != e.target){
audios[i].pause();
audios[i].load();
}
}
}, true);
function stopSound(sonido) {
var audio = document.getElementById(sonido);
console.log("empiezo el audio")
if (audio != null && audio.canPlayType && audio.canPlayType("audio/mpeg"))
{
audio.pause();
} }
function processScore(){
document.getElementById("myTable").innerHTML="";
var tableHeader = document.querySelector("#myTable");
var rowHeader = tableHeader.insertRow();
rowHeader.innerHTML = "<th scope='col'>Position</th><th scope='col'>Score</th>";
if(localStorage.pos1==undefined){
localStorage.pos1=0;
localStorage.pos2=0;
localStorage.pos3=0;
localStorage.pos4=0;
localStorage.pos5=0;
localStorage.pos6=0;
localStorage.pos7=0;
localStorage.pos8=0;
localStorage.pos9=0;
localStorage.pos10=0;
}
var scoreToProcess = points;
var position1 = localStorage.pos1;
var position2 = localStorage.pos2;
var position3 = localStorage.pos3;
var position4 = localStorage.pos4;
var position5 = localStorage.pos5;
var position6 = localStorage.pos6;
var position7 = localStorage.pos7;
var position8 = localStorage.pos8;
var position9 = localStorage.pos9;
var position10 = localStorage.pos10;
var arrayOfScores=[position1,position2,position3,position4,position5,position6,position7,position8,position9,position10];
arrayOfScores.push(scoreToProcess);
arrayOfScores.sort(function(a, b) {
return a - b;
});
arrayOfScores.reverse();
if(arrayOfScores.length==11){
arrayOfScores.pop();
}
localStorage.pos1 = arrayOfScores[0];
localStorage.pos2 = arrayOfScores[1];
localStorage.pos3 = arrayOfScores[2];
localStorage.pos4 = arrayOfScores[3];
localStorage.pos5 = arrayOfScores[4];
localStorage.pos6 = arrayOfScores[5];
localStorage.pos7 = arrayOfScores[6];
localStorage.pos8 = arrayOfScores[7];
localStorage.pos9 = arrayOfScores[8];
localStorage.pos10 = arrayOfScores[9];
console.log(arrayOfScores);
for(var i=0;i<arrayOfScores.length;i++){
var position=i+1;
var score=arrayOfScores[i];
var table = document.querySelector("#myTable");
var row = table.insertRow();
row.innerHTML = "<td>"+position+"</td><td>"+score+"</td>";
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Draw a monster in a canvas</title>
<img id="jugador" src="http://jordiminguell.com/wp-content/uploads/2017/10/RAJOY-724x1024.jpg" alt="player" width="" height="20" style="display:none">
<script src="https://cdnjs.cloudflare.com/ajax/libs/howler/1.1.28/howler.min.js"></script>
</head>
<body>
<center><input type="button" class="button button1" value="start game" id="start" onclick="init();"></center>
<center><h2 id="helpText">Help Mariano destroy the red bubbles!</h2></center>
<center><h4 id="loadingText"></h4></center>
<center> <canvas id="myCanvas" width="400" height="320"></canvas>
<center><h2 id="points"></h2></center>
<table id="myTable">
</table>
</body>
</html>