summaryrefslogtreecommitdiffstats
path: root/src/view/MapView.coffee
blob: e051d48cb122029df32e3c1ed66050fa7b557df0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
'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