game engine test
This commit is contained in:
parent
105aac8fd0
commit
5ab4e05afe
4 changed files with 167 additions and 67 deletions
27
game.css
Normal file
27
game.css
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
.message {
|
||||||
|
position: relative;
|
||||||
|
bottom: 800px;
|
||||||
|
width: 800px;
|
||||||
|
height: 800px;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
background: rgba(0,0,0,0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.message span {
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
color: rgb(255,255,255);
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#canvas {
|
||||||
|
width: 800px;
|
||||||
|
height: 800px;
|
||||||
|
image-rendering: pixelated
|
||||||
|
}
|
31
index.html
31
index.html
|
@ -1,16 +1,21 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
|
||||||
<link rel="stylesheet" href="https://dervland.net/index.css">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<section id='main'>
|
|
||||||
<h1>Fractal Hell</h1>
|
|
||||||
<canvas style='width: 800px; height: 800px; image-rendering: pixelated' id='canvas'>
|
|
||||||
</section>
|
|
||||||
<script src='js/perlin.js'></script>
|
|
||||||
<script src='js/index.js'></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="https://dervland.net/index.css">
|
||||||
|
<link rel='stylesheet' href='game.css'>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<section id='main'>
|
||||||
|
<h1>Fractal Hell</h1>
|
||||||
|
<canvas id='canvas'></canvas>
|
||||||
|
<div class='message' style='display: none;'><span>You died in the Void...</span></div>
|
||||||
|
</section>
|
||||||
|
<script src='js/perlin.js'></script>
|
||||||
|
<script src='js/index.js'></script>
|
||||||
|
<script src='js/motion.js'></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
147
js/index.js
147
js/index.js
|
@ -1,16 +1,11 @@
|
||||||
const width = 8 ** 3;
|
//const width = 2048;
|
||||||
const height = 8 ** 3;
|
//const height = 2048;
|
||||||
|
const tileSize = 8;
|
||||||
function validXY(x, y) {
|
|
||||||
if (x < 0 || x >= width) return false;
|
|
||||||
if (y < 0 || y >= height) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getRGBA(data, i) {
|
function getRGBA(data, i) {
|
||||||
let out = new Uint8Array(4);
|
let out = new Uint8Array(4);
|
||||||
for (let j = i * 4; j < i * 4 + 4; j++) {
|
for (let j = i * 4; j < i * 4 + 4; j++) {
|
||||||
out[j - i*4] = data[j];
|
out[j - i * 4] = data[j];
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -21,55 +16,83 @@ function setRGBA(data, i, input) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Game(inSize) {
|
function toPoint(x2, y2, base, fac, exp, inSize) {
|
||||||
this.img = new Image();
|
let isMask = 1;
|
||||||
|
x2 = Math.round(x2 / tileSize);
|
||||||
|
y2 = Math.round(y2 / tileSize);
|
||||||
|
for (let j = 0; j < exp; j++) {
|
||||||
|
isMask *= base[(y2 % inSize) * inSize + (x2 % inSize)];
|
||||||
|
|
||||||
|
x2 /= inSize;
|
||||||
|
y2 /= inSize;
|
||||||
|
|
||||||
|
x2 = Math.floor(x2);
|
||||||
|
y2 = Math.floor(y2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
isMask *= fac;
|
||||||
|
|
||||||
|
isMask = (isMask - 0.5) * 25 + 0.5;
|
||||||
|
isMask = Math.max(isMask, 0);
|
||||||
|
isMask = Math.min(isMask, 1);
|
||||||
|
return isMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Game(inSize, exp, cs) {
|
||||||
|
this.exp = exp;
|
||||||
this.inSize = inSize;
|
this.inSize = inSize;
|
||||||
|
this.cs = cs;
|
||||||
|
|
||||||
|
this.img = new Image();
|
||||||
this.base = new Float32Array(inSize * inSize);
|
this.base = new Float32Array(inSize * inSize);
|
||||||
|
this.frames = 0;
|
||||||
|
this.camera = [0, 0];
|
||||||
|
|
||||||
|
this.dead = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Game.prototype.main = function() {
|
Game.prototype.main = function () {
|
||||||
var {base, inSize, ctx} = this;
|
var { base, inSize, ctx, cs, frames, exp, camera, dat } = this;
|
||||||
|
if (this.dead) {
|
||||||
var dat = ctx.getImageData(0,0,width,height);
|
document.querySelector('.message').style.display = 'flex';
|
||||||
|
return;
|
||||||
for (let i = 0; i < base.length; i++) {
|
} else {
|
||||||
base[i] = Math.max(base[i] * 0.99999,0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let exp = Math.ceil(Math.log(width) - Math.log(inSize));
|
this.frames++;
|
||||||
|
|
||||||
for (let i = 0; i < dat.data.length / 4; i++) {
|
this.fac = 0.9999 ** frames;
|
||||||
let x = i % width;
|
for (let i = 0; i < cs * cs; i++) {
|
||||||
let y = Math.floor(i / width);
|
let x = i % cs
|
||||||
|
let y = Math.floor(i / cs);
|
||||||
|
|
||||||
let x2 = x;
|
x = x + Math.round(camera[0] - cs / 2);
|
||||||
let y2 = y;
|
y = y + Math.round(camera[1] - cs / 2);
|
||||||
|
|
||||||
let isMask = 1;
|
let isMask = toPoint(x, y, base, this.fac, exp, inSize);
|
||||||
|
if (x < 0 || y < 0) {
|
||||||
for (let j = 0; j < exp; j++) {
|
setRGBA(dat.data, i, [0, 0, 0, 255])
|
||||||
isMask *= base[(y2 % inSize) * inSize + (x2 % inSize)];
|
continue;
|
||||||
|
|
||||||
x2 /= inSize;
|
|
||||||
y2 /= inSize;
|
|
||||||
|
|
||||||
x2 = Math.floor(x2);
|
|
||||||
y2 = Math.floor(y2);
|
|
||||||
}
|
}
|
||||||
|
let rgb = [(Math.round(x / tileSize) % 2) ? 255 : 235, (Math.round(y / tileSize) % 2) ? 255 : 235, 255];
|
||||||
|
|
||||||
isMask = (isMask - 0.5) * 100 + 0.5;
|
setRGBA(dat.data, i, [rgb[0] * isMask, rgb[1] * isMask, rgb[2] * isMask, 255])
|
||||||
isMask = Math.max(isMask,0);
|
|
||||||
isMask = Math.min(isMask,1);
|
|
||||||
isMask *= 255;
|
|
||||||
|
|
||||||
setRGBA(dat.data,i,[isMask,isMask,isMask,255])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.putImageData(dat,0,0,0,0,width,height);
|
ctx.putImageData(dat, 0, 0, 0, 0, cs, cs);
|
||||||
|
|
||||||
|
ctx.fillStyle = 'red';
|
||||||
|
ctx.rect(cs / 2 - 2, cs / 2 - 2,4,4);
|
||||||
|
ctx.fill();
|
||||||
|
|
||||||
|
if (toPoint(camera[0], camera[1], base, this.fac, exp, inSize) == 0 ){
|
||||||
|
this.dead = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Game.prototype.map = function() {
|
Game.prototype.map = function () {
|
||||||
var {base, inSize} = this;
|
var { base, inSize, exp } = this;
|
||||||
|
|
||||||
//noise.seed(Math.random() * 1000);
|
//noise.seed(Math.random() * 1000);
|
||||||
|
|
||||||
|
@ -79,35 +102,51 @@ Game.prototype.map = function() {
|
||||||
|
|
||||||
base[i] = Math.random();
|
base[i] = Math.random();
|
||||||
|
|
||||||
base[i] = Math.max(base[i],0);
|
base[i] = Math.max(base[i], 0);
|
||||||
base[i] = Math.min(base[i],1);
|
base[i] = Math.min(base[i], 1);
|
||||||
base[i] = Math.pow(base[i],0.3);
|
base[i] = Math.pow(base[i], 0.3);
|
||||||
base[i] = base[i] * 0.4 + 0.6;
|
base[i] = base[i] * 0.4 + 0.6;
|
||||||
//base[i] = (Math.random() > 0.5) ? 0 : 1;
|
//base[i] = (Math.random() > 0.5) ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.fac = 1;
|
||||||
|
|
||||||
|
let x2 = 0, y2 = 0;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
x2 = Math.random() * 1e5;
|
||||||
|
y2 = Math.random() * 1e5;
|
||||||
|
let mask = toPoint(x2, y2, base, this.fac, exp, inSize);
|
||||||
|
if (mask == 1) break;
|
||||||
|
}
|
||||||
|
this.camera = [x2, y2];
|
||||||
}
|
}
|
||||||
|
|
||||||
Game.prototype.loop = function() {
|
Game.prototype.loop = function () {
|
||||||
let that = this;
|
let that = this;
|
||||||
setInterval(function() { that.main() } ,1000 / 60);
|
setInterval(function () { that.main() }, 1000 / 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
Game.prototype.startGame = function() {
|
Game.prototype.startGame = function () {
|
||||||
var canvas = document.querySelector("#canvas");
|
var canvas = document.querySelector("#canvas");
|
||||||
canvas.width = width;
|
canvas.width = this.cs;
|
||||||
canvas.height = height;
|
canvas.height = this.cs;
|
||||||
|
|
||||||
var ctx = this.ctx = canvas.getContext("2d",{ willReadFrequently: true });
|
var ctx = this.ctx = canvas.getContext("2d");
|
||||||
|
|
||||||
ctx.imageSmoothingEnabled = false;
|
ctx.imageSmoothingEnabled = false;
|
||||||
|
|
||||||
|
this.dat = ctx.getImageData(0, 0, this.cs, this.cs);
|
||||||
|
|
||||||
this.map();
|
this.map();
|
||||||
this.loop();
|
this.loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
Game.prototype.init = function() {
|
Game.prototype.init = function () {
|
||||||
let that = this;
|
let that = this;
|
||||||
that.startGame();
|
that.startGame();
|
||||||
}
|
}
|
||||||
|
|
||||||
new Game(8).init();
|
let game = new Game(8, 4, 32 * tileSize)
|
||||||
|
|
||||||
|
game.init();
|
||||||
|
|
29
js/motion.js
Normal file
29
js/motion.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
let keys = [];
|
||||||
|
let vel = [0, 0];
|
||||||
|
|
||||||
|
let id = '';
|
||||||
|
|
||||||
|
function down(e) {
|
||||||
|
keys[e.key.toLowerCase()] = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
function up(e) {
|
||||||
|
keys[e.key.toLowerCase()] = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
function move() {
|
||||||
|
var isShift = keys['q'];
|
||||||
|
vel[0] += ((keys['a'] ? 1 : 0) - (keys['d'] ? 1 : 0)) * (isShift ? 5 : 1);
|
||||||
|
vel[1] += ((keys['w'] ? 1 : 0) - (keys['s'] ? 1 : 0)) * (isShift ? 5 : 1);
|
||||||
|
|
||||||
|
vel[0] *= 0.8;
|
||||||
|
vel[1] *= 0.8;
|
||||||
|
|
||||||
|
game.camera[0] -= vel[0] * 0.2;
|
||||||
|
game.camera[1] -= vel[1] * 0.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
setInterval(move, 10);
|
||||||
|
|
||||||
|
window.addEventListener('keydown', down);
|
||||||
|
window.addEventListener('keyup', up);
|
Loading…
Reference in a new issue