diff --git a/.firebaserc b/.firebaserc new file mode 100644 index 0000000..3abc281 --- /dev/null +++ b/.firebaserc @@ -0,0 +1,5 @@ +{ + "projects": { + "default": "leaderboard-bf98b" + } +} diff --git a/Other versions/0.3/Ball.js b/Other versions/0.3/Ball.js new file mode 100644 index 0000000..321f2b2 --- /dev/null +++ b/Other versions/0.3/Ball.js @@ -0,0 +1,32 @@ +function Ball(startx,starty, vx, vy, radius) { + this.x = startx; + this.y = starty; + this.radius = radius; + this.xd = randomsign(); + this.yd = randomsign(); + this.dx = vx; + this.dy = vy; + this.move = function() { + if (this.x+this.dx > height-this.radius || this.x+this.dx < this.radius) { + this.xd = -this.xd; + } + if (this.y+this.dy > width-this.radius || this.y+this.dy < this.radius) { + this.yd = -this.yd; + } + + this.x = this.x + this.dx * this.xd; + this.y = this.y + this.dy * this.yd; + } + + this.shape = function() { + return new circle(this.x,this.y,this.radius); + } + + this.draw = function(ctx) { + ctx.beginPath(); + ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, false); + ctx.fillStyle = "green"; + ctx.fill(); + ctx.closePath(); + } +} \ No newline at end of file diff --git a/Other versions/0.3/Calculations.js b/Other versions/0.3/Calculations.js new file mode 100644 index 0000000..f6aa0c5 --- /dev/null +++ b/Other versions/0.3/Calculations.js @@ -0,0 +1,54 @@ +console.log("Calculations"); + + function circle(x,y,radius) { + this.x = x; + this.y = y; + this.r = radius; + } + + function rectangle(x,y,width,height) { + this.x = x; + this.y = y; + this.w = width; + this.h = height; + } + + function dist(x1,y1,x2,y2) { + return Math.sqrt(Math.pow(Math.abs(x1 - x2),2) + Math.pow(Math.abs(y1 - y2),2)); + } + + function randomsign() { + var i = random(0, 1); + if (i == 0) { + return -1; + } else { + return 1; + } + + } + function random(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + } + + function CircleCircleColliding(c1,c2) { + var dist = dist(c1.x , c1.y , c2.x , c2.y); + if (dist < Math.max(c1.r,c2.r)) { + return true; + } + return false; + } + + function RectCircleColliding(circle,rect){ + var distX = Math.abs(circle.x - rect.x-rect.w/2); + var distY = Math.abs(circle.y - rect.y-rect.h/2); + + if (distX > (rect.w/2 + circle.r)) { return false; } + if (distY > (rect.h/2 + circle.r)) { return false; } + + if (distX <= (rect.w/2)) { return true; } + if (distY <= (rect.h/2)) { return true; } + + var dx=distX-rect.w/2; + var dy=distY-rect.h/2; + return (dx*dx+dy*dy<=(circle.r*circle.r)); + } \ No newline at end of file diff --git a/Other versions/0.3/Controls.js b/Other versions/0.3/Controls.js new file mode 100644 index 0000000..a4fb39c --- /dev/null +++ b/Other versions/0.3/Controls.js @@ -0,0 +1,101 @@ +var playercontrol; + +var mouseX; +var mouseY; + +var upPressed = false; +var downPressed = false; +var rightPressed = false; +var leftPressed = false; + +var upKey = 38; +var rightKey = 39; +var leftKey = 37; +var downKey = 40; + +function setKeyBoardControl(mode) { + if (mode=="wasd") { + playercontrol = keyboardControl; + upKey = 87; + leftKey = 65; + downKey = 83; + rightKey = 68; + } else if (mode=="mouse") { + playercontrol = mouseControl; + mouseX = p.x; + mouseY = p.y; + } else { + playercontrol = keyboardControl; + } + +} + +function keyboardControl(object, speed) { + if(rightPressed) { + object.x += speed; + } + if(leftPressed) { + object.x -= speed; + } + + if(downPressed) { + object.y += speed; + } + + if(upPressed) { + object.y -= speed; + } + + if (object.x < 0) { + object.x = 0; + } else if (object.x > height) { + object.x = height; + } + + if (object.y < 0) { + object.y = 0; + } else if (object.y > width) { + object.y = width; + } +} + +function keyDownHandler(e) { + if(e.keyCode == downKey) { + downPressed = true; + } + if(e.keyCode == rightKey) { + rightPressed = true; + } + if(e.keyCode == upKey) { + upPressed = true; + } + else if(e.keyCode == leftKey) { + leftPressed = true; + } +} + + +function mouseControl(object,speed) { + object.x = mouseX - object.width/2; + object.y = mouseY - object.height/2; +} + +function mouseMoveHandler(e) { + mouseX = e.clientX - canvas.offsetLeft; + mouseY = e.clientY - canvas.offsetTop; +} + +function keyUpHandler(e) { + if(e.keyCode == downKey) { + downPressed = false; + } + if(e.keyCode == rightKey) { + rightPressed = false; + } + if(e.keyCode == upKey) { + upPressed = false; + } + else if(e.keyCode == leftKey) { + leftPressed = false; + } +} \ No newline at end of file diff --git a/Other versions/0.3/Cookies.js b/Other versions/0.3/Cookies.js new file mode 100644 index 0000000..5027c67 --- /dev/null +++ b/Other versions/0.3/Cookies.js @@ -0,0 +1,20 @@ +//Thanks http://www.w3schools.com/js/js_cookies.asp +function setCookie(c_name,c_value,exdays) { + var exdate=new Date(); + exdate.setDate(exdate.getDate() + exdays); + document.cookie=encodeURIComponent(c_name) + + "=" + encodeURIComponent(c_value) + + (!exdays ? "" : "; expires="+exdate.toUTCString()); + ; + } + +function getCookie(cname) { + var name = cname + "="; + var ca = document.cookie.split(';'); + for(var i=0; i newballtick) { + countervalue = 0; + score++; + return true; + } + return false; +} + + +var game = true; + +function addBall() { + var currentdist = 0; + while (currentdist < mindist) { + startx = random(0, height); + starty = random(0, width); + currentdist = dist(startx, starty, p.x, p.y); + } + + vx = random(maxBallspeed / Ballmin, maxBallspeed); + vy = random(maxBallspeed / Ballmin, maxBallspeed); + radius = random(ballRadius / Ballmin, ballRadius); + objects.push(new Ball(startx, starty, vx, vy, radius)); +} + +function draw() { + if (game) { + ctx.clearRect(0, 0, canvas.width, canvas.height); + p.move(); + p.draw(ctx); + + for (var int = 0; int < objects.length; int++) { + var object = objects[int]; + + object.draw(ctx); + + object.move(); + + if (RectCircleColliding(object.shape(), p.shape())) { + endgame(); + } + + } + + if (count()) { + addBall(); + } + requestAnimationFrame(draw); + } +} + +function endgame() { + game = false; + var highscore = getCookie("ballsballsHighScore"); + var again; + if (score > highscore) { + setCookie("ballsballsHighScore",score,100); + again = confirm("game over! \n New HighScore: " + score + + " ( Previous HighScore: " + highscore + + " ) \n Wanna Play Again?"); + } else { + again = confirm("game over! \n Score: " + score + " ( HighScore: " + + highscore + " ) \n Wanna Play Again?"); + } + if (again) { + document.location.reload(); + } else { + document.location.href = "credits"; + } +} \ No newline at end of file diff --git a/Other versions/0.3/Initialization.js b/Other versions/0.3/Initialization.js new file mode 100644 index 0000000..bbb2759 --- /dev/null +++ b/Other versions/0.3/Initialization.js @@ -0,0 +1,71 @@ +var canvas; +var ctx; +var p; +var objects; +var difficulty; +var height; +var width; + +window.onload = function () { +console.log("init"); + +canvas = document.getElementById("myCanvas"); +ctx = canvas.getContext("2d"); + +ctx.canvas.width = window.innerWidth; +ctx.canvas.height = window.innerHeight; + +height = canvas.width; +width = canvas.height; + +p = new Paddle(height/2, width/2, playerlength, playerlength); + +objects = []; + +difficulty = 1; + +if (getCookie("settings")) { + console.log(getCookie("input")); + setKeyBoardControl(getCookie("input")); + + difficulty = getCookie("difficulty"); + + if (difficulty > 0) { + maxBallspeed = maxBallspeed * (difficulty); + if (difficulty == 4) { + Ballmin = Ballmin * 2; + } + + } + + var maxX = getCookie("maxX"); + + if (maxX < height && maxX != 0) { + ctx.canvas.height = maxX; + width = maxX; + } + + var maxY = getCookie("maxY"); + + if (maxY < width && maxY != 0) { + ctx.canvas.width = maxY; + height = maxY; + } + +} else { + var setSettings = confirm("Settings not found, want to set them?"); + if (setSettings) { + window.location.href = "settings"; + } else { + } +} + + mindist = dist(0,0,width,height) / mindist; + +document.addEventListener("keydown", keyDownHandler, false); +document.addEventListener("keyup", keyUpHandler, false); +document.addEventListener("mousemove", mouseMoveHandler, false); + +draw(); + +} diff --git a/Other versions/0.3/Initialization.js~ b/Other versions/0.3/Initialization.js~ new file mode 100644 index 0000000..8497471 --- /dev/null +++ b/Other versions/0.3/Initialization.js~ @@ -0,0 +1,71 @@ +var canvas; +var ctx; +var p; +var objects; +var difficulty; +var height; +var width; + +window.onload = function () { +console.log("init"); + +canvas = document.getElementById("myCanvas"); +ctx = canvas.getContext("2d"); + +ctx.canvas.width = window.innerWidth; +ctx.canvas.height = window.innerHeight; + +height = canvas.width; +width = canvas.height; + +p = new Paddle(height/2, width/2, playerlength, playerlength); + +objects = []; + +difficulty = 1; + +if (getCookie("settings")) { + console.log(getCookie("input")); + setKeyBoardControl(getCookie("input")); + + difficulty = getCookie("difficulty"); + + if (difficulty > 0) { + maxBallspeed = maxBallspeed * (difficulty); + if (difficulty == 4) { + Ballmin = Ballmin * 2; + } + + } + + var maxX = getCookie("maxX"); + + if (maxX < height && maxX != 0) { + ctx.canvas.height = maxX; + width = maxX; + } + + var maxY = getCookie("maxY"); + + if (maxY < width && maxY != 0) { + ctx.canvas.width = maxY; + height = maxY; + } + +} else { + var setSettings = confirm("Settings not found, want to set them?"); + if (setSettings) { + window.location.href = "settings"; + } else { + } +} + + mindist = (height+width)/mindist; + +document.addEventListener("keydown", keyDownHandler, false); +document.addEventListener("keyup", keyUpHandler, false); +document.addEventListener("mousemove", mouseMoveHandler, false); + +draw(); + +} diff --git a/Other versions/0.3/Main.js b/Other versions/0.3/Main.js new file mode 100644 index 0000000..e108cad --- /dev/null +++ b/Other versions/0.3/Main.js @@ -0,0 +1,121 @@ +var game = true; +var canvas = document.getElementById("myCanvas"); +var ctx = canvas.getContext("2d"); + +ctx.canvas.width = window.innerWidth; +ctx.canvas.height = window.innerHeight; + + +var playerlength = 40; +var height = canvas.width; +var width = canvas.height; +var maxBallspeed = 10; +var ballRadius = 40; +var tick = 40; +var newballtick = 20; +var score = 0; +var mindist = 200; + +var p = new Paddle(height/2, width/2, playerlength, playerlength); + +var mousecontrol = confirm("Use Mouse for Control? \n (Arrow Keys are the alternative) "); +if (mousecontrol) { + playercontrol = mouseControl; + mouseX = p.x; + mouseY = p.y; +} else { + playercontrol = keyboardControl; +} + +function random(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; +} + +var countervalue = 0; +function count() { + countervalue++; + if (countervalue > newballtick) { + countervalue = 0; + score++; + return true; + } + return false; +} + +function turn() { + if (game) { + if (count()) { + addBall(); + } + draw(); + requestAnimationFrame(turn); + } +} + +function randomsign() { + var i = random(0, 1); + if (i == 0) { + return -1; + } else { + return 1; + } + +} + +function addBall() { + var currentdist = 0; + while (currentdist < mindist) { + startx = random(0, height); + starty = random(0, width); + currentdist = dist(startx, starty, p.x, p.y); + } + + vx = random(maxBallspeed / 4, maxBallspeed); + vy = random(maxBallspeed / 4, maxBallspeed); + radius = random(ballRadius / 4, ballRadius); + objects.push(new Ball(startx, starty, vx, vy, radius)); +} + +var objects = [ p ]; + +function draw() { + ctx.clearRect(0, 0, canvas.width, canvas.height); + + for (var int = 0; int < objects.length; int++) { + var object = objects[int]; + object.move(); + object.draw(ctx); + + if (object != p) { + if (RectCircleColliding(object.shape(), p.shape())) { + endgame(); + } + + } + + } +} + +function endgame() { + game = false; + var highscore = document.cookie.replace( + /(?:(?:^|.*;\s*)ballsballsHighScore\s*\=\s*([^;]*).*$)|^.*$/, "$1"); + var again; + if (score > highscore) { + document.cookie = "ballsballsHighScore=" + score; + again = confirm("game over! \n New HighScore: " + score + + " ( Previous HighScore: " + highscore + " ) \n Wanna Play Again?"); + } else { + again = confirm("game over! \n Score: " + score + " ( HighScore: " + + highscore + " ) \n Wanna Play Again?"); + } + if (again) { + document.location.reload(); + } else { + document.location.href = "credits"; + } + + +} + +turn(); \ No newline at end of file diff --git a/Other versions/0.3/Paddle.js b/Other versions/0.3/Paddle.js new file mode 100644 index 0000000..2326329 --- /dev/null +++ b/Other versions/0.3/Paddle.js @@ -0,0 +1,21 @@ +function Paddle(ax,ay,awidth,aheight) { + this.x = ax; + this.y = ay; + this.width = awidth; + this.height = aheight; + this.move = function(nx,ny) { + playercontrol(this,8); + } + + this.shape = function(){ + return new rectangle(this.x,this.y,this.width,this.height); + } + + this.draw = function(ctx) { + ctx.beginPath(); + ctx.rect(this.x, this.y, this.width, this.height); + ctx.fillStyle = "#0095DD"; + ctx.fill(); + ctx.closePath(); + } +} \ No newline at end of file diff --git a/Other versions/0.3/SettingsScript.js b/Other versions/0.3/SettingsScript.js new file mode 100644 index 0000000..041c3b1 --- /dev/null +++ b/Other versions/0.3/SettingsScript.js @@ -0,0 +1,78 @@ + window.onload = function () { + var input = document.getElementById("input method"); + addEventListener(input, "change", function () { + var select = document.getElementById("input method"); + var inputmethod = select.options[select.selectedIndex].value; + setCookie("input",inputmethod,100); + }); + + var diffi = document.getElementById("difficulty"); + addEventListener(diffi,"change", function () { + var select = document.getElementById("difficulty"); + var difficulty = select.options[select.selectedIndex].value; + setCookie("difficulty",difficulty,100); + }); + + var saveButton = document.getElementById("save"); + addEventListener(saveButton, "click", function () { + + select = document.getElementById("y"); + setCookie("maxY",select.value,100); + + setCookie("settings",true,100); + }); + + var maxX = document.getElementById("x"); + addEventListener(maxX, "input", function () { + select = document.getElementById("x"); + setCookie("maxX",select.value,100); + }); + + var maxY = document.getElementById("y"); + addEventListener(maxY, "input", function () { + select = document.getElementById("y"); + setCookie("maxY",select.value,100); + }); + + var playAgain = document.getElementById("play"); + addEventListener(playAgain, "click", function () { + setCookie("settings",true,100); + window.location.href = "index"; + }); + + + + + if (getCookie("settings")) { + + var select = document.getElementById("input method"); + var input = getCookie("input"); + var options = select.options; + for(var i = 0; i < options.length; i++) { + var option = options[i]; + if (option.value == input) { + select.selectedIndex = i; + } + } + + + select = document.getElementById("difficulty"); + select.selectedIndex = getCookie("difficulty"); + + select = document.getElementById("x"); + select.value = getCookie("maxX"); + select = document.getElementById("y"); + select.value = getCookie("maxY"); + + } + } + + function addEventListener(myNode, eventType, myHandlerFunc) { + if (myNode.addEventListener) + myNode.addEventListener(eventType, myHandlerFunc, false); + else + myNode.attachEvent("on" + eventType, + function (event) { + myHandlerFunc.call(myNode, event); + }); + } diff --git a/Other versions/0.3/SettingsScript.js~ b/Other versions/0.3/SettingsScript.js~ new file mode 100644 index 0000000..e046f26 --- /dev/null +++ b/Other versions/0.3/SettingsScript.js~ @@ -0,0 +1,78 @@ + window.onload = function () { + var input = document.getElementById("input method"); + addEventListener(input, "change", function () { + var select = document.getElementById("input method"); + var inputmethod = select.options[select.selectedIndex].value; + setCookie("input",inputmethod,100); + }); + + var diffi = document.getElementById("difficulty"); + addEventListener(diffi,"change", function () { + var select = document.getElementById("difficulty"); + var difficulty = select.options[select.selectedIndex].value; + setCookie("difficulty",difficulty,100); + }); + + var saveButton = document.getElementById("save"); + addEventListener(saveButton, "click", function () { + + select = document.getElementById("y"); + setCookie("maxY",select.value,100); + + setCookie("settings",true,100); + }); + + var maxX = document.getElementById("x"); + addEventListener(maxX, "input", function () { + select = document.getElementById("x"); + setCookie("maxX",select.value,100); + }); + + var maxY = document.getElementById("y"); + addEventListener(maxY, "input", function () { + select = document.getElementById("y"); + setCookie("maxY",select.value,100); + }); + + var playAgain = document.getElementByID("play"); + addEventListener(playAgain, "click", function () { + setCookie("settings",true,100); + window.location.href = "index"; + }); + + + + + if (getCookie("settings")) { + + var select = document.getElementById("input method"); + var input = getCookie("input"); + var options = select.options; + for(var i = 0; i < options.length; i++) { + var option = options[i]; + if (option.value == input) { + select.selectedIndex = i; + } + } + + + select = document.getElementById("difficulty"); + select.selectedIndex = getCookie("difficulty"); + + select = document.getElementById("x"); + select.value = getCookie("maxX"); + select = document.getElementById("y"); + select.value = getCookie("maxY"); + + } + } + + function addEventListener(myNode, eventType, myHandlerFunc) { + if (myNode.addEventListener) + myNode.addEventListener(eventType, myHandlerFunc, false); + else + myNode.attachEvent("on" + eventType, + function (event) { + myHandlerFunc.call(myNode, event); + }); + } diff --git a/Other versions/0.3/Values.js b/Other versions/0.3/Values.js new file mode 100644 index 0000000..83e92d8 --- /dev/null +++ b/Other versions/0.3/Values.js @@ -0,0 +1,12 @@ +var playerlength = 35; + +//Base +var maxBallspeed = 5; +var ballRadius = 40; + +var Ballmin = 5; //fraction for minimum speed and size of ball + +var tick = 40; //unused (ithink) +var newballtick = 20; //how often new ball is created + +var mindist = 4; //Fraction of average of width+Height diff --git a/Other versions/0.3/Values.js~ b/Other versions/0.3/Values.js~ new file mode 100644 index 0000000..5a34c2c --- /dev/null +++ b/Other versions/0.3/Values.js~ @@ -0,0 +1,12 @@ +var playerlength = 35; + +//Base +var maxBallspeed = 5; +var ballRadius = 10; + +var Ballmin = 5; //fraction for minimum speed and size of ball + +var tick = 40; //unused (ithink) +var newballtick = 20; //how often new ball is created + +var mindist = 4; //Fraction of average of width+Height diff --git a/Other versions/0.3/credits.html b/Other versions/0.3/credits.html new file mode 100644 index 0000000..3aa0825 --- /dev/null +++ b/Other versions/0.3/credits.html @@ -0,0 +1,32 @@ + + + + +Credits + + + +

+

Made by Søren Oehlenschlæger Hjort

+ + + +
+ +
+
+ +
+ +
+
+
+

Version 0.3

+ + \ No newline at end of file diff --git a/Other versions/0.3/favicon.ico b/Other versions/0.3/favicon.ico new file mode 100644 index 0000000..9647b48 Binary files /dev/null and b/Other versions/0.3/favicon.ico differ diff --git a/Other versions/0.3/index.html b/Other versions/0.3/index.html new file mode 100644 index 0000000..dc98298 --- /dev/null +++ b/Other versions/0.3/index.html @@ -0,0 +1,30 @@ + + + + + BallsBalls + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Other versions/0.3/settings.html b/Other versions/0.3/settings.html new file mode 100644 index 0000000..12a4ddc --- /dev/null +++ b/Other versions/0.3/settings.html @@ -0,0 +1,58 @@ + + + + + Credits + + + + + + + +

Settings for BallsBalls

+

Made by Søren Oehlenschlæger Hjort

+ Uses Cookies To save +
+
+ + Input Method: + + +
+
+ + Difficulty: + + +
+
+ Max Screen Width: + Max Screen Height: + +
+
+ + + + + + diff --git a/Other versions/0.3/settings.html~ b/Other versions/0.3/settings.html~ new file mode 100644 index 0000000..2b15dcc --- /dev/null +++ b/Other versions/0.3/settings.html~ @@ -0,0 +1,58 @@ + + + + + Credits + + + + + + + +

Settings for BallsBalls

+

Made by Søren Oehlenschlæger Hjort

+ Uses Cookies To save +
+
+ + Input Method: + + +
+
+ + Difficulty: + + +
+
+ Max Width: + Max Height: + +
+
+ + + + + + diff --git a/Other versions/0.5/Ball.js b/Other versions/0.5/Ball.js new file mode 100644 index 0000000..82e70dd --- /dev/null +++ b/Other versions/0.5/Ball.js @@ -0,0 +1,32 @@ +function Ball(startx,starty, vx, vy, radius) { + this.x = startx; + this.y = starty; + this.radius = radius; + this.xd = randomsign(); + this.yd = randomsign(); + this.dx = vx; + this.dy = vy; + this.move = function() { + if ((this.x > height-this.radius && this.xd > 0)|| (this.x < this.radius && this.xd < 0)) { + this.xd = -this.xd; + } + if ((this.y > width-this.radius && this.yd > 0) || (this.y < this.radius && this.yd < 0)) { + this.yd = -this.yd; + } + + this.x = this.x + this.dx * this.xd; + this.y = this.y + this.dy * this.yd; + } + + this.shape = function() { + return new circle(this.x,this.y,this.radius); + } + + this.draw = function(ctx) { + ctx.beginPath(); + ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, false); + ctx.fillStyle = "green"; + ctx.fill(); + ctx.closePath(); + } +} \ No newline at end of file diff --git a/Other versions/0.5/Calculations.js b/Other versions/0.5/Calculations.js new file mode 100644 index 0000000..d3f21d7 --- /dev/null +++ b/Other versions/0.5/Calculations.js @@ -0,0 +1,54 @@ + // Shape objects: + function circle(x,y,radius) { + this.x = x; + this.y = y; + this.r = radius; + } + + function rectangle(x,y,width,height) { + this.x = x; + this.y = y; + this.w = width; + this.h = height; + } + + //distance calculator (between two points) + function dist(x1,y1,x2,y2) { + return Math.sqrt(Math.pow(Math.abs(x1 - x2),2) + Math.pow(Math.abs(y1 - y2),2)); + } + + function randomsign() { + var i = random(0, 1); + if (i == 0) { + return -1; + } else { + return 1; + } + } + + function random(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + } + + function CircleCircleColliding(c1,c2) { + var dist = dist(c1.x , c1.y , c2.x , c2.y); + if (dist < Math.max(c1.r,c2.r)) { + return true; + } + return false; + } + + function RectCircleColliding(circle,rect){ + var distX = Math.abs(circle.x - rect.x-rect.w/2); + var distY = Math.abs(circle.y - rect.y-rect.h/2); + + if (distX > (rect.w/2 + circle.r)) { return false; } + if (distY > (rect.h/2 + circle.r)) { return false; } + + if (distX <= (rect.w/2)) { return true; } + if (distY <= (rect.h/2)) { return true; } + + var dx=distX-rect.w/2; + var dy=distY-rect.h/2; + return (dx*dx+dy*dy<=(circle.r*circle.r)); + } \ No newline at end of file diff --git a/Other versions/0.5/Controls.js b/Other versions/0.5/Controls.js new file mode 100644 index 0000000..74f4188 --- /dev/null +++ b/Other versions/0.5/Controls.js @@ -0,0 +1,101 @@ +var playercontrol; + +var mouseX; +var mouseY; + +var upPressed = false; +var downPressed = false; +var rightPressed = false; +var leftPressed = false; + +var upKey = 38; +var rightKey = 39; +var leftKey = 37; +var downKey = 40; + +//sets the control mode +function setControl(mode) { + if (mode=="wasd") { + playercontrol = keyboardControl; + upKey = 87; + leftKey = 65; + downKey = 83; + rightKey = 68; + } else if (mode=="mouse") { + playercontrol = mouseControl; + mouseX = p.x; + mouseY = p.y; + } else { + playercontrol = keyboardControl; + } + +} + +function keyboardControl(object, speed) { + if(rightPressed) { + object.x += speed; + } + if(leftPressed) { + object.x -= speed; + } + + if(downPressed) { + object.y += speed; + } + + if(upPressed) { + object.y -= speed; + } + + if (object.x < 0) { + object.x = 0; + } else if (object.x + object.height > height) { + object.x = height-object.height; + } + + if (object.y < 0) { + object.y = 0; + } else if (object.y + object.width > width) { + object.y = width-object.width; + } +} + +function mouseControl(object,speed) { + object.x = mouseX - object.width/2; + object.y = mouseY - object.height/2; +} + +function mouseMoveHandler(e) { + mouseX = e.clientX - canvas.offsetLeft; + mouseY = e.clientY - canvas.offsetTop; +} + +function keyDownHandler(e) { + if(e.keyCode == downKey) { + downPressed = true; + } + if(e.keyCode == rightKey) { + rightPressed = true; + } + if(e.keyCode == upKey) { + upPressed = true; + } + else if(e.keyCode == leftKey) { + leftPressed = true; + } +} + +function keyUpHandler(e) { + if(e.keyCode == downKey) { + downPressed = false; + } + if(e.keyCode == rightKey) { + rightPressed = false; + } + if(e.keyCode == upKey) { + upPressed = false; + } + else if(e.keyCode == leftKey) { + leftPressed = false; + } +} \ No newline at end of file diff --git a/Other versions/0.5/Cookies.js b/Other versions/0.5/Cookies.js new file mode 100644 index 0000000..5027c67 --- /dev/null +++ b/Other versions/0.5/Cookies.js @@ -0,0 +1,20 @@ +//Thanks http://www.w3schools.com/js/js_cookies.asp +function setCookie(c_name,c_value,exdays) { + var exdate=new Date(); + exdate.setDate(exdate.getDate() + exdays); + document.cookie=encodeURIComponent(c_name) + + "=" + encodeURIComponent(c_value) + + (!exdays ? "" : "; expires="+exdate.toUTCString()); + ; + } + +function getCookie(cname) { + var name = cname + "="; + var ca = document.cookie.split(';'); + for(var i=0; i tickperball) { + countervalue = 0; + score++; + return true; + } + return false; +} + +function addBall() { + //set starting position + var currentdist = 0; + while (currentdist < mindist) { + startx = random(0, height); + starty = random(0, width); + currentdist = dist(startx, starty, p.x, p.y); + } + + //set speed + vx = random(minBallspeed, maxBallspeed); + vy = random(minBallspeed, maxBallspeed); + + //set size + radius = random(minballRadius,maxballRadius); + + //add to ball list + objects.push(new Ball(startx, starty, vx, vy, radius)); +} + +//ending the game, when player dies +function endgame() { + game = false; + var highscore = getCookie("ballsballsHighScore"); + var again; + if (score > highscore) { + setCookie("ballsballsHighScore",score,100); + again = confirm("game over! \n New HighScore: " + score + + " ( Previous HighScore: " + highscore + + " ) \n Wanna Play Again?"); + } else { + again = confirm("game over! \n Score: " + score + " ( HighScore: " + + highscore + " ) \n Wanna Play Again?"); + } + if (again) { + document.location.reload(); + } else { + document.location.href = "credits"; + } +} \ No newline at end of file diff --git a/Other versions/0.5/Initialization.js b/Other versions/0.5/Initialization.js new file mode 100644 index 0000000..e17b4e4 --- /dev/null +++ b/Other versions/0.5/Initialization.js @@ -0,0 +1,69 @@ +var canvas; +var ctx; +var p; +var objects; +var difficulty; +var height; +var width; + +window.onload = function () { +console.log("init"); + +canvas = document.getElementById("myCanvas"); +ctx = canvas.getContext("2d"); + +ctx.canvas.width = window.innerWidth; +ctx.canvas.height = window.innerHeight; + +height = canvas.width; +width = canvas.height; + +p = new Paddle(height/2, width/2, playerlength); + +objects = []; + +difficulty = 1; + +if (getCookie("settings")) { + setControl(getCookie("input")); + + difficulty = getCookie("difficulty"); + +// if (difficulty > 0) { +// maxBallspeed = maxBallspeed * (difficulty); +// if (difficulty == 4) { +// Ballmin = Ballmin * 2; +// } +// } + + var maxX = getCookie("maxX"); + + if (maxX < height && maxX != 0) { + ctx.canvas.height = maxX; + width = maxX; + } + + var maxY = getCookie("maxY"); + + if (maxY < width && maxY != 0) { + ctx.canvas.width = maxY; + height = maxY; + } +} else { + var setSettings = confirm("Settings not found, want to set them?"); + if (setSettings) { + window.location.href = "settings"; + } else { + + } +} + +mindist = dist(0,0,width,height) / mindist; + +document.addEventListener("keydown", keyDownHandler, false); +document.addEventListener("keyup", keyUpHandler, false); +document.addEventListener("mousemove", mouseMoveHandler, false); + +doTurn(); + +} \ No newline at end of file diff --git a/Other versions/0.5/Paddle.js b/Other versions/0.5/Paddle.js new file mode 100644 index 0000000..c4ab3f3 --- /dev/null +++ b/Other versions/0.5/Paddle.js @@ -0,0 +1,21 @@ +function Paddle(ax,ay,length) { + this.x = ax; + this.y = ay; + this.width = length; + this.height = length; + this.move = function(nx,ny) { + playercontrol(this,playerSpeed); + } + + this.shape = function(){ + return new rectangle(this.x,this.y,this.width,this.height); + } + + this.draw = function(ctx) { + ctx.beginPath(); + ctx.rect(this.x, this.y, this.width, this.height); + ctx.fillStyle = "#0095DD"; + ctx.fill(); + ctx.closePath(); + } +} \ No newline at end of file diff --git a/Other versions/0.5/SettingsScript.js b/Other versions/0.5/SettingsScript.js new file mode 100644 index 0000000..041c3b1 --- /dev/null +++ b/Other versions/0.5/SettingsScript.js @@ -0,0 +1,78 @@ + window.onload = function () { + var input = document.getElementById("input method"); + addEventListener(input, "change", function () { + var select = document.getElementById("input method"); + var inputmethod = select.options[select.selectedIndex].value; + setCookie("input",inputmethod,100); + }); + + var diffi = document.getElementById("difficulty"); + addEventListener(diffi,"change", function () { + var select = document.getElementById("difficulty"); + var difficulty = select.options[select.selectedIndex].value; + setCookie("difficulty",difficulty,100); + }); + + var saveButton = document.getElementById("save"); + addEventListener(saveButton, "click", function () { + + select = document.getElementById("y"); + setCookie("maxY",select.value,100); + + setCookie("settings",true,100); + }); + + var maxX = document.getElementById("x"); + addEventListener(maxX, "input", function () { + select = document.getElementById("x"); + setCookie("maxX",select.value,100); + }); + + var maxY = document.getElementById("y"); + addEventListener(maxY, "input", function () { + select = document.getElementById("y"); + setCookie("maxY",select.value,100); + }); + + var playAgain = document.getElementById("play"); + addEventListener(playAgain, "click", function () { + setCookie("settings",true,100); + window.location.href = "index"; + }); + + + + + if (getCookie("settings")) { + + var select = document.getElementById("input method"); + var input = getCookie("input"); + var options = select.options; + for(var i = 0; i < options.length; i++) { + var option = options[i]; + if (option.value == input) { + select.selectedIndex = i; + } + } + + + select = document.getElementById("difficulty"); + select.selectedIndex = getCookie("difficulty"); + + select = document.getElementById("x"); + select.value = getCookie("maxX"); + select = document.getElementById("y"); + select.value = getCookie("maxY"); + + } + } + + function addEventListener(myNode, eventType, myHandlerFunc) { + if (myNode.addEventListener) + myNode.addEventListener(eventType, myHandlerFunc, false); + else + myNode.attachEvent("on" + eventType, + function (event) { + myHandlerFunc.call(myNode, event); + }); + } diff --git a/Other versions/0.5/Values.js b/Other versions/0.5/Values.js new file mode 100644 index 0000000..4289e3e --- /dev/null +++ b/Other versions/0.5/Values.js @@ -0,0 +1,17 @@ +var playerlength = 18; +var playerSpeed = 7; +var graceperiod = 100; +var mindist = 4; //Fraction of average of width+Height + +//Base (might change through levels) +var maxBallspeed = 5; +var minBallspeed = 1; +var maxballRadius = 15; +var minballRadius = 5; + +var initialballs = 1; //0balls at the start of the level +var levelduration = 30; + +var tickperball = 20; //how often new ball is created +var ballspertick = 1; //how many balls are created at once + diff --git a/Other versions/0.5/credits.html b/Other versions/0.5/credits.html new file mode 100644 index 0000000..ae80554 --- /dev/null +++ b/Other versions/0.5/credits.html @@ -0,0 +1,32 @@ + + + + +Credits + + + +

+

Made by Søren Oehlenschlæger Hjort

+ + + +
+ +
+
+ +
+ +
+
+
+

Version 0.5

+ + \ No newline at end of file diff --git a/Other versions/0.5/index.html b/Other versions/0.5/index.html new file mode 100644 index 0000000..467fd9b --- /dev/null +++ b/Other versions/0.5/index.html @@ -0,0 +1,30 @@ + + + + + BallsBalls + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Other versions/0.5/settings.html b/Other versions/0.5/settings.html new file mode 100644 index 0000000..12a4ddc --- /dev/null +++ b/Other versions/0.5/settings.html @@ -0,0 +1,58 @@ + + + + + Credits + + + + + + + +

Settings for BallsBalls

+

Made by Søren Oehlenschlæger Hjort

+ Uses Cookies To save +
+
+ + Input Method: + + +
+
+ + Difficulty: + + +
+
+ Max Screen Width: + Max Screen Height: + +
+
+ + + + + + diff --git a/Other versions/0.6/Ball.js b/Other versions/0.6/Ball.js new file mode 100644 index 0000000..82e70dd --- /dev/null +++ b/Other versions/0.6/Ball.js @@ -0,0 +1,32 @@ +function Ball(startx,starty, vx, vy, radius) { + this.x = startx; + this.y = starty; + this.radius = radius; + this.xd = randomsign(); + this.yd = randomsign(); + this.dx = vx; + this.dy = vy; + this.move = function() { + if ((this.x > height-this.radius && this.xd > 0)|| (this.x < this.radius && this.xd < 0)) { + this.xd = -this.xd; + } + if ((this.y > width-this.radius && this.yd > 0) || (this.y < this.radius && this.yd < 0)) { + this.yd = -this.yd; + } + + this.x = this.x + this.dx * this.xd; + this.y = this.y + this.dy * this.yd; + } + + this.shape = function() { + return new circle(this.x,this.y,this.radius); + } + + this.draw = function(ctx) { + ctx.beginPath(); + ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, false); + ctx.fillStyle = "green"; + ctx.fill(); + ctx.closePath(); + } +} \ No newline at end of file diff --git a/Other versions/0.6/Calculations.js b/Other versions/0.6/Calculations.js new file mode 100644 index 0000000..d3f21d7 --- /dev/null +++ b/Other versions/0.6/Calculations.js @@ -0,0 +1,54 @@ + // Shape objects: + function circle(x,y,radius) { + this.x = x; + this.y = y; + this.r = radius; + } + + function rectangle(x,y,width,height) { + this.x = x; + this.y = y; + this.w = width; + this.h = height; + } + + //distance calculator (between two points) + function dist(x1,y1,x2,y2) { + return Math.sqrt(Math.pow(Math.abs(x1 - x2),2) + Math.pow(Math.abs(y1 - y2),2)); + } + + function randomsign() { + var i = random(0, 1); + if (i == 0) { + return -1; + } else { + return 1; + } + } + + function random(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + } + + function CircleCircleColliding(c1,c2) { + var dist = dist(c1.x , c1.y , c2.x , c2.y); + if (dist < Math.max(c1.r,c2.r)) { + return true; + } + return false; + } + + function RectCircleColliding(circle,rect){ + var distX = Math.abs(circle.x - rect.x-rect.w/2); + var distY = Math.abs(circle.y - rect.y-rect.h/2); + + if (distX > (rect.w/2 + circle.r)) { return false; } + if (distY > (rect.h/2 + circle.r)) { return false; } + + if (distX <= (rect.w/2)) { return true; } + if (distY <= (rect.h/2)) { return true; } + + var dx=distX-rect.w/2; + var dy=distY-rect.h/2; + return (dx*dx+dy*dy<=(circle.r*circle.r)); + } \ No newline at end of file diff --git a/Other versions/0.6/Controls.js b/Other versions/0.6/Controls.js new file mode 100644 index 0000000..74f4188 --- /dev/null +++ b/Other versions/0.6/Controls.js @@ -0,0 +1,101 @@ +var playercontrol; + +var mouseX; +var mouseY; + +var upPressed = false; +var downPressed = false; +var rightPressed = false; +var leftPressed = false; + +var upKey = 38; +var rightKey = 39; +var leftKey = 37; +var downKey = 40; + +//sets the control mode +function setControl(mode) { + if (mode=="wasd") { + playercontrol = keyboardControl; + upKey = 87; + leftKey = 65; + downKey = 83; + rightKey = 68; + } else if (mode=="mouse") { + playercontrol = mouseControl; + mouseX = p.x; + mouseY = p.y; + } else { + playercontrol = keyboardControl; + } + +} + +function keyboardControl(object, speed) { + if(rightPressed) { + object.x += speed; + } + if(leftPressed) { + object.x -= speed; + } + + if(downPressed) { + object.y += speed; + } + + if(upPressed) { + object.y -= speed; + } + + if (object.x < 0) { + object.x = 0; + } else if (object.x + object.height > height) { + object.x = height-object.height; + } + + if (object.y < 0) { + object.y = 0; + } else if (object.y + object.width > width) { + object.y = width-object.width; + } +} + +function mouseControl(object,speed) { + object.x = mouseX - object.width/2; + object.y = mouseY - object.height/2; +} + +function mouseMoveHandler(e) { + mouseX = e.clientX - canvas.offsetLeft; + mouseY = e.clientY - canvas.offsetTop; +} + +function keyDownHandler(e) { + if(e.keyCode == downKey) { + downPressed = true; + } + if(e.keyCode == rightKey) { + rightPressed = true; + } + if(e.keyCode == upKey) { + upPressed = true; + } + else if(e.keyCode == leftKey) { + leftPressed = true; + } +} + +function keyUpHandler(e) { + if(e.keyCode == downKey) { + downPressed = false; + } + if(e.keyCode == rightKey) { + rightPressed = false; + } + if(e.keyCode == upKey) { + upPressed = false; + } + else if(e.keyCode == leftKey) { + leftPressed = false; + } +} \ No newline at end of file diff --git a/Other versions/0.6/Cookies.js b/Other versions/0.6/Cookies.js new file mode 100644 index 0000000..5027c67 --- /dev/null +++ b/Other versions/0.6/Cookies.js @@ -0,0 +1,20 @@ +//Thanks http://www.w3schools.com/js/js_cookies.asp +function setCookie(c_name,c_value,exdays) { + var exdate=new Date(); + exdate.setDate(exdate.getDate() + exdays); + document.cookie=encodeURIComponent(c_name) + + "=" + encodeURIComponent(c_value) + + (!exdays ? "" : "; expires="+exdate.toUTCString()); + ; + } + +function getCookie(cname) { + var name = cname + "="; + var ca = document.cookie.split(';'); + for(var i=0; i tickperball) { + countervalue = 0; + score++; + return true; + } + return false; +} + +function addBall() { + //set starting position + var currentdist = 0; + while (currentdist < mindist) { + startx = random(0, height); + starty = random(0, width); + currentdist = dist(startx, starty, p.x, p.y); + } + + //set speed + vx = random(minBallspeed, maxBallspeed); + vy = random(minBallspeed, maxBallspeed); + + //set size + radius = random(minballRadius,maxballRadius); + + //add to ball list + objects.push(new Ball(startx, starty, vx, vy, radius)); +} + +//ending the game, when player dies +function endgame() { + game = false; + var highscore = getCookie("ballsballsHighScore"); + var again; + if (score > highscore) { + setCookie("ballsballsHighScore",score,100); + again = confirm("game over! \n New HighScore: " + score + + " ( Previous HighScore: " + highscore + + " ) \n Wanna Play Again?"); + } else { + again = confirm("game over! \n Score: " + score + " ( HighScore: " + + highscore + " ) \n Wanna Play Again?"); + } + if (again) { + document.location.reload(); + } else { + document.location.href = "credits"; + } +} \ No newline at end of file diff --git a/Other versions/0.6/Initialization.js b/Other versions/0.6/Initialization.js new file mode 100644 index 0000000..21beb84 --- /dev/null +++ b/Other versions/0.6/Initialization.js @@ -0,0 +1,46 @@ +var canvas; +var ctx; +var p; +var objects; +var difficulty; +var height; +var width; + +window.onload = function () { +console.log("init"); + +canvas = document.getElementById("myCanvas"); +ctx = canvas.getContext("2d"); + +ctx.canvas.width = window.innerWidth; +ctx.canvas.height = window.innerHeight; + +height = canvas.width; +width = canvas.height; + +p = new Paddle(height/2, width/2, playerlength); + +objects = []; + +difficulty = 1; + +if (getCookie("settings")) { + setControl(getCookie("input")); +} else { + var setSettings = confirm("Settings not found, want to set them?"); + if (setSettings) { + window.location.href = "settings"; + } else { + setControl(""); + } +} + +mindist = dist(0,0,width,height) / mindist; + +document.addEventListener("keydown", keyDownHandler, false); +document.addEventListener("keyup", keyUpHandler, false); +document.addEventListener("mousemove", mouseMoveHandler, false); + +doTurn(); + +} \ No newline at end of file diff --git a/Other versions/0.6/Paddle.js b/Other versions/0.6/Paddle.js new file mode 100644 index 0000000..c4ab3f3 --- /dev/null +++ b/Other versions/0.6/Paddle.js @@ -0,0 +1,21 @@ +function Paddle(ax,ay,length) { + this.x = ax; + this.y = ay; + this.width = length; + this.height = length; + this.move = function(nx,ny) { + playercontrol(this,playerSpeed); + } + + this.shape = function(){ + return new rectangle(this.x,this.y,this.width,this.height); + } + + this.draw = function(ctx) { + ctx.beginPath(); + ctx.rect(this.x, this.y, this.width, this.height); + ctx.fillStyle = "#0095DD"; + ctx.fill(); + ctx.closePath(); + } +} \ No newline at end of file diff --git a/Other versions/0.6/SettingsScript.js b/Other versions/0.6/SettingsScript.js new file mode 100644 index 0000000..a5b2db2 --- /dev/null +++ b/Other versions/0.6/SettingsScript.js @@ -0,0 +1,45 @@ + window.onload = function () { + var input = document.getElementById("input method"); + addEventListener(input, "change", function () { + var select = document.getElementById("input method"); + var inputmethod = select.options[select.selectedIndex].value; + setCookie("input",inputmethod,100); + }); + + var saveButton = document.getElementById("save"); + addEventListener(saveButton, "click", function () { + + select = document.getElementById("y"); + setCookie("maxY",select.value,100); + + setCookie("settings",true,100); + }); + + var playAgain = document.getElementById("play"); + addEventListener(playAgain, "click", function () { + setCookie("settings",true,100); + window.location.href = "index"; + }); + + if (getCookie("settings")) { + var select = document.getElementById("input method"); + var input = getCookie("input"); + var options = select.options; + for(var i = 0; i < options.length; i++) { + var option = options[i]; + if (option.value == input) { + select.selectedIndex = i; + } + } + } + } + + function addEventListener(myNode, eventType, myHandlerFunc) { + if (myNode.addEventListener) + myNode.addEventListener(eventType, myHandlerFunc, false); + else + myNode.attachEvent("on" + eventType, + function (event) { + myHandlerFunc.call(myNode, event); + }); + } diff --git a/Other versions/0.6/Values.js b/Other versions/0.6/Values.js new file mode 100644 index 0000000..4289e3e --- /dev/null +++ b/Other versions/0.6/Values.js @@ -0,0 +1,17 @@ +var playerlength = 18; +var playerSpeed = 7; +var graceperiod = 100; +var mindist = 4; //Fraction of average of width+Height + +//Base (might change through levels) +var maxBallspeed = 5; +var minBallspeed = 1; +var maxballRadius = 15; +var minballRadius = 5; + +var initialballs = 1; //0balls at the start of the level +var levelduration = 30; + +var tickperball = 20; //how often new ball is created +var ballspertick = 1; //how many balls are created at once + diff --git a/Other versions/0.6/credits.html b/Other versions/0.6/credits.html new file mode 100644 index 0000000..895af1c --- /dev/null +++ b/Other versions/0.6/credits.html @@ -0,0 +1,32 @@ + + + + +Credits + + + +

+

Made by Søren Oehlenschlæger Hjort

+ + + +
+ +
+
+ +
+ +
+
+
+

Version 0.6

+ + \ No newline at end of file diff --git a/Other versions/0.6/index.html b/Other versions/0.6/index.html new file mode 100644 index 0000000..467fd9b --- /dev/null +++ b/Other versions/0.6/index.html @@ -0,0 +1,30 @@ + + + + + BallsBalls + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Other versions/0.6/settings.html b/Other versions/0.6/settings.html new file mode 100644 index 0000000..5d60a14 --- /dev/null +++ b/Other versions/0.6/settings.html @@ -0,0 +1,42 @@ + + + + + Credits + + + + + + + +

Settings for BallsBalls

+

Made by Søren Oehlenschlæger Hjort

+ Uses Cookies To save +
+
+ + Input Method: + + +
+
+ + + + + + diff --git a/Other versions/0.7/Ball.js b/Other versions/0.7/Ball.js new file mode 100644 index 0000000..82e70dd --- /dev/null +++ b/Other versions/0.7/Ball.js @@ -0,0 +1,32 @@ +function Ball(startx,starty, vx, vy, radius) { + this.x = startx; + this.y = starty; + this.radius = radius; + this.xd = randomsign(); + this.yd = randomsign(); + this.dx = vx; + this.dy = vy; + this.move = function() { + if ((this.x > height-this.radius && this.xd > 0)|| (this.x < this.radius && this.xd < 0)) { + this.xd = -this.xd; + } + if ((this.y > width-this.radius && this.yd > 0) || (this.y < this.radius && this.yd < 0)) { + this.yd = -this.yd; + } + + this.x = this.x + this.dx * this.xd; + this.y = this.y + this.dy * this.yd; + } + + this.shape = function() { + return new circle(this.x,this.y,this.radius); + } + + this.draw = function(ctx) { + ctx.beginPath(); + ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, false); + ctx.fillStyle = "green"; + ctx.fill(); + ctx.closePath(); + } +} \ No newline at end of file diff --git a/Other versions/0.7/Calculations.js b/Other versions/0.7/Calculations.js new file mode 100644 index 0000000..89537bb --- /dev/null +++ b/Other versions/0.7/Calculations.js @@ -0,0 +1,77 @@ + // Shape objects: + function circle(x,y,radius) { + this.x = x; + this.y = y; + this.r = radius; + } + + function rectangle(x,y,width,height) { + this.x = x; + this.y = y; + this.w = width; + this.h = height; + } + + //distance calculator (between two points) + function dist(x1,y1,x2,y2) { + return Math.sqrt(Math.pow(Math.abs(x1 - x2),2) + Math.pow(Math.abs(y1 - y2),2)); + } + + function randomsign() { + var i = random(0, 1); + if (i == 0) { + return -1; + } else { + return 1; + } + } + function sign(i) { + if (i > 0) { + return 1; + } else if (i < 0) { + return -1; + } else { + return 0; + } + } + + function random(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + } + + function CircleCircleColliding(c1,c2) { + var dist = dist(c1.x , c1.y , c2.x , c2.y); + if (dist < Math.max(c1.r,c2.r)) { + return true; + } + return false; + } + + function RectRectColliding(r1,r2) { + var distX = Math.abs(r1.x + r1.w/2 - r2.x - r2.w/2); + var distY = Math.abs(r1.y + r1.h/2 - r2.y - r2.h/2); + + if (distX > (r1.w + r2.w)/2) { + return false; + } else if (distY > (r1.h + r2.h)/2) { + return false; + } else { + return true; + } + + } + + function RectCircleColliding(circle,rect){ + var distX = Math.abs(circle.x - rect.x-rect.w/2); + var distY = Math.abs(circle.y - rect.y-rect.h/2); + + if (distX > (rect.w/2 + circle.r)) { return false; } + if (distY > (rect.h/2 + circle.r)) { return false; } + + if (distX <= (rect.w/2)) { return true; } + if (distY <= (rect.h/2)) { return true; } + + var dx=distX-rect.w/2; + var dy=distY-rect.h/2; + return (dx*dx+dy*dy<=(circle.r*circle.r)); + } \ No newline at end of file diff --git a/Other versions/0.7/Controls.js b/Other versions/0.7/Controls.js new file mode 100644 index 0000000..df5b7a2 --- /dev/null +++ b/Other versions/0.7/Controls.js @@ -0,0 +1,161 @@ +var playercontrol; +var controlMethod; + +var mouseX; +var mouseY; +var moving = false; + +var upPressed = false; +var downPressed = false; +var rightPressed = false; +var leftPressed = false; + +var upKey = 38; +var rightKey = 39; +var leftKey = 37; +var downKey = 40; + +var restartKey = 32; //spacebar +var settingsKey = 73; // i +var HighscoreKey = 72; // h +var SubmitKey = 13; //enter + +//sets the control mode +function setControl(mode) { + document.addEventListener("keydown", keyDownHandler, false); + document.addEventListener("keyup", keyUpHandler, false); + if (mode=="wasd") { + controlMethod = "WASD"; + playercontrol = keyboardControl; + upKey = 87; + leftKey = 65; + downKey = 83; + rightKey = 68; + } else if (mode=="mouse") { + controlMethod = "Mouse"; + document.addEventListener("mousemove", mouseMoveHandler, false); + playercontrol = mouseControl; + } else if (mode=="mobile") + { + controlMethod = "Mobile"; + playercontrol = mobileControl; + canvas.addEventListener("touchstart", handleStart, false); + canvas.addEventListener("touchend", handleEnd, false); + canvas.addEventListener("touchcancel", handleCancel, false); + canvas.addEventListener("touchmove", handleMove, false); + } + else { + controlMethod = "Arrow Keys"; + playercontrol = keyboardControl; + } +} + +function handleStart(e) { + moving = true; + mouseX = e.changedTouches[0].clientX - canvas.offsetLeft; + mouseY = e.changedTouches[0].clientY - canvas.offsetTop; +} +function handleEnd(e) { + moving = false; +} +function handleCancel(e) { + moving = false; +} +function handleMove(e) { + mouseX = e.changedTouches[0].clientX - canvas.offsetLeft; + mouseY = e.changedTouches[0].clientY - canvas.offsetTop; +} + +function mobileControl(object, speed) { + if (moving) { + object.x = object.x + sign(mouseX-object.x)*speed; + object.y = object.y + sign(mouseY-object.y)*speed; + } +} + +function keyboardControl(object, speed) { + if(rightPressed) { + object.x += speed; + } + if(leftPressed) { + object.x -= speed; + } + + if(downPressed) { + object.y += speed; + } + + if(upPressed) { + object.y -= speed; + } + + if (object.x < 0) { + object.x = 0; + } else if (object.x + object.height > height) { + object.x = height-object.height; + } + + if (object.y < 0) { + object.y = 0; + } else if (object.y + object.width > width) { + object.y = width-object.width; + } +} + +function mouseControl(object,speed) { + if (mouseX != null) { + object.x = mouseX - object.width/2; + object.y = mouseY - object.height/2; + } +} + +function mouseMoveHandler(e) { + mouseX = e.clientX - canvas.offsetLeft; + mouseY = e.clientY - canvas.offsetTop; +} + +function keyDownHandler(e) { + if(e.keyCode == downKey) { + downPressed = true; + } + else if(e.keyCode == rightKey) { + rightPressed = true; + } + else if(e.keyCode == upKey) { + upPressed = true; + } + else if(e.keyCode == leftKey) { + leftPressed = true; + } else if (playerdead && e.keyCode == restartKey) { + restartgame(); + } else if (playerdead && e.keyCode == settingsKey) { + document.location.href = "settings"; + } else if (playerdead && e.keyCode == HighscoreKey) { + document.location.href = "credits"; + } else if (playerdead && scorenotsubmitted && e.keyCode == SubmitKey) { + submitscore(); + } +} + +function keyUpHandler(e) { + if(e.keyCode == downKey) { + downPressed = false; + } + else if(e.keyCode == rightKey) { + rightPressed = false; + } + else if(e.keyCode == upKey) { + upPressed = false; + } + else if(e.keyCode == leftKey) { + leftPressed = false; + } +} + +function resetmovement() { + moving = false; + upPressed = false; + downPressed = false; + rightPressed = false; + leftPressed = false; +} diff --git a/Other versions/0.7/Cookies.js b/Other versions/0.7/Cookies.js new file mode 100644 index 0000000..5027c67 --- /dev/null +++ b/Other versions/0.7/Cookies.js @@ -0,0 +1,20 @@ +//Thanks http://www.w3schools.com/js/js_cookies.asp +function setCookie(c_name,c_value,exdays) { + var exdate=new Date(); + exdate.setDate(exdate.getDate() + exdays); + document.cookie=encodeURIComponent(c_name) + + "=" + encodeURIComponent(c_value) + + (!exdays ? "" : "; expires="+exdate.toUTCString()); + ; + } + +function getCookie(cname) { + var name = cname + "="; + var ca = document.cookie.split(';'); + for(var i=0; i tickperball) { + countervalue = 0; + return true; + } + return false; +} +function addObject(object) { + //set starting position + var currentdist = 0; + while (currentdist < mindist) { + startx = random(0, height); + starty = random(0, width); + currentdist = dist(startx, starty, p.x, p.y); + } + + //set speed + vx = random(minBallspeed, maxBallspeed); + vy = random(minBallspeed, maxBallspeed); + + //set size + radius = random(minballRadius,maxballRadius); + + //add to ball list + objects.push(new object(startx, starty, vx, vy, radius)); +} + + +function addBall() { + addObject(Ball); +} + +function addStealthBall() { + addObject(StealthBall); +} + +function addPickUp() { + //set position + var currentdist = 0; + while (currentdist < mindist) { + x = random(pickuplength, height-pickuplength); + y = random(pickuplength, width-pickuplength); + currentdist = dist(x, y, p.x, p.y); + } + //add Pickup + pickup = new Pickup(x,y,pickuplength); +} + +//ending the game, when player dies +function endgame() { + submitscore(); +} + +function submitscore() { + do { + var playername = prompt("Player name (max " + maxplayernamelength +" characters)"); + } while (!(playername == null) && (playername.length > maxplayernamelength)) + if (!(playername==null)) { + if (leaderboard == null) { + initializeFirebase(); + leaderboard = new Leaderboard("https://leaderboard-bf98b.firebaseio.com"); + } + //reset canvas + ctx.clearRect(0, 0, canvas.width, canvas.height); + //text drawing + ctx.font = "64px Arial"; + ctx.fillStyle = "#dd0095"; + ctx.fillText("Submitting score", width/2, height/4); + console.log(controlMethod); + console.log(" dd " + controlMethod); + console.log("ss"); + addandgo({name: playername, score: score, level: level, method: controlMethod}, function(){ + scorenotsubmitted = false; + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.fillText("Score Submitted", width/2, height/4); + ctx.fillText("Press Space to play again", width/2, height/4+75); + ctx.fillText("Press i for settings", width/2, height/4+150); + ctx.fillText("Press h for Leaderboard", width/2, height/4+225); + }); + } else { + + ctx.fillStyle = "#dd0095"; + ctx.font = "64px Arial"; + ctx.fillText("Game Over", width/2, height/4); + ctx.fillText("Press Space to play again", width/2, height/4+75); + ctx.fillText("Press i for settings", width/2, height/4+150); + ctx.fillText("Press h for Leaderboard", width/2, height/4+225); + ctx.fillText("Press Enter to submit Score", width/2, height/4+300); + } +} \ No newline at end of file diff --git a/Other versions/0.7/HighScoreScript.js b/Other versions/0.7/HighScoreScript.js new file mode 100644 index 0000000..f26cee2 --- /dev/null +++ b/Other versions/0.7/HighScoreScript.js @@ -0,0 +1,31 @@ +window.onload = function() { + var table = document.getElementById("items"); + initializeFirebase(); + var leaderboard = new Leaderboard("https://leaderboard-bf98b.firebaseio.com"); + leaderboard.getandgo(function(list) { + var index, len; + for (index = Math.min(list.length-1,10), len = 0; index >= len; --index) { + addRow(table,list[index]); + } + } + ); + +} + +function addRow(table, data) { //adding a simple row + + var rownumber = table.rows.length; + var row = table.insertRow(rownumber); + + var cell1 = row.insertCell(0); + var cell2 = row.insertCell(1); + var cell3 = row.insertCell(2); + var cell4 = row.insertCell(3); + var cell5 = row.insertCell(4); + + cell1.innerHTML = rownumber; + cell2.innerHTML = data.name; + cell3.innerHTML = data.level; + cell4.innerHTML = data.score; + cell5.innerHTML = data.method; +} \ No newline at end of file diff --git a/Other versions/0.7/Initialization.js b/Other versions/0.7/Initialization.js new file mode 100644 index 0000000..5622486 --- /dev/null +++ b/Other versions/0.7/Initialization.js @@ -0,0 +1,46 @@ +var canvas; +var ctx; +var p; +var pickup; +var objects; +var height; +var width; +var mindist = 4; +var leaderboard; + +window.onload = function () { + +// Initialize canvas +canvas = document.getElementById("myCanvas"); +ctx = canvas.getContext("2d"); + +ctx.canvas.width = window.innerWidth; +ctx.canvas.height = window.innerHeight; + +height = canvas.width; +width = canvas.height; + +if (getCookie("settings")) { + setControl(getCookie("input")); +} else { + var setSettings = confirm("Settings not found, want to set them?"); + if (setSettings) { + window.location.href = "settings"; + } else { + setControl(""); + } +} + +mindist = dist(0,0,width,height) / mindist; + +restartgame(); + +} + +function restartgame() { + setVariables(); + p = new Paddle(height/2, width/2, playerlength); + objects = []; + addPickUp(); + doTurn(); +} diff --git a/Other versions/0.7/Leaderboard.js b/Other versions/0.7/Leaderboard.js new file mode 100644 index 0000000..6d8cbc8 --- /dev/null +++ b/Other versions/0.7/Leaderboard.js @@ -0,0 +1,81 @@ +function initializeFirebase(){ + var config = { + apiKey: "AIzaSyDnQy8gUVUldROZM3hxjg2_M3FE7Yg_cSc", + authDomain: "leaderboard-bf98b.firebaseapp.com", + databaseURL: "https://leaderboard-bf98b.firebaseio.com", + storageBucket: "leaderboard-bf98b.appspot.com", + }; + firebase.initializeApp(config); +} + +class Leaderboard { + constructor(firebaseURL) { + this.firebase = firebase.database(); + this.firebase.ref("scores").orderByChild("score").limitToLast(5).on("value", (value) => { + this.scores = value.val() + }) + } + add(data) { + if(!data.name || data.name.length > maxplayernamelength) { + throw new Error("Requires a valid name.") + } else if(!data.score || isNaN(data.score)) { + throw new Error("Requires a valid score.") + } else { + this.firebase.ref("scores").push(data).setPriority(data.score) + } + } + addandgo(data,go) { + if(!data.name || data.name.length > maxplayernamelength) { + throw new Error("Requires a valid name.") + } else if(!data.score || isNaN(data.score)) { + throw new Error("Requires a valid score.") + } else { + this.firebase.ref("scores").push(data).setPriority(data.score).then(go); + } + } + + get() { + var list = []; + var running = true; + this.firebase.ref("scores").orderByChild("score").once("value").then( + function(snapshot) { + snapshot.forEach(function(childSnapshot) { + list.push(childSnapshot.val()); + }) + running = false; + }); + } + getandgo(go) { + var list = []; + this.firebase.ref("scores").orderByChild("score").once("value").then( + function(snapshot) { + snapshot.forEach(function(childSnapshot) { + list.push(childSnapshot.val()); + }); + go(list); + }); + } +} + +function add(data) { + addandgo(data,function(){}); +} +function addandgo(data,go) { + if(!data.name || data.name.length > maxplayernamelength) { + throw new Error("Requires a valid name.") + } else if(!data.score || isNaN(data.score)) { + throw new Error("Requires a valid score.") + } else { + firebase.database().ref("scores").push(data).setPriority(data.score).then(go); + } +} +function getandgo(go) { + var list = []; + firebase.database().ref("scores").orderByChild("score").once("value").then( + function(snapshot) { + snapshot.forEach(function(childSnapshot) { + list.push(childSnapshot.val()); + }); + go(list); + }); +} \ No newline at end of file diff --git a/Other versions/0.7/Paddle.js b/Other versions/0.7/Paddle.js new file mode 100644 index 0000000..c4ab3f3 --- /dev/null +++ b/Other versions/0.7/Paddle.js @@ -0,0 +1,21 @@ +function Paddle(ax,ay,length) { + this.x = ax; + this.y = ay; + this.width = length; + this.height = length; + this.move = function(nx,ny) { + playercontrol(this,playerSpeed); + } + + this.shape = function(){ + return new rectangle(this.x,this.y,this.width,this.height); + } + + this.draw = function(ctx) { + ctx.beginPath(); + ctx.rect(this.x, this.y, this.width, this.height); + ctx.fillStyle = "#0095DD"; + ctx.fill(); + ctx.closePath(); + } +} \ No newline at end of file diff --git a/Other versions/0.7/Pickup.js b/Other versions/0.7/Pickup.js new file mode 100644 index 0000000..4ab0e6e --- /dev/null +++ b/Other versions/0.7/Pickup.js @@ -0,0 +1,18 @@ +function Pickup(x,y,length) { + this.x = x; + this.y = y; + this.width = length; + this.height = length; + + this.shape = function(){ + return new rectangle(this.x,this.y,this.width,this.height); + } + + this.draw = function(ctx) { + ctx.beginPath(); + ctx.rect(this.x, this.y, this.width, this.height); + ctx.fillStyle = "#FFA500"; + ctx.fill(); + ctx.closePath(); + } +} \ No newline at end of file diff --git a/Other versions/0.7/SettingsScript.js b/Other versions/0.7/SettingsScript.js new file mode 100644 index 0000000..a5b2db2 --- /dev/null +++ b/Other versions/0.7/SettingsScript.js @@ -0,0 +1,45 @@ + window.onload = function () { + var input = document.getElementById("input method"); + addEventListener(input, "change", function () { + var select = document.getElementById("input method"); + var inputmethod = select.options[select.selectedIndex].value; + setCookie("input",inputmethod,100); + }); + + var saveButton = document.getElementById("save"); + addEventListener(saveButton, "click", function () { + + select = document.getElementById("y"); + setCookie("maxY",select.value,100); + + setCookie("settings",true,100); + }); + + var playAgain = document.getElementById("play"); + addEventListener(playAgain, "click", function () { + setCookie("settings",true,100); + window.location.href = "index"; + }); + + if (getCookie("settings")) { + var select = document.getElementById("input method"); + var input = getCookie("input"); + var options = select.options; + for(var i = 0; i < options.length; i++) { + var option = options[i]; + if (option.value == input) { + select.selectedIndex = i; + } + } + } + } + + function addEventListener(myNode, eventType, myHandlerFunc) { + if (myNode.addEventListener) + myNode.addEventListener(eventType, myHandlerFunc, false); + else + myNode.attachEvent("on" + eventType, + function (event) { + myHandlerFunc.call(myNode, event); + }); + } diff --git a/Other versions/0.7/StealthBall.js b/Other versions/0.7/StealthBall.js new file mode 100644 index 0000000..3949f05 --- /dev/null +++ b/Other versions/0.7/StealthBall.js @@ -0,0 +1,29 @@ +function StealthBall(startx,starty, vx, vy, radius) { + this.base = new Ball(startx,starty, vx, vy, radius); + this.speed = (Math.abs(this.base.dx) + Math.abs(this.base.dy)) / 2; + this.ticks = stealthBallticks/this.speed; + this.visible = true; + this.move = function() { + this.base.move(); + if (this.ticks <= 0) { + this.visible = !this.visible; + this.ticks = stealthBallticks/this.speed; + } else { + this.ticks = this.ticks - 1; + } + } + + this.shape = function() { + return this.base.shape(); + } + + this.draw = function(ctx) { + if (this.visible) { + ctx.beginPath(); + ctx.arc(this.base.x, this.base.y, this.base.radius, 0, Math.PI*2, false); + ctx.fillStyle = "red"; + ctx.fill(); + ctx.closePath(); + } + } +} \ No newline at end of file diff --git a/Other versions/0.7/Values.js b/Other versions/0.7/Values.js new file mode 100644 index 0000000..3665a61 --- /dev/null +++ b/Other versions/0.7/Values.js @@ -0,0 +1,54 @@ +// Constants +var playerlength; +var playerSpeed; +var graceperiod; +var pickuplength; +var maxplayernamelength = 10; +// var mindist; //Fraction of average of width+Height // moved to initialization +// Base (might change through levels) +var maxBallspeed; +var minBallspeed; +var maxballRadius; +var minballRadius; +var initialballs; //balls at the start of the level +var levelduration; +var tickperball; //how often new ball is created +var ballspertick; //how many balls are created at once +var stealthBallticks; +// Counter variables: +var countervalue; +var timeLeft; +var gracetimer; +// mode +var grace; +var playerdead; +var scorenotsubmitted; +// progess +var score; +var level; + + +function setVariables() { + playerlength = 18; + playerSpeed = 7; + graceperiod = 100; + pickuplength = 20; + maxBallspeed = 5; + minBallspeed = 1; + maxballRadius = 15; + minballRadius = 5; + initialballs = 1; + levelduration = 30; + tickperball = 20; + ballspertick = 1; + stealthBallticks = 100; + countervalue = 0; + timeLeft = 30; + gracetimer = 0; + grace = false; + playerdead = false; + scorenotsubmitted = true; + score = 0; + level = 1; + resetmovement(); +} \ No newline at end of file diff --git a/Other versions/0.7/credits.html b/Other versions/0.7/credits.html new file mode 100644 index 0000000..73cbf26 --- /dev/null +++ b/Other versions/0.7/credits.html @@ -0,0 +1,35 @@ + + + + +Credits + + + + + + + +
+ + + + + + + + +
RankNameLevelScore (Squares Gathered)Control Method
+
+
+
+ +
+
+ +
+
+

Made by Søren Oehlenschlæger Hjort

+

Version 0.7

+ + \ No newline at end of file diff --git a/Other versions/0.7/index.html b/Other versions/0.7/index.html new file mode 100644 index 0000000..9a5ab9e --- /dev/null +++ b/Other versions/0.7/index.html @@ -0,0 +1,40 @@ + + + + + BallsBalls + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Other versions/0.7/settings.html b/Other versions/0.7/settings.html new file mode 100644 index 0000000..5d60a14 --- /dev/null +++ b/Other versions/0.7/settings.html @@ -0,0 +1,42 @@ + + + + + Credits + + + + + + + +

Settings for BallsBalls

+

Made by Søren Oehlenschlæger Hjort

+ Uses Cookies To save +
+
+ + Input Method: + + +
+
+ + + + + + diff --git a/Other versions/0.9/To do.txt b/Other versions/0.9/To do.txt new file mode 100644 index 0000000..5cd0558 --- /dev/null +++ b/Other versions/0.9/To do.txt @@ -0,0 +1,53 @@ +/////////////////////////////////// +/////// New Objectives /////// +/////////////////////////////////// +**Iron out singlePage merging project** +Intro guide +Sound settings (done?) +Pause Game(done?) +Fix control method settings (done?) + +Start balancing, create a levers to control difficulty +/ change level progression +establish facade between game and animation + +powerup options +challenges +/////////////////////////////////// +//////// Old Stuff ///////// +/////////////////////////////////// +State concept +(gameState, + MenuState, + HighScoreState, + SettingsState +) + +Implement Menu properly +Settings in one page +Sound Settings +users + + +/////////////////////////////////// +//////// From mobile ///////// +/////////////////////////////////// + +Old TODO's: +Fix highscore submitting +reveal invis Ball on impact +fix text +lock when submitting +startsite +fjern størrelseforskelle (alt relativt) +Seeker ball fix loop + +Ideas: +Integrate/merge Pages/Single page'ify +Hints/Legends +Map (forhindringer) +samle ting (powerups) +Multiplayer (vs mode) +Webgl (the conversion) +Anti-mur ting (seeker is an idea) +Highscore board (+rework) \ No newline at end of file diff --git a/Other versions/0.9/index.html b/Other versions/0.9/index.html new file mode 100644 index 0000000..5315625 --- /dev/null +++ b/Other versions/0.9/index.html @@ -0,0 +1,26 @@ + + + + + BallsBalls + + + + + + + + +
+ + + \ No newline at end of file diff --git a/Other versions/0.9/scripts/Ball.js b/Other versions/0.9/scripts/Ball.js new file mode 100644 index 0000000..bd7f21d --- /dev/null +++ b/Other versions/0.9/scripts/Ball.js @@ -0,0 +1,35 @@ +define(["DrawFunctions","Calculations"],function(drawFunctions,Calculations) { +let Ball = function (startx,starty, vx, vy, radius,commonValues) { + this.x = startx; + this.y = starty; + this.radius = radius; + this.xd = Calculations.randomsign(); + this.yd = Calculations.randomsign(); + this.dx = vx; + this.dy = vy; + this.move = function() { + if ((this.x > commonValues.height-this.radius && this.xd > 0)|| (this.x < this.radius && this.xd < 0)) { + this.xd = -this.xd; + } + if ((this.y > commonValues.width-this.radius && this.yd > 0) || (this.y < this.radius && this.yd < 0)) { + this.yd = -this.yd; + } + + this.x = this.x + this.dx * this.xd; + this.y = this.y + this.dy * this.yd; + } + + this.shape = function() { + return new Calculations.circle(this.x,this.y,this.radius); + } + + this.draw = function(ctx) { + drawFunctions.drawBall(this.x, this.y, this.radius,ctx,"green"); + } +}; + + + + +return +}) \ No newline at end of file diff --git a/Other versions/0.9/scripts/Calculations.js b/Other versions/0.9/scripts/Calculations.js new file mode 100644 index 0000000..ae45bf7 --- /dev/null +++ b/Other versions/0.9/scripts/Calculations.js @@ -0,0 +1,114 @@ +define(function() { + return { + // Shape objects: + circle: function (x,y,radius) { + this.x = x; + this.y = y; + this.r = radius; + }, + + rectangle: + function rectangle(x,y,width,height) { + this.x = x; + this.y = y; + this.w = width; + this.h = height; + }, + + //distance calculator (between two points) + dist: function(x1,y1,x2,y2) { + return Math.sqrt(Math.pow(Math.abs(x1 - x2),2) + Math.pow(Math.abs(y1 - y2),2)); + }, + + + + randomsign: function () { + var i = this.random(0, 1); + if (i == 0) { + return -1; + } else { + return 1; + } + }, + + sign: function(i) { + if (i > 0) { + return 1; + } else if (i < 0) { + return -1; + } else { + return 0; + } + }, + + random: function(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + }, + + CircleCircleColliding: function(c1,c2) { + var dist = this.dist(c1.x , c1.y , c2.x , c2.y); + if (dist < Math.max(c1.r,c2.r)) { + return true; + } + return false; + }, + + RectRectColliding: function(r1,r2) { + var distX = Math.abs(r1.x + r1.w/2 - r2.x - r2.w/2); + var distY = Math.abs(r1.y + r1.h/2 - r2.y - r2.h/2); + + if (distX > (r1.w + r2.w)/2) { + return false; + } else if (distY > (r1.h + r2.h)/2) { + return false; + } else { + return true; + } + }, + + RectCircleColliding: function(circle,rect){ + var distX = Math.abs(circle.x - rect.x-rect.w/2); + var distY = Math.abs(circle.y - rect.y-rect.h/2); + + if (distX > (rect.w/2 + circle.r)) { return false; } + if (distY > (rect.h/2 + circle.r)) { return false; } + + if (distX <= (rect.w/2)) { return true; } + if (distY <= (rect.h/2)) { return true; } + + var dx=distX-rect.w/2; + var dy=distY-rect.h/2; + return (dx*dx+dy*dy<=(circle.r*circle.r)); + }, + + /** + * + * @param a the starting position + * @param b the end position + * @param max the maximum value (i.e. 360 for degrees in circle + * @returns {number} in {-1,0,1}, which direction is shortest + */ + shortestDirection: function (a, b, max) { + var ans; + if (b - a > max / 2) { + ans = b - a - max; + } else if (b - a > -max / 2) { + ans = b - a; + } else { + ans = b - a + max; + } + + if (ans > 0) { + return 1; + } else if (ans < 0) { + return -1; + } else { + return 0; + } + +} + + + + } +}) \ No newline at end of file diff --git a/Other versions/0.9/scripts/DrawFunctions.js b/Other versions/0.9/scripts/DrawFunctions.js new file mode 100644 index 0000000..c901ad7 --- /dev/null +++ b/Other versions/0.9/scripts/DrawFunctions.js @@ -0,0 +1,21 @@ +define(function() { +function drawBall(x,y,r,ctx,color) { + ctx.beginPath(); + ctx.arc(x, y, r, 0, Math.PI*2, false); + ctx.fillStyle = color; + ctx.fill(); + ctx.closePath(); +} + +function drawRect(x,y,w,h,ctx,color) { + ctx.beginPath(); + ctx.rect(x,y,w,h); + ctx.fillStyle = color; + ctx.fill(); + ctx.closePath(); +} +return { + drawBall: drawBall, + drawRect: drawRect +} +}) \ No newline at end of file diff --git a/Other versions/0.9/scripts/GameFlow.js b/Other versions/0.9/scripts/GameFlow.js new file mode 100644 index 0000000..701f796 --- /dev/null +++ b/Other versions/0.9/scripts/GameFlow.js @@ -0,0 +1,226 @@ +define(["GameValueHandler","Music","Calculations", +"Paddle","Ball","SeekerBall","StealthBall","Pickup" +],function(GameValueHandler,music,Calculations, +Paddle,Ball,SeekerBall ,StealthBall ,Pickup +) { +var canvas; +var gameState = new GameValueHandler(); +var myFont = "Arial" +var fillStyle = "#dd0095"; +var ctx +var p; +var objects; +var endFunc; +var timeLeft = 30; +var countervalue = 0; +var gracetimer = 0; +var grace = false; +var paused = false; + +var commonValues; + + function initiate(aCanvas,endFunction,ctrlHandler) { + canvas = aCanvas; + ctx = canvas.ctx; + endFunc = endFunction; + gameState.init(canvas.width, canvas.height); + timeLeft = 30; + countervalue = 0; + gracetimer = 0; + p = new Paddle(canvas.height/2, canvas.width/2, + gameState.playerLength,ctrlHandler, gameState.playerSpeed); + + commonValues = { + width: canvas.width, + height: canvas.height, + stealthBallticks: gameState.stealthBallticks, + p: p, + maxTurn: gameState.maxTurn + } + + objects = []; + + addPickUp(); + music.playMain(); + doTurn(); + } + +function doTurn() { + if (gameState.playerdead) { + endgame(); + return; + } else if (paused) { + return; + } + + //reset canvas + ctx.clearRect(0, 0, canvas.width, canvas.height); + + //text drawing + setFont(40); + ctx.fillText("Level: "+ gameState.level, 20, 20); + ctx.fillText("Squares Gathered: "+gameState.score, 20, 40); + ctx.fillText("Survive for: "+timeLeft, 20, 60); + + //grace text + if (grace) { + setFont(10); + ctx.fillText("Level Complete", canvas.width/4, canvas.height/4); + } + + //move player + p.move(); + p.draw(ctx); + + // check if pickup has been picked up + if (!grace) { + pickup.draw(ctx); + if (Calculations.RectRectColliding(p.shape(), pickup.shape())) { + addPickUp(); + gameState.score++; + } + } + + //move balls + for (var int = 0; int < objects.length; int++) { + var object = objects[int]; + + object.move(); + if (Calculations.RectCircleColliding(object.shape(), p.shape())) { + gameState.playerdead = true; + object.visible = true; + } + object.draw(ctx); + } + + //end of level + if (timeLeft == 0 && !grace) { + //Pause Music + music.playPause(); + //tick up level + gameState.levelup(); + //enter grace period + gracetimer = gameState.graceperiod; + grace = true; + //reset "game board" + objects = []; + pickup = null; + timeLeft = gameState.levelduration; + } + + //end of grace + if (grace && gracetimer == 0) { + grace = false; + //start Music Again + music.playMain(); + + addStealthBall(); + addSeekerBall(); + addPickUp(); + for (i = 0; i < gameState.initialballs; i++) { + addBall(); + } + } + + //grace countdown + else if (grace) { + gracetimer = gracetimer - 1; + } + + //level countdown + else if (count() && !(grace)) { + for (i = 0; i < gameState.ballspertick; i++) { + addBall(); + } + timeLeft--; + } + + requestAnimationFrame(doTurn); +} + +function setFont(quotent) { + ctx.font = (canvas.width/quotent)+"px " + myFont; + ctx.fillStyle = fillStyle; +} + + +//checks if addBall-tick has come (and counts up) +function count() { + countervalue++; + if (countervalue > gameState.tickperball) { + countervalue = 0; + return true; + } + return false; +} + +function addObject(object) { + //set starting position + var currentdist = 0; + let startx; + let starty; + while (currentdist < gameState.minDist) { + startx = Calculations.random(0, canvas.height); + starty = Calculations.random(0, canvas.width); + currentdist = Calculations.dist(startx, starty, p.x, p.y); + } + + //set speed + vx = Calculations.random(gameState.minBallspeed, gameState.maxBallspeed); + vy = Calculations.random(gameState.minBallspeed, gameState.maxBallspeed); + + //set size + radius = Calculations.random(gameState.minballRadius,gameState.maxballRadius); + + //add to ball list + let newObject = new object(startx, starty, vx, vy, radius,commonValues); + objects.push(newObject); + return newObject; +} + +function addBall() { + addObject(Ball); +} + +function addStealthBall() { + addObject(StealthBall); +} + +function addSeekerBall() { + addObject(SeekerBall); +} + +function addPickUp() { + //set position + let x; + let y; + var currentdist = 0; + while (currentdist < gameState.minDist) { + x = Calculations.random(gameState.pickupLength , canvas.height-gameState.pickupLength ); + y = Calculations.random(gameState.pickupLength , canvas.width-gameState.pickupLength ); + currentdist = Calculations.dist(x, y, p.x, p.y); + } + //add Pickup + pickup = new Pickup(x,y,gameState.pickupLength ); +} + +//ending the game, when player dies +function endgame() { + music.playGameOver(); + endFunc({score:gameState.score,level:gameState.level}); +} + +let pauseGameToggle = function() { + paused = !paused; + if (!paused) { + doTurn(); + } +}; + + +return { + initiateGame: initiate, + pauseGameToggle: pauseGameToggle +} + +}) \ No newline at end of file diff --git a/Other versions/0.9/scripts/GameValueHandler.js b/Other versions/0.9/scripts/GameValueHandler.js new file mode 100644 index 0000000..d3807ff --- /dev/null +++ b/Other versions/0.9/scripts/GameValueHandler.js @@ -0,0 +1,81 @@ +define(function() { + function dist(x1,y1,x2,y2) { + return Math.sqrt(Math.pow(Math.abs(x1 - x2),2) + Math.pow(Math.abs(y1 - y2),2)); + } + + +return function GameValueHandler() { + this.level = 1; + this.maxBallspeed; + this.minBallspeed; + this.maxballRadius; + this.minballRadius; + this.initialballs; //balls at the start of the level + this.levelduration; + this.tickperball; //how often new ball is created + this.ballspertick; //how many balls are created at once + this.basemaxBallspeed; + this.baseminBallspeed; + + this.durationTickUp = 5; + + this.baseForDurationIncrease = 0; + this.baseForSpeedIncrease = 2; + this.baseForBallsPerTickIncrease = 0; + this.baseForTicksPerBallDecrease = 3; + + this.ticksForDurationIncrease = 3; + this.ticksForSpeedIncrease = 4; + this.ticksForBallsPerTickIncrease = 5; + this.ticksForTicksPerBallDecrease = 5; + + this.levelup = function(){ + this.level++; + this.initialballs++; + if ((this.level % this.ticksForDurationIncrease) + this.baseForDurationIncrease == 0) { + this.levelduration += this.durationTickUp; + } + if ((this.level % this.ticksForSpeedIncrease) + this.baseForSpeedIncrease == 0) { + this.maxBallspeed += this.basemaxBallspeed; + this.minBallspeed += this.baseminBallspeed; + } + if ((this.level % this.baseForBallsPerTickIncrease) + this.baseForBallsPerTickIncrease == 0) { + this.ballspertick++; + } + if ((this.level % this.baseForTicksPerBallDecrease) + this.baseForTicksPerBallDecrease == 0) { + this.ticksperball--; + } + } + + + this.init = function(width,height) { + let averageSize = (Math.abs(width) + Math.abs(height)) / 2; + + this.playerLength = averageSize / 56; + this.playerSpeed = averageSize / 143; + this.pickupLength = averageSize / 50; + + this.minDist = dist(0,0,width,height) / 4; + + this.graceperiod = 100; + this.stealthBallticks = 100; + this.maxTurn = 0.03; + + this.playerdead = false; + this.scorenotsubmitted = true; + this.score = 0; + + this.level = 1; + this.basemaxBallspeed = averageSize / 200; + this.baseminBallspeed = averageSize / 1000; + this.maxBallspeed = this.basemaxBallspeed; + this.minBallspeed = this.baseminBallspeed; + this.maxballRadius = averageSize / 70; + this.minballRadius = averageSize / 200; + this.initialballs = 1; + this.levelduration = 30; + this.tickperball = 20; + this.ballspertick = 1; + } +} +}) \ No newline at end of file diff --git a/Other versions/0.9/scripts/Initialization.js b/Other versions/0.9/scripts/Initialization.js new file mode 100644 index 0000000..9d934d4 --- /dev/null +++ b/Other versions/0.9/scripts/Initialization.js @@ -0,0 +1,35 @@ +require(["menuState","State","settings"], function(menuState,State,settings) { + var canvas = {}; + var ctx; + var p; + var pickup; + var objects; + var height; + var width; + var mindist = 4; + var leaderboard; + var squared = true; + + init = function () { + + // Initialize canvas + canvas.dom = document.getElementById("myCanvas"); + canvas.ctx = canvas.dom.getContext("2d"); + + settings.init(); + + if (squared) { + let size = Math.min(window.innerWidth,window.innerHeight); + canvas.dom.width = canvas.height = size; + canvas.dom.height = canvas.width = size; + } else { + canvas.dom.width = canvas.height = window.innerWidth; + canvas.dom.height = canvas.width = window.innerHeight; + } + var controller = State.stateController(menuState,canvas); + }; + + init(); + +}); + diff --git a/Other versions/0.9/scripts/Leaderboard.js b/Other versions/0.9/scripts/Leaderboard.js new file mode 100644 index 0000000..76e7fe9 --- /dev/null +++ b/Other versions/0.9/scripts/Leaderboard.js @@ -0,0 +1,62 @@ +define(function() { +let firebaseURI = "https://leaderboard-bf98b.firebaseio.com"; + + var config = { + apiKey: "AIzaSyDnQy8gUVUldROZM3hxjg2_M3FE7Yg_cSc", + authDomain: "leaderboard-bf98b.firebaseapp.com", + databaseURL: "https://leaderboard-bf98b.firebaseio.com", + storageBucket: "leaderboard-bf98b.appspot.com", + }; + firebase.initializeApp(config); + +let Leaderboard = function(){ + this.firebase = firebase.database(); + this.firebase.ref("scores").orderByChild("score").limitToLast(5).on("value", (value) => { + this.scores = value.val() + }); + + + this.add = function(data) { + this.firebase.ref("scores").push(data).setPriority(data.score) + }; + + /* + * assumed that data is valid + */ + this.addandgo = function(data,go) { + this.firebase.ref("scores").push(data).setPriority(data.score).then(go, function(){ + console.log("fail"); + }); + }; + + this.get = function() { + throw new Error("this shouldn't happen"); + var list = []; + var running = true; + this.firebase.ref("scores").orderByChild("score").once("value").then( + function(snapshot) { + snapshot.forEach(function(childSnapshot) { + list.push(childSnapshot.val()); + }) + running = false; + }); + }; + + this.getandgo = function(go,limit) { + let query = this.firebase.ref("scores").orderByChild("score"); + if (limit!=null) { + query = query.limitToLast(limit); + } + query.once("value").then( + function(snapshot) { + let list = []; + snapshot.forEach(function(childSnapshot) { + list.push(childSnapshot.val()); + }); + go(list); + }); + }; +}; + +return new Leaderboard(); +}); \ No newline at end of file diff --git a/Other versions/0.9/scripts/Music.js b/Other versions/0.9/scripts/Music.js new file mode 100644 index 0000000..cf3531b --- /dev/null +++ b/Other versions/0.9/scripts/Music.js @@ -0,0 +1,55 @@ +define(["settings"],function(settings) { +var music = new Music(); + +function Music() { + this.audio = new Audio('soundFiles/Retro.wav'); + this.audio.loop = true; + this.sounds = new Audio(); + this.muted = false; + + this.playMain = function() { + if (!this.muted) { + this.audio.volume = settings.soundLevel; + } + this.sounds.pause(); + this.audio.play(); + } + + this.playGameOver = function() { + this.audio.pause(); + this.sounds.src = 'soundFiles/gameOver2.wav'; + this.sounds.play(); + } + + this.playPause = function() { + this.audio.pause(); + } + + this.pause = function() { + this.audio.pause(); + } + + this.stop = function() { + this.audio.pause(); + } + + this.toggleMute = function() { + if (this.muted) { + this.audio.volume = settings.soundLevel; + } else { + this.audio.volume = 0; + } + this.muted = !this.muted; + } + +// this.setVolume = function(value) { +// this.audio.volume = value; +// } + + this.changeVolume = function(change) { + this.audio.volume += value; + } +} + +return music; +}) diff --git a/Other versions/0.9/scripts/Paddle.js b/Other versions/0.9/scripts/Paddle.js new file mode 100644 index 0000000..da89dc2 --- /dev/null +++ b/Other versions/0.9/scripts/Paddle.js @@ -0,0 +1,19 @@ +define(["DrawFunctions","Calculations"],function(drawFunctions,Calculations) { +return function Paddle(ax,ay,length,controller,playerSpeed) { + this.x = ax; + this.y = ay; + this.width = length; + this.height = length; + this.move = function(nx,ny) { + controller.playerControl(this,playerSpeed); + } + + this.shape = function(){ + return new Calculations.rectangle(this.x,this.y,this.width,this.height); + } + + this.draw = function(ctx) { + drawFunctions.drawRect(this.x, this.y, this.width, this.height,ctx,"#0095DD"); + } +} +}) \ No newline at end of file diff --git a/Other versions/0.9/scripts/Pickup.js b/Other versions/0.9/scripts/Pickup.js new file mode 100644 index 0000000..e6ee14b --- /dev/null +++ b/Other versions/0.9/scripts/Pickup.js @@ -0,0 +1,16 @@ +define(["DrawFunctions","Calculations"],function(drawFunctions,Calculations) { + return function Pickup(x,y,length) { + this.x = x; + this.y = y; + this.width = length; + this.height = length; + + this.shape = function(){ + return new Calculations.rectangle(this.x,this.y,this.width,this.height); + } + + this.draw = function(ctx) { + drawFunctions.drawRect(this.x, this.y, this.width, this.height,ctx,"#FFA500"); + } + } +}) \ No newline at end of file diff --git a/Other versions/0.9/scripts/SeekerBall.js b/Other versions/0.9/scripts/SeekerBall.js new file mode 100644 index 0000000..47e84a1 --- /dev/null +++ b/Other versions/0.9/scripts/SeekerBall.js @@ -0,0 +1,39 @@ +define(["DrawFunctions","Calculations","Ball"],function(drawFunctions,Calculations,Ball) { + +return function SeekerBall(startx,starty, vx, vy, radius,commonValues) { + this.target = commonValues.p; + this.base = new Ball(startx,starty, vx, vy, radius,commonValues); + this.speed = (Math.abs(this.base.dx) + Math.abs(this.base.dy)) / 2; + this.currentDirection = 0; + + this.move = function() { + this.determineDirection(); + this.base.x -= this.speed * Math.cos(this.currentDirection); + this.base.y -= this.speed * Math.sin(this.currentDirection); + }; + + this.determineDirection = function() { + DesiredDirection = Math.atan2((this.target.y - this.base.y) , (this.target.x - this.base.x)) + Math.PI; + /* if (this.currentDirection < 0) { + this.currentDirection = (2*Math.PI) - this.currentDirection; + } else if (this.currentDirection > (2*Math.PI)) { + this.currentDirection %= (2*Math.PI); + } + */ + let change = this.currentDirection-DesiredDirection; + if (Math.abs(change) height) { + object.x = height-object.height; + } + + if (object.y < 0) { + object.y = 0; + } else if (object.y + object.width > width) { + object.y = width-object.width; + } + } + + this.keyDown = function(e) { + if(e.keyCode == settings.downKey) { + downPressed = true; + } else if(e.keyCode == settings.rightKey) { + rightPressed = true; + } else if(e.keyCode == settings.upKey) { + upPressed = true; + } else if(e.keyCode == settings.leftKey) { + leftPressed = true; + } else if(e.keyCode == settings.muteKey) { + music.toggleMute(); + } else if(e.keyCode == settings.pauseKey) { + game.pauseGameToggle(); + } + } + + this.keyUp = function(e) { + if(e.keyCode == settings.downKey) { + downPressed = false; + } + else if(e.keyCode == settings.rightKey) { + rightPressed = false; + } + else if(e.keyCode == settings.upKey) { + upPressed = false; + } + else if(e.keyCode == settings.leftKey) { + leftPressed = false; + } + } + this.playerControl = keyboardControl; + } + return gameControlHandler; +}) \ No newline at end of file diff --git a/Other versions/0.9/scripts/gameState.js b/Other versions/0.9/scripts/gameState.js new file mode 100644 index 0000000..5b0adf4 --- /dev/null +++ b/Other versions/0.9/scripts/gameState.js @@ -0,0 +1,23 @@ +define(["GameFlow","settings", "gameControlHandler"], +function(gameflow,settings,gameControlHandler) { + + function gameState(controller,canvas) { + settings.updateSettings(); + let gameCtrlHandler = new gameControlHandler(canvas.width, canvas.height); + this.init = function() { + canvas.dom.style.display = "block"; + gameflow.initiateGame(canvas, + function(gameData){controller.changeState("submitScoreState",gameData)} + ,gameCtrlHandler); + } + this.end = function() { + canvas.dom.style.display = "none"; + } + this.keydownHandler = gameCtrlHandler.keyDown; + this.keyupHandler = gameCtrlHandler.keyUp; + } + + return { + gameState: gameState + } +}); \ No newline at end of file diff --git a/Other versions/0.9/scripts/highScoreState.js b/Other versions/0.9/scripts/highScoreState.js new file mode 100644 index 0000000..80b0bc1 --- /dev/null +++ b/Other versions/0.9/scripts/highScoreState.js @@ -0,0 +1,52 @@ +define(["Leaderboard"],function(leaderboard) { + let site = '
Rank Name Level Score (Squares Gathered) Control Method

'; + let outerDiv = document.getElementById("outerDiv"); + + let highscoreState = function (controller,values) { + this.init = function() { + outerDiv.innerHTML = site; + document.getElementById("returnToMenu").addEventListener("click", + function() { + controller.changeState("menuState"); + }); + leaderboard.getandgo(function(list) { + let table = document.getElementById("items"); + var index, len; + for (index = Math.min(list.length-1,10), len = 0; index >= len; --index) { + addRow(table,list[index]); + } + }, 10); + } + + this.end = function() { + outerDiv.innerHTML = ""; + } + + this.keydownHandler = function(e) { + if (e.keyCode == 77) { // m + controller.changeState("menuState"); + } + } + this.keyupHandler = function(e) { + } + } + + function addRow(table, data) { //adding a simple row + var rownumber = table.rows.length; + var row = table.insertRow(rownumber); + + var cell1 = row.insertCell(0); + var cell2 = row.insertCell(1); + var cell3 = row.insertCell(2); + var cell4 = row.insertCell(3); + var cell5 = row.insertCell(4); + + cell1.innerHTML = rownumber; + cell2.innerHTML = data.name; + cell3.innerHTML = data.level; + cell4.innerHTML = data.score; + cell5.innerHTML = data.method; + } + + return highscoreState; +}); \ No newline at end of file diff --git a/Other versions/0.9/scripts/menuState.js b/Other versions/0.9/scripts/menuState.js new file mode 100644 index 0000000..52b5dd2 --- /dev/null +++ b/Other versions/0.9/scripts/menuState.js @@ -0,0 +1,61 @@ +define(["settings"],function(settings) { + var myFont = "Arial" + var fillStyle = "green"; + var keyStateMap = {}; + keyStateMap[settings.restartKey] = "gameState"; + keyStateMap[settings.settingsKey] = "settingsState"; + keyStateMap[settings.highscoreKey] = "highscoreState"; + + function setMenuText(canvas) { + //reset canvas + canvas.ctx.clearRect(0, 0, canvas.width, canvas.height); + setFont(canvas,5); + + canvas.ctx.fillText("BallsBalls", canvas.width/15, canvas.height/4); + + setFont(canvas,15); + //text drawing + let displayWidth = canvas.width/10; + let displayHeight = canvas.height/2; + let heightOffset = canvas.width/12; + + canvas.ctx.fillText("Press Space to Play Game", displayWidth, displayHeight); + canvas.ctx.fillText("Press i for settings", displayWidth, displayHeight+heightOffset*1); + canvas.ctx.fillText("Press h for Leaderboard", displayWidth, displayHeight+heightOffset*2); + } + + function setFont(canvas,quotent) { + canvas.ctx.font = (canvas.width/quotent)+"px " + myFont; + canvas.ctx.fillStyle = fillStyle; + } + + function menuState(controller,canvas) { + + this.init = function() { + canvas.dom.style.display = "block"; + setMenuText(canvas); + + } + this.end = function() { + canvas.dom.style.display = "none"; + } + + this.keydownHandler = function(e) { + let change = keyStateMap[e.keyCode]; + if(change!=null) { + controller.changeState(change); + } + } + this.keyupHandler = function(e) { + } + } + + return menuState; + +}); + + + + + + diff --git a/Other versions/0.9/scripts/require.js b/Other versions/0.9/scripts/require.js new file mode 100644 index 0000000..c32e6c1 --- /dev/null +++ b/Other versions/0.9/scripts/require.js @@ -0,0 +1,5 @@ +/** vim: et:ts=4:sw=4:sts=4 + * @license RequireJS 2.3.3 Copyright jQuery Foundation and other contributors. + * Released under MIT license, https://github.com/requirejs/requirejs/blob/master/LICENSE + */ +var requirejs,require,define;!function(global,setTimeout){function commentReplace(e,t){return t||""}function isFunction(e){return"[object Function]"===ostring.call(e)}function isArray(e){return"[object Array]"===ostring.call(e)}function each(e,t){if(e){var i;for(i=0;i-1&&(!e[i]||!t(e[i],i,e));i-=1);}}function hasProp(e,t){return hasOwn.call(e,t)}function getOwn(e,t){return hasProp(e,t)&&e[t]}function eachProp(e,t){var i;for(i in e)if(hasProp(e,i)&&t(e[i],i))break}function mixin(e,t,i,r){return t&&eachProp(t,function(t,n){!i&&hasProp(e,n)||(!r||"object"!=typeof t||!t||isArray(t)||isFunction(t)||t instanceof RegExp?e[n]=t:(e[n]||(e[n]={}),mixin(e[n],t,i,r)))}),e}function bind(e,t){return function(){return t.apply(e,arguments)}}function scripts(){return document.getElementsByTagName("script")}function defaultOnError(e){throw e}function getGlobal(e){if(!e)return e;var t=global;return each(e.split("."),function(e){t=t[e]}),t}function makeError(e,t,i,r){var n=new Error(t+"\nhttp://requirejs.org/docs/errors.html#"+e);return n.requireType=e,n.requireModules=r,i&&(n.originalError=i),n}function newContext(e){function t(e){var t,i;for(t=0;t0&&(e.splice(t-1,2),t-=2)}}function i(e,i,r){var n,o,a,s,u,c,d,p,f,l,h,m,g=i&&i.split("/"),v=y.map,x=v&&v["*"];if(e&&(e=e.split("/"),d=e.length-1,y.nodeIdCompat&&jsSuffixRegExp.test(e[d])&&(e[d]=e[d].replace(jsSuffixRegExp,"")),"."===e[0].charAt(0)&&g&&(m=g.slice(0,g.length-1),e=m.concat(e)),t(e),e=e.join("/")),r&&v&&(g||x)){a=e.split("/");e:for(s=a.length;s>0;s-=1){if(c=a.slice(0,s).join("/"),g)for(u=g.length;u>0;u-=1)if(o=getOwn(v,g.slice(0,u).join("/")),o&&(o=getOwn(o,c))){p=o,f=s;break e}!l&&x&&getOwn(x,c)&&(l=getOwn(x,c),h=s)}!p&&l&&(p=l,f=h),p&&(a.splice(0,f,p),e=a.join("/"))}return n=getOwn(y.pkgs,e),n?n:e}function r(e){isBrowser&&each(scripts(),function(t){if(t.getAttribute("data-requiremodule")===e&&t.getAttribute("data-requirecontext")===q.contextName)return t.parentNode.removeChild(t),!0})}function n(e){var t=getOwn(y.paths,e);if(t&&isArray(t)&&t.length>1)return t.shift(),q.require.undef(e),q.makeRequire(null,{skipMap:!0})([e]),!0}function o(e){var t,i=e?e.indexOf("!"):-1;return i>-1&&(t=e.substring(0,i),e=e.substring(i+1,e.length)),[t,e]}function a(e,t,r,n){var a,s,u,c,d=null,p=t?t.name:null,f=e,l=!0,h="";return e||(l=!1,e="_@r"+(T+=1)),c=o(e),d=c[0],e=c[1],d&&(d=i(d,p,n),s=getOwn(j,d)),e&&(d?h=r?e:s&&s.normalize?s.normalize(e,function(e){return i(e,p,n)}):e.indexOf("!")===-1?i(e,p,n):e:(h=i(e,p,n),c=o(h),d=c[0],h=c[1],r=!0,a=q.nameToUrl(h))),u=!d||s||r?"":"_unnormalized"+(A+=1),{prefix:d,name:h,parentMap:t,unnormalized:!!u,url:a,originalName:f,isDefine:l,id:(d?d+"!"+h:h)+u}}function s(e){var t=e.id,i=getOwn(S,t);return i||(i=S[t]=new q.Module(e)),i}function u(e,t,i){var r=e.id,n=getOwn(S,r);!hasProp(j,r)||n&&!n.defineEmitComplete?(n=s(e),n.error&&"error"===t?i(n.error):n.on(t,i)):"defined"===t&&i(j[r])}function c(e,t){var i=e.requireModules,r=!1;t?t(e):(each(i,function(t){var i=getOwn(S,t);i&&(i.error=e,i.events.error&&(r=!0,i.emit("error",e)))}),r||req.onError(e))}function d(){globalDefQueue.length&&(each(globalDefQueue,function(e){var t=e[0];"string"==typeof t&&(q.defQueueMap[t]=!0),O.push(e)}),globalDefQueue=[])}function p(e){delete S[e],delete k[e]}function f(e,t,i){var r=e.map.id;e.error?e.emit("error",e.error):(t[r]=!0,each(e.depMaps,function(r,n){var o=r.id,a=getOwn(S,o);!a||e.depMatched[n]||i[o]||(getOwn(t,o)?(e.defineDep(n,j[o]),e.check()):f(a,t,i))}),i[r]=!0)}function l(){var e,t,i=1e3*y.waitSeconds,o=i&&q.startTime+i<(new Date).getTime(),a=[],s=[],u=!1,d=!0;if(!x){if(x=!0,eachProp(k,function(e){var i=e.map,c=i.id;if(e.enabled&&(i.isDefine||s.push(e),!e.error))if(!e.inited&&o)n(c)?(t=!0,u=!0):(a.push(c),r(c));else if(!e.inited&&e.fetched&&i.isDefine&&(u=!0,!i.prefix))return d=!1}),o&&a.length)return e=makeError("timeout","Load timeout for modules: "+a,null,a),e.contextName=q.contextName,c(e);d&&each(s,function(e){f(e,{},{})}),o&&!t||!u||!isBrowser&&!isWebWorker||w||(w=setTimeout(function(){w=0,l()},50)),x=!1}}function h(e){hasProp(j,e[0])||s(a(e[0],null,!0)).init(e[1],e[2])}function m(e,t,i,r){e.detachEvent&&!isOpera?r&&e.detachEvent(r,t):e.removeEventListener(i,t,!1)}function g(e){var t=e.currentTarget||e.srcElement;return m(t,q.onScriptLoad,"load","onreadystatechange"),m(t,q.onScriptError,"error"),{node:t,id:t&&t.getAttribute("data-requiremodule")}}function v(){var e;for(d();O.length;){if(e=O.shift(),null===e[0])return c(makeError("mismatch","Mismatched anonymous define() module: "+e[e.length-1]));h(e)}q.defQueueMap={}}var x,b,q,E,w,y={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},S={},k={},M={},O=[],j={},P={},R={},T=1,A=1;return E={require:function(e){return e.require?e.require:e.require=q.makeRequire(e.map)},exports:function(e){if(e.usingExports=!0,e.map.isDefine)return e.exports?j[e.map.id]=e.exports:e.exports=j[e.map.id]={}},module:function(e){return e.module?e.module:e.module={id:e.map.id,uri:e.map.url,config:function(){return getOwn(y.config,e.map.id)||{}},exports:e.exports||(e.exports={})}}},b=function(e){this.events=getOwn(M,e.id)||{},this.map=e,this.shim=getOwn(y.shim,e.id),this.depExports=[],this.depMaps=[],this.depMatched=[],this.pluginMaps={},this.depCount=0},b.prototype={init:function(e,t,i,r){r=r||{},this.inited||(this.factory=t,i?this.on("error",i):this.events.error&&(i=bind(this,function(e){this.emit("error",e)})),this.depMaps=e&&e.slice(0),this.errback=i,this.inited=!0,this.ignore=r.ignore,r.enabled||this.enabled?this.enable():this.check())},defineDep:function(e,t){this.depMatched[e]||(this.depMatched[e]=!0,this.depCount-=1,this.depExports[e]=t)},fetch:function(){if(!this.fetched){this.fetched=!0,q.startTime=(new Date).getTime();var e=this.map;return this.shim?void q.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],bind(this,function(){return e.prefix?this.callPlugin():this.load()})):e.prefix?this.callPlugin():this.load()}},load:function(){var e=this.map.url;P[e]||(P[e]=!0,q.load(this.map.id,e))},check:function(){if(this.enabled&&!this.enabling){var e,t,i=this.map.id,r=this.depExports,n=this.exports,o=this.factory;if(this.inited){if(this.error)this.emit("error",this.error);else if(!this.defining){if(this.defining=!0,this.depCount<1&&!this.defined){if(isFunction(o)){if(this.events.error&&this.map.isDefine||req.onError!==defaultOnError)try{n=q.execCb(i,o,r,n)}catch(t){e=t}else n=q.execCb(i,o,r,n);if(this.map.isDefine&&void 0===n&&(t=this.module,t?n=t.exports:this.usingExports&&(n=this.exports)),e)return e.requireMap=this.map,e.requireModules=this.map.isDefine?[this.map.id]:null,e.requireType=this.map.isDefine?"define":"require",c(this.error=e)}else n=o;if(this.exports=n,this.map.isDefine&&!this.ignore&&(j[i]=n,req.onResourceLoad)){var a=[];each(this.depMaps,function(e){a.push(e.normalizedMap||e)}),req.onResourceLoad(q,this.map,a)}p(i),this.defined=!0}this.defining=!1,this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else hasProp(q.defQueueMap,i)||this.fetch()}},callPlugin:function(){var e=this.map,t=e.id,r=a(e.prefix);this.depMaps.push(r),u(r,"defined",bind(this,function(r){var n,o,d,f=getOwn(R,this.map.id),l=this.map.name,h=this.map.parentMap?this.map.parentMap.name:null,m=q.makeRequire(e.parentMap,{enableBuildCallback:!0});return this.map.unnormalized?(r.normalize&&(l=r.normalize(l,function(e){return i(e,h,!0)})||""),o=a(e.prefix+"!"+l,this.map.parentMap,!0),u(o,"defined",bind(this,function(e){this.map.normalizedMap=o,this.init([],function(){return e},null,{enabled:!0,ignore:!0})})),d=getOwn(S,o.id),void(d&&(this.depMaps.push(o),this.events.error&&d.on("error",bind(this,function(e){this.emit("error",e)})),d.enable()))):f?(this.map.url=q.nameToUrl(f),void this.load()):(n=bind(this,function(e){this.init([],function(){return e},null,{enabled:!0})}),n.error=bind(this,function(e){this.inited=!0,this.error=e,e.requireModules=[t],eachProp(S,function(e){0===e.map.id.indexOf(t+"_unnormalized")&&p(e.map.id)}),c(e)}),n.fromText=bind(this,function(i,r){var o=e.name,u=a(o),d=useInteractive;r&&(i=r),d&&(useInteractive=!1),s(u),hasProp(y.config,t)&&(y.config[o]=y.config[t]);try{req.exec(i)}catch(e){return c(makeError("fromtexteval","fromText eval for "+t+" failed: "+e,e,[t]))}d&&(useInteractive=!0),this.depMaps.push(u),q.completeLoad(o),m([o],n)}),void r.load(e.name,m,n,y))})),q.enable(r,this),this.pluginMaps[r.id]=r},enable:function(){k[this.map.id]=this,this.enabled=!0,this.enabling=!0,each(this.depMaps,bind(this,function(e,t){var i,r,n;if("string"==typeof e){if(e=a(e,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap),this.depMaps[t]=e,n=getOwn(E,e.id))return void(this.depExports[t]=n(this));this.depCount+=1,u(e,"defined",bind(this,function(e){this.undefed||(this.defineDep(t,e),this.check())})),this.errback?u(e,"error",bind(this,this.errback)):this.events.error&&u(e,"error",bind(this,function(e){this.emit("error",e)}))}i=e.id,r=S[i],hasProp(E,i)||!r||r.enabled||q.enable(e,this)})),eachProp(this.pluginMaps,bind(this,function(e){var t=getOwn(S,e.id);t&&!t.enabled&&q.enable(e,this)})),this.enabling=!1,this.check()},on:function(e,t){var i=this.events[e];i||(i=this.events[e]=[]),i.push(t)},emit:function(e,t){each(this.events[e],function(e){e(t)}),"error"===e&&delete this.events[e]}},q={config:y,contextName:e,registry:S,defined:j,urlFetched:P,defQueue:O,defQueueMap:{},Module:b,makeModuleMap:a,nextTick:req.nextTick,onError:c,configure:function(e){if(e.baseUrl&&"/"!==e.baseUrl.charAt(e.baseUrl.length-1)&&(e.baseUrl+="/"),"string"==typeof e.urlArgs){var t=e.urlArgs;e.urlArgs=function(e,i){return(i.indexOf("?")===-1?"?":"&")+t}}var i=y.shim,r={paths:!0,bundles:!0,config:!0,map:!0};eachProp(e,function(e,t){r[t]?(y[t]||(y[t]={}),mixin(y[t],e,!0,!0)):y[t]=e}),e.bundles&&eachProp(e.bundles,function(e,t){each(e,function(e){e!==t&&(R[e]=t)})}),e.shim&&(eachProp(e.shim,function(e,t){isArray(e)&&(e={deps:e}),!e.exports&&!e.init||e.exportsFn||(e.exportsFn=q.makeShimExports(e)),i[t]=e}),y.shim=i),e.packages&&each(e.packages,function(e){var t,i;e="string"==typeof e?{name:e}:e,i=e.name,t=e.location,t&&(y.paths[i]=e.location),y.pkgs[i]=e.name+"/"+(e.main||"main").replace(currDirRegExp,"").replace(jsSuffixRegExp,"")}),eachProp(S,function(e,t){e.inited||e.map.unnormalized||(e.map=a(t,null,!0))}),(e.deps||e.callback)&&q.require(e.deps||[],e.callback)},makeShimExports:function(e){function t(){var t;return e.init&&(t=e.init.apply(global,arguments)),t||e.exports&&getGlobal(e.exports)}return t},makeRequire:function(t,n){function o(i,r,u){var d,p,f;return n.enableBuildCallback&&r&&isFunction(r)&&(r.__requireJsBuild=!0),"string"==typeof i?isFunction(r)?c(makeError("requireargs","Invalid require call"),u):t&&hasProp(E,i)?E[i](S[t.id]):req.get?req.get(q,i,t,o):(p=a(i,t,!1,!0),d=p.id,hasProp(j,d)?j[d]:c(makeError("notloaded",'Module name "'+d+'" has not been loaded yet for context: '+e+(t?"":". Use require([])")))):(v(),q.nextTick(function(){v(),f=s(a(null,t)),f.skipMap=n.skipMap,f.init(i,r,u,{enabled:!0}),l()}),o)}return n=n||{},mixin(o,{isBrowser:isBrowser,toUrl:function(e){var r,n=e.lastIndexOf("."),o=e.split("/")[0],a="."===o||".."===o;return n!==-1&&(!a||n>1)&&(r=e.substring(n,e.length),e=e.substring(0,n)),q.nameToUrl(i(e,t&&t.id,!0),r,!0)},defined:function(e){return hasProp(j,a(e,t,!1,!0).id)},specified:function(e){return e=a(e,t,!1,!0).id,hasProp(j,e)||hasProp(S,e)}}),t||(o.undef=function(e){d();var i=a(e,t,!0),n=getOwn(S,e);n.undefed=!0,r(e),delete j[e],delete P[i.url],delete M[e],eachReverse(O,function(t,i){t[0]===e&&O.splice(i,1)}),delete q.defQueueMap[e],n&&(n.events.defined&&(M[e]=n.events),p(e))}),o},enable:function(e){var t=getOwn(S,e.id);t&&s(e).enable()},completeLoad:function(e){var t,i,r,o=getOwn(y.shim,e)||{},a=o.exports;for(d();O.length;){if(i=O.shift(),null===i[0]){if(i[0]=e,t)break;t=!0}else i[0]===e&&(t=!0);h(i)}if(q.defQueueMap={},r=getOwn(S,e),!t&&!hasProp(j,e)&&r&&!r.inited){if(!(!y.enforceDefine||a&&getGlobal(a)))return n(e)?void 0:c(makeError("nodefine","No define call for "+e,null,[e]));h([e,o.deps||[],o.exportsFn])}l()},nameToUrl:function(e,t,i){var r,n,o,a,s,u,c,d=getOwn(y.pkgs,e);if(d&&(e=d),c=getOwn(R,e))return q.nameToUrl(c,t,i);if(req.jsExtRegExp.test(e))s=e+(t||"");else{for(r=y.paths,n=e.split("/"),o=n.length;o>0;o-=1)if(a=n.slice(0,o).join("/"),u=getOwn(r,a)){isArray(u)&&(u=u[0]),n.splice(0,o,u);break}s=n.join("/"),s+=t||(/^data\:|^blob\:|\?/.test(s)||i?"":".js"),s=("/"===s.charAt(0)||s.match(/^[\w\+\.\-]+:/)?"":y.baseUrl)+s}return y.urlArgs&&!/^blob\:/.test(s)?s+y.urlArgs(e,s):s},load:function(e,t){req.load(q,e,t)},execCb:function(e,t,i,r){return t.apply(r,i)},onScriptLoad:function(e){if("load"===e.type||readyRegExp.test((e.currentTarget||e.srcElement).readyState)){interactiveScript=null;var t=g(e);q.completeLoad(t.id)}},onScriptError:function(e){var t=g(e);if(!n(t.id)){var i=[];return eachProp(S,function(e,r){0!==r.indexOf("_@r")&&each(e.depMaps,function(e){if(e.id===t.id)return i.push(r),!0})}),c(makeError("scripterror",'Script error for "'+t.id+(i.length?'", needed by: '+i.join(", "):'"'),e,[t.id]))}}},q.require=q.makeRequire(),q}function getInteractiveScript(){return interactiveScript&&"interactive"===interactiveScript.readyState?interactiveScript:(eachReverse(scripts(),function(e){if("interactive"===e.readyState)return interactiveScript=e}),interactiveScript)}var req,s,head,baseElement,dataMain,src,interactiveScript,currentlyAddingScript,mainScript,subPath,version="2.3.3",commentRegExp=/\/\*[\s\S]*?\*\/|([^:"'=]|^)\/\/.*$/gm,cjsRequireRegExp=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,jsSuffixRegExp=/\.js$/,currDirRegExp=/^\.\//,op=Object.prototype,ostring=op.toString,hasOwn=op.hasOwnProperty,isBrowser=!("undefined"==typeof window||"undefined"==typeof navigator||!window.document),isWebWorker=!isBrowser&&"undefined"!=typeof importScripts,readyRegExp=isBrowser&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,defContextName="_",isOpera="undefined"!=typeof opera&&"[object Opera]"===opera.toString(),contexts={},cfg={},globalDefQueue=[],useInteractive=!1;if("undefined"==typeof define){if("undefined"!=typeof requirejs){if(isFunction(requirejs))return;cfg=requirejs,requirejs=void 0}"undefined"==typeof require||isFunction(require)||(cfg=require,require=void 0),req=requirejs=function(e,t,i,r){var n,o,a=defContextName;return isArray(e)||"string"==typeof e||(o=e,isArray(t)?(e=t,t=i,i=r):e=[]),o&&o.context&&(a=o.context),n=getOwn(contexts,a),n||(n=contexts[a]=req.s.newContext(a)),o&&n.configure(o),n.require(e,t,i)},req.config=function(e){return req(e)},req.nextTick="undefined"!=typeof setTimeout?function(e){setTimeout(e,4)}:function(e){e()},require||(require=req),req.version=version,req.jsExtRegExp=/^\/|:|\?|\.js$/,req.isBrowser=isBrowser,s=req.s={contexts:contexts,newContext:newContext},req({}),each(["toUrl","undef","defined","specified"],function(e){req[e]=function(){var t=contexts[defContextName];return t.require[e].apply(t,arguments)}}),isBrowser&&(head=s.head=document.getElementsByTagName("head")[0],baseElement=document.getElementsByTagName("base")[0],baseElement&&(head=s.head=baseElement.parentNode)),req.onError=defaultOnError,req.createNode=function(e,t,i){var r=e.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script");return r.type=e.scriptType||"text/javascript",r.charset="utf-8",r.async=!0,r},req.load=function(e,t,i){var r,n=e&&e.config||{};if(isBrowser)return r=req.createNode(n,t,i),r.setAttribute("data-requirecontext",e.contextName),r.setAttribute("data-requiremodule",t),!r.attachEvent||r.attachEvent.toString&&r.attachEvent.toString().indexOf("[native code")<0||isOpera?(r.addEventListener("load",e.onScriptLoad,!1),r.addEventListener("error",e.onScriptError,!1)):(useInteractive=!0,r.attachEvent("onreadystatechange",e.onScriptLoad)),r.src=i,n.onNodeCreated&&n.onNodeCreated(r,n,t,i),currentlyAddingScript=r,baseElement?head.insertBefore(r,baseElement):head.appendChild(r),currentlyAddingScript=null,r;if(isWebWorker)try{setTimeout(function(){},0),importScripts(i),e.completeLoad(t)}catch(r){e.onError(makeError("importscripts","importScripts failed for "+t+" at "+i,r,[t]))}},isBrowser&&!cfg.skipDataMain&&eachReverse(scripts(),function(e){if(head||(head=e.parentNode),dataMain=e.getAttribute("data-main"))return mainScript=dataMain,cfg.baseUrl||mainScript.indexOf("!")!==-1||(src=mainScript.split("/"),mainScript=src.pop(),subPath=src.length?src.join("/")+"/":"./",cfg.baseUrl=subPath),mainScript=mainScript.replace(jsSuffixRegExp,""),req.jsExtRegExp.test(mainScript)&&(mainScript=dataMain),cfg.deps=cfg.deps?cfg.deps.concat(mainScript):[mainScript],!0}),define=function(e,t,i){var r,n;"string"!=typeof e&&(i=t,t=e,e=null),isArray(t)||(i=t,t=null),!t&&isFunction(i)&&(t=[],i.length&&(i.toString().replace(commentRegExp,commentReplace).replace(cjsRequireRegExp,function(e,i){t.push(i)}),t=(1===i.length?["require"]:["require","exports","module"]).concat(t))),useInteractive&&(r=currentlyAddingScript||getInteractiveScript(),r&&(e||(e=r.getAttribute("data-requiremodule")),n=contexts[r.getAttribute("data-requirecontext")])),n?(n.defQueue.push([e,t,i]),n.defQueueMap[e]=!0):globalDefQueue.push([e,t,i])},define.amd={jQuery:!0},req.exec=function(text){return eval(text)},req(cfg)}}(this,"undefined"==typeof setTimeout?void 0:setTimeout); \ No newline at end of file diff --git a/Other versions/0.9/scripts/settings.js b/Other versions/0.9/scripts/settings.js new file mode 100644 index 0000000..87a95b5 --- /dev/null +++ b/Other versions/0.9/scripts/settings.js @@ -0,0 +1,75 @@ +define([],function() { +//Thanks http://www.w3schools.com/js/js_cookies.asp +var settings = { + upKey: 38, + rightKey: 39, + leftKey: 37, + downKey: 40, + + restartKey: 32, //spacebar + settingsKey: 73, // i + highscoreKey: 72, // h + SubmitKey: 13, //enter + muteKey: 77, // m + pauseKey: 80, // m + + controlMethod: "Arrow Keys", + autoSubmit: false, + playerAutoName: "", + + setSetting: setCookie, + getSetting: getCookie, + updateSettings: updateSettings, + init: updateSettings +} + +function setCookie(c_name,c_value,exdays) { + settings[c_name] = c_value; + var exdate=new Date(); + exdate.setDate(exdate.getDate() + exdays); + document.cookie=encodeURIComponent(c_name) + + "=" + encodeURIComponent(c_value) + + (!exdays ? "" : "; expires="+exdate.toUTCString()); + ; + } + +function getCookie(cname) { + var name = cname + "="; + var ca = document.cookie.split(';'); + for(var i=0; iSubmitting score"; + + submitScore(name, + globalValues.extra.score, + globalValues.extra.level, + settings.controlMethod, + controller); + } + } + this.end = function() { + this.OuterDiv.innerHTML =""; + } + + this.keydownHandler = function(e) { + } + this.keyupHandler = function(e) { + } + } + + function getPlayerName() { + // setWriteMode(); alternative method, not yet implemented + let playername; + do { + playername = prompt("Player name (max " + maxplayernamelength +" characters)"); + if (playername == null) { + return null; + } + } while ((playername.length <= 0) || (playername.length > maxplayernamelength)) + // Ask for playername until proper name is given, or cancel is chosen. + return playername; + } + + + return highscoreState; +}); \ No newline at end of file diff --git a/Other versions/0.9/soundFiles/Retro.wav b/Other versions/0.9/soundFiles/Retro.wav new file mode 100644 index 0000000..bbf5709 Binary files /dev/null and b/Other versions/0.9/soundFiles/Retro.wav differ diff --git a/Other versions/0.9/soundFiles/gameOver2.wav b/Other versions/0.9/soundFiles/gameOver2.wav new file mode 100644 index 0000000..fb9a74d Binary files /dev/null and b/Other versions/0.9/soundFiles/gameOver2.wav differ diff --git a/Other versions/Best Version/To do.txt b/Other versions/Best Version/To do.txt new file mode 100644 index 0000000..c650dc7 --- /dev/null +++ b/Other versions/Best Version/To do.txt @@ -0,0 +1,57 @@ +/////////////////////////////////// +/////// New Objectives /////// +/////////////////////////////////// +**Iron out singlePage merging project** +Intro guide +checkup on diagonal movement + +Start balancing, create a levers to control difficulty +/ change level progression +establish facade between game and animation + +powerup options +challenges +/////////////////////////////////// +/////// done'ish Objectives /////// +/////////////////////////////////// +Sound settings (done?) +Pause Game(done?) +Fix control method settings (done?) +/////////////////////////////////// +//////// Old Stuff ///////// +/////////////////////////////////// +State concept +(gameState, + MenuState, + HighScoreState, + SettingsState +) + +Implement Menu properly +Settings in one page +Sound Settings +users + + +/////////////////////////////////// +//////// From mobile ///////// +/////////////////////////////////// + +Old TODO's: +Fix highscore submitting +reveal invis Ball on impact +fix text +lock when submitting +startsite +fjern størrelseforskelle (alt relativt) +Seeker ball fix loop + +Ideas: +Integrate/merge Pages/Single page'ify +Hints/Legends +Map (forhindringer) +samle ting (powerups) +Multiplayer (vs mode) +Webgl (the conversion) +Anti-mur ting (seeker is an idea) +Highscore board (+rework) \ No newline at end of file diff --git a/Other versions/Best Version/index.html b/Other versions/Best Version/index.html new file mode 100644 index 0000000..5315625 --- /dev/null +++ b/Other versions/Best Version/index.html @@ -0,0 +1,26 @@ + + + + + BallsBalls + + + + + + + + +
+ + + \ No newline at end of file diff --git a/Other versions/Best Version/scripts/Ball.js b/Other versions/Best Version/scripts/Ball.js new file mode 100644 index 0000000..b89ad17 --- /dev/null +++ b/Other versions/Best Version/scripts/Ball.js @@ -0,0 +1,32 @@ +define(["DrawFunctions","Calculations"],function(drawFunctions,Calculations) { +let Ball = function (startx,starty, vx, vy, radius,commonValues) { + this.x = startx; + this.y = starty; + this.radius = radius; + this.dx = vx * Calculations.randomsign(); + this.dy = vy * Calculations.randomsign(); + this.commonValues = commonValues; +}; + +Ball.prototype.move = function() { + if ((this.x > this.commonValues.height-this.radius && this.dx > 0)|| (this.x < this.radius && this.dx < 0)) { + this.dx = -this.dx; + } + if ((this.y > this.commonValues.width-this.radius && this.dy > 0) || (this.y < this.radius && this.dy < 0)) { + this.dy = -this.dy; + } + + this.x = this.x + this.dx; + this.y = this.y + this.dy; +}; + +Ball.prototype.shape = function() { + return new Calculations.circle(this.x,this.y,this.radius); +}; + +Ball.prototype.draw = function(ctx) { + drawFunctions.drawBall(this.x, this.y, this.radius,ctx,"green"); +}; + +return Ball; +}) \ No newline at end of file diff --git a/Other versions/Best Version/scripts/Calculations.js b/Other versions/Best Version/scripts/Calculations.js new file mode 100644 index 0000000..ae45bf7 --- /dev/null +++ b/Other versions/Best Version/scripts/Calculations.js @@ -0,0 +1,114 @@ +define(function() { + return { + // Shape objects: + circle: function (x,y,radius) { + this.x = x; + this.y = y; + this.r = radius; + }, + + rectangle: + function rectangle(x,y,width,height) { + this.x = x; + this.y = y; + this.w = width; + this.h = height; + }, + + //distance calculator (between two points) + dist: function(x1,y1,x2,y2) { + return Math.sqrt(Math.pow(Math.abs(x1 - x2),2) + Math.pow(Math.abs(y1 - y2),2)); + }, + + + + randomsign: function () { + var i = this.random(0, 1); + if (i == 0) { + return -1; + } else { + return 1; + } + }, + + sign: function(i) { + if (i > 0) { + return 1; + } else if (i < 0) { + return -1; + } else { + return 0; + } + }, + + random: function(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + }, + + CircleCircleColliding: function(c1,c2) { + var dist = this.dist(c1.x , c1.y , c2.x , c2.y); + if (dist < Math.max(c1.r,c2.r)) { + return true; + } + return false; + }, + + RectRectColliding: function(r1,r2) { + var distX = Math.abs(r1.x + r1.w/2 - r2.x - r2.w/2); + var distY = Math.abs(r1.y + r1.h/2 - r2.y - r2.h/2); + + if (distX > (r1.w + r2.w)/2) { + return false; + } else if (distY > (r1.h + r2.h)/2) { + return false; + } else { + return true; + } + }, + + RectCircleColliding: function(circle,rect){ + var distX = Math.abs(circle.x - rect.x-rect.w/2); + var distY = Math.abs(circle.y - rect.y-rect.h/2); + + if (distX > (rect.w/2 + circle.r)) { return false; } + if (distY > (rect.h/2 + circle.r)) { return false; } + + if (distX <= (rect.w/2)) { return true; } + if (distY <= (rect.h/2)) { return true; } + + var dx=distX-rect.w/2; + var dy=distY-rect.h/2; + return (dx*dx+dy*dy<=(circle.r*circle.r)); + }, + + /** + * + * @param a the starting position + * @param b the end position + * @param max the maximum value (i.e. 360 for degrees in circle + * @returns {number} in {-1,0,1}, which direction is shortest + */ + shortestDirection: function (a, b, max) { + var ans; + if (b - a > max / 2) { + ans = b - a - max; + } else if (b - a > -max / 2) { + ans = b - a; + } else { + ans = b - a + max; + } + + if (ans > 0) { + return 1; + } else if (ans < 0) { + return -1; + } else { + return 0; + } + +} + + + + } +}) \ No newline at end of file diff --git a/Other versions/Best Version/scripts/DrawFunctions.js b/Other versions/Best Version/scripts/DrawFunctions.js new file mode 100644 index 0000000..c901ad7 --- /dev/null +++ b/Other versions/Best Version/scripts/DrawFunctions.js @@ -0,0 +1,21 @@ +define(function() { +function drawBall(x,y,r,ctx,color) { + ctx.beginPath(); + ctx.arc(x, y, r, 0, Math.PI*2, false); + ctx.fillStyle = color; + ctx.fill(); + ctx.closePath(); +} + +function drawRect(x,y,w,h,ctx,color) { + ctx.beginPath(); + ctx.rect(x,y,w,h); + ctx.fillStyle = color; + ctx.fill(); + ctx.closePath(); +} +return { + drawBall: drawBall, + drawRect: drawRect +} +}) \ No newline at end of file diff --git a/Other versions/Best Version/scripts/GameFlow.js b/Other versions/Best Version/scripts/GameFlow.js new file mode 100644 index 0000000..79ca899 --- /dev/null +++ b/Other versions/Best Version/scripts/GameFlow.js @@ -0,0 +1,218 @@ +define(["GameValueHandler","Music","Calculations", +"Paddle","Ball","Pickup" +],function(GameValueHandler,music,Calculations, +Paddle,Ball,Pickup +) { +var canvas; +var gameState = new GameValueHandler(); +var myFont = "Arial" +var fillStyle = "#dd0095"; +var ctx +var p; +var objects; +var endFunc; +var timeLeft = 30; +var countervalue = 0; +var gracetimer = 0; +var grace = false; +var paused = false; +var commonValues; + + function initiate(aCanvas,endFunction,ctrlHandler) { + canvas = aCanvas; + ctx = canvas.ctx; + endFunc = endFunction; + gameState.init(canvas.width, canvas.height); + timeLeft = 30; + countervalue = 0; + gracetimer = 0; + p = new Paddle(canvas.height/2, canvas.width/2, + gameState.playerLength,ctrlHandler, gameState.playerSpeed); + + commonValues = { + width: canvas.width, + height: canvas.height, + stealthBallticks: gameState.stealthBallticks, + p: p, + maxTurn: gameState.maxTurn + } + + objects = []; + + addPickUp(); + music.playMain(); + doTurn(); + } + +function doGrace() { + //end of grace + if (gracetimer == 0) { + grace = false; + //start Music Again + music.playMain(); + //add objects: + addSpecialBall(); + addPickUp(); + for (i = 0; i < gameState.initialballs; i++) { + addBall(); + } + + requestAnimationFrame(doTurn); + } else { + //grace countdown + gracetimer = gracetimer - 1; + requestAnimationFrame(doGrace); + } +} + +function doTurn() { + if (gameState.playerdead) { + endgame(); + return; + } else if (paused) { + return; + } + + //reset canvas + ctx.clearRect(0, 0, canvas.width, canvas.height); + + //text drawing + setFont(40); + ctx.fillText("Level: "+ gameState.level, 20, 20); + ctx.fillText("Squares Gathered: "+gameState.score, 20, 40); + ctx.fillText("Survive for: "+timeLeft, 20, 60); + + //move player + p.move(); + p.draw(ctx); + + // check if pickup has been picked up + pickup.draw(ctx); + if (Calculations.RectRectColliding(p.shape(), pickup.shape())) { + addPickUp(); + gameState.score++; + } + + //move balls + for (var int = 0; int < objects.length; int++) { + var object = objects[int]; + + object.move(); + if (Calculations.RectCircleColliding(object.shape(), p.shape())) { + gameState.playerdead = true; + object.visible = true; + } + object.draw(ctx); + } + + //end of level + if (timeLeft == 0) { + //Pause Music + music.playPause(); + //tick up level + gameState.levelup(); + //enter grace period + gracetimer = gameState.graceperiod; + grace = true; + //reset "game board" + objects = []; + pickup = null; + timeLeft = gameState.levelduration; + //draw grace text + setFont(10); + ctx.fillText("Level Complete", canvas.width/4, canvas.height/4); + //begin grace: + requestAnimationFrame(doGrace); + } else { + count(); + //level countdown + for (i = 0; i < gameState.ballspertick; i++) { + addBall(); + } + timeLeft--; + requestAnimationFrame(doTurn); + } +} + +function setFont(quotent) { + ctx.font = (canvas.width/quotent)+"px " + myFont; + ctx.fillStyle = fillStyle; +} + + +//checks if addBall-tick has come (and counts up) +function count() { + countervalue++; + if (countervalue > gameState.tickperball) { + countervalue = 0; + return true; + } + return false; +} + +function addObject(object) { + //set starting position + var currentdist = 0; + let startx; + let starty; + while (currentdist < gameState.minDist) { + startx = Calculations.random(0, canvas.height); + starty = Calculations.random(0, canvas.width); + currentdist = Calculations.dist(startx, starty, p.x, p.y); + } + + //set speed + vx = Calculations.random(gameState.minBallspeed, gameState.maxBallspeed); + vy = Calculations.random(gameState.minBallspeed, gameState.maxBallspeed); + + //set size + radius = Calculations.random(gameState.minballRadius,gameState.maxballRadius); + + //add to ball list + let newObject = new object(startx, starty, vx, vy, radius,commonValues); + objects.push(newObject); + return newObject; +} + +function addBall() { + addObject(Ball); +} + +function addSpecialBall() { + addObject(gameState.specialBall); +} + +function addPickUp() { + //set position + let x; + let y; + var currentdist = 0; + while (currentdist < gameState.minDist) { + x = Calculations.random(gameState.pickupLength , canvas.height-gameState.pickupLength ); + y = Calculations.random(gameState.pickupLength , canvas.width-gameState.pickupLength ); + currentdist = Calculations.dist(x, y, p.x, p.y); + } + //add Pickup + pickup = new Pickup(x,y,gameState.pickupLength ); +} + +//ending the game, when player dies +function endgame() { + music.playGameOver(); + endFunc({score:gameState.score,level:gameState.level}); +} + +let pauseGameToggle = function() { + paused = !paused; + if (!paused) { + doTurn(); + } +}; + + +return { + initiateGame: initiate, + pauseGameToggle: pauseGameToggle +} + +}) \ No newline at end of file diff --git a/Other versions/Best Version/scripts/GameValueHandler.js b/Other versions/Best Version/scripts/GameValueHandler.js new file mode 100644 index 0000000..678d68e --- /dev/null +++ b/Other versions/Best Version/scripts/GameValueHandler.js @@ -0,0 +1,87 @@ +define(["SeekerBall","StealthBall"],function(SeekerBall, StealthBall) { + function dist(x1,y1,x2,y2) { + return Math.sqrt(Math.pow(Math.abs(x1 - x2),2) + Math.pow(Math.abs(y1 - y2),2)); + } + + +return function GameValueHandler() { + this.level = 1; + this.maxBallspeed; + this.minBallspeed; + this.maxballRadius; + this.minballRadius; + this.initialballs; //balls at the start of the level + this.levelduration; + this.tickperball; //how often new ball is created + this.ballspertick; //how many balls are created at once + this.basemaxBallspeed; + this.baseminBallspeed; + + this.durationTickUp = 5; + + this.baseForDurationIncrease = 0; + this.baseForSpeedIncrease = 2; + this.baseForBallsPerTickIncrease = 0; + this.baseForTicksPerBallDecrease = 3; + + this.ticksForDurationIncrease = 3; + this.ticksForSpeedIncrease = 4; + this.ticksForBallsPerTickIncrease = 5; + this.ticksForTicksPerBallDecrease = 5; + + this.levelup = function(){ + this.level++; + this.initialballs++; + if (this.level % 2 == 0) { + this.specialBall = StealthBall; + } else { + this.specialBall = SeekerBall; + } + + if ((this.level % this.ticksForDurationIncrease) + this.baseForDurationIncrease == 0) { + this.levelduration += this.durationTickUp; + } + if ((this.level % this.ticksForSpeedIncrease) + this.baseForSpeedIncrease == 0) { + this.maxBallspeed += this.basemaxBallspeed; + this.minBallspeed += this.baseminBallspeed; + } + if ((this.level % this.baseForBallsPerTickIncrease) + this.baseForBallsPerTickIncrease == 0) { + this.ballspertick++; + } + if ((this.level % this.baseForTicksPerBallDecrease) + this.baseForTicksPerBallDecrease == 0) { + this.ticksperball--; + } + } + + + this.init = function(width,height) { + let averageSize = (Math.abs(width) + Math.abs(height)) / 2; + + this.playerLength = averageSize / 56; + this.playerSpeed = averageSize / 143; + this.pickupLength = averageSize / 50; + + this.minDist = dist(0,0,width,height) / 4; + + this.graceperiod = 100; + this.stealthBallticks = 100; + this.maxTurn = 0.03; + + this.playerdead = false; + this.scorenotsubmitted = true; + this.score = 0; + + this.level = 1; + this.basemaxBallspeed = averageSize / 200; + this.baseminBallspeed = averageSize / 1000; + this.maxBallspeed = this.basemaxBallspeed; + this.minBallspeed = this.baseminBallspeed; + this.maxballRadius = averageSize / 70; + this.minballRadius = averageSize / 200; + this.initialballs = 1; + this.levelduration = 30; + this.tickperball = 20; + this.ballspertick = 1; + } +} +}) \ No newline at end of file diff --git a/Other versions/Best Version/scripts/Initialization.js b/Other versions/Best Version/scripts/Initialization.js new file mode 100644 index 0000000..9d934d4 --- /dev/null +++ b/Other versions/Best Version/scripts/Initialization.js @@ -0,0 +1,35 @@ +require(["menuState","State","settings"], function(menuState,State,settings) { + var canvas = {}; + var ctx; + var p; + var pickup; + var objects; + var height; + var width; + var mindist = 4; + var leaderboard; + var squared = true; + + init = function () { + + // Initialize canvas + canvas.dom = document.getElementById("myCanvas"); + canvas.ctx = canvas.dom.getContext("2d"); + + settings.init(); + + if (squared) { + let size = Math.min(window.innerWidth,window.innerHeight); + canvas.dom.width = canvas.height = size; + canvas.dom.height = canvas.width = size; + } else { + canvas.dom.width = canvas.height = window.innerWidth; + canvas.dom.height = canvas.width = window.innerHeight; + } + var controller = State.stateController(menuState,canvas); + }; + + init(); + +}); + diff --git a/Other versions/Best Version/scripts/Leaderboard.js b/Other versions/Best Version/scripts/Leaderboard.js new file mode 100644 index 0000000..76e7fe9 --- /dev/null +++ b/Other versions/Best Version/scripts/Leaderboard.js @@ -0,0 +1,62 @@ +define(function() { +let firebaseURI = "https://leaderboard-bf98b.firebaseio.com"; + + var config = { + apiKey: "AIzaSyDnQy8gUVUldROZM3hxjg2_M3FE7Yg_cSc", + authDomain: "leaderboard-bf98b.firebaseapp.com", + databaseURL: "https://leaderboard-bf98b.firebaseio.com", + storageBucket: "leaderboard-bf98b.appspot.com", + }; + firebase.initializeApp(config); + +let Leaderboard = function(){ + this.firebase = firebase.database(); + this.firebase.ref("scores").orderByChild("score").limitToLast(5).on("value", (value) => { + this.scores = value.val() + }); + + + this.add = function(data) { + this.firebase.ref("scores").push(data).setPriority(data.score) + }; + + /* + * assumed that data is valid + */ + this.addandgo = function(data,go) { + this.firebase.ref("scores").push(data).setPriority(data.score).then(go, function(){ + console.log("fail"); + }); + }; + + this.get = function() { + throw new Error("this shouldn't happen"); + var list = []; + var running = true; + this.firebase.ref("scores").orderByChild("score").once("value").then( + function(snapshot) { + snapshot.forEach(function(childSnapshot) { + list.push(childSnapshot.val()); + }) + running = false; + }); + }; + + this.getandgo = function(go,limit) { + let query = this.firebase.ref("scores").orderByChild("score"); + if (limit!=null) { + query = query.limitToLast(limit); + } + query.once("value").then( + function(snapshot) { + let list = []; + snapshot.forEach(function(childSnapshot) { + list.push(childSnapshot.val()); + }); + go(list); + }); + }; +}; + +return new Leaderboard(); +}); \ No newline at end of file diff --git a/Other versions/Best Version/scripts/Music.js b/Other versions/Best Version/scripts/Music.js new file mode 100644 index 0000000..cf3531b --- /dev/null +++ b/Other versions/Best Version/scripts/Music.js @@ -0,0 +1,55 @@ +define(["settings"],function(settings) { +var music = new Music(); + +function Music() { + this.audio = new Audio('soundFiles/Retro.wav'); + this.audio.loop = true; + this.sounds = new Audio(); + this.muted = false; + + this.playMain = function() { + if (!this.muted) { + this.audio.volume = settings.soundLevel; + } + this.sounds.pause(); + this.audio.play(); + } + + this.playGameOver = function() { + this.audio.pause(); + this.sounds.src = 'soundFiles/gameOver2.wav'; + this.sounds.play(); + } + + this.playPause = function() { + this.audio.pause(); + } + + this.pause = function() { + this.audio.pause(); + } + + this.stop = function() { + this.audio.pause(); + } + + this.toggleMute = function() { + if (this.muted) { + this.audio.volume = settings.soundLevel; + } else { + this.audio.volume = 0; + } + this.muted = !this.muted; + } + +// this.setVolume = function(value) { +// this.audio.volume = value; +// } + + this.changeVolume = function(change) { + this.audio.volume += value; + } +} + +return music; +}) diff --git a/Other versions/Best Version/scripts/Paddle.js b/Other versions/Best Version/scripts/Paddle.js new file mode 100644 index 0000000..da89dc2 --- /dev/null +++ b/Other versions/Best Version/scripts/Paddle.js @@ -0,0 +1,19 @@ +define(["DrawFunctions","Calculations"],function(drawFunctions,Calculations) { +return function Paddle(ax,ay,length,controller,playerSpeed) { + this.x = ax; + this.y = ay; + this.width = length; + this.height = length; + this.move = function(nx,ny) { + controller.playerControl(this,playerSpeed); + } + + this.shape = function(){ + return new Calculations.rectangle(this.x,this.y,this.width,this.height); + } + + this.draw = function(ctx) { + drawFunctions.drawRect(this.x, this.y, this.width, this.height,ctx,"#0095DD"); + } +} +}) \ No newline at end of file diff --git a/Other versions/Best Version/scripts/Pickup.js b/Other versions/Best Version/scripts/Pickup.js new file mode 100644 index 0000000..e6ee14b --- /dev/null +++ b/Other versions/Best Version/scripts/Pickup.js @@ -0,0 +1,16 @@ +define(["DrawFunctions","Calculations"],function(drawFunctions,Calculations) { + return function Pickup(x,y,length) { + this.x = x; + this.y = y; + this.width = length; + this.height = length; + + this.shape = function(){ + return new Calculations.rectangle(this.x,this.y,this.width,this.height); + } + + this.draw = function(ctx) { + drawFunctions.drawRect(this.x, this.y, this.width, this.height,ctx,"#FFA500"); + } + } +}) \ No newline at end of file diff --git a/Other versions/Best Version/scripts/SeekerBall.js b/Other versions/Best Version/scripts/SeekerBall.js new file mode 100644 index 0000000..b9453fa --- /dev/null +++ b/Other versions/Best Version/scripts/SeekerBall.js @@ -0,0 +1,34 @@ +define(["DrawFunctions","Calculations","Ball"],function(drawFunctions,Calculations,Ball) { + +return function SeekerBall(startx,starty, vx, vy, radius,commonValues) { + this.target = commonValues.p; + this.base = new Ball(startx,starty, vx, vy, radius,commonValues); + this.speed = (Math.abs(this.base.dx) + Math.abs(this.base.dy)) / 2; + this.currentDirection = 0; + + this.move = function() { + this.determineDirection(); + this.base.x -= this.speed * Math.cos(this.currentDirection); + this.base.y -= this.speed * Math.sin(this.currentDirection); + }; + + this.determineDirection = function() { + DesiredDirection = Math.atan2((this.target.y - this.base.y) , (this.target.x - this.base.x)) + Math.PI; + + let change = this.currentDirection-DesiredDirection; + if (Math.abs(change)0) { + return 1; + } else if (x<0) { + return -1; + } + return 0; + } + + + gameControlHandler = function(width,height) { + var upPressed = false; + var downPressed = false; + var rightPressed = false; + var leftPressed = false; + + function keyboardControl(object, speed) { + let xChange = 0; + let yChange = 0; + + if(rightPressed) { + xChange += speed; + } + if(leftPressed) { + xChange -= speed; + } + + if(downPressed) { + yChange += speed; + } + + if(upPressed) { + yChange -= speed; + } + + if (xChange!=0 && yChange!=0) { + xChange = sign(xChange)*Math.sqrt(settings.diagonalFactor*speed); + yChange = sign(yChange)*Math.sqrt(settings.diagonalFactor*speed); + } + + object.x += xChange; + object.y += yChange; + + if (object.x < 0) { + object.x = 0; + } else if (object.x + object.height > height) { + object.x = height-object.height; + } + + if (object.y < 0) { + object.y = 0; + } else if (object.y + object.width > width) { + object.y = width-object.width; + } + } + + this.keyDown = function(e) { + if(e.keyCode == settings.downKey) { + downPressed = true; + } else if(e.keyCode == settings.rightKey) { + rightPressed = true; + } else if(e.keyCode == settings.upKey) { + upPressed = true; + } else if(e.keyCode == settings.leftKey) { + leftPressed = true; + } else if(e.keyCode == settings.muteKey) { + music.toggleMute(); + } else if(e.keyCode == settings.pauseKey) { + game.pauseGameToggle(); + } + } + + this.keyUp = function(e) { + if(e.keyCode == settings.downKey) { + downPressed = false; + } + else if(e.keyCode == settings.rightKey) { + rightPressed = false; + } + else if(e.keyCode == settings.upKey) { + upPressed = false; + } + else if(e.keyCode == settings.leftKey) { + leftPressed = false; + } + } + this.playerControl = keyboardControl; + } + return gameControlHandler; +}) \ No newline at end of file diff --git a/Other versions/Best Version/scripts/gameState.js b/Other versions/Best Version/scripts/gameState.js new file mode 100644 index 0000000..5b0adf4 --- /dev/null +++ b/Other versions/Best Version/scripts/gameState.js @@ -0,0 +1,23 @@ +define(["GameFlow","settings", "gameControlHandler"], +function(gameflow,settings,gameControlHandler) { + + function gameState(controller,canvas) { + settings.updateSettings(); + let gameCtrlHandler = new gameControlHandler(canvas.width, canvas.height); + this.init = function() { + canvas.dom.style.display = "block"; + gameflow.initiateGame(canvas, + function(gameData){controller.changeState("submitScoreState",gameData)} + ,gameCtrlHandler); + } + this.end = function() { + canvas.dom.style.display = "none"; + } + this.keydownHandler = gameCtrlHandler.keyDown; + this.keyupHandler = gameCtrlHandler.keyUp; + } + + return { + gameState: gameState + } +}); \ No newline at end of file diff --git a/Other versions/Best Version/scripts/highScoreState.js b/Other versions/Best Version/scripts/highScoreState.js new file mode 100644 index 0000000..80b0bc1 --- /dev/null +++ b/Other versions/Best Version/scripts/highScoreState.js @@ -0,0 +1,52 @@ +define(["Leaderboard"],function(leaderboard) { + let site = '
Rank Name Level Score (Squares Gathered) Control Method

'; + let outerDiv = document.getElementById("outerDiv"); + + let highscoreState = function (controller,values) { + this.init = function() { + outerDiv.innerHTML = site; + document.getElementById("returnToMenu").addEventListener("click", + function() { + controller.changeState("menuState"); + }); + leaderboard.getandgo(function(list) { + let table = document.getElementById("items"); + var index, len; + for (index = Math.min(list.length-1,10), len = 0; index >= len; --index) { + addRow(table,list[index]); + } + }, 10); + } + + this.end = function() { + outerDiv.innerHTML = ""; + } + + this.keydownHandler = function(e) { + if (e.keyCode == 77) { // m + controller.changeState("menuState"); + } + } + this.keyupHandler = function(e) { + } + } + + function addRow(table, data) { //adding a simple row + var rownumber = table.rows.length; + var row = table.insertRow(rownumber); + + var cell1 = row.insertCell(0); + var cell2 = row.insertCell(1); + var cell3 = row.insertCell(2); + var cell4 = row.insertCell(3); + var cell5 = row.insertCell(4); + + cell1.innerHTML = rownumber; + cell2.innerHTML = data.name; + cell3.innerHTML = data.level; + cell4.innerHTML = data.score; + cell5.innerHTML = data.method; + } + + return highscoreState; +}); \ No newline at end of file diff --git a/Other versions/Best Version/scripts/menuState.js b/Other versions/Best Version/scripts/menuState.js new file mode 100644 index 0000000..52b5dd2 --- /dev/null +++ b/Other versions/Best Version/scripts/menuState.js @@ -0,0 +1,61 @@ +define(["settings"],function(settings) { + var myFont = "Arial" + var fillStyle = "green"; + var keyStateMap = {}; + keyStateMap[settings.restartKey] = "gameState"; + keyStateMap[settings.settingsKey] = "settingsState"; + keyStateMap[settings.highscoreKey] = "highscoreState"; + + function setMenuText(canvas) { + //reset canvas + canvas.ctx.clearRect(0, 0, canvas.width, canvas.height); + setFont(canvas,5); + + canvas.ctx.fillText("BallsBalls", canvas.width/15, canvas.height/4); + + setFont(canvas,15); + //text drawing + let displayWidth = canvas.width/10; + let displayHeight = canvas.height/2; + let heightOffset = canvas.width/12; + + canvas.ctx.fillText("Press Space to Play Game", displayWidth, displayHeight); + canvas.ctx.fillText("Press i for settings", displayWidth, displayHeight+heightOffset*1); + canvas.ctx.fillText("Press h for Leaderboard", displayWidth, displayHeight+heightOffset*2); + } + + function setFont(canvas,quotent) { + canvas.ctx.font = (canvas.width/quotent)+"px " + myFont; + canvas.ctx.fillStyle = fillStyle; + } + + function menuState(controller,canvas) { + + this.init = function() { + canvas.dom.style.display = "block"; + setMenuText(canvas); + + } + this.end = function() { + canvas.dom.style.display = "none"; + } + + this.keydownHandler = function(e) { + let change = keyStateMap[e.keyCode]; + if(change!=null) { + controller.changeState(change); + } + } + this.keyupHandler = function(e) { + } + } + + return menuState; + +}); + + + + + + diff --git a/Other versions/Best Version/scripts/require.js b/Other versions/Best Version/scripts/require.js new file mode 100644 index 0000000..c32e6c1 --- /dev/null +++ b/Other versions/Best Version/scripts/require.js @@ -0,0 +1,5 @@ +/** vim: et:ts=4:sw=4:sts=4 + * @license RequireJS 2.3.3 Copyright jQuery Foundation and other contributors. + * Released under MIT license, https://github.com/requirejs/requirejs/blob/master/LICENSE + */ +var requirejs,require,define;!function(global,setTimeout){function commentReplace(e,t){return t||""}function isFunction(e){return"[object Function]"===ostring.call(e)}function isArray(e){return"[object Array]"===ostring.call(e)}function each(e,t){if(e){var i;for(i=0;i-1&&(!e[i]||!t(e[i],i,e));i-=1);}}function hasProp(e,t){return hasOwn.call(e,t)}function getOwn(e,t){return hasProp(e,t)&&e[t]}function eachProp(e,t){var i;for(i in e)if(hasProp(e,i)&&t(e[i],i))break}function mixin(e,t,i,r){return t&&eachProp(t,function(t,n){!i&&hasProp(e,n)||(!r||"object"!=typeof t||!t||isArray(t)||isFunction(t)||t instanceof RegExp?e[n]=t:(e[n]||(e[n]={}),mixin(e[n],t,i,r)))}),e}function bind(e,t){return function(){return t.apply(e,arguments)}}function scripts(){return document.getElementsByTagName("script")}function defaultOnError(e){throw e}function getGlobal(e){if(!e)return e;var t=global;return each(e.split("."),function(e){t=t[e]}),t}function makeError(e,t,i,r){var n=new Error(t+"\nhttp://requirejs.org/docs/errors.html#"+e);return n.requireType=e,n.requireModules=r,i&&(n.originalError=i),n}function newContext(e){function t(e){var t,i;for(t=0;t0&&(e.splice(t-1,2),t-=2)}}function i(e,i,r){var n,o,a,s,u,c,d,p,f,l,h,m,g=i&&i.split("/"),v=y.map,x=v&&v["*"];if(e&&(e=e.split("/"),d=e.length-1,y.nodeIdCompat&&jsSuffixRegExp.test(e[d])&&(e[d]=e[d].replace(jsSuffixRegExp,"")),"."===e[0].charAt(0)&&g&&(m=g.slice(0,g.length-1),e=m.concat(e)),t(e),e=e.join("/")),r&&v&&(g||x)){a=e.split("/");e:for(s=a.length;s>0;s-=1){if(c=a.slice(0,s).join("/"),g)for(u=g.length;u>0;u-=1)if(o=getOwn(v,g.slice(0,u).join("/")),o&&(o=getOwn(o,c))){p=o,f=s;break e}!l&&x&&getOwn(x,c)&&(l=getOwn(x,c),h=s)}!p&&l&&(p=l,f=h),p&&(a.splice(0,f,p),e=a.join("/"))}return n=getOwn(y.pkgs,e),n?n:e}function r(e){isBrowser&&each(scripts(),function(t){if(t.getAttribute("data-requiremodule")===e&&t.getAttribute("data-requirecontext")===q.contextName)return t.parentNode.removeChild(t),!0})}function n(e){var t=getOwn(y.paths,e);if(t&&isArray(t)&&t.length>1)return t.shift(),q.require.undef(e),q.makeRequire(null,{skipMap:!0})([e]),!0}function o(e){var t,i=e?e.indexOf("!"):-1;return i>-1&&(t=e.substring(0,i),e=e.substring(i+1,e.length)),[t,e]}function a(e,t,r,n){var a,s,u,c,d=null,p=t?t.name:null,f=e,l=!0,h="";return e||(l=!1,e="_@r"+(T+=1)),c=o(e),d=c[0],e=c[1],d&&(d=i(d,p,n),s=getOwn(j,d)),e&&(d?h=r?e:s&&s.normalize?s.normalize(e,function(e){return i(e,p,n)}):e.indexOf("!")===-1?i(e,p,n):e:(h=i(e,p,n),c=o(h),d=c[0],h=c[1],r=!0,a=q.nameToUrl(h))),u=!d||s||r?"":"_unnormalized"+(A+=1),{prefix:d,name:h,parentMap:t,unnormalized:!!u,url:a,originalName:f,isDefine:l,id:(d?d+"!"+h:h)+u}}function s(e){var t=e.id,i=getOwn(S,t);return i||(i=S[t]=new q.Module(e)),i}function u(e,t,i){var r=e.id,n=getOwn(S,r);!hasProp(j,r)||n&&!n.defineEmitComplete?(n=s(e),n.error&&"error"===t?i(n.error):n.on(t,i)):"defined"===t&&i(j[r])}function c(e,t){var i=e.requireModules,r=!1;t?t(e):(each(i,function(t){var i=getOwn(S,t);i&&(i.error=e,i.events.error&&(r=!0,i.emit("error",e)))}),r||req.onError(e))}function d(){globalDefQueue.length&&(each(globalDefQueue,function(e){var t=e[0];"string"==typeof t&&(q.defQueueMap[t]=!0),O.push(e)}),globalDefQueue=[])}function p(e){delete S[e],delete k[e]}function f(e,t,i){var r=e.map.id;e.error?e.emit("error",e.error):(t[r]=!0,each(e.depMaps,function(r,n){var o=r.id,a=getOwn(S,o);!a||e.depMatched[n]||i[o]||(getOwn(t,o)?(e.defineDep(n,j[o]),e.check()):f(a,t,i))}),i[r]=!0)}function l(){var e,t,i=1e3*y.waitSeconds,o=i&&q.startTime+i<(new Date).getTime(),a=[],s=[],u=!1,d=!0;if(!x){if(x=!0,eachProp(k,function(e){var i=e.map,c=i.id;if(e.enabled&&(i.isDefine||s.push(e),!e.error))if(!e.inited&&o)n(c)?(t=!0,u=!0):(a.push(c),r(c));else if(!e.inited&&e.fetched&&i.isDefine&&(u=!0,!i.prefix))return d=!1}),o&&a.length)return e=makeError("timeout","Load timeout for modules: "+a,null,a),e.contextName=q.contextName,c(e);d&&each(s,function(e){f(e,{},{})}),o&&!t||!u||!isBrowser&&!isWebWorker||w||(w=setTimeout(function(){w=0,l()},50)),x=!1}}function h(e){hasProp(j,e[0])||s(a(e[0],null,!0)).init(e[1],e[2])}function m(e,t,i,r){e.detachEvent&&!isOpera?r&&e.detachEvent(r,t):e.removeEventListener(i,t,!1)}function g(e){var t=e.currentTarget||e.srcElement;return m(t,q.onScriptLoad,"load","onreadystatechange"),m(t,q.onScriptError,"error"),{node:t,id:t&&t.getAttribute("data-requiremodule")}}function v(){var e;for(d();O.length;){if(e=O.shift(),null===e[0])return c(makeError("mismatch","Mismatched anonymous define() module: "+e[e.length-1]));h(e)}q.defQueueMap={}}var x,b,q,E,w,y={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},S={},k={},M={},O=[],j={},P={},R={},T=1,A=1;return E={require:function(e){return e.require?e.require:e.require=q.makeRequire(e.map)},exports:function(e){if(e.usingExports=!0,e.map.isDefine)return e.exports?j[e.map.id]=e.exports:e.exports=j[e.map.id]={}},module:function(e){return e.module?e.module:e.module={id:e.map.id,uri:e.map.url,config:function(){return getOwn(y.config,e.map.id)||{}},exports:e.exports||(e.exports={})}}},b=function(e){this.events=getOwn(M,e.id)||{},this.map=e,this.shim=getOwn(y.shim,e.id),this.depExports=[],this.depMaps=[],this.depMatched=[],this.pluginMaps={},this.depCount=0},b.prototype={init:function(e,t,i,r){r=r||{},this.inited||(this.factory=t,i?this.on("error",i):this.events.error&&(i=bind(this,function(e){this.emit("error",e)})),this.depMaps=e&&e.slice(0),this.errback=i,this.inited=!0,this.ignore=r.ignore,r.enabled||this.enabled?this.enable():this.check())},defineDep:function(e,t){this.depMatched[e]||(this.depMatched[e]=!0,this.depCount-=1,this.depExports[e]=t)},fetch:function(){if(!this.fetched){this.fetched=!0,q.startTime=(new Date).getTime();var e=this.map;return this.shim?void q.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],bind(this,function(){return e.prefix?this.callPlugin():this.load()})):e.prefix?this.callPlugin():this.load()}},load:function(){var e=this.map.url;P[e]||(P[e]=!0,q.load(this.map.id,e))},check:function(){if(this.enabled&&!this.enabling){var e,t,i=this.map.id,r=this.depExports,n=this.exports,o=this.factory;if(this.inited){if(this.error)this.emit("error",this.error);else if(!this.defining){if(this.defining=!0,this.depCount<1&&!this.defined){if(isFunction(o)){if(this.events.error&&this.map.isDefine||req.onError!==defaultOnError)try{n=q.execCb(i,o,r,n)}catch(t){e=t}else n=q.execCb(i,o,r,n);if(this.map.isDefine&&void 0===n&&(t=this.module,t?n=t.exports:this.usingExports&&(n=this.exports)),e)return e.requireMap=this.map,e.requireModules=this.map.isDefine?[this.map.id]:null,e.requireType=this.map.isDefine?"define":"require",c(this.error=e)}else n=o;if(this.exports=n,this.map.isDefine&&!this.ignore&&(j[i]=n,req.onResourceLoad)){var a=[];each(this.depMaps,function(e){a.push(e.normalizedMap||e)}),req.onResourceLoad(q,this.map,a)}p(i),this.defined=!0}this.defining=!1,this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else hasProp(q.defQueueMap,i)||this.fetch()}},callPlugin:function(){var e=this.map,t=e.id,r=a(e.prefix);this.depMaps.push(r),u(r,"defined",bind(this,function(r){var n,o,d,f=getOwn(R,this.map.id),l=this.map.name,h=this.map.parentMap?this.map.parentMap.name:null,m=q.makeRequire(e.parentMap,{enableBuildCallback:!0});return this.map.unnormalized?(r.normalize&&(l=r.normalize(l,function(e){return i(e,h,!0)})||""),o=a(e.prefix+"!"+l,this.map.parentMap,!0),u(o,"defined",bind(this,function(e){this.map.normalizedMap=o,this.init([],function(){return e},null,{enabled:!0,ignore:!0})})),d=getOwn(S,o.id),void(d&&(this.depMaps.push(o),this.events.error&&d.on("error",bind(this,function(e){this.emit("error",e)})),d.enable()))):f?(this.map.url=q.nameToUrl(f),void this.load()):(n=bind(this,function(e){this.init([],function(){return e},null,{enabled:!0})}),n.error=bind(this,function(e){this.inited=!0,this.error=e,e.requireModules=[t],eachProp(S,function(e){0===e.map.id.indexOf(t+"_unnormalized")&&p(e.map.id)}),c(e)}),n.fromText=bind(this,function(i,r){var o=e.name,u=a(o),d=useInteractive;r&&(i=r),d&&(useInteractive=!1),s(u),hasProp(y.config,t)&&(y.config[o]=y.config[t]);try{req.exec(i)}catch(e){return c(makeError("fromtexteval","fromText eval for "+t+" failed: "+e,e,[t]))}d&&(useInteractive=!0),this.depMaps.push(u),q.completeLoad(o),m([o],n)}),void r.load(e.name,m,n,y))})),q.enable(r,this),this.pluginMaps[r.id]=r},enable:function(){k[this.map.id]=this,this.enabled=!0,this.enabling=!0,each(this.depMaps,bind(this,function(e,t){var i,r,n;if("string"==typeof e){if(e=a(e,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap),this.depMaps[t]=e,n=getOwn(E,e.id))return void(this.depExports[t]=n(this));this.depCount+=1,u(e,"defined",bind(this,function(e){this.undefed||(this.defineDep(t,e),this.check())})),this.errback?u(e,"error",bind(this,this.errback)):this.events.error&&u(e,"error",bind(this,function(e){this.emit("error",e)}))}i=e.id,r=S[i],hasProp(E,i)||!r||r.enabled||q.enable(e,this)})),eachProp(this.pluginMaps,bind(this,function(e){var t=getOwn(S,e.id);t&&!t.enabled&&q.enable(e,this)})),this.enabling=!1,this.check()},on:function(e,t){var i=this.events[e];i||(i=this.events[e]=[]),i.push(t)},emit:function(e,t){each(this.events[e],function(e){e(t)}),"error"===e&&delete this.events[e]}},q={config:y,contextName:e,registry:S,defined:j,urlFetched:P,defQueue:O,defQueueMap:{},Module:b,makeModuleMap:a,nextTick:req.nextTick,onError:c,configure:function(e){if(e.baseUrl&&"/"!==e.baseUrl.charAt(e.baseUrl.length-1)&&(e.baseUrl+="/"),"string"==typeof e.urlArgs){var t=e.urlArgs;e.urlArgs=function(e,i){return(i.indexOf("?")===-1?"?":"&")+t}}var i=y.shim,r={paths:!0,bundles:!0,config:!0,map:!0};eachProp(e,function(e,t){r[t]?(y[t]||(y[t]={}),mixin(y[t],e,!0,!0)):y[t]=e}),e.bundles&&eachProp(e.bundles,function(e,t){each(e,function(e){e!==t&&(R[e]=t)})}),e.shim&&(eachProp(e.shim,function(e,t){isArray(e)&&(e={deps:e}),!e.exports&&!e.init||e.exportsFn||(e.exportsFn=q.makeShimExports(e)),i[t]=e}),y.shim=i),e.packages&&each(e.packages,function(e){var t,i;e="string"==typeof e?{name:e}:e,i=e.name,t=e.location,t&&(y.paths[i]=e.location),y.pkgs[i]=e.name+"/"+(e.main||"main").replace(currDirRegExp,"").replace(jsSuffixRegExp,"")}),eachProp(S,function(e,t){e.inited||e.map.unnormalized||(e.map=a(t,null,!0))}),(e.deps||e.callback)&&q.require(e.deps||[],e.callback)},makeShimExports:function(e){function t(){var t;return e.init&&(t=e.init.apply(global,arguments)),t||e.exports&&getGlobal(e.exports)}return t},makeRequire:function(t,n){function o(i,r,u){var d,p,f;return n.enableBuildCallback&&r&&isFunction(r)&&(r.__requireJsBuild=!0),"string"==typeof i?isFunction(r)?c(makeError("requireargs","Invalid require call"),u):t&&hasProp(E,i)?E[i](S[t.id]):req.get?req.get(q,i,t,o):(p=a(i,t,!1,!0),d=p.id,hasProp(j,d)?j[d]:c(makeError("notloaded",'Module name "'+d+'" has not been loaded yet for context: '+e+(t?"":". Use require([])")))):(v(),q.nextTick(function(){v(),f=s(a(null,t)),f.skipMap=n.skipMap,f.init(i,r,u,{enabled:!0}),l()}),o)}return n=n||{},mixin(o,{isBrowser:isBrowser,toUrl:function(e){var r,n=e.lastIndexOf("."),o=e.split("/")[0],a="."===o||".."===o;return n!==-1&&(!a||n>1)&&(r=e.substring(n,e.length),e=e.substring(0,n)),q.nameToUrl(i(e,t&&t.id,!0),r,!0)},defined:function(e){return hasProp(j,a(e,t,!1,!0).id)},specified:function(e){return e=a(e,t,!1,!0).id,hasProp(j,e)||hasProp(S,e)}}),t||(o.undef=function(e){d();var i=a(e,t,!0),n=getOwn(S,e);n.undefed=!0,r(e),delete j[e],delete P[i.url],delete M[e],eachReverse(O,function(t,i){t[0]===e&&O.splice(i,1)}),delete q.defQueueMap[e],n&&(n.events.defined&&(M[e]=n.events),p(e))}),o},enable:function(e){var t=getOwn(S,e.id);t&&s(e).enable()},completeLoad:function(e){var t,i,r,o=getOwn(y.shim,e)||{},a=o.exports;for(d();O.length;){if(i=O.shift(),null===i[0]){if(i[0]=e,t)break;t=!0}else i[0]===e&&(t=!0);h(i)}if(q.defQueueMap={},r=getOwn(S,e),!t&&!hasProp(j,e)&&r&&!r.inited){if(!(!y.enforceDefine||a&&getGlobal(a)))return n(e)?void 0:c(makeError("nodefine","No define call for "+e,null,[e]));h([e,o.deps||[],o.exportsFn])}l()},nameToUrl:function(e,t,i){var r,n,o,a,s,u,c,d=getOwn(y.pkgs,e);if(d&&(e=d),c=getOwn(R,e))return q.nameToUrl(c,t,i);if(req.jsExtRegExp.test(e))s=e+(t||"");else{for(r=y.paths,n=e.split("/"),o=n.length;o>0;o-=1)if(a=n.slice(0,o).join("/"),u=getOwn(r,a)){isArray(u)&&(u=u[0]),n.splice(0,o,u);break}s=n.join("/"),s+=t||(/^data\:|^blob\:|\?/.test(s)||i?"":".js"),s=("/"===s.charAt(0)||s.match(/^[\w\+\.\-]+:/)?"":y.baseUrl)+s}return y.urlArgs&&!/^blob\:/.test(s)?s+y.urlArgs(e,s):s},load:function(e,t){req.load(q,e,t)},execCb:function(e,t,i,r){return t.apply(r,i)},onScriptLoad:function(e){if("load"===e.type||readyRegExp.test((e.currentTarget||e.srcElement).readyState)){interactiveScript=null;var t=g(e);q.completeLoad(t.id)}},onScriptError:function(e){var t=g(e);if(!n(t.id)){var i=[];return eachProp(S,function(e,r){0!==r.indexOf("_@r")&&each(e.depMaps,function(e){if(e.id===t.id)return i.push(r),!0})}),c(makeError("scripterror",'Script error for "'+t.id+(i.length?'", needed by: '+i.join(", "):'"'),e,[t.id]))}}},q.require=q.makeRequire(),q}function getInteractiveScript(){return interactiveScript&&"interactive"===interactiveScript.readyState?interactiveScript:(eachReverse(scripts(),function(e){if("interactive"===e.readyState)return interactiveScript=e}),interactiveScript)}var req,s,head,baseElement,dataMain,src,interactiveScript,currentlyAddingScript,mainScript,subPath,version="2.3.3",commentRegExp=/\/\*[\s\S]*?\*\/|([^:"'=]|^)\/\/.*$/gm,cjsRequireRegExp=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,jsSuffixRegExp=/\.js$/,currDirRegExp=/^\.\//,op=Object.prototype,ostring=op.toString,hasOwn=op.hasOwnProperty,isBrowser=!("undefined"==typeof window||"undefined"==typeof navigator||!window.document),isWebWorker=!isBrowser&&"undefined"!=typeof importScripts,readyRegExp=isBrowser&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,defContextName="_",isOpera="undefined"!=typeof opera&&"[object Opera]"===opera.toString(),contexts={},cfg={},globalDefQueue=[],useInteractive=!1;if("undefined"==typeof define){if("undefined"!=typeof requirejs){if(isFunction(requirejs))return;cfg=requirejs,requirejs=void 0}"undefined"==typeof require||isFunction(require)||(cfg=require,require=void 0),req=requirejs=function(e,t,i,r){var n,o,a=defContextName;return isArray(e)||"string"==typeof e||(o=e,isArray(t)?(e=t,t=i,i=r):e=[]),o&&o.context&&(a=o.context),n=getOwn(contexts,a),n||(n=contexts[a]=req.s.newContext(a)),o&&n.configure(o),n.require(e,t,i)},req.config=function(e){return req(e)},req.nextTick="undefined"!=typeof setTimeout?function(e){setTimeout(e,4)}:function(e){e()},require||(require=req),req.version=version,req.jsExtRegExp=/^\/|:|\?|\.js$/,req.isBrowser=isBrowser,s=req.s={contexts:contexts,newContext:newContext},req({}),each(["toUrl","undef","defined","specified"],function(e){req[e]=function(){var t=contexts[defContextName];return t.require[e].apply(t,arguments)}}),isBrowser&&(head=s.head=document.getElementsByTagName("head")[0],baseElement=document.getElementsByTagName("base")[0],baseElement&&(head=s.head=baseElement.parentNode)),req.onError=defaultOnError,req.createNode=function(e,t,i){var r=e.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script");return r.type=e.scriptType||"text/javascript",r.charset="utf-8",r.async=!0,r},req.load=function(e,t,i){var r,n=e&&e.config||{};if(isBrowser)return r=req.createNode(n,t,i),r.setAttribute("data-requirecontext",e.contextName),r.setAttribute("data-requiremodule",t),!r.attachEvent||r.attachEvent.toString&&r.attachEvent.toString().indexOf("[native code")<0||isOpera?(r.addEventListener("load",e.onScriptLoad,!1),r.addEventListener("error",e.onScriptError,!1)):(useInteractive=!0,r.attachEvent("onreadystatechange",e.onScriptLoad)),r.src=i,n.onNodeCreated&&n.onNodeCreated(r,n,t,i),currentlyAddingScript=r,baseElement?head.insertBefore(r,baseElement):head.appendChild(r),currentlyAddingScript=null,r;if(isWebWorker)try{setTimeout(function(){},0),importScripts(i),e.completeLoad(t)}catch(r){e.onError(makeError("importscripts","importScripts failed for "+t+" at "+i,r,[t]))}},isBrowser&&!cfg.skipDataMain&&eachReverse(scripts(),function(e){if(head||(head=e.parentNode),dataMain=e.getAttribute("data-main"))return mainScript=dataMain,cfg.baseUrl||mainScript.indexOf("!")!==-1||(src=mainScript.split("/"),mainScript=src.pop(),subPath=src.length?src.join("/")+"/":"./",cfg.baseUrl=subPath),mainScript=mainScript.replace(jsSuffixRegExp,""),req.jsExtRegExp.test(mainScript)&&(mainScript=dataMain),cfg.deps=cfg.deps?cfg.deps.concat(mainScript):[mainScript],!0}),define=function(e,t,i){var r,n;"string"!=typeof e&&(i=t,t=e,e=null),isArray(t)||(i=t,t=null),!t&&isFunction(i)&&(t=[],i.length&&(i.toString().replace(commentRegExp,commentReplace).replace(cjsRequireRegExp,function(e,i){t.push(i)}),t=(1===i.length?["require"]:["require","exports","module"]).concat(t))),useInteractive&&(r=currentlyAddingScript||getInteractiveScript(),r&&(e||(e=r.getAttribute("data-requiremodule")),n=contexts[r.getAttribute("data-requirecontext")])),n?(n.defQueue.push([e,t,i]),n.defQueueMap[e]=!0):globalDefQueue.push([e,t,i])},define.amd={jQuery:!0},req.exec=function(text){return eval(text)},req(cfg)}}(this,"undefined"==typeof setTimeout?void 0:setTimeout); \ No newline at end of file diff --git a/Other versions/Best Version/scripts/settings.js b/Other versions/Best Version/scripts/settings.js new file mode 100644 index 0000000..826bf09 --- /dev/null +++ b/Other versions/Best Version/scripts/settings.js @@ -0,0 +1,77 @@ +define([],function() { +//Thanks http://www.w3schools.com/js/js_cookies.asp +var settings = { + upKey: 38, + rightKey: 39, + leftKey: 37, + downKey: 40, + + restartKey: 32, //spacebar + settingsKey: 73, // i + highscoreKey: 72, // h + SubmitKey: 13, //enter + muteKey: 77, // m + pauseKey: 80, // m + + controlMethod: "Arrow Keys", + autoSubmit: false, + playerAutoName: "", + + diagonalFactor: 4, + + setSetting: setCookie, + getSetting: getCookie, + updateSettings: updateSettings, + init: updateSettings +} + +function setCookie(c_name,c_value,exdays) { + settings[c_name] = c_value; + var exdate=new Date(); + exdate.setDate(exdate.getDate() + exdays); + document.cookie=encodeURIComponent(c_name) + + "=" + encodeURIComponent(c_value) + + (!exdays ? "" : "; expires="+exdate.toUTCString()); + ; + } + +function getCookie(cname) { + var name = cname + "="; + var ca = document.cookie.split(';'); + for(var i=0; iSubmitting score"; + + submitScore(name, + globalValues.extra.score, + globalValues.extra.level, + settings.controlMethod, + controller); + } + } + this.end = function() { + this.OuterDiv.innerHTML =""; + } + + this.keydownHandler = function(e) { + } + this.keyupHandler = function(e) { + } + } + + function getPlayerName() { + // setWriteMode(); alternative method, not yet implemented + let playername; + do { + playername = prompt("Player name (max " + maxplayernamelength +" characters)"); + if (playername == null) { + return null; + } + } while ((playername.length <= 0) || (playername.length > maxplayernamelength)) + // Ask for playername until proper name is given, or cancel is chosen. + return playername; + } + + + return highscoreState; +}); \ No newline at end of file diff --git a/Other versions/Best Version/soundFiles/Retro.wav b/Other versions/Best Version/soundFiles/Retro.wav new file mode 100644 index 0000000..bbf5709 Binary files /dev/null and b/Other versions/Best Version/soundFiles/Retro.wav differ diff --git a/Other versions/Best Version/soundFiles/gameOver2.wav b/Other versions/Best Version/soundFiles/gameOver2.wav new file mode 100644 index 0000000..fb9a74d Binary files /dev/null and b/Other versions/Best Version/soundFiles/gameOver2.wav differ diff --git a/Other versions/Runner/bunny.png b/Other versions/Runner/bunny.png new file mode 100644 index 0000000..79c3167 Binary files /dev/null and b/Other versions/Runner/bunny.png differ diff --git a/Other versions/Runner/draw.js b/Other versions/Runner/draw.js new file mode 100644 index 0000000..db8152a --- /dev/null +++ b/Other versions/Runner/draw.js @@ -0,0 +1,34 @@ +function drawPanels() { + var start = rstart; + var thecurrentpart = level.currentpart; + console.log("Starting point: " + rstart); + var part = level.parts[thecurrentpart]; + while(start + + + + pixi.js example 1 + + + + + + + + + + + \ No newline at end of file diff --git a/Other versions/Runner/level.js b/Other versions/Runner/level.js new file mode 100644 index 0000000..5d3da66 --- /dev/null +++ b/Other versions/Runner/level.js @@ -0,0 +1,47 @@ +function Level() { + this.parts = []; + this.addpart = function(part) { + this.parts.push(part); + } + this.currentpart = 0; +} + +function Part(start, end) { + this.start = start; + this.end = end; + this.length = end - start; +} + + +function printLevel(thelevel){ + var parts = thelevel.parts; + for(var i = 0; i < parts.length; i++){ + var part = parts[i]; + console.log("from " + part.start + " , to " + part.end); + } +} + + +function generateLevel(length,mindist,maxdist,gap) { + var newlevel = new Level(); + var lengthused = 0; + var partlength; + var newpart; + + while(lengthused+maxdist= 0 && + arr.length % 1 === 0 + ); + } + + function _arrayEach(arr, iterator) { + var index = -1, + length = arr.length; + + while (++index < length) { + iterator(arr[index], index, arr); + } + } + + function _map(arr, iterator) { + var index = -1, + length = arr.length, + result = Array(length); + + while (++index < length) { + result[index] = iterator(arr[index], index, arr); + } + return result; + } + + function _range(count) { + return _map(Array(count), function (v, i) { return i; }); + } + + function _reduce(arr, iterator, memo) { + _arrayEach(arr, function (x, i, a) { + memo = iterator(memo, x, i, a); + }); + return memo; + } + + function _forEachOf(object, iterator) { + _arrayEach(_keys(object), function (key) { + iterator(object[key], key); + }); + } + + function _indexOf(arr, item) { + for (var i = 0; i < arr.length; i++) { + if (arr[i] === item) return i; + } + return -1; + } + + var _keys = Object.keys || function (obj) { + var keys = []; + for (var k in obj) { + if (obj.hasOwnProperty(k)) { + keys.push(k); + } + } + return keys; + }; + + function _keyIterator(coll) { + var i = -1; + var len; + var keys; + if (_isArrayLike(coll)) { + len = coll.length; + return function next() { + i++; + return i < len ? i : null; + }; + } else { + keys = _keys(coll); + len = keys.length; + return function next() { + i++; + return i < len ? keys[i] : null; + }; + } + } + + // Similar to ES6's rest param (http://ariya.ofilabs.com/2013/03/es6-and-rest-parameter.html) + // This accumulates the arguments passed into an array, after a given index. + // From underscore.js (https://github.com/jashkenas/underscore/pull/2140). + function _restParam(func, startIndex) { + startIndex = startIndex == null ? func.length - 1 : +startIndex; + return function() { + var length = Math.max(arguments.length - startIndex, 0); + var rest = Array(length); + for (var index = 0; index < length; index++) { + rest[index] = arguments[index + startIndex]; + } + switch (startIndex) { + case 0: return func.call(this, rest); + case 1: return func.call(this, arguments[0], rest); + } + // Currently unused but handle cases outside of the switch statement: + // var args = Array(startIndex + 1); + // for (index = 0; index < startIndex; index++) { + // args[index] = arguments[index]; + // } + // args[startIndex] = rest; + // return func.apply(this, args); + }; + } + + function _withoutIndex(iterator) { + return function (value, index, callback) { + return iterator(value, callback); + }; + } + + //// exported async module functions //// + + //// nextTick implementation with browser-compatible fallback //// + + // capture the global reference to guard against fakeTimer mocks + var _setImmediate = typeof setImmediate === 'function' && setImmediate; + + var _delay = _setImmediate ? function(fn) { + // not a direct alias for IE10 compatibility + _setImmediate(fn); + } : function(fn) { + setTimeout(fn, 0); + }; + + if (typeof process === 'object' && typeof process.nextTick === 'function') { + async.nextTick = process.nextTick; + } else { + async.nextTick = _delay; + } + async.setImmediate = _setImmediate ? _delay : async.nextTick; + + + async.forEach = + async.each = function (arr, iterator, callback) { + return async.eachOf(arr, _withoutIndex(iterator), callback); + }; + + async.forEachSeries = + async.eachSeries = function (arr, iterator, callback) { + return async.eachOfSeries(arr, _withoutIndex(iterator), callback); + }; + + + async.forEachLimit = + async.eachLimit = function (arr, limit, iterator, callback) { + return _eachOfLimit(limit)(arr, _withoutIndex(iterator), callback); + }; + + async.forEachOf = + async.eachOf = function (object, iterator, callback) { + callback = _once(callback || noop); + object = object || []; + + var iter = _keyIterator(object); + var key, completed = 0; + + while ((key = iter()) != null) { + completed += 1; + iterator(object[key], key, only_once(done)); + } + + if (completed === 0) callback(null); + + function done(err) { + completed--; + if (err) { + callback(err); + } + // Check key is null in case iterator isn't exhausted + // and done resolved synchronously. + else if (key === null && completed <= 0) { + callback(null); + } + } + }; + + async.forEachOfSeries = + async.eachOfSeries = function (obj, iterator, callback) { + callback = _once(callback || noop); + obj = obj || []; + var nextKey = _keyIterator(obj); + var key = nextKey(); + function iterate() { + var sync = true; + if (key === null) { + return callback(null); + } + iterator(obj[key], key, only_once(function (err) { + if (err) { + callback(err); + } + else { + key = nextKey(); + if (key === null) { + return callback(null); + } else { + if (sync) { + async.setImmediate(iterate); + } else { + iterate(); + } + } + } + })); + sync = false; + } + iterate(); + }; + + + + async.forEachOfLimit = + async.eachOfLimit = function (obj, limit, iterator, callback) { + _eachOfLimit(limit)(obj, iterator, callback); + }; + + function _eachOfLimit(limit) { + + return function (obj, iterator, callback) { + callback = _once(callback || noop); + obj = obj || []; + var nextKey = _keyIterator(obj); + if (limit <= 0) { + return callback(null); + } + var done = false; + var running = 0; + var errored = false; + + (function replenish () { + if (done && running <= 0) { + return callback(null); + } + + while (running < limit && !errored) { + var key = nextKey(); + if (key === null) { + done = true; + if (running <= 0) { + callback(null); + } + return; + } + running += 1; + iterator(obj[key], key, only_once(function (err) { + running -= 1; + if (err) { + callback(err); + errored = true; + } + else { + replenish(); + } + })); + } + })(); + }; + } + + + function doParallel(fn) { + return function (obj, iterator, callback) { + return fn(async.eachOf, obj, iterator, callback); + }; + } + function doParallelLimit(fn) { + return function (obj, limit, iterator, callback) { + return fn(_eachOfLimit(limit), obj, iterator, callback); + }; + } + function doSeries(fn) { + return function (obj, iterator, callback) { + return fn(async.eachOfSeries, obj, iterator, callback); + }; + } + + function _asyncMap(eachfn, arr, iterator, callback) { + callback = _once(callback || noop); + arr = arr || []; + var results = _isArrayLike(arr) ? [] : {}; + eachfn(arr, function (value, index, callback) { + iterator(value, function (err, v) { + results[index] = v; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + + async.map = doParallel(_asyncMap); + async.mapSeries = doSeries(_asyncMap); + async.mapLimit = doParallelLimit(_asyncMap); + + // reduce only has a series version, as doing reduce in parallel won't + // work in many situations. + async.inject = + async.foldl = + async.reduce = function (arr, memo, iterator, callback) { + async.eachOfSeries(arr, function (x, i, callback) { + iterator(memo, x, function (err, v) { + memo = v; + callback(err); + }); + }, function (err) { + callback(err, memo); + }); + }; + + async.foldr = + async.reduceRight = function (arr, memo, iterator, callback) { + var reversed = _map(arr, identity).reverse(); + async.reduce(reversed, memo, iterator, callback); + }; + + async.transform = function (arr, memo, iterator, callback) { + if (arguments.length === 3) { + callback = iterator; + iterator = memo; + memo = _isArray(arr) ? [] : {}; + } + + async.eachOf(arr, function(v, k, cb) { + iterator(memo, v, k, cb); + }, function(err) { + callback(err, memo); + }); + }; + + function _filter(eachfn, arr, iterator, callback) { + var results = []; + eachfn(arr, function (x, index, callback) { + iterator(x, function (v) { + if (v) { + results.push({index: index, value: x}); + } + callback(); + }); + }, function () { + callback(_map(results.sort(function (a, b) { + return a.index - b.index; + }), function (x) { + return x.value; + })); + }); + } + + async.select = + async.filter = doParallel(_filter); + + async.selectLimit = + async.filterLimit = doParallelLimit(_filter); + + async.selectSeries = + async.filterSeries = doSeries(_filter); + + function _reject(eachfn, arr, iterator, callback) { + _filter(eachfn, arr, function(value, cb) { + iterator(value, function(v) { + cb(!v); + }); + }, callback); + } + async.reject = doParallel(_reject); + async.rejectLimit = doParallelLimit(_reject); + async.rejectSeries = doSeries(_reject); + + function _createTester(eachfn, check, getResult) { + return function(arr, limit, iterator, cb) { + function done() { + if (cb) cb(getResult(false, void 0)); + } + function iteratee(x, _, callback) { + if (!cb) return callback(); + iterator(x, function (v) { + if (cb && check(v)) { + cb(getResult(true, x)); + cb = iterator = false; + } + callback(); + }); + } + if (arguments.length > 3) { + eachfn(arr, limit, iteratee, done); + } else { + cb = iterator; + iterator = limit; + eachfn(arr, iteratee, done); + } + }; + } + + async.any = + async.some = _createTester(async.eachOf, toBool, identity); + + async.someLimit = _createTester(async.eachOfLimit, toBool, identity); + + async.all = + async.every = _createTester(async.eachOf, notId, notId); + + async.everyLimit = _createTester(async.eachOfLimit, notId, notId); + + function _findGetResult(v, x) { + return x; + } + async.detect = _createTester(async.eachOf, identity, _findGetResult); + async.detectSeries = _createTester(async.eachOfSeries, identity, _findGetResult); + async.detectLimit = _createTester(async.eachOfLimit, identity, _findGetResult); + + async.sortBy = function (arr, iterator, callback) { + async.map(arr, function (x, callback) { + iterator(x, function (err, criteria) { + if (err) { + callback(err); + } + else { + callback(null, {value: x, criteria: criteria}); + } + }); + }, function (err, results) { + if (err) { + return callback(err); + } + else { + callback(null, _map(results.sort(comparator), function (x) { + return x.value; + })); + } + + }); + + function comparator(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + } + }; + + async.auto = function (tasks, concurrency, callback) { + if (typeof arguments[1] === 'function') { + // concurrency is optional, shift the args. + callback = concurrency; + concurrency = null; + } + callback = _once(callback || noop); + var keys = _keys(tasks); + var remainingTasks = keys.length; + if (!remainingTasks) { + return callback(null); + } + if (!concurrency) { + concurrency = remainingTasks; + } + + var results = {}; + var runningTasks = 0; + + var hasError = false; + + var listeners = []; + function addListener(fn) { + listeners.unshift(fn); + } + function removeListener(fn) { + var idx = _indexOf(listeners, fn); + if (idx >= 0) listeners.splice(idx, 1); + } + function taskComplete() { + remainingTasks--; + _arrayEach(listeners.slice(0), function (fn) { + fn(); + }); + } + + addListener(function () { + if (!remainingTasks) { + callback(null, results); + } + }); + + _arrayEach(keys, function (k) { + if (hasError) return; + var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]]; + var taskCallback = _restParam(function(err, args) { + runningTasks--; + if (args.length <= 1) { + args = args[0]; + } + if (err) { + var safeResults = {}; + _forEachOf(results, function(val, rkey) { + safeResults[rkey] = val; + }); + safeResults[k] = args; + hasError = true; + + callback(err, safeResults); + } + else { + results[k] = args; + async.setImmediate(taskComplete); + } + }); + var requires = task.slice(0, task.length - 1); + // prevent dead-locks + var len = requires.length; + var dep; + while (len--) { + if (!(dep = tasks[requires[len]])) { + throw new Error('Has nonexistent dependency in ' + requires.join(', ')); + } + if (_isArray(dep) && _indexOf(dep, k) >= 0) { + throw new Error('Has cyclic dependencies'); + } + } + function ready() { + return runningTasks < concurrency && _reduce(requires, function (a, x) { + return (a && results.hasOwnProperty(x)); + }, true) && !results.hasOwnProperty(k); + } + if (ready()) { + runningTasks++; + task[task.length - 1](taskCallback, results); + } + else { + addListener(listener); + } + function listener() { + if (ready()) { + runningTasks++; + removeListener(listener); + task[task.length - 1](taskCallback, results); + } + } + }); + }; + + + + async.retry = function(times, task, callback) { + var DEFAULT_TIMES = 5; + var DEFAULT_INTERVAL = 0; + + var attempts = []; + + var opts = { + times: DEFAULT_TIMES, + interval: DEFAULT_INTERVAL + }; + + function parseTimes(acc, t){ + if(typeof t === 'number'){ + acc.times = parseInt(t, 10) || DEFAULT_TIMES; + } else if(typeof t === 'object'){ + acc.times = parseInt(t.times, 10) || DEFAULT_TIMES; + acc.interval = parseInt(t.interval, 10) || DEFAULT_INTERVAL; + } else { + throw new Error('Unsupported argument type for \'times\': ' + typeof t); + } + } + + var length = arguments.length; + if (length < 1 || length > 3) { + throw new Error('Invalid arguments - must be either (task), (task, callback), (times, task) or (times, task, callback)'); + } else if (length <= 2 && typeof times === 'function') { + callback = task; + task = times; + } + if (typeof times !== 'function') { + parseTimes(opts, times); + } + opts.callback = callback; + opts.task = task; + + function wrappedTask(wrappedCallback, wrappedResults) { + function retryAttempt(task, finalAttempt) { + return function(seriesCallback) { + task(function(err, result){ + seriesCallback(!err || finalAttempt, {err: err, result: result}); + }, wrappedResults); + }; + } + + function retryInterval(interval){ + return function(seriesCallback){ + setTimeout(function(){ + seriesCallback(null); + }, interval); + }; + } + + while (opts.times) { + + var finalAttempt = !(opts.times-=1); + attempts.push(retryAttempt(opts.task, finalAttempt)); + if(!finalAttempt && opts.interval > 0){ + attempts.push(retryInterval(opts.interval)); + } + } + + async.series(attempts, function(done, data){ + data = data[data.length - 1]; + (wrappedCallback || opts.callback)(data.err, data.result); + }); + } + + // If a callback is passed, run this as a controll flow + return opts.callback ? wrappedTask() : wrappedTask; + }; + + async.waterfall = function (tasks, callback) { + callback = _once(callback || noop); + if (!_isArray(tasks)) { + var err = new Error('First argument to waterfall must be an array of functions'); + return callback(err); + } + if (!tasks.length) { + return callback(); + } + function wrapIterator(iterator) { + return _restParam(function (err, args) { + if (err) { + callback.apply(null, [err].concat(args)); + } + else { + var next = iterator.next(); + if (next) { + args.push(wrapIterator(next)); + } + else { + args.push(callback); + } + ensureAsync(iterator).apply(null, args); + } + }); + } + wrapIterator(async.iterator(tasks))(); + }; + + function _parallel(eachfn, tasks, callback) { + callback = callback || noop; + var results = _isArrayLike(tasks) ? [] : {}; + + eachfn(tasks, function (task, key, callback) { + task(_restParam(function (err, args) { + if (args.length <= 1) { + args = args[0]; + } + results[key] = args; + callback(err); + })); + }, function (err) { + callback(err, results); + }); + } + + async.parallel = function (tasks, callback) { + _parallel(async.eachOf, tasks, callback); + }; + + async.parallelLimit = function(tasks, limit, callback) { + _parallel(_eachOfLimit(limit), tasks, callback); + }; + + async.series = function(tasks, callback) { + _parallel(async.eachOfSeries, tasks, callback); + }; + + async.iterator = function (tasks) { + function makeCallback(index) { + function fn() { + if (tasks.length) { + tasks[index].apply(null, arguments); + } + return fn.next(); + } + fn.next = function () { + return (index < tasks.length - 1) ? makeCallback(index + 1): null; + }; + return fn; + } + return makeCallback(0); + }; + + async.apply = _restParam(function (fn, args) { + return _restParam(function (callArgs) { + return fn.apply( + null, args.concat(callArgs) + ); + }); + }); + + function _concat(eachfn, arr, fn, callback) { + var result = []; + eachfn(arr, function (x, index, cb) { + fn(x, function (err, y) { + result = result.concat(y || []); + cb(err); + }); + }, function (err) { + callback(err, result); + }); + } + async.concat = doParallel(_concat); + async.concatSeries = doSeries(_concat); + + async.whilst = function (test, iterator, callback) { + callback = callback || noop; + if (test()) { + var next = _restParam(function(err, args) { + if (err) { + callback(err); + } else if (test.apply(this, args)) { + iterator(next); + } else { + callback.apply(null, [null].concat(args)); + } + }); + iterator(next); + } else { + callback(null); + } + }; + + async.doWhilst = function (iterator, test, callback) { + var calls = 0; + return async.whilst(function() { + return ++calls <= 1 || test.apply(this, arguments); + }, iterator, callback); + }; + + async.until = function (test, iterator, callback) { + return async.whilst(function() { + return !test.apply(this, arguments); + }, iterator, callback); + }; + + async.doUntil = function (iterator, test, callback) { + return async.doWhilst(iterator, function() { + return !test.apply(this, arguments); + }, callback); + }; + + async.during = function (test, iterator, callback) { + callback = callback || noop; + + var next = _restParam(function(err, args) { + if (err) { + callback(err); + } else { + args.push(check); + test.apply(this, args); + } + }); + + var check = function(err, truth) { + if (err) { + callback(err); + } else if (truth) { + iterator(next); + } else { + callback(null); + } + }; + + test(check); + }; + + async.doDuring = function (iterator, test, callback) { + var calls = 0; + async.during(function(next) { + if (calls++ < 1) { + next(null, true); + } else { + test.apply(this, arguments); + } + }, iterator, callback); + }; + + function _queue(worker, concurrency, payload) { + if (concurrency == null) { + concurrency = 1; + } + else if(concurrency === 0) { + throw new Error('Concurrency must not be zero'); + } + function _insert(q, data, pos, callback) { + if (callback != null && typeof callback !== "function") { + throw new Error("task callback must be a function"); + } + q.started = true; + if (!_isArray(data)) { + data = [data]; + } + if(data.length === 0 && q.idle()) { + // call drain immediately if there are no tasks + return async.setImmediate(function() { + q.drain(); + }); + } + _arrayEach(data, function(task) { + var item = { + data: task, + callback: callback || noop + }; + + if (pos) { + q.tasks.unshift(item); + } else { + q.tasks.push(item); + } + + if (q.tasks.length === q.concurrency) { + q.saturated(); + } + }); + async.setImmediate(q.process); + } + function _next(q, tasks) { + return function(){ + workers -= 1; + + var removed = false; + var args = arguments; + _arrayEach(tasks, function (task) { + _arrayEach(workersList, function (worker, index) { + if (worker === task && !removed) { + workersList.splice(index, 1); + removed = true; + } + }); + + task.callback.apply(task, args); + }); + if (q.tasks.length + workers === 0) { + q.drain(); + } + q.process(); + }; + } + + var workers = 0; + var workersList = []; + var q = { + tasks: [], + concurrency: concurrency, + payload: payload, + saturated: noop, + empty: noop, + drain: noop, + started: false, + paused: false, + push: function (data, callback) { + _insert(q, data, false, callback); + }, + kill: function () { + q.drain = noop; + q.tasks = []; + }, + unshift: function (data, callback) { + _insert(q, data, true, callback); + }, + process: function () { + while(!q.paused && workers < q.concurrency && q.tasks.length){ + + var tasks = q.payload ? + q.tasks.splice(0, q.payload) : + q.tasks.splice(0, q.tasks.length); + + var data = _map(tasks, function (task) { + return task.data; + }); + + if (q.tasks.length === 0) { + q.empty(); + } + workers += 1; + workersList.push(tasks[0]); + var cb = only_once(_next(q, tasks)); + worker(data, cb); + } + }, + length: function () { + return q.tasks.length; + }, + running: function () { + return workers; + }, + workersList: function () { + return workersList; + }, + idle: function() { + return q.tasks.length + workers === 0; + }, + pause: function () { + q.paused = true; + }, + resume: function () { + if (q.paused === false) { return; } + q.paused = false; + var resumeCount = Math.min(q.concurrency, q.tasks.length); + // Need to call q.process once per concurrent + // worker to preserve full concurrency after pause + for (var w = 1; w <= resumeCount; w++) { + async.setImmediate(q.process); + } + } + }; + return q; + } + + async.queue = function (worker, concurrency) { + var q = _queue(function (items, cb) { + worker(items[0], cb); + }, concurrency, 1); + + return q; + }; + + async.priorityQueue = function (worker, concurrency) { + + function _compareTasks(a, b){ + return a.priority - b.priority; + } + + function _binarySearch(sequence, item, compare) { + var beg = -1, + end = sequence.length - 1; + while (beg < end) { + var mid = beg + ((end - beg + 1) >>> 1); + if (compare(item, sequence[mid]) >= 0) { + beg = mid; + } else { + end = mid - 1; + } + } + return beg; + } + + function _insert(q, data, priority, callback) { + if (callback != null && typeof callback !== "function") { + throw new Error("task callback must be a function"); + } + q.started = true; + if (!_isArray(data)) { + data = [data]; + } + if(data.length === 0) { + // call drain immediately if there are no tasks + return async.setImmediate(function() { + q.drain(); + }); + } + _arrayEach(data, function(task) { + var item = { + data: task, + priority: priority, + callback: typeof callback === 'function' ? callback : noop + }; + + q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item); + + if (q.tasks.length === q.concurrency) { + q.saturated(); + } + async.setImmediate(q.process); + }); + } + + // Start with a normal queue + var q = async.queue(worker, concurrency); + + // Override push to accept second parameter representing priority + q.push = function (data, priority, callback) { + _insert(q, data, priority, callback); + }; + + // Remove unshift function + delete q.unshift; + + return q; + }; + + async.cargo = function (worker, payload) { + return _queue(worker, 1, payload); + }; + + function _console_fn(name) { + return _restParam(function (fn, args) { + fn.apply(null, args.concat([_restParam(function (err, args) { + if (typeof console === 'object') { + if (err) { + if (console.error) { + console.error(err); + } + } + else if (console[name]) { + _arrayEach(args, function (x) { + console[name](x); + }); + } + } + })])); + }); + } + async.log = _console_fn('log'); + async.dir = _console_fn('dir'); + /*async.info = _console_fn('info'); + async.warn = _console_fn('warn'); + async.error = _console_fn('error');*/ + + async.memoize = function (fn, hasher) { + var memo = {}; + var queues = {}; + var has = Object.prototype.hasOwnProperty; + hasher = hasher || identity; + var memoized = _restParam(function memoized(args) { + var callback = args.pop(); + var key = hasher.apply(null, args); + if (has.call(memo, key)) { + async.setImmediate(function () { + callback.apply(null, memo[key]); + }); + } + else if (has.call(queues, key)) { + queues[key].push(callback); + } + else { + queues[key] = [callback]; + fn.apply(null, args.concat([_restParam(function (args) { + memo[key] = args; + var q = queues[key]; + delete queues[key]; + for (var i = 0, l = q.length; i < l; i++) { + q[i].apply(null, args); + } + })])); + } + }); + memoized.memo = memo; + memoized.unmemoized = fn; + return memoized; + }; + + async.unmemoize = function (fn) { + return function () { + return (fn.unmemoized || fn).apply(null, arguments); + }; + }; + + function _times(mapper) { + return function (count, iterator, callback) { + mapper(_range(count), iterator, callback); + }; + } + + async.times = _times(async.map); + async.timesSeries = _times(async.mapSeries); + async.timesLimit = function (count, limit, iterator, callback) { + return async.mapLimit(_range(count), limit, iterator, callback); + }; + + async.seq = function (/* functions... */) { + var fns = arguments; + return _restParam(function (args) { + var that = this; + + var callback = args[args.length - 1]; + if (typeof callback == 'function') { + args.pop(); + } else { + callback = noop; + } + + async.reduce(fns, args, function (newargs, fn, cb) { + fn.apply(that, newargs.concat([_restParam(function (err, nextargs) { + cb(err, nextargs); + })])); + }, + function (err, results) { + callback.apply(that, [err].concat(results)); + }); + }); + }; + + async.compose = function (/* functions... */) { + return async.seq.apply(null, Array.prototype.reverse.call(arguments)); + }; + + + function _applyEach(eachfn) { + return _restParam(function(fns, args) { + var go = _restParam(function(args) { + var that = this; + var callback = args.pop(); + return eachfn(fns, function (fn, _, cb) { + fn.apply(that, args.concat([cb])); + }, + callback); + }); + if (args.length) { + return go.apply(this, args); + } + else { + return go; + } + }); + } + + async.applyEach = _applyEach(async.eachOf); + async.applyEachSeries = _applyEach(async.eachOfSeries); + + + async.forever = function (fn, callback) { + var done = only_once(callback || noop); + var task = ensureAsync(fn); + function next(err) { + if (err) { + return done(err); + } + task(next); + } + next(); + }; + + function ensureAsync(fn) { + return _restParam(function (args) { + var callback = args.pop(); + args.push(function () { + var innerArgs = arguments; + if (sync) { + async.setImmediate(function () { + callback.apply(null, innerArgs); + }); + } else { + callback.apply(null, innerArgs); + } + }); + var sync = true; + fn.apply(this, args); + sync = false; + }); + } + + async.ensureAsync = ensureAsync; + + async.constant = _restParam(function(values) { + var args = [null].concat(values); + return function (callback) { + return callback.apply(this, args); + }; + }); + + async.wrapSync = + async.asyncify = function asyncify(func) { + return _restParam(function (args) { + var callback = args.pop(); + var result; + try { + result = func.apply(this, args); + } catch (e) { + return callback(e); + } + // if result is Promise object + if (_isObject(result) && typeof result.then === "function") { + result.then(function(value) { + callback(null, value); + })["catch"](function(err) { + callback(err.message ? err : new Error(err)); + }); + } else { + callback(null, result); + } + }); + }; + + // Node.js + if (typeof module === 'object' && module.exports) { + module.exports = async; + } + // AMD / RequireJS + else if (typeof define === 'function' && define.amd) { + define([], function () { + return async; + }); + } + // included directly via + + + + +
+ + + \ No newline at end of file diff --git a/Other versions/SinglePage/scripts/Ball.js b/Other versions/SinglePage/scripts/Ball.js new file mode 100644 index 0000000..943ed18 --- /dev/null +++ b/Other versions/SinglePage/scripts/Ball.js @@ -0,0 +1,30 @@ +define(["DrawFunctions","Calculations"],function(drawFunctions,Calculations) { +return function Ball(startx,starty, vx, vy, radius,commonValues) { + this.x = startx; + this.y = starty; + this.radius = radius; + this.xd = Calculations.randomsign(); + this.yd = Calculations.randomsign(); + this.dx = vx; + this.dy = vy; + this.move = function() { + if ((this.x > commonValues.height-this.radius && this.xd > 0)|| (this.x < this.radius && this.xd < 0)) { + this.xd = -this.xd; + } + if ((this.y > commonValues.width-this.radius && this.yd > 0) || (this.y < this.radius && this.yd < 0)) { + this.yd = -this.yd; + } + + this.x = this.x + this.dx * this.xd; + this.y = this.y + this.dy * this.yd; + } + + this.shape = function() { + return new Calculations.circle(this.x,this.y,this.radius); + } + + this.draw = function(ctx) { + drawFunctions.drawBall(this.x, this.y, this.radius,ctx,"green"); + } +} +}) \ No newline at end of file diff --git a/Other versions/SinglePage/scripts/Calculations.js b/Other versions/SinglePage/scripts/Calculations.js new file mode 100644 index 0000000..ae45bf7 --- /dev/null +++ b/Other versions/SinglePage/scripts/Calculations.js @@ -0,0 +1,114 @@ +define(function() { + return { + // Shape objects: + circle: function (x,y,radius) { + this.x = x; + this.y = y; + this.r = radius; + }, + + rectangle: + function rectangle(x,y,width,height) { + this.x = x; + this.y = y; + this.w = width; + this.h = height; + }, + + //distance calculator (between two points) + dist: function(x1,y1,x2,y2) { + return Math.sqrt(Math.pow(Math.abs(x1 - x2),2) + Math.pow(Math.abs(y1 - y2),2)); + }, + + + + randomsign: function () { + var i = this.random(0, 1); + if (i == 0) { + return -1; + } else { + return 1; + } + }, + + sign: function(i) { + if (i > 0) { + return 1; + } else if (i < 0) { + return -1; + } else { + return 0; + } + }, + + random: function(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + }, + + CircleCircleColliding: function(c1,c2) { + var dist = this.dist(c1.x , c1.y , c2.x , c2.y); + if (dist < Math.max(c1.r,c2.r)) { + return true; + } + return false; + }, + + RectRectColliding: function(r1,r2) { + var distX = Math.abs(r1.x + r1.w/2 - r2.x - r2.w/2); + var distY = Math.abs(r1.y + r1.h/2 - r2.y - r2.h/2); + + if (distX > (r1.w + r2.w)/2) { + return false; + } else if (distY > (r1.h + r2.h)/2) { + return false; + } else { + return true; + } + }, + + RectCircleColliding: function(circle,rect){ + var distX = Math.abs(circle.x - rect.x-rect.w/2); + var distY = Math.abs(circle.y - rect.y-rect.h/2); + + if (distX > (rect.w/2 + circle.r)) { return false; } + if (distY > (rect.h/2 + circle.r)) { return false; } + + if (distX <= (rect.w/2)) { return true; } + if (distY <= (rect.h/2)) { return true; } + + var dx=distX-rect.w/2; + var dy=distY-rect.h/2; + return (dx*dx+dy*dy<=(circle.r*circle.r)); + }, + + /** + * + * @param a the starting position + * @param b the end position + * @param max the maximum value (i.e. 360 for degrees in circle + * @returns {number} in {-1,0,1}, which direction is shortest + */ + shortestDirection: function (a, b, max) { + var ans; + if (b - a > max / 2) { + ans = b - a - max; + } else if (b - a > -max / 2) { + ans = b - a; + } else { + ans = b - a + max; + } + + if (ans > 0) { + return 1; + } else if (ans < 0) { + return -1; + } else { + return 0; + } + +} + + + + } +}) \ No newline at end of file diff --git a/Other versions/SinglePage/scripts/DrawFunctions.js b/Other versions/SinglePage/scripts/DrawFunctions.js new file mode 100644 index 0000000..c901ad7 --- /dev/null +++ b/Other versions/SinglePage/scripts/DrawFunctions.js @@ -0,0 +1,21 @@ +define(function() { +function drawBall(x,y,r,ctx,color) { + ctx.beginPath(); + ctx.arc(x, y, r, 0, Math.PI*2, false); + ctx.fillStyle = color; + ctx.fill(); + ctx.closePath(); +} + +function drawRect(x,y,w,h,ctx,color) { + ctx.beginPath(); + ctx.rect(x,y,w,h); + ctx.fillStyle = color; + ctx.fill(); + ctx.closePath(); +} +return { + drawBall: drawBall, + drawRect: drawRect +} +}) \ No newline at end of file diff --git a/Other versions/SinglePage/scripts/GameFlow.js b/Other versions/SinglePage/scripts/GameFlow.js new file mode 100644 index 0000000..e39fd9b --- /dev/null +++ b/Other versions/SinglePage/scripts/GameFlow.js @@ -0,0 +1,214 @@ +define(["GameValueHandler","Music","Calculations", +"Paddle","Ball","SeekerBall","StealthBall","Pickup" +],function(GameValueHandler,music,Calculations, +Paddle,Ball,SeekerBall ,StealthBall ,Pickup +) { +var canvas; +var gameState = new GameValueHandler(); +var myFont = "Arial" +var fillStyle = "#dd0095"; +var ctx +var p; +var objects; +var endFunc; +var timeLeft = 30; +var countervalue = 0; +var gracetimer = 0; +var grace = false; + +var commonValues; + + function initiate(aCanvas,endFunction,ctrlHandler) { + canvas = aCanvas; + ctx = canvas.ctx; + endFunc = endFunction; + gameState.init(canvas.width, canvas.height); + timeLeft = 30; + countervalue = 0; + gracetimer = 0; + p = new Paddle(canvas.height/2, canvas.width/2, + gameState.playerLength,ctrlHandler, gameState.playerSpeed); + + commonValues = { + width: canvas.width, + height: canvas.height, + stealthBallticks: gameState.stealthBallticks, + p: p + } + + objects = []; + + addPickUp(); + music.playMain(); + doTurn(); + } + +function doTurn() { + if (gameState.playerdead) { + endgame(); + return; + } + + //reset canvas + ctx.clearRect(0, 0, canvas.width, canvas.height); + + //text drawing + setFont(40); + ctx.fillText("Level: "+ gameState.level, 20, 20); + ctx.fillText("Squares Gathered: "+gameState.score, 20, 40); + ctx.fillText("Survive for: "+timeLeft, 20, 60); + + //grace text + if (grace) { + setFont(10); + ctx.fillText("Level Complete", canvas.width/4, canvas.height/4); + } + + //move player + p.move(); + p.draw(ctx); + + // check if pickup has been picked up + if (!grace) { + pickup.draw(ctx); + if (Calculations.RectRectColliding(p.shape(), pickup.shape())) { + addPickUp(); + gameState.score++; + } + } + + //move balls + for (var int = 0; int < objects.length; int++) { + var object = objects[int]; + + object.move(); + if (Calculations.RectCircleColliding(object.shape(), p.shape())) { + gameState.playerdead = true; + object.visible = true; + } + object.draw(ctx); + } + + //end of level + if (timeLeft == 0 && !grace) { + //Pause Music + music.playPause(); + //tick up level + gameState.levelup(); + //enter grace period + gracetimer = gameState.graceperiod; + grace = true; + //reset "game board" + objects = []; + pickup = null; + timeLeft = gameState.levelduration; + } + + //end of grace + if (grace && gracetimer == 0) { + grace = false; + //start Music Again + music.playMain(); + + addStealthBall(); + addSeekerBall(); + addPickUp(); + for (i = 0; i < gameState.initialballs; i++) { + addBall(); + } + } + + //grace countdown + else if (grace) { + gracetimer = gracetimer - 1; + } + + //level countdown + else if (count() && !(grace)) { + for (i = 0; i < gameState.ballspertick; i++) { + addBall(); + } + timeLeft--; + } + + requestAnimationFrame(doTurn); +} + +function setFont(quotent) { + ctx.font = (canvas.width/quotent)+"px " + myFont; + ctx.fillStyle = fillStyle; +} + + +//checks if addBall-tick has come (and counts up) +function count() { + countervalue++; + if (countervalue > gameState.tickperball) { + countervalue = 0; + return true; + } + return false; +} + +function addObject(object) { + //set starting position + var currentdist = 0; + let startx; + let starty; + while (currentdist < gameState.minDist) { + startx = Calculations.random(0, canvas.height); + starty = Calculations.random(0, canvas.width); + currentdist = Calculations.dist(startx, starty, p.x, p.y); + } + + //set speed + vx = Calculations.random(gameState.minBallspeed, gameState.maxBallspeed); + vy = Calculations.random(gameState.minBallspeed, gameState.maxBallspeed); + + //set size + radius = Calculations.random(gameState.minballRadius,gameState.maxballRadius); + + //add to ball list + let newObject = new object(startx, starty, vx, vy, radius,commonValues); + objects.push(newObject); + return newObject; +} + +function addBall() { + addObject(Ball); +} + +function addStealthBall() { + addObject(StealthBall); +} + +function addSeekerBall() { + addObject(SeekerBall); +} + +function addPickUp() { + //set position + let x; + let y; + var currentdist = 0; + while (currentdist < gameState.minDist) { + x = Calculations.random(gameState.pickupLength , canvas.height-gameState.pickupLength ); + y = Calculations.random(gameState.pickupLength , canvas.width-gameState.pickupLength ); + currentdist = Calculations.dist(x, y, p.x, p.y); + } + //add Pickup + pickup = new Pickup(x,y,gameState.pickupLength ); +} + +//ending the game, when player dies +function endgame() { + music.playGameOver(); + endFunc({score:gameState.score,level:gameState.level}); +} + + +return { + initiateGame: initiate +} + +}) \ No newline at end of file diff --git a/Other versions/SinglePage/scripts/GameValueHandler.js b/Other versions/SinglePage/scripts/GameValueHandler.js new file mode 100644 index 0000000..7c24364 --- /dev/null +++ b/Other versions/SinglePage/scripts/GameValueHandler.js @@ -0,0 +1,80 @@ +define(function() { + function dist(x1,y1,x2,y2) { + return Math.sqrt(Math.pow(Math.abs(x1 - x2),2) + Math.pow(Math.abs(y1 - y2),2)); + } + + +return function GameValueHandler() { + this.level = 1; + this.maxBallspeed; + this.minBallspeed; + this.maxballRadius; + this.minballRadius; + this.initialballs; //balls at the start of the level + this.levelduration; + this.tickperball; //how often new ball is created + this.ballspertick; //how many balls are created at once + this.basemaxBallspeed; + this.baseminBallspeed; + + this.durationTickUp = 5; + + this.baseForDurationIncrease = 0; + this.baseForSpeedIncrease = 2; + this.baseForBallsPerTickIncrease = 0; + this.baseForTicksPerBallDecrease = 3; + + this.ticksForDurationIncrease = 3; + this.ticksForSpeedIncrease = 4; + this.ticksForBallsPerTickIncrease = 5; + this.ticksForTicksPerBallDecrease = 5; + + this.levelup = function(){ + this.level++; + this.initialballs++; + if ((this.level % this.ticksForDurationIncrease) + this.baseForDurationIncrease == 0) { + this.levelduration += this.durationTickUp; + } + if ((this.level % this.ticksForSpeedIncrease) + this.baseForSpeedIncrease == 0) { + this.maxBallspeed += this.basemaxBallspeed; + this.minBallspeed += this.baseminBallspeed; + } + if ((this.level % this.baseForBallsPerTickIncrease) + this.baseForBallsPerTickIncrease == 0) { + this.ballspertick++; + } + if ((this.level % this.baseForTicksPerBallDecrease) + this.baseForTicksPerBallDecrease == 0) { + this.ticksperball--; + } + } + + + this.init = function(width,height) { + let averageSize = (Math.abs(width) + Math.abs(height)) / 2; + + this.playerLength = averageSize / 56; + this.playerSpeed = averageSize / 143; + this.pickupLength = averageSize / 50; + + this.minDist = dist(0,0,width,height) / 4; + + this.graceperiod = 100; + this.stealthBallticks = 100; + + this.playerdead = false; + this.scorenotsubmitted = true; + this.score = 0; + + this.level = 1; + this.basemaxBallspeed = averageSize / 200; + this.baseminBallspeed = averageSize / 1000; + this.maxBallspeed = this.basemaxBallspeed; + this.minBallspeed = this.baseminBallspeed; + this.maxballRadius = averageSize / 70; + this.minballRadius = averageSize / 200; + this.initialballs = 1; + this.levelduration = 30; + this.tickperball = 20; + this.ballspertick = 1; + } +} +}) \ No newline at end of file diff --git a/Other versions/SinglePage/scripts/Initialization.js b/Other versions/SinglePage/scripts/Initialization.js new file mode 100644 index 0000000..ea5ca4b --- /dev/null +++ b/Other versions/SinglePage/scripts/Initialization.js @@ -0,0 +1,33 @@ +require(["menuState","State"], function(menuState,State) { + var canvas = {}; + var ctx; + var p; + var pickup; + var objects; + var height; + var width; + var mindist = 4; + var leaderboard; + var squared = true; + + init = function () { + + // Initialize canvas + canvas.dom = document.getElementById("myCanvas"); + canvas.ctx = canvas.dom.getContext("2d"); + + if (squared) { + let size = Math.min(window.innerWidth,window.innerHeight); + canvas.dom.width = canvas.height = size; + canvas.dom.height = canvas.width = size; + } else { + canvas.dom.width = canvas.height = window.innerWidth; + canvas.dom.height = canvas.width = window.innerHeight; + } + var controller = State.stateController(menuState,canvas); + }; + + init(); + +}); + diff --git a/Other versions/SinglePage/scripts/Leaderboard.js b/Other versions/SinglePage/scripts/Leaderboard.js new file mode 100644 index 0000000..76e7fe9 --- /dev/null +++ b/Other versions/SinglePage/scripts/Leaderboard.js @@ -0,0 +1,62 @@ +define(function() { +let firebaseURI = "https://leaderboard-bf98b.firebaseio.com"; + + var config = { + apiKey: "AIzaSyDnQy8gUVUldROZM3hxjg2_M3FE7Yg_cSc", + authDomain: "leaderboard-bf98b.firebaseapp.com", + databaseURL: "https://leaderboard-bf98b.firebaseio.com", + storageBucket: "leaderboard-bf98b.appspot.com", + }; + firebase.initializeApp(config); + +let Leaderboard = function(){ + this.firebase = firebase.database(); + this.firebase.ref("scores").orderByChild("score").limitToLast(5).on("value", (value) => { + this.scores = value.val() + }); + + + this.add = function(data) { + this.firebase.ref("scores").push(data).setPriority(data.score) + }; + + /* + * assumed that data is valid + */ + this.addandgo = function(data,go) { + this.firebase.ref("scores").push(data).setPriority(data.score).then(go, function(){ + console.log("fail"); + }); + }; + + this.get = function() { + throw new Error("this shouldn't happen"); + var list = []; + var running = true; + this.firebase.ref("scores").orderByChild("score").once("value").then( + function(snapshot) { + snapshot.forEach(function(childSnapshot) { + list.push(childSnapshot.val()); + }) + running = false; + }); + }; + + this.getandgo = function(go,limit) { + let query = this.firebase.ref("scores").orderByChild("score"); + if (limit!=null) { + query = query.limitToLast(limit); + } + query.once("value").then( + function(snapshot) { + let list = []; + snapshot.forEach(function(childSnapshot) { + list.push(childSnapshot.val()); + }); + go(list); + }); + }; +}; + +return new Leaderboard(); +}); \ No newline at end of file diff --git a/Other versions/SinglePage/scripts/Music.js b/Other versions/SinglePage/scripts/Music.js new file mode 100644 index 0000000..a19a9ca --- /dev/null +++ b/Other versions/SinglePage/scripts/Music.js @@ -0,0 +1,53 @@ +define(function() { +var music = new Music(); + +function Music() { + this.audio = new Audio('soundFiles/Retro.wav'); + this.audio.loop = true; + this.sounds = new Audio(); + this.volume = 1; + this.muted = false; + + this.playMain = function() { + this.sounds.pause(); + this.audio.play(); + } + + this.playGameOver = function() { + this.audio.pause(); + this.sounds.src = 'soundFiles/gameOver2.wav'; + this.sounds.play(); + } + + this.playPause = function() { + this.audio.pause(); + } + + this.pause = function() { + this.audio.pause(); + } + + this.stop = function() { + this.audio.pause(); + } + + this.toggleMute = function() { + if (this.muted) { + this.audio.volume = this.volume; + } else { + this.audio.volume = 0; + } + this.muted = !this.muted; + } + + this.setVolume = function(value) { + this.audio.volume = value; + } + + this.changeVolume = function(change) { + this.audio.volume += value; + } +} + +return music; +}) diff --git a/Other versions/SinglePage/scripts/Paddle.js b/Other versions/SinglePage/scripts/Paddle.js new file mode 100644 index 0000000..da89dc2 --- /dev/null +++ b/Other versions/SinglePage/scripts/Paddle.js @@ -0,0 +1,19 @@ +define(["DrawFunctions","Calculations"],function(drawFunctions,Calculations) { +return function Paddle(ax,ay,length,controller,playerSpeed) { + this.x = ax; + this.y = ay; + this.width = length; + this.height = length; + this.move = function(nx,ny) { + controller.playerControl(this,playerSpeed); + } + + this.shape = function(){ + return new Calculations.rectangle(this.x,this.y,this.width,this.height); + } + + this.draw = function(ctx) { + drawFunctions.drawRect(this.x, this.y, this.width, this.height,ctx,"#0095DD"); + } +} +}) \ No newline at end of file diff --git a/Other versions/SinglePage/scripts/Pickup.js b/Other versions/SinglePage/scripts/Pickup.js new file mode 100644 index 0000000..e6ee14b --- /dev/null +++ b/Other versions/SinglePage/scripts/Pickup.js @@ -0,0 +1,16 @@ +define(["DrawFunctions","Calculations"],function(drawFunctions,Calculations) { + return function Pickup(x,y,length) { + this.x = x; + this.y = y; + this.width = length; + this.height = length; + + this.shape = function(){ + return new Calculations.rectangle(this.x,this.y,this.width,this.height); + } + + this.draw = function(ctx) { + drawFunctions.drawRect(this.x, this.y, this.width, this.height,ctx,"#FFA500"); + } + } +}) \ No newline at end of file diff --git a/Other versions/SinglePage/scripts/SeekerBall.js b/Other versions/SinglePage/scripts/SeekerBall.js new file mode 100644 index 0000000..41b99b0 --- /dev/null +++ b/Other versions/SinglePage/scripts/SeekerBall.js @@ -0,0 +1,40 @@ +define(["DrawFunctions","Calculations","Ball"],function(drawFunctions,Calculations,Ball) { + +return function SeekerBall(startx,starty, vx, vy, radius,commonValues) { + this.target = commonValues.p; + this.base = new Ball(startx,starty, vx, vy, radius,commonValues); + this.speed = (Math.abs(this.base.dx) + Math.abs(this.base.dy)) / 2; + this.maxTurn = 0.1; + this.currentDirection = 0; + + this.move = function() { + this.determineDirection(); + this.base.x -= this.speed * Math.cos(this.currentDirection); + this.base.y -= this.speed * Math.sin(this.currentDirection); + }; + + this.determineDirection = function() { + DesiredDirection = Math.atan2((this.target.y - this.base.y) , (this.target.x - this.base.x)) + Math.PI; + /* if (this.currentDirection < 0) { + this.currentDirection = (2*Math.PI) - this.currentDirection; + } else if (this.currentDirection > (2*Math.PI)) { + this.currentDirection %= (2*Math.PI); + } + */ + let change = this.currentDirection-DesiredDirection; + if (Math.abs(change) height) { + object.x = height-object.height; + } + + if (object.y < 0) { + object.y = 0; + } else if (object.y + object.width > width) { + object.y = width-object.width; + } + } + + this.keyDown = function(e) { + if(e.keyCode == settings.downKey) { + downPressed = true; + } else if(e.keyCode == settings.rightKey) { + rightPressed = true; + } else if(e.keyCode == settings.upKey) { + upPressed = true; + } else if(e.keyCode == settings.leftKey) { + leftPressed = true; + } else if(e.keyCode == settings.muteKey) { + music.toggleMute(); + } + } + + this.keyUp = function(e) { + if(e.keyCode == settings.downKey) { + downPressed = false; + } + else if(e.keyCode == settings.rightKey) { + rightPressed = false; + } + else if(e.keyCode == settings.upKey) { + upPressed = false; + } + else if(e.keyCode == settings.leftKey) { + leftPressed = false; + } + } + this.playerControl = keyboardControl; + } + return gameControlHandler; +}) \ No newline at end of file diff --git a/Other versions/SinglePage/scripts/gameState.js b/Other versions/SinglePage/scripts/gameState.js new file mode 100644 index 0000000..fc6fcf6 --- /dev/null +++ b/Other versions/SinglePage/scripts/gameState.js @@ -0,0 +1,23 @@ +define(["GameFlow","settings", "gameControlHandler"], +function(gameflow,settings,gameControlHandler) { + + function gameState(controller,canvas) { + settings.updateSettings(); + let gameCtrlHandler = new gameControlHandler(canvas.width, canvas.height); + this.init = function() { + canvas.dom.style.display = "block"; + gameflow.initiateGame(canvas, + function(gameData){controller.changeState("highscoreState",gameData)} + ,gameCtrlHandler); + } + this.end = function() { + canvas.dom.style.display = "none"; + } + this.keydownHandler = gameCtrlHandler.keyDown; + this.keyupHandler = gameCtrlHandler.keyUp; + } + + return { + gameState: gameState + } +}); \ No newline at end of file diff --git a/Other versions/SinglePage/scripts/highscoreState.js b/Other versions/SinglePage/scripts/highscoreState.js new file mode 100644 index 0000000..2617007 --- /dev/null +++ b/Other versions/SinglePage/scripts/highscoreState.js @@ -0,0 +1,59 @@ +define(["Leaderboard","settings"],function(leaderboard,settings) { + let localHighscore = 0; + + function submitScore(playername,score,level,controlMethod,controller) { + let data = {"name": playername, + "score": score, + "level": level, + "method": controlMethod}; + console.log(data); + leaderboard.addandgo(data,function(){ + controller.changeState("menuState"); + }); + + } + + highscoreState = function(controller,globalValues) { + this.OuterDiv = document.getElementById("outerDiv"); + this.init = function() { + let name; + if(settings.autoSubmit) { + name = settings.playerAutoName; + } else { + name = getPlayerName(); + } + this.OuterDiv.innerHTML = + "

Submitting score

"; + + submitScore(name, + globalValues.extra.score, + globalValues.extra.level, + settings.controlMethod, + controller); + } + this.end = function() { + this.OuterDiv.innerHTML =""; + } + + this.keydownHandler = function(e) { + } + this.keyupHandler = function(e) { + } + } + + function getPlayerName() { + // setWriteMode(); alternative method, not yet implemented + let playername; + do { + playername = prompt("Player name (max " + maxplayernamelength +" characters)"); + if (playername == null) { + return null; + } + } while ((playername.length <= 0) || (playername.length > maxplayernamelength)) + // Ask for playername until proper name is given, or cancel is chosen. + return playername; + } + + + return highscoreState; +}); \ No newline at end of file diff --git a/Other versions/SinglePage/scripts/menuState.js b/Other versions/SinglePage/scripts/menuState.js new file mode 100644 index 0000000..282a8b4 --- /dev/null +++ b/Other versions/SinglePage/scripts/menuState.js @@ -0,0 +1,62 @@ +define(["settings"],function(settings) { + var myFont = "Arial" + var fillStyle = "green"; + + function setMenuText(canvas) { + //reset canvas + canvas.ctx.clearRect(0, 0, canvas.width, canvas.height); + setFont(canvas,5); + + canvas.ctx.fillText("BallsBalls", canvas.width/15, canvas.height/4); + + setFont(canvas,15); + //text drawing + let displayWidth = canvas.width/10; + let displayHeight = canvas.height/2; + let heightOffset = canvas.width/12; + + canvas.ctx.fillText("Press Space to Play Game", displayWidth, displayHeight); + canvas.ctx.fillText("Press i for settings", displayWidth, displayHeight+heightOffset*1); + canvas.ctx.fillText("Press h for Leaderboard", displayWidth, displayHeight+heightOffset*2); + } + + function setFont(canvas,quotent) { + canvas.ctx.font = (canvas.width/quotent)+"px " + myFont; + canvas.ctx.fillStyle = fillStyle; + } + + function menuState(controller,canvas) { + + this.init = function() { + console.log("starting Menu!"); + canvas.dom.style.display = "block"; + setMenuText(canvas); + + } + this.end = function() { + console.log("ending Menu!"); + canvas.dom.style.display = "none"; + } + + this.keydownHandler = function(e) { + if (e.keyCode == settings.restartKey) { + controller.changeState("gameState"); + } else if (e.keyCode == settings.settingsKey) { + controller.changeState("settingsState"); + } else if (e.keyCode == settings.HighscoreKey) { + controller.changeState("highscoreState"); + } + } + this.keyupHandler = function(e) { + } + } + + return menuState; + +}); + + + + + + diff --git a/Other versions/SinglePage/scripts/require.js b/Other versions/SinglePage/scripts/require.js new file mode 100644 index 0000000..c32e6c1 --- /dev/null +++ b/Other versions/SinglePage/scripts/require.js @@ -0,0 +1,5 @@ +/** vim: et:ts=4:sw=4:sts=4 + * @license RequireJS 2.3.3 Copyright jQuery Foundation and other contributors. + * Released under MIT license, https://github.com/requirejs/requirejs/blob/master/LICENSE + */ +var requirejs,require,define;!function(global,setTimeout){function commentReplace(e,t){return t||""}function isFunction(e){return"[object Function]"===ostring.call(e)}function isArray(e){return"[object Array]"===ostring.call(e)}function each(e,t){if(e){var i;for(i=0;i-1&&(!e[i]||!t(e[i],i,e));i-=1);}}function hasProp(e,t){return hasOwn.call(e,t)}function getOwn(e,t){return hasProp(e,t)&&e[t]}function eachProp(e,t){var i;for(i in e)if(hasProp(e,i)&&t(e[i],i))break}function mixin(e,t,i,r){return t&&eachProp(t,function(t,n){!i&&hasProp(e,n)||(!r||"object"!=typeof t||!t||isArray(t)||isFunction(t)||t instanceof RegExp?e[n]=t:(e[n]||(e[n]={}),mixin(e[n],t,i,r)))}),e}function bind(e,t){return function(){return t.apply(e,arguments)}}function scripts(){return document.getElementsByTagName("script")}function defaultOnError(e){throw e}function getGlobal(e){if(!e)return e;var t=global;return each(e.split("."),function(e){t=t[e]}),t}function makeError(e,t,i,r){var n=new Error(t+"\nhttp://requirejs.org/docs/errors.html#"+e);return n.requireType=e,n.requireModules=r,i&&(n.originalError=i),n}function newContext(e){function t(e){var t,i;for(t=0;t0&&(e.splice(t-1,2),t-=2)}}function i(e,i,r){var n,o,a,s,u,c,d,p,f,l,h,m,g=i&&i.split("/"),v=y.map,x=v&&v["*"];if(e&&(e=e.split("/"),d=e.length-1,y.nodeIdCompat&&jsSuffixRegExp.test(e[d])&&(e[d]=e[d].replace(jsSuffixRegExp,"")),"."===e[0].charAt(0)&&g&&(m=g.slice(0,g.length-1),e=m.concat(e)),t(e),e=e.join("/")),r&&v&&(g||x)){a=e.split("/");e:for(s=a.length;s>0;s-=1){if(c=a.slice(0,s).join("/"),g)for(u=g.length;u>0;u-=1)if(o=getOwn(v,g.slice(0,u).join("/")),o&&(o=getOwn(o,c))){p=o,f=s;break e}!l&&x&&getOwn(x,c)&&(l=getOwn(x,c),h=s)}!p&&l&&(p=l,f=h),p&&(a.splice(0,f,p),e=a.join("/"))}return n=getOwn(y.pkgs,e),n?n:e}function r(e){isBrowser&&each(scripts(),function(t){if(t.getAttribute("data-requiremodule")===e&&t.getAttribute("data-requirecontext")===q.contextName)return t.parentNode.removeChild(t),!0})}function n(e){var t=getOwn(y.paths,e);if(t&&isArray(t)&&t.length>1)return t.shift(),q.require.undef(e),q.makeRequire(null,{skipMap:!0})([e]),!0}function o(e){var t,i=e?e.indexOf("!"):-1;return i>-1&&(t=e.substring(0,i),e=e.substring(i+1,e.length)),[t,e]}function a(e,t,r,n){var a,s,u,c,d=null,p=t?t.name:null,f=e,l=!0,h="";return e||(l=!1,e="_@r"+(T+=1)),c=o(e),d=c[0],e=c[1],d&&(d=i(d,p,n),s=getOwn(j,d)),e&&(d?h=r?e:s&&s.normalize?s.normalize(e,function(e){return i(e,p,n)}):e.indexOf("!")===-1?i(e,p,n):e:(h=i(e,p,n),c=o(h),d=c[0],h=c[1],r=!0,a=q.nameToUrl(h))),u=!d||s||r?"":"_unnormalized"+(A+=1),{prefix:d,name:h,parentMap:t,unnormalized:!!u,url:a,originalName:f,isDefine:l,id:(d?d+"!"+h:h)+u}}function s(e){var t=e.id,i=getOwn(S,t);return i||(i=S[t]=new q.Module(e)),i}function u(e,t,i){var r=e.id,n=getOwn(S,r);!hasProp(j,r)||n&&!n.defineEmitComplete?(n=s(e),n.error&&"error"===t?i(n.error):n.on(t,i)):"defined"===t&&i(j[r])}function c(e,t){var i=e.requireModules,r=!1;t?t(e):(each(i,function(t){var i=getOwn(S,t);i&&(i.error=e,i.events.error&&(r=!0,i.emit("error",e)))}),r||req.onError(e))}function d(){globalDefQueue.length&&(each(globalDefQueue,function(e){var t=e[0];"string"==typeof t&&(q.defQueueMap[t]=!0),O.push(e)}),globalDefQueue=[])}function p(e){delete S[e],delete k[e]}function f(e,t,i){var r=e.map.id;e.error?e.emit("error",e.error):(t[r]=!0,each(e.depMaps,function(r,n){var o=r.id,a=getOwn(S,o);!a||e.depMatched[n]||i[o]||(getOwn(t,o)?(e.defineDep(n,j[o]),e.check()):f(a,t,i))}),i[r]=!0)}function l(){var e,t,i=1e3*y.waitSeconds,o=i&&q.startTime+i<(new Date).getTime(),a=[],s=[],u=!1,d=!0;if(!x){if(x=!0,eachProp(k,function(e){var i=e.map,c=i.id;if(e.enabled&&(i.isDefine||s.push(e),!e.error))if(!e.inited&&o)n(c)?(t=!0,u=!0):(a.push(c),r(c));else if(!e.inited&&e.fetched&&i.isDefine&&(u=!0,!i.prefix))return d=!1}),o&&a.length)return e=makeError("timeout","Load timeout for modules: "+a,null,a),e.contextName=q.contextName,c(e);d&&each(s,function(e){f(e,{},{})}),o&&!t||!u||!isBrowser&&!isWebWorker||w||(w=setTimeout(function(){w=0,l()},50)),x=!1}}function h(e){hasProp(j,e[0])||s(a(e[0],null,!0)).init(e[1],e[2])}function m(e,t,i,r){e.detachEvent&&!isOpera?r&&e.detachEvent(r,t):e.removeEventListener(i,t,!1)}function g(e){var t=e.currentTarget||e.srcElement;return m(t,q.onScriptLoad,"load","onreadystatechange"),m(t,q.onScriptError,"error"),{node:t,id:t&&t.getAttribute("data-requiremodule")}}function v(){var e;for(d();O.length;){if(e=O.shift(),null===e[0])return c(makeError("mismatch","Mismatched anonymous define() module: "+e[e.length-1]));h(e)}q.defQueueMap={}}var x,b,q,E,w,y={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},S={},k={},M={},O=[],j={},P={},R={},T=1,A=1;return E={require:function(e){return e.require?e.require:e.require=q.makeRequire(e.map)},exports:function(e){if(e.usingExports=!0,e.map.isDefine)return e.exports?j[e.map.id]=e.exports:e.exports=j[e.map.id]={}},module:function(e){return e.module?e.module:e.module={id:e.map.id,uri:e.map.url,config:function(){return getOwn(y.config,e.map.id)||{}},exports:e.exports||(e.exports={})}}},b=function(e){this.events=getOwn(M,e.id)||{},this.map=e,this.shim=getOwn(y.shim,e.id),this.depExports=[],this.depMaps=[],this.depMatched=[],this.pluginMaps={},this.depCount=0},b.prototype={init:function(e,t,i,r){r=r||{},this.inited||(this.factory=t,i?this.on("error",i):this.events.error&&(i=bind(this,function(e){this.emit("error",e)})),this.depMaps=e&&e.slice(0),this.errback=i,this.inited=!0,this.ignore=r.ignore,r.enabled||this.enabled?this.enable():this.check())},defineDep:function(e,t){this.depMatched[e]||(this.depMatched[e]=!0,this.depCount-=1,this.depExports[e]=t)},fetch:function(){if(!this.fetched){this.fetched=!0,q.startTime=(new Date).getTime();var e=this.map;return this.shim?void q.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],bind(this,function(){return e.prefix?this.callPlugin():this.load()})):e.prefix?this.callPlugin():this.load()}},load:function(){var e=this.map.url;P[e]||(P[e]=!0,q.load(this.map.id,e))},check:function(){if(this.enabled&&!this.enabling){var e,t,i=this.map.id,r=this.depExports,n=this.exports,o=this.factory;if(this.inited){if(this.error)this.emit("error",this.error);else if(!this.defining){if(this.defining=!0,this.depCount<1&&!this.defined){if(isFunction(o)){if(this.events.error&&this.map.isDefine||req.onError!==defaultOnError)try{n=q.execCb(i,o,r,n)}catch(t){e=t}else n=q.execCb(i,o,r,n);if(this.map.isDefine&&void 0===n&&(t=this.module,t?n=t.exports:this.usingExports&&(n=this.exports)),e)return e.requireMap=this.map,e.requireModules=this.map.isDefine?[this.map.id]:null,e.requireType=this.map.isDefine?"define":"require",c(this.error=e)}else n=o;if(this.exports=n,this.map.isDefine&&!this.ignore&&(j[i]=n,req.onResourceLoad)){var a=[];each(this.depMaps,function(e){a.push(e.normalizedMap||e)}),req.onResourceLoad(q,this.map,a)}p(i),this.defined=!0}this.defining=!1,this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else hasProp(q.defQueueMap,i)||this.fetch()}},callPlugin:function(){var e=this.map,t=e.id,r=a(e.prefix);this.depMaps.push(r),u(r,"defined",bind(this,function(r){var n,o,d,f=getOwn(R,this.map.id),l=this.map.name,h=this.map.parentMap?this.map.parentMap.name:null,m=q.makeRequire(e.parentMap,{enableBuildCallback:!0});return this.map.unnormalized?(r.normalize&&(l=r.normalize(l,function(e){return i(e,h,!0)})||""),o=a(e.prefix+"!"+l,this.map.parentMap,!0),u(o,"defined",bind(this,function(e){this.map.normalizedMap=o,this.init([],function(){return e},null,{enabled:!0,ignore:!0})})),d=getOwn(S,o.id),void(d&&(this.depMaps.push(o),this.events.error&&d.on("error",bind(this,function(e){this.emit("error",e)})),d.enable()))):f?(this.map.url=q.nameToUrl(f),void this.load()):(n=bind(this,function(e){this.init([],function(){return e},null,{enabled:!0})}),n.error=bind(this,function(e){this.inited=!0,this.error=e,e.requireModules=[t],eachProp(S,function(e){0===e.map.id.indexOf(t+"_unnormalized")&&p(e.map.id)}),c(e)}),n.fromText=bind(this,function(i,r){var o=e.name,u=a(o),d=useInteractive;r&&(i=r),d&&(useInteractive=!1),s(u),hasProp(y.config,t)&&(y.config[o]=y.config[t]);try{req.exec(i)}catch(e){return c(makeError("fromtexteval","fromText eval for "+t+" failed: "+e,e,[t]))}d&&(useInteractive=!0),this.depMaps.push(u),q.completeLoad(o),m([o],n)}),void r.load(e.name,m,n,y))})),q.enable(r,this),this.pluginMaps[r.id]=r},enable:function(){k[this.map.id]=this,this.enabled=!0,this.enabling=!0,each(this.depMaps,bind(this,function(e,t){var i,r,n;if("string"==typeof e){if(e=a(e,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap),this.depMaps[t]=e,n=getOwn(E,e.id))return void(this.depExports[t]=n(this));this.depCount+=1,u(e,"defined",bind(this,function(e){this.undefed||(this.defineDep(t,e),this.check())})),this.errback?u(e,"error",bind(this,this.errback)):this.events.error&&u(e,"error",bind(this,function(e){this.emit("error",e)}))}i=e.id,r=S[i],hasProp(E,i)||!r||r.enabled||q.enable(e,this)})),eachProp(this.pluginMaps,bind(this,function(e){var t=getOwn(S,e.id);t&&!t.enabled&&q.enable(e,this)})),this.enabling=!1,this.check()},on:function(e,t){var i=this.events[e];i||(i=this.events[e]=[]),i.push(t)},emit:function(e,t){each(this.events[e],function(e){e(t)}),"error"===e&&delete this.events[e]}},q={config:y,contextName:e,registry:S,defined:j,urlFetched:P,defQueue:O,defQueueMap:{},Module:b,makeModuleMap:a,nextTick:req.nextTick,onError:c,configure:function(e){if(e.baseUrl&&"/"!==e.baseUrl.charAt(e.baseUrl.length-1)&&(e.baseUrl+="/"),"string"==typeof e.urlArgs){var t=e.urlArgs;e.urlArgs=function(e,i){return(i.indexOf("?")===-1?"?":"&")+t}}var i=y.shim,r={paths:!0,bundles:!0,config:!0,map:!0};eachProp(e,function(e,t){r[t]?(y[t]||(y[t]={}),mixin(y[t],e,!0,!0)):y[t]=e}),e.bundles&&eachProp(e.bundles,function(e,t){each(e,function(e){e!==t&&(R[e]=t)})}),e.shim&&(eachProp(e.shim,function(e,t){isArray(e)&&(e={deps:e}),!e.exports&&!e.init||e.exportsFn||(e.exportsFn=q.makeShimExports(e)),i[t]=e}),y.shim=i),e.packages&&each(e.packages,function(e){var t,i;e="string"==typeof e?{name:e}:e,i=e.name,t=e.location,t&&(y.paths[i]=e.location),y.pkgs[i]=e.name+"/"+(e.main||"main").replace(currDirRegExp,"").replace(jsSuffixRegExp,"")}),eachProp(S,function(e,t){e.inited||e.map.unnormalized||(e.map=a(t,null,!0))}),(e.deps||e.callback)&&q.require(e.deps||[],e.callback)},makeShimExports:function(e){function t(){var t;return e.init&&(t=e.init.apply(global,arguments)),t||e.exports&&getGlobal(e.exports)}return t},makeRequire:function(t,n){function o(i,r,u){var d,p,f;return n.enableBuildCallback&&r&&isFunction(r)&&(r.__requireJsBuild=!0),"string"==typeof i?isFunction(r)?c(makeError("requireargs","Invalid require call"),u):t&&hasProp(E,i)?E[i](S[t.id]):req.get?req.get(q,i,t,o):(p=a(i,t,!1,!0),d=p.id,hasProp(j,d)?j[d]:c(makeError("notloaded",'Module name "'+d+'" has not been loaded yet for context: '+e+(t?"":". Use require([])")))):(v(),q.nextTick(function(){v(),f=s(a(null,t)),f.skipMap=n.skipMap,f.init(i,r,u,{enabled:!0}),l()}),o)}return n=n||{},mixin(o,{isBrowser:isBrowser,toUrl:function(e){var r,n=e.lastIndexOf("."),o=e.split("/")[0],a="."===o||".."===o;return n!==-1&&(!a||n>1)&&(r=e.substring(n,e.length),e=e.substring(0,n)),q.nameToUrl(i(e,t&&t.id,!0),r,!0)},defined:function(e){return hasProp(j,a(e,t,!1,!0).id)},specified:function(e){return e=a(e,t,!1,!0).id,hasProp(j,e)||hasProp(S,e)}}),t||(o.undef=function(e){d();var i=a(e,t,!0),n=getOwn(S,e);n.undefed=!0,r(e),delete j[e],delete P[i.url],delete M[e],eachReverse(O,function(t,i){t[0]===e&&O.splice(i,1)}),delete q.defQueueMap[e],n&&(n.events.defined&&(M[e]=n.events),p(e))}),o},enable:function(e){var t=getOwn(S,e.id);t&&s(e).enable()},completeLoad:function(e){var t,i,r,o=getOwn(y.shim,e)||{},a=o.exports;for(d();O.length;){if(i=O.shift(),null===i[0]){if(i[0]=e,t)break;t=!0}else i[0]===e&&(t=!0);h(i)}if(q.defQueueMap={},r=getOwn(S,e),!t&&!hasProp(j,e)&&r&&!r.inited){if(!(!y.enforceDefine||a&&getGlobal(a)))return n(e)?void 0:c(makeError("nodefine","No define call for "+e,null,[e]));h([e,o.deps||[],o.exportsFn])}l()},nameToUrl:function(e,t,i){var r,n,o,a,s,u,c,d=getOwn(y.pkgs,e);if(d&&(e=d),c=getOwn(R,e))return q.nameToUrl(c,t,i);if(req.jsExtRegExp.test(e))s=e+(t||"");else{for(r=y.paths,n=e.split("/"),o=n.length;o>0;o-=1)if(a=n.slice(0,o).join("/"),u=getOwn(r,a)){isArray(u)&&(u=u[0]),n.splice(0,o,u);break}s=n.join("/"),s+=t||(/^data\:|^blob\:|\?/.test(s)||i?"":".js"),s=("/"===s.charAt(0)||s.match(/^[\w\+\.\-]+:/)?"":y.baseUrl)+s}return y.urlArgs&&!/^blob\:/.test(s)?s+y.urlArgs(e,s):s},load:function(e,t){req.load(q,e,t)},execCb:function(e,t,i,r){return t.apply(r,i)},onScriptLoad:function(e){if("load"===e.type||readyRegExp.test((e.currentTarget||e.srcElement).readyState)){interactiveScript=null;var t=g(e);q.completeLoad(t.id)}},onScriptError:function(e){var t=g(e);if(!n(t.id)){var i=[];return eachProp(S,function(e,r){0!==r.indexOf("_@r")&&each(e.depMaps,function(e){if(e.id===t.id)return i.push(r),!0})}),c(makeError("scripterror",'Script error for "'+t.id+(i.length?'", needed by: '+i.join(", "):'"'),e,[t.id]))}}},q.require=q.makeRequire(),q}function getInteractiveScript(){return interactiveScript&&"interactive"===interactiveScript.readyState?interactiveScript:(eachReverse(scripts(),function(e){if("interactive"===e.readyState)return interactiveScript=e}),interactiveScript)}var req,s,head,baseElement,dataMain,src,interactiveScript,currentlyAddingScript,mainScript,subPath,version="2.3.3",commentRegExp=/\/\*[\s\S]*?\*\/|([^:"'=]|^)\/\/.*$/gm,cjsRequireRegExp=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,jsSuffixRegExp=/\.js$/,currDirRegExp=/^\.\//,op=Object.prototype,ostring=op.toString,hasOwn=op.hasOwnProperty,isBrowser=!("undefined"==typeof window||"undefined"==typeof navigator||!window.document),isWebWorker=!isBrowser&&"undefined"!=typeof importScripts,readyRegExp=isBrowser&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,defContextName="_",isOpera="undefined"!=typeof opera&&"[object Opera]"===opera.toString(),contexts={},cfg={},globalDefQueue=[],useInteractive=!1;if("undefined"==typeof define){if("undefined"!=typeof requirejs){if(isFunction(requirejs))return;cfg=requirejs,requirejs=void 0}"undefined"==typeof require||isFunction(require)||(cfg=require,require=void 0),req=requirejs=function(e,t,i,r){var n,o,a=defContextName;return isArray(e)||"string"==typeof e||(o=e,isArray(t)?(e=t,t=i,i=r):e=[]),o&&o.context&&(a=o.context),n=getOwn(contexts,a),n||(n=contexts[a]=req.s.newContext(a)),o&&n.configure(o),n.require(e,t,i)},req.config=function(e){return req(e)},req.nextTick="undefined"!=typeof setTimeout?function(e){setTimeout(e,4)}:function(e){e()},require||(require=req),req.version=version,req.jsExtRegExp=/^\/|:|\?|\.js$/,req.isBrowser=isBrowser,s=req.s={contexts:contexts,newContext:newContext},req({}),each(["toUrl","undef","defined","specified"],function(e){req[e]=function(){var t=contexts[defContextName];return t.require[e].apply(t,arguments)}}),isBrowser&&(head=s.head=document.getElementsByTagName("head")[0],baseElement=document.getElementsByTagName("base")[0],baseElement&&(head=s.head=baseElement.parentNode)),req.onError=defaultOnError,req.createNode=function(e,t,i){var r=e.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script");return r.type=e.scriptType||"text/javascript",r.charset="utf-8",r.async=!0,r},req.load=function(e,t,i){var r,n=e&&e.config||{};if(isBrowser)return r=req.createNode(n,t,i),r.setAttribute("data-requirecontext",e.contextName),r.setAttribute("data-requiremodule",t),!r.attachEvent||r.attachEvent.toString&&r.attachEvent.toString().indexOf("[native code")<0||isOpera?(r.addEventListener("load",e.onScriptLoad,!1),r.addEventListener("error",e.onScriptError,!1)):(useInteractive=!0,r.attachEvent("onreadystatechange",e.onScriptLoad)),r.src=i,n.onNodeCreated&&n.onNodeCreated(r,n,t,i),currentlyAddingScript=r,baseElement?head.insertBefore(r,baseElement):head.appendChild(r),currentlyAddingScript=null,r;if(isWebWorker)try{setTimeout(function(){},0),importScripts(i),e.completeLoad(t)}catch(r){e.onError(makeError("importscripts","importScripts failed for "+t+" at "+i,r,[t]))}},isBrowser&&!cfg.skipDataMain&&eachReverse(scripts(),function(e){if(head||(head=e.parentNode),dataMain=e.getAttribute("data-main"))return mainScript=dataMain,cfg.baseUrl||mainScript.indexOf("!")!==-1||(src=mainScript.split("/"),mainScript=src.pop(),subPath=src.length?src.join("/")+"/":"./",cfg.baseUrl=subPath),mainScript=mainScript.replace(jsSuffixRegExp,""),req.jsExtRegExp.test(mainScript)&&(mainScript=dataMain),cfg.deps=cfg.deps?cfg.deps.concat(mainScript):[mainScript],!0}),define=function(e,t,i){var r,n;"string"!=typeof e&&(i=t,t=e,e=null),isArray(t)||(i=t,t=null),!t&&isFunction(i)&&(t=[],i.length&&(i.toString().replace(commentRegExp,commentReplace).replace(cjsRequireRegExp,function(e,i){t.push(i)}),t=(1===i.length?["require"]:["require","exports","module"]).concat(t))),useInteractive&&(r=currentlyAddingScript||getInteractiveScript(),r&&(e||(e=r.getAttribute("data-requiremodule")),n=contexts[r.getAttribute("data-requirecontext")])),n?(n.defQueue.push([e,t,i]),n.defQueueMap[e]=!0):globalDefQueue.push([e,t,i])},define.amd={jQuery:!0},req.exec=function(text){return eval(text)},req(cfg)}}(this,"undefined"==typeof setTimeout?void 0:setTimeout); \ No newline at end of file diff --git a/Other versions/SinglePage/scripts/settings.js b/Other versions/SinglePage/scripts/settings.js new file mode 100644 index 0000000..36916b9 --- /dev/null +++ b/Other versions/SinglePage/scripts/settings.js @@ -0,0 +1,72 @@ +define([],function() { +//Thanks http://www.w3schools.com/js/js_cookies.asp +var settings = { + upKey: 38, + rightKey: 39, + leftKey: 37, + downKey: 40, + + restartKey: 32, //spacebar + settingsKey: 73, // i + HighscoreKey: 72, // h + SubmitKey: 13, //enter + muteKey: 77, // m + + controlMethod: "Arrow Keys", + autoSubmit: false, + playerAutoName: "", + + setSetting: setCookie, + getSetting: getCookie, + updateSettings: updateSettings +} + +function setCookie(c_name,c_value,exdays) { + var exdate=new Date(); + exdate.setDate(exdate.getDate() + exdays); + document.cookie=encodeURIComponent(c_name) + + "=" + encodeURIComponent(c_value) + + (!exdays ? "" : "; expires="+exdate.toUTCString()); + ; + } + +function getCookie(cname) { + var name = cname + "="; + var ca = document.cookie.split(';'); + for(var i=0; iSettings for BallsBalls

Made by Søren Oehlenschlæger Hjort

Uses Cookies To save

Input Method:

Auto submit score after game:

Name for Auto submit:


' + ; + initiateListeners(controller); + } + this.end = function() { + document.getElementById("outerDiv").innerHTML =""; + } + this.keydownHandler = function(e) { + + } + this.keyupHandler = function(e) { + + } +} +}); diff --git a/Other versions/SinglePage/soundFiles/Retro.wav b/Other versions/SinglePage/soundFiles/Retro.wav new file mode 100644 index 0000000..bbf5709 Binary files /dev/null and b/Other versions/SinglePage/soundFiles/Retro.wav differ diff --git a/Other versions/SinglePage/soundFiles/gameOver2.wav b/Other versions/SinglePage/soundFiles/gameOver2.wav new file mode 100644 index 0000000..fb9a74d Binary files /dev/null and b/Other versions/SinglePage/soundFiles/gameOver2.wav differ diff --git a/Other versions/old/1/Ball.js b/Other versions/old/1/Ball.js new file mode 100644 index 0000000..f19d8bf --- /dev/null +++ b/Other versions/old/1/Ball.js @@ -0,0 +1,28 @@ +function Ball(startx,starty, vx, vy, radius) { + this.x = startx; + this.y = starty; + this.radius = radius; + this.xd = randomsign(); + this.yd = randomsign(); + this.dx = vx; + this.dy = vy; + this.move = function() { + if ((this.x > height-this.radius && this.xd > 0)|| (this.x < this.radius && this.xd < 0)) { + this.xd = -this.xd; + } + if ((this.y > width-this.radius && this.yd > 0) || (this.y < this.radius && this.yd < 0)) { + this.yd = -this.yd; + } + + this.x = this.x + this.dx * this.xd; + this.y = this.y + this.dy * this.yd; + } + + this.shape = function() { + return new circle(this.x,this.y,this.radius); + } + + this.draw = function(ctx) { + drawBall(this.x, this.y, this.radius,ctx,"green"); + } +} \ No newline at end of file diff --git a/Other versions/old/1/Calculations.js b/Other versions/old/1/Calculations.js new file mode 100644 index 0000000..89537bb --- /dev/null +++ b/Other versions/old/1/Calculations.js @@ -0,0 +1,77 @@ + // Shape objects: + function circle(x,y,radius) { + this.x = x; + this.y = y; + this.r = radius; + } + + function rectangle(x,y,width,height) { + this.x = x; + this.y = y; + this.w = width; + this.h = height; + } + + //distance calculator (between two points) + function dist(x1,y1,x2,y2) { + return Math.sqrt(Math.pow(Math.abs(x1 - x2),2) + Math.pow(Math.abs(y1 - y2),2)); + } + + function randomsign() { + var i = random(0, 1); + if (i == 0) { + return -1; + } else { + return 1; + } + } + function sign(i) { + if (i > 0) { + return 1; + } else if (i < 0) { + return -1; + } else { + return 0; + } + } + + function random(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + } + + function CircleCircleColliding(c1,c2) { + var dist = dist(c1.x , c1.y , c2.x , c2.y); + if (dist < Math.max(c1.r,c2.r)) { + return true; + } + return false; + } + + function RectRectColliding(r1,r2) { + var distX = Math.abs(r1.x + r1.w/2 - r2.x - r2.w/2); + var distY = Math.abs(r1.y + r1.h/2 - r2.y - r2.h/2); + + if (distX > (r1.w + r2.w)/2) { + return false; + } else if (distY > (r1.h + r2.h)/2) { + return false; + } else { + return true; + } + + } + + function RectCircleColliding(circle,rect){ + var distX = Math.abs(circle.x - rect.x-rect.w/2); + var distY = Math.abs(circle.y - rect.y-rect.h/2); + + if (distX > (rect.w/2 + circle.r)) { return false; } + if (distY > (rect.h/2 + circle.r)) { return false; } + + if (distX <= (rect.w/2)) { return true; } + if (distY <= (rect.h/2)) { return true; } + + var dx=distX-rect.w/2; + var dy=distY-rect.h/2; + return (dx*dx+dy*dy<=(circle.r*circle.r)); + } \ No newline at end of file diff --git a/Other versions/old/1/Controls.js b/Other versions/old/1/Controls.js new file mode 100644 index 0000000..c3b10f1 --- /dev/null +++ b/Other versions/old/1/Controls.js @@ -0,0 +1,188 @@ +var highscorePage = "highscore"; +var settingsPage = "settings"; + +var playercontrol; +var controlMethod; + +var mouseX; +var mouseY; +var moving = false; + +var upPressed = false; +var downPressed = false; +var rightPressed = false; +var leftPressed = false; + +var upKey = 38; +var rightKey = 39; +var leftKey = 37; +var downKey = 40; + +var restartKey = 32; //spacebar +var settingsKey = 73; // i +var HighscoreKey = 72; // h +var SubmitKey = 13; //enter +var muteKey = 77; // m + +//sets the control mode +function setControl(mode) { + document.addEventListener("keydown", keyDownHandler, false); + document.addEventListener("keyup", keyUpHandler, false); + if (mode=="wasd") { + controlMethod = "WASD"; + playercontrol = keyboardControl; + upKey = 87; + leftKey = 65; + downKey = 83; + rightKey = 68; + } else if (mode=="mouse") { + controlMethod = "Mouse"; + document.addEventListener("mousemove", mouseMoveHandler, false); + playercontrol = mouseControl; + } else if (mode=="mobile") + { + controlMethod = "Mobile"; + playercontrol = mobileControl; + canvas.addEventListener("touchstart", handleStart, false); + canvas.addEventListener("touchend", handleEnd, false); + canvas.addEventListener("touchcancel", handleCancel, false); + canvas.addEventListener("touchmove", handleMove, false); + } + else { + controlMethod = "Arrow Keys"; + playercontrol = keyboardControl; + } +} + +function handleStart(e) { + moving = true; + mouseX = e.changedTouches[0].clientX - canvas.offsetLeft; + mouseY = e.changedTouches[0].clientY - canvas.offsetTop; +} +function handleEnd(e) { + moving = false; +} +function handleCancel(e) { + moving = false; +} +function handleMove(e) { + mouseX = e.changedTouches[0].clientX - canvas.offsetLeft; + mouseY = e.changedTouches[0].clientY - canvas.offsetTop; +} + +function mobileControl(object, speed) { + if (moving) { + object.x = object.x + sign(mouseX-object.x)*speed; + object.y = object.y + sign(mouseY-object.y)*speed; + } +} + +function keyboardControl(object, speed) { + if(rightPressed) { + object.x += speed; + } + if(leftPressed) { + object.x -= speed; + } + + if(downPressed) { + object.y += speed; + } + + if(upPressed) { + object.y -= speed; + } + + if (object.x < 0) { + object.x = 0; + } else if (object.x + object.height > height) { + object.x = height-object.height; + } + + if (object.y < 0) { + object.y = 0; + } else if (object.y + object.width > width) { + object.y = width-object.width; + } +} + +function mouseControl(object,speed) { + if (mouseX != null) { + object.x = mouseX - object.width/2; + object.y = mouseY - object.height/2; + } +} + +function mouseMoveHandler(e) { + mouseX = e.clientX - canvas.offsetLeft; + mouseY = e.clientY - canvas.offsetTop; +} + +var currentKeyDownHandler; + +function setControlMode(type) { + if (type=="menu") { + currentKeyDownHandler = menuKeyDownHandler; + } else if (type=="game") { + currentKeyDownHandler = gameKeyDownHandler; + } +} + +var gameKeyDownHandler = function(e) { + if(e.keyCode == downKey) { + downPressed = true; + } else if(e.keyCode == rightKey) { + rightPressed = true; + } else if(e.keyCode == upKey) { + upPressed = true; + } else if(e.keyCode == leftKey) { + leftPressed = true; + } else if(e.keyCode == muteKey) { + music.toggleMute(); + } +} + +var menuKeyDownHandler = function(e) { + if (e.keyCode == restartKey) { + restartgame(); + } else if (e.keyCode == settingsKey) { + document.location.href = settingsPage; + } else if (e.keyCode == HighscoreKey) { + document.location.href = highscorePage; + } else if (e.keyCode == SubmitKey) { + submitscore(); + } +} + +function keyDownHandler(e) { + currentKeyDownHandler(e); +} + +function keyUpHandler(e) { + if(e.keyCode == downKey) { + downPressed = false; + } + else if(e.keyCode == rightKey) { + rightPressed = false; + } + else if(e.keyCode == upKey) { + upPressed = false; + } + else if(e.keyCode == leftKey) { + leftPressed = false; + } +} + +function resetmovement() { + moving = false; + upPressed = false; + downPressed = false; + rightPressed = false; + leftPressed = false; +} + +function setWriteMode(callback) { +} + + + diff --git a/Other versions/old/1/Cookies.js b/Other versions/old/1/Cookies.js new file mode 100644 index 0000000..8a29ced --- /dev/null +++ b/Other versions/old/1/Cookies.js @@ -0,0 +1,20 @@ +//Thanks http://www.w3schools.com/js/js_cookies.asp +function setCookie(c_name,c_value,exdays) { + var exdate=new Date(); + exdate.setDate(exdate.getDate() + exdays); + document.cookie=encodeURIComponent(c_name) + + "=" + encodeURIComponent(c_value) + + (!exdays ? "" : "; expires="+exdate.toUTCString()); + ; + } + +function getCookie(cname) { + var name = cname + "="; + var ca = document.cookie.split(';'); + for(var i=0; i gameState.tickperball) { + countervalue = 0; + return true; + } + return false; +} + +function addObject(object) { + //set starting position + var currentdist = 0; + while (currentdist < mindist) { + startx = random(0, height); + starty = random(0, width); + currentdist = dist(startx, starty, p.x, p.y); + } + + //set speed + vx = random(gameState.minBallspeed, gameState.maxBallspeed); + vy = random(gameState.minBallspeed, gameState.maxBallspeed); + + //set size + radius = random(gameState.minballRadius,gameState.maxballRadius); + + //add to ball list + let newObject = new object(startx, starty, vx, vy, radius); + objects.push(newObject); + return newObject; +} + +function addBall() { + addObject(Ball); +} + +function addStealthBall() { + addObject(StealthBall); +} + +function addSeekerBall() { + let ball = addObject(SeekerBall); + ball.target = p; +} + +function addPickUp() { + //set position + var currentdist = 0; + while (currentdist < mindist) { + x = random(pickuplength, height-pickuplength); + y = random(pickuplength, width-pickuplength); + currentdist = dist(x, y, p.x, p.y); + } + //add Pickup + pickup = new Pickup(x,y,pickuplength); +} + +//ending the game, when player dies +function endgame() { + music.playGameOver(); + setControlMode("menu"); + submitscore(); +} + +function submitscore() { + let playername = null; + if (autoSubmit) { + playername = playerAutoName; + } else { + playername = getPlayerName(); + if (playername == null) { + DisplayAfterGameMessages("Game Over"); + return; + } + } + if (leaderboard == null) { + initializeFirebase(); + leaderboard = new Leaderboard("https://leaderboard-bf98b.firebaseio.com"); + } + ctx.clearRect(0, 0, canvas.width, canvas.height); + setFont(20); + ctx.fillText("Submitting score", width/2, height/4); + addandgo({"name": playername, "score": score, "level": gameState.level, "method": controlMethod}, function(){ + scorenotsubmitted = false; + DisplayAfterGameMessages("Score Submitted"); + }); +} + +function validateName(name) { + + if(!name || name.length > maxplayernamelength) { + return "Requires a valid name."; + } else if(!data.score || isNaN(data.score)) { + return "Requires a valid score. score: " + data.score; + } + return true; +} + +function getPlayerName() { +// setWriteMode(); alternative method, not yet implemented + let playername; + do { + playername = prompt("Player name (max " + maxplayernamelength +" characters)"); + if (playername == null) { + return null; + } + } while ((playername.length <= 0) || (playername.length > maxplayernamelength)) + // Ask for playername until proper name is given, or cancel is chosen. + return playername; +} + +function DisplayAfterGameMessages(message) { + //reset canvas + ctx.clearRect(0, 0, canvas.width, canvas.height); + + setFont(20); + //text drawing + let displayWidth = width/5; + let displayHeight = height/5; + let heightOffset = width/20; + + ctx.fillText(message, displayWidth, displayHeight); + ctx.fillText("Press Space to play again", displayWidth, displayHeight+heightOffset); + ctx.fillText("Press i for settings", displayWidth, displayHeight+heightOffset*2); + ctx.fillText("Press h for Leaderboard", displayWidth, displayHeight+heightOffset*3); +} diff --git a/Other versions/old/1/GameState.js b/Other versions/old/1/GameState.js new file mode 100644 index 0000000..78c463c --- /dev/null +++ b/Other versions/old/1/GameState.js @@ -0,0 +1,59 @@ +function GameState() { + this.level = 1; + this.maxBallspeed; + this.minBallspeed; + this.maxballRadius; + this.minballRadius; + this.initialballs; //balls at the start of the level + this.levelduration; + this.tickperball; //how often new ball is created + this.ballspertick; //how many balls are created at once + this.basemaxBallspeed; + this.baseminBallspeed; + + this.durationTickUp = 5; + + this.baseForDurationIncrease = 0; + this.baseForSpeedIncrease = 2; + this.baseForBallsPerTickIncrease = 0; + this.baseForTicksPerBallDecrease = 3; + + this.ticksForDurationIncrease = 3; + this.ticksForSpeedIncrease = 4; + this.ticksForBallsPerTickIncrease = 5; + this.ticksForTicksPerBallDecrease = 5; + + this.levelup = function(){ + this.level++; + this.initialballs++; + if ((this.level % this.ticksForDurationIncrease) + this.baseForDurationIncrease == 0) { + this.levelduration += this.durationTickUp; + } + if ((this.level % this.ticksForSpeedIncrease) + this.baseForSpeedIncrease == 0) { + this.maxBallspeed += this.basemaxBallspeed; + this.minBallspeed += this.baseminBallspeed; + } + if ((this.level % this.baseForBallsPerTickIncrease) + this.baseForBallsPerTickIncrease == 0) { + this.ballspertick++; + } + if ((this.level % this.baseForTicksPerBallDecrease) + this.baseForTicksPerBallDecrease == 0) { + this.ticksperball--; + } + } + + + this.init = function() { + let averageSize = (Math.abs(width) + Math.abs(height)) / 2; + this.level = 1; + this.basemaxBallspeed = averageSize / 200; + this.baseminBallspeed = averageSize / 1000; + this.maxBallspeed = this.basemaxBallspeed; + this.minBallspeed = this.baseminBallspeed; + this.maxballRadius = averageSize / 70; + this.minballRadius = averageSize / 200; + this.initialballs = 1; + this.levelduration = 30; + this.tickperball = 20; + this.ballspertick = 1; + } +} \ No newline at end of file diff --git a/Other versions/old/1/HighScoreScript.js b/Other versions/old/1/HighScoreScript.js new file mode 100644 index 0000000..6f48fd7 --- /dev/null +++ b/Other versions/old/1/HighScoreScript.js @@ -0,0 +1,31 @@ +window.onload = function() { + var table = document.getElementById("items"); + initializeFirebase(); + var leaderboard = new Leaderboard("https://leaderboard-bf98b.firebaseio.com"); + leaderboard.getandgo(function(list) { + var index, len; + for (index = Math.min(list.length-1,10), len = 0; index >= len; --index) { + addRow(table,list[index]); + } + }, 10 + ); + +} + +function addRow(table, data) { //adding a simple row + + var rownumber = table.rows.length; + var row = table.insertRow(rownumber); + + var cell1 = row.insertCell(0); + var cell2 = row.insertCell(1); + var cell3 = row.insertCell(2); + var cell4 = row.insertCell(3); + var cell5 = row.insertCell(4); + + cell1.innerHTML = rownumber; + cell2.innerHTML = data.name; + cell3.innerHTML = data.level; + cell4.innerHTML = data.score; + cell5.innerHTML = data.method; +} \ No newline at end of file diff --git a/Other versions/old/1/Initialization.js b/Other versions/old/1/Initialization.js new file mode 100644 index 0000000..aa77fd3 --- /dev/null +++ b/Other versions/old/1/Initialization.js @@ -0,0 +1,69 @@ + + +var canvas; +var ctx; +var p; +var pickup; +var objects; +var height; +var width; +var mindist = 4; +var leaderboard; +var squared = true; +var autoSubmit = false; +var playerAutoName = null; +window.onload = function () { + +// Initialize canvas +canvas = document.getElementById("myCanvas"); +ctx = canvas.getContext("2d"); + + +if (squared) { + let size = Math.min(window.innerWidth,window.innerHeight); + + ctx.canvas.width = size; + ctx.canvas.height = size; + + height = size; + width = size; +} else { + ctx.canvas.width = window.innerWidth; + ctx.canvas.height = window.innerHeight; + + height = canvas.width; + width = canvas.height; +} + + +if (getCookie("settings")) { + setControl(getCookie("input")); + autoSubmit = getCookie("autoSubmit"); + if (autoSubmit) { + playerAutoName = getCookie("playerName"); + } +} else { + var setSettings = confirm("Settings not found, want to set them? /n \n (default control is arrow keys)"); + if (setSettings) { + window.location.href = "settings"; + } else { + setControl(""); + } +} + +mindist = dist(0,0,width,height) / mindist; + +restartgame(); + +} + +function restartgame() { + setControlMode("game"); + setVariables(); + gameState.init(); + p = new Paddle(height/2, width/2, playerlength); + objects = []; + addPickUp(); + music.playMain(); + doTurn(); +} diff --git a/Other versions/old/1/Leaderboard.js b/Other versions/old/1/Leaderboard.js new file mode 100644 index 0000000..1d11ba6 --- /dev/null +++ b/Other versions/old/1/Leaderboard.js @@ -0,0 +1,87 @@ +function initializeFirebase(){ + var config = { + apiKey: "AIzaSyDnQy8gUVUldROZM3hxjg2_M3FE7Yg_cSc", + authDomain: "leaderboard-bf98b.firebaseapp.com", + databaseURL: "https://leaderboard-bf98b.firebaseio.com", + storageBucket: "leaderboard-bf98b.appspot.com", + }; + firebase.initializeApp(config); +} + +class Leaderboard { + constructor(firebaseURL) { + this.firebase = firebase.database(); + this.firebase.ref("scores").orderByChild("score").limitToLast(5).on("value", (value) => { + this.scores = value.val() + }) + } + + add(data) { + if(!data.name || data.name.length > maxplayernamelength) { + throw new Error("Requires a valid name.") + } else if(!data.score || isNaN(data.score)) { + throw new Error("Requires a valid score.") + } else { + this.firebase.ref("scores").push(data).setPriority(data.score) + } + } + + /* + * assumed that data is valid + */ + addandgo(data,go) { + firebase.database().ref("scores").push(data).setPriority(data.score).then(go); + } + + get() { + throw new Error("this shouldn't happen"); + var list = []; + var running = true; + this.firebase.ref("scores").orderByChild("score").once("value").then( + function(snapshot) { + snapshot.forEach(function(childSnapshot) { + list.push(childSnapshot.val()); + }) + running = false; + }); + } + + getandgo(go,limit) { + let query = this.firebase.ref("scores").orderByChild("score"); + if (limit!=null) { + query = query.limitToLast(limit); + } + query.once("value").then( + function(snapshot) { + let list = []; + snapshot.forEach(function(childSnapshot) { + list.push(childSnapshot.val()); + }); + go(list); + }); + } +} + +function add(data) { + addandgo(data,function(){}); +} +/* +* assumed that data is valid +*/ +function addandgo(data,go) { + firebase.database().ref("scores").push(data).setPriority(data.score).then(go); +} +function getandgo(go) { + let query = this.firebase.ref("scores").orderByChild("score"); + if (limit!=null) { + console.log("limted"); + query = query.limitToLast(limit); + } + query.once("value").then( + function(snapshot) { + snapshot.forEach(function(childSnapshot) { + list.push(childSnapshot.val()); + }); + go(list); + }); +} \ No newline at end of file diff --git a/Other versions/old/1/Paddle.js b/Other versions/old/1/Paddle.js new file mode 100644 index 0000000..3a7247c --- /dev/null +++ b/Other versions/old/1/Paddle.js @@ -0,0 +1,17 @@ +function Paddle(ax,ay,length) { + this.x = ax; + this.y = ay; + this.width = length; + this.height = length; + this.move = function(nx,ny) { + playercontrol(this,playerSpeed); + } + + this.shape = function(){ + return new rectangle(this.x,this.y,this.width,this.height); + } + + this.draw = function(ctx) { + drawRect(this.x, this.y, this.width, this.height,ctx,"#0095DD"); + } +} \ No newline at end of file diff --git a/Other versions/old/1/Pickup.js b/Other versions/old/1/Pickup.js new file mode 100644 index 0000000..a9216b5 --- /dev/null +++ b/Other versions/old/1/Pickup.js @@ -0,0 +1,14 @@ +function Pickup(x,y,length) { + this.x = x; + this.y = y; + this.width = length; + this.height = length; + + this.shape = function(){ + return new rectangle(this.x,this.y,this.width,this.height); + } + + this.draw = function(ctx) { + drawRect(this.x, this.y, this.width, this.height,ctx,"#FFA500"); + } +} \ No newline at end of file diff --git a/Other versions/old/1/SeekerBall.js b/Other versions/old/1/SeekerBall.js new file mode 100644 index 0000000..63950d6 --- /dev/null +++ b/Other versions/old/1/SeekerBall.js @@ -0,0 +1,64 @@ +function SeekerBall(startx,starty, vx, vy, radius, target) { + this.target; + this.base = new Ball(startx,starty, vx, vy, radius); + this.speed = (Math.abs(this.base.dx) + Math.abs(this.base.dy)) / 2; + this.maxTurn = 0.1; + this.currentDirection = 0; + + this.move = function() { + this.determineDirection(); + this.base.x -= this.speed * Math.cos(this.currentDirection); + this.base.y -= this.speed * Math.sin(this.currentDirection); + }; + + this.determineDirection = function() { + DesiredDirection = Math.atan2((this.target.y - this.base.y) , (this.target.x - this.base.x)) + Math.PI; + /* if (this.currentDirection < 0) { + this.currentDirection = (2*Math.PI) - this.currentDirection; + } else if (this.currentDirection > (2*Math.PI)) { + this.currentDirection %= (2*Math.PI); + } + */ + let change = this.currentDirection-DesiredDirection; + if (Math.abs(change) max / 2) { + ans = b - a - max; + } else if (b - a > -max / 2) { + ans = b - a; + } else { + ans = b - a + max; + } + + if (ans > 0) { + return 1; + } else if (ans < 0) { + return -1; + } else { + return 0; + } + +} \ No newline at end of file diff --git a/Other versions/old/1/SettingsScript.js b/Other versions/old/1/SettingsScript.js new file mode 100644 index 0000000..7dd78f8 --- /dev/null +++ b/Other versions/old/1/SettingsScript.js @@ -0,0 +1,67 @@ +define(["settings"],function(settings) { +initiateListeners = function () { + //input method + var input = document.getElementById("input method"); + //listen to input method + addEventListener(input, "change", function () { + var inputmethod = input.options[input.selectedIndex].value; + setCookie("input",inputmethod,100); + }); + + //auto submit + var aSubmit = document.getElementById("autoSubmit"); + addEventListener(aSubmit, "change", function () { + setCookie("autoSubmit",aSubmit.checked,100); + }); + + //name for auto submit + var name = document.getElementById("playerName"); + addEventListener(name, "change", function () { + setCookie("playerName",name.value,100); + }); + + + //save button + var saveButton = document.getElementById("save"); + //listen to save button + addEventListener(saveButton, "click", function () { + setCookie("settings",true,100); + }); + + //Play again + var playAgain = document.getElementById("play"); + //listen to play again + addEventListener(playAgain, "click", function () { + setCookie("settings",true,100); + controller.changeState("menuState"); + }); + + //load cookies + if (getCookie("settings")) { + aSubmit.checked = getCookie("autoSubmit"); + name.value = getCookie("playerName"); + + var inputVal = getCookie("input"); + var options = input.options; + for(var i = 0; i < options.length; i++) { + var option = options[i]; + if (option.value == inputVal) { + input.selectedIndex = i; + } + } + + } + } + + function addEventListener(myNode, eventType, myHandlerFunc) { + if (myNode.addEventListener) + myNode.addEventListener(eventType, myHandlerFunc, false); + else + myNode.attachEvent("on" + eventType, + function (event) { + myHandlerFunc.call(myNode, event); + }); + } + + +}) diff --git a/Other versions/old/1/Sound.js b/Other versions/old/1/Sound.js new file mode 100644 index 0000000..54b8b56 --- /dev/null +++ b/Other versions/old/1/Sound.js @@ -0,0 +1,51 @@ +var music = new Music(); + +function Music() { + this.audio = new Audio('Retro.wav'); + this.audio.loop = true; + this.sounds = new Audio(); + this.volume = 1; + this.muted = false; + + this.playMain = function() { + this.sounds.pause(); + this.audio.play(); + } + + this.playGameOver = function() { + this.audio.pause(); + this.sounds.src = 'gameOver2.wav'; + this.sounds.play(); + } + + this.playPause = function() { + this.audio.pause(); + } + + this.pause = function() { + this.audio.pause(); + } + + this.stop = function() { + this.audio.pause(); + } + + this.toggleMute = function() { + if (this.muted) { + this.audio.volume = this.volume; + } else { + this.audio.volume = 0; + } + this.muted = !this.muted; + } + + this.setVolume = function(value) { + this.audio.volume = value; + } + + this.changeVolume = function(change) { + this.audio.volume += value; + } + + +} diff --git a/Other versions/old/1/StealthBall.js b/Other versions/old/1/StealthBall.js new file mode 100644 index 0000000..6647f06 --- /dev/null +++ b/Other versions/old/1/StealthBall.js @@ -0,0 +1,25 @@ +function StealthBall(startx,starty, vx, vy, radius) { + this.base = new Ball(startx,starty, vx, vy, radius); + this.speed = (Math.abs(this.base.dx) + Math.abs(this.base.dy)) / 2; + this.ticks = stealthBallticks/this.speed; + this.visible = true; + this.move = function() { + this.base.move(); + if (this.ticks <= 0) { + this.visible = !this.visible; + this.ticks = stealthBallticks/this.speed; + } else { + this.ticks = this.ticks - 1; + } + } + + this.shape = function() { + return this.base.shape(); + } + + this.draw = function(ctx) { + if (this.visible) { + drawBall(this.base.x, this.base.y, this.base.radius,ctx,"red"); + } + } +} \ No newline at end of file diff --git a/Other versions/old/1/Values.js b/Other versions/old/1/Values.js new file mode 100644 index 0000000..39e6eb5 --- /dev/null +++ b/Other versions/old/1/Values.js @@ -0,0 +1,40 @@ +// Constants +var playerlength; +var playerSpeed; +var graceperiod; +var pickuplength; +var maxplayernamelength = 10; +// var mindist; //Fraction of average of width+Height // moved to initialization +// Base (might change through levels) +var stealthBallticks; +// Counter variables: +var countervalue; +var timeLeft; +var gracetimer; +// mode +var grace; +var playerdead; +var scorenotsubmitted; +// progess +var score; + + +function setVariables() { + let averageSize = (Math.abs(width) + Math.abs(height)) / 2; + playerlength = averageSize / 56; + playerSpeed = averageSize / 143; + pickuplength = averageSize / 50; + + graceperiod = 100; + timeLeft = 30; + stealthBallticks = 100; + + countervalue = 0; + gracetimer = 0; + + grace = false; + playerdead = false; + scorenotsubmitted = true; + score = 0; + resetmovement(); +} \ No newline at end of file diff --git a/Other versions/old/1/highscore.html b/Other versions/old/1/highscore.html new file mode 100644 index 0000000..24937c4 --- /dev/null +++ b/Other versions/old/1/highscore.html @@ -0,0 +1,35 @@ + + + + +Credits + + + + + + + +
+ + + + + + + + +
RankNameLevelScore (Squares Gathered)Control Method
+
+
+
+ +
+
+ +
+
+

Made by Søren Oehlenschlæger Hjort

+

Version 0.7

+ + \ No newline at end of file diff --git a/Other versions/old/1/index.html b/Other versions/old/1/index.html new file mode 100644 index 0000000..1d6a4a7 --- /dev/null +++ b/Other versions/old/1/index.html @@ -0,0 +1,44 @@ + + + + + BallsBalls + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Other versions/old/1/settings.html b/Other versions/old/1/settings.html new file mode 100644 index 0000000..889fc38 --- /dev/null +++ b/Other versions/old/1/settings.html @@ -0,0 +1,51 @@ + + + + + Credits + + + + + +

Settings for BallsBalls

+

Made by Søren Oehlenschlæger Hjort

+ Uses Cookies To save +
+
+ + Input Method: + + +
+
+ + Auto submit score after game: +
+ +
+ Name for Auto submit: +
+ + +
+
+ + + + + + diff --git a/Other versions/old/2/Ball.js b/Other versions/old/2/Ball.js new file mode 100644 index 0000000..f19d8bf --- /dev/null +++ b/Other versions/old/2/Ball.js @@ -0,0 +1,28 @@ +function Ball(startx,starty, vx, vy, radius) { + this.x = startx; + this.y = starty; + this.radius = radius; + this.xd = randomsign(); + this.yd = randomsign(); + this.dx = vx; + this.dy = vy; + this.move = function() { + if ((this.x > height-this.radius && this.xd > 0)|| (this.x < this.radius && this.xd < 0)) { + this.xd = -this.xd; + } + if ((this.y > width-this.radius && this.yd > 0) || (this.y < this.radius && this.yd < 0)) { + this.yd = -this.yd; + } + + this.x = this.x + this.dx * this.xd; + this.y = this.y + this.dy * this.yd; + } + + this.shape = function() { + return new circle(this.x,this.y,this.radius); + } + + this.draw = function(ctx) { + drawBall(this.x, this.y, this.radius,ctx,"green"); + } +} \ No newline at end of file diff --git a/Other versions/old/2/Calculations.js b/Other versions/old/2/Calculations.js new file mode 100644 index 0000000..89537bb --- /dev/null +++ b/Other versions/old/2/Calculations.js @@ -0,0 +1,77 @@ + // Shape objects: + function circle(x,y,radius) { + this.x = x; + this.y = y; + this.r = radius; + } + + function rectangle(x,y,width,height) { + this.x = x; + this.y = y; + this.w = width; + this.h = height; + } + + //distance calculator (between two points) + function dist(x1,y1,x2,y2) { + return Math.sqrt(Math.pow(Math.abs(x1 - x2),2) + Math.pow(Math.abs(y1 - y2),2)); + } + + function randomsign() { + var i = random(0, 1); + if (i == 0) { + return -1; + } else { + return 1; + } + } + function sign(i) { + if (i > 0) { + return 1; + } else if (i < 0) { + return -1; + } else { + return 0; + } + } + + function random(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + } + + function CircleCircleColliding(c1,c2) { + var dist = dist(c1.x , c1.y , c2.x , c2.y); + if (dist < Math.max(c1.r,c2.r)) { + return true; + } + return false; + } + + function RectRectColliding(r1,r2) { + var distX = Math.abs(r1.x + r1.w/2 - r2.x - r2.w/2); + var distY = Math.abs(r1.y + r1.h/2 - r2.y - r2.h/2); + + if (distX > (r1.w + r2.w)/2) { + return false; + } else if (distY > (r1.h + r2.h)/2) { + return false; + } else { + return true; + } + + } + + function RectCircleColliding(circle,rect){ + var distX = Math.abs(circle.x - rect.x-rect.w/2); + var distY = Math.abs(circle.y - rect.y-rect.h/2); + + if (distX > (rect.w/2 + circle.r)) { return false; } + if (distY > (rect.h/2 + circle.r)) { return false; } + + if (distX <= (rect.w/2)) { return true; } + if (distY <= (rect.h/2)) { return true; } + + var dx=distX-rect.w/2; + var dy=distY-rect.h/2; + return (dx*dx+dy*dy<=(circle.r*circle.r)); + } \ No newline at end of file diff --git a/Other versions/old/2/Controls.js b/Other versions/old/2/Controls.js new file mode 100644 index 0000000..c3b10f1 --- /dev/null +++ b/Other versions/old/2/Controls.js @@ -0,0 +1,188 @@ +var highscorePage = "highscore"; +var settingsPage = "settings"; + +var playercontrol; +var controlMethod; + +var mouseX; +var mouseY; +var moving = false; + +var upPressed = false; +var downPressed = false; +var rightPressed = false; +var leftPressed = false; + +var upKey = 38; +var rightKey = 39; +var leftKey = 37; +var downKey = 40; + +var restartKey = 32; //spacebar +var settingsKey = 73; // i +var HighscoreKey = 72; // h +var SubmitKey = 13; //enter +var muteKey = 77; // m + +//sets the control mode +function setControl(mode) { + document.addEventListener("keydown", keyDownHandler, false); + document.addEventListener("keyup", keyUpHandler, false); + if (mode=="wasd") { + controlMethod = "WASD"; + playercontrol = keyboardControl; + upKey = 87; + leftKey = 65; + downKey = 83; + rightKey = 68; + } else if (mode=="mouse") { + controlMethod = "Mouse"; + document.addEventListener("mousemove", mouseMoveHandler, false); + playercontrol = mouseControl; + } else if (mode=="mobile") + { + controlMethod = "Mobile"; + playercontrol = mobileControl; + canvas.addEventListener("touchstart", handleStart, false); + canvas.addEventListener("touchend", handleEnd, false); + canvas.addEventListener("touchcancel", handleCancel, false); + canvas.addEventListener("touchmove", handleMove, false); + } + else { + controlMethod = "Arrow Keys"; + playercontrol = keyboardControl; + } +} + +function handleStart(e) { + moving = true; + mouseX = e.changedTouches[0].clientX - canvas.offsetLeft; + mouseY = e.changedTouches[0].clientY - canvas.offsetTop; +} +function handleEnd(e) { + moving = false; +} +function handleCancel(e) { + moving = false; +} +function handleMove(e) { + mouseX = e.changedTouches[0].clientX - canvas.offsetLeft; + mouseY = e.changedTouches[0].clientY - canvas.offsetTop; +} + +function mobileControl(object, speed) { + if (moving) { + object.x = object.x + sign(mouseX-object.x)*speed; + object.y = object.y + sign(mouseY-object.y)*speed; + } +} + +function keyboardControl(object, speed) { + if(rightPressed) { + object.x += speed; + } + if(leftPressed) { + object.x -= speed; + } + + if(downPressed) { + object.y += speed; + } + + if(upPressed) { + object.y -= speed; + } + + if (object.x < 0) { + object.x = 0; + } else if (object.x + object.height > height) { + object.x = height-object.height; + } + + if (object.y < 0) { + object.y = 0; + } else if (object.y + object.width > width) { + object.y = width-object.width; + } +} + +function mouseControl(object,speed) { + if (mouseX != null) { + object.x = mouseX - object.width/2; + object.y = mouseY - object.height/2; + } +} + +function mouseMoveHandler(e) { + mouseX = e.clientX - canvas.offsetLeft; + mouseY = e.clientY - canvas.offsetTop; +} + +var currentKeyDownHandler; + +function setControlMode(type) { + if (type=="menu") { + currentKeyDownHandler = menuKeyDownHandler; + } else if (type=="game") { + currentKeyDownHandler = gameKeyDownHandler; + } +} + +var gameKeyDownHandler = function(e) { + if(e.keyCode == downKey) { + downPressed = true; + } else if(e.keyCode == rightKey) { + rightPressed = true; + } else if(e.keyCode == upKey) { + upPressed = true; + } else if(e.keyCode == leftKey) { + leftPressed = true; + } else if(e.keyCode == muteKey) { + music.toggleMute(); + } +} + +var menuKeyDownHandler = function(e) { + if (e.keyCode == restartKey) { + restartgame(); + } else if (e.keyCode == settingsKey) { + document.location.href = settingsPage; + } else if (e.keyCode == HighscoreKey) { + document.location.href = highscorePage; + } else if (e.keyCode == SubmitKey) { + submitscore(); + } +} + +function keyDownHandler(e) { + currentKeyDownHandler(e); +} + +function keyUpHandler(e) { + if(e.keyCode == downKey) { + downPressed = false; + } + else if(e.keyCode == rightKey) { + rightPressed = false; + } + else if(e.keyCode == upKey) { + upPressed = false; + } + else if(e.keyCode == leftKey) { + leftPressed = false; + } +} + +function resetmovement() { + moving = false; + upPressed = false; + downPressed = false; + rightPressed = false; + leftPressed = false; +} + +function setWriteMode(callback) { +} + + + diff --git a/Other versions/old/2/Cookies.js b/Other versions/old/2/Cookies.js new file mode 100644 index 0000000..8a29ced --- /dev/null +++ b/Other versions/old/2/Cookies.js @@ -0,0 +1,20 @@ +//Thanks http://www.w3schools.com/js/js_cookies.asp +function setCookie(c_name,c_value,exdays) { + var exdate=new Date(); + exdate.setDate(exdate.getDate() + exdays); + document.cookie=encodeURIComponent(c_name) + + "=" + encodeURIComponent(c_value) + + (!exdays ? "" : "; expires="+exdate.toUTCString()); + ; + } + +function getCookie(cname) { + var name = cname + "="; + var ca = document.cookie.split(';'); + for(var i=0; i gameState.tickperball) { + countervalue = 0; + return true; + } + return false; +} + +function addObject(object) { + //set starting position + var currentdist = 0; + while (currentdist < mindist) { + startx = random(0, height); + starty = random(0, width); + currentdist = dist(startx, starty, p.x, p.y); + } + + //set speed + vx = random(gameState.minBallspeed, gameState.maxBallspeed); + vy = random(gameState.minBallspeed, gameState.maxBallspeed); + + //set size + radius = random(gameState.minballRadius,gameState.maxballRadius); + + //add to ball list + let newObject = new object(startx, starty, vx, vy, radius); + objects.push(newObject); + return newObject; +} + +function addBall() { + addObject(Ball); +} + +function addStealthBall() { + addObject(StealthBall); +} + +function addSeekerBall() { + let ball = addObject(SeekerBall); + ball.target = p; +} + +function addPickUp() { + //set position + var currentdist = 0; + while (currentdist < mindist) { + x = random(pickuplength, height-pickuplength); + y = random(pickuplength, width-pickuplength); + currentdist = dist(x, y, p.x, p.y); + } + //add Pickup + pickup = new Pickup(x,y,pickuplength); +} + +//ending the game, when player dies +function endgame() { + music.playGameOver(); + setControlMode("menu"); + submitscore(); +} + +function submitscore() { + let playername = null; + if (autoSubmit) { + playername = playerAutoName; + } else { + playername = getPlayerName(); + if (playername == null) { + DisplayAfterGameMessages("Game Over"); + return; + } + } + if (leaderboard == null) { + initializeFirebase(); + leaderboard = new Leaderboard("https://leaderboard-bf98b.firebaseio.com"); + } + ctx.clearRect(0, 0, canvas.width, canvas.height); + setFont(20); + ctx.fillText("Submitting score", width/2, height/4); + addandgo({"name": playername, "score": score, "level": gameState.level, "method": controlMethod}, function(){ + scorenotsubmitted = false; + DisplayAfterGameMessages("Score Submitted"); + }); +} + +function validateName(name) { + + if(!name || name.length > maxplayernamelength) { + return "Requires a valid name."; + } else if(!data.score || isNaN(data.score)) { + return "Requires a valid score. score: " + data.score; + } + return true; +} + +function getPlayerName() { +// setWriteMode(); alternative method, not yet implemented + let playername; + do { + playername = prompt("Player name (max " + maxplayernamelength +" characters)"); + if (playername == null) { + return null; + } + } while ((playername.length <= 0) || (playername.length > maxplayernamelength)) + // Ask for playername until proper name is given, or cancel is chosen. + return playername; +} + +function DisplayAfterGameMessages(message) { + //reset canvas + ctx.clearRect(0, 0, canvas.width, canvas.height); + + setFont(20); + //text drawing + let displayWidth = width/5; + let displayHeight = height/5; + let heightOffset = width/20; + + ctx.fillText(message, displayWidth, displayHeight); + ctx.fillText("Press Space to play again", displayWidth, displayHeight+heightOffset); + ctx.fillText("Press i for settings", displayWidth, displayHeight+heightOffset*2); + ctx.fillText("Press h for Leaderboard", displayWidth, displayHeight+heightOffset*3); +} diff --git a/Other versions/old/2/GameState.js b/Other versions/old/2/GameState.js new file mode 100644 index 0000000..78c463c --- /dev/null +++ b/Other versions/old/2/GameState.js @@ -0,0 +1,59 @@ +function GameState() { + this.level = 1; + this.maxBallspeed; + this.minBallspeed; + this.maxballRadius; + this.minballRadius; + this.initialballs; //balls at the start of the level + this.levelduration; + this.tickperball; //how often new ball is created + this.ballspertick; //how many balls are created at once + this.basemaxBallspeed; + this.baseminBallspeed; + + this.durationTickUp = 5; + + this.baseForDurationIncrease = 0; + this.baseForSpeedIncrease = 2; + this.baseForBallsPerTickIncrease = 0; + this.baseForTicksPerBallDecrease = 3; + + this.ticksForDurationIncrease = 3; + this.ticksForSpeedIncrease = 4; + this.ticksForBallsPerTickIncrease = 5; + this.ticksForTicksPerBallDecrease = 5; + + this.levelup = function(){ + this.level++; + this.initialballs++; + if ((this.level % this.ticksForDurationIncrease) + this.baseForDurationIncrease == 0) { + this.levelduration += this.durationTickUp; + } + if ((this.level % this.ticksForSpeedIncrease) + this.baseForSpeedIncrease == 0) { + this.maxBallspeed += this.basemaxBallspeed; + this.minBallspeed += this.baseminBallspeed; + } + if ((this.level % this.baseForBallsPerTickIncrease) + this.baseForBallsPerTickIncrease == 0) { + this.ballspertick++; + } + if ((this.level % this.baseForTicksPerBallDecrease) + this.baseForTicksPerBallDecrease == 0) { + this.ticksperball--; + } + } + + + this.init = function() { + let averageSize = (Math.abs(width) + Math.abs(height)) / 2; + this.level = 1; + this.basemaxBallspeed = averageSize / 200; + this.baseminBallspeed = averageSize / 1000; + this.maxBallspeed = this.basemaxBallspeed; + this.minBallspeed = this.baseminBallspeed; + this.maxballRadius = averageSize / 70; + this.minballRadius = averageSize / 200; + this.initialballs = 1; + this.levelduration = 30; + this.tickperball = 20; + this.ballspertick = 1; + } +} \ No newline at end of file diff --git a/Other versions/old/2/HighScoreScript.js b/Other versions/old/2/HighScoreScript.js new file mode 100644 index 0000000..6f48fd7 --- /dev/null +++ b/Other versions/old/2/HighScoreScript.js @@ -0,0 +1,31 @@ +window.onload = function() { + var table = document.getElementById("items"); + initializeFirebase(); + var leaderboard = new Leaderboard("https://leaderboard-bf98b.firebaseio.com"); + leaderboard.getandgo(function(list) { + var index, len; + for (index = Math.min(list.length-1,10), len = 0; index >= len; --index) { + addRow(table,list[index]); + } + }, 10 + ); + +} + +function addRow(table, data) { //adding a simple row + + var rownumber = table.rows.length; + var row = table.insertRow(rownumber); + + var cell1 = row.insertCell(0); + var cell2 = row.insertCell(1); + var cell3 = row.insertCell(2); + var cell4 = row.insertCell(3); + var cell5 = row.insertCell(4); + + cell1.innerHTML = rownumber; + cell2.innerHTML = data.name; + cell3.innerHTML = data.level; + cell4.innerHTML = data.score; + cell5.innerHTML = data.method; +} \ No newline at end of file diff --git a/Other versions/old/2/Initialization.js b/Other versions/old/2/Initialization.js new file mode 100644 index 0000000..aa77fd3 --- /dev/null +++ b/Other versions/old/2/Initialization.js @@ -0,0 +1,69 @@ + + +var canvas; +var ctx; +var p; +var pickup; +var objects; +var height; +var width; +var mindist = 4; +var leaderboard; +var squared = true; +var autoSubmit = false; +var playerAutoName = null; +window.onload = function () { + +// Initialize canvas +canvas = document.getElementById("myCanvas"); +ctx = canvas.getContext("2d"); + + +if (squared) { + let size = Math.min(window.innerWidth,window.innerHeight); + + ctx.canvas.width = size; + ctx.canvas.height = size; + + height = size; + width = size; +} else { + ctx.canvas.width = window.innerWidth; + ctx.canvas.height = window.innerHeight; + + height = canvas.width; + width = canvas.height; +} + + +if (getCookie("settings")) { + setControl(getCookie("input")); + autoSubmit = getCookie("autoSubmit"); + if (autoSubmit) { + playerAutoName = getCookie("playerName"); + } +} else { + var setSettings = confirm("Settings not found, want to set them? /n \n (default control is arrow keys)"); + if (setSettings) { + window.location.href = "settings"; + } else { + setControl(""); + } +} + +mindist = dist(0,0,width,height) / mindist; + +restartgame(); + +} + +function restartgame() { + setControlMode("game"); + setVariables(); + gameState.init(); + p = new Paddle(height/2, width/2, playerlength); + objects = []; + addPickUp(); + music.playMain(); + doTurn(); +} diff --git a/Other versions/old/2/Leaderboard.js b/Other versions/old/2/Leaderboard.js new file mode 100644 index 0000000..1d11ba6 --- /dev/null +++ b/Other versions/old/2/Leaderboard.js @@ -0,0 +1,87 @@ +function initializeFirebase(){ + var config = { + apiKey: "AIzaSyDnQy8gUVUldROZM3hxjg2_M3FE7Yg_cSc", + authDomain: "leaderboard-bf98b.firebaseapp.com", + databaseURL: "https://leaderboard-bf98b.firebaseio.com", + storageBucket: "leaderboard-bf98b.appspot.com", + }; + firebase.initializeApp(config); +} + +class Leaderboard { + constructor(firebaseURL) { + this.firebase = firebase.database(); + this.firebase.ref("scores").orderByChild("score").limitToLast(5).on("value", (value) => { + this.scores = value.val() + }) + } + + add(data) { + if(!data.name || data.name.length > maxplayernamelength) { + throw new Error("Requires a valid name.") + } else if(!data.score || isNaN(data.score)) { + throw new Error("Requires a valid score.") + } else { + this.firebase.ref("scores").push(data).setPriority(data.score) + } + } + + /* + * assumed that data is valid + */ + addandgo(data,go) { + firebase.database().ref("scores").push(data).setPriority(data.score).then(go); + } + + get() { + throw new Error("this shouldn't happen"); + var list = []; + var running = true; + this.firebase.ref("scores").orderByChild("score").once("value").then( + function(snapshot) { + snapshot.forEach(function(childSnapshot) { + list.push(childSnapshot.val()); + }) + running = false; + }); + } + + getandgo(go,limit) { + let query = this.firebase.ref("scores").orderByChild("score"); + if (limit!=null) { + query = query.limitToLast(limit); + } + query.once("value").then( + function(snapshot) { + let list = []; + snapshot.forEach(function(childSnapshot) { + list.push(childSnapshot.val()); + }); + go(list); + }); + } +} + +function add(data) { + addandgo(data,function(){}); +} +/* +* assumed that data is valid +*/ +function addandgo(data,go) { + firebase.database().ref("scores").push(data).setPriority(data.score).then(go); +} +function getandgo(go) { + let query = this.firebase.ref("scores").orderByChild("score"); + if (limit!=null) { + console.log("limted"); + query = query.limitToLast(limit); + } + query.once("value").then( + function(snapshot) { + snapshot.forEach(function(childSnapshot) { + list.push(childSnapshot.val()); + }); + go(list); + }); +} \ No newline at end of file diff --git a/Other versions/old/2/Paddle.js b/Other versions/old/2/Paddle.js new file mode 100644 index 0000000..3a7247c --- /dev/null +++ b/Other versions/old/2/Paddle.js @@ -0,0 +1,17 @@ +function Paddle(ax,ay,length) { + this.x = ax; + this.y = ay; + this.width = length; + this.height = length; + this.move = function(nx,ny) { + playercontrol(this,playerSpeed); + } + + this.shape = function(){ + return new rectangle(this.x,this.y,this.width,this.height); + } + + this.draw = function(ctx) { + drawRect(this.x, this.y, this.width, this.height,ctx,"#0095DD"); + } +} \ No newline at end of file diff --git a/Other versions/old/2/Pickup.js b/Other versions/old/2/Pickup.js new file mode 100644 index 0000000..a9216b5 --- /dev/null +++ b/Other versions/old/2/Pickup.js @@ -0,0 +1,14 @@ +function Pickup(x,y,length) { + this.x = x; + this.y = y; + this.width = length; + this.height = length; + + this.shape = function(){ + return new rectangle(this.x,this.y,this.width,this.height); + } + + this.draw = function(ctx) { + drawRect(this.x, this.y, this.width, this.height,ctx,"#FFA500"); + } +} \ No newline at end of file diff --git a/Other versions/old/2/SeekerBall.js b/Other versions/old/2/SeekerBall.js new file mode 100644 index 0000000..63950d6 --- /dev/null +++ b/Other versions/old/2/SeekerBall.js @@ -0,0 +1,64 @@ +function SeekerBall(startx,starty, vx, vy, radius, target) { + this.target; + this.base = new Ball(startx,starty, vx, vy, radius); + this.speed = (Math.abs(this.base.dx) + Math.abs(this.base.dy)) / 2; + this.maxTurn = 0.1; + this.currentDirection = 0; + + this.move = function() { + this.determineDirection(); + this.base.x -= this.speed * Math.cos(this.currentDirection); + this.base.y -= this.speed * Math.sin(this.currentDirection); + }; + + this.determineDirection = function() { + DesiredDirection = Math.atan2((this.target.y - this.base.y) , (this.target.x - this.base.x)) + Math.PI; + /* if (this.currentDirection < 0) { + this.currentDirection = (2*Math.PI) - this.currentDirection; + } else if (this.currentDirection > (2*Math.PI)) { + this.currentDirection %= (2*Math.PI); + } + */ + let change = this.currentDirection-DesiredDirection; + if (Math.abs(change) max / 2) { + ans = b - a - max; + } else if (b - a > -max / 2) { + ans = b - a; + } else { + ans = b - a + max; + } + + if (ans > 0) { + return 1; + } else if (ans < 0) { + return -1; + } else { + return 0; + } + +} \ No newline at end of file diff --git a/Other versions/old/2/SettingsScript.js b/Other versions/old/2/SettingsScript.js new file mode 100644 index 0000000..7dd78f8 --- /dev/null +++ b/Other versions/old/2/SettingsScript.js @@ -0,0 +1,67 @@ +define(["settings"],function(settings) { +initiateListeners = function () { + //input method + var input = document.getElementById("input method"); + //listen to input method + addEventListener(input, "change", function () { + var inputmethod = input.options[input.selectedIndex].value; + setCookie("input",inputmethod,100); + }); + + //auto submit + var aSubmit = document.getElementById("autoSubmit"); + addEventListener(aSubmit, "change", function () { + setCookie("autoSubmit",aSubmit.checked,100); + }); + + //name for auto submit + var name = document.getElementById("playerName"); + addEventListener(name, "change", function () { + setCookie("playerName",name.value,100); + }); + + + //save button + var saveButton = document.getElementById("save"); + //listen to save button + addEventListener(saveButton, "click", function () { + setCookie("settings",true,100); + }); + + //Play again + var playAgain = document.getElementById("play"); + //listen to play again + addEventListener(playAgain, "click", function () { + setCookie("settings",true,100); + controller.changeState("menuState"); + }); + + //load cookies + if (getCookie("settings")) { + aSubmit.checked = getCookie("autoSubmit"); + name.value = getCookie("playerName"); + + var inputVal = getCookie("input"); + var options = input.options; + for(var i = 0; i < options.length; i++) { + var option = options[i]; + if (option.value == inputVal) { + input.selectedIndex = i; + } + } + + } + } + + function addEventListener(myNode, eventType, myHandlerFunc) { + if (myNode.addEventListener) + myNode.addEventListener(eventType, myHandlerFunc, false); + else + myNode.attachEvent("on" + eventType, + function (event) { + myHandlerFunc.call(myNode, event); + }); + } + + +}) diff --git a/Other versions/old/2/Sound.js b/Other versions/old/2/Sound.js new file mode 100644 index 0000000..f128047 --- /dev/null +++ b/Other versions/old/2/Sound.js @@ -0,0 +1,51 @@ +var music = new Music(); + +function Music() { + this.audio = new Audio('soundFiles/Retro.wav'); + this.audio.loop = true; + this.sounds = new Audio(); + this.volume = 1; + this.muted = false; + + this.playMain = function() { + this.sounds.pause(); + this.audio.play(); + } + + this.playGameOver = function() { + this.audio.pause(); + this.sounds.src = 'soundFiles/gameOver2.wav'; + this.sounds.play(); + } + + this.playPause = function() { + this.audio.pause(); + } + + this.pause = function() { + this.audio.pause(); + } + + this.stop = function() { + this.audio.pause(); + } + + this.toggleMute = function() { + if (this.muted) { + this.audio.volume = this.volume; + } else { + this.audio.volume = 0; + } + this.muted = !this.muted; + } + + this.setVolume = function(value) { + this.audio.volume = value; + } + + this.changeVolume = function(change) { + this.audio.volume += value; + } + + +} diff --git a/Other versions/old/2/StealthBall.js b/Other versions/old/2/StealthBall.js new file mode 100644 index 0000000..6647f06 --- /dev/null +++ b/Other versions/old/2/StealthBall.js @@ -0,0 +1,25 @@ +function StealthBall(startx,starty, vx, vy, radius) { + this.base = new Ball(startx,starty, vx, vy, radius); + this.speed = (Math.abs(this.base.dx) + Math.abs(this.base.dy)) / 2; + this.ticks = stealthBallticks/this.speed; + this.visible = true; + this.move = function() { + this.base.move(); + if (this.ticks <= 0) { + this.visible = !this.visible; + this.ticks = stealthBallticks/this.speed; + } else { + this.ticks = this.ticks - 1; + } + } + + this.shape = function() { + return this.base.shape(); + } + + this.draw = function(ctx) { + if (this.visible) { + drawBall(this.base.x, this.base.y, this.base.radius,ctx,"red"); + } + } +} \ No newline at end of file diff --git a/Other versions/old/2/To do.txt b/Other versions/old/2/To do.txt new file mode 100644 index 0000000..22416ee --- /dev/null +++ b/Other versions/old/2/To do.txt @@ -0,0 +1,11 @@ +State concept +(gameState, + MenuState, + HighScoreState, + SettingsState +) + +Implement Menu properly +Settings in one page +Sound Settings +users \ No newline at end of file diff --git a/Other versions/old/2/Values.js b/Other versions/old/2/Values.js new file mode 100644 index 0000000..39e6eb5 --- /dev/null +++ b/Other versions/old/2/Values.js @@ -0,0 +1,40 @@ +// Constants +var playerlength; +var playerSpeed; +var graceperiod; +var pickuplength; +var maxplayernamelength = 10; +// var mindist; //Fraction of average of width+Height // moved to initialization +// Base (might change through levels) +var stealthBallticks; +// Counter variables: +var countervalue; +var timeLeft; +var gracetimer; +// mode +var grace; +var playerdead; +var scorenotsubmitted; +// progess +var score; + + +function setVariables() { + let averageSize = (Math.abs(width) + Math.abs(height)) / 2; + playerlength = averageSize / 56; + playerSpeed = averageSize / 143; + pickuplength = averageSize / 50; + + graceperiod = 100; + timeLeft = 30; + stealthBallticks = 100; + + countervalue = 0; + gracetimer = 0; + + grace = false; + playerdead = false; + scorenotsubmitted = true; + score = 0; + resetmovement(); +} \ No newline at end of file diff --git a/Other versions/old/2/highscore.html b/Other versions/old/2/highscore.html new file mode 100644 index 0000000..24937c4 --- /dev/null +++ b/Other versions/old/2/highscore.html @@ -0,0 +1,35 @@ + + + + +Credits + + + + + + + +
+ + + + + + + + +
RankNameLevelScore (Squares Gathered)Control Method
+
+
+
+ +
+
+ +
+
+

Made by Søren Oehlenschlæger Hjort

+

Version 0.7

+ + \ No newline at end of file diff --git a/Other versions/old/2/index.html b/Other versions/old/2/index.html new file mode 100644 index 0000000..1d6a4a7 --- /dev/null +++ b/Other versions/old/2/index.html @@ -0,0 +1,44 @@ + + + + + BallsBalls + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Other versions/old/2/settings.html b/Other versions/old/2/settings.html new file mode 100644 index 0000000..889fc38 --- /dev/null +++ b/Other versions/old/2/settings.html @@ -0,0 +1,51 @@ + + + + + Credits + + + + + +

Settings for BallsBalls

+

Made by Søren Oehlenschlæger Hjort

+ Uses Cookies To save +
+
+ + Input Method: + + +
+
+ + Auto submit score after game: +
+ +
+ Name for Auto submit: +
+ + +
+
+ + + + + + diff --git a/Other versions/old/2/soundFiles/GameOVer.mp3 b/Other versions/old/2/soundFiles/GameOVer.mp3 new file mode 100644 index 0000000..7561d40 Binary files /dev/null and b/Other versions/old/2/soundFiles/GameOVer.mp3 differ diff --git a/Other versions/old/2/soundFiles/Retro.wav b/Other versions/old/2/soundFiles/Retro.wav new file mode 100644 index 0000000..bbf5709 Binary files /dev/null and b/Other versions/old/2/soundFiles/Retro.wav differ diff --git a/Other versions/old/2/soundFiles/gameOver1.wav b/Other versions/old/2/soundFiles/gameOver1.wav new file mode 100644 index 0000000..58a3f20 Binary files /dev/null and b/Other versions/old/2/soundFiles/gameOver1.wav differ diff --git a/Other versions/old/2/soundFiles/gameOver2.wav b/Other versions/old/2/soundFiles/gameOver2.wav new file mode 100644 index 0000000..fb9a74d Binary files /dev/null and b/Other versions/old/2/soundFiles/gameOver2.wav differ diff --git a/Other versions/old/2/soundFiles/playTime.mp3 b/Other versions/old/2/soundFiles/playTime.mp3 new file mode 100644 index 0000000..7792bbd Binary files /dev/null and b/Other versions/old/2/soundFiles/playTime.mp3 differ diff --git a/Other versions/old/2/soundFiles/someMusic.mp3 b/Other versions/old/2/soundFiles/someMusic.mp3 new file mode 100644 index 0000000..3869311 Binary files /dev/null and b/Other versions/old/2/soundFiles/someMusic.mp3 differ diff --git a/Other versions/pixi/bunny.png b/Other versions/pixi/bunny.png new file mode 100644 index 0000000..79c3167 Binary files /dev/null and b/Other versions/pixi/bunny.png differ diff --git a/Other versions/pixi/index.html b/Other versions/pixi/index.html new file mode 100644 index 0000000..543a6db --- /dev/null +++ b/Other versions/pixi/index.html @@ -0,0 +1,58 @@ + + + + pixi.js example 1 + + + + + + + + + diff --git a/Other versions/pixi/pixi.js b/Other versions/pixi/pixi.js new file mode 100644 index 0000000..28797ce --- /dev/null +++ b/Other versions/pixi/pixi.js @@ -0,0 +1,4201 @@ +/** + * @license + * Pixi.JS - v1.0.0 + * Copyright (c) 2012, Mat Groves + * http://goodboydigital.com/ + * + * Compiled: 2013-04-16 + * + * Pixi.JS is licensed under the MIT License. + * http://www.opensource.org/licenses/mit-license.php + */ +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + +/** +@module PIXI + */ +var PIXI = PIXI || {}; + +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + +/** + * The Point object represents a location in a two-dimensional coordinate system, where x represents the horizontal axis and y represents the vertical axis. + * @class Point + * @constructor + * @param x {Number} position of the point + * @param y {Number} position of the point + */ +PIXI.Point = function(x, y) +{ + /** + * @property x + * @type Number + * @default 0 + */ + this.x = x || 0; + + /** + * @property y + * @type Number + * @default 0 + */ + this.y = y || 0; +} + +/** + * @method clone + * @return a copy of the point + */ +PIXI.Point.clone = function() +{ + return new PIXI.Point(this.x, this.y); +} + +// constructor +PIXI.Point.constructor = PIXI.Point; + + +/** + * @author Mat Groves http://matgroves.com/ + */ + +/** + * the Rectangle object is an area defined by its position, as indicated by its top-left corner point (x, y) and by its width and its height. + * @class Rectangle + * @constructor + * @param x {Number} position of the rectangle + * @param y {Number} position of the rectangle + * @param width {Number} of the rectangle + * @param height {Number} of the rectangle + */ +PIXI.Rectangle = function(x, y, width, height) +{ + /** + * @property x + * @type Number + * @default 0 + */ + this.x = x || 0; + + /** + * @property y + * @type Number + * @default 0 + */ + this.y = y || 0; + + /** + * @property width + * @type Number + * @default 0 + */ + this.width = width || 0; + + /** + * @property height + * @type Number + * @default 0 + */ + this.height = height || 0; +} + +/** + * @method clone + * @return a copy of the rectangle + */ +PIXI.Rectangle.clone = function() +{ + return new PIXI.Rectangle(this.x, this.y, this.width, this.height); +} + +// constructor +PIXI.Rectangle.constructor = PIXI.Rectangle; + + +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + +/** + * this is the base class for all objects that are rendered on the screen. + * @class DisplayObject + * @constructor + */ +PIXI.DisplayObject = function() +{ + /** + * The coordinate of the object relative to the local coordinates of the parent. + * @property position + * @type Point + */ + this.position = new PIXI.Point(); + + /** + * The scale factor of the object. + * @property scale + * @type Point + */ + this.scale = new PIXI.Point(1,1);//{x:1, y:1}; + + /** + * The rotation of the object in radians. + * @property rotation + * @type Number + */ + this.rotation = 0; + + /** + * The opacity of the object. + * @property alpha + * @type Number + */ + this.alpha = 1; + + /** + * The visibility of the object. + * @property visible + * @type Boolean + */ + this.visible = true; + this.cacheVisible = false; + + /** + * [read-only] The display object container that contains this display object. + * @property parent + * @type DisplayObjectContainer + */ + this.parent = null; + + /** + * [read-only] The stage the display object is connected to, or undefined if it is not connected to the stage. + * @property stage + * @type Stage + */ + this.stage = null; + + /** + * This is the defined area that will pick up mouse / touch events. It is null by default. + * Setting it is a neat way of optimising the hitTest function that the interactionManager will use (as it will not need to hit test all the children) + * @property hitArea + * @type Rectangle + */ + this.hitArea = null; + + this.worldAlpha = 1; + this.color = []; + + this.worldTransform = PIXI.mat3.create()//mat3.identity(); + this.localTransform = PIXI.mat3.create()//mat3.identity(); + + this.dynamic = true; + // chach that puppy! + this._sr = 0; + this._cr = 1; + + this.renderable = false; + + // [readonly] best not to toggle directly! use setInteractive() + this.interactive = false; + this.buttonMode = false; + + /* + * MOUSE Callbacks + */ + + /** + * A callback that is used when the users clicks on the displayObject with their mouse + * @method click + * @param interactionData {InteractionData} + */ + + /** + * A callback that is used when the user clicks the mouse down over the sprite + * @method mousedown + * @param interactionData {InteractionData} + */ + + /** + * A callback that is used when the user releases the mouse that was over the displayObject + * for this callback to be fired the mouse must have been pressed down over the displayObject + * @method mouseup + * @param interactionData {InteractionData} + */ + + /** + * A callback that is used when the user releases the mouse that was over the displayObject but is no longer over the displayObject + * for this callback to be fired, The touch must have started over the displayObject + * @method mouseupoutside + * @param interactionData {InteractionData} + */ + + /** + * A callback that is used when the users mouse rolls over the displayObject + * @method mouseover + * @param interactionData {InteractionData} + */ + + /** + * A callback that is used when the users mouse leaves the displayObject + * @method mouseout + * @param interactionData {InteractionData} + */ + + + /* + * TOUCH Callbacks + */ + + /** + * A callback that is used when the users taps on the sprite with their finger + * basically a touch version of click + * @method tap + * @param interactionData {InteractionData} + */ + + /** + * A callback that is used when the user touch's over the displayObject + * @method touchstart + * @param interactionData {InteractionData} + */ + + /** + * A callback that is used when the user releases a touch over the displayObject + * @method touchend + * @param interactionData {InteractionData} + */ + + /** + * A callback that is used when the user releases the touch that was over the displayObject + * for this callback to be fired, The touch must have started over the sprite + * @method touchendoutside + * @param interactionData {InteractionData} + */ +} + +// constructor +PIXI.DisplayObject.constructor = PIXI.DisplayObject; + +/** + * Indicates if the sprite will have touch and mouse interactivity. It is false by default + * @method setInteractive + * @param interactive {Boolean} + */ +PIXI.DisplayObject.prototype.setInteractive = function(interactive) +{ + this.interactive = interactive; + // TODO more to be done here.. + // need to sort out a re-crawl! + if(this.stage)this.stage.dirty = true; +} + + +/** + * @private + */ +PIXI.DisplayObject.prototype.updateTransform = function() +{ + // TODO OPTIMIZE THIS!! with dirty + if(this.rotation != this.rotationCache) + { + this.rotationCache = this.rotation; + this._sr = Math.sin(this.rotation); + this._cr = Math.cos(this.rotation); + } + + var localTransform = this.localTransform; + var parentTransform = this.parent.worldTransform; + var worldTransform = this.worldTransform; + //console.log(localTransform) + localTransform[0] = this._cr * this.scale.x; + localTransform[1] = -this._sr * this.scale.y + localTransform[3] = this._sr * this.scale.x; + localTransform[4] = this._cr * this.scale.y; + + ///AAARR GETTER SETTTER! + localTransform[2] = this.position.x; + localTransform[5] = this.position.y; + + // Cache the matrix values (makes for huge speed increases!) + var a00 = localTransform[0], a01 = localTransform[1], a02 = localTransform[2], + a10 = localTransform[3], a11 = localTransform[4], a12 = localTransform[5], + + b00 = parentTransform[0], b01 = parentTransform[1], b02 = parentTransform[2], + b10 = parentTransform[3], b11 = parentTransform[4], b12 = parentTransform[5]; + + worldTransform[0] = b00 * a00 + b01 * a10; + worldTransform[1] = b00 * a01 + b01 * a11; + worldTransform[2] = b00 * a02 + b01 * a12 + b02; + + worldTransform[3] = b10 * a00 + b11 * a10; + worldTransform[4] = b10 * a01 + b11 * a11; + worldTransform[5] = b10 * a02 + b11 * a12 + b12; + + // because we are using affine transformation, we can optimise the matrix concatenation process.. wooo! + // mat3.multiply(this.localTransform, this.parent.worldTransform, this.worldTransform); + this.worldAlpha = this.alpha * this.parent.worldAlpha; +} + +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + + +/** + * A DisplayObjectContainer represents a collection of display objects. It is the base class of all display objects that act as a container for other objects. + * @class DisplayObjectContainer + * @extends DisplayObject + * @constructor + */ +PIXI.DisplayObjectContainer = function() +{ + PIXI.DisplayObject.call( this ); + + /** + * [read-only] The of children of this container. + * @property children {Array} + */ + this.children = []; + //s + this.renderable = false; +} + +// constructor +PIXI.DisplayObjectContainer.constructor = PIXI.DisplayObjectContainer; +PIXI.DisplayObjectContainer.prototype = Object.create( PIXI.DisplayObject.prototype ); + +/** + * Adds a child to the container. + * @method addChild + * @param DisplayObject {DisplayObject} + */ +PIXI.DisplayObjectContainer.prototype.addChild = function(child) +{ + if(child.parent != undefined) + { + child.parent.removeChild(child) + } + + child.parent = this; + child.childIndex = this.children.length; + + this.children.push(child); + if(this.stage) + { + this.stage.__addChild(child); + } +} + +/** + * Adds a child to the container at a specified index. If the index is out of bounds an error will be thrown + * @method addChildAt + * @param DisplayObject {DisplayObject} + * @param index {Number} + */ +PIXI.DisplayObjectContainer.prototype.addChildAt = function(child, index) +{ + if(index >= 0 && index <= this.children.length) + { + if(child.parent != undefined) + { + child.parent.removeChild(child); + } + + if (index == this.children.length) + { + this.children.push(child); + } + else + { + this.children.splice(index, 0, child); + } + + child.parent = this; + child.childIndex = index; + + var length = this.children.length; + for (var i=index; i < length; i++) + { + this.children[i].childIndex = i; + } + + if(this.stage) + { + this.stage.__addChild(child); + } + } + else + { + // error! + + throw new Error(child + " The index "+ index +" supplied is out of bounds " + this.children.length); + } +} + +/** + * Removes a child from the container. + * @method removeChild + * @param DisplayObject {DisplayObject} + */ +PIXI.DisplayObjectContainer.prototype.removeChild = function(child) +{ + var index = this.children.indexOf( child ); + + if ( index !== -1 ) + { + if(this.stage)this.stage.__removeChild(child); + child.parent = undefined; + //child.childIndex = 0 + this.children.splice( index, 1 ); + + // update in dexs! + for(var i=index,j=this.children.length; i= 0; i--) + { + var child = children[i]; + + // push all interactive bits + if(child.interactive) + { + iParent.interactiveChildren = true; + //child.__iParent = iParent; + this.interactiveItems.push(child); + + if(child.children.length > 0) + { + this.collectInteractiveSprite(child, child); + } + } + else + { + child.__iParent = null; + + if(child.children.length > 0) + { + this.collectInteractiveSprite(child, iParent); + } + } + } +} + +PIXI.InteractionManager.prototype.setTarget = function(target) +{ + if (window.navigator.msPointerEnabled) + { + // time to remove some of that zoom in ja.. + target.view.style["-ms-content-zooming"] = "none"; + target.view.style["-ms-touch-action"] = "none" + + // DO some window specific touch! + } + + + { + + this.target = target; + target.view.addEventListener('mousemove', this.onMouseMove.bind(this), true); + target.view.addEventListener('mousedown', this.onMouseDown.bind(this), true); + document.body.addEventListener('mouseup', this.onMouseUp.bind(this), true); + target.view.addEventListener('mouseout', this.onMouseUp.bind(this), true); + + // aint no multi touch just yet! + target.view.addEventListener("touchstart", this.onTouchStart.bind(this), true); + target.view.addEventListener("touchend", this.onTouchEnd.bind(this), true); + target.view.addEventListener("touchmove", this.onTouchMove.bind(this), true); + } + + + +} + +PIXI.InteractionManager.prototype.update = function() +{ + // frequency of 30fps?? + var now = Date.now(); + var diff = now - this.last; + diff = (diff * 30) / 1000; + if(diff < 1)return; + this.last = now; + // + + // ok.. so mouse events?? + // yes for now :) + // OPTIMSE - how often to check?? + if(this.dirty) + { + this.dirty = false; + + var len = this.interactiveItems.length; + + for (var i=0; i < this.interactiveItems.length; i++) { + this.interactiveItems[i].interactiveChildren = true; + } + + this.interactiveItems = []; + + if(this.stage.interactive)this.interactiveItems.push(this.stage); + // go through and collect all the objects that are interactive.. + this.collectInteractiveSprite(this.stage, this.stage); + } + + // loop through interactive objects! + var length = this.interactiveItems.length; + + for (var i = 0; i < length; i++) + { + var item = this.interactiveItems[i]; + if(!item.visible)continue; + + // OPTIMISATION - only calculate every time if the mousemove function exists.. + // OK so.. does the object have any other interactive functions? + // hit-test the clip! + if(item.mouseover || item.mouseout || item.buttonMode) + { + // ok so there are some functions so lets hit test it.. + item.__hit = this.hitTest(item, this.mouse); + // ok so deal with interactions.. + // loks like there was a hit! + if(item.__hit) + { + if(!item.__isOver) + { + if(item.buttonMode)this.target.view.style.cursor = "pointer"; + if(item.mouseover)item.mouseover(this.mouse); + item.__isOver = true; + } + } + else + { + if(item.__isOver) + { + // roll out! + if(item.buttonMode)this.target.view.style.cursor = "default"; + if(item.mouseout)item.mouseout(this.mouse); + item.__isOver = false; + } + } + } + + // ---> + } +} + +PIXI.InteractionManager.prototype.onMouseMove = function(event) +{ + event.preventDefault(); + + // TODO optimize by not check EVERY TIME! maybe half as often? // + var rect = this.target.view.getBoundingClientRect(); + + this.mouse.global.x = (event.clientX - rect.left) * (this.target.width / rect.width); + this.mouse.global.y = (event.clientY - rect.top) * ( this.target.height / rect.height); + + var length = this.interactiveItems.length; + var global = this.mouse.global; + + + for (var i = 0; i < length; i++) + { + var item = this.interactiveItems[i]; + + if(item.mousemove) + { + //call the function! + item.mousemove(this.mouse); + } + } +} + +PIXI.InteractionManager.prototype.onMouseDown = function(event) +{ + event.preventDefault(); + + // loop through inteaction tree... + // hit test each item! -> + // --->--->--->---> + // get interactive items under point?? + // --->--->--->---> + //stage.__i + var length = this.interactiveItems.length; + var global = this.mouse.global; + + var index = 0; + var parent = this.stage; + + // while + // hit test + for (var i = 0; i < length; i++) + { + var item = this.interactiveItems[i]; + + if(item.mousedown || item.click) + { + item.__mouseIsDown = true; + item.__hit = this.hitTest(item, this.mouse); + + if(item.__hit) + { + //call the function! + if(item.mousedown)item.mousedown(this.mouse); + item.__isDown = true; + + // just the one! + if(!item.interactiveChildren)break; + } + } + } +} + +PIXI.InteractionManager.prototype.onMouseUp = function(event) +{ + event.preventDefault(); + var global = this.mouse.global; + + + var length = this.interactiveItems.length; + var up = false; + + for (var i = 0; i < length; i++) + { + var item = this.interactiveItems[i]; + + if(item.mouseup || item.mouseupoutside || item.click) + { + item.__hit = this.hitTest(item, this.mouse); + + if(item.__hit && !up) + { + //call the function! + if(item.mouseup) + { + item.mouseup(this.mouse); + } + if(item.__isDown) + { + if(item.click)item.click(this.mouse); + } + + if(!item.interactiveChildren)up = true; + } + else + { + if(item.__isDown) + { + if(item.mouseupoutside)item.mouseupoutside(this.mouse); + } + } + + item.__isDown = false; + } + } +} + +PIXI.InteractionManager.prototype.hitTest = function(item, interactionData) +{ + var global = interactionData.global; + + if(!item.visible)return false; + + if(item instanceof PIXI.Sprite) + { + var worldTransform = item.worldTransform; + + var a00 = worldTransform[0], a01 = worldTransform[1], a02 = worldTransform[2], + a10 = worldTransform[3], a11 = worldTransform[4], a12 = worldTransform[5], + id = 1 / (a00 * a11 + a01 * -a10); + + var x = a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id; + var y = a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id; + + var x1 = -item.width * item.anchor.x; + + if(x > x1 && x < x1 + item.width) + { + var y1 = -item.height * item.anchor.y; + + if(y > y1 && y < y1 + item.height) + { + return true; + } + } + } + else if(item.hitArea) + { + var worldTransform = item.worldTransform; + var hitArea = item.hitArea; + + var a00 = worldTransform[0], a01 = worldTransform[1], a02 = worldTransform[2], + a10 = worldTransform[3], a11 = worldTransform[4], a12 = worldTransform[5], + id = 1 / (a00 * a11 + a01 * -a10); + + var x = a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id; + var y = a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id; + + var x1 = hitArea.x; + if(x > x1 && x < x1 + hitArea.width) + { + var y1 = hitArea.y; + + if(y > y1 && y < y1 + hitArea.height) + { + return true; + } + } + } + + var length = item.children.length; + + for (var i = 0; i < length; i++) + { + var item = item.children[i]; + var hit = this.hitTest(item, interactionData); + if(hit)return true; + } + + return false; +} + + + +PIXI.InteractionManager.prototype.onTouchMove = function(event) +{ + event.preventDefault(); + + var rect = this.target.view.getBoundingClientRect(); + var changedTouches = event.changedTouches; + + for (var i=0; i < changedTouches.length; i++) + { + var touchEvent = changedTouches[i]; + var touchData = this.touchs[touchEvent.identifier]; + + // update the touch position + touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width); + touchData.global.y = (touchEvent.clientY - rect.top) * (this.target.height / rect.height); + } + + var length = this.interactiveItems.length; + for (var i = 0; i < length; i++) + { + var item = this.interactiveItems[i]; + if(item.touchmove)item.touchmove(touchData); + } +} + +PIXI.InteractionManager.prototype.onTouchStart = function(event) +{ + event.preventDefault(); + var rect = this.target.view.getBoundingClientRect(); + + var changedTouches = event.changedTouches; + for (var i=0; i < changedTouches.length; i++) + { + var touchEvent = changedTouches[i]; + + var touchData = this.pool.pop(); + if(!touchData)touchData = new PIXI.InteractionData(); + + this.touchs[touchEvent.identifier] = touchData; + touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width); + touchData.global.y = (touchEvent.clientY - rect.top) * (this.target.height / rect.height); + + var length = this.interactiveItems.length; + + for (var j = 0; j < length; j++) + { + var item = this.interactiveItems[j]; + + if(item.touchstart || item.tap) + { + item.__hit = this.hitTest(item, touchData); + + if(item.__hit) + { + //call the function! + if(item.touchstart)item.touchstart(touchData); + item.__isDown = true; + item.__touchData = touchData; + + if(!item.interactiveChildren)break; + } + } + } + } + +} + +PIXI.InteractionManager.prototype.onTouchEnd = function(event) +{ + event.preventDefault(); + + + var rect = this.target.view.getBoundingClientRect(); + var changedTouches = event.changedTouches; + + for (var i=0; i < changedTouches.length; i++) + { + + var touchEvent = changedTouches[i]; + var touchData = this.touchs[touchEvent.identifier]; + var up = false; + touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width); + touchData.global.y = (touchEvent.clientY - rect.top) * (this.target.height / rect.height); + + var length = this.interactiveItems.length; + for (var j = 0; j < length; j++) + { + var item = this.interactiveItems[j]; + var itemTouchData = item.__touchData; // <-- Here! + item.__hit = this.hitTest(item, touchData); + + if(itemTouchData == touchData) + { + // so this one WAS down... + + // hitTest?? + + if(item.touchend || item.tap) + { + if(item.__hit && !up) + { + if(item.touchend)item.touchend(touchData); + if(item.__isDown) + { + if(item.tap)item.tap(touchData); + } + + if(!item.interactiveChildren)up = true; + } + else + { + if(item.__isDown) + { + if(item.touchendoutside)item.touchendoutside(touchData); + } + } + + item.__isDown = false; + } + + item.__touchData = null; + + } + else + { + + } + } + // remove the touch.. + this.pool.push(touchData); + this.touchs[touchEvent.identifier] = null; + } +} + +/** +@class InteractionData +@constructor +*/ +PIXI.InteractionData = function() +{ + /** + * This point stores the global coords of where the touch/mouse event happened + * @property global + * @type Point + */ + this.global = new PIXI.Point(); + + // this is here for legacy... but will remove + this.local = new PIXI.Point(); + + /** + * The target Sprite that was interacted with + * @property target + * @type Sprite + */ + this.target; +} + +/** + * This will return the local coords of the specified displayObject for this InteractionData + * @method getLocalPosition + * @param displayObject {DisplayObject} The DisplayObject that you would like the local coords off + * @return {Point} A point containing the coords of the InteractionData position relative to the DisplayObject + */ +PIXI.InteractionData.prototype.getLocalPosition = function(displayObject) +{ + var worldTransform = displayObject.worldTransform; + var global = this.global; + + // do a cheeky transform to get the mouse coords; + var a00 = worldTransform[0], a01 = worldTransform[1], a02 = worldTransform[2], + a10 = worldTransform[3], a11 = worldTransform[4], a12 = worldTransform[5], + id = 1 / (a00 * a11 + a01 * -a10); + // set the mouse coords... + return new PIXI.Point(a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id, + a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id) +} + +// constructor +PIXI.InteractionData.constructor = PIXI.InteractionData; + + + +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + +/** +A Stage represents the root of the display tree. Everything connected to the stage is rendered +@class Stage +@extends DisplayObjectContainer +@constructor +@param backgroundColor {Number} the background color of the stage +@param interactive {Boolean} enable / disable interaction (default is false) +*/ +PIXI.Stage = function(backgroundColor, interactive) +{ + + PIXI.DisplayObjectContainer.call( this ); + this.worldTransform = PIXI.mat3.create()//.//identity(); + this.__childrenAdded = []; + this.__childrenRemoved = []; + this.childIndex = 0; + this.stage= this; + + this.stage.hitArea = new PIXI.Rectangle(0,0,100000, 100000); + + // interaction! + this.interactive = !!interactive; + this.interactionManager = new PIXI.InteractionManager(this); + + this.setBackgroundColor(backgroundColor); +} + +// constructor +PIXI.Stage.constructor = PIXI.Stage; + +PIXI.Stage.prototype = Object.create( PIXI.DisplayObjectContainer.prototype ); + +/** +@method updateTransform +@internal +*/ +PIXI.Stage.prototype.updateTransform = function() +{ + this.worldAlpha = 1; + + for(var i=0,j=this.children.length; i> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255]; +} + +/** + * Provides bind in a cross browser way. + */ +if (typeof Function.prototype.bind != 'function') { + Function.prototype.bind = (function () { + var slice = Array.prototype.slice; + return function (thisArg) { + var target = this, boundArgs = slice.call(arguments, 1); + + if (typeof target != 'function') throw new TypeError(); + + function bound() { + var args = boundArgs.concat(slice.call(arguments)); + target.apply(this instanceof bound ? this : thisArg, args); + } + + bound.prototype = (function F(proto) { + proto && (F.prototype = proto); + if (!(this instanceof F)) return new F; + })(target.prototype); + + return bound; + }; + })(); +} + +var AjaxRequest = function() +{ + var activexmodes = ["Msxml2.XMLHTTP", "Microsoft.XMLHTTP"] //activeX versions to check for in IE + + if (window.ActiveXObject) + { //Test for support for ActiveXObject in IE first (as XMLHttpRequest in IE7 is broken) + for (var i=0; i 0) + { + this.checkVisibility(child, actualVisibility); + } + }; +} + + +/** + * Renders the stage to its webGL view + * @method render + * @param stage {Stage} the PIXI.Stage element to be rendered + */ +PIXI.WebGLRenderer.prototype.render = function(stage) +{ + if(this.contextLost)return; + + + + // if rendering a new stage clear the batchs.. + if(this.__stage !== stage) + { + if(this.__stage)this.checkVisibility(this.__stage, false) + this.__stage = stage; + } + + // update children if need be + // best to remove first! + for (var i=0; i < stage.__childrenRemoved.length; i++) + { + this.removeDisplayObject(stage.__childrenRemoved[i]); + } + + + // update any textures + for (var i=0; i < PIXI.texturesToUpdate.length; i++) this.updateTexture(PIXI.texturesToUpdate[i]); + + // empty out the arrays + stage.__childrenRemoved = []; + stage.__childrenAdded = []; + PIXI.texturesToUpdate = []; + + // recursivly loop through all items! + this.checkVisibility(stage, true); + + // update the scene graph + stage.updateTransform(); + + var gl = this.gl; + + gl.clear(gl.COLOR_BUFFER_BIT) + + gl.clearColor(stage.backgroundColorSplit[0], stage.backgroundColorSplit[1], stage.backgroundColorSplit[2], 0); + + + // set the correct blend mode! + gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + gl.uniformMatrix4fv(this.shaderProgram.mvMatrixUniform, false, this.projectionMatrix); + + // render all the batchs! + + + var renderable; + for (var i=0; i < this.batchs.length; i++) + { + renderable = this.batchs[i]; + if(renderable instanceof PIXI.WebGLBatch) + { + this.batchs[i].render(); + } + else if(renderable instanceof PIXI.Strip) + { + if(renderable.visible)this.renderStrip(renderable); + } + } + + // interaction + // run interaction! + if(stage.interactive) + { + //need to add some events! + if(!stage._interactiveEventsAdded) + { + stage._interactiveEventsAdded = true; + stage.interactionManager.setTarget(this); + } + } +} + +/** + * @private + */ +PIXI.WebGLRenderer.prototype.updateTexture = function(texture) +{ + var gl = this.gl; + + if(!texture._glTexture) + { + texture._glTexture = gl.createTexture(); + } + + if(texture.hasLoaded) + { + gl.bindTexture(gl.TEXTURE_2D, texture._glTexture); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + + // gl.generateMipmap(gl.TEXTURE_2D); + gl.bindTexture(gl.TEXTURE_2D, null); + } + + this.refreshBatchs = true; +} + +/** + * @private + */ +PIXI.WebGLRenderer.prototype.addDisplayObject = function(displayObject) +{ + + if(!displayObject.stage)return; // means it was removed + if(displayObject.__inWebGL)return; //means it is already in webgL + + //displayObject.cacheVisible = displayObject.visible; + + // TODO if objects parent is not visible then dont add to stage!!!! + //if(!displayObject.visible)return; + + + displayObject.batch = null; + + //displayObject.cacheVisible = true; + if(!displayObject.renderable)return; + + // while looping below THE OBJECT MAY NOT HAVE BEEN ADDED + displayObject.__inWebGL = true; + + /* + * LOOK FOR THE PREVIOUS SPRITE + * This part looks for the closest previous sprite that can go into a batch + * It keeps going back until it finds a sprite or the stage + */ + var previousSprite = displayObject; + do + { + if(previousSprite.childIndex == 0) + { + previousSprite = previousSprite.parent; + + } + else + { + previousSprite = previousSprite.parent.children[previousSprite.childIndex-1]; + // what if the bloop has children??? + while(previousSprite.children.length != 0) + { + // keep diggin till we get to the last child + previousSprite = previousSprite.children[previousSprite.children.length-1]; + } + } + + if(previousSprite == displayObject.stage)break; + } + while(!previousSprite.renderable || !previousSprite.__inWebGL) + //while(!(previousSprite instanceof PIXI.Sprite)) + + /* + * LOOK FOR THE NEXT SPRITE + * This part looks for the closest next sprite that can go into a batch + * it keeps looking until it finds a sprite or gets to the end of the display + * scene graph + * + * These look a lot scarier than the actually are... + */ + var nextSprite = displayObject; + do + { + // moving forward! + // if it has no children.. + if(nextSprite.children.length == 0) + { + // go along to the parent.. + while(nextSprite.childIndex == nextSprite.parent.children.length-1) + { + nextSprite = nextSprite.parent; + if(nextSprite == displayObject.stage) + { + nextSprite = null + break; + } + } + + if(nextSprite)nextSprite = nextSprite.parent.children[nextSprite.childIndex+1]; + + } + else + { + nextSprite = nextSprite.children[0]; + } + + if(!nextSprite)break; + } + while(!nextSprite.renderable || !nextSprite.__inWebGL) + + /* + * so now we have the next renderable and the previous renderable + * + */ + + if(displayObject instanceof PIXI.Sprite) + { + var previousBatch + var nextBatch + + if(previousSprite instanceof PIXI.Sprite) + { + previousBatch = previousSprite.batch; + + if(previousBatch) + { + if(previousBatch.texture == displayObject.texture.baseTexture && previousBatch.blendMode == displayObject.blendMode) + { + previousBatch.insertAfter(displayObject, previousSprite); + return; + } + } + } + else + { + // TODO reword! + previousBatch = previousSprite; + } + + if(nextSprite) + { + if(nextSprite instanceof PIXI.Sprite) + { + nextBatch = nextSprite.batch; + + //batch may not exist if item was added to the display list but not to the webGL + if(nextBatch) + { + if(nextBatch.texture == displayObject.texture.baseTexture && nextBatch.blendMode == displayObject.blendMode) + { + nextBatch.insertBefore(displayObject, nextSprite); + return; + } + else + { + if(nextBatch == previousBatch) + { + // THERE IS A SPLIT IN THIS BATCH! // + var splitBatch = previousBatch.split(nextSprite); + // COOL! + // add it back into the array + /* + * OOPS! + * seems the new sprite is in the middle of a batch + * lets split it.. + */ + var batch = PIXI._getBatch(this.gl); + + var index = this.batchs.indexOf( previousBatch ); + batch.init(displayObject); + this.batchs.splice(index+1, 0, batch, splitBatch); + + return; + } + } + } + } + else + { + // TODO re-word! + nextBatch = nextSprite; + } + } + + /* + * looks like it does not belong to any batch! + * but is also not intersecting one.. + * time to create anew one! + */ + + var batch = PIXI._getBatch(this.gl); + batch.init(displayObject); + + if(previousBatch) // if this is invalid it means + { + var index = this.batchs.indexOf( previousBatch ); + this.batchs.splice(index+1, 0, batch); + } + else + { + this.batchs.push(batch); + } + + } + else if(displayObject instanceof PIXI.Strip) + { + // add to a batch!! + this.initStrip(displayObject); + this.batchs.push(displayObject); + + } + + // if its somthing else... then custom codes! + this.batchUpdate = true; +} + +/** + * @private + */ +PIXI.WebGLRenderer.prototype.removeDisplayObject = function(displayObject) +{ + //if(displayObject.stage)return; + displayObject.cacheVisible = false;//displayObject.visible; + + if(!displayObject.renderable)return; + + displayObject.__inWebGL = false; + + /* + * removing is a lot quicker.. + * + */ + var batchToRemove; + + if(displayObject instanceof PIXI.Sprite) + { + // should always have a batch! + var batch = displayObject.batch; + if(!batch)return; // this means the display list has been altered befre rendering + + batch.remove(displayObject); + + + if(batch.size==0) + { + batchToRemove = batch + } + } + else + { + batchToRemove = displayObject; + } + + /* + * Looks like there is somthing that needs removing! + */ + if(batchToRemove) + { + var index = this.batchs.indexOf( batchToRemove ); + if(index == -1)return;// this means it was added then removed before rendered + + // ok so.. check to see if you adjacent batchs should be joined. + // TODO may optimise? + if(index == 0 || index == this.batchs.length-1) + { + // wha - eva! just get of the empty batch! + this.batchs.splice(index, 1); + if(batchToRemove instanceof PIXI.WebGLBatch)PIXI._returnBatch(batchToRemove); + + return; + } + + if(this.batchs[index-1] instanceof PIXI.WebGLBatch && this.batchs[index+1] instanceof PIXI.WebGLBatch) + { + if(this.batchs[index-1].texture == this.batchs[index+1].texture && this.batchs[index-1].blendMode == this.batchs[index+1].blendMode) + { + //console.log("MERGE") + this.batchs[index-1].merge(this.batchs[index+1]); + + if(batchToRemove instanceof PIXI.WebGLBatch)PIXI._returnBatch(batchToRemove); + PIXI._returnBatch(this.batchs[index+1]); + this.batchs.splice(index, 2); + return; + } + } + + + this.batchs.splice(index, 1); + if(batchToRemove instanceof PIXI.WebGLBatch)PIXI._returnBatch(batchToRemove); + } + + +} + +/** + * resizes the webGL view to the specified width and height + * @method resize + * @param width {Number} the new width of the webGL view + * @param height {Number} the new height of the webGL view + */ +PIXI.WebGLRenderer.prototype.resize = function(width, height) +{ + this.width = width; + this.height = height; + + this.view.width = width; + this.view.height = height; + + this.gl.viewport(0, 0, this.width, this.height); + + var projectionMatrix = this.projectionMatrix; + + projectionMatrix[0] = 2/this.width; + projectionMatrix[5] = -2/this.height; + projectionMatrix[12] = -1; + projectionMatrix[13] = 1; +} + +/** + * @private + */ +PIXI.WebGLRenderer.prototype.initStrip = function(strip) +{ + // build the strip! + var gl = this.gl; + var shaderProgram = this.shaderProgram; + + strip._vertexBuffer = gl.createBuffer(); + strip._indexBuffer = gl.createBuffer(); + strip._uvBuffer = gl.createBuffer(); + strip._colorBuffer = gl.createBuffer(); + + gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer); + gl.bufferData(gl.ARRAY_BUFFER, strip.verticies, gl.DYNAMIC_DRAW); + + gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer); + gl.bufferData(gl.ARRAY_BUFFER, strip.uvs, gl.STATIC_DRAW); + + gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer); + gl.bufferData(gl.ARRAY_BUFFER, strip.colors, gl.STATIC_DRAW); + + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, strip.indices, gl.STATIC_DRAW); +} + +/** + * @private + */ +PIXI.WebGLRenderer.prototype.renderStrip = function(strip) +{ + var gl = this.gl; + var shaderProgram = this.shaderProgram; +// mat + var mat4Real = PIXI.mat3.toMat4(strip.worldTransform); + PIXI.mat4.transpose(mat4Real); + PIXI.mat4.multiply(this.projectionMatrix, mat4Real, mat4Real ) + + gl.uniformMatrix4fv(this.shaderProgram.mvMatrixUniform, false, mat4Real); + + if(strip.blendMode == PIXI.blendModes.NORMAL) + { + gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + } + else + { + gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_COLOR); + } + + if(!strip.dirty) + { + + gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer); + gl.bufferSubData(gl.ARRAY_BUFFER, 0, strip.verticies) + gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0); + + // update the uvs + gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer); + gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0); + + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, strip.texture.baseTexture._glTexture); + + gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer); + gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0); + + // dont need to upload! + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer); + + + } + else + { + strip.dirty = false; + gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer); + gl.bufferData(gl.ARRAY_BUFFER, strip.verticies, gl.STATIC_DRAW) + gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0); + + // update the uvs + gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer); + gl.bufferData(gl.ARRAY_BUFFER, strip.uvs, gl.STATIC_DRAW) + gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0); + + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, strip.texture.baseTexture._glTexture); + + gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer); + gl.bufferData(gl.ARRAY_BUFFER, strip.colors, gl.STATIC_DRAW) + gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0); + + // dont need to upload! + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, strip.indices, gl.STATIC_DRAW); + + } + + gl.drawElements(gl.TRIANGLE_STRIP, strip.indices.length, gl.UNSIGNED_SHORT, 0); + + gl.uniformMatrix4fv(this.shaderProgram.mvMatrixUniform, false, this.projectionMatrix); + + // console.log("!!!") +} + +/** + * @private + */ +PIXI.WebGLRenderer.prototype.handleContextLost = function(event) +{ + event.preventDefault(); + this.contextLost = true; +} + +/** + * @private + */ +PIXI.WebGLRenderer.prototype.handleContextRestored = function(event) +{ + this.gl = this.view.getContext("experimental-webgl", { + alpha: true + }); + + this.initShaders(); + + for (var i=0; i < PIXI.TextureCache.length; i++) + { + this.updateTexture(PIXI.TextureCache[i]); + }; + + for (var i=0; i < this.batchs.length; i++) + { + this.batchs[i].restoreLostContext(this.gl)// + this.batchs[i].dirty = true; + }; + + PIXI._restoreBatchs(this.gl); + + this.contextLost = false; +} + + +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + +PIXI._batchs = []; + +/** + * @private + */ +PIXI._getBatch = function(gl) +{ + if(PIXI._batchs.length == 0) + { + return new PIXI.WebGLBatch(gl); + } + else + { + return PIXI._batchs.pop(); + } +} + +/** + * @private + */ +PIXI._returnBatch = function(batch) +{ + batch.clean(); + PIXI._batchs.push(batch); +} + +/** + * @private + */ +PIXI._restoreBatchs = function(gl) +{ + for (var i=0; i < PIXI._batchs.length; i++) + { + PIXI._batchs[i].restoreLostContext(gl); + }; +} + +/** + * A WebGLBatch Enables a group of sprites to be drawn using the same settings. + * if a group of sprites all have the same baseTexture and blendMode then they can be grouped into a batch. All the sprites in a batch can then be drawn in one go by the GPU which is hugely efficient. ALL sprites in the webGL renderer are added to a batch even if the batch only contains one sprite. Batching is handled automatically by the webGL renderer. A good tip is: the smaller the number of batchs there are, the faster the webGL renderer will run. + * @class WebGLBatch + * @param an instance of the webGL context + * @return {PIXI.renderers.WebGLBatch} WebGLBatch {@link PIXI.renderers.WebGLBatch} + */ +PIXI.WebGLBatch = function(gl) +{ + this.gl = gl; + + this.size = 0; + + this.vertexBuffer = gl.createBuffer(); + this.indexBuffer = gl.createBuffer(); + this.uvBuffer = gl.createBuffer(); + this.colorBuffer = gl.createBuffer(); + this.blendMode = PIXI.blendModes.NORMAL; + this.dynamicSize = 1; +} + + +// constructor +PIXI.WebGLBatch.constructor = PIXI.WebGLBatch; + +/** + * Cleans the batch so that is can be returned to an object pool and reused + */ +PIXI.WebGLBatch.prototype.clean = function() +{ + this.verticies = []; + this.uvs = []; + this.indices = []; + this.colors = []; + //this.sprites = []; + this.dynamicSize = 1; + this.texture = null; + this.last = null; + this.size = 0; + + this.head; + this.tail; +} + +/* + * recreates the buffers in the event of a context loss + */ +PIXI.WebGLBatch.prototype.restoreLostContext = function(gl) +{ + this.gl = gl; + this.vertexBuffer = gl.createBuffer(); + this.indexBuffer = gl.createBuffer(); + this.uvBuffer = gl.createBuffer(); + this.colorBuffer = gl.createBuffer(); +} + +/** + * inits the batch's texture and blend mode based if the supplied sprite + * @method init + * @param sprite {Sprite} the first sprite to be added to the batch. Only sprites with the same base texture and blend mode will be allowed to be added to this batch + */ +PIXI.WebGLBatch.prototype.init = function(sprite) +{ + sprite.batch = this; + this.dirty = true; + this.blendMode = sprite.blendMode; + this.texture = sprite.texture.baseTexture; +// this.sprites.push(sprite); + this.head = sprite; + this.tail = sprite; + this.size = 1; + + this.growBatch(); +} + +/** + * inserts a sprite before the specified sprite + * @method insertBefore + * @param sprite {Sprite} the sprite to be added + * @param nextSprite {nextSprite} the first sprite will be inserted before this sprite + */ +PIXI.WebGLBatch.prototype.insertBefore = function(sprite, nextSprite) +{ + this.size++; + + sprite.batch = this; + this.dirty = true; + var tempPrev = nextSprite.__prev; + nextSprite.__prev = sprite; + sprite.__next = nextSprite; + + if(tempPrev) + { + sprite.__prev = tempPrev; + tempPrev.__next = sprite; + } + else + { + this.head = sprite; + //this.head.__prev = null + } +} + +/** + * inserts a sprite after the specified sprite + * @method insertAfter + * @param sprite {Sprite} the sprite to be added + * @param previousSprite {Sprite} the first sprite will be inserted after this sprite + */ +PIXI.WebGLBatch.prototype.insertAfter = function(sprite, previousSprite) +{ + this.size++; + + + sprite.batch = this; + this.dirty = true; + + var tempNext = previousSprite.__next; + previousSprite.__next = sprite; + sprite.__prev = previousSprite; + + if(tempNext) + { + sprite.__next = tempNext; + tempNext.__prev = sprite; + } + else + { + this.tail = sprite + } + +} + +/** + * removes a sprite from the batch + * @method remove + * @param sprite {Sprite} the sprite to be removed + */ +PIXI.WebGLBatch.prototype.remove = function(sprite) +{ + this.size--; + + if(this.size == 0) + { + sprite.batch = null; + sprite.__prev = null; + sprite.__next = null; + return; + } + + if(sprite.__prev) + { + sprite.__prev.__next = sprite.__next; + } + else + { + this.head = sprite.__next; + this.head.__prev = null; + } + + if(sprite.__next) + { + sprite.__next.__prev = sprite.__prev; + } + else + { + this.tail = sprite.__prev; + this.tail.__next = null + } + + sprite.batch = null; + sprite.__next = null; + sprite.__prev = null; + this.dirty = true; +} + +/** + * Splits the batch into two with the specified sprite being the start of the new batch. + * @method split + * @param sprite {Sprite} the sprite that indicates where the batch should be split + * @return {WebGLBatch} the new batch + */ +PIXI.WebGLBatch.prototype.split = function(sprite) +{ + + //console.log("Splitting batch :" + this.size) +// console.log(sprite) +// console.log("-------") + this.dirty = true; + + //var val = (this.tail == this.head) + //console.log(val + " SAME?"); + var batch = new PIXI.WebGLBatch(this.gl)//PIXI._getBatch(this.gl); + batch.init(sprite); + batch.tail = this.tail; + //console.log("id is " +batcheee.id) + + this.tail = sprite.__prev; + this.tail.__next = null; + + sprite.__prev = null; + // return a splite batch! + //sprite.__prev.__next = null; + //sprite.__prev = null; + + + // TODO this size is wrong! + // need to recalculate :/ problem with a linked list! + // unless it gets calculated in the "clean"? + + // need to loop through items as there is no way to know the length on a linked list :/ + var tempSize = 0; + while(sprite) + { + tempSize++; + sprite.batch = batch; + sprite = sprite.__next; + } + + batch.size = tempSize; + this.size -= tempSize; + + return batch; +} + +/** + * Merges two batchs together + * @method merge + * @param batch {WebGLBatch} the batch that will be merged + */ +PIXI.WebGLBatch.prototype.merge = function(batch) +{ + this.dirty = true; + + this.tail.__next = batch.head; + batch.head.__prev = this.tail; + + this.size += batch.size; + + this.tail = batch.tail; + + var sprite = batch.head; + while(sprite) + { + sprite.batch = this; + sprite = sprite.__next; + } + +} + +/** + * Grows the size of the batch. As the elements in the batch cannot have a dynamic size this function is used to increase the size of the batch. It also creates a little extra room so that the batch does not need to be resized every time a sprite is added + * @methos growBatch + */ +PIXI.WebGLBatch.prototype.growBatch = function() +{ + var gl = this.gl; + if( this.size == 1) + { + this.dynamicSize = 1; + } + else + { + this.dynamicSize = this.size * 1.5 + } + // grow verts + this.verticies = new Float32Array(this.dynamicSize * 8); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + gl.bufferData(gl.ARRAY_BUFFER,this.verticies , gl.DYNAMIC_DRAW); + + this.uvs = new Float32Array( this.dynamicSize * 8 ) + gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); + gl.bufferData(gl.ARRAY_BUFFER, this.uvs , gl.DYNAMIC_DRAW); + + this.dirtyUVS = true; + + this.colors = new Float32Array( this.dynamicSize * 4 ) + gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); + gl.bufferData(gl.ARRAY_BUFFER, this.colors , gl.DYNAMIC_DRAW); + + this.dirtyColors = true; + + this.indices = new Uint16Array(this.dynamicSize * 6); + var length = this.indices.length/6; + + for (var i=0; i < length; i++) + { + var index2 = i * 6; + var index3 = i * 4; + this.indices[index2 + 0] = index3 + 0; + this.indices[index2 + 1] = index3 + 1; + this.indices[index2 + 2] = index3 + 2; + this.indices[index2 + 3] = index3 + 0; + this.indices[index2 + 4] = index3 + 2; + this.indices[index2 + 5] = index3 + 3; + }; + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); + +} + +/** + * Refresh's all the data in the batch and sync's it with the webGL buffers + * @method refresh + */ +PIXI.WebGLBatch.prototype.refresh = function() +{ + var gl = this.gl; + + if (this.dynamicSize < this.size) + { + this.growBatch(); + } + + var indexRun = 0; + var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index + var a, b, c, d, tx, ty + + var displayObject = this.head + + while(displayObject) + { + index = indexRun * 8; + + var texture = displayObject.texture; + + var frame = texture.frame; + var tw = texture.baseTexture.width; + var th = texture.baseTexture.height; + + this.uvs[index + 0] = frame.x / tw; + this.uvs[index +1] = frame.y / th; + + this.uvs[index +2] = (frame.x + frame.width) / tw; + this.uvs[index +3] = frame.y / th; + + this.uvs[index +4] = (frame.x + frame.width) / tw; + this.uvs[index +5] = (frame.y + frame.height) / th; + + this.uvs[index +6] = frame.x / tw; + this.uvs[index +7] = (frame.y + frame.height) / th; + + displayObject.updateFrame = false; + + colorIndex = indexRun * 4; + this.colors[colorIndex] = this.colors[colorIndex + 1] = this.colors[colorIndex + 2] = this.colors[colorIndex + 3] = displayObject.worldAlpha; + + displayObject = displayObject.__next; + + indexRun ++; + } + + this.dirtyUVS = true; + this.dirtyColors = true; +} + +/** + * Updates all the relevant geometry and uploads the data to the GPU + * @method update + */ +PIXI.WebGLBatch.prototype.update = function() +{ + var gl = this.gl; + var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index, index2, index3 + + var a, b, c, d, tx, ty; + + var indexRun = 0; + + var displayObject = this.head; + + while(displayObject) + { + width = displayObject.width; + height = displayObject.height; + + aX = displayObject.anchor.x - displayObject.texture.trim.x + aY = displayObject.anchor.y - displayObject.texture.trim.y + w0 = width * (1-aX); + w1 = width * -aX; + + h0 = height * (1-aY); + h1 = height * -aY; + + index = indexRun * 8; + + worldTransform = displayObject.worldTransform; + + a = worldTransform[0]; + b = worldTransform[3]; + c = worldTransform[1]; + d = worldTransform[4]; + tx = worldTransform[2]; + ty = worldTransform[5]; + + this.verticies[index + 0 ] = a * w1 + c * h1 + tx; + this.verticies[index + 1 ] = d * h1 + b * w1 + ty; + + this.verticies[index + 2 ] = a * w0 + c * h1 + tx; + this.verticies[index + 3 ] = d * h1 + b * w0 + ty; + + this.verticies[index + 4 ] = a * w0 + c * h0 + tx; + this.verticies[index + 5 ] = d * h0 + b * w0 + ty; + + this.verticies[index + 6] = a * w1 + c * h0 + tx; + this.verticies[index + 7] = d * h0 + b * w1 + ty; + + if(displayObject.updateFrame) + { + this.dirtyUVS = true; + + var texture = displayObject.texture; + + var frame = texture.frame; + var tw = texture.baseTexture.width; + var th = texture.baseTexture.height; + + this.uvs[index + 0] = frame.x / tw; + this.uvs[index +1] = frame.y / th; + + this.uvs[index +2] = (frame.x + frame.width) / tw; + this.uvs[index +3] = frame.y / th; + + this.uvs[index +4] = (frame.x + frame.width) / tw; + this.uvs[index +5] = (frame.y + frame.height) / th; + + this.uvs[index +6] = frame.x / tw; + this.uvs[index +7] = (frame.y + frame.height) / th; + + displayObject.updateFrame = false; + } + + // TODO this probably could do with some optimisation.... + if(displayObject.cacheAlpha != displayObject.worldAlpha) + { + displayObject.cacheAlpha = displayObject.worldAlpha; + + var colorIndex = indexRun * 4; + this.colors[colorIndex] = this.colors[colorIndex + 1] = this.colors[colorIndex + 2] = this.colors[colorIndex + 3] = displayObject.worldAlpha; + this.dirtyColors = true; + } + + indexRun++; + displayObject = displayObject.__next; + } +} + +/** + * Draws the batch to the frame buffer + * @method render + */ +PIXI.WebGLBatch.prototype.render = function() +{ + if(this.dirty) + { + this.refresh(); + this.dirty = false; + } + + if (this.size == 0)return; + + this.update(); + var gl = this.gl; + + //TODO optimize this! + if(this.blendMode == PIXI.blendModes.NORMAL) + { + gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + } + else + { + gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_COLOR); + } + + var shaderProgram = PIXI.shaderProgram; + + // update the verts.. + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + // ok.. + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.verticies) + gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0); + + // update the uvs + gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); + + if(this.dirtyUVS) + { + this.dirtyUVS = false; + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvs); + } + + gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0); + + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, this.texture._glTexture); + + // update color! + gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); + + if(this.dirtyColors) + { + this.dirtyColors = false; + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.colors); + } + + gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0); + + // dont need to upload! + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + + // DRAW THAT this! + gl.drawElements(gl.TRIANGLES, this.size * 6, gl.UNSIGNED_SHORT, 0); +} + + +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + + +/** + * the CanvasRenderer draws the stage and all its content onto a 2d canvas. This renderer should be used for browsers that do not support webGL. + * Dont forget to add the view to your DOM or you will not see anything :) + * @class CanvasRenderer + * @constructor + * @param width {Number} the width of the canvas view + * @default 0 + * @param height {Number} the height of the canvas view + * @default 0 + * @param view {Canvas} the canvas to use as a view, optional + * @param transparent {Boolean} the transparency of the render view, default false + * @default false + * + */ +PIXI.CanvasRenderer = function(width, height, view, transparent) +{ + this.transparent = transparent; + + /** + * The width of the canvas view + * @property width + * @type Number + * @default 800 + */ + this.width = width || 800; + /** + * The height of the canvas view + * @property height + * @type Number + * @default 600 + */ + this.height = height || 600; + + this.refresh = true; + + /** + * The canvas element that the everything is drawn to + * @property view + * @type Canvas + */ + this.view = view || document.createElement( 'canvas' ); + + // hack to enable some hardware acceleration! + //this.view.style["transform"] = "translatez(0)"; + + this.view.width = this.width; + this.view.height = this.height; + this.count = 0; + + /** + * The canvas context that the everything is drawn to + * @property context + * @type Canvas 2d Context + */ + this.context = this.view.getContext("2d"); +} + +// constructor +PIXI.CanvasRenderer.constructor = PIXI.CanvasRenderer; + +/** + * Renders the stage to its canvas view + * @method render + * @param stage {Stage} the Stage element to be rendered + */ +PIXI.CanvasRenderer.prototype.render = function(stage) +{ + // update children if need be + + stage.__childrenAdded = []; + stage.__childrenRemoved = []; + + // update textures if need be + PIXI.texturesToUpdate = []; + + this.context.setTransform(1,0,0,1,0,0); + stage.updateTransform(); + + this.context.setTransform(1,0,0,1,0,0); + + // update the background color + if(this.view.style.backgroundColor!=stage.backgroundColorString && !this.transparent)this.view.style.backgroundColor = stage.backgroundColorString; + + this.context.clearRect(0, 0, this.width, this.height) + this.renderDisplayObject(stage); + //as + + // run interaction! + if(stage.interactive) + { + //need to add some events! + if(!stage._interactiveEventsAdded) + { + stage._interactiveEventsAdded = true; + stage.interactionManager.setTarget(this); + } + } +} + +/** + * resizes the canvas view to the specified width and height + * @param the new width of the canvas view + * @param the new height of the canvas view + */ +PIXI.CanvasRenderer.prototype.resize = function(width, height) +{ + this.width = width; + this.height = height; + + this.view.width = width; + this.view.height = height; +} + +/** + * @private + */ +PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject) +{ + var transform = displayObject.worldTransform; + var context = this.context; + context.globalCompositeOperation = "source-over" + var blit = false; + + if(!displayObject.visible)return; + + if(displayObject instanceof PIXI.Sprite) + { + var frame = displayObject.texture.frame; + + if(frame) + { + context.globalAlpha = displayObject.worldAlpha; + + // BLITZ!!! + /* + * if the rotation is 0 then we can blitz it + * meaning we dont need to do a transform and also we + * can round to the nearest round number for a little extra speed! + */ + /*if(displayObject.rotation == 0) + { + if(!blit)this.context.setTransform(1,0,0,1,0,0); + blit = true; + context.drawImage(displayObject.texture.baseTexture.image, + frame.x, + frame.y, + frame.width, + frame.height, + (transform[2]+ ((displayObject.anchor.x - displayObject.texture.trim.x) * -frame.width) * transform[0]), + (transform[5]+ ((displayObject.anchor.y - displayObject.texture.trim.y) * -frame.height)* transform[4]), + (displayObject.width * transform[0]), + (displayObject.height * transform[4])); + + } + else + {*/ + blit = false; + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]) + context.drawImage(displayObject.texture.baseTexture.source, + frame.x, + frame.y, + frame.width, + frame.height, + (displayObject.anchor.x - displayObject.texture.trim.x) * -frame.width, + (displayObject.anchor.y - displayObject.texture.trim.y) * -frame.height, + displayObject.width, + displayObject.height); + //} + } + } + else if(displayObject instanceof PIXI.Strip) + { + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]) + this.renderStrip(displayObject); + } + + // render! + for (var i=0; i < displayObject.children.length; i++) + { + this.renderDisplayObject(displayObject.children[i]); + } +} + +/** + * @private + */ +PIXI.CanvasRenderer.prototype.renderStripFlat = function(strip) +{ + var context = this.context; + var verticies = strip.verticies; + var uvs = strip.uvs; + + var length = verticies.length/2; + this.count++; + + context.beginPath(); + for (var i=1; i < length-2; i++) + { + + // draw some triangles! + var index = i*2; + + var x0 = verticies[index], x1 = verticies[index+2], x2 = verticies[index+4]; + var y0 = verticies[index+1], y1 = verticies[index+3], y2 = verticies[index+5]; + + context.moveTo(x0, y0); + context.lineTo(x1, y1); + context.lineTo(x2, y2); + + }; + +// context.globalCompositeOperation = 'lighter'; + context.fillStyle = "#FF0000"; + context.fill(); + context.closePath(); + //context.globalCompositeOperation = 'source-over'; +} + +/** + * @private + */ +PIXI.CanvasRenderer.prototype.renderStrip = function(strip) +{ + var context = this.context; + //context.globalCompositeOperation = 'lighter'; + // draw triangles!! + var verticies = strip.verticies; + var uvs = strip.uvs; + + var length = verticies.length/2; + this.count++; + for (var i=1; i < length-2; i++) + { + + // draw some triangles! + var index = i*2; + + var x0 = verticies[index], x1 = verticies[index+2], x2 = verticies[index+4]; + var y0 = verticies[index+1], y1 = verticies[index+3], y2 = verticies[index+5]; + + var u0 = uvs[index] * strip.texture.width, u1 = uvs[index+2]* strip.texture.width, u2 = uvs[index+4]* strip.texture.width; + var v0 = uvs[index+1]* strip.texture.height, v1 = uvs[index+3]* strip.texture.height, v2 = uvs[index+5]* strip.texture.height; + + + context.save(); + context.beginPath(); + context.moveTo(x0, y0); + context.lineTo(x1, y1); + context.lineTo(x2, y2); + context.closePath(); + + // context.fillStyle = "white"//rgb(1, 1, 1,1)); + // context.fill(); + context.clip(); + + + // Compute matrix transform + var delta = u0*v1 + v0*u2 + u1*v2 - v1*u2 - v0*u1 - u0*v2; + var delta_a = x0*v1 + v0*x2 + x1*v2 - v1*x2 - v0*x1 - x0*v2; + var delta_b = u0*x1 + x0*u2 + u1*x2 - x1*u2 - x0*u1 - u0*x2; + var delta_c = u0*v1*x2 + v0*x1*u2 + x0*u1*v2 - x0*v1*u2 - v0*u1*x2 - u0*x1*v2; + var delta_d = y0*v1 + v0*y2 + y1*v2 - v1*y2 - v0*y1 - y0*v2; + var delta_e = u0*y1 + y0*u2 + u1*y2 - y1*u2 - y0*u1 - u0*y2; + var delta_f = u0*v1*y2 + v0*y1*u2 + y0*u1*v2 - y0*v1*u2 - v0*u1*y2 - u0*y1*v2; + + + + + context.transform(delta_a/delta, delta_d/delta, + delta_b/delta, delta_e/delta, + delta_c/delta, delta_f/delta); + + context.drawImage(strip.texture.baseTexture.source, 0, 0); + context.restore(); + }; + +// context.globalCompositeOperation = 'source-over'; +} + + + + + + + + + +/** + * @author Mat Groves http://matgroves.com/ + */ + +PIXI.Strip = function(texture, width, height) +{ + PIXI.DisplayObjectContainer.call( this ); + this.texture = texture; + this.blendMode = PIXI.blendModes.NORMAL; + + try + { + this.uvs = new Float32Array([0, 1, + 1, 1, + 1, 0, 0,1]); + + this.verticies = new Float32Array([0, 0, + 0,0, + 0,0, 0, + 0, 0]); + + this.colors = new Float32Array([1, 1, 1, 1]); + + this.indices = new Uint16Array([0, 1, 2, 3]); + } + catch(error) + { + this.uvs = [0, 1, + 1, 1, + 1, 0, 0,1]; + + this.verticies = [0, 0, + 0,0, + 0,0, 0, + 0, 0]; + + this.colors = [1, 1, 1, 1]; + + this.indices = [0, 1, 2, 3]; + } + + + /* + this.uvs = new Float32Array() + this.verticies = new Float32Array() + this.colors = new Float32Array() + this.indices = new Uint16Array() +*/ + this.width = width; + this.height = height; + + // load the texture! + if(texture.baseTexture.hasLoaded) + { + this.width = this.texture.frame.width; + this.height = this.texture.frame.height; + this.updateFrame = true; + } + else + { + this.onTextureUpdateBind = this.onTextureUpdate.bind(this); + this.texture.addEventListener( 'update', this.onTextureUpdateBind ); + } + + this.renderable = true; +} + +// constructor +PIXI.Strip.constructor = PIXI.Strip; +PIXI.Strip.prototype = Object.create( PIXI.DisplayObjectContainer.prototype ); + +PIXI.Strip.prototype.setTexture = function(texture) +{ + //TODO SET THE TEXTURES + //TODO VISIBILITY + + // stop current texture + this.texture = texture; + this.width = texture.frame.width; + this.height = texture.frame.height; + this.updateFrame = true; +} + +PIXI.Strip.prototype.onTextureUpdate = function(event) +{ + this.updateFrame = true; +} +// some helper functions.. + + +/** + * @author Mat Groves http://matgroves.com/ + */ + + +PIXI.Rope = function(texture, points) +{ + PIXI.Strip.call( this, texture ); + this.points = points; + + try + { + this.verticies = new Float32Array( points.length * 4); + this.uvs = new Float32Array( points.length * 4); + this.colors = new Float32Array( points.length * 2); + this.indices = new Uint16Array( points.length * 2); + } + catch(error) + { + this.verticies = verticies + + this.uvs = uvs + this.colors = colors + this.indices = indices + } + + this.refresh(); +} + + +// constructor +PIXI.Rope.constructor = PIXI.Rope; +PIXI.Rope.prototype = Object.create( PIXI.Strip.prototype ); + +PIXI.Rope.prototype.refresh = function() +{ + var points = this.points; + if(points.length < 1)return; + + var uvs = this.uvs + var indices = this.indices; + var colors = this.colors; + + var lastPoint = points[0]; + var nextPoint; + var perp = {x:0, y:0}; + var point = points[0]; + + this.count-=0.2; + + + uvs[0] = 0 + uvs[1] = 1 + uvs[2] = 0 + uvs[3] = 1 + + colors[0] = 1; + colors[1] = 1; + + indices[0] = 0; + indices[1] = 1; + + var total = points.length; + + for (var i = 1; i < total; i++) + { + + var point = points[i]; + var index = i * 4; + // time to do some smart drawing! + var amount = i/(total-1) + + if(i%2) + { + uvs[index] = amount; + uvs[index+1] = 0; + + uvs[index+2] = amount + uvs[index+3] = 1 + + } + else + { + uvs[index] = amount + uvs[index+1] = 0 + + uvs[index+2] = amount + uvs[index+3] = 1 + } + + index = i * 2; + colors[index] = 1; + colors[index+1] = 1; + + index = i * 2; + indices[index] = index; + indices[index + 1] = index + 1; + + lastPoint = point; + } +} + +PIXI.Rope.prototype.updateTransform = function() +{ + + var points = this.points; + if(points.length < 1)return; + + var verticies = this.verticies + + var lastPoint = points[0]; + var nextPoint; + var perp = {x:0, y:0}; + var point = points[0]; + + this.count-=0.2; + + verticies[0] = point.x + perp.x + verticies[1] = point.y + perp.y //+ 200 + verticies[2] = point.x - perp.x + verticies[3] = point.y - perp.y//+200 + // time to do some smart drawing! + + var total = points.length; + + for (var i = 1; i < total; i++) + { + + var point = points[i]; + var index = i * 4; + + if(i < points.length-1) + { + nextPoint = points[i+1]; + } + else + { + nextPoint = point + } + + perp.y = -(nextPoint.x - lastPoint.x); + perp.x = nextPoint.y - lastPoint.y; + + var ratio = (1 - (i / (total-1))) * 10; + if(ratio > 1)ratio = 1; + + var perpLength = Math.sqrt(perp.x * perp.x + perp.y * perp.y); + var num = this.texture.height/2//(20 + Math.abs(Math.sin((i + this.count) * 0.3) * 50) )* ratio; + perp.x /= perpLength; + perp.y /= perpLength; + + perp.x *= num; + perp.y *= num; + + verticies[index] = point.x + perp.x + verticies[index+1] = point.y + perp.y + verticies[index+2] = point.x - perp.x + verticies[index+3] = point.y - perp.y + + lastPoint = point; + } + + PIXI.DisplayObjectContainer.prototype.updateTransform.call( this ); +} + +PIXI.Rope.prototype.setTexture = function(texture) +{ + // stop current texture + this.texture = texture; + this.updateFrame = true; +} + + + + + +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + +PIXI.BaseTextureCache = {}; +PIXI.texturesToUpdate = []; + +/** + * A texture stores the information that represents an image. All textures have a base texture + * @class BaseTexture + * @extends EventTarget + * @constructor + * @param source {String} the source object (image or canvas) + */ +PIXI.BaseTexture = function(source) +{ + PIXI.EventTarget.call( this ); + + /* + * The url of the texture + * @property imageUrl + * @type String + */ + //this.imageUrl = source.src; + + /** + * [read only] The width of the base texture set when the image has loaded + * @property width + * @type Number + */ + this.width = 100; + /** + * [read only] The height of the base texture set when the image has loaded + * @property height + * @type Number + */ + this.height = 100; + + /** + * The source that is loaded to create the texture + * @property source + * @type Image + */ + this.source = source//new Image(); + + if(this.source instanceof Image) + { + if(this.source.complete) + { + this.hasLoaded = true; + this.width = this.source.width; + this.height = this.source.height; + + PIXI.texturesToUpdate.push(this); + } + else + { + + var scope = this; + this.source.onload = function(){ + + scope.hasLoaded = true; + scope.width = scope.source.width; + scope.height = scope.source.height; + + // add it to somewhere... + PIXI.texturesToUpdate.push(scope); + scope.dispatchEvent( { type: 'loaded', content: scope } ); + } + // this.image.src = imageUrl; + } + } + else + { + this.hasLoaded = true; + this.width = this.source.width; + this.height = this.source.height; + + //console.log(">!!",this.width) + PIXI.texturesToUpdate.push(this); + } + + + +} + +PIXI.BaseTexture.constructor = PIXI.BaseTexture; + +PIXI.BaseTexture.prototype.fromImage = function(imageUrl) +{ + +} + +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + +PIXI.TextureCache = {}; +PIXI.FrameCache = {}; + +/** + * A texture stores the information that represents an image or part of an image. It cannot be added to the display list directly. To do this use PIXI.Sprite. If no frame is provided then the whole image is used + * @class Texture + * @extends EventTarget + * @constructor + * @param baseTexture {BaseTexture} + * @param frmae {Rectangle} + */ +PIXI.Texture = function(baseTexture, frame) +{ + PIXI.EventTarget.call( this ); + + if(!frame) + { + this.noFrame = true; + frame = new PIXI.Rectangle(0,0,1,1); + } + + this.trim = new PIXI.Point(); + + /** + * The base texture of this texture + * @property baseTexture + * @type BaseTexture + */ + this.baseTexture = baseTexture; + + + + /** + * The frame specifies the region of the base texture that this texture uses + * @property frame + * @type #Rectangle + */ + this.frame = frame; + + this.scope = this; + + if(baseTexture.hasLoaded) + { + if(this.noFrame)frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height); + //console.log(frame) + + this.setFrame(frame); + } + else + { + var scope = this; + baseTexture.addEventListener( 'loaded', function(){ scope.onBaseTextureLoaded()} ); + } +} + +PIXI.Texture.constructor = PIXI.Texture; + +PIXI.Texture.prototype.onBaseTextureLoaded = function(event) +{ + var baseTexture = this.baseTexture; + baseTexture.removeEventListener( 'loaded', this.onLoaded ); + + if(this.noFrame)this.frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height); + this.noFrame = false; + this.width = this.frame.width; + this.height = this.frame.height; + + this.scope.dispatchEvent( { type: 'update', content: this } ); +} + +/** + * Specifies the rectangle region of the baseTexture + * @method setFrame + * @param frame {Rectangle} + */ +PIXI.Texture.prototype.setFrame = function(frame) +{ + this.frame = frame; + this.width = frame.width; + this.height = frame.height; + + if(frame.x + frame.width > this.baseTexture.width || frame.y + frame.height > this.baseTexture.height) + { + throw new Error("Texture Error: frame does not fit inside the base Texture dimensions " + this); + } + //this.updateFrame = true; +} + +/** + * + * Helper function that returns a texture based on an image url + * If the image is not in the texture cache it will be created and loaded + * @static + * @method fromImage + * @param imageUrl {String} The image url of the texture + * @return Texture + */ +PIXI.Texture.fromImage = function(imageUrl, crossorigin) +{ + var texture = PIXI.TextureCache[imageUrl]; + + if(!texture) + { + var baseTexture = PIXI.BaseTextureCache[imageUrl]; + if(!baseTexture) + { + var image = new Image();//new Image(); + if (crossorigin) + { + image.crossOrigin = ''; + } + image.src = imageUrl; + baseTexture = new PIXI.BaseTexture(image); + PIXI.BaseTextureCache[imageUrl] = baseTexture; + } + texture = new PIXI.Texture(baseTexture); + + + PIXI.TextureCache[imageUrl] = texture; + + + } + + return texture; +} + +/** + * + * Helper function that returns a texture based on a frame id + * If the frame id is not in the texture cache an error will be thrown + * @method fromFrame + * @param frameId {String} The frame id of the texture + * @return Texture + */ +PIXI.Texture.fromFrame = function(frameId) +{ + var texture = PIXI.TextureCache[frameId]; + if(!texture)throw new Error("The frameId '"+ frameId +"' does not exist in the texture cache " + this); + return texture; +} + +/** + * + * Helper function that returns a texture based on a canvas element + * If the canvas is not in the texture cache it will be created and loaded + * @static + * @method fromCanvas + * @param canvas {Canvas} The canvas element source of the texture + * @return Texture + */ +PIXI.Texture.fromCanvas = function(canvas) +{ + var baseTexture = new PIXI.BaseTexture(canvas); + return new PIXI.Texture(baseTexture); +} + + +/** + * + * Adds a texture to the textureCache. + * @method addTextureToCache + * @param texture {Texture} + * @param id {String} the id that the texture will be stored against. + */ +PIXI.Texture.addTextureToCache = function(texture, id) +{ + PIXI.TextureCache[id] = texture; +} + +/** + * + * Remove a texture from the textureCache. + * @method removeTextureFromCache + * @param id {String} the id of the texture to be removed + * @return {Texture} the texture that was removed + */ +PIXI.Texture.removeTextureFromCache = function(id) +{ + var texture = PIXI.TextureCache[id] + PIXI.TextureCache[id] = null; + return texture; +} + + +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + +/** + * The sprite sheet loader is used to load in JSON sprite sheet data + * To generate the data you can use http://www.codeandweb.com/texturepacker and publish the "JSON" format + * There is a free version so thats nice, although the paid version is great value for money. + * It is highly recommended to use Sprite sheets (also know as texture atlas') as it means sprite's can be batched and drawn together for highly increased rendering speed. + * Once the data has been loaded the frames are stored in the PIXI texture cache and can be accessed though PIXI.Texture.fromFrameId() and PIXI.Sprite.fromFromeId() + * This loader will also load the image file that the Spritesheet points to as well as the data. + * When loaded this class will dispatch a 'loaded' event + * @class SpriteSheetLoader + * @extends EventTarget + * @constructor + * @param url {String} the url of the sprite sheet JSON file + */ + +PIXI.SpriteSheetLoader = function(url) +{ + /* + * i use texture packer to load the assets.. + * http://www.codeandweb.com/texturepacker + * make sure to set the format as "JSON" + */ + PIXI.EventTarget.call( this ); + this.url = url; + this.baseUrl = url.replace(/[^\/]*$/, ''); + this.texture; + this.frames = {}; + this.crossorigin = false; +} + +// constructor +PIXI.SpriteSheetLoader.constructor = PIXI.SpriteSheetLoader; + +/** + * This will begin loading the JSON file + */ +PIXI.SpriteSheetLoader.prototype.load = function() +{ + this.ajaxRequest = new AjaxRequest(); + var scope = this; + this.ajaxRequest.onreadystatechange=function() + { + scope.onLoaded(); + } + + this.ajaxRequest.open("GET", this.url, true) + if (this.ajaxRequest.overrideMimeType) this.ajaxRequest.overrideMimeType("application/json"); + this.ajaxRequest.send(null) +} + +PIXI.SpriteSheetLoader.prototype.onLoaded = function() +{ + if (this.ajaxRequest.readyState==4) + { + if (this.ajaxRequest.status==200 || window.location.href.indexOf("http")==-1) + { + var jsondata = eval("("+this.ajaxRequest.responseText+")"); + + var textureUrl = this.baseUrl + jsondata.meta.image; + + this.texture = PIXI.Texture.fromImage(textureUrl, this.crossorigin).baseTexture; + + // if(!this.texture)this.texture = new PIXI.Texture(textureUrl); + + var frameData = jsondata.frames; + for (var i in frameData) + { + var rect = frameData[i].frame; + if (rect) + { + PIXI.TextureCache[i] = new PIXI.Texture(this.texture, {x:rect.x, y:rect.y, width:rect.w, height:rect.h}); + + if(frameData[i].trimmed) + { + //var realSize = frameData[i].spriteSourceSize; + PIXI.TextureCache[i].realSize = frameData[i].spriteSourceSize; + PIXI.TextureCache[i].trim.x = 0// (realSize.x / rect.w) + // calculate the offset! + } + // this.frames[i] = ; + } + } + + if(this.texture.hasLoaded) + { + this.dispatchEvent( { type: 'loaded', content: this } ); + } + else + { + var scope = this; + // wait for the texture to load.. + this.texture.addEventListener('loaded', function(){ + + scope.dispatchEvent( { type: 'loaded', content: scope } ); + + }); + } + } + } + +} + + +/** + * @author Mat Groves http://matgroves.com/ @Doormat23 + */ + +/** + * A Class that loads a bunch of images / sprite sheet files. Once the assets have been loaded they are added to the PIXI Texture cache and can be accessed easily through PIXI.Texture.fromFrame(), PIXI.Texture.fromImage() and PIXI.Sprite.fromImage(), PIXI.Sprite.fromFromeId() + * When all items have been loaded this class will dispatch a 'loaded' event + * As each individual item is loaded this class will dispatch a 'progress' event + * @class AssetLoader + * @constructor + * @extends EventTarget + * @param assetURLs {Array} an array of image/sprite sheet urls that you would like loaded supported. Supported image formats include "jpeg", "jpg", "png", "gif". Supported sprite sheet data formats only include "JSON" at this time + */ +PIXI.AssetLoader = function(assetURLs) +{ + PIXI.EventTarget.call( this ); + + /** + * The array of asset URLs that are going to be loaded + * @property assetURLs + * @type Array + */ + this.assetURLs = assetURLs; + + this.assets = []; + + this.crossorigin = false; +} + +/** +Fired when an item has loaded +@event onProgress +**/ + +/** +Fired when all the assets have loaded +@event onComplete +**/ + +// constructor +PIXI.AssetLoader.constructor = PIXI.AssetLoader; + +/** + * This will begin loading the assets sequentially + */ +PIXI.AssetLoader.prototype.load = function() +{ + this.loadCount = this.assetURLs.length; + var imageTypes = ["jpeg", "jpg", "png", "gif"]; + + var spriteSheetTypes = ["json"]; + + for (var i=0; i < this.assetURLs.length; i++) + { + var filename = this.assetURLs[i]; + var fileType = filename.split('.').pop().toLowerCase(); + // what are we loading? + var type = null; + + for (var j=0; j < imageTypes.length; j++) + { + if(fileType == imageTypes[j]) + { + type = "img"; + break; + } + } + + if(type != "img") + { + for (var j=0; j < spriteSheetTypes.length; j++) + { + if(fileType == spriteSheetTypes[j]) + { + type = "atlas"; + break; + } + } + } + + if(type == "img") + { + + var texture = PIXI.Texture.fromImage(filename, this.crossorigin); + if(!texture.baseTexture.hasLoaded) + { + + var scope = this; + texture.baseTexture.addEventListener( 'loaded', function ( event ) + { + scope.onAssetLoaded(); + }); + + this.assets.push(texture); + } + else + { + + // already loaded! + this.loadCount--; + // if this hits zero here.. then everything was cached! + if(this.loadCount == 0) + { + this.dispatchEvent( { type: 'onComplete', content: this } ); + if(this.onComplete)this.onComplete(); + } + } + + } + else if(type == "atlas") + { + var spriteSheetLoader = new PIXI.SpriteSheetLoader(filename); + spriteSheetLoader.crossorigin = this.crossorigin; + this.assets.push(spriteSheetLoader); + + var scope = this; + spriteSheetLoader.addEventListener( 'loaded', function ( event ) + { + scope.onAssetLoaded(); + }); + + spriteSheetLoader.load(); + } + else + { + // dont know what the file is! :/ + //this.loadCount--; + throw new Error(filename + " is an unsupported file type " + this); + } + + //this.assets[i].load(); + }; +} + +PIXI.AssetLoader.prototype.onAssetLoaded = function() +{ + this.loadCount--; + this.dispatchEvent( { type: 'onProgress', content: this } ); + if(this.onProgress)this.onProgress(); + + if(this.loadCount == 0) + { + this.dispatchEvent( { type: 'onComplete', content: this } ); + if(this.onComplete)this.onComplete(); + } +} + diff --git a/Other versions/webgl test2/glMatrix-0.9.5.min.js b/Other versions/webgl test2/glMatrix-0.9.5.min.js new file mode 100644 index 0000000..4e4a830 --- /dev/null +++ b/Other versions/webgl test2/glMatrix-0.9.5.min.js @@ -0,0 +1,32 @@ +// glMatrix v0.9.5 +glMatrixArrayType=typeof Float32Array!="undefined"?Float32Array:typeof WebGLFloatArray!="undefined"?WebGLFloatArray:Array;var vec3={};vec3.create=function(a){var b=new glMatrixArrayType(3);if(a){b[0]=a[0];b[1]=a[1];b[2]=a[2]}return b};vec3.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];return b};vec3.add=function(a,b,c){if(!c||a==c){a[0]+=b[0];a[1]+=b[1];a[2]+=b[2];return a}c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];return c}; +vec3.subtract=function(a,b,c){if(!c||a==c){a[0]-=b[0];a[1]-=b[1];a[2]-=b[2];return a}c[0]=a[0]-b[0];c[1]=a[1]-b[1];c[2]=a[2]-b[2];return c};vec3.negate=function(a,b){b||(b=a);b[0]=-a[0];b[1]=-a[1];b[2]=-a[2];return b};vec3.scale=function(a,b,c){if(!c||a==c){a[0]*=b;a[1]*=b;a[2]*=b;return a}c[0]=a[0]*b;c[1]=a[1]*b;c[2]=a[2]*b;return c}; +vec3.normalize=function(a,b){b||(b=a);var c=a[0],d=a[1],e=a[2],g=Math.sqrt(c*c+d*d+e*e);if(g){if(g==1){b[0]=c;b[1]=d;b[2]=e;return b}}else{b[0]=0;b[1]=0;b[2]=0;return b}g=1/g;b[0]=c*g;b[1]=d*g;b[2]=e*g;return b};vec3.cross=function(a,b,c){c||(c=a);var d=a[0],e=a[1];a=a[2];var g=b[0],f=b[1];b=b[2];c[0]=e*b-a*f;c[1]=a*g-d*b;c[2]=d*f-e*g;return c};vec3.length=function(a){var b=a[0],c=a[1];a=a[2];return Math.sqrt(b*b+c*c+a*a)};vec3.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]}; +vec3.direction=function(a,b,c){c||(c=a);var d=a[0]-b[0],e=a[1]-b[1];a=a[2]-b[2];b=Math.sqrt(d*d+e*e+a*a);if(!b){c[0]=0;c[1]=0;c[2]=0;return c}b=1/b;c[0]=d*b;c[1]=e*b;c[2]=a*b;return c};vec3.lerp=function(a,b,c,d){d||(d=a);d[0]=a[0]+c*(b[0]-a[0]);d[1]=a[1]+c*(b[1]-a[1]);d[2]=a[2]+c*(b[2]-a[2]);return d};vec3.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+"]"};var mat3={}; +mat3.create=function(a){var b=new glMatrixArrayType(9);if(a){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9]}return b};mat3.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];return b};mat3.identity=function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=1;a[5]=0;a[6]=0;a[7]=0;a[8]=1;return a}; +mat3.transpose=function(a,b){if(!b||a==b){var c=a[1],d=a[2],e=a[5];a[1]=a[3];a[2]=a[6];a[3]=c;a[5]=a[7];a[6]=d;a[7]=e;return a}b[0]=a[0];b[1]=a[3];b[2]=a[6];b[3]=a[1];b[4]=a[4];b[5]=a[7];b[6]=a[2];b[7]=a[5];b[8]=a[8];return b};mat3.toMat4=function(a,b){b||(b=mat4.create());b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=0;b[4]=a[3];b[5]=a[4];b[6]=a[5];b[7]=0;b[8]=a[6];b[9]=a[7];b[10]=a[8];b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return b}; +mat3.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+"]"};var mat4={};mat4.create=function(a){var b=new glMatrixArrayType(16);if(a){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=a[12];b[13]=a[13];b[14]=a[14];b[15]=a[15]}return b}; +mat4.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=a[12];b[13]=a[13];b[14]=a[14];b[15]=a[15];return b};mat4.identity=function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=1;a[6]=0;a[7]=0;a[8]=0;a[9]=0;a[10]=1;a[11]=0;a[12]=0;a[13]=0;a[14]=0;a[15]=1;return a}; +mat4.transpose=function(a,b){if(!b||a==b){var c=a[1],d=a[2],e=a[3],g=a[6],f=a[7],h=a[11];a[1]=a[4];a[2]=a[8];a[3]=a[12];a[4]=c;a[6]=a[9];a[7]=a[13];a[8]=d;a[9]=g;a[11]=a[14];a[12]=e;a[13]=f;a[14]=h;return a}b[0]=a[0];b[1]=a[4];b[2]=a[8];b[3]=a[12];b[4]=a[1];b[5]=a[5];b[6]=a[9];b[7]=a[13];b[8]=a[2];b[9]=a[6];b[10]=a[10];b[11]=a[14];b[12]=a[3];b[13]=a[7];b[14]=a[11];b[15]=a[15];return b}; +mat4.determinant=function(a){var b=a[0],c=a[1],d=a[2],e=a[3],g=a[4],f=a[5],h=a[6],i=a[7],j=a[8],k=a[9],l=a[10],o=a[11],m=a[12],n=a[13],p=a[14];a=a[15];return m*k*h*e-j*n*h*e-m*f*l*e+g*n*l*e+j*f*p*e-g*k*p*e-m*k*d*i+j*n*d*i+m*c*l*i-b*n*l*i-j*c*p*i+b*k*p*i+m*f*d*o-g*n*d*o-m*c*h*o+b*n*h*o+g*c*p*o-b*f*p*o-j*f*d*a+g*k*d*a+j*c*h*a-b*k*h*a-g*c*l*a+b*f*l*a}; +mat4.inverse=function(a,b){b||(b=a);var c=a[0],d=a[1],e=a[2],g=a[3],f=a[4],h=a[5],i=a[6],j=a[7],k=a[8],l=a[9],o=a[10],m=a[11],n=a[12],p=a[13],r=a[14],s=a[15],A=c*h-d*f,B=c*i-e*f,t=c*j-g*f,u=d*i-e*h,v=d*j-g*h,w=e*j-g*i,x=k*p-l*n,y=k*r-o*n,z=k*s-m*n,C=l*r-o*p,D=l*s-m*p,E=o*s-m*r,q=1/(A*E-B*D+t*C+u*z-v*y+w*x);b[0]=(h*E-i*D+j*C)*q;b[1]=(-d*E+e*D-g*C)*q;b[2]=(p*w-r*v+s*u)*q;b[3]=(-l*w+o*v-m*u)*q;b[4]=(-f*E+i*z-j*y)*q;b[5]=(c*E-e*z+g*y)*q;b[6]=(-n*w+r*t-s*B)*q;b[7]=(k*w-o*t+m*B)*q;b[8]=(f*D-h*z+j*x)*q; +b[9]=(-c*D+d*z-g*x)*q;b[10]=(n*v-p*t+s*A)*q;b[11]=(-k*v+l*t-m*A)*q;b[12]=(-f*C+h*y-i*x)*q;b[13]=(c*C-d*y+e*x)*q;b[14]=(-n*u+p*B-r*A)*q;b[15]=(k*u-l*B+o*A)*q;return b};mat4.toRotationMat=function(a,b){b||(b=mat4.create());b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=0;b[13]=0;b[14]=0;b[15]=1;return b}; +mat4.toMat3=function(a,b){b||(b=mat3.create());b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[4];b[4]=a[5];b[5]=a[6];b[6]=a[8];b[7]=a[9];b[8]=a[10];return b};mat4.toInverseMat3=function(a,b){var c=a[0],d=a[1],e=a[2],g=a[4],f=a[5],h=a[6],i=a[8],j=a[9],k=a[10],l=k*f-h*j,o=-k*g+h*i,m=j*g-f*i,n=c*l+d*o+e*m;if(!n)return null;n=1/n;b||(b=mat3.create());b[0]=l*n;b[1]=(-k*d+e*j)*n;b[2]=(h*d-e*f)*n;b[3]=o*n;b[4]=(k*c-e*i)*n;b[5]=(-h*c+e*g)*n;b[6]=m*n;b[7]=(-j*c+d*i)*n;b[8]=(f*c-d*g)*n;return b}; +mat4.multiply=function(a,b,c){c||(c=a);var d=a[0],e=a[1],g=a[2],f=a[3],h=a[4],i=a[5],j=a[6],k=a[7],l=a[8],o=a[9],m=a[10],n=a[11],p=a[12],r=a[13],s=a[14];a=a[15];var A=b[0],B=b[1],t=b[2],u=b[3],v=b[4],w=b[5],x=b[6],y=b[7],z=b[8],C=b[9],D=b[10],E=b[11],q=b[12],F=b[13],G=b[14];b=b[15];c[0]=A*d+B*h+t*l+u*p;c[1]=A*e+B*i+t*o+u*r;c[2]=A*g+B*j+t*m+u*s;c[3]=A*f+B*k+t*n+u*a;c[4]=v*d+w*h+x*l+y*p;c[5]=v*e+w*i+x*o+y*r;c[6]=v*g+w*j+x*m+y*s;c[7]=v*f+w*k+x*n+y*a;c[8]=z*d+C*h+D*l+E*p;c[9]=z*e+C*i+D*o+E*r;c[10]=z* +g+C*j+D*m+E*s;c[11]=z*f+C*k+D*n+E*a;c[12]=q*d+F*h+G*l+b*p;c[13]=q*e+F*i+G*o+b*r;c[14]=q*g+F*j+G*m+b*s;c[15]=q*f+F*k+G*n+b*a;return c};mat4.multiplyVec3=function(a,b,c){c||(c=b);var d=b[0],e=b[1];b=b[2];c[0]=a[0]*d+a[4]*e+a[8]*b+a[12];c[1]=a[1]*d+a[5]*e+a[9]*b+a[13];c[2]=a[2]*d+a[6]*e+a[10]*b+a[14];return c}; +mat4.multiplyVec4=function(a,b,c){c||(c=b);var d=b[0],e=b[1],g=b[2];b=b[3];c[0]=a[0]*d+a[4]*e+a[8]*g+a[12]*b;c[1]=a[1]*d+a[5]*e+a[9]*g+a[13]*b;c[2]=a[2]*d+a[6]*e+a[10]*g+a[14]*b;c[3]=a[3]*d+a[7]*e+a[11]*g+a[15]*b;return c}; +mat4.translate=function(a,b,c){var d=b[0],e=b[1];b=b[2];if(!c||a==c){a[12]=a[0]*d+a[4]*e+a[8]*b+a[12];a[13]=a[1]*d+a[5]*e+a[9]*b+a[13];a[14]=a[2]*d+a[6]*e+a[10]*b+a[14];a[15]=a[3]*d+a[7]*e+a[11]*b+a[15];return a}var g=a[0],f=a[1],h=a[2],i=a[3],j=a[4],k=a[5],l=a[6],o=a[7],m=a[8],n=a[9],p=a[10],r=a[11];c[0]=g;c[1]=f;c[2]=h;c[3]=i;c[4]=j;c[5]=k;c[6]=l;c[7]=o;c[8]=m;c[9]=n;c[10]=p;c[11]=r;c[12]=g*d+j*e+m*b+a[12];c[13]=f*d+k*e+n*b+a[13];c[14]=h*d+l*e+p*b+a[14];c[15]=i*d+o*e+r*b+a[15];return c}; +mat4.scale=function(a,b,c){var d=b[0],e=b[1];b=b[2];if(!c||a==c){a[0]*=d;a[1]*=d;a[2]*=d;a[3]*=d;a[4]*=e;a[5]*=e;a[6]*=e;a[7]*=e;a[8]*=b;a[9]*=b;a[10]*=b;a[11]*=b;return a}c[0]=a[0]*d;c[1]=a[1]*d;c[2]=a[2]*d;c[3]=a[3]*d;c[4]=a[4]*e;c[5]=a[5]*e;c[6]=a[6]*e;c[7]=a[7]*e;c[8]=a[8]*b;c[9]=a[9]*b;c[10]=a[10]*b;c[11]=a[11]*b;c[12]=a[12];c[13]=a[13];c[14]=a[14];c[15]=a[15];return c}; +mat4.rotate=function(a,b,c,d){var e=c[0],g=c[1];c=c[2];var f=Math.sqrt(e*e+g*g+c*c);if(!f)return null;if(f!=1){f=1/f;e*=f;g*=f;c*=f}var h=Math.sin(b),i=Math.cos(b),j=1-i;b=a[0];f=a[1];var k=a[2],l=a[3],o=a[4],m=a[5],n=a[6],p=a[7],r=a[8],s=a[9],A=a[10],B=a[11],t=e*e*j+i,u=g*e*j+c*h,v=c*e*j-g*h,w=e*g*j-c*h,x=g*g*j+i,y=c*g*j+e*h,z=e*c*j+g*h;e=g*c*j-e*h;g=c*c*j+i;if(d){if(a!=d){d[12]=a[12];d[13]=a[13];d[14]=a[14];d[15]=a[15]}}else d=a;d[0]=b*t+o*u+r*v;d[1]=f*t+m*u+s*v;d[2]=k*t+n*u+A*v;d[3]=l*t+p*u+B* +v;d[4]=b*w+o*x+r*y;d[5]=f*w+m*x+s*y;d[6]=k*w+n*x+A*y;d[7]=l*w+p*x+B*y;d[8]=b*z+o*e+r*g;d[9]=f*z+m*e+s*g;d[10]=k*z+n*e+A*g;d[11]=l*z+p*e+B*g;return d};mat4.rotateX=function(a,b,c){var d=Math.sin(b);b=Math.cos(b);var e=a[4],g=a[5],f=a[6],h=a[7],i=a[8],j=a[9],k=a[10],l=a[11];if(c){if(a!=c){c[0]=a[0];c[1]=a[1];c[2]=a[2];c[3]=a[3];c[12]=a[12];c[13]=a[13];c[14]=a[14];c[15]=a[15]}}else c=a;c[4]=e*b+i*d;c[5]=g*b+j*d;c[6]=f*b+k*d;c[7]=h*b+l*d;c[8]=e*-d+i*b;c[9]=g*-d+j*b;c[10]=f*-d+k*b;c[11]=h*-d+l*b;return c}; +mat4.rotateY=function(a,b,c){var d=Math.sin(b);b=Math.cos(b);var e=a[0],g=a[1],f=a[2],h=a[3],i=a[8],j=a[9],k=a[10],l=a[11];if(c){if(a!=c){c[4]=a[4];c[5]=a[5];c[6]=a[6];c[7]=a[7];c[12]=a[12];c[13]=a[13];c[14]=a[14];c[15]=a[15]}}else c=a;c[0]=e*b+i*-d;c[1]=g*b+j*-d;c[2]=f*b+k*-d;c[3]=h*b+l*-d;c[8]=e*d+i*b;c[9]=g*d+j*b;c[10]=f*d+k*b;c[11]=h*d+l*b;return c}; +mat4.rotateZ=function(a,b,c){var d=Math.sin(b);b=Math.cos(b);var e=a[0],g=a[1],f=a[2],h=a[3],i=a[4],j=a[5],k=a[6],l=a[7];if(c){if(a!=c){c[8]=a[8];c[9]=a[9];c[10]=a[10];c[11]=a[11];c[12]=a[12];c[13]=a[13];c[14]=a[14];c[15]=a[15]}}else c=a;c[0]=e*b+i*d;c[1]=g*b+j*d;c[2]=f*b+k*d;c[3]=h*b+l*d;c[4]=e*-d+i*b;c[5]=g*-d+j*b;c[6]=f*-d+k*b;c[7]=h*-d+l*b;return c}; +mat4.frustum=function(a,b,c,d,e,g,f){f||(f=mat4.create());var h=b-a,i=d-c,j=g-e;f[0]=e*2/h;f[1]=0;f[2]=0;f[3]=0;f[4]=0;f[5]=e*2/i;f[6]=0;f[7]=0;f[8]=(b+a)/h;f[9]=(d+c)/i;f[10]=-(g+e)/j;f[11]=-1;f[12]=0;f[13]=0;f[14]=-(g*e*2)/j;f[15]=0;return f};mat4.perspective=function(a,b,c,d,e){a=c*Math.tan(a*Math.PI/360);b=a*b;return mat4.frustum(-b,b,-a,a,c,d,e)}; +mat4.ortho=function(a,b,c,d,e,g,f){f||(f=mat4.create());var h=b-a,i=d-c,j=g-e;f[0]=2/h;f[1]=0;f[2]=0;f[3]=0;f[4]=0;f[5]=2/i;f[6]=0;f[7]=0;f[8]=0;f[9]=0;f[10]=-2/j;f[11]=0;f[12]=-(a+b)/h;f[13]=-(d+c)/i;f[14]=-(g+e)/j;f[15]=1;return f}; +mat4.lookAt=function(a,b,c,d){d||(d=mat4.create());var e=a[0],g=a[1];a=a[2];var f=c[0],h=c[1],i=c[2];c=b[1];var j=b[2];if(e==b[0]&&g==c&&a==j)return mat4.identity(d);var k,l,o,m;c=e-b[0];j=g-b[1];b=a-b[2];m=1/Math.sqrt(c*c+j*j+b*b);c*=m;j*=m;b*=m;k=h*b-i*j;i=i*c-f*b;f=f*j-h*c;if(m=Math.sqrt(k*k+i*i+f*f)){m=1/m;k*=m;i*=m;f*=m}else f=i=k=0;h=j*f-b*i;l=b*k-c*f;o=c*i-j*k;if(m=Math.sqrt(h*h+l*l+o*o)){m=1/m;h*=m;l*=m;o*=m}else o=l=h=0;d[0]=k;d[1]=h;d[2]=c;d[3]=0;d[4]=i;d[5]=l;d[6]=j;d[7]=0;d[8]=f;d[9]= +o;d[10]=b;d[11]=0;d[12]=-(k*e+i*g+f*a);d[13]=-(h*e+l*g+o*a);d[14]=-(c*e+j*g+b*a);d[15]=1;return d};mat4.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+", "+a[9]+", "+a[10]+", "+a[11]+", "+a[12]+", "+a[13]+", "+a[14]+", "+a[15]+"]"};quat4={};quat4.create=function(a){var b=new glMatrixArrayType(4);if(a){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3]}return b};quat4.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];return b}; +quat4.calculateW=function(a,b){var c=a[0],d=a[1],e=a[2];if(!b||a==b){a[3]=-Math.sqrt(Math.abs(1-c*c-d*d-e*e));return a}b[0]=c;b[1]=d;b[2]=e;b[3]=-Math.sqrt(Math.abs(1-c*c-d*d-e*e));return b};quat4.inverse=function(a,b){if(!b||a==b){a[0]*=1;a[1]*=1;a[2]*=1;return a}b[0]=-a[0];b[1]=-a[1];b[2]=-a[2];b[3]=a[3];return b};quat4.length=function(a){var b=a[0],c=a[1],d=a[2];a=a[3];return Math.sqrt(b*b+c*c+d*d+a*a)}; +quat4.normalize=function(a,b){b||(b=a);var c=a[0],d=a[1],e=a[2],g=a[3],f=Math.sqrt(c*c+d*d+e*e+g*g);if(f==0){b[0]=0;b[1]=0;b[2]=0;b[3]=0;return b}f=1/f;b[0]=c*f;b[1]=d*f;b[2]=e*f;b[3]=g*f;return b};quat4.multiply=function(a,b,c){c||(c=a);var d=a[0],e=a[1],g=a[2];a=a[3];var f=b[0],h=b[1],i=b[2];b=b[3];c[0]=d*b+a*f+e*i-g*h;c[1]=e*b+a*h+g*f-d*i;c[2]=g*b+a*i+d*h-e*f;c[3]=a*b-d*f-e*h-g*i;return c}; +quat4.multiplyVec3=function(a,b,c){c||(c=b);var d=b[0],e=b[1],g=b[2];b=a[0];var f=a[1],h=a[2];a=a[3];var i=a*d+f*g-h*e,j=a*e+h*d-b*g,k=a*g+b*e-f*d;d=-b*d-f*e-h*g;c[0]=i*a+d*-b+j*-h-k*-f;c[1]=j*a+d*-f+k*-b-i*-h;c[2]=k*a+d*-h+i*-f-j*-b;return c};quat4.toMat3=function(a,b){b||(b=mat3.create());var c=a[0],d=a[1],e=a[2],g=a[3],f=c+c,h=d+d,i=e+e,j=c*f,k=c*h;c=c*i;var l=d*h;d=d*i;e=e*i;f=g*f;h=g*h;g=g*i;b[0]=1-(l+e);b[1]=k-g;b[2]=c+h;b[3]=k+g;b[4]=1-(j+e);b[5]=d-f;b[6]=c-h;b[7]=d+f;b[8]=1-(j+l);return b}; +quat4.toMat4=function(a,b){b||(b=mat4.create());var c=a[0],d=a[1],e=a[2],g=a[3],f=c+c,h=d+d,i=e+e,j=c*f,k=c*h;c=c*i;var l=d*h;d=d*i;e=e*i;f=g*f;h=g*h;g=g*i;b[0]=1-(l+e);b[1]=k-g;b[2]=c+h;b[3]=0;b[4]=k+g;b[5]=1-(j+e);b[6]=d-f;b[7]=0;b[8]=c-h;b[9]=d+f;b[10]=1-(j+l);b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return b};quat4.slerp=function(a,b,c,d){d||(d=a);var e=c;if(a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3]<0)e=-1*c;d[0]=1-c*a[0]+e*b[0];d[1]=1-c*a[1]+e*b[1];d[2]=1-c*a[2]+e*b[2];d[3]=1-c*a[3]+e*b[3];return d}; +quat4.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+"]"}; diff --git a/Other versions/webgl test2/index.html b/Other versions/webgl test2/index.html new file mode 100644 index 0000000..3a24714 --- /dev/null +++ b/Other versions/webgl test2/index.html @@ -0,0 +1,37 @@ + + + +Learning WebGL — lesson 1 + + + + + + + + + + + + + + + + + + diff --git a/Other versions/webgl test2/main.js b/Other versions/webgl test2/main.js new file mode 100644 index 0000000..aad1495 --- /dev/null +++ b/Other versions/webgl test2/main.js @@ -0,0 +1,149 @@ + var gl; + function initGL(canvas) { + try { + gl = canvas.getContext("experimental-webgl"); + gl.viewportWidth = canvas.width; + gl.viewportHeight = canvas.height; + } catch (e) { + } + if (!gl) { + alert("Could not initialise WebGL, sorry :-("); + } + } + + + function getShader(gl, id) { + var shaderScript = document.getElementById(id); + if (!shaderScript) { + return null; + } + + var str = ""; + var k = shaderScript.firstChild; + while (k) { + if (k.nodeType == 3) { + str += k.textContent; + } + k = k.nextSibling; + } + + var shader; + if (shaderScript.type == "x-shader/x-fragment") { + shader = gl.createShader(gl.FRAGMENT_SHADER); + } else if (shaderScript.type == "x-shader/x-vertex") { + shader = gl.createShader(gl.VERTEX_SHADER); + } else { + return null; + } + + gl.shaderSource(shader, str); + gl.compileShader(shader); + + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + alert(gl.getShaderInfoLog(shader)); + return null; + } + + return shader; + } + + + var shaderProgram; + + function initShaders() { + var fragmentShader = getShader(gl, "shader-fs"); + var vertexShader = getShader(gl, "shader-vs"); + + shaderProgram = gl.createProgram(); + gl.attachShader(shaderProgram, vertexShader); + gl.attachShader(shaderProgram, fragmentShader); + gl.linkProgram(shaderProgram); + + if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { + alert("Could not initialise shaders"); + } + + gl.useProgram(shaderProgram); + + shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); + gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); + + shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); + shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); + } + + + var mvMatrix = mat4.create(); + var pMatrix = mat4.create(); + + function setMatrixUniforms() { + gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix); + gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix); + } + + + + var triangleVertexPositionBuffer; + var squareVertexPositionBuffer; + + function initBuffers() { + triangleVertexPositionBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer); + var vertices = [ + 0.0, 1.0, 0.0, + -1.0, -1.0, 0.0, + 1.0, -1.0, 0.0 + ]; + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); + triangleVertexPositionBuffer.itemSize = 3; + triangleVertexPositionBuffer.numItems = 3; + + squareVertexPositionBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer); + vertices = [ + 1.0, 1.0, 0.0, + -1.0, 1.0, 0.0, + 1.0, -1.0, 0.0, + -1.0, -1.0, 0.0 + ]; + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); + squareVertexPositionBuffer.itemSize = 3; + squareVertexPositionBuffer.numItems = 4; + } + + + function drawScene() { + gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + + mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix); + + mat4.identity(mvMatrix); + + mat4.translate(mvMatrix, [-1.5, 0.0, -7.0]); + gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer); + gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, triangleVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0); + setMatrixUniforms(); + gl.drawArrays(gl.TRIANGLES, 0, triangleVertexPositionBuffer.numItems); + + + mat4.translate(mvMatrix, [3.0, 1.0, 0.0]); + gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer); + gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0); + setMatrixUniforms(); + gl.drawArrays(gl.TRIANGLE_STRIP, 0, squareVertexPositionBuffer.numItems); + } + + + + function webGLStart() { + var canvas = document.getElementById("canvas"); + initGL(canvas); + initShaders(); + initBuffers(); + + gl.clearColor(0.0, 0.0, 0.0, 1.0); + gl.enable(gl.DEPTH_TEST); + + drawScene(); + } diff --git a/Other versions/webgl tests/index.html b/Other versions/webgl tests/index.html new file mode 100644 index 0000000..3ee7417 --- /dev/null +++ b/Other versions/webgl tests/index.html @@ -0,0 +1,36 @@ + + + + WebGL Demo + + + + + + + + + + + + + + + + + + Your browser doesn't appear to support the HTML5 <canvas> element. + + + \ No newline at end of file diff --git a/Other versions/webgl tests/webgl-demo.js b/Other versions/webgl tests/webgl-demo.js new file mode 100644 index 0000000..7aafd05 --- /dev/null +++ b/Other versions/webgl tests/webgl-demo.js @@ -0,0 +1,246 @@ +var canvas; +var gl; +var squareVerticesBuffer; +var mvMatrix; +var shaderProgram; +var vertexPositionAttribute; +var perspectiveMatrix; + +// +// start +// +// Called when the canvas is created to get the ball rolling. +// Figuratively, that is. There's nothing moving in this demo. +// +function start() { + canvas = document.getElementById("glcanvas"); + + initWebGL(canvas); // Initialize the GL context + + // Only continue if WebGL is available and working + + if (gl) { + gl.clearColor(0.0, 0.0, 0.0, 1.0); // Clear to black, fully opaque + gl.clearDepth(1.0); // Clear everything + gl.enable(gl.DEPTH_TEST); // Enable depth testing + gl.depthFunc(gl.LEQUAL); // Near things obscure far things + + // Initialize the shaders; this is where all the lighting for the + // vertices and so forth is established. + + initShaders(); + + // Here's where we call the routine that builds all the objects + // we'll be drawing. + + initBuffers(); + + // Set up to draw the scene periodically. + + setInterval(drawScene, 15); + } +} + +// +// initWebGL +// +// Initialize WebGL, returning the GL context or null if +// WebGL isn't available or could not be initialized. +// +function initWebGL() { + gl = null; + + try { + gl = canvas.getContext("experimental-webgl"); + } + catch(e) { + } + + // If we don't have a GL context, give up now + + if (!gl) { + alert("Unable to initialize WebGL. Your browser may not support it."); + } +} + +// +// initBuffers +// +// Initialize the buffers we'll need. For this demo, we just have +// one object -- a simple two-dimensional square. +// +function initBuffers() { + + // Create a buffer for the square's vertices. + + squareVerticesBuffer = gl.createBuffer(); + + // Select the squareVerticesBuffer as the one to apply vertex + // operations to from here out. + + gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBuffer); + + // Now create an array of vertices for the square. Note that the Z + // coordinate is always 0 here. + + var vertices = [ + 1.0, 1.0, 0.0, + -1.0, 1.0, 0.0, + 1.0, -1.0, 0.0, + -1.0, -1.0, 0.0 + ]; + + // Now pass the list of vertices into WebGL to build the shape. We + // do this by creating a Float32Array from the JavaScript array, + // then use it to fill the current vertex buffer. + + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); +} + +// +// drawScene +// +// Draw the scene. +// +function drawScene() { + // Clear the canvas before we start drawing on it. + + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + + // Establish the perspective with which we want to view the + // scene. Our field of view is 45 degrees, with a width/height + // ratio of 640:480, and we only want to see objects between 0.1 units + // and 100 units away from the camera. + + perspectiveMatrix = makePerspective(45, 640.0/480.0, 0.1, 100.0); + + // Set the drawing position to the "identity" point, which is + // the center of the scene. + + loadIdentity(); + + // Now move the drawing position a bit to where we want to start + // drawing the square. + + mvTranslate([-0.0, 0.0, -6.0]); + + // Draw the square by binding the array buffer to the square's vertices + // array, setting attributes, and pushing it to GL. + + gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBuffer); + gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0); + setMatrixUniforms(); + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); +} + +// +// initShaders +// +// Initialize the shaders, so WebGL knows how to light our scene. +// +function initShaders() { + var fragmentShader = getShader(gl, "shader-fs"); + var vertexShader = getShader(gl, "shader-vs"); + + // Create the shader program + + shaderProgram = gl.createProgram(); + gl.attachShader(shaderProgram, vertexShader); + gl.attachShader(shaderProgram, fragmentShader); + gl.linkProgram(shaderProgram); + + // If creating the shader program failed, alert + + if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { + alert("Unable to initialize the shader program: " + gl.getProgramInfoLog(shader)); + } + + gl.useProgram(shaderProgram); + + vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); + gl.enableVertexAttribArray(vertexPositionAttribute); +} + +// +// getShader +// +// Loads a shader program by scouring the current document, +// looking for a script with the specified ID. +// +function getShader(gl, id) { + var shaderScript = document.getElementById(id); + + // Didn't find an element with the specified ID; abort. + + if (!shaderScript) { + return null; + } + + // Walk through the source element's children, building the + // shader source string. + + var theSource = ""; + var currentChild = shaderScript.firstChild; + + while(currentChild) { + if (currentChild.nodeType == 3) { + theSource += currentChild.textContent; + } + + currentChild = currentChild.nextSibling; + } + + // Now figure out what type of shader script we have, + // based on its MIME type. + + var shader; + + if (shaderScript.type == "x-shader/x-fragment") { + shader = gl.createShader(gl.FRAGMENT_SHADER); + } else if (shaderScript.type == "x-shader/x-vertex") { + shader = gl.createShader(gl.VERTEX_SHADER); + } else { + return null; // Unknown shader type + } + + // Send the source to the shader object + + gl.shaderSource(shader, theSource); + + // Compile the shader program + + gl.compileShader(shader); + + // See if it compiled successfully + + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + alert("An error occurred compiling the shaders: " + gl.getShaderInfoLog(shader)); + return null; + } + + return shader; +} + +// +// Matrix utility functions +// + +function loadIdentity() { + mvMatrix = Matrix.I(4); +} + +function multMatrix(m) { + mvMatrix = mvMatrix.x(m); +} + +function mvTranslate(v) { + multMatrix(Matrix.Translation($V([v[0], v[1], v[2]])).ensure4x4()); +} + +function setMatrixUniforms() { + var pUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); + gl.uniformMatrix4fv(pUniform, false, new Float32Array(perspectiveMatrix.flatten())); + + var mvUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); + gl.uniformMatrix4fv(mvUniform, false, new Float32Array(mvMatrix.flatten())); +} \ No newline at end of file diff --git a/database.rules.json b/database.rules.json new file mode 100644 index 0000000..1f9c283 --- /dev/null +++ b/database.rules.json @@ -0,0 +1,11 @@ +{ + "rules": { + "scores": { + ".read": true, + "$scores": { + ".write": true, + ".validate": "newData.hasChildren(['level', 'method', 'name', 'score']) && newData.child('name').val().length < 11 && newData.child('level').isNumber() && newData.child('score').isNumber()" + } + } + } +} diff --git a/firebase.json b/firebase.json new file mode 100644 index 0000000..20050ae --- /dev/null +++ b/firebase.json @@ -0,0 +1,23 @@ +{ + "database": { + "rules": "database.rules.json" + }, + "hosting": { + "public": "public", + "rewrites": [ +{ + "source": "/settings", + "destination": "/settings.html" +} , +{ + "source": "/highscore", + "destination": "/highscore.html" +}, +{ + "source": "*", + "destination": "/index.html" +} +] + + } +} diff --git a/public - Copy/Ball.js b/public - Copy/Ball.js new file mode 100644 index 0000000..f19d8bf --- /dev/null +++ b/public - Copy/Ball.js @@ -0,0 +1,28 @@ +function Ball(startx,starty, vx, vy, radius) { + this.x = startx; + this.y = starty; + this.radius = radius; + this.xd = randomsign(); + this.yd = randomsign(); + this.dx = vx; + this.dy = vy; + this.move = function() { + if ((this.x > height-this.radius && this.xd > 0)|| (this.x < this.radius && this.xd < 0)) { + this.xd = -this.xd; + } + if ((this.y > width-this.radius && this.yd > 0) || (this.y < this.radius && this.yd < 0)) { + this.yd = -this.yd; + } + + this.x = this.x + this.dx * this.xd; + this.y = this.y + this.dy * this.yd; + } + + this.shape = function() { + return new circle(this.x,this.y,this.radius); + } + + this.draw = function(ctx) { + drawBall(this.x, this.y, this.radius,ctx,"green"); + } +} \ No newline at end of file diff --git a/public - Copy/Calculations.js b/public - Copy/Calculations.js new file mode 100644 index 0000000..89537bb --- /dev/null +++ b/public - Copy/Calculations.js @@ -0,0 +1,77 @@ + // Shape objects: + function circle(x,y,radius) { + this.x = x; + this.y = y; + this.r = radius; + } + + function rectangle(x,y,width,height) { + this.x = x; + this.y = y; + this.w = width; + this.h = height; + } + + //distance calculator (between two points) + function dist(x1,y1,x2,y2) { + return Math.sqrt(Math.pow(Math.abs(x1 - x2),2) + Math.pow(Math.abs(y1 - y2),2)); + } + + function randomsign() { + var i = random(0, 1); + if (i == 0) { + return -1; + } else { + return 1; + } + } + function sign(i) { + if (i > 0) { + return 1; + } else if (i < 0) { + return -1; + } else { + return 0; + } + } + + function random(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + } + + function CircleCircleColliding(c1,c2) { + var dist = dist(c1.x , c1.y , c2.x , c2.y); + if (dist < Math.max(c1.r,c2.r)) { + return true; + } + return false; + } + + function RectRectColliding(r1,r2) { + var distX = Math.abs(r1.x + r1.w/2 - r2.x - r2.w/2); + var distY = Math.abs(r1.y + r1.h/2 - r2.y - r2.h/2); + + if (distX > (r1.w + r2.w)/2) { + return false; + } else if (distY > (r1.h + r2.h)/2) { + return false; + } else { + return true; + } + + } + + function RectCircleColliding(circle,rect){ + var distX = Math.abs(circle.x - rect.x-rect.w/2); + var distY = Math.abs(circle.y - rect.y-rect.h/2); + + if (distX > (rect.w/2 + circle.r)) { return false; } + if (distY > (rect.h/2 + circle.r)) { return false; } + + if (distX <= (rect.w/2)) { return true; } + if (distY <= (rect.h/2)) { return true; } + + var dx=distX-rect.w/2; + var dy=distY-rect.h/2; + return (dx*dx+dy*dy<=(circle.r*circle.r)); + } \ No newline at end of file diff --git a/public - Copy/Controls.js b/public - Copy/Controls.js new file mode 100644 index 0000000..c3b10f1 --- /dev/null +++ b/public - Copy/Controls.js @@ -0,0 +1,188 @@ +var highscorePage = "highscore"; +var settingsPage = "settings"; + +var playercontrol; +var controlMethod; + +var mouseX; +var mouseY; +var moving = false; + +var upPressed = false; +var downPressed = false; +var rightPressed = false; +var leftPressed = false; + +var upKey = 38; +var rightKey = 39; +var leftKey = 37; +var downKey = 40; + +var restartKey = 32; //spacebar +var settingsKey = 73; // i +var HighscoreKey = 72; // h +var SubmitKey = 13; //enter +var muteKey = 77; // m + +//sets the control mode +function setControl(mode) { + document.addEventListener("keydown", keyDownHandler, false); + document.addEventListener("keyup", keyUpHandler, false); + if (mode=="wasd") { + controlMethod = "WASD"; + playercontrol = keyboardControl; + upKey = 87; + leftKey = 65; + downKey = 83; + rightKey = 68; + } else if (mode=="mouse") { + controlMethod = "Mouse"; + document.addEventListener("mousemove", mouseMoveHandler, false); + playercontrol = mouseControl; + } else if (mode=="mobile") + { + controlMethod = "Mobile"; + playercontrol = mobileControl; + canvas.addEventListener("touchstart", handleStart, false); + canvas.addEventListener("touchend", handleEnd, false); + canvas.addEventListener("touchcancel", handleCancel, false); + canvas.addEventListener("touchmove", handleMove, false); + } + else { + controlMethod = "Arrow Keys"; + playercontrol = keyboardControl; + } +} + +function handleStart(e) { + moving = true; + mouseX = e.changedTouches[0].clientX - canvas.offsetLeft; + mouseY = e.changedTouches[0].clientY - canvas.offsetTop; +} +function handleEnd(e) { + moving = false; +} +function handleCancel(e) { + moving = false; +} +function handleMove(e) { + mouseX = e.changedTouches[0].clientX - canvas.offsetLeft; + mouseY = e.changedTouches[0].clientY - canvas.offsetTop; +} + +function mobileControl(object, speed) { + if (moving) { + object.x = object.x + sign(mouseX-object.x)*speed; + object.y = object.y + sign(mouseY-object.y)*speed; + } +} + +function keyboardControl(object, speed) { + if(rightPressed) { + object.x += speed; + } + if(leftPressed) { + object.x -= speed; + } + + if(downPressed) { + object.y += speed; + } + + if(upPressed) { + object.y -= speed; + } + + if (object.x < 0) { + object.x = 0; + } else if (object.x + object.height > height) { + object.x = height-object.height; + } + + if (object.y < 0) { + object.y = 0; + } else if (object.y + object.width > width) { + object.y = width-object.width; + } +} + +function mouseControl(object,speed) { + if (mouseX != null) { + object.x = mouseX - object.width/2; + object.y = mouseY - object.height/2; + } +} + +function mouseMoveHandler(e) { + mouseX = e.clientX - canvas.offsetLeft; + mouseY = e.clientY - canvas.offsetTop; +} + +var currentKeyDownHandler; + +function setControlMode(type) { + if (type=="menu") { + currentKeyDownHandler = menuKeyDownHandler; + } else if (type=="game") { + currentKeyDownHandler = gameKeyDownHandler; + } +} + +var gameKeyDownHandler = function(e) { + if(e.keyCode == downKey) { + downPressed = true; + } else if(e.keyCode == rightKey) { + rightPressed = true; + } else if(e.keyCode == upKey) { + upPressed = true; + } else if(e.keyCode == leftKey) { + leftPressed = true; + } else if(e.keyCode == muteKey) { + music.toggleMute(); + } +} + +var menuKeyDownHandler = function(e) { + if (e.keyCode == restartKey) { + restartgame(); + } else if (e.keyCode == settingsKey) { + document.location.href = settingsPage; + } else if (e.keyCode == HighscoreKey) { + document.location.href = highscorePage; + } else if (e.keyCode == SubmitKey) { + submitscore(); + } +} + +function keyDownHandler(e) { + currentKeyDownHandler(e); +} + +function keyUpHandler(e) { + if(e.keyCode == downKey) { + downPressed = false; + } + else if(e.keyCode == rightKey) { + rightPressed = false; + } + else if(e.keyCode == upKey) { + upPressed = false; + } + else if(e.keyCode == leftKey) { + leftPressed = false; + } +} + +function resetmovement() { + moving = false; + upPressed = false; + downPressed = false; + rightPressed = false; + leftPressed = false; +} + +function setWriteMode(callback) { +} + + + diff --git a/public - Copy/Cookies.js b/public - Copy/Cookies.js new file mode 100644 index 0000000..5027c67 --- /dev/null +++ b/public - Copy/Cookies.js @@ -0,0 +1,20 @@ +//Thanks http://www.w3schools.com/js/js_cookies.asp +function setCookie(c_name,c_value,exdays) { + var exdate=new Date(); + exdate.setDate(exdate.getDate() + exdays); + document.cookie=encodeURIComponent(c_name) + + "=" + encodeURIComponent(c_value) + + (!exdays ? "" : "; expires="+exdate.toUTCString()); + ; + } + +function getCookie(cname) { + var name = cname + "="; + var ca = document.cookie.split(';'); + for(var i=0; i gameState.tickperball) { + countervalue = 0; + return true; + } + return false; +} + +function addObject(object) { + //set starting position + var currentdist = 0; + while (currentdist < mindist) { + startx = random(0, height); + starty = random(0, width); + currentdist = dist(startx, starty, p.x, p.y); + } + + //set speed + vx = random(gameState.minBallspeed, gameState.maxBallspeed); + vy = random(gameState.minBallspeed, gameState.maxBallspeed); + + //set size + radius = random(gameState.minballRadius,gameState.maxballRadius); + + //add to ball list + let newObject = new object(startx, starty, vx, vy, radius); + objects.push(newObject); + return newObject; +} + +function addBall() { + addObject(Ball); +} + +function addStealthBall() { + addObject(StealthBall); +} + +function addSeekerBall() { + let ball = addObject(SeekerBall); + ball.target = p; +} + +function addPickUp() { + //set position + var currentdist = 0; + while (currentdist < mindist) { + x = random(pickuplength, height-pickuplength); + y = random(pickuplength, width-pickuplength); + currentdist = dist(x, y, p.x, p.y); + } + //add Pickup + pickup = new Pickup(x,y,pickuplength); +} + +//ending the game, when player dies +function endgame() { + music.playGameOver(); + setControlMode("menu"); + submitscore(); +} + +function submitscore() { + let playername = null; + if (autoSubmit) { + playername = playerAutoName; + } else { + playername = getPlayerName(); + if (playername == null) { + DisplayAfterGameMessages("Game Over"); + return; + } + } + if (leaderboard == null) { + initializeFirebase(); + leaderboard = new Leaderboard("https://leaderboard-bf98b.firebaseio.com"); + } + ctx.clearRect(0, 0, canvas.width, canvas.height); + setFont(20); + ctx.fillText("Submitting score", width/2, height/4); + addandgo({"name": playername, "score": score, "level": gameState.level, "method": controlMethod}, function(){ + scorenotsubmitted = false; + DisplayAfterGameMessages("Score Submitted"); + }); +} + +function validateName(name) { + + if(!name || name.length > maxplayernamelength) { + return "Requires a valid name."; + } else if(!data.score || isNaN(data.score)) { + return "Requires a valid score. score: " + data.score; + } + return true; +} + +function getPlayerName() { +// setWriteMode(); alternative method, not yet implemented + let playername; + do { + playername = prompt("Player name (max " + maxplayernamelength +" characters)"); + if (playername == null) { + return null; + } + } while ((playername.length <= 0) || (playername.length > maxplayernamelength)) + // Ask for playername until proper name is given, or cancel is chosen. + return playername; +} + +function DisplayAfterGameMessages(message) { + //reset canvas + ctx.clearRect(0, 0, canvas.width, canvas.height); + + setFont(20); + //text drawing + let displayWidth = width/5; + let displayHeight = height/5; + let heightOffset = width/20; + + ctx.fillText(message, displayWidth, displayHeight); + ctx.fillText("Press Space to play again", displayWidth, displayHeight+heightOffset); + ctx.fillText("Press i for settings", displayWidth, displayHeight+heightOffset*2); + ctx.fillText("Press h for Leaderboard", displayWidth, displayHeight+heightOffset*3); +} diff --git a/public - Copy/GameOVer.mp3 b/public - Copy/GameOVer.mp3 new file mode 100644 index 0000000..7561d40 Binary files /dev/null and b/public - Copy/GameOVer.mp3 differ diff --git a/public - Copy/GameState.js b/public - Copy/GameState.js new file mode 100644 index 0000000..78c463c --- /dev/null +++ b/public - Copy/GameState.js @@ -0,0 +1,59 @@ +function GameState() { + this.level = 1; + this.maxBallspeed; + this.minBallspeed; + this.maxballRadius; + this.minballRadius; + this.initialballs; //balls at the start of the level + this.levelduration; + this.tickperball; //how often new ball is created + this.ballspertick; //how many balls are created at once + this.basemaxBallspeed; + this.baseminBallspeed; + + this.durationTickUp = 5; + + this.baseForDurationIncrease = 0; + this.baseForSpeedIncrease = 2; + this.baseForBallsPerTickIncrease = 0; + this.baseForTicksPerBallDecrease = 3; + + this.ticksForDurationIncrease = 3; + this.ticksForSpeedIncrease = 4; + this.ticksForBallsPerTickIncrease = 5; + this.ticksForTicksPerBallDecrease = 5; + + this.levelup = function(){ + this.level++; + this.initialballs++; + if ((this.level % this.ticksForDurationIncrease) + this.baseForDurationIncrease == 0) { + this.levelduration += this.durationTickUp; + } + if ((this.level % this.ticksForSpeedIncrease) + this.baseForSpeedIncrease == 0) { + this.maxBallspeed += this.basemaxBallspeed; + this.minBallspeed += this.baseminBallspeed; + } + if ((this.level % this.baseForBallsPerTickIncrease) + this.baseForBallsPerTickIncrease == 0) { + this.ballspertick++; + } + if ((this.level % this.baseForTicksPerBallDecrease) + this.baseForTicksPerBallDecrease == 0) { + this.ticksperball--; + } + } + + + this.init = function() { + let averageSize = (Math.abs(width) + Math.abs(height)) / 2; + this.level = 1; + this.basemaxBallspeed = averageSize / 200; + this.baseminBallspeed = averageSize / 1000; + this.maxBallspeed = this.basemaxBallspeed; + this.minBallspeed = this.baseminBallspeed; + this.maxballRadius = averageSize / 70; + this.minballRadius = averageSize / 200; + this.initialballs = 1; + this.levelduration = 30; + this.tickperball = 20; + this.ballspertick = 1; + } +} \ No newline at end of file diff --git a/public - Copy/HighScoreScript.js b/public - Copy/HighScoreScript.js new file mode 100644 index 0000000..6f48fd7 --- /dev/null +++ b/public - Copy/HighScoreScript.js @@ -0,0 +1,31 @@ +window.onload = function() { + var table = document.getElementById("items"); + initializeFirebase(); + var leaderboard = new Leaderboard("https://leaderboard-bf98b.firebaseio.com"); + leaderboard.getandgo(function(list) { + var index, len; + for (index = Math.min(list.length-1,10), len = 0; index >= len; --index) { + addRow(table,list[index]); + } + }, 10 + ); + +} + +function addRow(table, data) { //adding a simple row + + var rownumber = table.rows.length; + var row = table.insertRow(rownumber); + + var cell1 = row.insertCell(0); + var cell2 = row.insertCell(1); + var cell3 = row.insertCell(2); + var cell4 = row.insertCell(3); + var cell5 = row.insertCell(4); + + cell1.innerHTML = rownumber; + cell2.innerHTML = data.name; + cell3.innerHTML = data.level; + cell4.innerHTML = data.score; + cell5.innerHTML = data.method; +} \ No newline at end of file diff --git a/public - Copy/Initialization.js b/public - Copy/Initialization.js new file mode 100644 index 0000000..373ce45 --- /dev/null +++ b/public - Copy/Initialization.js @@ -0,0 +1,67 @@ +var canvas; +var ctx; +var p; +var pickup; +var objects; +var height; +var width; +var mindist = 4; +var leaderboard; +var squared = true; +var autoSubmit = false; +var playerAutoName = null; +window.onload = function () { + +// Initialize canvas +canvas = document.getElementById("myCanvas"); +ctx = canvas.getContext("2d"); + + +if (squared) { + let size = Math.min(window.innerWidth,window.innerHeight); + + ctx.canvas.width = size; + ctx.canvas.height = size; + + height = size; + width = size; +} else { + ctx.canvas.width = window.innerWidth; + ctx.canvas.height = window.innerHeight; + + height = canvas.width; + width = canvas.height; +} + + +if (getCookie("settings")) { + setControl(getCookie("input")); + autoSubmit = getCookie("autoSubmit"); + if (autoSubmit) { + playerAutoName = getCookie("playerName"); + } +} else { + var setSettings = confirm("Settings not found, want to set them? /n \n (default control is arrow keys)"); + if (setSettings) { + window.location.href = "settings"; + } else { + setControl(""); + } +} + +mindist = dist(0,0,width,height) / mindist; + +restartgame(); + +} + +function restartgame() { + setControlMode("game"); + setVariables(); + gameState.init(); + p = new Paddle(height/2, width/2, playerlength); + objects = []; + addPickUp(); + music.playMain(); + doTurn(); +} diff --git a/public - Copy/Leaderboard.js b/public - Copy/Leaderboard.js new file mode 100644 index 0000000..1d11ba6 --- /dev/null +++ b/public - Copy/Leaderboard.js @@ -0,0 +1,87 @@ +function initializeFirebase(){ + var config = { + apiKey: "AIzaSyDnQy8gUVUldROZM3hxjg2_M3FE7Yg_cSc", + authDomain: "leaderboard-bf98b.firebaseapp.com", + databaseURL: "https://leaderboard-bf98b.firebaseio.com", + storageBucket: "leaderboard-bf98b.appspot.com", + }; + firebase.initializeApp(config); +} + +class Leaderboard { + constructor(firebaseURL) { + this.firebase = firebase.database(); + this.firebase.ref("scores").orderByChild("score").limitToLast(5).on("value", (value) => { + this.scores = value.val() + }) + } + + add(data) { + if(!data.name || data.name.length > maxplayernamelength) { + throw new Error("Requires a valid name.") + } else if(!data.score || isNaN(data.score)) { + throw new Error("Requires a valid score.") + } else { + this.firebase.ref("scores").push(data).setPriority(data.score) + } + } + + /* + * assumed that data is valid + */ + addandgo(data,go) { + firebase.database().ref("scores").push(data).setPriority(data.score).then(go); + } + + get() { + throw new Error("this shouldn't happen"); + var list = []; + var running = true; + this.firebase.ref("scores").orderByChild("score").once("value").then( + function(snapshot) { + snapshot.forEach(function(childSnapshot) { + list.push(childSnapshot.val()); + }) + running = false; + }); + } + + getandgo(go,limit) { + let query = this.firebase.ref("scores").orderByChild("score"); + if (limit!=null) { + query = query.limitToLast(limit); + } + query.once("value").then( + function(snapshot) { + let list = []; + snapshot.forEach(function(childSnapshot) { + list.push(childSnapshot.val()); + }); + go(list); + }); + } +} + +function add(data) { + addandgo(data,function(){}); +} +/* +* assumed that data is valid +*/ +function addandgo(data,go) { + firebase.database().ref("scores").push(data).setPriority(data.score).then(go); +} +function getandgo(go) { + let query = this.firebase.ref("scores").orderByChild("score"); + if (limit!=null) { + console.log("limted"); + query = query.limitToLast(limit); + } + query.once("value").then( + function(snapshot) { + snapshot.forEach(function(childSnapshot) { + list.push(childSnapshot.val()); + }); + go(list); + }); +} \ No newline at end of file diff --git a/public - Copy/Paddle.js b/public - Copy/Paddle.js new file mode 100644 index 0000000..3a7247c --- /dev/null +++ b/public - Copy/Paddle.js @@ -0,0 +1,17 @@ +function Paddle(ax,ay,length) { + this.x = ax; + this.y = ay; + this.width = length; + this.height = length; + this.move = function(nx,ny) { + playercontrol(this,playerSpeed); + } + + this.shape = function(){ + return new rectangle(this.x,this.y,this.width,this.height); + } + + this.draw = function(ctx) { + drawRect(this.x, this.y, this.width, this.height,ctx,"#0095DD"); + } +} \ No newline at end of file diff --git a/public - Copy/Pickup.js b/public - Copy/Pickup.js new file mode 100644 index 0000000..a9216b5 --- /dev/null +++ b/public - Copy/Pickup.js @@ -0,0 +1,14 @@ +function Pickup(x,y,length) { + this.x = x; + this.y = y; + this.width = length; + this.height = length; + + this.shape = function(){ + return new rectangle(this.x,this.y,this.width,this.height); + } + + this.draw = function(ctx) { + drawRect(this.x, this.y, this.width, this.height,ctx,"#FFA500"); + } +} \ No newline at end of file diff --git a/public - Copy/Retro.wav b/public - Copy/Retro.wav new file mode 100644 index 0000000..bbf5709 Binary files /dev/null and b/public - Copy/Retro.wav differ diff --git a/public - Copy/SeekerBall.js b/public - Copy/SeekerBall.js new file mode 100644 index 0000000..63950d6 --- /dev/null +++ b/public - Copy/SeekerBall.js @@ -0,0 +1,64 @@ +function SeekerBall(startx,starty, vx, vy, radius, target) { + this.target; + this.base = new Ball(startx,starty, vx, vy, radius); + this.speed = (Math.abs(this.base.dx) + Math.abs(this.base.dy)) / 2; + this.maxTurn = 0.1; + this.currentDirection = 0; + + this.move = function() { + this.determineDirection(); + this.base.x -= this.speed * Math.cos(this.currentDirection); + this.base.y -= this.speed * Math.sin(this.currentDirection); + }; + + this.determineDirection = function() { + DesiredDirection = Math.atan2((this.target.y - this.base.y) , (this.target.x - this.base.x)) + Math.PI; + /* if (this.currentDirection < 0) { + this.currentDirection = (2*Math.PI) - this.currentDirection; + } else if (this.currentDirection > (2*Math.PI)) { + this.currentDirection %= (2*Math.PI); + } + */ + let change = this.currentDirection-DesiredDirection; + if (Math.abs(change) max / 2) { + ans = b - a - max; + } else if (b - a > -max / 2) { + ans = b - a; + } else { + ans = b - a + max; + } + + if (ans > 0) { + return 1; + } else if (ans < 0) { + return -1; + } else { + return 0; + } + +} \ No newline at end of file diff --git a/public - Copy/SettingsScript.js b/public - Copy/SettingsScript.js new file mode 100644 index 0000000..92b05f4 --- /dev/null +++ b/public - Copy/SettingsScript.js @@ -0,0 +1,63 @@ + window.onload = function () { + //input method + var input = document.getElementById("input method"); + //listen to input method + addEventListener(input, "change", function () { + var inputmethod = input.options[input.selectedIndex].value; + setCookie("input",inputmethod,100); + }); + + //auto submit + var aSubmit = document.getElementById("autoSubmit"); + addEventListener(aSubmit, "change", function () { + setCookie("autoSubmit",aSubmit.checked,100); + }); + + //name for auto submit + var name = document.getElementById("playerName"); + addEventListener(name, "change", function () { + setCookie("playerName",name.value,100); + }); + + + //save button + var saveButton = document.getElementById("save"); + //listen to save button + addEventListener(saveButton, "click", function () { + setCookie("settings",true,100); + }); + + //Play again + var playAgain = document.getElementById("play"); + //listen to play again + addEventListener(playAgain, "click", function () { + setCookie("settings",true,100); + window.location.href = "index"; + }); + + //load cookies + if (getCookie("settings")) { + aSubmit.checked = getCookie("autoSubmit"); + name.value = getCookie("playerName"); + + var inputVal = getCookie("input"); + var options = input.options; + for(var i = 0; i < options.length; i++) { + var option = options[i]; + if (option.value == inputVal) { + input.selectedIndex = i; + } + } + + } + } + + function addEventListener(myNode, eventType, myHandlerFunc) { + if (myNode.addEventListener) + myNode.addEventListener(eventType, myHandlerFunc, false); + else + myNode.attachEvent("on" + eventType, + function (event) { + myHandlerFunc.call(myNode, event); + }); + } diff --git a/public - Copy/SinglePage/Initialization.js b/public - Copy/SinglePage/Initialization.js new file mode 100644 index 0000000..6857073 --- /dev/null +++ b/public - Copy/SinglePage/Initialization.js @@ -0,0 +1,35 @@ +var canvas; +var ctx; +var p; +var pickup; +var objects; +var height; +var width; +var mindist = 4; +var leaderboard; +var squared = true; +window.onload = function () { + +// Initialize canvas +canvas = document.getElementById("myCanvas"); +ctx = canvas.getContext("2d"); + + +if (squared) { + let size = Math.min(window.innerWidth,window.innerHeight); + + ctx.canvas.width = size; + ctx.canvas.height = size; + + height = size; + width = size; +} else { + ctx.canvas.width = window.innerWidth; + ctx.canvas.height = window.innerHeight; + + height = canvas.width; + width = canvas.height; +} + +startMainMenu(); +} \ No newline at end of file diff --git a/public - Copy/SinglePage/Menu.js b/public - Copy/SinglePage/Menu.js new file mode 100644 index 0000000..4ce7cb7 --- /dev/null +++ b/public - Copy/SinglePage/Menu.js @@ -0,0 +1,32 @@ +var myFont = "Arial" +var fillStyle = "#dd0095"; + +function startMainMenu() { + setMenuText(); + setControl("menu"); +} + +function setMenuText() { + //reset canvas + ctx.clearRect(0, 0, canvas.width, canvas.height); + setFont(5); + + ctx.fillText("BallsBalls", width/15, height/4); + + + setFont(15); + //text drawing + let displayWidth = width/10; + let displayHeight = height/2; + let heightOffset = width/12; + + ctx.fillText("Press Space to Play Game", displayWidth, displayHeight); + ctx.fillText("Press i for settings", displayWidth, displayHeight+heightOffset*1); + ctx.fillText("Press h for Leaderboard", displayWidth, displayHeight+heightOffset*2); +} + +function setFont(quotent) { + ctx.font = (width/quotent)+"px " + myFont; + ctx.fillStyle = "green"; +} + diff --git a/public - Copy/SinglePage/SettingsScript.js b/public - Copy/SinglePage/SettingsScript.js new file mode 100644 index 0000000..e69de29 diff --git a/public - Copy/SinglePage/State.js b/public - Copy/SinglePage/State.js new file mode 100644 index 0000000..c6d529a --- /dev/null +++ b/public - Copy/SinglePage/State.js @@ -0,0 +1,45 @@ +var currentState; + + +ChangeState(newState) { + currentState.end(); + newState.init(); + currentState = newState; +} + +function settingsState() { + this.init = function() { + + } + this.end = function() { + + } + this.keydownHandler = function(e) { + + } +} + +function gameState() { + this.init = function() { + + } + this.end = function() { + canvas.style.display="none"; + } + this.keydownHandler = function(e) { + + } +} + +function endgameState() { + this.init = function() { + + } + this.end = function() { + + } + this.keydownHandler = function(e) { + + } +} + diff --git a/public - Copy/SinglePage/index.html b/public - Copy/SinglePage/index.html new file mode 100644 index 0000000..ffef346 --- /dev/null +++ b/public - Copy/SinglePage/index.html @@ -0,0 +1,29 @@ + + + + + BallsBalls + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/public - Copy/Sound.js b/public - Copy/Sound.js new file mode 100644 index 0000000..54b8b56 --- /dev/null +++ b/public - Copy/Sound.js @@ -0,0 +1,51 @@ +var music = new Music(); + +function Music() { + this.audio = new Audio('Retro.wav'); + this.audio.loop = true; + this.sounds = new Audio(); + this.volume = 1; + this.muted = false; + + this.playMain = function() { + this.sounds.pause(); + this.audio.play(); + } + + this.playGameOver = function() { + this.audio.pause(); + this.sounds.src = 'gameOver2.wav'; + this.sounds.play(); + } + + this.playPause = function() { + this.audio.pause(); + } + + this.pause = function() { + this.audio.pause(); + } + + this.stop = function() { + this.audio.pause(); + } + + this.toggleMute = function() { + if (this.muted) { + this.audio.volume = this.volume; + } else { + this.audio.volume = 0; + } + this.muted = !this.muted; + } + + this.setVolume = function(value) { + this.audio.volume = value; + } + + this.changeVolume = function(change) { + this.audio.volume += value; + } + + +} diff --git a/public - Copy/StealthBall.js b/public - Copy/StealthBall.js new file mode 100644 index 0000000..6647f06 --- /dev/null +++ b/public - Copy/StealthBall.js @@ -0,0 +1,25 @@ +function StealthBall(startx,starty, vx, vy, radius) { + this.base = new Ball(startx,starty, vx, vy, radius); + this.speed = (Math.abs(this.base.dx) + Math.abs(this.base.dy)) / 2; + this.ticks = stealthBallticks/this.speed; + this.visible = true; + this.move = function() { + this.base.move(); + if (this.ticks <= 0) { + this.visible = !this.visible; + this.ticks = stealthBallticks/this.speed; + } else { + this.ticks = this.ticks - 1; + } + } + + this.shape = function() { + return this.base.shape(); + } + + this.draw = function(ctx) { + if (this.visible) { + drawBall(this.base.x, this.base.y, this.base.radius,ctx,"red"); + } + } +} \ No newline at end of file diff --git a/public - Copy/To do.txt b/public - Copy/To do.txt new file mode 100644 index 0000000..22416ee --- /dev/null +++ b/public - Copy/To do.txt @@ -0,0 +1,11 @@ +State concept +(gameState, + MenuState, + HighScoreState, + SettingsState +) + +Implement Menu properly +Settings in one page +Sound Settings +users \ No newline at end of file diff --git a/public - Copy/Values.js b/public - Copy/Values.js new file mode 100644 index 0000000..39e6eb5 --- /dev/null +++ b/public - Copy/Values.js @@ -0,0 +1,40 @@ +// Constants +var playerlength; +var playerSpeed; +var graceperiod; +var pickuplength; +var maxplayernamelength = 10; +// var mindist; //Fraction of average of width+Height // moved to initialization +// Base (might change through levels) +var stealthBallticks; +// Counter variables: +var countervalue; +var timeLeft; +var gracetimer; +// mode +var grace; +var playerdead; +var scorenotsubmitted; +// progess +var score; + + +function setVariables() { + let averageSize = (Math.abs(width) + Math.abs(height)) / 2; + playerlength = averageSize / 56; + playerSpeed = averageSize / 143; + pickuplength = averageSize / 50; + + graceperiod = 100; + timeLeft = 30; + stealthBallticks = 100; + + countervalue = 0; + gracetimer = 0; + + grace = false; + playerdead = false; + scorenotsubmitted = true; + score = 0; + resetmovement(); +} \ No newline at end of file diff --git a/public - Copy/gameOver1.wav b/public - Copy/gameOver1.wav new file mode 100644 index 0000000..58a3f20 Binary files /dev/null and b/public - Copy/gameOver1.wav differ diff --git a/public - Copy/gameOver2.wav b/public - Copy/gameOver2.wav new file mode 100644 index 0000000..fb9a74d Binary files /dev/null and b/public - Copy/gameOver2.wav differ diff --git a/public - Copy/highscore.html b/public - Copy/highscore.html new file mode 100644 index 0000000..24937c4 --- /dev/null +++ b/public - Copy/highscore.html @@ -0,0 +1,35 @@ + + + + +Credits + + + + + + + +
+ + + + + + + + +
RankNameLevelScore (Squares Gathered)Control Method
+
+
+
+ +
+
+ +
+
+

Made by Søren Oehlenschlæger Hjort

+

Version 0.7

+ + \ No newline at end of file diff --git a/public - Copy/index.html b/public - Copy/index.html new file mode 100644 index 0000000..1d6a4a7 --- /dev/null +++ b/public - Copy/index.html @@ -0,0 +1,44 @@ + + + + + BallsBalls + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public - Copy/playTime.mp3 b/public - Copy/playTime.mp3 new file mode 100644 index 0000000..7792bbd Binary files /dev/null and b/public - Copy/playTime.mp3 differ diff --git a/public - Copy/settings.html b/public - Copy/settings.html new file mode 100644 index 0000000..889fc38 --- /dev/null +++ b/public - Copy/settings.html @@ -0,0 +1,51 @@ + + + + + Credits + + + + + +

Settings for BallsBalls

+

Made by Søren Oehlenschlæger Hjort

+ Uses Cookies To save +
+
+ + Input Method: + + +
+
+ + Auto submit score after game: +
+ +
+ Name for Auto submit: +
+ + +
+
+ + + + + + diff --git a/public - Copy/someMusic.mp3 b/public - Copy/someMusic.mp3 new file mode 100644 index 0000000..3869311 Binary files /dev/null and b/public - Copy/someMusic.mp3 differ diff --git a/public/To do.txt b/public/To do.txt new file mode 100644 index 0000000..c650dc7 --- /dev/null +++ b/public/To do.txt @@ -0,0 +1,57 @@ +/////////////////////////////////// +/////// New Objectives /////// +/////////////////////////////////// +**Iron out singlePage merging project** +Intro guide +checkup on diagonal movement + +Start balancing, create a levers to control difficulty +/ change level progression +establish facade between game and animation + +powerup options +challenges +/////////////////////////////////// +/////// done'ish Objectives /////// +/////////////////////////////////// +Sound settings (done?) +Pause Game(done?) +Fix control method settings (done?) +/////////////////////////////////// +//////// Old Stuff ///////// +/////////////////////////////////// +State concept +(gameState, + MenuState, + HighScoreState, + SettingsState +) + +Implement Menu properly +Settings in one page +Sound Settings +users + + +/////////////////////////////////// +//////// From mobile ///////// +/////////////////////////////////// + +Old TODO's: +Fix highscore submitting +reveal invis Ball on impact +fix text +lock when submitting +startsite +fjern størrelseforskelle (alt relativt) +Seeker ball fix loop + +Ideas: +Integrate/merge Pages/Single page'ify +Hints/Legends +Map (forhindringer) +samle ting (powerups) +Multiplayer (vs mode) +Webgl (the conversion) +Anti-mur ting (seeker is an idea) +Highscore board (+rework) \ No newline at end of file diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..c82b30c --- /dev/null +++ b/public/index.html @@ -0,0 +1,27 @@ + + + + + BallsBalls + + + + + + + + + +
+ + + diff --git a/public/index.html~ b/public/index.html~ new file mode 100644 index 0000000..937e6b2 --- /dev/null +++ b/public/index.html~ @@ -0,0 +1,26 @@ + + + + + BallsBalls + + + + + + + + +
+ + + diff --git a/public/scripts/Ball.js b/public/scripts/Ball.js new file mode 100644 index 0000000..b89ad17 --- /dev/null +++ b/public/scripts/Ball.js @@ -0,0 +1,32 @@ +define(["DrawFunctions","Calculations"],function(drawFunctions,Calculations) { +let Ball = function (startx,starty, vx, vy, radius,commonValues) { + this.x = startx; + this.y = starty; + this.radius = radius; + this.dx = vx * Calculations.randomsign(); + this.dy = vy * Calculations.randomsign(); + this.commonValues = commonValues; +}; + +Ball.prototype.move = function() { + if ((this.x > this.commonValues.height-this.radius && this.dx > 0)|| (this.x < this.radius && this.dx < 0)) { + this.dx = -this.dx; + } + if ((this.y > this.commonValues.width-this.radius && this.dy > 0) || (this.y < this.radius && this.dy < 0)) { + this.dy = -this.dy; + } + + this.x = this.x + this.dx; + this.y = this.y + this.dy; +}; + +Ball.prototype.shape = function() { + return new Calculations.circle(this.x,this.y,this.radius); +}; + +Ball.prototype.draw = function(ctx) { + drawFunctions.drawBall(this.x, this.y, this.radius,ctx,"green"); +}; + +return Ball; +}) \ No newline at end of file diff --git a/public/scripts/Calculations.js b/public/scripts/Calculations.js new file mode 100644 index 0000000..ae45bf7 --- /dev/null +++ b/public/scripts/Calculations.js @@ -0,0 +1,114 @@ +define(function() { + return { + // Shape objects: + circle: function (x,y,radius) { + this.x = x; + this.y = y; + this.r = radius; + }, + + rectangle: + function rectangle(x,y,width,height) { + this.x = x; + this.y = y; + this.w = width; + this.h = height; + }, + + //distance calculator (between two points) + dist: function(x1,y1,x2,y2) { + return Math.sqrt(Math.pow(Math.abs(x1 - x2),2) + Math.pow(Math.abs(y1 - y2),2)); + }, + + + + randomsign: function () { + var i = this.random(0, 1); + if (i == 0) { + return -1; + } else { + return 1; + } + }, + + sign: function(i) { + if (i > 0) { + return 1; + } else if (i < 0) { + return -1; + } else { + return 0; + } + }, + + random: function(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + }, + + CircleCircleColliding: function(c1,c2) { + var dist = this.dist(c1.x , c1.y , c2.x , c2.y); + if (dist < Math.max(c1.r,c2.r)) { + return true; + } + return false; + }, + + RectRectColliding: function(r1,r2) { + var distX = Math.abs(r1.x + r1.w/2 - r2.x - r2.w/2); + var distY = Math.abs(r1.y + r1.h/2 - r2.y - r2.h/2); + + if (distX > (r1.w + r2.w)/2) { + return false; + } else if (distY > (r1.h + r2.h)/2) { + return false; + } else { + return true; + } + }, + + RectCircleColliding: function(circle,rect){ + var distX = Math.abs(circle.x - rect.x-rect.w/2); + var distY = Math.abs(circle.y - rect.y-rect.h/2); + + if (distX > (rect.w/2 + circle.r)) { return false; } + if (distY > (rect.h/2 + circle.r)) { return false; } + + if (distX <= (rect.w/2)) { return true; } + if (distY <= (rect.h/2)) { return true; } + + var dx=distX-rect.w/2; + var dy=distY-rect.h/2; + return (dx*dx+dy*dy<=(circle.r*circle.r)); + }, + + /** + * + * @param a the starting position + * @param b the end position + * @param max the maximum value (i.e. 360 for degrees in circle + * @returns {number} in {-1,0,1}, which direction is shortest + */ + shortestDirection: function (a, b, max) { + var ans; + if (b - a > max / 2) { + ans = b - a - max; + } else if (b - a > -max / 2) { + ans = b - a; + } else { + ans = b - a + max; + } + + if (ans > 0) { + return 1; + } else if (ans < 0) { + return -1; + } else { + return 0; + } + +} + + + + } +}) \ No newline at end of file diff --git a/public/scripts/DrawFunctions.js b/public/scripts/DrawFunctions.js new file mode 100644 index 0000000..c901ad7 --- /dev/null +++ b/public/scripts/DrawFunctions.js @@ -0,0 +1,21 @@ +define(function() { +function drawBall(x,y,r,ctx,color) { + ctx.beginPath(); + ctx.arc(x, y, r, 0, Math.PI*2, false); + ctx.fillStyle = color; + ctx.fill(); + ctx.closePath(); +} + +function drawRect(x,y,w,h,ctx,color) { + ctx.beginPath(); + ctx.rect(x,y,w,h); + ctx.fillStyle = color; + ctx.fill(); + ctx.closePath(); +} +return { + drawBall: drawBall, + drawRect: drawRect +} +}) \ No newline at end of file diff --git a/public/scripts/GameFlow.js b/public/scripts/GameFlow.js new file mode 100644 index 0000000..de66066 --- /dev/null +++ b/public/scripts/GameFlow.js @@ -0,0 +1,229 @@ +define(["GameValueHandler","Music","Calculations", +"Paddle","Ball","Pickup" +],function(GameValueHandler,music,Calculations, +Paddle,Ball,Pickup +) { +var canvas; +var gameState = new GameValueHandler(); +var myFont = "Arial" +var fillStyle = "#dd0095"; +var ctx +var p; +var objects; +var endFunc; +var gracetimer = 0; +var grace = false; +var paused = false; +var commonValues; + + function initiate(aCanvas,endFunction,ctrlHandler) { + canvas = aCanvas; + ctx = canvas.ctx; + endFunc = endFunction; + gameState.init(canvas.width, canvas.height); + gracetimer = 0; + p = new Paddle(canvas.height/2, canvas.width/2, + gameState.playerLength,ctrlHandler, gameState.playerSpeed); + + commonValues = { + width: canvas.width, + height: canvas.height, + stealthBallticks: gameState.stealthBallticks, + p: p, + maxTurn: gameState.maxTurn + } + + objects = []; + + addPickUp(); + music.playMain(); + doTurn(); + } + + +function doBasic(thirdMessage) { + //reset canvas + ctx.clearRect(0, 0, canvas.width, canvas.height); + + //text drawing + setFont(40); + ctx.fillText("Level: "+ gameState.level, canvas.width/100, 1*canvas.height/40); + ctx.fillText("Squares Gathered: "+gameState.score, canvas.width/100, 2*canvas.height/40); + if (thirdMessage!=null) { + ctx.fillText("Survive for: "+gameState.secondsLeft, canvas.width/100, 3*canvas.height/40); + } + //move player + p.move(); + p.draw(ctx); +} + +function doGrace() { + if (paused) { + return; + } + + doBasic(); + + //draw grace text + setFont(10); + ctx.fillText("Level Complete", canvas.width/4, canvas.height/4); + + //end of grace + if (gracetimer == 0) { + grace = false; + //start Music Again + music.playMain(); + //add objects: + addSpecialBall(); + addPickUp(); + for (i = 0; i < gameState.initialballs; i++) { + addBall(); + } + + nextTurn(doTurn); + } else { + //grace countdown + gracetimer = gracetimer - 1; + nextTurn(doGrace); + } +} + +function doTurn() { + if (gameState.playerdead) { + endgame(); + return; + } else if (paused) { + return; + } + + doBasic("Survive for: "+gameState.secondsLeft); + + // check if pickup has been picked up + pickup.draw(ctx); + if (Calculations.RectRectColliding(p.shape(), pickup.shape())) { + addPickUp(); + gameState.score++; + } + + //move balls + for (var int = 0; int < objects.length; int++) { + var object = objects[int]; + + object.move(); + if (Calculations.RectCircleColliding(object.shape(), p.shape())) { + gameState.playerdead = true; + object.visible = true; + } + object.draw(ctx); + } + + //end of level + if (gameState.timeLeft == 0) { + //Pause Music + music.playPause(); + //tick up level + gameState.levelup(); + //enter grace period + gracetimer = gameState.graceperiod; + grace = true; + //reset "game board" + objects = []; + pickup = null; + gameState.timeLeft = gameState.levelduration; + //begin grace: + nextTurn(doGrace); + } else { + //count countsdown timer + if (gameState.count()) { + for (i = 0; i < gameState.ballspertick; i++) { + addBall(); + } + } + nextTurn(doTurn); + } +} + + + +function nextTurn(feed) { + setTimeout(feed,gameState.refreshTime); +} + +function setFont(quotent) { + ctx.font = (canvas.width/quotent)+"px " + myFont; + ctx.fillStyle = fillStyle; +} + + + + +function addObject(object) { + //set starting position + var currentdist = 0; + let startx; + let starty; + while (currentdist < gameState.minDist) { + startx = Calculations.random(0, canvas.height); + starty = Calculations.random(0, canvas.width); + currentdist = Calculations.dist(startx, starty, p.x, p.y); + } + + //set speed + vx = Calculations.random(gameState.minBallspeed, gameState.maxBallspeed); + vy = Calculations.random(gameState.minBallspeed, gameState.maxBallspeed); + + //set size + radius = Calculations.random(gameState.minballRadius,gameState.maxballRadius); + + //add to ball list + let newObject = new object(startx, starty, vx, vy, radius,commonValues); + objects.push(newObject); + return newObject; +} + +function addBall() { + addObject(Ball); +} + +function addSpecialBall() { + addObject(gameState.specialBall); +} + +function addPickUp() { + //set position + let x; + let y; + var currentdist = 0; + while (currentdist < gameState.minDist) { + x = Calculations.random(gameState.pickupLength , canvas.height-gameState.pickupLength ); + y = Calculations.random(gameState.pickupLength , canvas.width-gameState.pickupLength ); + currentdist = Calculations.dist(x, y, p.x, p.y); + } + //add Pickup + pickup = new Pickup(x,y,gameState.pickupLength ); +} + +//ending the game, when player dies +function endgame() { + music.playGameOver(); + endFunc({score:gameState.score,level:gameState.level}); +} + +let pauseGameToggle = function() { + paused = !paused; + if (!paused) { + if (grace) { + doGrace(); + } else { + doTurn(); + } + } +}; + + +return { + initiateGame: initiate, + pauseGameToggle: pauseGameToggle +} + +}) \ No newline at end of file diff --git a/public/scripts/GameValueHandler.js b/public/scripts/GameValueHandler.js new file mode 100644 index 0000000..eced3f2 --- /dev/null +++ b/public/scripts/GameValueHandler.js @@ -0,0 +1,119 @@ +define(["SeekerBall","StealthBall"],function(SeekerBall, StealthBall) { + function dist(x1,y1,x2,y2) { + return Math.sqrt(Math.pow(Math.abs(x1 - x2),2) + Math.pow(Math.abs(y1 - y2),2)); + } + + //checks if addBall-tick has come (and counts up) + + +return function GameValueHandler() { + this.level = 1; + this.maxBallspeed; + this.minBallspeed; + this.maxballRadius; + this.minballRadius; + this.initialballs; //balls at the start of the level + this.levelduration; + this.tickperball; //how often new ball is created + this.ballspertick; //how many balls are created at once + this.basemaxBallspeed; + this.baseminBallspeed; + + this.durationTickUp = 60; + + this.baseForDurationIncrease = 0; + this.baseForSpeedIncrease = 2; + this.baseForBallsPerTickIncrease = 0; + this.baseForTicksPerBallDecrease = 3; + + this.ticksForDurationIncrease = 2; + this.ticksForSpeedIncrease = 4; + this.ticksForBallsPerTickIncrease = 5; + this.ticksForTicksPerBallDecrease = 5; + + this.levelup = function(){ + this.level++; + this.initialballs++; + if (this.level % 2 == 0) { + this.specialBall = StealthBall; + } else { + this.specialBall = SeekerBall; + } + + if ((this.level % this.ticksForDurationIncrease) + this.baseForDurationIncrease == 0) { + this.levelduration += this.durationTickUp; + } + if ((this.level % this.ticksForSpeedIncrease) + this.baseForSpeedIncrease == 0) { + this.maxBallspeed += this.basemaxBallspeed; + this.minBallspeed += this.baseminBallspeed; + } + if ((this.level % this.baseForBallsPerTickIncrease) + this.baseForBallsPerTickIncrease == 0) { + this.ballspertick++; + } + if ((this.level % this.baseForTicksPerBallDecrease) + this.baseForTicksPerBallDecrease == 0) { + this.ticksperball--; + } + + this.levelstart = new Date().getTime() / 1000; + } + + let countervalue = 0; + + this.count = function () { + this.timeLeft--; + this.secondsLeft = Math.floor(this.timeLeft/this.updatesPerSecond); + countervalue++; + if (countervalue > this.tickperball) { + countervalue = 0; + return true; + } + return false; + } + + + + this.init = function(width,height) { + this.initialballs = 1; + this.levelduration = 600; + this.tickperball = 20; + this.ballspertick = 1; + + + + + this.timeLeft = this.levelduration; + this.updatesPerSecond = 60; + + + + let averageSize = (Math.abs(width) + Math.abs(height)) / 2; + + this.playerLength = averageSize / 56; + this.playerSpeed = averageSize / 143; + this.pickupLength = averageSize / 50; + + this.minDist = dist(0,0,width,height) / 4; + + this.graceperiod = 100; + this.stealthBallticks = 100; + this.maxTurn = 0.03; + + this.playerdead = false; + this.scorenotsubmitted = true; + this.score = 0; + + + + this.level = 1; + this.basemaxBallspeed = averageSize / 200; + this.baseminBallspeed = averageSize / 1000; + this.maxBallspeed = this.basemaxBallspeed; + this.minBallspeed = this.baseminBallspeed; + this.maxballRadius = averageSize / 70; + this.minballRadius = averageSize / 200; + + this.refreshTime = 1000/this.updatesPerSecond; + this.levelstart = new Date().getTime() / 1000; + } +} +}) \ No newline at end of file diff --git a/public/scripts/Initialization.js b/public/scripts/Initialization.js new file mode 100644 index 0000000..84030ed --- /dev/null +++ b/public/scripts/Initialization.js @@ -0,0 +1,39 @@ +require.config({ + urlArgs: "bust=v2" +}); + +require(["menuState","State","settings"], function(menuState,State,settings) { + var canvas = {}; + var ctx; + var p; + var pickup; + var objects; + var height; + var width; + var mindist = 4; + var leaderboard; + var squared = true; + + init = function () { + + // Initialize canvas + canvas.dom = document.getElementById("myCanvas"); + canvas.ctx = canvas.dom.getContext("2d"); + + settings.init(); + + if (squared) { + let size = Math.min(window.innerWidth,window.innerHeight); + canvas.dom.width = canvas.height = size; + canvas.dom.height = canvas.width = size; + } else { + canvas.dom.width = canvas.height = window.innerWidth; + canvas.dom.height = canvas.width = window.innerHeight; + } + var controller = State.stateController(menuState,canvas); + }; + + init(); + +}); + diff --git a/public/scripts/Initialization.js~ b/public/scripts/Initialization.js~ new file mode 100644 index 0000000..9d934d4 --- /dev/null +++ b/public/scripts/Initialization.js~ @@ -0,0 +1,35 @@ +require(["menuState","State","settings"], function(menuState,State,settings) { + var canvas = {}; + var ctx; + var p; + var pickup; + var objects; + var height; + var width; + var mindist = 4; + var leaderboard; + var squared = true; + + init = function () { + + // Initialize canvas + canvas.dom = document.getElementById("myCanvas"); + canvas.ctx = canvas.dom.getContext("2d"); + + settings.init(); + + if (squared) { + let size = Math.min(window.innerWidth,window.innerHeight); + canvas.dom.width = canvas.height = size; + canvas.dom.height = canvas.width = size; + } else { + canvas.dom.width = canvas.height = window.innerWidth; + canvas.dom.height = canvas.width = window.innerHeight; + } + var controller = State.stateController(menuState,canvas); + }; + + init(); + +}); + diff --git a/public/scripts/Leaderboard.js b/public/scripts/Leaderboard.js new file mode 100644 index 0000000..76e7fe9 --- /dev/null +++ b/public/scripts/Leaderboard.js @@ -0,0 +1,62 @@ +define(function() { +let firebaseURI = "https://leaderboard-bf98b.firebaseio.com"; + + var config = { + apiKey: "AIzaSyDnQy8gUVUldROZM3hxjg2_M3FE7Yg_cSc", + authDomain: "leaderboard-bf98b.firebaseapp.com", + databaseURL: "https://leaderboard-bf98b.firebaseio.com", + storageBucket: "leaderboard-bf98b.appspot.com", + }; + firebase.initializeApp(config); + +let Leaderboard = function(){ + this.firebase = firebase.database(); + this.firebase.ref("scores").orderByChild("score").limitToLast(5).on("value", (value) => { + this.scores = value.val() + }); + + + this.add = function(data) { + this.firebase.ref("scores").push(data).setPriority(data.score) + }; + + /* + * assumed that data is valid + */ + this.addandgo = function(data,go) { + this.firebase.ref("scores").push(data).setPriority(data.score).then(go, function(){ + console.log("fail"); + }); + }; + + this.get = function() { + throw new Error("this shouldn't happen"); + var list = []; + var running = true; + this.firebase.ref("scores").orderByChild("score").once("value").then( + function(snapshot) { + snapshot.forEach(function(childSnapshot) { + list.push(childSnapshot.val()); + }) + running = false; + }); + }; + + this.getandgo = function(go,limit) { + let query = this.firebase.ref("scores").orderByChild("score"); + if (limit!=null) { + query = query.limitToLast(limit); + } + query.once("value").then( + function(snapshot) { + let list = []; + snapshot.forEach(function(childSnapshot) { + list.push(childSnapshot.val()); + }); + go(list); + }); + }; +}; + +return new Leaderboard(); +}); \ No newline at end of file diff --git a/public/scripts/Music.js b/public/scripts/Music.js new file mode 100644 index 0000000..811a85d --- /dev/null +++ b/public/scripts/Music.js @@ -0,0 +1,55 @@ +define(["settings"],function(settings) { +var music = new Music(); + +function Music() { + this.audio = new Audio('soundFiles/Retro.wav'); + this.audio.loop = true; + this.sounds = new Audio(); + this.muted = false; + + this.playMain = function() { + if (!this.muted) { + this.audio.volume = settings.soundLevel; + } + this.sounds.pause(); + this.audio.play(); + } + + this.playGameOver = function() { + this.audio.pause(); + this.sounds.src = 'soundFiles/gameOver2.wav'; + this.sounds.play(); + } + + this.playPause = function() { + this.audio.pause(); + } + + this.pause = function() { + this.audio.pause(); + } + + this.stop = function() { + this.audio.pause(); + } + + this.toggleMute = function() { + if (this.muted) { + this.audio.volume = settings.soundLevel; + } else { + this.audio.volume = 0; + } + this.muted = !this.muted; + } + +// this.setVolume = function(value) { +// this.audio.volume = value; +// } + + this.changeVolume = function(change) { + this.audio.volume += value; + } +} + +return music; +}) diff --git a/public/scripts/Music.js~ b/public/scripts/Music.js~ new file mode 100644 index 0000000..fa65ab5 --- /dev/null +++ b/public/scripts/Music.js~ @@ -0,0 +1,56 @@ +define(["settings"],function(settings) { +var music = new Music(); + +function Music() { + this.audio = new Audio('soundFiles/Retro.wav'); + this.audio.loop = true; + this.sounds = new Audio(); + this.muted = false; + + this.playMain = function() { + if (!this.muted) { + console.log(settings.soundLevel); + this.audio.volume = settings.soundLevel; + } + this.sounds.pause(); + this.audio.play(); + } + + this.playGameOver = function() { + this.audio.pause(); + this.sounds.src = 'soundFiles/gameOver2.wav'; + this.sounds.play(); + } + + this.playPause = function() { + this.audio.pause(); + } + + this.pause = function() { + this.audio.pause(); + } + + this.stop = function() { + this.audio.pause(); + } + + this.toggleMute = function() { + if (this.muted) { + this.audio.volume = settings.soundLevel; + } else { + this.audio.volume = 0; + } + this.muted = !this.muted; + } + +// this.setVolume = function(value) { +// this.audio.volume = value; +// } + + this.changeVolume = function(change) { + this.audio.volume += value; + } +} + +return music; +}) diff --git a/public/scripts/Paddle.js b/public/scripts/Paddle.js new file mode 100644 index 0000000..da89dc2 --- /dev/null +++ b/public/scripts/Paddle.js @@ -0,0 +1,19 @@ +define(["DrawFunctions","Calculations"],function(drawFunctions,Calculations) { +return function Paddle(ax,ay,length,controller,playerSpeed) { + this.x = ax; + this.y = ay; + this.width = length; + this.height = length; + this.move = function(nx,ny) { + controller.playerControl(this,playerSpeed); + } + + this.shape = function(){ + return new Calculations.rectangle(this.x,this.y,this.width,this.height); + } + + this.draw = function(ctx) { + drawFunctions.drawRect(this.x, this.y, this.width, this.height,ctx,"#0095DD"); + } +} +}) \ No newline at end of file diff --git a/public/scripts/Pickup.js b/public/scripts/Pickup.js new file mode 100644 index 0000000..e6ee14b --- /dev/null +++ b/public/scripts/Pickup.js @@ -0,0 +1,16 @@ +define(["DrawFunctions","Calculations"],function(drawFunctions,Calculations) { + return function Pickup(x,y,length) { + this.x = x; + this.y = y; + this.width = length; + this.height = length; + + this.shape = function(){ + return new Calculations.rectangle(this.x,this.y,this.width,this.height); + } + + this.draw = function(ctx) { + drawFunctions.drawRect(this.x, this.y, this.width, this.height,ctx,"#FFA500"); + } + } +}) \ No newline at end of file diff --git a/public/scripts/SeekerBall.js b/public/scripts/SeekerBall.js new file mode 100644 index 0000000..b9453fa --- /dev/null +++ b/public/scripts/SeekerBall.js @@ -0,0 +1,34 @@ +define(["DrawFunctions","Calculations","Ball"],function(drawFunctions,Calculations,Ball) { + +return function SeekerBall(startx,starty, vx, vy, radius,commonValues) { + this.target = commonValues.p; + this.base = new Ball(startx,starty, vx, vy, radius,commonValues); + this.speed = (Math.abs(this.base.dx) + Math.abs(this.base.dy)) / 2; + this.currentDirection = 0; + + this.move = function() { + this.determineDirection(); + this.base.x -= this.speed * Math.cos(this.currentDirection); + this.base.y -= this.speed * Math.sin(this.currentDirection); + }; + + this.determineDirection = function() { + DesiredDirection = Math.atan2((this.target.y - this.base.y) , (this.target.x - this.base.x)) + Math.PI; + + let change = this.currentDirection-DesiredDirection; + if (Math.abs(change)0) { + return 1; + } else if (x<0) { + return -1; + } + return 0; + } + + + gameControlHandler = function(width,height) { + var upPressed = false; + var downPressed = false; + var rightPressed = false; + var leftPressed = false; + + function keyboardControl(object, speed) { + let xChange = 0; + let yChange = 0; + + if(rightPressed) { + xChange += speed; + } + if(leftPressed) { + xChange -= speed; + } + + if(downPressed) { + yChange += speed; + } + + if(upPressed) { + yChange -= speed; + } + + if (xChange!=0 && yChange!=0) { + xChange = sign(xChange)*Math.sqrt(settings.diagonalFactor*speed); + yChange = sign(yChange)*Math.sqrt(settings.diagonalFactor*speed); + } + + object.x += xChange; + object.y += yChange; + + if (object.x < 0) { + object.x = 0; + } else if (object.x + object.height > height) { + object.x = height-object.height; + } + + if (object.y < 0) { + object.y = 0; + } else if (object.y + object.width > width) { + object.y = width-object.width; + } + } + + this.keyDown = function(e) { + if(e.keyCode == settings.downKey) { + downPressed = true; + } else if(e.keyCode == settings.rightKey) { + rightPressed = true; + } else if(e.keyCode == settings.upKey) { + upPressed = true; + } else if(e.keyCode == settings.leftKey) { + leftPressed = true; + } else if(e.keyCode == settings.muteKey) { + music.toggleMute(); + } else if(e.keyCode == settings.pauseKey) { + game.pauseGameToggle(); + } + } + + this.keyUp = function(e) { + if(e.keyCode == settings.downKey) { + downPressed = false; + } + else if(e.keyCode == settings.rightKey) { + rightPressed = false; + } + else if(e.keyCode == settings.upKey) { + upPressed = false; + } + else if(e.keyCode == settings.leftKey) { + leftPressed = false; + } + } + this.playerControl = keyboardControl; + } + return gameControlHandler; +}) \ No newline at end of file diff --git a/public/scripts/gameState.js b/public/scripts/gameState.js new file mode 100644 index 0000000..5b0adf4 --- /dev/null +++ b/public/scripts/gameState.js @@ -0,0 +1,23 @@ +define(["GameFlow","settings", "gameControlHandler"], +function(gameflow,settings,gameControlHandler) { + + function gameState(controller,canvas) { + settings.updateSettings(); + let gameCtrlHandler = new gameControlHandler(canvas.width, canvas.height); + this.init = function() { + canvas.dom.style.display = "block"; + gameflow.initiateGame(canvas, + function(gameData){controller.changeState("submitScoreState",gameData)} + ,gameCtrlHandler); + } + this.end = function() { + canvas.dom.style.display = "none"; + } + this.keydownHandler = gameCtrlHandler.keyDown; + this.keyupHandler = gameCtrlHandler.keyUp; + } + + return { + gameState: gameState + } +}); \ No newline at end of file diff --git a/public/scripts/highScoreState.js b/public/scripts/highScoreState.js new file mode 100644 index 0000000..80b0bc1 --- /dev/null +++ b/public/scripts/highScoreState.js @@ -0,0 +1,52 @@ +define(["Leaderboard"],function(leaderboard) { + let site = '
Rank Name Level Score (Squares Gathered) Control Method

'; + let outerDiv = document.getElementById("outerDiv"); + + let highscoreState = function (controller,values) { + this.init = function() { + outerDiv.innerHTML = site; + document.getElementById("returnToMenu").addEventListener("click", + function() { + controller.changeState("menuState"); + }); + leaderboard.getandgo(function(list) { + let table = document.getElementById("items"); + var index, len; + for (index = Math.min(list.length-1,10), len = 0; index >= len; --index) { + addRow(table,list[index]); + } + }, 10); + } + + this.end = function() { + outerDiv.innerHTML = ""; + } + + this.keydownHandler = function(e) { + if (e.keyCode == 77) { // m + controller.changeState("menuState"); + } + } + this.keyupHandler = function(e) { + } + } + + function addRow(table, data) { //adding a simple row + var rownumber = table.rows.length; + var row = table.insertRow(rownumber); + + var cell1 = row.insertCell(0); + var cell2 = row.insertCell(1); + var cell3 = row.insertCell(2); + var cell4 = row.insertCell(3); + var cell5 = row.insertCell(4); + + cell1.innerHTML = rownumber; + cell2.innerHTML = data.name; + cell3.innerHTML = data.level; + cell4.innerHTML = data.score; + cell5.innerHTML = data.method; + } + + return highscoreState; +}); \ No newline at end of file diff --git a/public/scripts/introState.js b/public/scripts/introState.js new file mode 100644 index 0000000..ae47824 --- /dev/null +++ b/public/scripts/introState.js @@ -0,0 +1,71 @@ +define(["GameValueHandler","Paddle","Ball","Pickup"], +function(GameValueHandler,Paddle,Ball,Pickup) { + var myFont = "Arial" + var fillStyle = "green"; + let player; + let pickup; + + let lineStart = 10; + let lineMargin = 10; + + function init() { + let gameValueHandler = new GameValueHandler(); + player = new Paddle(lineStart, lineMargin*1, + GameValueHandler.playerLength,null,0); + pickup = new Pickup(lineStart,lineMargin*2,GameValueHandler.pickupLength); + } + + function setMenuText(canvas) { + //reset canvas + canvas.ctx.clearRect(0, 0, canvas.width, canvas.height); + setFont(canvas,5); + + player.draw(canvas.ctx); + pickup.draw(canvas.ctx); + + canvas.ctx.fillText("BallsBalls", canvas.width/15, canvas.height/4); + + setFont(canvas,15); + //text drawing + let displayWidth = canvas.width/10; + let displayHeight = canvas.height/2; + let heightOffset = canvas.width/12; + + // canvas.ctx.fillText("Press Space to Play Game", displayWidth, displayHeight); + // canvas.ctx.fillText("Press i for settings", displayWidth, displayHeight+heightOffset*1); + // canvas.ctx.fillText("Press h for Leaderboard", displayWidth, displayHeight+heightOffset*2); + } + + function setFont(canvas,quotent) { + canvas.ctx.font = (canvas.width/quotent)+"px " + myFont; + canvas.ctx.fillStyle = fillStyle; + } + + function menuState(controller,canvas) { + + this.init = function() { + canvas.dom.style.display = "block"; + init(); + setMenuText(canvas); + + } + this.end = function() { + canvas.dom.style.display = "none"; + } + + this.keydownHandler = function(e) { + controller.changeState("menuState"); + } + this.keyupHandler = function(e) { + } + } + + return menuState; + +}); + + + + + + diff --git a/public/scripts/menuState.js b/public/scripts/menuState.js new file mode 100644 index 0000000..e250f58 --- /dev/null +++ b/public/scripts/menuState.js @@ -0,0 +1,64 @@ +define(["settings"],function(settings) { + var myFont = "Arial" + var fillStyle = "green"; + var keyStateMap = {}; + keyStateMap[settings.restartKey] = "gameState"; + keyStateMap[settings.settingsKey] = "settingsState"; + keyStateMap[settings.highscoreKey] = "highscoreState"; + keyStateMap[settings.introKey] = "introState"; + + + + function setMenuText(canvas) { + //reset canvas + canvas.ctx.clearRect(0, 0, canvas.width, canvas.height); + setFont(canvas,5); + + canvas.ctx.fillText("BallsBalls", canvas.width/15, canvas.height/4); + + setFont(canvas,15); + //text drawing + let displayWidth = canvas.width/10; + let displayHeight = canvas.height/2; + let heightOffset = canvas.width/12; + + canvas.ctx.fillText("Press Space to Play Game", displayWidth, displayHeight); + canvas.ctx.fillText("Press i for settings", displayWidth, displayHeight+heightOffset*1); + canvas.ctx.fillText("Press h for Leaderboard", displayWidth, displayHeight+heightOffset*2); + } + + function setFont(canvas,quotent) { + canvas.ctx.font = (canvas.width/quotent)+"px " + myFont; + canvas.ctx.fillStyle = fillStyle; + } + + function menuState(controller,canvas) { + + this.init = function() { + canvas.dom.style.display = "block"; + setMenuText(canvas); + + } + this.end = function() { + canvas.dom.style.display = "none"; + } + + this.keydownHandler = function(e) { + let change = keyStateMap[e.keyCode]; + if(change!=null) { + controller.changeState(change); + } + } + this.keyupHandler = function(e) { + } + } + + return menuState; + +}); + + + + + + diff --git a/public/scripts/require.js b/public/scripts/require.js new file mode 100644 index 0000000..c32e6c1 --- /dev/null +++ b/public/scripts/require.js @@ -0,0 +1,5 @@ +/** vim: et:ts=4:sw=4:sts=4 + * @license RequireJS 2.3.3 Copyright jQuery Foundation and other contributors. + * Released under MIT license, https://github.com/requirejs/requirejs/blob/master/LICENSE + */ +var requirejs,require,define;!function(global,setTimeout){function commentReplace(e,t){return t||""}function isFunction(e){return"[object Function]"===ostring.call(e)}function isArray(e){return"[object Array]"===ostring.call(e)}function each(e,t){if(e){var i;for(i=0;i-1&&(!e[i]||!t(e[i],i,e));i-=1);}}function hasProp(e,t){return hasOwn.call(e,t)}function getOwn(e,t){return hasProp(e,t)&&e[t]}function eachProp(e,t){var i;for(i in e)if(hasProp(e,i)&&t(e[i],i))break}function mixin(e,t,i,r){return t&&eachProp(t,function(t,n){!i&&hasProp(e,n)||(!r||"object"!=typeof t||!t||isArray(t)||isFunction(t)||t instanceof RegExp?e[n]=t:(e[n]||(e[n]={}),mixin(e[n],t,i,r)))}),e}function bind(e,t){return function(){return t.apply(e,arguments)}}function scripts(){return document.getElementsByTagName("script")}function defaultOnError(e){throw e}function getGlobal(e){if(!e)return e;var t=global;return each(e.split("."),function(e){t=t[e]}),t}function makeError(e,t,i,r){var n=new Error(t+"\nhttp://requirejs.org/docs/errors.html#"+e);return n.requireType=e,n.requireModules=r,i&&(n.originalError=i),n}function newContext(e){function t(e){var t,i;for(t=0;t0&&(e.splice(t-1,2),t-=2)}}function i(e,i,r){var n,o,a,s,u,c,d,p,f,l,h,m,g=i&&i.split("/"),v=y.map,x=v&&v["*"];if(e&&(e=e.split("/"),d=e.length-1,y.nodeIdCompat&&jsSuffixRegExp.test(e[d])&&(e[d]=e[d].replace(jsSuffixRegExp,"")),"."===e[0].charAt(0)&&g&&(m=g.slice(0,g.length-1),e=m.concat(e)),t(e),e=e.join("/")),r&&v&&(g||x)){a=e.split("/");e:for(s=a.length;s>0;s-=1){if(c=a.slice(0,s).join("/"),g)for(u=g.length;u>0;u-=1)if(o=getOwn(v,g.slice(0,u).join("/")),o&&(o=getOwn(o,c))){p=o,f=s;break e}!l&&x&&getOwn(x,c)&&(l=getOwn(x,c),h=s)}!p&&l&&(p=l,f=h),p&&(a.splice(0,f,p),e=a.join("/"))}return n=getOwn(y.pkgs,e),n?n:e}function r(e){isBrowser&&each(scripts(),function(t){if(t.getAttribute("data-requiremodule")===e&&t.getAttribute("data-requirecontext")===q.contextName)return t.parentNode.removeChild(t),!0})}function n(e){var t=getOwn(y.paths,e);if(t&&isArray(t)&&t.length>1)return t.shift(),q.require.undef(e),q.makeRequire(null,{skipMap:!0})([e]),!0}function o(e){var t,i=e?e.indexOf("!"):-1;return i>-1&&(t=e.substring(0,i),e=e.substring(i+1,e.length)),[t,e]}function a(e,t,r,n){var a,s,u,c,d=null,p=t?t.name:null,f=e,l=!0,h="";return e||(l=!1,e="_@r"+(T+=1)),c=o(e),d=c[0],e=c[1],d&&(d=i(d,p,n),s=getOwn(j,d)),e&&(d?h=r?e:s&&s.normalize?s.normalize(e,function(e){return i(e,p,n)}):e.indexOf("!")===-1?i(e,p,n):e:(h=i(e,p,n),c=o(h),d=c[0],h=c[1],r=!0,a=q.nameToUrl(h))),u=!d||s||r?"":"_unnormalized"+(A+=1),{prefix:d,name:h,parentMap:t,unnormalized:!!u,url:a,originalName:f,isDefine:l,id:(d?d+"!"+h:h)+u}}function s(e){var t=e.id,i=getOwn(S,t);return i||(i=S[t]=new q.Module(e)),i}function u(e,t,i){var r=e.id,n=getOwn(S,r);!hasProp(j,r)||n&&!n.defineEmitComplete?(n=s(e),n.error&&"error"===t?i(n.error):n.on(t,i)):"defined"===t&&i(j[r])}function c(e,t){var i=e.requireModules,r=!1;t?t(e):(each(i,function(t){var i=getOwn(S,t);i&&(i.error=e,i.events.error&&(r=!0,i.emit("error",e)))}),r||req.onError(e))}function d(){globalDefQueue.length&&(each(globalDefQueue,function(e){var t=e[0];"string"==typeof t&&(q.defQueueMap[t]=!0),O.push(e)}),globalDefQueue=[])}function p(e){delete S[e],delete k[e]}function f(e,t,i){var r=e.map.id;e.error?e.emit("error",e.error):(t[r]=!0,each(e.depMaps,function(r,n){var o=r.id,a=getOwn(S,o);!a||e.depMatched[n]||i[o]||(getOwn(t,o)?(e.defineDep(n,j[o]),e.check()):f(a,t,i))}),i[r]=!0)}function l(){var e,t,i=1e3*y.waitSeconds,o=i&&q.startTime+i<(new Date).getTime(),a=[],s=[],u=!1,d=!0;if(!x){if(x=!0,eachProp(k,function(e){var i=e.map,c=i.id;if(e.enabled&&(i.isDefine||s.push(e),!e.error))if(!e.inited&&o)n(c)?(t=!0,u=!0):(a.push(c),r(c));else if(!e.inited&&e.fetched&&i.isDefine&&(u=!0,!i.prefix))return d=!1}),o&&a.length)return e=makeError("timeout","Load timeout for modules: "+a,null,a),e.contextName=q.contextName,c(e);d&&each(s,function(e){f(e,{},{})}),o&&!t||!u||!isBrowser&&!isWebWorker||w||(w=setTimeout(function(){w=0,l()},50)),x=!1}}function h(e){hasProp(j,e[0])||s(a(e[0],null,!0)).init(e[1],e[2])}function m(e,t,i,r){e.detachEvent&&!isOpera?r&&e.detachEvent(r,t):e.removeEventListener(i,t,!1)}function g(e){var t=e.currentTarget||e.srcElement;return m(t,q.onScriptLoad,"load","onreadystatechange"),m(t,q.onScriptError,"error"),{node:t,id:t&&t.getAttribute("data-requiremodule")}}function v(){var e;for(d();O.length;){if(e=O.shift(),null===e[0])return c(makeError("mismatch","Mismatched anonymous define() module: "+e[e.length-1]));h(e)}q.defQueueMap={}}var x,b,q,E,w,y={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},S={},k={},M={},O=[],j={},P={},R={},T=1,A=1;return E={require:function(e){return e.require?e.require:e.require=q.makeRequire(e.map)},exports:function(e){if(e.usingExports=!0,e.map.isDefine)return e.exports?j[e.map.id]=e.exports:e.exports=j[e.map.id]={}},module:function(e){return e.module?e.module:e.module={id:e.map.id,uri:e.map.url,config:function(){return getOwn(y.config,e.map.id)||{}},exports:e.exports||(e.exports={})}}},b=function(e){this.events=getOwn(M,e.id)||{},this.map=e,this.shim=getOwn(y.shim,e.id),this.depExports=[],this.depMaps=[],this.depMatched=[],this.pluginMaps={},this.depCount=0},b.prototype={init:function(e,t,i,r){r=r||{},this.inited||(this.factory=t,i?this.on("error",i):this.events.error&&(i=bind(this,function(e){this.emit("error",e)})),this.depMaps=e&&e.slice(0),this.errback=i,this.inited=!0,this.ignore=r.ignore,r.enabled||this.enabled?this.enable():this.check())},defineDep:function(e,t){this.depMatched[e]||(this.depMatched[e]=!0,this.depCount-=1,this.depExports[e]=t)},fetch:function(){if(!this.fetched){this.fetched=!0,q.startTime=(new Date).getTime();var e=this.map;return this.shim?void q.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],bind(this,function(){return e.prefix?this.callPlugin():this.load()})):e.prefix?this.callPlugin():this.load()}},load:function(){var e=this.map.url;P[e]||(P[e]=!0,q.load(this.map.id,e))},check:function(){if(this.enabled&&!this.enabling){var e,t,i=this.map.id,r=this.depExports,n=this.exports,o=this.factory;if(this.inited){if(this.error)this.emit("error",this.error);else if(!this.defining){if(this.defining=!0,this.depCount<1&&!this.defined){if(isFunction(o)){if(this.events.error&&this.map.isDefine||req.onError!==defaultOnError)try{n=q.execCb(i,o,r,n)}catch(t){e=t}else n=q.execCb(i,o,r,n);if(this.map.isDefine&&void 0===n&&(t=this.module,t?n=t.exports:this.usingExports&&(n=this.exports)),e)return e.requireMap=this.map,e.requireModules=this.map.isDefine?[this.map.id]:null,e.requireType=this.map.isDefine?"define":"require",c(this.error=e)}else n=o;if(this.exports=n,this.map.isDefine&&!this.ignore&&(j[i]=n,req.onResourceLoad)){var a=[];each(this.depMaps,function(e){a.push(e.normalizedMap||e)}),req.onResourceLoad(q,this.map,a)}p(i),this.defined=!0}this.defining=!1,this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else hasProp(q.defQueueMap,i)||this.fetch()}},callPlugin:function(){var e=this.map,t=e.id,r=a(e.prefix);this.depMaps.push(r),u(r,"defined",bind(this,function(r){var n,o,d,f=getOwn(R,this.map.id),l=this.map.name,h=this.map.parentMap?this.map.parentMap.name:null,m=q.makeRequire(e.parentMap,{enableBuildCallback:!0});return this.map.unnormalized?(r.normalize&&(l=r.normalize(l,function(e){return i(e,h,!0)})||""),o=a(e.prefix+"!"+l,this.map.parentMap,!0),u(o,"defined",bind(this,function(e){this.map.normalizedMap=o,this.init([],function(){return e},null,{enabled:!0,ignore:!0})})),d=getOwn(S,o.id),void(d&&(this.depMaps.push(o),this.events.error&&d.on("error",bind(this,function(e){this.emit("error",e)})),d.enable()))):f?(this.map.url=q.nameToUrl(f),void this.load()):(n=bind(this,function(e){this.init([],function(){return e},null,{enabled:!0})}),n.error=bind(this,function(e){this.inited=!0,this.error=e,e.requireModules=[t],eachProp(S,function(e){0===e.map.id.indexOf(t+"_unnormalized")&&p(e.map.id)}),c(e)}),n.fromText=bind(this,function(i,r){var o=e.name,u=a(o),d=useInteractive;r&&(i=r),d&&(useInteractive=!1),s(u),hasProp(y.config,t)&&(y.config[o]=y.config[t]);try{req.exec(i)}catch(e){return c(makeError("fromtexteval","fromText eval for "+t+" failed: "+e,e,[t]))}d&&(useInteractive=!0),this.depMaps.push(u),q.completeLoad(o),m([o],n)}),void r.load(e.name,m,n,y))})),q.enable(r,this),this.pluginMaps[r.id]=r},enable:function(){k[this.map.id]=this,this.enabled=!0,this.enabling=!0,each(this.depMaps,bind(this,function(e,t){var i,r,n;if("string"==typeof e){if(e=a(e,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap),this.depMaps[t]=e,n=getOwn(E,e.id))return void(this.depExports[t]=n(this));this.depCount+=1,u(e,"defined",bind(this,function(e){this.undefed||(this.defineDep(t,e),this.check())})),this.errback?u(e,"error",bind(this,this.errback)):this.events.error&&u(e,"error",bind(this,function(e){this.emit("error",e)}))}i=e.id,r=S[i],hasProp(E,i)||!r||r.enabled||q.enable(e,this)})),eachProp(this.pluginMaps,bind(this,function(e){var t=getOwn(S,e.id);t&&!t.enabled&&q.enable(e,this)})),this.enabling=!1,this.check()},on:function(e,t){var i=this.events[e];i||(i=this.events[e]=[]),i.push(t)},emit:function(e,t){each(this.events[e],function(e){e(t)}),"error"===e&&delete this.events[e]}},q={config:y,contextName:e,registry:S,defined:j,urlFetched:P,defQueue:O,defQueueMap:{},Module:b,makeModuleMap:a,nextTick:req.nextTick,onError:c,configure:function(e){if(e.baseUrl&&"/"!==e.baseUrl.charAt(e.baseUrl.length-1)&&(e.baseUrl+="/"),"string"==typeof e.urlArgs){var t=e.urlArgs;e.urlArgs=function(e,i){return(i.indexOf("?")===-1?"?":"&")+t}}var i=y.shim,r={paths:!0,bundles:!0,config:!0,map:!0};eachProp(e,function(e,t){r[t]?(y[t]||(y[t]={}),mixin(y[t],e,!0,!0)):y[t]=e}),e.bundles&&eachProp(e.bundles,function(e,t){each(e,function(e){e!==t&&(R[e]=t)})}),e.shim&&(eachProp(e.shim,function(e,t){isArray(e)&&(e={deps:e}),!e.exports&&!e.init||e.exportsFn||(e.exportsFn=q.makeShimExports(e)),i[t]=e}),y.shim=i),e.packages&&each(e.packages,function(e){var t,i;e="string"==typeof e?{name:e}:e,i=e.name,t=e.location,t&&(y.paths[i]=e.location),y.pkgs[i]=e.name+"/"+(e.main||"main").replace(currDirRegExp,"").replace(jsSuffixRegExp,"")}),eachProp(S,function(e,t){e.inited||e.map.unnormalized||(e.map=a(t,null,!0))}),(e.deps||e.callback)&&q.require(e.deps||[],e.callback)},makeShimExports:function(e){function t(){var t;return e.init&&(t=e.init.apply(global,arguments)),t||e.exports&&getGlobal(e.exports)}return t},makeRequire:function(t,n){function o(i,r,u){var d,p,f;return n.enableBuildCallback&&r&&isFunction(r)&&(r.__requireJsBuild=!0),"string"==typeof i?isFunction(r)?c(makeError("requireargs","Invalid require call"),u):t&&hasProp(E,i)?E[i](S[t.id]):req.get?req.get(q,i,t,o):(p=a(i,t,!1,!0),d=p.id,hasProp(j,d)?j[d]:c(makeError("notloaded",'Module name "'+d+'" has not been loaded yet for context: '+e+(t?"":". Use require([])")))):(v(),q.nextTick(function(){v(),f=s(a(null,t)),f.skipMap=n.skipMap,f.init(i,r,u,{enabled:!0}),l()}),o)}return n=n||{},mixin(o,{isBrowser:isBrowser,toUrl:function(e){var r,n=e.lastIndexOf("."),o=e.split("/")[0],a="."===o||".."===o;return n!==-1&&(!a||n>1)&&(r=e.substring(n,e.length),e=e.substring(0,n)),q.nameToUrl(i(e,t&&t.id,!0),r,!0)},defined:function(e){return hasProp(j,a(e,t,!1,!0).id)},specified:function(e){return e=a(e,t,!1,!0).id,hasProp(j,e)||hasProp(S,e)}}),t||(o.undef=function(e){d();var i=a(e,t,!0),n=getOwn(S,e);n.undefed=!0,r(e),delete j[e],delete P[i.url],delete M[e],eachReverse(O,function(t,i){t[0]===e&&O.splice(i,1)}),delete q.defQueueMap[e],n&&(n.events.defined&&(M[e]=n.events),p(e))}),o},enable:function(e){var t=getOwn(S,e.id);t&&s(e).enable()},completeLoad:function(e){var t,i,r,o=getOwn(y.shim,e)||{},a=o.exports;for(d();O.length;){if(i=O.shift(),null===i[0]){if(i[0]=e,t)break;t=!0}else i[0]===e&&(t=!0);h(i)}if(q.defQueueMap={},r=getOwn(S,e),!t&&!hasProp(j,e)&&r&&!r.inited){if(!(!y.enforceDefine||a&&getGlobal(a)))return n(e)?void 0:c(makeError("nodefine","No define call for "+e,null,[e]));h([e,o.deps||[],o.exportsFn])}l()},nameToUrl:function(e,t,i){var r,n,o,a,s,u,c,d=getOwn(y.pkgs,e);if(d&&(e=d),c=getOwn(R,e))return q.nameToUrl(c,t,i);if(req.jsExtRegExp.test(e))s=e+(t||"");else{for(r=y.paths,n=e.split("/"),o=n.length;o>0;o-=1)if(a=n.slice(0,o).join("/"),u=getOwn(r,a)){isArray(u)&&(u=u[0]),n.splice(0,o,u);break}s=n.join("/"),s+=t||(/^data\:|^blob\:|\?/.test(s)||i?"":".js"),s=("/"===s.charAt(0)||s.match(/^[\w\+\.\-]+:/)?"":y.baseUrl)+s}return y.urlArgs&&!/^blob\:/.test(s)?s+y.urlArgs(e,s):s},load:function(e,t){req.load(q,e,t)},execCb:function(e,t,i,r){return t.apply(r,i)},onScriptLoad:function(e){if("load"===e.type||readyRegExp.test((e.currentTarget||e.srcElement).readyState)){interactiveScript=null;var t=g(e);q.completeLoad(t.id)}},onScriptError:function(e){var t=g(e);if(!n(t.id)){var i=[];return eachProp(S,function(e,r){0!==r.indexOf("_@r")&&each(e.depMaps,function(e){if(e.id===t.id)return i.push(r),!0})}),c(makeError("scripterror",'Script error for "'+t.id+(i.length?'", needed by: '+i.join(", "):'"'),e,[t.id]))}}},q.require=q.makeRequire(),q}function getInteractiveScript(){return interactiveScript&&"interactive"===interactiveScript.readyState?interactiveScript:(eachReverse(scripts(),function(e){if("interactive"===e.readyState)return interactiveScript=e}),interactiveScript)}var req,s,head,baseElement,dataMain,src,interactiveScript,currentlyAddingScript,mainScript,subPath,version="2.3.3",commentRegExp=/\/\*[\s\S]*?\*\/|([^:"'=]|^)\/\/.*$/gm,cjsRequireRegExp=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,jsSuffixRegExp=/\.js$/,currDirRegExp=/^\.\//,op=Object.prototype,ostring=op.toString,hasOwn=op.hasOwnProperty,isBrowser=!("undefined"==typeof window||"undefined"==typeof navigator||!window.document),isWebWorker=!isBrowser&&"undefined"!=typeof importScripts,readyRegExp=isBrowser&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,defContextName="_",isOpera="undefined"!=typeof opera&&"[object Opera]"===opera.toString(),contexts={},cfg={},globalDefQueue=[],useInteractive=!1;if("undefined"==typeof define){if("undefined"!=typeof requirejs){if(isFunction(requirejs))return;cfg=requirejs,requirejs=void 0}"undefined"==typeof require||isFunction(require)||(cfg=require,require=void 0),req=requirejs=function(e,t,i,r){var n,o,a=defContextName;return isArray(e)||"string"==typeof e||(o=e,isArray(t)?(e=t,t=i,i=r):e=[]),o&&o.context&&(a=o.context),n=getOwn(contexts,a),n||(n=contexts[a]=req.s.newContext(a)),o&&n.configure(o),n.require(e,t,i)},req.config=function(e){return req(e)},req.nextTick="undefined"!=typeof setTimeout?function(e){setTimeout(e,4)}:function(e){e()},require||(require=req),req.version=version,req.jsExtRegExp=/^\/|:|\?|\.js$/,req.isBrowser=isBrowser,s=req.s={contexts:contexts,newContext:newContext},req({}),each(["toUrl","undef","defined","specified"],function(e){req[e]=function(){var t=contexts[defContextName];return t.require[e].apply(t,arguments)}}),isBrowser&&(head=s.head=document.getElementsByTagName("head")[0],baseElement=document.getElementsByTagName("base")[0],baseElement&&(head=s.head=baseElement.parentNode)),req.onError=defaultOnError,req.createNode=function(e,t,i){var r=e.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script");return r.type=e.scriptType||"text/javascript",r.charset="utf-8",r.async=!0,r},req.load=function(e,t,i){var r,n=e&&e.config||{};if(isBrowser)return r=req.createNode(n,t,i),r.setAttribute("data-requirecontext",e.contextName),r.setAttribute("data-requiremodule",t),!r.attachEvent||r.attachEvent.toString&&r.attachEvent.toString().indexOf("[native code")<0||isOpera?(r.addEventListener("load",e.onScriptLoad,!1),r.addEventListener("error",e.onScriptError,!1)):(useInteractive=!0,r.attachEvent("onreadystatechange",e.onScriptLoad)),r.src=i,n.onNodeCreated&&n.onNodeCreated(r,n,t,i),currentlyAddingScript=r,baseElement?head.insertBefore(r,baseElement):head.appendChild(r),currentlyAddingScript=null,r;if(isWebWorker)try{setTimeout(function(){},0),importScripts(i),e.completeLoad(t)}catch(r){e.onError(makeError("importscripts","importScripts failed for "+t+" at "+i,r,[t]))}},isBrowser&&!cfg.skipDataMain&&eachReverse(scripts(),function(e){if(head||(head=e.parentNode),dataMain=e.getAttribute("data-main"))return mainScript=dataMain,cfg.baseUrl||mainScript.indexOf("!")!==-1||(src=mainScript.split("/"),mainScript=src.pop(),subPath=src.length?src.join("/")+"/":"./",cfg.baseUrl=subPath),mainScript=mainScript.replace(jsSuffixRegExp,""),req.jsExtRegExp.test(mainScript)&&(mainScript=dataMain),cfg.deps=cfg.deps?cfg.deps.concat(mainScript):[mainScript],!0}),define=function(e,t,i){var r,n;"string"!=typeof e&&(i=t,t=e,e=null),isArray(t)||(i=t,t=null),!t&&isFunction(i)&&(t=[],i.length&&(i.toString().replace(commentRegExp,commentReplace).replace(cjsRequireRegExp,function(e,i){t.push(i)}),t=(1===i.length?["require"]:["require","exports","module"]).concat(t))),useInteractive&&(r=currentlyAddingScript||getInteractiveScript(),r&&(e||(e=r.getAttribute("data-requiremodule")),n=contexts[r.getAttribute("data-requirecontext")])),n?(n.defQueue.push([e,t,i]),n.defQueueMap[e]=!0):globalDefQueue.push([e,t,i])},define.amd={jQuery:!0},req.exec=function(text){return eval(text)},req(cfg)}}(this,"undefined"==typeof setTimeout?void 0:setTimeout); \ No newline at end of file diff --git a/public/scripts/settings.js b/public/scripts/settings.js new file mode 100644 index 0000000..b5ccd39 --- /dev/null +++ b/public/scripts/settings.js @@ -0,0 +1,91 @@ +define([],function() { +//Thanks http://www.w3schools.com/js/js_cookies.asp +let autoSubmitDefault = false; +let playerAutoNameDefault = ""; +let soundLevelDefault = 0.5; + +var settings = { + upKey: 38, + rightKey: 39, + leftKey: 37, + downKey: 40, + + restartKey: 32, //spacebar + settingsKey: 73, // i + highscoreKey: 72, // h + SubmitKey: 13, //enter + muteKey: 77, // m + pauseKey: 80, // p + introKey: 71, + + controlMethod: "Arrow Keys", + autoSubmit: false, + playerAutoName: "", + + diagonalFactor: 4, + + setSetting: setCookie, + getSetting: getCookie, + updateSettings: updateSettings, + init: updateSettings +} + +function setCookie(c_name,c_value,exdays) { + settings[c_name] = c_value; + var exdate=new Date(); + exdate.setDate(exdate.getDate() + exdays); + document.cookie=encodeURIComponent(c_name) + + "=" + encodeURIComponent(c_value) + + (!exdays ? "" : "; expires="+exdate.toUTCString()); + ; + } + +function getCookie(cname) { + var name = cname + "="; + var ca = document.cookie.split(';'); + for(var i=0; iSubmitting score"; + + submitScore(name, + globalValues.extra.score, + globalValues.extra.level, + settings.controlMethod, + controller); + } + } + this.end = function() { + this.OuterDiv.innerHTML =""; + } + + this.keydownHandler = function(e) { + } + this.keyupHandler = function(e) { + } + } + + function getPlayerName() { + // setWriteMode(); alternative method, not yet implemented + let playername; + do { + playername = prompt("Player name (max " + maxplayernamelength +" characters)"); + if (playername == null) { + return null; + } + } while ((playername.length <= 0) || (playername.length > maxplayernamelength)) + // Ask for playername until proper name is given, or cancel is chosen. + return playername; + } + + + return highscoreState; +}); \ No newline at end of file diff --git a/public/soundFiles/Retro.wav b/public/soundFiles/Retro.wav new file mode 100644 index 0000000..bbf5709 Binary files /dev/null and b/public/soundFiles/Retro.wav differ diff --git a/public/soundFiles/gameOver2.wav b/public/soundFiles/gameOver2.wav new file mode 100644 index 0000000..fb9a74d Binary files /dev/null and b/public/soundFiles/gameOver2.wav differ diff --git a/public/to dk b/public/to dk new file mode 100644 index 0000000..56c3a0e --- /dev/null +++ b/public/to dk @@ -0,0 +1,58 @@ +/////////////////////////////////// +/////// New Objectives /////// +/////////////////////////////////// +**Iron out singlePage merging project** +Intro guide +checkup on diagonal movement + +Start balancing, create a levers to control difficulty +/ change level progression +establish facade between game and animation + +powerup options +challenges +SHIELD +/////////////////////////////////// +/////// done'ish Objectives /////// +/////////////////////////////////// +Sound settings (done?) +Pause Game(done?) +Fix control method settings (done?) +/////////////////////////////////// +//////// Old Stuff ///////// +/////////////////////////////////// +State concept +(gameState, + MenuState, + HighScoreState, + SettingsState +) + +Implement Menu properly +Settings in one page +Sound Settings +users + + +/////////////////////////////////// +//////// From mobile ///////// +/////////////////////////////////// + +Old TODO's: +Fix highscore submitting +reveal invis Ball on impact +fix text +lock when submitting +startsite +fjern størrelseforskelle (alt relativt) +Seeker ball fix loop + +Ideas: +Integrate/merge Pages/Single page'ify +Hints/Legends +Map (forhindringer) +samle ting (powerups) +Multiplayer (vs mode) +Webgl (the conversion) +Anti-mur ting (seeker is an idea) +Highscore board (+rework) \ No newline at end of file