From c64ead08a36fccc36a42b3e74362aa423cfb62ed Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 6 Jan 2016 17:10:19 +0100 Subject: Replace all CoffeeScript code by TypeScript --- src/app.coffee | 21 ------ src/app.ts | 26 ++++++++ src/control/MapContext.coffee | 29 -------- src/control/MapContext.ts | 34 ++++++++++ src/model/Direction.coffee | 13 ---- src/model/Direction.ts | 13 ++++ src/model/Entity.coffee | 8 --- src/model/Entity.ts | 6 ++ src/model/EntityPosition.coffee | 8 --- src/model/EntityPosition.ts | 11 ++++ src/model/MapData.coffee | 9 --- src/model/MapData.ts | 20 ++++++ src/model/Position.coffee | 10 --- src/model/Position.ts | 10 +++ src/util.coffee | 13 ---- src/util.ts | 13 ++++ src/view/MapView.coffee | 108 ------------------------------ src/view/MapView.ts | 142 ++++++++++++++++++++++++++++++++++++++++ 18 files changed, 275 insertions(+), 219 deletions(-) delete mode 100644 src/app.coffee create mode 100644 src/app.ts delete mode 100644 src/control/MapContext.coffee create mode 100644 src/control/MapContext.ts delete mode 100644 src/model/Direction.coffee create mode 100644 src/model/Direction.ts delete mode 100644 src/model/Entity.coffee create mode 100644 src/model/Entity.ts delete mode 100644 src/model/EntityPosition.coffee create mode 100644 src/model/EntityPosition.ts delete mode 100644 src/model/MapData.coffee create mode 100644 src/model/MapData.ts delete mode 100644 src/model/Position.coffee create mode 100644 src/model/Position.ts delete mode 100644 src/util.coffee create mode 100644 src/util.ts delete mode 100644 src/view/MapView.coffee create mode 100644 src/view/MapView.ts (limited to 'src') diff --git a/src/app.coffee b/src/app.coffee deleted file mode 100644 index ca3ddf8..0000000 --- a/src/app.coffee +++ /dev/null @@ -1,21 +0,0 @@ -'use strict' - -require './style.css' - -window._ = require 'lodash' - -MapData = require './model/MapData' -MapContext = require './control/MapContext' - - -mapContext = null - - -window.onload = -> - xhr = new XMLHttpRequest() - xhr.onload = -> - mapDef = new MapData(JSON.parse this.responseText) - mapContext = new MapContext mapDef - - xhr.open 'GET', 'resources/map/test.json', true - xhr.send() diff --git a/src/app.ts b/src/app.ts new file mode 100644 index 0000000..d1ca3cd --- /dev/null +++ b/src/app.ts @@ -0,0 +1,26 @@ +'use strict'; + + +require('./style.css'); + + +import * as lodash from 'lodash'; +_ = lodash; + +import MapContext from './control/MapContext'; +import MapData from './model/MapData'; + + +var mapContext: MapContext; + +window.onload = () => { + var xhr = new XMLHttpRequest(); + + xhr.onload = function() { + let mapDef = new MapData(JSON.parse(this.responseText)); + mapContext = new MapContext(mapDef); + } + + xhr.open('GET', 'resources/map/test.json', true); + xhr.send(); +}; diff --git a/src/control/MapContext.coffee b/src/control/MapContext.coffee deleted file mode 100644 index df6efec..0000000 --- a/src/control/MapContext.coffee +++ /dev/null @@ -1,29 +0,0 @@ -'use strict' - - -Direction = require '../model/Direction' -Entity = require '../model/Entity' -EntityPosition = require '../model/EntityPosition' -Position = require '../model/Position' - -MapView = require '../view/MapView' - - -class MapContext - constructor: (@map) -> - @entities = {} - - @playerEntity = new EntityPosition( - new Entity('square'), - new Position(8, 8), - Direction.EAST) - - @addEntity(@playerEntity) - - @mavView = new MapView @map, @entities - - addEntity: (entity) => - @entities[entity.position.asString()] = entity - - -module.exports = MapContext diff --git a/src/control/MapContext.ts b/src/control/MapContext.ts new file mode 100644 index 0000000..4bc75c7 --- /dev/null +++ b/src/control/MapContext.ts @@ -0,0 +1,34 @@ +'use strict'; + + +import Direction from '../model/Direction'; +import Entity from '../model/Entity'; +import EntityPosition from '../model/EntityPosition'; +import MapData from '../model/MapData'; +import Position from '../model/Position'; + +import MapView from '../view/MapView'; + + +export default class MapContext { + view: MapView; + + entities: {[key: string]: EntityPosition} = {}; + playerEntity: EntityPosition; + + constructor(public map: MapData) { + this.playerEntity = new EntityPosition( + new Entity('square'), + new Position(8, 8), + Direction.East + ); + + this.addEntity(this.playerEntity); + + this.view = new MapView(map, this.entities); + } + + addEntity(entity: EntityPosition) { + this.entities[entity.position.asString()] = entity; + } +} diff --git a/src/model/Direction.coffee b/src/model/Direction.coffee deleted file mode 100644 index 5c49c80..0000000 --- a/src/model/Direction.coffee +++ /dev/null @@ -1,13 +0,0 @@ -'use strict' - - -Direction = - NORTH: 0 - EAST: 1 - SOUTH: 2 - WEST: 3 - - reverse: (d) -> (d+2)%4 - - -module.exports = Direction diff --git a/src/model/Direction.ts b/src/model/Direction.ts new file mode 100644 index 0000000..a0cf45d --- /dev/null +++ b/src/model/Direction.ts @@ -0,0 +1,13 @@ +'use strict'; + + +export enum Direction { + North, + East, + South, + West +}; + +export function reverse(r: Direction): Direction { return (r+2) % 4; } + +export default Direction; diff --git a/src/model/Entity.coffee b/src/model/Entity.coffee deleted file mode 100644 index 70c81fa..0000000 --- a/src/model/Entity.coffee +++ /dev/null @@ -1,8 +0,0 @@ -'use strict' - - -class Entity - constructor: (@name) -> - - -module.exports = Entity diff --git a/src/model/Entity.ts b/src/model/Entity.ts new file mode 100644 index 0000000..b9a52eb --- /dev/null +++ b/src/model/Entity.ts @@ -0,0 +1,6 @@ +'use strict'; + + +export default class Entity { + constructor(public name: string) {} +} diff --git a/src/model/EntityPosition.coffee b/src/model/EntityPosition.coffee deleted file mode 100644 index aaf9531..0000000 --- a/src/model/EntityPosition.coffee +++ /dev/null @@ -1,8 +0,0 @@ -'use strict' - - -class EntityPosition - constructor: (@entity, @position, @direction) -> - - -module.exports = EntityPosition diff --git a/src/model/EntityPosition.ts b/src/model/EntityPosition.ts new file mode 100644 index 0000000..815eceb --- /dev/null +++ b/src/model/EntityPosition.ts @@ -0,0 +1,11 @@ +'use strict'; + + +import Direction from '../model/Direction'; +import Entity from './Entity'; +import Position from './Position'; + + +export default class EntityPosition { + constructor(public entity: Entity, public position: Position, public direction: Direction) {} +} diff --git a/src/model/MapData.coffee b/src/model/MapData.coffee deleted file mode 100644 index 39b2140..0000000 --- a/src/model/MapData.coffee +++ /dev/null @@ -1,9 +0,0 @@ -'use strict' - - -class MapData - constructor: (data) -> - {@tiles, @collition, @layers} = data - - -module.exports = MapData diff --git a/src/model/MapData.ts b/src/model/MapData.ts new file mode 100644 index 0000000..54894c0 --- /dev/null +++ b/src/model/MapData.ts @@ -0,0 +1,20 @@ +'use strict'; + + +interface Input { + tiles: {[key: string]: {file: string}}; + collision: string[]; + layers: string[][][]; +} + +export default class MapData { + 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; + } +} diff --git a/src/model/Position.coffee b/src/model/Position.coffee deleted file mode 100644 index 08bb999..0000000 --- a/src/model/Position.coffee +++ /dev/null @@ -1,10 +0,0 @@ -'use strict' - - -class Position - constructor: (@x, @y) -> - - asString: => "#{@x},#{@y}" - - -module.exports = Position diff --git a/src/model/Position.ts b/src/model/Position.ts new file mode 100644 index 0000000..1db37af --- /dev/null +++ b/src/model/Position.ts @@ -0,0 +1,10 @@ +'use strict'; + + +export default class Position { + constructor(public x: number, public y: number) {} + + asString(): string { + return `${this.x},${this.y}`; + } +} diff --git a/src/util.coffee b/src/util.coffee deleted file mode 100644 index 4e0cd76..0000000 --- a/src/util.coffee +++ /dev/null @@ -1,13 +0,0 @@ -'use strict' - - -module.exports = - mapPromises: (promises) -> - p = [] - ret = {} - - for own k, v of promises - do (k, v) -> - p.push(v.then (r) -> ret[k] = r) - - Promise.all(p).then -> ret diff --git a/src/util.ts b/src/util.ts new file mode 100644 index 0000000..2292820 --- /dev/null +++ b/src/util.ts @@ -0,0 +1,13 @@ +'use strict'; + + +export function mapPromises(promises: {[key: string]: Promise}): Promise<{[key: string]: T}> { + var p: Promise[] = [] + var ret: {[key: string]: T} = {} + + _.forOwn(promises, (v, k) => { + p.push(v.then(r => {ret[k] = r;})); + }); + + return Promise.all(p).then(() => ret); +} diff --git a/src/view/MapView.coffee b/src/view/MapView.coffee deleted file mode 100644 index e051d48..0000000 --- a/src/view/MapView.coffee +++ /dev/null @@ -1,108 +0,0 @@ -'use strict' - -util = require '../util' - - -tileSize = 32 - -body = document.getElementsByTagName('body')[0] - - -loadImage = (url) -> - new Promise (resolve, reject) -> - img = new Image() - img.addEventListener 'load', -> resolve img - img.addEventListener 'error', -> reject Error('Failed to load ' + url) - img.src = url - -loadImages = (imgs) -> - util.mapPromises(_.mapValues imgs, loadImage) - -loadTiles = (tiles) -> - loadImages(_.mapValues tiles, (t) -> "resources/sprite/tile/#{t.file}.png") - -loadEntities = (entities) -> - p = {} - for e in entities - do (e) -> - p[e.entity.name] = loadImage "resources/sprite/entity/#{e.entity.name}.png" - - util.mapPromises p - - -class MapView - constructor: (@map, @entities) -> - @redrawPending = false - - @canvas = document.createElement 'canvas' - @canvas.style.position = 'absolute' - body.appendChild @canvas - - @ctx = @canvas.getContext '2d' - - window.addEventListener 'resize', @setSize - @setSize() - - tilesReady = loadTiles(@map.tiles).then (tiles) => - @tiles = tiles - - entitiesReady = loadEntities(_.values @entities).then (entities) => - @entitySprites = entities - - tilesReady.then(entitiesReady).then => - @redraw() - return - - drawTile: (x, y, tile) => - return unless tile - - @ctx.drawImage tile, x, y - - drawEntity: (e) => - sprite = @entitySprites[e.entity.name] - return unless sprite - - @ctx.drawImage( - sprite, - e.direction*tileSize, 0, - tileSize, tileSize, - e.position.x*tileSize, e.position.y*tileSize, - tileSize, tileSize) - - draw: => - @redrawPending = false - - @ctx.clearRect 0, 0, @canvas.width, @canvas.height - - return unless @tiles and @entitySprites - - for layer in @map.layers - y = 0 - - for row in layer - x = 0 - - for tile in row - @drawTile x, y, @tiles[tile] - x += tileSize - - y += tileSize - - for e in _.values @entities - @drawEntity e - - redraw: => - unless @redrawPending - @redrawPending = true - window.requestAnimationFrame @draw - - setSize: => - e = document.documentElement - @canvas.width = window.innerWidth || e.clientWidth || body.clientWidth - @canvas.height = window.innerHeight || e.clientHeight || body.clientHeight - - @redraw() - - - -module.exports = MapView diff --git a/src/view/MapView.ts b/src/view/MapView.ts new file mode 100644 index 0000000..b366d28 --- /dev/null +++ b/src/view/MapView.ts @@ -0,0 +1,142 @@ +'use strict'; + + +import * as util from '../util'; +import EntityPosition from '../model/EntityPosition'; +import MapData from '../model/MapData'; + + +const tileSize = 32; + +const body = document.getElementsByTagName('body')[0]; + + +function loadImage(url: string): Promise { + return new Promise(function(resolve, reject) { + var img = new Image(); + img.addEventListener('load', () => { resolve(img); }); + img.addEventListener('error', () => { reject(Error('Failed to load ' + url)); }); + img.src = url; + }); +} + +function loadImages(imgs: {[key: string]: string}): Promise<{[key: string]: HTMLImageElement}> { + return util.mapPromises(_.mapValues(imgs, loadImage)); +} + +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}> { + var p: {[key: string]: Promise} = {}; + + entities.forEach(e => { + p[e.entity.name] = loadImage(`resources/sprite/entity/${e.entity.name}.png`); + }); + + return util.mapPromises(p); +} + + +export default class MapView { + redrawPending: boolean = false; + + canvas: HTMLCanvasElement; + ctx: CanvasRenderingContext2D; + + tiles: {[key: string]: HTMLImageElement}; + entitySprites: {[key: string]: HTMLImageElement}; + + constructor(private map: MapData, private entities: {[key: string]: EntityPosition}) { + this.canvas = document.createElement('canvas'); + this.canvas.style.position = 'absolute'; + body.appendChild(this.canvas); + + this.ctx = this.canvas.getContext('2d'); + + window.addEventListener('resize', () => this.setSize()); + this.setSize(); + + var tilesReady = loadTiles(map.tiles).then((tiles) => { + this.tiles = tiles; + }); + + var entitiesReady = loadEntities(this.getEntities()).then((entities) => { + this.entitySprites = entities; + }); + + Promise.all([tilesReady, entitiesReady]).then(() => { + this.redraw(); + }); + } + + getEntities(): EntityPosition[] { + return _.valuesIn(this.entities); + } + + setSize() { + var e = document.documentElement; + this.canvas.width = window.innerWidth || e.clientWidth || body.clientWidth; + this.canvas.height = window.innerHeight || e.clientHeight || body.clientHeight; + + this.redraw() + } + + drawTile(x: number, y: number, tile: HTMLImageElement) { + if (!tile) + return; + + this.ctx.drawImage(tile, x, y); + } + + drawEntity(e: EntityPosition) { + var sprite = this.entitySprites[e.entity.name]; + if (!sprite) + return; + + this.ctx.drawImage( + sprite, + e.direction*tileSize, 0, + tileSize, tileSize, + e.position.x*tileSize, e.position.y*tileSize, + tileSize, tileSize + ); + } + + draw() { + this.redrawPending = false; + + this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); + + if (!this.tiles || !this.entitySprites) + return; + + this.map.layers.forEach((layer) => { + let y = 0; + + layer.forEach((row) => { + let x = 0; + + for (let tile in row) { + this.drawTile(x, y, this.tiles[row[tile]]); + x += tileSize; + } + + y += tileSize; + }); + }); + + this.getEntities().forEach(e => { + this.drawEntity(e); + }); + } + + redraw() { + if (this.redrawPending) + return; + + this.redrawPending = true; + window.requestAnimationFrame(() => this.draw()); + } +} -- cgit v1.2.3