Browse Source

started something game-y

master
mortie 3 years ago
commit
a82e29c75e
12 changed files with 2452 additions and 0 deletions
  1. 3
    0
      .babelrc
  2. 2
    0
      .gitignore
  3. 51
    0
      js/Entity.js
  4. 65
    0
      js/Level.js
  5. 45
    0
      js/Rect.js
  6. 11
    0
      js/Vec2.js
  7. 17
    0
      js/entities/Player.js
  8. 9
    0
      js/main.js
  9. 34
    0
      js/traits/KeyboardControls.js
  10. 2176
    0
      package-lock.json
  11. 19
    0
      package.json
  12. 20
    0
      public/index.html

+ 3
- 0
.babelrc View File

@@ -0,0 +1,3 @@
{
"presets": ["env"]
}

+ 2
- 0
.gitignore View File

@@ -0,0 +1,2 @@
public/bundle.js
node_modules

+ 51
- 0
js/Entity.js View File

@@ -0,0 +1,51 @@
import Rect from './Rect';
import Vec2 from './Vec2';

export class Trait {
constructor(entity, name) {
this.name = name;
this.entity = entity;
this.enabled = true;
}

init() {}
update(dt) {}
}

export default class Entity {
constructor(level) {
this.level = level;
this.bounds = new Rect();
this.velocity = new Vec2();
this.t = {};
this.traits = [];
}

init() {
for (let trait of this.traits) {
trait.init();
}
}

update(dt) {
for (let trait of this.traits) {
if (trait.enabled)
trait.update(dt);
}

this.bounds.pos.x += this.velocity.x * dt;
this.bounds.pos.y += this.velocity.y * dt;
}

draw(ctx) {}

has(name) {
let t = this.t[name];
return t != null && t.enabled;
}

addTrait(t) {
this.t[t.name] = t;
this.traits.push(t);
}
}

+ 65
- 0
js/Level.js View File

@@ -0,0 +1,65 @@
import Player from './entities/Player';

export default class Level {
constructor(canvas) {
this.step = 1 / 120;

this.canvas = canvas;
this.ctx = canvas.getContext("2d");
this.lastTime = null;
this.raf = null;
this.timeAcc = 0;
this.entities = [];
}

spawn(ent, x, y) {
ent.bounds.pos.set(x, y);
this.entities.push(ent);
ent.init();
}

physics(dt) {
this.entities.forEach(ent =>
ent.update(dt));
this.entities.forEach(ent => {
ent.bounds.pos.x += ent.velocity.x * dt;
ent.bounds.pos.y += ent.velocity.y * dt;
});
}

draw() {
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;
this.entities.forEach(ent => ent.draw(this.ctx));
}

update(time) {
if (this.lastTime != null) {
let dt = (time - this.lastTime) / 1000;

this.timeAcc += dt;
while (this.timeAcc > this.step) {
this.physics(this.step);
this.timeAcc -= this.step;
}

this.draw();
}

this.lastTime = time;
this.raf = requestAnimationFrame(time => this.update(time));
}

start() {
this.stop();
this.lastTime = null;
this.update();
}

stop() {
if (this.raf != null) {
cancelAnimationFrame(this.raf);
this.raf = null;
}
}
}

+ 45
- 0
js/Rect.js View File

@@ -0,0 +1,45 @@
import Vec2 from './Vec2';

export default class Rect {
constructor(pos = new Vec2(), size = new Vec2()) {
this.pos = pos;
this.size = size;
}

draw(ctx) {
ctx.moveTo(this.left, this.top);
ctx.lineTo(this.right, this.top);
ctx.lineTo(this.right, this.bottom);
ctx.lineTo(this.left, this.bottom);
ctx.closePath();
ctx.stroke();
}

get top() {
return this.pos.y;
}
set top(n) {
this.pos.y = n;
}

get bottom() {
return this.pos.y + this.size.y;
}
set bottom(n) {
this.pos.y = n - this.size.y;
}

get left() {
return this.pos.x;
}
set left(n) {
this.pos.x = n;
}

get right() {
return this.pos.x + this.size.x;
}
set right(n) {
this.pos.x = n - this.size.x;
}
}

+ 11
- 0
js/Vec2.js View File

@@ -0,0 +1,11 @@
export default class Vec2 {
constructor(x = 0, y = 0) {
this.x = x;
this.y = y;
}

set(x, y) {
this.x = x;
this.y = y;
}
}

+ 17
- 0
js/entities/Player.js View File

@@ -0,0 +1,17 @@
import Entity from '../Entity';
import Vec2 from '../Vec2';

import KeyboardControls from '../traits/KeyboardControls';

export default class Player extends Entity {
constructor(level) {
super(level);

this.bounds.size.set(20, 20);
this.addTrait(new KeyboardControls(this));
}

draw(ctx) {
this.bounds.draw(ctx);
}
}

+ 9
- 0
js/main.js View File

@@ -0,0 +1,9 @@
import Level from './Level';
import Player from './entities/Player';
import Vec2 from './Vec2';

let level = new Level(document.getElementById("canvas"));

level.spawn(new Player(level), 20, 20);

level.start();

+ 34
- 0
js/traits/KeyboardControls.js View File

@@ -0,0 +1,34 @@
import {Trait} from '../Entity';

export default class KeyboardControls extends Trait {
constructor(entity) {
super(entity, "keyboardControls");

this.speed = 500;
this.map = {
KeyA: 'left',
KeyD: 'right',
};

this.pressed = {};
}

onkey(evt) {
let name = this.map[evt.code];
if (name == null) return;
evt.preventDefault();
this.pressed[name] = evt.type === 'keydown';
}

init() {
window.addEventListener("keydown", e => this.onkey(e));
window.addEventListener("keyup", e => this.onkey(e));
}

update(dt) {
if (this.pressed.left)
this.entity.velocity.x -= this.speed * dt;
if (this.pressed.right)
this.entity.velocity.x += this.speed * dt;
}
}

+ 2176
- 0
package-lock.json
File diff suppressed because it is too large
View File


+ 19
- 0
package.json View File

@@ -0,0 +1,19 @@
{
"name": "smartgame",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build-dbg": "browserify js/main.js -t [ babelify --sourceMap ] --debug --outfile public/bundle.js",
"build-prod": "browserify js/main.js -t [ babelify --sourceMap ] --outfile public/bundle.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-preset-env": "^1.6.1",
"babelify": "^8.0.0",
"browserify": "^14.5.0"
}
}

+ 20
- 0
public/index.html View File

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Game</title>
<style>
body {
margin: 0;
}

canvas {
display: block;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="bundle.js"></script>
</body>
</html>

Loading…
Cancel
Save