]> git.lizzy.rs Git - dragonblocks.git/blob - engine/map.js
Code style overhaul
[dragonblocks.git] / engine / map.js
1 /*
2  * map.js
3  *
4  * Copyright 2020 Elias Fleckenstein <eliasfleckenstein@web.de>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  * MA 02110-1301, USA.
20  *
21  *
22  */
23
24 dragonblocks.Map = class
25 {
26         constructor()
27         {
28                 dblib.copy(this, dragonblocks.world.map);
29                 this.data = this.data || this.content;
30                 delete this.content;
31         }
32
33         load()
34         {
35                 for (let x = 0; x < this.width; x++)
36                         for (let y = 0; y < this.height; y++)
37                                 this.setNode(x, y, new dragonblocks.MapNode().createFromMapNode(this.data[x][y]));
38
39                 this.initGraphics();
40         }
41
42         setNode(x, y, node)
43         {
44                 if (this.withinBounds(x, y)) {
45                         let oldNode = this.data[x][y];
46                         let oldNodeDef = oldNode instanceof dragonblocks.MapNode && oldNode.toNode();
47                         oldNodeDef && oldNodeDef.onremove && oldNodeDef.onremove(x, y);
48
49                         for (let func of dragonblocks.onRemoveNodeCallbacks)
50                                 func(x, y);
51
52                         this.data[x][y] = node;
53
54                         let nodeDef = node.toNode();
55                         nodeDef.onset && nodeDef.onset(x, y);
56
57                         for (let func of dragonblocks.onSetNodeCallbacks)
58                                 func(x, y);
59
60                         this.updateNodeGraphics(x, y);
61                 }
62         }
63
64         activate(x, y)
65         {
66                 for (let ix = x - 1; ix <= x + 1; ix++) {
67                         for (let iy = y - 1; iy <= y + 1; iy++) {
68                                 let node = this.getNode(ix, iy);
69
70                                 if (! node)
71                                         continue;
72
73                                 let nodeDef = node.toNode();
74                                 nodeDef.onactivate && nodeDef.onactivate(ix, iy);
75
76                                 for(let func of dragonblocks.onActivateNodeCallbacks)
77                                         func(ix, iy);
78                         }
79                 }
80         }
81
82         getNode(x, y)
83         {
84                 if (this.withinBounds(x, y))
85                         return this.data[x][y];
86         }
87
88         withinBounds(x, y)
89         {
90                 return x < this.width && y < this.height && x >= 0 && y >= 0;
91         }
92
93         getNodeDisplay(x, y)
94         {
95                 return document.getElementById("dragonblocks.map.node[" + (x - this.displayLeft) + "][" + (y - this.displayTop) + "]");
96         }
97
98         getScreenCoordinates(x, y)
99         {
100                 return [Math.floor(x / dragonblocks.settings.map.scale) + this.displayLeft, Math.floor(y / dragonblocks.settings.map.scale) + this.displayTop];
101         }
102
103         updateNodeGraphics(x, y)
104         {
105                 let nodeDisplay = this.getNodeDisplay(x, y);
106
107                 if (! nodeDisplay)
108                         return;
109
110                 let nodeDef = this.getNode(x, y).toNode();
111
112                 if (! nodeDef)
113                         return;
114
115                 nodeDisplay.style.background = dragonblocks.getTexture(nodeDef.texture);
116                 nodeDisplay.style.backgroundSize = "cover";
117                 nodeDisplay.style.zIndex = nodeDef.zIndex || "1";
118         }
119
120         updateGraphics()
121         {
122                 if (this.displayLeft < 0)
123                         this.displayLeft = 0;
124                 else if (this.displayLeft + this.displayWidth > this.width)
125                         this.displayLeft = this.width - this.displayWidth;
126
127                 if (this.displayTop < 0)
128                         this.displayTop = 0;
129                 else if (this.displayTop + this.displayHeight > this.height)
130                         this.displayTop = this.height - this.displayHeight;
131
132                 for (let x = 0; x < this.displayWidth; x++) {
133                         for(let y = 0; y < this.displayHeight; y++) {
134                                 this.updateNodeGraphics(x + this.displayLeft, y + this.displayTop);
135                         }
136                 }
137         }
138
139         initGraphics()
140         {
141                 this.displayWidth = Math.min(Math.ceil(innerWidth / dragonblocks.settings.map.scale), this.width);
142                 this.displayHeight = Math.min(Math.ceil(innerHeight / dragonblocks.settings.map.scale), this.height);
143
144                 let display = document.body.insertBefore(document.createElement("div"), document.body.firstChild);
145                 display.id = "dragonblocks.map";
146                 display.style.width = this.displayWidth * dragonblocks.settings.map.scale + "px";
147                 display.style.height = this.displayHeight * dragonblocks.settings.map.scale + "px";
148                 display.style.position = "fixed";
149                 display.style.top = "0px";
150                 display.style.left = "0px";
151                 display.style.backgroundColor = "skyblue";
152                 display.style.visibility = "hidden";
153
154                 for (let x = 0; x < this.displayWidth; x++){
155                         for (let y = 0; y < this.displayHeight; y++){
156                                 let nodeDisplay = display.appendChild(document.createElement("div"));
157                                 nodeDisplay.id = "dragonblocks.map.node[" + x + "][" + y + "]";
158                                 nodeDisplay.style.position = "absolute";
159                                 nodeDisplay.style.top = y * dragonblocks.settings.map.scale + "px";
160                                 nodeDisplay.style.left = x * dragonblocks.settings.map.scale + "px";
161                                 nodeDisplay.style.width = dragonblocks.settings.map.scale + "px";
162                                 nodeDisplay.style.height = dragonblocks.settings.map.scale + "px";
163                         }
164                 }
165         }
166 };
167
168 dragonblocks.setNode = (x, y, node) => {
169         dragonblocks.map.setNode(x, y, new dragonblocks.MapNode(node));
170 };
171
172 dragonblocks.getNode = (x, y) => {
173         return dragonblocks.map.getNode(x, y);
174 };
175
176 dragonblocks.registerOnStarted(_ => {
177         document.getElementById("dragonblocks.map").style.visibility = "visible";
178 });
179
180 dragonblocks.registerOnQuit(_ => {
181         document.getElementById("dragonblocks.map").style.visibility = "hidden";
182 });