4 * Copyright 2020 Elias Fleckenstein <eliasfleckenstein@web.de>
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.
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.
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,
24 dragonblocks.SpawnedEntity = class
26 constructor(def, x, y){
27 dblib.copy(this, def);
29 if (def instanceof dragonblocks.Entity) {
30 this.id = dragonblocks.getToken();
31 this.jumping = this.movingRight = this.movingLeft = this.movingUp = this.movingDown = false;
38 this.meta = this.meta || {};
39 this.toEntity().oninit && this.toEntity().oninit(this);
42 this.restorePhysics();
49 this.tickInterval = setInterval(_ => {
52 this.physicInterval = setInterval(_=>{
56 let entityDef = this.toEntity();
57 entityDef.onspawn && entityDef.onspawn(this);
59 addEventListener("focus", _ => {
60 self.restorePhysics();
63 addEventListener("blur", _ => {
64 self.restorePhysics();
67 dragonblocks.spawnedEntities.push(this);
72 return dragonblocks.entities[this.name];
77 let entityDef = this.toEntity();
78 entityDef.ondespawn && entityDef.ondespawn(this);
81 dragonblocks.spawnedEntities = dragonblocks.spawnedEntities.filter(entity => {
82 return entity.id != id;
85 clearInterval(this.physicInterval);
86 clearInterval(this.tickInterval);
88 document.getElementById("dragonblocks.entity[" + this.id + "]").remove();
93 this.tx0 = new Date().getTime() / 1000;
94 this.ty0 = new Date().getTime() / 1000;
104 if (this.x + this.width > dragonblocks.map.width)
107 return this.collision();
115 if (this.y + this.height > dragonblocks.map.height)
118 return this.collision();
123 for (let ix = Math.floor(this.x); ix <= Math.ceil(this.x + this.width - 0.01) - 1; ix++)
124 for (let iy = Math.floor(this.y); iy <= Math.ceil(this.y + this.height - 0.01) - 1; iy++)
125 if (dragonblocks.getNode(ix, iy).mobstable)
132 this.tx0 = new Date().getTime() / 1000;
135 this.x = Math.round(this.x * 10) / 10;
140 this.ty0 = new Date().getTime() / 1000;
143 this.y = Math.round(this.y * 10) / 10;
148 let t = new Date().getTime() / 1000;
151 var dtx = t - this.tx0;
154 this.x = this.ax * dtx * dtx + this.vx * dtx + this.x0;
156 this.x = this.vx * dtx + this.x0;
158 if (! this.collisionX()) {
160 this.physicsResetX();
161 this.toEntity().oncollide && this.toEntity().oncollide(this);
165 var dty = t - this.ty0;
168 this.y = this.ay * dty * dty + this.vy * dty + this.y0;
170 this.y = this.vy * dty + this.y0;
172 if (! this.collisionY()) {
174 this.physicsResetY();
175 this.toEntity().oncollide && this.toEntity().oncollide(this);
178 this.y = Math.round(this.y * 50) / 50;
180 this.updateGraphics();
185 for (let ix = Math.floor(this.x); ix <= Math.ceil(this.x + this.width - 0.01) - 1; ix++)
186 for (let iy = Math.floor(this.y); iy <= Math.ceil(this.y + this.height - 0.01) - 1; iy++)
187 if (iy == y && ix == x)
193 var display = document.getElementById("dragonblocks.map").appendChild(document.createElement("div"));
194 display.id = "dragonblocks.entity[" + this.id + "]";
195 display.style.position = "absolute";
196 display.style.width = this.width * dragonblocks.settings.map.scale + "px";
197 display.style.height = this.height * dragonblocks.settings.map.scale + "px";
198 display.style.zIndex = "0";
201 display.addEventListener("mouseover", event => {
202 event.srcElement.style.boxShadow = "0 0 0 1px black inset";
205 display.addEventListener("mouseleave", event => {
206 event.srcElement.style.boxShadow = "none";
211 display.addEventListener("mousedown", event => {
212 let entityDef = self.toEntity();
214 switch (event.which) {
216 entityDef.onpunch && entityDef.onpunch(self);
220 entityDef.onclick && entityDef.onclick(self);
225 this.updateTexture();
226 this.updateGraphics();
229 async updateGraphics()
231 let display = document.getElementById("dragonblocks.entity[" + this.id + "]");
236 display.style.left = (this.x - dragonblocks.map.displayLeft) * dragonblocks.settings.map.scale + "px";
237 display.style.top = (this.y - dragonblocks.map.displayTop) * dragonblocks.settings.map.scale + "px";
242 let display = document.getElementById("dragonblocks.entity[" + this.id + "]");
243 display.style.background = dragonblocks.getTexture(this.texture);
244 display.style.backgroundSize = "cover";
249 this.physicsResetX();
250 this.physicsResetY();
257 if (this.vx == -this.horizontalSpeed)
260 if (this.movingRight)
261 this.movingRight = false;
263 this.movingLeft = true;
264 this.physicsResetX();
265 this.vx = -this.horizontalSpeed;
270 if (this.vx == this.horizontalSpeed)
274 this.movingLeft = false;
276 this.movingRight = true;
277 this.physicsResetX();
278 this.vx = this.horizontalSpeed;
283 this.movingLeft = false;
284 this.movingRight = false;
285 this.physicsResetX();
290 if (this.vy == this.verticalSpeed)
294 this.movingDown = false;
296 this.movingDown = true;
297 this.physicsResetY();
298 this.vy = this.verticalSpeed;
303 if (this.vy == -this.verticalSpeed)
307 this.movingUp = false;
309 this.movingUp = true;
310 this.physicsResetY();
311 this.vy = -this.verticalSpeed;
316 this.movingUp = false;
317 this.movingDown = false;
318 this.physicsResetY();
323 for (let x = Math.floor(this.x); x <= Math.ceil(this.x + this.width - 0.01) - 1; x++) {
324 let entityY = this.y + this.height;
325 let y = Math.ceil(entityY);
327 if (y - entityY <= 0.01) {
328 let node = dragonblocks.getNode(x, y);
330 if (! node || node.mobstable)
338 if (! this.canJump())
342 this.vy = -this.verticalSpeed;
347 this.jumping = false;
352 this.vy = -this.verticalSpeed;
357 this._gravity = value;
360 this.ay = dragonblocks.settings.physics.gravity;
367 return this._gravity;
374 if (this.movingRight)
389 dragonblocks.spawnedEntities = [];
390 dragonblocks.registerOnStarted(_ => {
391 if (dragonblocks.worldIsLoaded)
392 for (let entity of dragonblocks.world.spawnedEntities)
393 new dragonblocks.SpawnedEntity(entity);