commit
d0f71bc79d
11 changed files with 1086 additions and 0 deletions
@ -0,0 +1,2 @@ |
|||||||
|
.idea |
||||||
|
|
@ -0,0 +1,6 @@ |
|||||||
|
{ |
||||||
|
"display_name": "2D Openworld", |
||||||
|
"info_text": "My first 2D Openworld project. You can explore by moving your cursor to the frame borders.". |
||||||
|
"visible": false, |
||||||
|
"tags": ["Game", "Simulation"] |
||||||
|
} |
@ -0,0 +1,40 @@ |
|||||||
|
<!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://code.jquery.com/jquery-3.3.1.min.js" type="text/javascript"></script> |
||||||
|
<script src="scripts/lib/BenjoLibrary.js" type="text/javascript"></script> |
||||||
|
<script src="scripts/sketch.js" type="text/javascript"></script> |
||||||
|
<script src="scripts/Cloud.js" type="text/javascript"></script> |
||||||
|
<script src="scripts/Tree.js" type="text/javascript"></script> |
||||||
|
<script src="scripts/Bird.js" type="text/javascript"></script> |
||||||
|
<link href="styles.css" rel="stylesheet"> |
||||||
|
<title>2D Openworld</title> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<!-- Hide <a> and <input> --> |
||||||
|
<a download="worldData.json" href="#" id="saveLink"></a> |
||||||
|
<input id="fileBrowser" onchange="uploadWorld()" type="file"/> |
||||||
|
|
||||||
|
<button id="createWorld" onclick="createWorld()">Neue Welt erstellen</button> |
||||||
|
<button id="restoreWorld" onclick="$('#fileBrowser')[0].click()">Welt mit Datei wiederherstellen</button> |
||||||
|
|
||||||
|
<button id="toolBarOpener" onclick="toggleToolBar(this)"></button> |
||||||
|
<div id="toolBar"> |
||||||
|
<button class="toolBarEntry" id="downloadButton" onclick="downloadWorld()">⤓</button> |
||||||
|
<button class="toolBarEntry" id="uploadButton" onclick="$('#fileBrowser')[0].click()">⤒</button> |
||||||
|
<button class="toolBarEntry" id="pauseButton" onclick="togglePause(this)">||</button> |
||||||
|
<button class="toolBarEntry" id="infoButton" onclick="toggleInfo()">i</button> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div id="infoWrapper"> |
||||||
|
<div id="info"> |
||||||
|
<p> |
||||||
|
//Hier stehen irgendwann mal Infos |
||||||
|
</p> |
||||||
|
<center><button onclick="toggleInfo()">OK</button></center> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,41 @@ |
|||||||
|
class Bird{ |
||||||
|
|
||||||
|
constructor(x){ |
||||||
|
this.x = x; |
||||||
|
this.y = random(height * 0.05, height * 0.3); |
||||||
|
this.v = random([true, false]) ? random(3, 5) : random(-3, -5); |
||||||
|
this.length = random(50, 100); |
||||||
|
} |
||||||
|
|
||||||
|
move(){ |
||||||
|
this.x += this.v; |
||||||
|
if (this.x - this.length / 2 > worldWidth) this.x = -this.length / 2; |
||||||
|
if (this.x + this.length / 2 < 0) this.x = worldWidth + this.length / 2; |
||||||
|
} |
||||||
|
|
||||||
|
show(){ |
||||||
|
let wing = sin(0.02 * PI * this.x); |
||||||
|
if (this.x + this.length / 2 > viewPort.x && this.x - this.length / 2 < viewPort.x + width){ |
||||||
|
fill(0); |
||||||
|
beginShape(); |
||||||
|
vertex(this.x - this.length / 2, this.y); |
||||||
|
vertex(this.x - this.length * 0.4, this.y - this.length * 0.1); |
||||||
|
vertex(this.x + this.length * 0.15, this.y - this.length * 0.1); |
||||||
|
vertex(this.x + this.length * 0.15, this.y - this.length * 0.1 - this.length * 0.4 * wing); |
||||||
|
vertex(this.x + this.length * 0.1, this.y - this.length * 0.1 - this.length * 0.5 * wing); |
||||||
|
vertex(this.x + this.length * 0.05, this.y - this.length * 0.1 - this.length * 0.4 * wing); |
||||||
|
vertex(this.x, this.y - this.length * 0.1 - this.length * 0.5 * wing); |
||||||
|
vertex(this.x - this.length * 0.05, this.y - this.length * 0.1 - this.length * 0.4 * wing); |
||||||
|
vertex(this.x - this.length * 0.1, this.y - this.length * 0.1 - this.length * 0.5 * wing); |
||||||
|
vertex(this.x - this.length * 0.15, this.y - this.length * 0.1 - this.length * 0.4 * wing); |
||||||
|
vertex(this.x - this.length * 0.15, this.y - this.length * 0.1); |
||||||
|
vertex(this.x + this.length * 0.4, this.y - this.length * 0.1); |
||||||
|
vertex(this.x + this.length / 2, this.y); |
||||||
|
vertex(this.x + this.length * 0.4, this.y + this.length * 0.1); |
||||||
|
vertex(this.x - this.length * 0.4, this.y + this.length * 0.1); |
||||||
|
endShape(); |
||||||
|
fill(255); |
||||||
|
ellipse(this.x + ((this.v > 0) ? 1 : -1) * this.length * 0.4, this.y - this.length * 0.025, this.length * 0.05); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
class Cloud{ |
||||||
|
|
||||||
|
constructor(x, y, w, h){ |
||||||
|
this.x = x; |
||||||
|
this.y = y; |
||||||
|
this.width = w; |
||||||
|
this.height = h; |
||||||
|
this.v = 0.25; |
||||||
|
this.brightness = random(0.75, 1); |
||||||
|
} |
||||||
|
|
||||||
|
move(){ |
||||||
|
this.x += this.v; |
||||||
|
if (this.x - this.width / 2 > worldWidth){ |
||||||
|
this.x = -this.width; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
show(){ |
||||||
|
fill(255 * this.brightness); |
||||||
|
if (this.x + this.width * 9 / 8 > viewPort.x && this.x - this.width * 9 / 8 < viewPort.x + width){ |
||||||
|
ellipse(this.x + this.width / 4, this.y + this.height * 2 / 3, this.width / 2, this.height / 2); |
||||||
|
ellipse(this.x + this.width / 2, this.y + this.height * 2 / 3, this.width / 2, this.height / 2); |
||||||
|
ellipse(this.x + this.width * 3 / 4, this.y + this.height * 2 / 3, this.width / 2, this.height / 2); |
||||||
|
ellipse(this.x + this.width * 3 / 8, this.y + this.height * 1 / 3, this.width / 2, this.height / 2); |
||||||
|
ellipse(this.x + this.width * 5 / 8, this.y + this.height * 1 / 3, this.width / 2, this.height / 2); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
function Human(x, h, v){ |
||||||
|
this.x = x; |
||||||
|
this.height = h; |
||||||
|
this.male = random([true, false]); |
||||||
|
this.legDist = 0; |
||||||
|
this.v = v; |
||||||
|
|
||||||
|
this.move = function(d){ |
||||||
|
this.x += this.v * d; |
||||||
|
} |
||||||
|
|
||||||
|
this.show = function(){ |
||||||
|
var y = ground[this.x]; |
||||||
|
stroke(0); |
||||||
|
fill(0); |
||||||
|
strokeWeight(1); |
||||||
|
line(this.x, y - this.height * 0.4, this.x, y - this.height * 0.85); |
||||||
|
ellipse(this.x, y - this.height * 0.925, this.height * 0.1, this.height * 0.15); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
class Tree{ |
||||||
|
|
||||||
|
constructor(x, w, h){ |
||||||
|
this.x = x; |
||||||
|
this.width = w; |
||||||
|
this.height = h; |
||||||
|
let c = round(random(60, 100)); |
||||||
|
this.color = {r: c, g: round(random(170, 230)), b: c}; |
||||||
|
} |
||||||
|
|
||||||
|
show(){ |
||||||
|
if (this.x + this.height * 0.375 > viewPort.x && this.x - this.height * 0.375 < viewPort.x + width){ |
||||||
|
let yArr = []; |
||||||
|
for (let x = this.x - this.width / 2; x < this.x + this.width / 2; x++){ |
||||||
|
try{yArr.push(ground[round(x)].y);} |
||||||
|
catch(e){} |
||||||
|
} |
||||||
|
let crownY = max(yArr) - this.height; |
||||||
|
fill(80, 50, 40); |
||||||
|
rect(this.x - this.width / 2, crownY, this.width, this.height); |
||||||
|
fill(this.color.r, this.color.g, this.color.b); |
||||||
|
ellipse(this.x, crownY, this.height / 2, this.height / 2); |
||||||
|
for (let i = 0; i < TWO_PI; i += 1 / 4 * PI){ |
||||||
|
let x = this.x + this.height / 4 * sin(i); |
||||||
|
let y = crownY + this.height / 4 * cos(i); |
||||||
|
ellipse(x, y, this.height / 2, this.height / 2); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,380 @@ |
|||||||
|
var TOP = 1; |
||||||
|
var RIGHT = 2 |
||||||
|
var BOTTOM = 3; |
||||||
|
var LEFT = 4; |
||||||
|
var TOP_RIGHT = 5; |
||||||
|
var BOTTOM_RIGHT = 6; |
||||||
|
var BOTTOM_LEFT = 7; |
||||||
|
var TOP_LEFT = 8; |
||||||
|
|
||||||
|
var wWidth = window.innerWidth; |
||||||
|
var wHeight = window.innerHeight; |
||||||
|
var oldWHeight; |
||||||
|
var oldWWidth; |
||||||
|
|
||||||
|
function updateVars(){ |
||||||
|
oldWWidth = wWidth; |
||||||
|
oldWHeight = wHeight; |
||||||
|
wWidth = window.innerWidth; |
||||||
|
wHeight = window.innerHeight; |
||||||
|
} |
||||||
|
|
||||||
|
function collisionDetection(obj0, obj1){ |
||||||
|
|
||||||
|
var sp = strokePadding; |
||||||
|
if (sp == null) sp = 0; |
||||||
|
|
||||||
|
if (obj0.isEllipse && obj1.isRectangle){ |
||||||
|
|
||||||
|
//Ball
|
||||||
|
var b = obj0; |
||||||
|
|
||||||
|
//Rectangle
|
||||||
|
var r = obj1; |
||||||
|
|
||||||
|
for (var 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
|
||||||
|
var bcx = b.x; |
||||||
|
|
||||||
|
// Ball Center Y
|
||||||
|
var bcy = b.y; |
||||||
|
|
||||||
|
// Ball Border X
|
||||||
|
var bbx = b.x + sin(i) * b.r; |
||||||
|
|
||||||
|
// Ball Border Y inverted because Y = 0 is the TOP of the screen
|
||||||
|
var bby = b.y - cos(i) * b.r; |
||||||
|
|
||||||
|
// Rectangle Width
|
||||||
|
var rW = r.width + 2 * sp; |
||||||
|
|
||||||
|
// Rectangle Height
|
||||||
|
var rH = r.height + 2 * sp; |
||||||
|
|
||||||
|
// Rectangle Border X
|
||||||
|
var rX = r.x - sp; |
||||||
|
|
||||||
|
// Rectangle Border Y
|
||||||
|
var 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
|
||||||
|
var b1 = obj0; |
||||||
|
|
||||||
|
//Ball 2
|
||||||
|
var 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){ |
||||||
|
|
||||||
|
var 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){ |
||||||
|
|
||||||
|
var 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){ |
||||||
|
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: |
||||||
|
var cornerX = obj1.x; |
||||||
|
var cornerY = obj1.y; |
||||||
|
break; |
||||||
|
case TOP_RIGHT: |
||||||
|
var cornerX = obj1.x + obj1.width; |
||||||
|
var cornerY = obj1.y; |
||||||
|
break; |
||||||
|
case BOTTOM_LEFT: |
||||||
|
var cornerX = obj1.x; |
||||||
|
var cornerY = obj1.y + obj1.height; |
||||||
|
break; |
||||||
|
case BOTTOM_RIGHT: |
||||||
|
var cornerX = obj1.x + obj1.width; |
||||||
|
var cornerY = obj1.y + obj1.height; |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
var nx = ball.x - cornerX; |
||||||
|
var ny = ball.y - cornerY; |
||||||
|
var length = sqrt(nx * nx + ny * ny); |
||||||
|
nx /= length; |
||||||
|
ny /= length; |
||||||
|
|
||||||
|
var 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){ |
||||||
|
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: |
||||||
|
var cornerX = obj1.x; |
||||||
|
var cornerY = obj1.y + obj1.height; |
||||||
|
break; |
||||||
|
case BOTTOM_RIGHT: |
||||||
|
var cornerX = obj1.x + obj1.width; |
||||||
|
var cornerY = obj1.y + obj1.height; |
||||||
|
break; |
||||||
|
} |
||||||
|
var nx = ball.x - cornerX; |
||||||
|
var ny = ball.y - cornerY; |
||||||
|
var length = sqrt(nx * nx + ny * ny); |
||||||
|
nx /= length; |
||||||
|
ny /= length; |
||||||
|
|
||||||
|
var 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
|
||||||
|
var b1 = obj0; |
||||||
|
|
||||||
|
//Ball 2
|
||||||
|
var 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
|
||||||
|
var collisionAngle = atan2((b2.y - b1.y), (b2.x - b1.x)); |
||||||
|
|
||||||
|
//Converting directions of velocity vector of balls into angles
|
||||||
|
var d1 = atan2(b1.v.y, b1.v.x); |
||||||
|
var d2 = atan2(b2.v.y, b2.v.x); |
||||||
|
|
||||||
|
//Ignoring mass effects new velocites are simply magnitude multiplied with value of angle differences
|
||||||
|
var newXspeed1 = b1.v.mag * cos(d1 - collisionAngle); |
||||||
|
var newYspeed1 = b1.v.mag * sin(d1 - collisionAngle); |
||||||
|
var newXspeed2 = b2.v.mag * cos(d2 - collisionAngle); |
||||||
|
var 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
|
||||||
|
var finalXspeed1 = ((b1.mass - b2.mass) * newXspeed1 + b2.mass * 2 * newXspeed2) / (b1.mass + b2.mass); |
||||||
|
var finalYspeed1 = newYspeed1; |
||||||
|
var finalXspeed2 = (b1.mass * 2 * newXspeed1 + (b2.mass - b1.mass) * newXspeed2) / (b1.mass + b2.mass); |
||||||
|
var finalYspeed2 = newYspeed2; |
||||||
|
|
||||||
|
//Values of collisionAngle
|
||||||
|
var cosAngle = cos(collisionAngle); |
||||||
|
var 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
|
||||||
|
var u1x = cosAngle * finalXspeed1 - sinAngle * finalYspeed1; |
||||||
|
var u1y = sinAngle * finalXspeed1 + cosAngle * finalYspeed1; |
||||||
|
var u2x = cosAngle * finalXspeed2 - sinAngle * finalYspeed2; |
||||||
|
var 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){ |
||||||
|
|
||||||
|
var time = floor(time / 10); |
||||||
|
|
||||||
|
var hs = String(floor(time % 100)); |
||||||
|
var fs = String(floor((time / 100) % 60)); |
||||||
|
|
||||||
|
if (hoursWanted){ |
||||||
|
var min = String(floor(((time / 100) / 60) % 60)); |
||||||
|
var 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; |
||||||
|
|
||||||
|
var timeString = hr + ":" + min + ":" + fs + ":" + hs; |
||||||
|
} else { |
||||||
|
var 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; |
||||||
|
|
||||||
|
var timeString = min + ":" + fs + ":" + hs; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return timeString; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
function setCookie(name, value, years){ |
||||||
|
var expires = ""; |
||||||
|
if (years){ |
||||||
|
var 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){ |
||||||
|
var nameEQ = name + "="; |
||||||
|
var ca = document.cookie.split(';'); |
||||||
|
for (var i = 0; i < ca.length; i++){ |
||||||
|
var 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 (var i = 0; i < arguments.length; i++) setCookie(arguments[i], "", -1); |
||||||
|
} |
||||||
|
|
||||||
|
function deleteAllCookies(){ |
||||||
|
var cookies = document.cookie.split(";"); |
||||||
|
for (var 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); |
||||||
|
}; |
||||||
|
|
||||||
|
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; |
||||||
|
} |
@ -0,0 +1,434 @@ |
|||||||
|
let trees = [], |
||||||
|
birds = [], |
||||||
|
clouds = [], |
||||||
|
humans = [], |
||||||
|
ground = [], |
||||||
|
time = 12, // in hours
|
||||||
|
cycleTime = 10, // in minutes
|
||||||
|
worldWidth = 40000, |
||||||
|
viewPort = {x: Math.round(worldWidth / 2 - window.innerWidth / 2), y: 0, v: 20}, |
||||||
|
waveDispo = 0, |
||||||
|
cliffDispo = 25, |
||||||
|
STRAIGHT_GROUND = 0, |
||||||
|
SMALL_HILLS = 1, |
||||||
|
LARGE_HILL = 2, |
||||||
|
LAKE = 3, |
||||||
|
gameIsRunning = false; |
||||||
|
|
||||||
|
function setup(){ |
||||||
|
setFrameRate(120); |
||||||
|
createCanvas(window.innerWidth, window.innerHeight); |
||||||
|
background(160, 160, 255); |
||||||
|
noStroke(); |
||||||
|
$("#saveLink").hide(); |
||||||
|
$("#fileBrowser").hide(); |
||||||
|
$("#toolBarOpener").hide(); |
||||||
|
$("#infoWrapper").hide(); |
||||||
|
$("button").on("click", function(){this.blur();}); |
||||||
|
} |
||||||
|
|
||||||
|
function createWorld(){ |
||||||
|
$("#restoreWorld, #createWorld").hide(); |
||||||
|
fill(80); |
||||||
|
rect(width * 0.1, height * 0.5 - 25, width * 0.8, 50); |
||||||
|
fill(0, 255, 0); |
||||||
|
let x = 0, |
||||||
|
createProgress = 0, |
||||||
|
y = random(height * 0.7, height * 0.8), |
||||||
|
treeDist = 0, |
||||||
|
a = 0, c = 1, b = 0, |
||||||
|
biome, |
||||||
|
biomeX = 0, |
||||||
|
biomeDistance = 1, |
||||||
|
usedBiomes = [], |
||||||
|
biomes = [STRAIGHT_GROUND, SMALL_HILLS, LARGE_HILL, LAKE], |
||||||
|
isWooden; |
||||||
|
|
||||||
|
function create(){ |
||||||
|
//Updating progressbar
|
||||||
|
createProgress++; |
||||||
|
rect(width * 0.1, height * 0.5 - 25, width * 0.8 * (createProgress / (worldWidth * 2)), 50); |
||||||
|
|
||||||
|
//Main creating
|
||||||
|
if (ground.length < worldWidth){ |
||||||
|
//Ground
|
||||||
|
let biomeRemainder = (x - biomeX) % biomeDistance; |
||||||
|
if (biomeRemainder == 0){ |
||||||
|
biome = random(biomes); |
||||||
|
if (usedBiomes.includes(biome)) biome = random(biomes); |
||||||
|
usedBiomes.push(biome); |
||||||
|
biomeX = x; |
||||||
|
isWooden = biome == LAKE ? false : random([true, false]); |
||||||
|
biomeDistance = round(random(1000, 1500)); |
||||||
|
a = 0, c = 1, b = 0; |
||||||
|
} |
||||||
|
switch (biome){ |
||||||
|
case STRAIGHT_GROUND: |
||||||
|
a = 0; |
||||||
|
if (y < height * 0.3) a = -1; |
||||||
|
if (y > height * 0.95) a = 1; |
||||||
|
//y = noise(x / 100, y / 100) * height;
|
||||||
|
y += random(-0.25 - a, 0.25 - a); |
||||||
|
break; |
||||||
|
case SMALL_HILLS: |
||||||
|
if (biomeRemainder == round(biomeDistance / 12) |
||||||
|
|| biomeRemainder == round(biomeDistance * 5 / 12) |
||||||
|
|| biomeRemainder == round(biomeDistance * 0.75)) |
||||||
|
c = -1; |
||||||
|
if (biomeRemainder == round(biomeDistance * 0.25) |
||||||
|
|| biomeRemainder == round(biomeDistance * 7 / 12) |
||||||
|
|| biomeRemainder == round(biomeDistance * 11 / 12)) |
||||||
|
c = 1; |
||||||
|
if (y < height * 0.3){ |
||||||
|
c = -1; |
||||||
|
b = -0.5; |
||||||
|
} |
||||||
|
else if (y > height * 0.9){ |
||||||
|
c = 1; |
||||||
|
b = 0.5; |
||||||
|
} |
||||||
|
else b = 0; |
||||||
|
a -= random(0.005, 0.015) * c; |
||||||
|
y += random(2 * a - b); |
||||||
|
break; |
||||||
|
case LARGE_HILL: |
||||||
|
if (biomeRemainder == round(biomeDistance * 0.25)) c = -1; |
||||||
|
if (biomeRemainder == round(biomeDistance * 0.75)) c = 1; |
||||||
|
if (y < height * 0.3){ |
||||||
|
c = -1; |
||||||
|
b = -1; |
||||||
|
} |
||||||
|
else if (y > height * 0.9){ |
||||||
|
c = 1; |
||||||
|
b = 1; |
||||||
|
} |
||||||
|
else b = 0; |
||||||
|
a -= random(0.0025, 0.0075) * c; |
||||||
|
y += random(2 * a - b); |
||||||
|
break; |
||||||
|
} |
||||||
|
ground[x] = {y: y, biome: biome, isWooden: isWooden}; |
||||||
|
|
||||||
|
//Trees
|
||||||
|
let treeH, treeW, valid; |
||||||
|
treeDist++; |
||||||
|
if (isWooden) valid = random(100) < 1 ? true : false; |
||||||
|
if (!isWooden) valid = random(1000) < 0.5 ? true : false; |
||||||
|
treeH = random(height * 0.3, height * 0.5), |
||||||
|
treeW = random(40, 60); |
||||||
|
if (treeDist < treeH * 0.25) valid = false; |
||||||
|
try{if (ground[round(x - treeW / 2)].biome == LAKE || biomeRemainder > biomeDistance - treeW || y - treeH < height * 0.15) valid = false;} |
||||||
|
catch(e){} |
||||||
|
if (valid){ |
||||||
|
trees.push(new Tree(x, treeW, treeH)); |
||||||
|
treeDist = 0; |
||||||
|
} |
||||||
|
|
||||||
|
//Clouds
|
||||||
|
let cloudY, cloudW, cloudH; |
||||||
|
valid = random(1000) < 1 ? true : false; |
||||||
|
if (valid){ |
||||||
|
cloudY = random(0, 200), |
||||||
|
cloudW = random(100, 500), |
||||||
|
cloudH = random(50, 80); |
||||||
|
clouds.push(new Cloud(x, cloudY, cloudW, cloudH)); |
||||||
|
} |
||||||
|
|
||||||
|
//Birds
|
||||||
|
valid = random(1000) < 1 ? true : false; |
||||||
|
if (valid){ |
||||||
|
birds.push(new Bird(x)); |
||||||
|
} |
||||||
|
|
||||||
|
x++; |
||||||
|
} |
||||||
|
|
||||||
|
//Reset some variables
|
||||||
|
if (x == worldWidth){ |
||||||
|
x = 0; |
||||||
|
a = 0; |
||||||
|
} |
||||||
|
|
||||||
|
//Ground details
|
||||||
|
if (ground.length == worldWidth){ |
||||||
|
try{ |
||||||
|
if (ground[x].biome != LAKE && ground[x + cliffDispo * 2].biome == LAKE){ |
||||||
|
a++; |
||||||
|
ground[x].y += a * a * 0.01; |
||||||
|
} |
||||||
|
else if (ground[x].biome != LAKE && ground[x - cliffDispo * 2].biome == LAKE){ |
||||||
|
a--; |
||||||
|
ground[x].y += a * a * 0.01; |
||||||
|
} |
||||||
|
else if (ground[x].biome == LAKE) a = cliffDispo * 2; |
||||||
|
else a = 0; |
||||||
|
}catch(e){} |
||||||
|
x++; |
||||||
|
} |
||||||
|
|
||||||
|
//End progress if bar is full
|
||||||
|
if (createProgress == worldWidth * 2){ |
||||||
|
clearInterval(interval); |
||||||
|
trees.shuffle(); |
||||||
|
clouds.shuffle(); |
||||||
|
birds.shuffle(); |
||||||
|
$("#toolBarOpener").show(); |
||||||
|
gameIsRunning = true; |
||||||
|
} |
||||||
|
if (createProgress < worldWidth * 2){ |
||||||
|
setTimeout(create, 0); |
||||||
|
} |
||||||
|
} |
||||||
|
let interval = setInterval(create, 0); |
||||||
|
} |
||||||
|
|
||||||
|
function downloadWorld(){ |
||||||
|
let newGround = [],
|
||||||
|
newTrees = [],
|
||||||
|
newBirds = [],
|
||||||
|
newClouds= [], |
||||||
|
worldValues = [{time: time, viewPort: {x: viewPort.x, y: viewPort.y}}]; |
||||||
|
for (let g of ground) newGround.push({y: round(g.y), b: g.biome, w: g.isWooden ? 1 : 0}); |
||||||
|
for (let t of trees) newTrees.push({x: round(t.x), w: round(t.width), h: round(t.height), c: t.color}); |
||||||
|
for (let b of birds) newBirds.push({x: round(b.x), y: round(b.y), v: round(b.v * 100) / 100, l: round(b.length)}); |
||||||
|
for (let c of clouds) newClouds.push({x: round(c.x), y: round(c.y), w: round(c.width), h: round(c.height), b: round(c.brightness * 100) / 100}); |
||||||
|
let str = |
||||||
|
JSON.stringify(newGround.partitiate(1)) + ", " |
||||||
|
+ JSON.stringify(newTrees.partitiate(1)) + ", " |
||||||
|
+ JSON.stringify(newBirds.partitiate(1)) + ", " |
||||||
|
+ JSON.stringify(newClouds.partitiate(1)) + ", " |
||||||
|
+ JSON.stringify(worldValues); |
||||||
|
let data = 'data:application/json;charset=utf-8,['+ encodeURIComponent(str) + "]"; |
||||||
|
$("#saveLink").attr("href", data); |
||||||
|
$("#saveLink")[0].click(); |
||||||
|
} |
||||||
|
|
||||||
|
function uploadWorld(){ |
||||||
|
gameIsRunning = false; |
||||||
|
let files = document.getElementById("fileBrowser").files; |
||||||
|
let fr = new FileReader(), recovery = {ground: ground, trees: trees, birds: birds, clouds: clouds, time: time, viewPort: viewPort}; |
||||||
|
fr.onload = function(e){ |
||||||
|
try{ |
||||||
|
let data = JSON.parse(e.target.result); |
||||||
|
let newGround = data[0].departitiate(); |
||||||
|
let newTrees = data[1].departitiate(); |
||||||
|
let newBirds = data[2].departitiate(); |
||||||
|
let newClouds = data[3].departitiate(); |
||||||
|
|
||||||
|
ground = [], trees = [], birds = [], clouds = []; |
||||||
|
|
||||||
|
for (let g of newGround) ground.push({y: g.y, biome: g.b, isWooden: g.w == 1 ? true : false}); |
||||||
|
for (let t of newTrees){ |
||||||
|
let i = newTrees.indexOf(t); |
||||||
|
trees.push(new Tree(t.x, t.w, t.h)); |
||||||
|
trees[i].color = t.c; |
||||||
|
} |
||||||
|
for (let b of newBirds){ |
||||||
|
let i = newBirds.indexOf(b); |
||||||
|
birds.push(new Bird(b.x)); |
||||||
|
birds[i].y = b.y; |
||||||
|
birds[i].v = b.v; |
||||||
|
birds[i].length = b.l; |
||||||
|
} |
||||||
|
for (let c of newClouds){ |
||||||
|
let i = newClouds.indexOf(c); |
||||||
|
clouds.push(new Cloud(c.x, c.y, c.w, c.h)); |
||||||
|
clouds[i].brightness = c.b; |
||||||
|
} |
||||||
|
|
||||||
|
time = data[4][0].time; |
||||||
|
viewPort = {x: data[4][0].viewPort.x, y: data[4][0].viewPort.y, v: recovery.viewPort.v}; |
||||||
|
$("#restoreWorld, #createWorld").hide(); |
||||||
|
$("#toolBarOpener").show(); |
||||||
|
|
||||||
|
} catch(e){ |
||||||
|
ground = recovery.ground; |
||||||
|
trees = recovery.trees; |
||||||
|
birds = recovery.birds; |
||||||
|
clouds = recovery.clouds; |
||||||
|
time = recovery.time; |
||||||
|
viewPort = recovery.viewPort; |
||||||
|
waveDispo = recovery.waveDispo; |
||||||
|
window.alert("Data is damaged!"); |
||||||
|
} |
||||||
|
|
||||||
|
if (ground.length > 0) gameIsRunning = true; |
||||||
|
else {$("#restoreWorld, #createWorld").show();} |
||||||
|
} |
||||||
|
fr.readAsText(files.item(0)); |
||||||
|
} |
||||||
|
|
||||||
|
function draw(){ |
||||||
|
if (gameIsRunning){ |
||||||
|
clear(); |
||||||
|
translate(-viewPort.x, -viewPort.y); |
||||||
|
updateUnits(); |
||||||
|
updateGround(); |
||||||
|
updateTime(); |
||||||
|
checkViewPort(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function updateUnits(){ |
||||||
|
//Sky
|
||||||
|
background(160, 160, 255); |
||||||
|
|
||||||
|
//Clouds
|
||||||
|
for (let c of clouds){ |
||||||
|
c.move(); |
||||||
|
c.show(); |
||||||
|
} |
||||||
|
|
||||||
|
//Birds
|
||||||
|
for (let b of birds){ |
||||||
|
b.move(); |
||||||
|
b.show(); |
||||||
|
} |
||||||
|
|
||||||
|
//Trees
|
||||||
|
for (let t of trees){ |
||||||
|
t.show(); |
||||||
|
} |
||||||
|
|
||||||
|
//Humans
|
||||||
|
for (let h of humans){ |
||||||
|
h.move(); |
||||||
|
h.show(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function updateGround(){ |
||||||
|
let x, y, lake = false, grassH = 20, waveH = 2; |
||||||
|
waveDispo += 1; |
||||||
|
waveDispo %= 8 * PI; |
||||||
|
function wave(x){ |
||||||
|
return sin((0.25 * (x - waveDispo))) * 3; |
||||||
|
} |
||||||
|
|
||||||
|
// grass
|
||||||
|
fill(100, 200, 100); |
||||||
|
beginShape(); |
||||||
|
for (x = viewPort.x; x <= viewPort.x + width; x++){ |
||||||
|
//console.log(x);
|
||||||
|
let g = ground[x]; |
||||||
|
if (g.biome == LAKE) |
||||||
|
vertex(x, height); |
||||||
|
else |
||||||
|
vertex(x, g.y); |
||||||
|
} |
||||||
|
for (x = viewPort.x + width; x >= viewPort.x; x--){ |
||||||
|
let g = ground[x]; |
||||||
|
if (g.biome == LAKE) |
||||||
|
vertex(x, height); |
||||||
|
else |
||||||
|
vertex(x, g.y + grassH); |
||||||
|
} |
||||||
|
endShape(); |
||||||
|
|
||||||
|
// water
|
||||||
|
fill(100, 100, 255); |
||||||
|
beginShape(); |
||||||
|
for (x = viewPort.x; x <= viewPort.x + width; x++){ |
||||||
|
let g = ground[x]; |
||||||
|
if (g.biome == LAKE) |
||||||
|
vertex(x, g.y + grassH / 2 + waveH + cliffDispo + wave(x)); |
||||||
|
else |
||||||
|
vertex(x, height); |
||||||
|
} |
||||||
|
for (x = viewPort.x + width - 1; x >= viewPort.x; x--){ |
||||||
|
vertex(x, height); |
||||||
|
} |
||||||
|
endShape(); |
||||||
|
|
||||||
|
// water --> waves
|
||||||
|
fill(50, 50, 255); |
||||||
|
beginShape(); |
||||||
|
for (x = viewPort.x; x <= viewPort.x + width; x++){ |
||||||
|
let g = ground[x]; |
||||||
|
if (g.biome == LAKE) |
||||||
|
vertex(x, g.y + grassH / 2 + cliffDispo + wave(x)); |
||||||
|
else |
||||||
|
vertex(x, height); |
||||||
|
} |
||||||
|
for (x = viewPort.x + width - 1; x >= viewPort.x; x--){ |
||||||
|
let g = ground[x]; |
||||||
|
if (g.biome == LAKE) |
||||||
|
vertex(x, g.y + grassH / 2 + cliffDispo + wave(x) + waveH); |
||||||
|
else |
||||||
|
vertex(x, height); |
||||||
|
} |
||||||
|
endShape(); |
||||||
|
|
||||||
|
// dirt
|
||||||
|
fill(80, 60, 40); |
||||||
|
beginShape(); |
||||||
|
for (x = viewPort.x; x <= viewPort.x + width; x++){ |
||||||
|
let g = ground[x]; |
||||||
|
if (g.biome == LAKE) |
||||||
|
vertex(x, height); |
||||||
|
else |
||||||
|
vertex(x, g.y + grassH); |
||||||
|
} |
||||||
|
for (x = viewPort.x + width; x >= viewPort.x; x--){ |
||||||
|
vertex(x, height); |
||||||
|
} |
||||||
|
endShape(); |
||||||
|
} |
||||||
|
|
||||||
|
function updateTime(){ |
||||||
|
function getDayBrightness(){ |
||||||
|
let value = sin(PI / 12 * (time - 8)) + 0.25; |
||||||
|
value = value > 1 ? 1 : value; |
||||||
|
value = value < 0.1 ? 0.1 : value; |
||||||
|
return value; |
||||||
|
} |
||||||
|
let timeTick = 24 / (60 * cycleTime * frameRate()); |
||||||
|
time += (timeTick == Infinity ? 0 : timeTick); |
||||||
|
fill(0, 0, 0, 255 - 255 * getDayBrightness()); |
||||||
|
rect(viewPort.x, viewPort.y, width, height); |
||||||
|
} |
||||||
|
|
||||||
|
function checkViewPort(){ |
||||||
|
let scrollBegin = 100; |
||||||
|
if (winMouseX <= scrollBegin && viewPort.x > 0)
|
||||||
|
viewPort.x -= round(viewPort.v * (scrollBegin - winMouseX) / scrollBegin); |
||||||
|
if (winMouseX >= width - scrollBegin && viewPort.x < worldWidth - width - viewPort.v)
|
||||||
|
viewPort.x += round(viewPort.v * (winMouseX - (width - scrollBegin)) / scrollBegin); |
||||||
|
if (viewPort.x < 0) viewPort.x = 0; |
||||||
|
if (viewPort.x >= worldWidth + width) viewPort.x = worldWidth - width - 1; |
||||||
|
} |
||||||
|
|
||||||
|
function togglePause(obj){ |
||||||
|
gameIsRunning = !gameIsRunning; |
||||||
|
if (gameIsRunning) $(obj).html("||"); |
||||||
|
else $(obj).html("►"); |
||||||
|
} |
||||||
|
|
||||||
|
function toggleToolBar(obj){ |
||||||
|
if ($(obj).css("top") == "0px"){ |
||||||
|
$(obj).animate({top: 103}, {top: "easeOut"}); |
||||||
|
$("#toolBar").animate({top: 0}, {top: "easeOut"}); |
||||||
|
} |
||||||
|
if ($(obj).css("top") == "103px"){ |
||||||
|
$(obj).animate({top: 0}, {top: "easeOut"}); |
||||||
|
$("#toolBar").animate({top: -103}, {top: "easeOut"}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function toggleInfo(){ |
||||||
|
$("#pauseButton")[0].click(); |
||||||
|
$("#infoWrapper").toggle(); |
||||||
|
} |
||||||
|
|
||||||
|
Array.prototype.departitiate = function(){ |
||||||
|
let newArr = []; |
||||||
|
for (let i = 0; i < this.length; i++){ |
||||||
|
let a = this[i]; |
||||||
|
for (let j = 0; j < a.length; j++){ |
||||||
|
let object = a[j]; |
||||||
|
newArr.push(object); |
||||||
|
//for (let k = 0; k < b.length; k++){}
|
||||||
|
} |
||||||
|
} |
||||||
|
return newArr; |
||||||
|
} |
@ -0,0 +1,103 @@ |
|||||||
|
a:link, a:hover, a:active, a:visited{color: #000;} |
||||||
|
|
||||||
|
body{margin: 0; padding: 0; overflow-y:hidden; overflow-x: hidden;} |
||||||
|
|
||||||
|
canvas{margin: 0; padding: 0; border: none; display: block;} |
||||||
|
|
||||||
|
button{cursor: pointer;} |
||||||
|
|
||||||
|
#toolBarOpener{ |
||||||
|
position: absolute; |
||||||
|
display: block; |
||||||
|
background-color: #FFF; |
||||||
|
left: calc((100% - 50px) / 2); |
||||||
|
top: 0; |
||||||
|
width: 50px; |
||||||
|
height: 20px; |
||||||
|
border: none; |
||||||
|
border-radius: 0 0 5px 5px; |
||||||
|
} |
||||||
|
|
||||||
|
#toolBar{ |
||||||
|
position: absolute; |
||||||
|
display: block; |
||||||
|
background-color: #F90; |
||||||
|
left: calc((100% - 371px) / 2); |
||||||
|
top: -103px; |
||||||
|
width: 335px; |
||||||
|
height: 70px; |
||||||
|
padding: 15px; |
||||||
|
border-radius: 0 0 20px 20px; |
||||||
|
border: 3px solid #000; |
||||||
|
border-top: none; |
||||||
|
} |
||||||
|
|
||||||
|
.toolBarEntry{ |
||||||
|
width: 70px; |
||||||
|
height: 70px; |
||||||
|
margin: 0 5px 0 5px; |
||||||
|
border: 3px solid #000; |
||||||
|
border-radius: 10px; |
||||||
|
background-color: #FFF; |
||||||
|
padding: 0; |
||||||
|
font-size: 50px; |
||||||
|
} |
||||||
|
|
||||||
|
#downloadButton{color: #0C0;} |
||||||
|
#uploadButton{color: #C00;} |
||||||
|
#infoButton{color: #00F;} |
||||||
|
|
||||||
|
#createWorld{ |
||||||
|
position: absolute; |
||||||
|
top: calc(100% / 2 - 50px); |
||||||
|
left: calc(100% / 2 - 220px); |
||||||
|
width: 200px; |
||||||
|
height: 100px; |
||||||
|
border: 5px solid #000; |
||||||
|
border-radius: 10px; |
||||||
|
font-size: 25px; |
||||||
|
} |
||||||
|
|
||||||
|
#restoreWorld{ |
||||||
|
position: absolute; |
||||||
|
top: calc(100% / 2 - 50px); |
||||||
|
left: calc(100% / 2 + 20px); |
||||||
|
width: 200px; |
||||||
|
height: 100px; |
||||||
|
border: 5px solid #000; |
||||||
|
border-radius: 10px; |
||||||
|
font-size: 25px; |
||||||
|
} |
||||||
|
|
||||||
|
#infoWrapper{ |
||||||
|
position: absolute; |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
z-index: 5; |
||||||
|
background-color: rgba(0, 0, 0, 0.3); |
||||||
|
} |
||||||
|
|
||||||
|
#info{ |
||||||
|
position: absolute; |
||||||
|
width: 600px; |
||||||
|
height: 400px; |
||||||
|
margin: auto; |
||||||
|
top: 0; |
||||||
|
bottom: 0; |
||||||
|
left: 0; |
||||||
|
right: 0; |
||||||
|
border: 7px solid #333; |
||||||
|
border-radius: 30px; |
||||||
|
font-size: 25px; |
||||||
|
background-color: #999; |
||||||
|
} |
||||||
|
|
||||||
|
#info button{ |
||||||
|
width: 100px; |
||||||
|
height: 50px; |
||||||
|
margin: 30px; |
||||||
|
background-color: #0C0; |
||||||
|
border: 3px solid #080; |
||||||
|
border-radius: 5px; |
||||||
|
font-size: 30px; |
||||||
|
} |
After Width: | Height: | Size: 107 KiB |
Loading…
Reference in new issue