Move game logic to a new module
This commit is contained in:
parent
b08479af40
commit
5372d1b417
2 changed files with 100 additions and 50 deletions
98
src/controller/gamecontext.ts
Normal file
98
src/controller/gamecontext.ts
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
import MapData from '../model/data/MapData';
|
||||||
|
|
||||||
|
import { loadSimpleEntity } from '../view/entity';
|
||||||
|
import DirectionHandler from '../view/input/DirectionHandler';
|
||||||
|
import { loadMap } from '../view/map';
|
||||||
|
import Renderer from '../view/renderer/Renderer';
|
||||||
|
import { SpriteView } from '../view/sprite';
|
||||||
|
|
||||||
|
import { getJSON } from '../util';
|
||||||
|
|
||||||
|
import { vec2 } from 'gl-matrix';
|
||||||
|
|
||||||
|
function snapToGrid(out: vec2, a: vec2): void {
|
||||||
|
const res = 64;
|
||||||
|
|
||||||
|
vec2.scale(out, a, res);
|
||||||
|
vec2.round(out, out);
|
||||||
|
vec2.scale(out, out, 1 / res);
|
||||||
|
}
|
||||||
|
|
||||||
|
export class GameContext {
|
||||||
|
public static async load(renderer: Renderer): Promise<GameContext> {
|
||||||
|
const [
|
||||||
|
mapView,
|
||||||
|
entity,
|
||||||
|
] = await Promise.all([
|
||||||
|
GameContext.loadMap(renderer),
|
||||||
|
loadSimpleEntity(renderer, 'simple_square'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return new GameContext(
|
||||||
|
renderer,
|
||||||
|
mapView,
|
||||||
|
entity,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async loadMap(renderer: Renderer): Promise<SpriteView> {
|
||||||
|
const map = new MapData(await getJSON('resources/map/test.json'));
|
||||||
|
return loadMap(renderer, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
private time: number|null = null;
|
||||||
|
|
||||||
|
private readonly speed = 1 / 100;
|
||||||
|
|
||||||
|
private readonly input: DirectionHandler;
|
||||||
|
|
||||||
|
private readonly entityPos: vec2 = vec2.create();
|
||||||
|
private readonly entityMovement: vec2 = vec2.create();
|
||||||
|
|
||||||
|
private constructor(
|
||||||
|
private readonly renderer: Renderer,
|
||||||
|
private readonly mapView: SpriteView,
|
||||||
|
private readonly entity: SpriteView,
|
||||||
|
) {
|
||||||
|
this.input = new DirectionHandler();
|
||||||
|
this.input.addListener((v) => {
|
||||||
|
if (vec2.sqrLen(v) > 0)
|
||||||
|
vec2.normalize(this.entityMovement, v);
|
||||||
|
else
|
||||||
|
vec2.copy(this.entityMovement, [0, 0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
window.requestAnimationFrame(this.render);
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateTime(time: number): number {
|
||||||
|
let diff = 0;
|
||||||
|
if (this.time !== null)
|
||||||
|
diff = time - this.time;
|
||||||
|
|
||||||
|
this.time = time;
|
||||||
|
|
||||||
|
return diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
private update(time: number): void {
|
||||||
|
const diff = this.updateTime(time);
|
||||||
|
|
||||||
|
vec2.scaleAndAdd(this.entityPos, this.entityPos, this.entityMovement, diff * this.speed);
|
||||||
|
snapToGrid(this.entityPos, this.entityPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
private render = (time: number) => {
|
||||||
|
this.update(time);
|
||||||
|
|
||||||
|
this.renderer.setCenter(this.entityPos);
|
||||||
|
this.renderer.clear();
|
||||||
|
|
||||||
|
this.mapView.render();
|
||||||
|
|
||||||
|
this.renderer.setTranslation(this.entityPos);
|
||||||
|
this.entity.render();
|
||||||
|
|
||||||
|
window.requestAnimationFrame(this.render);
|
||||||
|
}
|
||||||
|
}
|
52
src/index.ts
52
src/index.ts
|
@ -1,61 +1,13 @@
|
||||||
import MapData from './model/data/MapData';
|
import { GameContext } from './controller/gamecontext';
|
||||||
|
|
||||||
import { vec2 } from 'gl-matrix';
|
|
||||||
|
|
||||||
import { getJSON } from './util';
|
|
||||||
import { loadSimpleEntity } from './view/entity';
|
|
||||||
import DirectionHandler from './view/input/DirectionHandler';
|
|
||||||
import { loadMap } from './view/map';
|
|
||||||
import Renderer from './view/renderer/Renderer';
|
import Renderer from './view/renderer/Renderer';
|
||||||
|
|
||||||
const entityPos = vec2.create();
|
|
||||||
const entityMovement = vec2.create();
|
|
||||||
|
|
||||||
window.onload = async () => {
|
window.onload = async () => {
|
||||||
const canvas = document.getElementById('rpgedit') as HTMLCanvasElement;
|
const canvas = document.getElementById('rpgedit') as HTMLCanvasElement;
|
||||||
if (!canvas)
|
if (!canvas)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const input = new DirectionHandler();
|
|
||||||
input.addListener((v) => {
|
|
||||||
if (vec2.sqrLen(v) > 0)
|
|
||||||
vec2.normalize(entityMovement, v);
|
|
||||||
else
|
|
||||||
vec2.copy(entityMovement, [0, 0]);
|
|
||||||
});
|
|
||||||
|
|
||||||
const renderer = new Renderer(canvas);
|
const renderer = new Renderer(canvas);
|
||||||
|
|
||||||
const map = new MapData(await getJSON('resources/map/test.json'));
|
await GameContext.load(renderer);
|
||||||
const mapView = await loadMap(renderer, map);
|
|
||||||
|
|
||||||
const entity = await loadSimpleEntity(renderer, 'simple_square');
|
|
||||||
|
|
||||||
let prevTime: number|null = null;
|
|
||||||
|
|
||||||
const render = (time: number) => {
|
|
||||||
const res = 64;
|
|
||||||
|
|
||||||
let diff = 0;
|
|
||||||
if (prevTime !== null)
|
|
||||||
diff = time - prevTime;
|
|
||||||
prevTime = time;
|
|
||||||
|
|
||||||
vec2.scaleAndAdd(entityPos, entityPos, entityMovement, diff / 100);
|
|
||||||
vec2.scale(entityPos, entityPos, res);
|
|
||||||
vec2.round(entityPos, entityPos);
|
|
||||||
vec2.scale(entityPos, entityPos, 1 / res);
|
|
||||||
|
|
||||||
renderer.setCenter(entityPos);
|
|
||||||
renderer.clear();
|
|
||||||
|
|
||||||
mapView.render();
|
|
||||||
|
|
||||||
renderer.setTranslation(entityPos);
|
|
||||||
entity.render();
|
|
||||||
|
|
||||||
window.requestAnimationFrame(render);
|
|
||||||
};
|
|
||||||
|
|
||||||
window.requestAnimationFrame(render);
|
|
||||||
};
|
};
|
||||||
|
|
Reference in a new issue