main v1.0
Benjamin Kraft 2 years ago
commit 5123fb6548
  1. 1
      .gitignore
  2. 6
      project.json
  3. BIN
      public/data/audio/music/background0.mp3
  4. BIN
      public/data/audio/music/background1.mp3
  5. BIN
      public/data/audio/music/background2.mp3
  6. BIN
      public/data/audio/music/background3.mp3
  7. BIN
      public/data/audio/music/background4.mp3
  8. BIN
      public/data/audio/music/background5.mp3
  9. BIN
      public/data/audio/music/background6.mp3
  10. BIN
      public/data/audio/music/background7.mp3
  11. BIN
      public/data/audio/music/background8.mp3
  12. BIN
      public/data/audio/sound/aww0.wav
  13. BIN
      public/data/audio/sound/aww1.wav
  14. BIN
      public/data/audio/sound/boo0.wav
  15. BIN
      public/data/audio/sound/cheer0.mp3
  16. BIN
      public/data/audio/sound/cheer1.wav
  17. BIN
      public/data/audio/sound/cheer2.wav
  18. BIN
      public/data/audio/sound/cheer3.wav
  19. BIN
      public/data/audio/sound/electrical_sweep.mp3
  20. BIN
      public/data/audio/sound/jump.mp3
  21. BIN
      public/data/images/favicon.ico
  22. 54
      public/data/scripts/Background.js
  23. 104
      public/data/scripts/Brick.js
  24. 90
      public/data/scripts/Coin.js
  25. 318
      public/data/scripts/Game.js
  26. 90
      public/data/scripts/Goal.js
  27. 73
      public/data/scripts/Interface.js
  28. 39
      public/data/scripts/LevelText.js
  29. 179
      public/data/scripts/Loader.js
  30. 46
      public/data/scripts/Map.js
  31. 83
      public/data/scripts/Message.js
  32. 122
      public/data/scripts/Plant.js
  33. 153
      public/data/scripts/Player.js
  34. 110
      public/data/scripts/Sound.js
  35. 79
      public/data/scripts/events.js
  36. 678
      public/data/scripts/lib/benjo_library.js
  37. 1
      public/data/scripts/lib/benjo_library.min.js
  38. 62
      public/data/scripts/sketch.js
  39. 86
      public/data/settings/Credits.json
  40. 215
      public/data/settings/Settings.json
  41. 88
      public/data/styles/color_picker.css
  42. BIN
      public/data/styles/font.ttf
  43. 88
      public/data/styles/range_input.css
  44. 50
      public/index.html
  45. 125
      public/styles.css
  46. BIN
      public/thumbnail.png

1
.gitignore vendored

@ -0,0 +1 @@
.idea

