Compare commits
No commits in common. "4258619517fc04a9dde1aa6119c72b7b2d1baea8" and "a09b58b54c19673d3b699b069d0c7683053e27d3" have entirely different histories.
4258619517
...
a09b58b54c
14 changed files with 86 additions and 223 deletions
|
@ -6,11 +6,12 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"css-loader": "^0.23.1",
|
||||
"html-webpack-plugin": "^1.7.0",
|
||||
"lodash": "^3.10.1",
|
||||
"style-loader": "^0.13.1",
|
||||
"style-loader": "^0.13.0",
|
||||
"ts-loader": "^0.7.2",
|
||||
"typescript": "^1.8.10",
|
||||
"webpack": "^1.13.1",
|
||||
"webpack-dev-server": "^1.14.1"
|
||||
"typescript": "^1.7.5",
|
||||
"webpack": "^1.12.9",
|
||||
"webpack-dev-server": "^1.14.0"
|
||||
}
|
||||
}
|
||||
|
|
12
src/app.ts
12
src/app.ts
|
@ -11,16 +11,6 @@ import MapContext from './control/MapContext';
|
|||
import MapData from './model/MapData';
|
||||
import InputHandler from './view/InputHandler';
|
||||
|
||||
import * as util from './util';
|
||||
|
||||
|
||||
var relevantKeys = [
|
||||
InputHandler.Up,
|
||||
InputHandler.Right,
|
||||
InputHandler.Down,
|
||||
InputHandler.Left,
|
||||
];
|
||||
|
||||
|
||||
var mapContext: MapContext;
|
||||
|
||||
|
@ -29,7 +19,7 @@ window.onload = () => {
|
|||
|
||||
xhr.onload = function() {
|
||||
var mapDef = new MapData(JSON.parse(this.responseText));
|
||||
var inputHandler = new InputHandler(util.arrayToObject(relevantKeys));
|
||||
var inputHandler = new InputHandler();
|
||||
mapContext = new MapContext(mapDef, inputHandler);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,23 +13,13 @@ import MapView from '../view/MapView';
|
|||
|
||||
|
||||
export default class MapContext {
|
||||
private view: MapView;
|
||||
view: MapView;
|
||||
|
||||
private entities: EntityPosition[] = [];
|
||||
private playerEntity: EntityPosition;
|
||||
|
||||
private collision: number[][];
|
||||
entities: EntityPosition[] = [];
|
||||
playerEntity: EntityPosition;
|
||||
|
||||
|
||||
constructor(private map: MapData, private inputHandler: InputHandler) {
|
||||
this.collision = new Array(map.width);
|
||||
for (let i = 0; i < map.width; i++) {
|
||||
this.collision[i] = new Array(map.height);
|
||||
|
||||
for (let j = 0; j < map.height; j++)
|
||||
this.collision[i][j] = map.collision[j][i] == '0' ? 0 : 1;
|
||||
}
|
||||
|
||||
this.playerEntity = new EntityPosition(
|
||||
new Entity('square'),
|
||||
new Position(8, 8),
|
||||
|
@ -38,12 +28,6 @@ export default class MapContext {
|
|||
|
||||
this.addEntity(this.playerEntity);
|
||||
|
||||
this.addEntity(new EntityPosition(
|
||||
new Entity('square'),
|
||||
new Position(10, 10),
|
||||
Direction.East
|
||||
));
|
||||
|
||||
this.view = new MapView(
|
||||
map,
|
||||
this.entities,
|
||||
|
@ -57,50 +41,24 @@ export default class MapContext {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
private inMap(p: Position): boolean {
|
||||
return p.x >= 0 && p.x < this.map.width && p.y >= 0 && p.y < this.map.height;
|
||||
}
|
||||
|
||||
private incCollision(p: Position): void {
|
||||
if (this.inMap(p))
|
||||
this.collision[p.x][p.y]++;
|
||||
}
|
||||
|
||||
private decCollision(p: Position): void {
|
||||
if (this.inMap(p))
|
||||
this.collision[p.x][p.y]--;
|
||||
}
|
||||
|
||||
private collides(p: Position): boolean {
|
||||
return (!this.inMap(p)) || (this.collision[p.x][p.y] > 0);
|
||||
}
|
||||
|
||||
private addEntity(entity: EntityPosition): void {
|
||||
private addEntity(entity: EntityPosition) {
|
||||
this.entities.push(entity);
|
||||
|
||||
this.incCollision(entity.position);
|
||||
}
|
||||
|
||||
private addTransition(entity: EntityPosition, dest: Position, start: number, dur: number): void {
|
||||
private addTransition(entity: EntityPosition, dest: Position, start: number, dur: number) {
|
||||
entity.transition = new Transition(start, start+dur, entity.position, dest);
|
||||
|
||||
this.incCollision(dest);
|
||||
}
|
||||
|
||||
private finishTransition(entity: EntityPosition): void {
|
||||
this.decCollision(entity.position);
|
||||
|
||||
private finishTransition(entity: EntityPosition) {
|
||||
entity.position = entity.transition.dest;
|
||||
entity.transition = null;
|
||||
|
||||
}
|
||||
|
||||
private updateState(time: number): boolean {
|
||||
var ret = false;
|
||||
|
||||
while (true) {
|
||||
let origTime = time;
|
||||
var origTime = time;
|
||||
|
||||
if (this.playerEntity.transition && this.playerEntity.transition.end <= time) {
|
||||
origTime = this.playerEntity.transition.end;
|
||||
|
@ -111,7 +69,7 @@ export default class MapContext {
|
|||
if (this.playerEntity.transition)
|
||||
return true;
|
||||
|
||||
let dir: Direction = null;
|
||||
var dir: Direction = null;
|
||||
|
||||
if (this.inputHandler.keys[InputHandler.Up])
|
||||
dir = Direction.North;
|
||||
|
@ -126,13 +84,8 @@ export default class MapContext {
|
|||
return ret;
|
||||
|
||||
this.playerEntity.direction = dir;
|
||||
ret = true;
|
||||
|
||||
let dest = this.playerEntity.position.translate(dir, 1);
|
||||
if (this.collides(dest))
|
||||
return true;
|
||||
|
||||
this.addTransition(this.playerEntity, dest, origTime, 250);
|
||||
this.addTransition(this.playerEntity, this.playerEntity.position.translate(dir, 1),
|
||||
origTime, 250);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import Transition from './Transition';
|
|||
|
||||
|
||||
export default class EntityPosition {
|
||||
transition: Transition = null;
|
||||
public transition: Transition = null;
|
||||
|
||||
constructor(public entity: Entity, public position: Position, public direction: Direction) {}
|
||||
}
|
||||
|
|
|
@ -1,29 +1,20 @@
|
|||
'use strict';
|
||||
|
||||
|
||||
import TileData from './TileData';
|
||||
|
||||
|
||||
interface Input {
|
||||
tiles: {[key: string]: TileData};
|
||||
tiles: {[key: string]: {file: string}};
|
||||
collision: string[];
|
||||
layers: string[][][];
|
||||
}
|
||||
|
||||
export default class MapData {
|
||||
tiles: {[key: string]: TileData};
|
||||
collision: string[];
|
||||
layers: string[][][];
|
||||
|
||||
width: number;
|
||||
height: number;
|
||||
tiles: {[key: string]: {file: string}};
|
||||
public collision: string[];
|
||||
public layers: string[][][];
|
||||
|
||||
constructor(data: Input) {
|
||||
this.tiles = data.tiles;
|
||||
this.collision = data.collision;
|
||||
this.layers = data.layers;
|
||||
|
||||
this.height = this.collision.length;
|
||||
this.width = this.collision[0].length;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
|
||||
export default class TileData {
|
||||
file: string;
|
||||
subtile: number;
|
||||
}
|
13
src/util.ts
13
src/util.ts
|
@ -2,8 +2,8 @@
|
|||
|
||||
|
||||
export function mapPromises<T>(promises: {[key: string]: Promise<T>}): Promise<{[key: string]: T}> {
|
||||
var p: Promise<void>[] = [];
|
||||
var ret: {[key: string]: T} = {};
|
||||
var p: Promise<void>[] = []
|
||||
var ret: {[key: string]: T} = {}
|
||||
|
||||
_.forOwn(promises, (v, k) => {
|
||||
p.push(v.then(r => {ret[k] = r;}));
|
||||
|
@ -11,12 +11,3 @@ export function mapPromises<T>(promises: {[key: string]: Promise<T>}): Promise<{
|
|||
|
||||
return Promise.all(p).then(() => ret);
|
||||
}
|
||||
|
||||
export function arrayToObject(arr: (number|string)[]): {[key: string]: boolean} {
|
||||
var ret: {[key: string]: boolean} = {};
|
||||
|
||||
for (let v of arr)
|
||||
ret[v] = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -7,19 +7,14 @@ import Direction from '../model/Direction';
|
|||
class InputHandler {
|
||||
keys: {[key: number]: boolean} = {};
|
||||
|
||||
private listeners: (() => void)[] = [];
|
||||
listeners: (() => void)[] = [];
|
||||
|
||||
private callListeners(): void {
|
||||
private callListeners() {
|
||||
this.listeners.forEach(l => l());
|
||||
}
|
||||
|
||||
constructor(private relevantKeys: {[key: number]: boolean}) {
|
||||
constructor() {
|
||||
window.addEventListener('keydown', (ev) => {
|
||||
if (!relevantKeys[ev.keyCode])
|
||||
return;
|
||||
|
||||
ev.preventDefault();
|
||||
|
||||
if (!this.keys[ev.keyCode]) {
|
||||
this.keys[ev.keyCode] = true;
|
||||
this.callListeners();
|
||||
|
@ -27,11 +22,6 @@ class InputHandler {
|
|||
});
|
||||
|
||||
window.addEventListener('keyup', (ev) => {
|
||||
if (!relevantKeys[ev.keyCode])
|
||||
return;
|
||||
|
||||
ev.preventDefault();
|
||||
|
||||
if (this.keys[ev.keyCode]) {
|
||||
delete this.keys[ev.keyCode];
|
||||
this.callListeners();
|
||||
|
|
|
@ -5,7 +5,6 @@ import * as util from '../util';
|
|||
import EntityPosition from '../model/EntityPosition';
|
||||
import MapData from '../model/MapData';
|
||||
import Position from '../model/Position';
|
||||
import TileData from '../model/TileData';
|
||||
|
||||
|
||||
const tileSize = 32;
|
||||
|
@ -26,14 +25,8 @@ function loadImages(imgs: {[key: string]: string}): Promise<{[key: string]: HTML
|
|||
return util.mapPromises(_.mapValues(imgs, loadImage));
|
||||
}
|
||||
|
||||
function loadTiles(tiles: {[key: string]: TileData}): Promise<{[key: string]: HTMLImageElement}> {
|
||||
var imgs: {[key: string]: string} = {}
|
||||
|
||||
_.forOwn(tiles, t => {
|
||||
imgs[t.file] = `resources/sprite/tile/${t.file}.png`
|
||||
});
|
||||
|
||||
return loadImages(imgs);
|
||||
function loadTiles(tiles: {[key: string]: {file: string}}): Promise<{[key: string]: HTMLImageElement}> {
|
||||
return loadImages(_.mapValues(tiles, (t) => `resources/sprite/tile/${t.file}.png`));
|
||||
}
|
||||
|
||||
function loadEntities(entities: EntityPosition[]): Promise<{[key: string]: HTMLImageElement}> {
|
||||
|
@ -107,7 +100,7 @@ export default class MapView {
|
|||
});
|
||||
}
|
||||
|
||||
private setSize(): void {
|
||||
private setSize() {
|
||||
var e = document.documentElement;
|
||||
var w = window.innerWidth || e.clientWidth || body.clientWidth;
|
||||
var h = window.innerHeight || e.clientHeight || body.clientHeight;
|
||||
|
@ -121,27 +114,11 @@ export default class MapView {
|
|||
this.redraw()
|
||||
}
|
||||
|
||||
private drawSprite(img: HTMLImageElement, srcX: number, srcY: number, destX: number, destY: number): void {
|
||||
this.ctx.drawImage(
|
||||
img,
|
||||
tiles(srcX), tiles(srcY),
|
||||
tileSize, tileSize,
|
||||
tiles(destX)*this.scale,
|
||||
tiles(destY)*this.scale,
|
||||
tileSize*this.scale,
|
||||
tileSize*this.scale
|
||||
);
|
||||
}
|
||||
|
||||
private drawTile(x: number, y: number, tile: TileData): void {
|
||||
private drawTile(x: number, y: number, tile: HTMLImageElement) {
|
||||
if (!tile)
|
||||
return;
|
||||
|
||||
var img = this.tiles[tile.file];
|
||||
if (!img)
|
||||
return;
|
||||
|
||||
this.drawSprite(img, tile.subtile || 0, 0, x, y);
|
||||
this.ctx.drawImage(tile, tiles(x)*this.scale, tiles(y)*this.scale, tileSize*this.scale, tileSize*this.scale);
|
||||
}
|
||||
|
||||
private drawEntity(e: EntityPosition, time: number): boolean {
|
||||
|
@ -150,12 +127,19 @@ export default class MapView {
|
|||
return false;
|
||||
|
||||
var p = entityPosition(e, time);
|
||||
this.drawSprite(sprite, e.direction, 0, p.x, p.y);
|
||||
|
||||
this.ctx.drawImage(
|
||||
sprite,
|
||||
tiles(e.direction), 0,
|
||||
tileSize, tileSize,
|
||||
tiles(p.x)*this.scale, tiles(p.y)*this.scale,
|
||||
tileSize*this.scale, tileSize*this.scale
|
||||
);
|
||||
|
||||
return !!e.transition;
|
||||
}
|
||||
|
||||
private setOrigin(time: number): Rect {
|
||||
private setOrigin(time: number) {
|
||||
var origin = entityPosition(this.origin, time);
|
||||
|
||||
var w = this.canvas.width;
|
||||
|
@ -172,7 +156,7 @@ export default class MapView {
|
|||
);
|
||||
}
|
||||
|
||||
private draw(time: number): void {
|
||||
private draw(time: number) {
|
||||
this.updateState(time);
|
||||
|
||||
this.redrawPending = false;
|
||||
|
@ -202,7 +186,7 @@ export default class MapView {
|
|||
if (!tile)
|
||||
continue;
|
||||
|
||||
this.drawTile(x, y, this.map.tiles[tile]);
|
||||
this.drawTile(x, y, this.tiles[tile]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -220,7 +204,7 @@ export default class MapView {
|
|||
this.redraw();
|
||||
}
|
||||
|
||||
redraw(): void {
|
||||
redraw() {
|
||||
if (this.redrawPending)
|
||||
return;
|
||||
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>RPGedit</title>
|
||||
</head>
|
||||
<body>
|
||||
<script src="bundle.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,42 +1,42 @@
|
|||
{
|
||||
"tiles": {
|
||||
"G": {"file": "grass"},
|
||||
"<": {"file": "road", "subtile": 0},
|
||||
">": {"file": "road", "subtile": 1}
|
||||
"G": {"rotate": 0, "file": "grass"},
|
||||
"<": {"rotate": 0, "file": "road_left"},
|
||||
">": {"rotate": 0, "file": "road_right"}
|
||||
},
|
||||
"collision": [
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000110000000000000000000",
|
||||
"00000000000000000000000000000000"
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111",
|
||||
"11111111111111111111111111111111"
|
||||
],
|
||||
"layers": [
|
||||
[
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 329 B |
|
@ -3,32 +3,10 @@
|
|||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"noImplicitAny": true,
|
||||
"sourceMap": true,
|
||||
"noEmit": true
|
||||
"sourceMap": true
|
||||
},
|
||||
"files": [
|
||||
"require.d.ts",
|
||||
"typings/tsd.d.ts",
|
||||
"src/app.ts",
|
||||
"src/control/MapContext.ts",
|
||||
"src/model/Direction.ts",
|
||||
"src/model/Entity.ts",
|
||||
"src/model/EntityPosition.ts",
|
||||
"src/model/MapData.ts",
|
||||
"src/model/Position.ts",
|
||||
"src/model/TileData.ts",
|
||||
"src/model/Transition.ts",
|
||||
"src/util.ts",
|
||||
"src/view/InputHandler.ts",
|
||||
"src/view/MapView.ts"
|
||||
],
|
||||
"filesGlob": [
|
||||
"require.d.ts",
|
||||
"typings/tsd.d.ts",
|
||||
"src/**/*.ts"
|
||||
],
|
||||
"compileOnSave": false,
|
||||
"atom": {
|
||||
"rewriteTsconfig": true
|
||||
}
|
||||
"typings/tsd.d.ts"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -6,6 +6,11 @@ module.exports = {
|
|||
path: './build',
|
||||
filename: 'bundle.js'
|
||||
},
|
||||
plugins: [
|
||||
new HtmlWebpackPlugin({
|
||||
title: 'RPGedit'
|
||||
})
|
||||
],
|
||||
module: {
|
||||
loaders: [
|
||||
{ test: /\.css$/, loader: 'style-loader!css-loader' },
|
||||
|
@ -14,8 +19,5 @@ module.exports = {
|
|||
},
|
||||
resolve: {
|
||||
extensions: ['', '.ts']
|
||||
},
|
||||
ts: {
|
||||
compilerOptions: { noEmit: false }
|
||||
}
|
||||
};
|
||||
|
|
Reference in a new issue