commit
5123fb6548
46 changed files with 2940 additions and 0 deletions
@ -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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
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; |
||||
} |
After Width: | Height: | Size: 167 KiB |
Loading…
Reference in new issue