@ -0,0 +1,6 @@
{
"display_name": "Jump and run",
"info_text": "Birthday present for Selina ♥",
"visible": true,
"tags": ["Game"]
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

@ -0,0 +1,54 @@
"use strict"
class Background{
constructor(world){
this.yScale = height * 0.4;
this.backScale = int(values.backgroundMoveScale);
}
update(){
this.viewPort();
}
display(){
this.show();
}
viewPort(){
this.mountainPoints = [];
this.groundPoints = [];
this.yOff = height / 2 - (viewPort.y / game.world.dim.y - 0.5) * height / 2;
for (let x = 0; x < width; x++){
let y = noise(x / 100 + viewPort.x / this.backScale) - 0.5;
this.mountainPoints.push({x: x, y: y * this.yScale + this.yOff});
this.groundPoints.push({x: x, y: y * this.yScale * 0.1 + this.yOff + this.yScale / 2});
}
}
show(){
//Sky
background(colors.background.sky);
//Mountains
strokeWeight(2);
stroke(colors.background.mountains.stroke);
fill(colors.background.mountains.fill)
beginShape();
for (let p of this.mountainPoints) vertex(p.x, p.y);
vertex(width, height);
vertex(0, height);
vertex(0, this.mountainPoints[0].y);
endShape();
//Ground
fill(colors.background.ground);
beginShape();
for (let p of this.groundPoints) vertex(p.x, p.y);
vertex(width, height);
vertex(0, height);
vertex(0, this.groundPoints[0].y);
endShape();
}
}

@ -0,0 +1,104 @@
"use strict"
class Brick{
constructor(x, y, w, h, v){
this.pos = createVector(x, y);
this.vel = createVector(v.x, v.y);
this.dim = createVector(w, h);
this.prepareNoise();
}
createTrees(){
this.trees = [];
for (let i = 0; i < int(random(3)); i++) this.trees.push(new Tree(this));
}
createPlants(){
this.grasses = [];
for (let i = 0; i < int(random(4)); i++) this.grasses.push(new Grass(this, random(this.dim.x)));
}
createCoins(){
let rarity = int(values.coinRarity);
this.coin = ranBool(rarity) ? new Coin(this) : null;
}
update(world){
if (!game.paused) {
this.borders(world);
this.move();
}
}
display(){
let thrashHold = 300;
if (this.pos.x < viewPort.x + width + thrashHold && this.pos.x + this.dim.x + thrashHold > viewPort.x &&
this.pos.y < viewPort.y + height + thrashHold && this.pos.y + this.dim.y > viewPort.y - thrashHold){
this.show();
}
}
move(){
this.pos.add(this.vel);
}
borders(world){
if (this.pos.x > world.pos.x + world.dim.x - this.dim.x
|| this.pos.x < world.pos.x){
this.vel.x *= -1;
}
if (this.pos.y > world.pos.y + world.dim.y - this.dim.y
|| this.pos.y < world.pos.y){
this.vel.y *= -1;
}
}
show(){
noStroke();
//Brown earth
fill(colors.brick.earth);
rect(this.pos.x, this.pos.y + this.dim.y * 0.3, this.dim.x, this.dim.y * 0.7, this.dim.y / 4);
//Green grass ground
fill(colors.brick.ground);
beginShape();
for (let x = 0; x < this.dim.x; x += 5){
let y = this.pos.y - this.noiseValues[x] * 3;
vertex(this.pos.x + x, y);
if (!(x + 5 < this.dim.x)){
vertex(this.pos.x + this.dim.x, y);
break;
}
}
vertex(this.pos.x + this.dim.x, this.pos.y + this.dim.y / 2);
vertex(this.pos.x, this.pos.y + this.dim.y / 2);
endShape();
//Trees and grasses with flowers
for (let t of this.trees) t.show();
for (let g of this.grasses) g.show();
//Coin
if (this.coin) this.coin.update();
}
getHitbox(){
let hitbox = {
pos: {x: this.pos.x, y: this.pos.y},
dim: {x: this.dim.x, y: 0},
vel: {x: this.vel.x, y: this.vel.y}
};
return hitbox;
}
//For better performance
prepareNoise(){
this.noiseValues = [];
let trashHold = 100;
for (let x = random(trashHold); x <= int(values.maxBrickWidth) + trashHold; x++){
this.noiseValues.push(noise(x));
}
}
}

@ -0,0 +1,90 @@
"use strict"
class Coin{
constructor(brick){
this.pos = brick.pos;
this.dispoX = random(brick.dim.x);
this.brick = brick;
this.dir = ranBool() ? 1 : -1;
this.colorSetup();
}
update(){
this.blink();
this.show();
this.collision();
}
blink(){
this.hue += this.dir * sin(frameCount / 10) * 5;
this.hue = this.hue < 0 ? this.hue + 360 : this.hue;
this.hue %= 360;
colorMode(HSB);
let s = this.color.stroke;
s = color(this.hue, saturation(s), brightness(s));
this.color.stroke = s;
colorMode(RGB);
}
show(){
fill(this.color.fill);
stroke(this.color.stroke);
strokeWeight(4);
strokeJoin(ROUND);
let size = int(values.coinSize),
dispoY = int(values.coinDispoY);
let p1 = {x: this.pos.x + this.dispoX, y: this.pos.y - dispoY},
p2 = {x: this.pos.x + this.dispoX + size / 3, y: this.pos.y - (dispoY + size / 2)},
p3 = {x: this.pos.x + this.dispoX, y: this.pos.y - (dispoY + size)},
p4 = {x: this.pos.x + this.dispoX - size / 3, y: this.pos.y - (dispoY + size / 2)};
quad(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);
if (debug){
let hitbox = this.getHitbox();
noFill();
stroke(255, 0, 0);
rect(hitbox.pos.x, hitbox.pos.y, hitbox.dim.x, hitbox.dim.y);
}
}
collision(){
if (game.player.touches(this) && hue(game.player.color) != hue(this.color.fill)){
game.player.setColor(this.color.fill);
new Sound(Sound.Coin()).play();
this.brick.coin = null;
}
}
colorSetup(){
let s = color(colors.brick.coin.stroke),
f = color(colors.brick.coin.fill);
this.hue = int(random(360));
this.hue = floor(this.hue / 60) * 60;
colorMode(HSB);
let stroke = color(this.hue, saturation(s), brightness(s)),
fill = color(this.hue, saturation(f), brightness(f));
this.color = {
stroke: stroke,
fill: fill
};
colorMode(RGB);
}
getHitbox(){
let size = int(values.coinSize),
dispoY = int(values.coinDispoY);
let hitbox = {
pos: {x: this.pos.x + this.dispoX - size / 3, y: this.pos.y - (dispoY + size)},
dim: {x: size * 2 / 3, y: size}
};
return hitbox;
}
}

@ -0,0 +1,318 @@
"use strict"
class Game{
constructor(){}
load(){
let minSize = int(values.minWorldSize),
maxSize = int(values.maxWorldSize);
let world = {pos: createVector(0, 0), dim: createVector(random(minSize, maxSize), random(minSize, maxSize))};
let bricks = [];
loader = new Loader(Loader.Bar(), "Loading The Game...");
this.createBrick(world.pos.x + int(values.maxBrickWidth), bricks, world, 4);
}
next(num, bricks, world, loadingParts, percentage, partIndex, info, func){
setTimeout(function(){
let progress = percentage / loadingParts + partIndex / loadingParts;
loader.updateProgress(progress, info);
game[func](num, bricks, world, loadingParts);
});
}
createBrick(x, bricks, world, loadingParts){
let minBrickWidth = int(values.minBrickWidth),
maxBrickWidth = int(values.maxBrickWidth),
maxWorldSize = int(values.maxWorldSize);
if (x < world.pos.x + world.dim.x - maxBrickWidth){
let y = random(world.pos.y, world.pos.y + world.dim.y),
w = random(minBrickWidth, maxBrickWidth),
h = 30,
v = {
x: ranBool() ? random(-4, 4) : 0,
y: ranBool() ? random(-4, 4) : 0
};
bricks.push(new Brick(x, y, w, h, v));
x += 400000 / world.dim.y;
let percentage = (x - maxBrickWidth) / (world.pos.x + world.dim.x - maxBrickWidth * 2);
this.next(x, bricks, world, loadingParts, percentage, 0, "Building Platforms...", "createBrick");
} else {
this.createTrees(0, bricks, world, loadingParts);
}
}
createTrees(index, bricks, world, loadingParts){
bricks[index].createTrees();
if (bricks[index + 1]){
index++;
let percentage = index / bricks.length;
this.next(index, bricks, world, loadingParts, percentage, 1, "Planting Trees...", "createTrees");
} else {
this.createPlants(0, bricks, world, loadingParts);
}
}
createPlants(index, bricks, world, loadingParts){
bricks[index].createPlants();
if (bricks[index + 1]){
index++;
let percentage = index / bricks.length;
this.next(index, bricks, world, loadingParts, percentage, 2, "Planting Flowers...", "createPlants");
} else {
this.createCoins(0, bricks, world, loadingParts);
}
}
createCoins(index, bricks, world, loadingParts){
bricks[index].createCoins();
if (bricks[index + 1]){
index++;
let percentage = index / bricks.length;
this.next(index, bricks, world, loadingParts, percentage, 3, "Hiding Treasures...", "createCoins");
} else {
this.tidyUp(bricks, world);
}
}
tidyUp(bricks, world){
let variables = this.createVariables(bricks, world);
this.applyVariables(variables);
this.safeStartingConditions(variables);
resetMusics();
loader.updateProgress(1, "Cleaning up...");
//setTimeout(function(){loadAudioFiles(audioFilesLoaded)}, 1000); crashes PC :D
setTimeout(function(){game.finishLoading();}, int(values.loadedWaitTime));
}
createVariables(bricks, world){
let maxWorldSize = int(values.maxWorldSize),
maxMapSize = int(values.maxMapSize);
let iconMap = new Map(map(world.dim.x, 0, maxWorldSize, 0, maxMapSize), map(world.dim.y, 0, maxWorldSize, 0, maxMapSize));
let player = new Player(random(world.pos.x + width, world.pos.x + world.dim.x - width), random(world.pos.y + height, world.pos.y - height + world.dim.y));
let goal = new Goal();
let background = new Background(world);
viewPort.x = player.pos.x - width / 2;
viewPort.y = player.pos.y - height / 2;
let showHint = true;
let showMap = true;
let isWon = false;
let level = 0;
let maxLevel = int(values.maxLevelCount);
let variablesObject = {
world: world,
bricks: bricks,
player: player,
goal: goal,
iconMap: iconMap,
background: background,
showHint: showHint,
showMap: showMap,
isWon: isWon,
level: level,
maxLevel: maxLevel
};
return variablesObject;
}
applyVariables(variables){
for (let property in variables){
this[property] = variables[property];
}
}
safeStartingConditions(v){
let sc = {};
for (let key in v){
if (v[key] instanceof Array){
sc[key] = v[key].clone();
} else if (v[key] instanceof Player){
sc[key] = new Player(v[key].pos.x, v[key].pos.y);
} else if (v[key] instanceof Goal){
sc[key] = new Goal();
}
}
sc.isWon = false;
sc.level = 0;
this.startingConditions = sc;
}
finishLoading(){
loader.destroy();
$("#loaderWrapper").hide();
if (!menuOpen) toggleMenu($("#menuOpener"));
this.nextLevel();
this.ready = true;
this.start();
updateMenu();
}
start(){
this.playMusic();
this.resume();
}
restart(){
this.applyVariables(this.startingConditions);
this.safeStartingConditions(this.startingConditions);
this.nextLevel();
this.resume();
}
update(){
if (!this.ready || this.paused){
return;
}
this.background.update();
for (let b of this.bricks){
b.update(this.world);
}
this.goal.update();
this.player.update();
if (!this.paused){
this.player.collision(this.bricks, this.world);
}
if (this.goal.contains(this.player)
&& this.goal.brick == this.player.brick
&& !this.paused
&& !this.isWon){
this.goalReached();
}
if (this.levelText.isActive()){
this.levelText.update();
}
}
display(){
if (!this.ready){
return;
}
checkViewPort();
this.background.display();
translate(-viewPort.x, -viewPort.y);
for (let b of this.bricks){
b.display(this.world);
}
if (this.showHint){
this.goal.hint(this.player, this.world);
}
this.goal.display();
this.player.display();
translate(viewPort.x, viewPort.y);
if (this.showMap){
this.iconMap.display(this.player, this.goal, this.world);
}
if (this.levelText.isActive()){
this.levelText.display();
}
}
nextLevel(){
this.level++;
this.goal.setBrick(random(this.bricks));
this.player.maxVelocityX = int(values.maxVelocityX[this.level - 1]);
this.player.jumpVelocity = int(values.jumpVelocity[this.level - 1]);
this.levelText = new LevelText(this.level);
}
goalReached(){
if (this.level < this.maxLevel) this.nextLevel();
else this.won();
}
won(){
this.isWon = true;
this.pause();
new Sound(Sound.Won()).play();
new Message(Message.Won()).display();
}
lost(){
this.pause();
new Sound(Sound.Lost()).play();
new Message(Message.Lost()).display();
}
pause(){
this.paused = true;
this.pauseMusic();
}
resume(){
this.paused = false;
this.unpauseMusic();
}
toggleRun(){
if (this.paused) this.resume();
else this.pause();
}
toggleMap(){
this.showMap = !this.showMap;
}
toggleHint(){
this.showHint = !this.showHint;
}
getMusics(){
return audio.music.game;
}
playMusic(){
let musics = this.getMusics();
this.songIndex = int(random(musics.length));
musics[this.songIndex].play();
updateVolume();
let self = this;
setTimeout(function(){
musics[self.songIndex].onended(function(){
if (!musics[self.songIndex].isPaused()) self.playMusic();
});
});
}
pauseMusic(){
let musics = this.getMusics();
if (musics[this.songIndex].isPaused()) return;
musics[this.songIndex].pause();
}
unpauseMusic(){
let musics = this.getMusics();
if (musics[this.songIndex].isPlaying()) return;
musics[this.songIndex].play();
updateVolume();
}
}
function checkViewPort(){
//Between 0.5 and 1
let limit = 0.5;
let player = game.player,
world = game.world;
if (player.pos.x > width * limit + viewPort.x && viewPort.x + width < world.pos.x + world.dim.x) viewPort.x = player.pos.x - width * limit;
if (player.pos.x < width * (1 - limit) + viewPort.x && viewPort.x > world.pos.x) viewPort.x = player.pos.x - width * (1 - limit);
if (player.pos.y > height * limit + viewPort.y && viewPort.y + height < world.pos.y + world.dim.y) viewPort.y = player.pos.y - height * limit;
if (player.pos.y < height * (1 - limit) + viewPort.y && viewPort.y > world.pos.y) viewPort.y = player.pos.y - height * (1 - limit);
}
function loadNewGame(){
game = new Game();
game.load();
}
function requestNewGame(){
game.pause();
new Message(Message.New()).display();
}

@ -0,0 +1,90 @@
"use strict"
class Goal{
constructor(){
this.dim = createVector(200, 375);
}
setBrick(b){
this.pos = createVector(b.pos.x + b.dim.x / 2, b.pos.y);
this.vel = b.vel;
this.brick = b;
}
update(){
let b = this.brick;
this.pos = createVector(b.pos.x + b.dim.x / 2, b.pos.y);
}
display(){
this.show();
}
show(){
fill(colors.goal.main);
noStroke();
rect(this.pos.x - this.dim.x / 2, this.pos.y - this.dim.y * 0.76, this.dim.x, this.dim.y * 0.76);
triangle(this.pos.x - this.dim.x / 2, this.pos.y - this.dim.y * 0.75, this.pos.x, this.pos.y - this.dim.y, this.pos.x + this.dim.x / 2, this.pos.y - this.dim.y * 0.75);
stroke(colors.goal.roof);
strokeWeight(20);
line(this.pos.x - this.dim.x / 2 - this.dim.x * 0.1, this.pos.y - this.dim.y * 0.75 + this.dim.x * 0.1, this.pos.x, this.pos.y - this.dim.y);
line(this.pos.x + this.dim.x / 2 + this.dim.x * 0.1, this.pos.y - this.dim.y * 0.75 + this.dim.x * 0.1, this.pos.x, this.pos.y - this.dim.y);
fill(colors.goal.hole);
noStroke();
rect(this.pos.x - this.dim.x / 3, this.pos.y - this.dim.y * 0.41, this.dim.x * 2 / 3, this.dim.y * 0.41);
arc(this.pos.x, this.pos.y - this.dim.y * 0.4, this.dim.x * 2 / 3, this.dim.x * 2 / 3, PI, TWO_PI);
}
contains(p){
if (p.pos.x + p.radius < this.pos.x + this.dim.x / 2 && p.pos.x - p.radius > this.pos.x - this.dim.x / 2
&& p.pos.y - p.radius > this.pos.y - this.dim.y && p.pos.y + p.radius <= this.pos.y){
return true;
}
return false;
}
hint(player, world){
let pl = player.pos.copy();
let gl = this.pos.copy();
let v = p5.Vector.sub(gl, pl).normalize();
let d = dist(pl.x, pl.y, gl.x, gl.y);
while (true){
v.setMag(v.mag() + 1);
if (pl.x + v.x > viewPort.x + width - 20
|| pl.x + v.x < viewPort.x + 20
|| pl.y + v.y > viewPort.y + height - 20
|| pl.y + v.y < viewPort.y + 20){
break;
}
}
if (v.mag() > d) return;
let pos = p5.Vector.add(pl, v);
//green starts at a distance of worldWidth / 3
let r = d / (world.dim.x / 3) * 255;
//Arrow
push();
translate(pos.x, pos.y);
rotate(v.heading());
strokeWeight(3);
stroke(0);
fill(r, 255 - r, 0);
//Arrow
beginShape();
vertex(0, 0);
vertex(-10, 10);
vertex(-10, 5);
vertex(-30, 5);
vertex(-30, -5);
vertex(-10, -5);
vertex(-10, -10);
vertex(0, 0);
endShape();
pop();
}
}

@ -0,0 +1,73 @@
"use strict"
function prepareInterface(){
globalCursor = {
isActive: true,
standStillTime: 0,
//seconds not moving cursor -> it disappears
timeLimit: int(values.cursorTimeLimit) / 1000
}
$("#messageWrapper").hide();
$("#menuOpener").click(function(){
toggleMenu($(this));
});
$("button, input").click(function(){
$(this).blur();
updateMenu();
});
}
function toggleMenu(opener){
menuOpen = !menuOpen;
let menuAnimationTime = int(values.menuAnimationTime),
openerAnimationTime = int(values.openerAnimationTime);
let menuLeft;
if ($("#menu").css("left") == "0px") menuLeft = -$("#menu").outerWidth();
else menuLeft = 0;
let menuBorder = abs(menuLeft);
opener.animate({"left": menuBorder - opener.outerWidth()}, openerAnimationTime, function(){
opener.hide();
$("#menu").show();
$("#menu").animate({"left": menuLeft}, menuAnimationTime, function(){
menuBorder = int($(this).css("left").substring(0, $(this).css("left").length - 2)) + $(this).outerWidth();
opener.show();
opener.css("left", menuBorder - opener.outerWidth());
opener.animate({"left": menuBorder}, openerAnimationTime, function(){
//Animation ended successfully
});
});
});
}
function toggleFullscreen(htmlElement){
let fs = fullscreen();
fullscreen(!fs);
$(htmlElement).html(fs ? "Fullscreen: Off" : "Fullscreen: On");
}
function checkCursor(){
globalCursor.standStillTime += 1 / frameRate();
if (globalCursor.isActive && globalCursor.standStillTime > globalCursor.timeLimit){
globalCursor.isActive = false;
noCursor();
}
if (!globalCursor.isActive && globalCursor.standStillTime < globalCursor.timeLimit){
globalCursor.isActive = true;
cursor(ARROW);
}
}
function updateMenu(){
let val = [
["run", game.paused ? "Resume" : "Pause"],
["restart", "Restart"],
["new", "New Game"],
["map", game.showMap ? "Map: On" : "Map: Off"],
["hint", game.showHint ? "Hint: On" : "Hint: Off"],
["sound", audioOptions.sound ? "Sound: On" : "Sound: Off"],
["music", audioOptions.music ? "Music: On" : "Music: Off"]
];
for (let v of val) $("#" + v[0]).html(v[1]);
}

@ -0,0 +1,39 @@
class LevelText{
constructor(level){
this.text = "Level " + level;
this.pos = createVector(width / 2, height - 50);
this.vel = createVector(0, -0.1);
this.acc = createVector(0, -5);
this.dim = createVector(textWidth(this.text), 50);
}
isActive(){
return this.pos.y > -this.dim.y;
}
display(){
push();
textSize(this.dim.y);
fill(255, 0, 0);
stroke(0);
strokeWeight(5);
textAlign(CENTER);
translate(this.pos.x, this.pos.y);
scale(2, 2 - (this.vel.y / 50));
text(this.text, 0, 0);
pop();
}
update(){
this.vel.add(this.acc);
this.pos.add(this.vel);
if (this.pos.y < height / 2 && this.acc.y != 8 && this.acc.y != -0.25){
this.acc.y = 8;
}
if (this.vel.y > 0){
this.acc.y = -0.25;
}
}
}

@ -0,0 +1,179 @@
"use strict"
class Loader{
constructor(type, title, loadedCallback){
this.type = type;
this.title = title;
this.loadedCallback = loadedCallback;
this.spinnerAngle = 0;
$("#menu, #menuOpener").hide();
}
static Bar(){
return 0;
}
static Circle(){
return 1;
}
updateProgress(progress, infoText){
this.progress = progress > 1 ? 1 : progress;
this.radianAngle = progress * TWO_PI;
this.strokeWidth = progress * 8 + 2;
this.infoText = infoText;
}
update(){
this.display(this.getColors());
this.spinnerAngle += PI / 16;
this.spinnerAngle %= TWO_PI;
if (this.progress === 1 && this.loadedCallback){
this.loadedCallback();
}
}
display(c){
background(c.background);
switch (this.type){
case Loader.Bar():
this.bar(c);
break;
case Loader.Circle():
this.circle(c);
break;
}
}
bar(c){
let w = width * 0.6,
h = 30;
let x = (width - w) / 2,
y = (height - h) / 2;
this.displayBar(x, y, w, h, c);
this.displaySpinner(width / 2, height * 3 / 4, 30, c.spinner);
fill(c.text.fill);
stroke(c.text.stroke);
strokeWeight(5);
textAlign(CENTER, CENTER);
textSize(height / 32);
text(str(this.title), width / 2, height / 8);
strokeWeight(2);
textSize(h / 2);
text(str(this.infoText), width / 2, y - h * 1.5);
strokeWeight(5);
stroke(c.progress);
textSize(height / 16);
text(int(this.progress * 100) + "%", width / 2, height * 5 / 8);
}
circle(c){
let size = min(width, height) / 2;
size = size < 100 ? 100 : size;
let posX = width / 2;
let posY = height / 2;
this.displayCircle(posX, posY, size, c);
this.displaySpinner(posX, height * 7 / 8, 30, c.spinner);
fill(c.text.fill);
stroke(c.text.stroke);
strokeWeight(5);
textSize(height / 32);
text(this.title, posX, height / 8);
strokeWeight(2);
textSize(15);
text(str(this.infoText), width / 2, posY + size / 2 + 30);
stroke(c.progress);
strokeWeight(5);
textSize(height / 16);
text(str(int(this.progress * 100)) + "%", posX, posY);
}
displayBar(x, y, w, h, c){
noFill();
stroke(0);
strokeWeight(5);
rect(x, y, w, h, h / 4);
w -= (1 - this.progress) * w;
noStroke();
fill(c.progress);
rect(x + 1, y + 1, w - 2 < 0 ? w : w - 2, h - 2, h / 4);
}
displayCircle(posX, posY, size, c){
noFill();
for (let i = 0; i < 3; i++){
stroke(i == 1 ? c.progress: 0);
strokeWeight(i == 1 ? 5 : 2);
if (this.radianAngle < TWO_PI && i == 1){
arc(posX, posY, size, size, -HALF_PI, this.radianAngle - HALF_PI);
} else {
ellipse(posX, posY, size + (i - 1) * 10);
}
}
}
displaySpinner(x, y, r, c){
let c2 = c;
colorMode(HSB);
let c1 = color(hue(c2), saturation(c2), brightness(c2) / 5);
colorMode(RGB);
let length = PI + HALF_PI;
for (let i = this.spinnerAngle; i < this.spinnerAngle + length; i += PI / 16){
strokeWeight((i - this.spinnerAngle) / length * 10);
//stroke(lerpColor(c1, c2, (i - this.spinnerAngle) / length));
stroke(c2);
let x1 = sin(i) * r + x,
y1 = cos(i) * r + y,
x2 = sin(i + PI / 16) * r + x,
y2 = cos(i + PI / 16) * r + y;
line(x1, y1, x2, y2);
}
}
getColors(){
return {
background: color(colors.loader.background),
progress: color(colors.loader.finished),
spinner: color(colors.loader.spinner),
text: {
fill: color(colors.loader.text.fill),
stroke: color(colors.loader.text.stroke)
},
};
}
destroy(){
$("#loader").html("");
$("#menu, #menuOpener").show();
loader = null;
}
}
function drawGradient(x, y, w, h, c1, c2, r){
strokeWeight(1);
for (let i = x; i <= x + w; i++){
let inter = map(i, x, x + w, 0, 1);
let c = lerpColor(c1, c2, inter);
let b = r - pow(r * r - (i - x - r) * (i - x - r), 0.5);
b = (i - x > r && i < x + w - r) ? 0 : b;
b = i > x + w - r ? r - pow(r * r - (i - x - w + r) * (i - x - w + r), 0.5) : b;
stroke(c);
line(i, y + b + 1, i, y + h - b - 2);
}
}

@ -0,0 +1,46 @@
"use strict"
class Map{
constructor(w, h){
let x = width - w - 20;
let y = height - h - 20;
this.pos = createVector(x, y);
this.dim = createVector(w, h);
this.bricks = [];
}
display(player, goal, world){
this.show(player, goal, world);
}
show(player, goal, world){
let x = width - this.dim.x - 20;
let y = height - this.dim.y - 20;
this.pos = createVector(x, y);
fill(colors.map.background.fill);
stroke(colors.map.background.stroke);
strokeWeight(10);
rect(this.pos.x, this.pos.y, this.dim.x, this.dim.y, this.dim.x * 0.05);
let goalX = map(goal.pos.x, 0, world.dim.x, this.pos.x + 10, this.pos.x + this.dim.x - 10),
goalY = map(goal.pos.y, 0, world.dim.y, this.pos.y + 10, this.pos.y + this.dim.y - 10);
stroke(colors.goal.main);
point(goalX, goalY);
let playerX = map(player.pos.x, 0, world.dim.x, this.pos.x + 10, this.pos.x + this.dim.x - 10),
playerY = map(player.pos.y, 0, world.dim.y, this.pos.y + 10, this.pos.y + this.dim.y - 10);
stroke(player.color);
point(playerX, playerY);
let flagH = 30,
flagW = 15;
stroke(0);
strokeWeight(2);
line(goalX, goalY, goalX, goalY - flagH);
fill(255, 0, 0);
rect(goalX, goalY - flagH + 2, flagW, flagH * 0.3);
}
}

@ -0,0 +1,83 @@
"use strict"
class Message{
constructor(type){
let set = settings.messages[type];
this.getFullHTML(set);
}
static Won(){return "won";}
static Lost(){return "lost";}
static New(){return "newGame";}
static Credits(){return "credits";}
getFullHTML(set){
let self = this;
this.html = set.html;
this.styles = set.styles;
this.buttons = [];
for (let b of set.buttons){
let htmlButton = $("<button></button>");
htmlButton.text(b.text);
htmlButton.css(b.styles);
htmlButton.click(function(){self.buttonClicked(b);});
this.buttons.push(htmlButton);
}
}
buttonClicked(setButton){
eval(setButton.onclick);
this.destroy(this);
}
display(){
let pane = $("<div></div>");
pane.css(this.styles);
pane.append(this.html);
for (let b of this.buttons) pane.append(b);
pane.attr("id", "message");
$("#messageWrapper").append(pane);
$("#messageWrapper").show();
}
destroy(obj){
$("#messageWrapper").hide();
$("#messageWrapper").html("");
obj = null;
}
}
function prepareCredits(){
credits = credits.credits;
let htmlCredits = $("<div></div>");
htmlCredits.attr("id", "creditsTableWrapper");
let table = "<table id=\"creditsTable\" align=\"center\">";
table += "<tr>";
for (let prop in credits[0]){
table += "<th>" + prop.capitalize() + "</th>";
}
table += "</tr>";
for (let c of credits){
let section = "<tr>";
for (let prop in c){
let link = {open: "", close: ""};
if (prop === "link"){
link.open = "<a href=\"" + c[prop] + "\" target=\"_blank\">";
link.close = "</a>";
}
section += "<td>" + link.open + c[prop] + link.close + "</td>";
}
section += "</tr>";
table += section;
}
table += "</table>";
htmlCredits.append($(table));
settings.messages.credits.html = htmlCredits;
}

@ -0,0 +1,122 @@
"use strict"
class Tree{
constructor(brick){
this.pos = brick.pos;
this.dim = createVector(random(10, 30), random(100, 200));
this.current = createVector(0, 0);
this.dispoX = random(brick.dim.x - 40) + 20;
this.colorSetup();
}
show(){
//Wood
fill(this.color.wood);
rect(this.pos.x + this.dispoX, this.pos.y - this.dim.y, this.dim.x, this.dim.y);
//Leaf
fill(this.color.leaf);
for (let i = 0; i <= TWO_PI; i += PI / 4){
let x = this.dispoX + this.pos.x + this.dim.x / 2 + this.dim.x * 2 * sin(i);
let y = this.pos.y - this.dim.y + this.dim.x * 2 * cos(i);
ellipse(x, y, this.dim.x * 3);
}
ellipse(this.dispoX + this.pos.x + this.dim.x / 2, this.pos.y - this.dim.y, this.dim.x * 3);
}
colorSetup(){
let l = color(colors.brick.tree.leaf),
w = color(colors.brick.tree.wood);
colorMode(HSB);
let leaf = color(hue(l), saturation(l), brightness(l) + random(-10, 10)),
wood = color(hue(w), saturation(w), brightness(w) + random(-10, 10));
colorMode(RGB);
this.color = {
leaf: leaf,
wood: wood
};
}
}
class Grass{
constructor(parent, dispoX){
this.pos = parent.pos;
this.dispoX = dispoX;
this.positions = [];
this.flower = ranBool() ? new Flower(this) : null;
for (let i = HALF_PI + 0.25; i < HALF_PI + PI - 0.25; i += random(PI / 8, PI / 16)) this.positions.push(createVector(sin(i) * 15, cos(i) * 25));
}
show(){
if (this.flower){
this.flower.show();
}
fill(colors.brick.grass);
for (let p of this.positions){
let x1 = this.pos.x + this.dispoX + p.x;
let x2 = this.pos.x + this.dispoX + p.x * 0.5;
let y = this.pos.y + p.y;
triangle(x1, y, this.pos.x + this.dispoX, this.pos.y, x2, y);
}
}
}
class Flower{
constructor(grass){
this.pos = grass.pos;
this.dim = createVector(3, random(25, 50));
this.dispoX = grass.dispoX;
this.colorSetup();
let cr = random(2, 5);
this.radius = {
center: cr,
petal: cr + random(2, 4)
};
this.petals = [];
for (let i = 0; i < TWO_PI; i += PI / 2){
let x = this.dispoX + sin(i) * this.radius.center * 2;
let y = cos(i) * this.radius.center * 2;
this.petals.push(createVector(x, y));
}
}
show(){
//Haulm
strokeWeight(this.dim.x);
stroke(colors.brick.flower.haulm);
line(this.pos.x + this.dispoX, this.pos.y, this.pos.x + this.dispoX, this.pos.y - this.dim.y);
//Center
noStroke();
fill(this.color.center);
ellipse(this.pos.x + this.dispoX, this.pos.y - this.dim.y, this.radius.center * 2);
//Petals
fill(this.color.petal);
for (let p of this.petals){
ellipse(p.x + this.pos.x, p.y + this.pos.y - this.dim.y, this.radius.petal * 2);
}
}
colorSetup(){
let c = color(colors.brick.flower.center),
p = color(colors.brick.flower.petal);
colorMode(HSB);
let center = color(int(random(360)), saturation(c), brightness(c));
let petal = color(int(random(360)), saturation(p), brightness(p));
colorMode(RGB);
this.color = {
center: center,
petal: petal
};
}
}

@ -0,0 +1,153 @@
"use strict"
class Player{
constructor(x, y){
this.pos = createVector(x, y);
this.vel = createVector(0, 0);
this.acc = createVector(0, 0.25);
this.radius = 50;
this.brick = null;
this.colorSetup();
}
update(){
this.move();
}
display(){
this.show();
}
move(){
if (this.brick){
this.vel.y = 0;
this.pos.add(this.brick.vel);
this.pos.y = this.brick.pos.y - this.radius;
}
this.pos.add(this.vel);
this.vel.add(this.acc);
this.vel.x *= 0.95;
let limit = this.maxVelocityX;
if (this.vel.x < -limit) this.vel.x = -limit;
if (this.vel.x > limit) this.vel.x = limit;
}
show(){
stroke(red(this.color) * 0.5, green(this.color) * 0.5, blue(this.color) * 0.5);
strokeWeight(1);
//Body
fill(this.color);
ellipse(this.pos.x, this.pos.y, this.radius * 2);
//Eyes
let radius = this.radius * 0.3;
let dispoX = 1 / (1 + pow(0.7, this.vel.x)) - 0.5;
let dispoY = 1 / (1 + pow(0.7, this.vel.y)) - 0.5;
let outerDispoX = dispoX * this.radius / 2;
let outerDispoY = dispoY * this.radius / 2;
let innerDispoX = outerDispoX + dispoX * radius / 2;
let innerDispoY = outerDispoY + dispoY * radius / 2;
fill(colors.player.eyes.outer);
ellipse(this.pos.x + radius + outerDispoX, this.pos.y - radius + outerDispoY, radius, radius * 4/3);
ellipse(this.pos.x - radius + outerDispoX, this.pos.y - radius + outerDispoY, radius, radius * 4/3);
fill(colors.player.eyes.inner);
ellipse(this.pos.x + radius + innerDispoX, this.pos.y - radius + innerDispoY, radius / 2, radius * 2/3);
ellipse(this.pos.x - radius + innerDispoX, this.pos.y - radius + innerDispoY, radius / 2, radius * 2/3);
//Mouth
let rotation = dispoX / 2;
fill(red(this.color) / 3, green(this.color) / 3, blue(this.color) / 3);
arc(this.pos.x, this.pos.y + this.radius * 0.2 + dispoY * this.radius / 2, this.radius, this.radius * 0.8, PI / 16 + rotation, PI - PI / 16 + rotation, CHORD);
}
collision(bricks, world){
//Bricks
if (!this.touches(this.brick)){
let brick = null;
for (let b of bricks){
if (this.touches(b)){
brick = b;
break;
} else brick = null;
}
this.brick = brick;
}
let trashHold = 10;
//World borders
if (this.pos.x - this.radius < world.pos.x) this.pos.x = world.pos.x + this.radius;
if (this.pos.x + this.radius > world.pos.x + world.dim.x) this.pos.x = world.pos.x + world.dim.x - this.radius;
if (this.pos.y - this.radius < world.pos.y){
this.pos.y = world.pos.y + this.radius;
this.vel.y *= -1;
}
if (this.pos.y - this.radius > world.pos.y + world.dim.y) game.lost();
}
touches(object){
if (!object) return false;
let hitbox = object.getHitbox();
if (object instanceof Brick){
if (this.pos.x + this.radius / 2 > hitbox.pos.x && this.pos.x - this.radius / 2 < hitbox.pos.x + hitbox.dim.x &&
(this.pos.y + this.radius <= hitbox.pos.y && (this.pos.y + this.radius + this.vel.y >= hitbox.pos.y + hitbox.vel.y
|| this.pos.y + this.radius + this.vel.y >= hitbox.pos.y))){
return true;
}
}
if (object instanceof Coin){
let distX = abs(this.pos.x - (hitbox.pos.x + hitbox.dim.x / 2));
let distY = abs(this.pos.y - (hitbox.pos.y + hitbox.dim.y / 2));
if ((distX <= (hitbox.dim.x / 2) || distY <= (hitbox.dim.y / 2))
&& distX < (hitbox.dim.x / 2 + this.radius)
&& distY < (hitbox.dim.y / 2 + this.radius)) return true;
let dx = distX - hitbox.dim.x / 2;
let dy = distY - hitbox.dim.y / 2;
if (dx * dx + dy * dy <= this.radius * this.radius) return true;
}
return false;
}
walk(d){
this.acc.x = d;
}
break(){
this.acc.x = 0;
}
jump(){
if (!this.brick) return;
this.vel.y = -abs(this.vel.x * 0.3) - this.jumpVelocity + this.brick.vel.y;
this.brick = null;
new Sound(Sound.Jump()).play();
}
fall(d){
this.acc.y += d * 0.5;
}
setColor(color){
this.color = color;
}
colorSetup(){
let h = int(random(360));
h = floor(h / 60) * 60;
let c = color(colors.player.body);
colorMode(HSB);
this.color = color(h, saturation(c), brightness(c));
colorMode(RGB);
}
}

@ -0,0 +1,110 @@
"use strict"
let audioOptions = {
sound: true,
music: true
};
class Sound{
constructor(type){
this.sound = random(audio.sound[type]);
}
static Won(){return "won";}
static Lost(){return "lost";}
static Coin(){return "coin";}
static Jump(){return "jump";}
play(){
this.sound.play();
updateVolume();
}
}
function toggleSounds(){
audioOptions.sound = !audioOptions.sound;
$("#soundVolume").prop("disabled", !audioOptions.sound);
updateVolume();
}
function toggleMusic(){
audioOptions.music = !audioOptions.music;
$("#musicVolume").prop("disabled", !audioOptions.music);
updateVolume();
}
function updateVolume(){
let soundVolume = $("#soundVolume").val() / 100,
musicVolume = $("#musicVolume").val() / 100;
soundVolume = !audioOptions.sound ? 0 : soundVolume;
musicVolume = !audioOptions.music ? 0 : musicVolume;
setVolume("sound", soundVolume);
setVolume("music", musicVolume);
}
function getVolume(type){
let val = $("#" + type + "Volume").val();
return val / 100;
}
function setVolume(key, volume){
for (let prop in audio){
if (prop === key){
for (let type in audio[prop]){
let audios = audio[prop][type];
for (let audio of audios){
audio.setVolume(volume);
}
}
}
}
}
function resetMusics(){
for (let type in audio.music){
let audios = audio.music[type];
for (let audio of audios){
audio.jump();
audio.pause();
}
}
}
function loadAudioFiles(loadedCallback){
soundFormats("mp3", "wav");
audio = JSON.parse(JSON.stringify(settings.audio));
loader = new Loader(Loader.Circle(), "Loading Assets...", loadedCallback);
let count = 0, index = 0;
for (let prop in audio){
let type = audio[prop];
for (let key in type){
let files = type[key];
for (let file of files){
count++;
}
}
}
for (let prop in audio){
let type = audio[prop];
for (let key in type){
let files = type[key];
for (let file of files){
loadSound(file, updateProgress);
function updateProgress(song){
files[files.indexOf(file)] = song;
index++;
loader.updateProgress(index / count, song.file);
}
}
}
}
}
function audioFilesLoaded(){
updateVolume();
loadNewGame();
}

@ -0,0 +1,79 @@
"use strict"
function keyPressed(){
if (!game) return false;
if (!game.ready) return false;
switch(keyCode){
case LEFT_ARROW:
game.player.walk(-1);
break;
case RIGHT_ARROW:
game.player.walk(1);
break;
case UP_ARROW:
game.player.jump();
break;
case DOWN_ARROW:
game.player.fall(1);
break;
case 68: //D
debug = !debug;
break;
case 78: //N
loadNewGame();
break;
case 76: //L
game.lost();
break;
case 27: //ESC
case 9: //TAB
toggleMenu($("#menuOpener"));
break;
case 32: //Spacebar
game.toggleRun();
break;
}
return false;
}
function keyReleased(){
if (!game) return false;
if (!game.ready) return true;
switch(keyCode){
case LEFT_ARROW:
if (!keyIsDown(RIGHT_ARROW)) game.player.break();
break;
case RIGHT_ARROW:
if (!keyIsDown(LEFT_ARROW)) game.player.break();
break;
case DOWN_ARROW:
game.player.fall(-1);
break;
}
}
function mouseMoved(){
globalCursor ? globalCursor.standStillTime = 0 : null;
}
function mouseDragged(){
}
function mousePressed(){
}
function mouseReleased(){
}
window.onresize = function(){
let i = 0;
function resize(){
resizeCanvas($("#canvasHolder").outerWidth(), $("#canvasHolder").outerHeight(), true);
i++;
if (i < 5) window.setTimeout(resize, 0);
}
resize();
}

@ -0,0 +1,678 @@
let TOP = 1,
RIGHT = 2,
BOTTOM = 3,
LEFT = 4,
TOP_RIGHT = 5,
BOTTOM_RIGHT = 6,
BOTTOM_LEFT = 7,
TOP_LEFT = 8;
function collisionDetection(obj0, obj1){
let sp = strokePadding;
if (sp == null) sp = 0;
if (obj0.isEllipse && obj1.isRectangle){
//Ball
let b = obj0;
//Rectangle
let r = obj1;
for (let i = 0; i < TWO_PI; i += PI / 32){
/* Check every borderpoint of the ball beginning
at the top in clock direction up to top again */
// Ball Center X
let bcx = b.x;
// Ball Center Y
let bcy = b.y;
// Ball Border X
let bbx = b.x + sin(i) * b.r;
// Ball Border Y inverted because Y = 0 is the TOP of the screen
let bby = b.y - cos(i) * b.r;
// Rectangle Width
let rW = r.width + 2 * sp;
// Rectangle Height
let rH = r.height + 2 * sp;
// Rectangle Border X
let rX = r.x - sp;
// Rectangle Border Y
let rY = r.y - sp;
// Objects touch
if (bbx > rX && bbx < rX + rW
&& bby > rY && bby < rY + rH){
// STRAIGHT FACES //
//Top/Bottom touch
if (bcx > rX && bcx < rX + rW){
//Top touch
if (b.v.y > 0) return {isTouching: true, location: TOP};
//Bottom touch
if (b.v.y < 0) return {isTouching: true, location: BOTTOM};
}
//Left/Right touch
if (bcy > rY && bcy < rY + rH){
//Left touch
if (b.v.x > 0) return {isTouching: true, location: LEFT};
//Right touch
if (b.v.x < 0) return {isTouching: true, location: RIGHT};
}
// CORNERS //
// BOTTOM Left/Right
if (i > 0 && i <= PI / 2) return {isTouching: true, location: BOTTOM_LEFT};
//LEFT Bottom/Top
if (i > PI / 2 && i <= PI) return {isTouching: true, location: TOP_LEFT};
//TOP Left/Right
if (i > PI && i <= PI + PI / 2) return {isTouching: true, location: TOP_RIGHT};
//RIGHT Bottom/Top
if (i > PI + PI / 2 && i <= TWO_PI) return {isTouching: true, location: BOTTOM_RIGHT};
}
}
}
if (obj0.isEllipse && obj1.isEllipse){
//Ball 1
let b1 = obj0;
//Ball 2
let b2 = obj1;
//Balls are close to each other
if (b1.x + b1.r > b2.x - b2.r
&& b1.x - b1.r < b2.x + b2.r
&& b1.y + b1.r > b2.y - b2.r
&& b1.y - b1.r < b2.y + b2.r){
let distance = sqrt(pow(b1.x - b2.x, 2) + pow(b1.y - b2.y, 2));
if (distance < b1.r + b2.r) return {isTouching: true};
}
}
return {isTouching: false, location: 0};
}
function performCollision(obj0, obj1, collision){
if (obj0.isEllipse){
let ball = obj0;
//Ball collides with frameborder
if (obj1.isFrameborder){
switch (collision.location){
case BOTTOM:
ball.v.y *= -1;
break;
case LEFT:
case RIGHT:
ball.v.x *= -1;
break;
}
if (testMode && collision.location == TOP) ball.v.y *= -1;
ball.move();
}
//Ball collides with any brick
if (obj1.isBrick){
let cornerX, cornerY;
switch (collision.location){
case TOP:
case BOTTOM:
ball.v.y *= -1;
ball.move();
return;
case LEFT:
case RIGHT:
ball.v.x *= -1;
ball.move();
return;
case TOP_LEFT:
cornerX = obj1.x;
cornerY = obj1.y;
break;
case TOP_RIGHT:
cornerX = obj1.x + obj1.width;
cornerY = obj1.y;
break;
case BOTTOM_LEFT:
cornerX = obj1.x;
cornerY = obj1.y + obj1.height;
break;
case BOTTOM_RIGHT:
cornerX = obj1.x + obj1.width;
cornerY = obj1.y + obj1.height;
break;
}
let nx = ball.x - cornerX;
let ny = ball.y - cornerY;
let length = sqrt(nx * nx + ny * ny);
nx /= length;
ny /= length;
let projection = ball.v.x * nx + ball.v.y * ny;
ball.v.x = ball.v.x - 2 * projection * nx;
ball.v.y = ball.v.y - 2 * projection * ny;
ball.move();
}
//Ball collides with paddleboard
if (obj1.isPaddle){
let cornerX, cornerY;
switch (collision.location){
case TOP:
case TOP_LEFT:
case TOP_RIGHT:
ball.v.x = ball.calcVelocityX(obj1, ball.v.x);
ball.v.y = -ball.calcVelocityY();
ball.move();
return;
case LEFT:
case RIGHT:
ball.v.x *= -1;
ball.move();
return;
case BOTTOM_LEFT:
cornerX = obj1.x;
cornerY = obj1.y + obj1.height;
break;
case BOTTOM_RIGHT:
cornerX = obj1.x + obj1.width;
cornerY = obj1.y + obj1.height;
break;
}
let nx = ball.x - cornerX;
let ny = ball.y - cornerY;
let length = sqrt(nx * nx + ny * ny);
nx /= length;
ny /= length;
let projection = ball.v.x * nx + ball.v.y * ny;
ball.v.x = ball.v.x - 2 * projection * nx;
ball.v.y = ball.v.y - 2 * projection * ny;
ball.move();
}
//Ball collides with other ball
if (obj1.isEllipse){
//Ball 1
let b1 = obj0;
//Ball 2
let b2 = obj1;
//Set mass equal to radius of each ball
b1.mass = b1.r;
b2.mass = b2.r;
//Colliding angle of ball 1 to ball 2 using arc tan of both x and y differences
let collisionAngle = atan2((b2.y - b1.y), (b2.x - b1.x));
//Converting directions of velocity vector of balls into angles
let d1 = atan2(b1.v.y, b1.v.x);
let d2 = atan2(b2.v.y, b2.v.x);
//Ignoring mass effects new velocites are simply magnitude multiplied with value of angle differences
let newXspeed1 = b1.v.mag * cos(d1 - collisionAngle);
let newYspeed1 = b1.v.mag * sin(d1 - collisionAngle);
let newXspeed2 = b2.v.mag * cos(d2 - collisionAngle);
let newYspeed2 = b2.v.mag * sin(d2 - collisionAngle);
//According to the principle of linear momentum, kinetic energy stays the same after collision, so velocities are now related to masses
let finalXspeed1 = ((b1.mass - b2.mass) * newXspeed1 + b2.mass * 2 * newXspeed2) / (b1.mass + b2.mass);
let finalYspeed1 = newYspeed1;
let finalXspeed2 = (b1.mass * 2 * newXspeed1 + (b2.mass - b1.mass) * newXspeed2) / (b1.mass + b2.mass);
let finalYspeed2 = newYspeed2;
//Values of collisionAngle
let cosAngle = cos(collisionAngle);
let sinAngle = sin(collisionAngle);
//To also keep velocites relative to pure collisionAngle, subtract sin*x from cos*x and add sin*y to cos*y because coordSystem has y = 0 on the top
let u1x = cosAngle * finalXspeed1 - sinAngle * finalYspeed1;
let u1y = sinAngle * finalXspeed1 + cosAngle * finalYspeed1;
let u2x = cosAngle * finalXspeed2 - sinAngle * finalYspeed2;
let u2y = sinAngle * finalXspeed2 + cosAngle * finalYspeed2;
//Set new velocities to both balls
b1.v.x = u1x;
b1.v.y = u1y;
b2.v.x = u2x;
b2.v.y = u2y;
//Update magnitude
b1.v.mag = sqrt(pow(b1.v.x, 2) + pow(b1.v.y, 2));
b2.v.mag = sqrt(pow(b2.v.x, 2) + pow(b2.v.y, 2));
//Move balls one vx/vy forward to avoid double inverting collision detection
b1.x += b1.v.x;
b1.y += b1.v.y;
b2.x += b2.v.x;
b2.y += b2.v.y;
}
}
}
function toTimeString(time, hoursWanted){
time = floor(time / 10);
let hs = String(floor(time % 100));
let fs = String(floor((time / 100) % 60));
if (hoursWanted){
let min = String(floor(((time / 100) / 60) % 60));
let hr = String(floor(((time / 100) / 60) / 60));
if (hs.length < 2) hs = "0" + hs;
if (fs.length < 2) fs = "0" + fs;
if (min.length < 2) min = "0" + min;
if (hr.length < 2) hr = "0" + hr;
let timeString = hr + ":" + min + ":" + fs + ":" + hs;
} else {
let min = String(floor(((time / 100) / 60) % 60));
if (hs.length < 2) hs = "0" + hs;
if (fs.length < 2) fs = "0" + fs;
if (min.length < 2) min = "0" + min;
let timeString = min + ":" + fs + ":" + hs;
}
return timeString;
}
function setCookie(name, value, years){
let expires = "";
if (years){
let date = new Date();
date.setTime(date.getTime() + (years * 365 * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + value + expires + "; path=/";
}
function getCookie(name){
let nameEQ = name + "=";
let ca = document.cookie.split(';');
for (let i = 0; i < ca.length; i++){
let c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
function deleteCookies(){
for (let i = 0; i < arguments.length; i++) setCookie(arguments[i], "", -1);
}
function deleteAllCookies(){
let cookies = document.cookie.split(";");
for (let i = 0; i < cookies.length; i++) deleteCookies(cookies[i].split("=")[0]);
}
Array.prototype.shuffle = function(){
let currentIndex = this.length, temporaryValue, randomIndex;
while (0 != currentIndex){
randomIndex = floor(random() * currentIndex);
currentIndex -= 1;
temporaryValue = this[currentIndex];
this[currentIndex] = this[randomIndex];
this[randomIndex] = temporaryValue;
}
}
Array.prototype.clone = function(){
return this.slice(0);
};
//Divides big Array into big multidimensional Array
Array.prototype.partitiate = function(dimensions){
if (dimensions == 0) return this;
let parts = [];
while(this.length) parts.push(this.splice(0, round(pow(this.length, 1 / (1 + 1 / dimensions)))).partitiate(dimensions - 1));
return parts;
}
String.prototype.isValidHEX = function(){
return /(^#[0-9A-Fa-f]{6}$)|(^#[0-9A-Fa-f]{3}$)/i.test(this);
}
String.prototype.capitalize = function(){
return this.charAt(0).toUpperCase() + this.slice(1);
}
function debugInformation(){
let x = 0,
y = 0;
textSize(12);
textStyle(NORMAL);
stroke(255);
strokeWeight(1);
fill(255);
text("FPS : " + round(frameRate()), 10 + x, 10 + textAscent("FPS : ") + y);
text("MouseX : " + round(mouseX + x), 10 + x, 10 + textAscent("FPS : ") + 10 + textAscent("MouseX : ") + y);
text("MouseY : " + round(-mouseY - y), 10 + x, 10 + textAscent("FPS : ") + 10 + textAscent("MouseX : ") + 10 + textAscent("MouseY : ") + y);
}
function ColorPicker(editor) {
this.movingObject = "";
this.updateFromGraphical = function(){
this.h = (1 - $("#hue_picker").position().top / $("#hue").height()) * 360;
this.s = ($("#sb_picker").position().left + 8) / $("#saturation").width() * 100;
this.v = (1 - ($("#sb_picker").position().top + 8) / $("#value").height()) * 100;
this.r = HSVtoRGB(this.h, this.s, this.v).r;
this.g = HSVtoRGB(this.h, this.s, this.v).g;
this.b = HSVtoRGB(this.h, this.s, this.v).b;
this.hex = RGBtoHEX(this.r, this.g, this.b);
this.updateInterface();
}
this.updateFromHSV = function(){
this.h = $($("#color_picker_hsv input")[0]).val();
this.s = $($("#color_picker_hsv input")[1]).val();
this.v = $($("#color_picker_hsv input")[2]).val();
this.r = HSVtoRGB(this.h, this.s, this.v).r;
this.g = HSVtoRGB(this.h, this.s, this.v).g;
this.b = HSVtoRGB(this.h, this.s, this.v).b;
this.hex = RGBtoHEX(this.r, this.g, this.b);
this.updateFromHEX(null, true);
this.updateInterface();
}
this.updateFromRGB = function(){
this.r = $($("#color_picker_rgb input")[0]).val();
this.g = $($("#color_picker_rgb input")[1]).val();
this.b = $($("#color_picker_rgb input")[2]).val();
this.h = RGBtoHSV(this.r, this.g, this.b).h;
this.s = RGBtoHSV(this.r, this.g, this.b).s;
this.v = RGBtoHSV(this.r, this.g, this.b).v;
this.hex = RGBtoHEX(this.r, this.g, this.b);
this.updateFromHEX(null, true);
this.updateInterface();
}
this.updateFromHEX = function(input, otf){
if (!otf){ //Not on the fly
if ($(input).val().isValidHEX()) this.hex = $(input).val();
else {
alert("Error!");
return;
}
}
this.r = HEXtoRGB(this.hex).r;
this.g = HEXtoRGB(this.hex).g;
this.b = HEXtoRGB(this.hex).b;
this.h = RGBtoHSV(this.r, this.g, this.b).h;
this.s = RGBtoHSV(this.r, this.g, this.b).s;
this.v = RGBtoHSV(this.r, this.g, this.b).v;
this.updateInterface();
}
this.updateInterface = function(){
let r = $($("#color_picker_rgb input")[0]),
g = $($("#color_picker_rgb input")[1]),
b = $($("#color_picker_rgb input")[2]),
h = $($("#color_picker_hsv input")[0]),
s = $($("#color_picker_hsv input")[1]),
v = $($("#color_picker_hsv input")[2]),
hex = $("#color_picker_hex"),
bgColor;
r.val(round(this.r));
g.val(round(this.g));
b.val(round(this.b));
h.val(round(this.h));
s.val(round(this.s));
v.val(round(this.v));
bgColor = color(this.r, 0, 0);
r.css({
"background-color": bgColor.toString(),
"color": fontColor(bgColor)
});
bgColor = color(0, this.g, 0);
g.css({
"background-color": bgColor.toString(),
"color": fontColor(bgColor)
});
bgColor = color(0, 0, this.b);
b.css({
"background-color": bgColor.toString(),
"color": fontColor(bgColor)
});
colorMode(HSL);
bgColor = color(this.h, 100, 50);
h.css({
"background-color": bgColor.toString(),
"color": fontColor(bgColor)
});
bgColor = color(this.h, this.s, 100 - this.s / 2);
s.css({
"background-color": bgColor.toString(),
"color": fontColor(bgColor)
});
bgColor = color(this.h, 100, this.v / 2);
v.css({
"background-color": bgColor.toString(),
"color": fontColor(bgColor)
});
colorMode(RGB);
hex.val(this.hex);
hex.css({
"background-color": this.hex,
"color": fontColor(color(this.hex))
});
let sRGB = HSVtoRGB(this.h, 100, 100);
let saturationBackground = "linear-gradient(to right, #FFF 0%, rgb("
+ sRGB.r + ","
+ sRGB.g + ","
+ sRGB.b + ") 100%)";
$("#hue_picker").css("top", (1 - this.h / 360) * $("#hue").height());
$("#sb_picker").css({
"left": this.s / 100 * $("#saturation").width() - 8,
"top": (1 - this.v / 100) * $("#value").height() - 8
});
$("#saturation").css("background", saturationBackground);
}
this.mousePressed = function(){
let x = winMouseX - $("#saturation").offset().left;
let y = winMouseY - $("#value").offset().top;
if (x > 0 && x < $("#saturation").width() && y > 0 && y < $("#value").height()){
this.movingObject = "sb";
}
if (x > $("#saturation").width() + 6 && x < $("#saturation").width() + 6 + $("#hue").width() && y > 0 && y < $("#hue").height()){
this.movingObject = "hue";
}
this.mouseDragged();
}
this.mouseDragged = function(){
if (this.movingObject == "hue"){
let objH = $("#hue");
let picker = $("#hue_picker");
let h = winMouseY - objH.offset().top;
if (h > 0 && h < objH.height()){
picker.css("top", h - 1);
} else if (h > objH.height()){
picker.css("top", objH.height() - 1);
} else if (h < 0){
picker.css("top", -1);
}
}
if (this.movingObject == "sb"){
let objS = $("#saturation");
let objV = $("#value");
let picker = $("#sb_picker");
let s = winMouseX - objS.offset().left;
let v = winMouseY - objV.offset().top;
if (s > 0 && s < objS.width()){
picker.css("left", s - 8);
} else if (s < 0){
picker.css("left", -8);
} else if (s < objS.width()){
picker.css("left", objS.width() - 8);
}
if (v > 0 && v < objV.height()){
picker.css("top", v - 8);
} else if (v < 0){
picker.css("top", -8);
} else if (v > objV.height()){
picker.css("top", objV.height() - 8);
}
}
this.updateFromGraphical();
}
this.mouseReleased = function(){
this.movingObject = "";
}
this.getColor = function(){
return this.hex;
}
}
function fontColor(color){
//https://www.nbdtech.com/Blog/archive/2008/04/27/Calculating-the-Perceived-Brightness-of-a-Color.aspx
let o = (red(color) * 299 + green(color) * 587 + blue(color) * 114) / 1000;
return (o > 125) ? "#000" : "#CCC";
}
//www.stackoverflow.com -->
function RGBtoHEX(r, g, b) {
let rgb = b | (g << 8) | (r << 16);
return '#' + (0x1000000 + rgb).toString(16).slice(1);
}
function HEXtoRGB(hex) {
let shorthandRegex = /^#?([a-fA-F\d])([a-fA-F\d])([a-fA-F\d])$/i;
hex = hex.replace(shorthandRegex, function(m, r, g, b) {
return r + r + g + g + b + b;
});
let result = /^#?([a-fA-F\d]{2})([a-fA-F\d]{2})([a-fA-F\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
function HSVtoRGB(h, s, v) {
let r, g, b, i, f, p, q, t;
if (arguments.length === 1) {
s = h.s, v = h.v, h = h.h;
}
h /= 360;
s /= 100;
v /= 100;
i = Math.floor(h * 6);
f = h * 6 - i;
p = v * (1 - s);
q = v * (1 - f * s);
t = v * (1 - (1 - f) * s);
switch (i % 6) {
case 0: r = v, g = t, b = p; break;
case 1: r = q, g = v, b = p; break;
case 2: r = p, g = v, b = t; break;
case 3: r = p, g = q, b = v; break;
case 4: r = t, g = p, b = v; break;
case 5: r = v, g = p, b = q; break;
}
return {
r: r * 255,
g: g * 255,
b: b * 255
};
}
function RGBtoHSV(r, g, b) {
if (arguments.length === 1) {
g = r.g, b = r.b, r = r.r;
}
let max = Math.max(r, g, b), min = Math.min(r, g, b),
d = max - min,
h,
s = (max === 0 ? 0 : d / max),
v = max / 255;
switch (max) {
case min: h = 0; break;
case r: h = (g - b) + d * (g < b ? 6: 0); h /= 6 * d; break;
case g: h = (b - r) + d * 2; h /= 6 * d; break;
case b: h = (r - g) + d * 4; h /= 6 * d; break;
}
return {
h: h * 360,
s: s * 100,
v: v * 100
};
}
function ranBool(chance){
if (!chance) chance = 2;
return Math.floor(Math.random() * chance + 1) == chance ? true : false;
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,62 @@
"use strict"
let debug = false,
viewPort = {x: 0, y: 0};
let game,
menuOpen = false,
globalCursor,
loader,
settings,
colors,
values,
audio,
font,
credits;
function preload(){
settings = loadJSON("data/settings/Settings.json");
font = loadFont("data/styles/font.ttf");
credits = loadJSON("data/settings/Credits.json");
}
function setup(){
canvasSetup();
createVariables();
loadAudioFiles(audioFilesLoaded);
prepareInterface();
}
function draw(){
checkCursor();
if (loader){
loader.update();
}
if (game){
game.update();
game.display();
}
if (debug) debugInformation();
}
function canvasSetup(){
setFrameRate(60);
let c = createCanvas($("#canvasHolder").width(), $("#canvasHolder").height());
c.parent("canvasHolder");
textFont(font);
textAlign(CENTER, CENTER);
}
function createVariables(){
colors = settings.colors;
values = settings.values;
prepareCredits();
}
function showCredits(){
game.pause();
new Message(Message.Credits()).display();
}

@ -0,0 +1,86 @@
{
"credits": [
{
"title": "Electrical Sweep",
"artist": "Sweeper",
"link": "https://soundbible.com/1795-Electrical-Sweep.html",
"license": "Public Domain"
},
{
"title": "Jump",
"artist": "snottyboy",
"link": "https://soundbible.com/1343-Jump.html",
"license": "Attribution 3.0"
},
{
"title": "boo 01",
"artist": "tim.kahn",
"link": "https://freesound.org/people/tim.kahn/sounds/336997/",
"license": "Attribution 3.0"
},
{
"title": "Cheer crowd",
"artist": "Johanneskristjansson",
"link": "https://freesound.org/people/Johanneskristjansson/sounds/371339/",
"license": "Attribution 3.0"
},
{
"title": "cheer 01",
"artist": "tim.kahn",
"link": "https://freesound.org/people/tim.kahn/sounds/337000/",
"license": "Attribution 3.0"
},
{
"title": "awww 01",
"artist": "tim.kahn",
"link": "https://freesound.org/people/tim.kahn/sounds/336998/",
"license": "Attribution 3.0"
},
{
"title": "Evolution",
"artist": "Josh Woodward",
"link": "https://www.youtube.com/watch?v=RA6XneJGwfQ",
"license": "Creative Commons - Attribution"
},
{
"title": "Home Improvement",
"artist": "Josh Woodward",
"link": "https://youtu.be/NMi9Nrm1Mfs?t=2359",
"license": "Creative Commons - Attribution"
},
{
"title": "Incoherent",
"artist": "Josh Woodward",
"link": "https://www.youtube.com/watch?v=bxgzIOS-lSs",
"license": "Creative Commons - Attribution"
},
{
"title": "Cherubs",
"artist": "Josh Woodward",
"link": "https://www.youtube.com/watch?v=pzUkoJonpro",
"license": "Creative Commons - Attribution"
},
{
"title": "Let it in",
"artist": "Josh Woodward",
"link": "https://www.youtube.com/watch?v=M-GylSik2h8",
"license": "Creative Commons - Attribution"
},
{
"title": "California Lullabye",
"artist": "Josh Woodward",
"link": "https://www.youtube.com/watch?v=WmWHcyLsqHQ",
"license": "Creative Commons - Attribution"
},
{
"title": "Memorized",
"artist": "Josh Woodward",
"link": "https://www.youtube.com/watch?v=2eFKOxfUYwE",
"license": "Creative Commons - Attribution"
}
]
}

@ -0,0 +1,215 @@
{
"colors": {
"background": {
"mountains": {
"stroke": "rgb(0, 0, 0)",
"fill": "rgb(60, 60, 60)"
},
"ground": "rgb(40, 100, 30)",
"sky":"rgb(110, 130, 230)"
},
"map": {
"background": {
"stroke": "rgb(0, 0, 0)",
"fill": "rgb(90, 110, 210)"
}
},
"player": {
"body": "hsb(0, 100%, 100%)",
"eyes": {
"inner": "rgb(0, 0, 0)" ,
"outer": "rgb(255, 255, 255)"
}
},
"goal": {
"main": "#473115",
"roof": "#32210b",
"hole": "#14100b"
},
"brick": {
"earth": "rgb(81, 54, 37)",
"ground": "rgb(40, 150, 20)",
"grass": "#2c8300",
"flower": {
"center": "hsb(0, 100%, 100%)",
"petal": "hsb(0, 100%, 100%)",
"haulm": "#2c8300"
},
"tree": {
"leaf": "hsb(110, 100%, 50%)",
"wood": "hsb(32, 100%, 25%)"
},
"coin": {
"fill": "hsb(0, 100%, 100%)",
"stroke": "hsb(0, 100%, 100%)"
}
},
"loader": {
"background": "#3c598d",
"start": "hsb(120, 100%, 30%)",
"finished": "#00d3db",
"spinner": "#00d3db",
"text": {
"fill": "rgb(0, 0, 0)",
"stroke": "#00d3db"
}
}
},
"messages": {
"won": {
"html": "<p>You won the game! :D Wanna start another?</p>",
"styles": {
"border-color": "rgb(30, 120, 30)",
"height": "auto"
},
"buttons": [
{
"text": "Restart",
"styles": {
"background-color": "rgb(60, 160, 60)"
},
"onclick": "game.restart();"
},
{
"text": "New Game",
"styles": {
"background-color": "rgb(60, 160, 60)"
},
"onclick": "loadNewGame();"
},
{
"text": "Continue",
"styles": {
"background-color": "rgb(60, 160, 60)"
},
"onclick": "game.resume()"
}
]
},
"lost": {
"html": "<p>Oh no, you fell out of the world!</p>",
"styles": {
"border-color": "rgb(160, 30, 30)",
"height": "auto"
},
"buttons": [
{
"text": "Restart",
"styles": {
"background-color": "rgb(160, 60, 60)"
},
"onclick": "game.restart();"
}
]
},
"newGame": {
"html": "<p>Are you sure you wanna start a new one?</p>",
"styles": {
"border-color": "rgb(70, 70, 20)",
"height": "auto"
},
"buttons": [
{
"text": "New Game",
"styles": {
"background-color": "rgb(60, 160, 60)"
},
"onclick": "loadNewGame();"
},
{
"text": "Cancel",
"styles": {
"background-color": "rgb(160, 60, 60)"
},
"onclick": "game.resume();"
}
]
},
"credits": {
"html": "",
"styles": {
"border-color": "rgb(0, 37, 160)",
"background-color": "rgb(83, 61, 255)",
"height": "auto"
},
"buttons": [
{
"text": "Continue",
"styles": {
"background-color": "rgb(60, 160, 60)"
},
"onclick": "game.resume()"
}
]
}
},
"audio": {
"sound": {
"won": [
"data/audio/sound/cheer0.mp3",
"data/audio/sound/cheer1.wav",
"data/audio/sound/cheer2.wav",
"data/audio/sound/cheer3.wav"
],
"lost": [
"data/audio/sound/boo0.wav",
"data/audio/sound/aww0.wav",
"data/audio/sound/aww1.wav"
],
"jump": [
"data/audio/sound/jump.mp3"
],
"coin": [
"data/audio/sound/electrical_sweep.mp3"
]
},
"music":{
"game": [
"data/audio/music/background0.mp3",
"data/audio/music/background1.mp3",
"data/audio/music/background2.mp3",
"data/audio/music/background3.mp3",
"data/audio/music/background4.mp3",
"data/audio/music/background5.mp3",
"data/audio/music/background6.mp3",
"data/audio/music/background7.mp3",
"data/audio/music/background8.mp3"
]
}
},
"values": {
"minBrickWidth": "200",
"maxBrickWidth": "800",
"backgroundMoveScale": "500",
"minWorldSize": "5000",
"maxWorldSize": "10000",
"maxMapSize": "300",
"coinSize": "50",
"coinRarity": "20",
"coinDispoY": "10",
"loadedWaitTime": "1000",
"cursorTimeLimit": "1000",
"menuAnimationTime": "200",
"openerAnimationTime": "200",
"maxLevelCount": "5",
"maxVelocityX": [
"15",
"12",
"10",
"9",
"8"
],
"jumpVelocity": [
"15",
"12",
"10",
"8",
"6"
]
}
}

@ -0,0 +1,88 @@
#color_picker{
width: 300px;
height: 25%;
margin: 20px;
margin-top: 50px;
border: 5px solid #000;
background-color: #000;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
position: relative;
}
#color_picker_numeric{
width: 80%;
padding: 5%;
margin: 5%;
background-color: #888;
border-radius: 10px;
overflow: hidden;
}
.color_picker_rgb{
float: left;
width: 22%;
height: 35px;
font-size: 25px;
color: #000;
}
.color_picker_rgb:nth-child(1){
margin-right: 10%;
margin-left: 3%;
background-color: #F00;
}
.color_picker_rgb:nth-child(2){
background-color: #0F0;
}
.color_picker_rgb:nth-child(3){
margin-left: 10%;
background-color: #00F;
color: #FFF;
}
#color_picker_hex{
width: 50%;
height: 30px;
font-size: 25px;
margin: 10% 25% 0 25%;
}
#saturation{
position: relative;
width: calc(100% - 33px);
height: 100%;
background: linear-gradient(to right, #FFF 0%, #F00 100%);
float: left;
margin-right: 6px;
}
#value {
width: 100%;
height: 100%;
background: linear-gradient(to top, #000 0%, rgba(255,255,255,0) 100%);
}
#sb_picker{
border: 2px solid;
border-color: #FFF;
position: absolute;
width: 14px;
height: 14px;
border-radius: 10px;
bottom: 50px;
left: 50px;
box-sizing: border-box;
z-index: 10;
}
#hue {
width: 27px;
height: 100%;
position: relative;
float: left;
background: linear-gradient(to bottom, #F00 0%, #F0F 17%, #00F 34%, #0FF 50%, #0F0 67%, #FF0 84%, #F00 100%);
}
#hue_picker {
position: absolute;
background: #000;
border-bottom: 1px solid #000;
top: 0;
width: 27px;
height: 2px;
}

Binary file not shown.

@ -0,0 +1,88 @@
input[type=range] {
-webkit-appearance: none;
margin: 18px 0;
width: 100%;
}
input[type=range]:focus {
outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 8.4px;
cursor: pointer;
animate: 0.2s;
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
background: #3071a9;
border-radius: 1.3px;
border: 0.2px solid #010101;
}
input[type=range]::-webkit-slider-thumb {
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
border: 1px solid #000000;
height: 36px;
width: 16px;
border-radius: 3px;
background: #ffffff;
cursor: pointer;
-webkit-appearance: none;
margin-top: -14px;
}
input[type=range]:focus::-webkit-slider-runnable-track {
background: #367ebd;
}
input[type=range]::-moz-range-track {
width: 100%;
height: 8.4px;
cursor: pointer;
animate: 0.2s;
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
background: #3071a9;
border-radius: 1.3px;
border: 0.2px solid #010101;
}
input[type=range]::-moz-range-thumb {
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
border: 1px solid #000000;
height: 36px;
width: 16px;
border-radius: 3px;
background: #ffffff;
cursor: pointer;
}
input[type=range]::-ms-track {
width: 100%;
height: 8.4px;
cursor: pointer;
animate: 0.2s;
background: transparent;
border-color: transparent;
border-width: 16px 0;
color: transparent;
}
input[type=range]::-ms-fill-lower {
background: #2a6495;
border: 0.2px solid #010101;
border-radius: 2.6px;
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
}
input[type=range]::-ms-fill-upper {
background: #3071a9;
border: 0.2px solid #010101;
border-radius: 2.6px;
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
}
input[type=range]::-ms-thumb {
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
border: 1px solid #000000;
height: 36px;
width: 16px;
border-radius: 3px;
background: #ffffff;
cursor: pointer;
}
input[type=range]:focus::-ms-fill-lower {
background: #3071a9;
}
input[type=range]:focus::-ms-fill-upper {
background: #367ebd;
}

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.dom.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.sound.min.js" type="text/javascript"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" type="text/javascript"></script>
<script src="data/scripts/lib/benjo_library.js" type="text/javascript"></script>
<script src="data/scripts/events.js" type="text/javascript"></script>
<script src="data/scripts/sketch.js" type="text/javascript"></script>
<script src="data/scripts/Game.js" type="text/javascript"></script>
<script src="data/scripts/Player.js" type="text/javascript"></script>
<script src="data/scripts/Brick.js" type="text/javascript"></script>
<script src="data/scripts/Goal.js" type="text/javascript"></script>
<script src="data/scripts/Plant.js" type="text/javascript"></script>
<script src="data/scripts/Map.js" type="text/javascript"></script>
<script src="data/scripts/Background.js" type="text/javascript"></script>
<script src="data/scripts/Interface.js" type="text/javascript"></script>
<script src="data/scripts/Message.js" type="text/javascript"></script>
<script src="data/scripts/Coin.js" type="text/javascript"></script>
<script src="data/scripts/Sound.js" type="text/javascript"></script>
<script src="data/scripts/Loader.js" type="text/javascript"></script>
<script src="data/scripts/LevelText.js" type="text/javascript"></script>
<link href="styles.css" rel="stylesheet">
<link href="data/styles/color_picker.css" rel="stylesheet">
<link href="data/styles/range_input.css" rel="stylesheet">
<link href="data/images/favicon.ico" rel="icon" type="image/x-icon">
<title>Jump and Run</title>
</head>
<body>
<div id="p5_loading"></div>
<div id="canvasHolder"></div>
<div id="messageWrapper" style="display: none"></div>
<div id="menuOpener"></div>
<div id="menu">
<button id="run" onclick="game.toggleRun();"></button>
<button id="restart" onclick="game.restart();"></button>
<button id="new" onclick="requestNewGame();"></button>
<button id="map" onclick="game.toggleMap();"></button>
<button id="hint" onclick="game.toggleHint();"></button>
<button id="fs" onclick="toggleFullscreen(this);">Fullscreen: Off</button>
<input id="soundVolume" max="100" min="0" oninput="updateVolume();" type="range"/>
<button id="sound" onclick="toggleSounds();"></button>
<input id="musicVolume" max="100" min="0" oninput="updateVolume();" type="range"/>
<button id="music" onclick="toggleMusic();"></button>
<button id="credits" onclick="showCredits();">Credits</button>
</div>
</body>
</html>

@ -0,0 +1,125 @@
a:link, a:hover, a:active, a:visited{color: #000;}
html, body{margin: 0; padding: 0; height: 100%; width: 100%;}
canvas{margin: 0; padding: 0; border: none; display: block;}
button:hover{cursor: pointer;}
@font-face{
font-family: "Rametto";
src: url("data/styles/font.ttf");
}
*{
font-family: "Rametto";
}
#canvasHolder{
position: absolute;
width: 100%;
height: 100%;
}
#messageWrapper{
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
z-index: 1;
}
#message{
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 700px;
left: 0;
right: 0;
margin: auto;
background-color: rgb(130, 130, 130);
border: 10px solid;
border-radius: 50px;
text-align: center;
align-content: center;
}
#message p{
margin: 100px;
font-size: 35px;
}
#message button{
margin: 20px;
margin-bottom: 50px;
font-size: 35px;
border: 5px solid #000;
border-radius: 10px;
}
#menuOpener{
position: absolute;
left: 0;
top: 0;
bottom: 0;
margin: auto;
height: 100px;
width: 20px;
background-color: rgb(70, 70, 70);
border-radius: 0 20px 20px 0;
border: 3px solid #000;
border-left: none;
}
#menuOpener:hover{
background-color: rgb(50, 50, 50);
cursor: pointer;
}
#menu{
position: absolute;
top: 50%;
transform: translateY(-50%);
left: -450px;
width: 400px;
background-color: rgb(90, 90, 90);
border-radius: 0 20px 20px 0;
border: 10px solid #000;
border-left: none;
padding: 20px;
text-align: center;
}
#menu button{
margin-bottom: 20px;
width: 100%;
background-color: rgb(160, 200, 100);
border: 2px solid #000;
border-radius: 5px;
font-size: 30px;
}
#menu button:last-child{
margin-bottom: 0px;
}
#menu button:hover{
background-color: rgb(80, 190, 40);
}
#creditsTableWrapper{
margin: 20px;
height: 500px;
overflow-x: auto;
overflow-y: auto;
}
#creditsTable{
border-collapse: collapse;
margin: 0px auto;
}
#creditsTable, #creditsTable th, #creditsTable td{
border: 2px solid #0091a3;
padding: 5px;
font-size: 20px;
border-left: none;
border-right: none;
}
#creditsTable th{
font-size: 25px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Loading…
Cancel
Save