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,
23 dragonblocks.SpawnedEntity = class {
24 constructor(entity, x, y){
25 dblib.copy(this, entity);
26 if(entity instanceof dragonblocks.Entity){
27 this.id = dragonblocks.getToken();
28 this.jumping = this.movingRight = this.movingLeft = this.movingUp = this.movingDown = false;
35 this.meta = this.meta || {};
36 this.toEntity().oninit && this.toEntity().oninit(this);
38 this.physicsRecover();
42 this.tickInterval = setInterval(_ => {self.tick()}, 100);
43 this.physicInterval = setInterval(_=>{self.physics()});
44 this.toEntity().onspawn && this.toEntity().onspawn(this);
45 addEventListener("focus", _ => { self.physicsRecover(); });
46 addEventListener("blur", _ => { self.physicsRecover(); });
47 dragonblocks.spawnedEntities.push(this);
50 return dragonblocks.entities[this.name];
53 this.toEntity().ondespawn && this.toEntity().ondespawn(this);
55 dragonblocks.spawnedEntities = dragonblocks.spawnedEntities.filter(entity => {return entity.id != id});
56 clearInterval(this.physicInterval);
57 clearInterval(this.tickInterval);
58 dblib.remove(document.getElementById("dragonblocks.entity[" + this.id + "]"));
61 this.tx0 = new Date().getTime() / 1000;
62 this.ty0 = new Date().getTime() / 1000;
69 if(this.x + this.width > dragonblocks.map.width)
71 return this.physicsCheckBoth();
76 if(this.y + this.height > dragonblocks.map.height)
78 return this.physicsCheckBoth();
81 for(let ix = Math.floor(this.x); ix <= Math.ceil(this.x + this.width - 0.01) - 1; ix++)
82 for(let iy = Math.floor(this.y); iy <= Math.ceil(this.y + this.height - 0.01) - 1; iy++)
83 if(dragonblocks.getNode(ix, iy).mobstable)
88 this.tx0 = new Date().getTime() / 1000;
91 this.x = Math.round(this.x * 10) / 10;
94 this.ty0 = new Date().getTime() / 1000;
97 this.y = Math.round(this.y * 10) / 10;
100 let t = new Date().getTime() / 1000;
102 var dtx = t - this.tx0;
104 this.x = this.ax * dtx * dtx + this.vx * dtx + this.x0;
106 this.x = this.vx * dtx + this.x0;
107 if(! this.physicsCheckX())
110 this.physicsResetX();
111 this.toEntity().oncollide && this.toEntity().oncollide(this);
114 var dty = t - this.ty0;
116 this.y = this.ay * dty * dty + this.vy * dty + this.y0;
118 this.y = this.vy * dty + this.y0;
119 if(! this.physicsCheckY())
122 this.physicsResetY();
123 this.toEntity().oncollide && this.toEntity().oncollide(this);
125 this.y = Math.round(this.y * 50) / 50;
126 this.updateGraphics();
129 for(let ix = Math.floor(this.x); ix <= Math.ceil(this.x + this.width - 0.01) - 1; ix++)
130 for(let iy = Math.floor(this.y); iy <= Math.ceil(this.y + this.height - 0.01) - 1; iy++)
131 if(iy == y && ix == x)
135 var display = document.createElement("div");
136 display.id = "dragonblocks.entity[" + this.id + "]";
137 display.style.position = "absolute";
138 display.style.width = this.width * dragonblocks.settings.map.scale + "px";
139 display.style.height = this.height * dragonblocks.settings.map.scale + "px";
140 display.style.zIndex = "0";
142 display.addEventListener("mouseover", event => {
143 event.srcElement.style.boxShadow = "0 0 0 1px black inset";
145 display.addEventListener("mouseleave", event => {
146 event.srcElement.style.boxShadow = "none";
148 display.addEventListener("mousedown", event => {
151 self.toEntity().onpunch && self.toEntity().onpunch(self);
154 self.toEntity().onclick && self.toEntity().onclick(self);
158 document.getElementById("dragonblocks.map").appendChild(display);
159 this.updateTexture();
160 this.updateGraphics();
162 async updateGraphics(){
163 let display = document.getElementById("dragonblocks.entity[" + this.id + "]");
166 display.style.left = (this.x - dragonblocks.map.displayLeft) * dragonblocks.settings.map.scale + "px";
167 display.style.top = (this.y - dragonblocks.map.displayTop) * dragonblocks.settings.map.scale + "px";
170 let display = document.getElementById("dragonblocks.entity[" + this.id + "]");
171 display.style.background = dragonblocks.getTexture(this.texture);
172 display.style.backgroundSize = "cover";
175 this.physicsResetX();
176 this.physicsResetY();
181 if(this.vx == -this.horizontalSpeed)
184 this.movingRight = false;
185 this.movingLeft = true;
186 this.physicsResetX();
187 this.vx = -this.horizontalSpeed;
190 if(this.vx == this.horizontalSpeed)
193 this.movingLeft = false;
194 this.movingRight = true;
195 this.physicsResetX();
196 this.vx = this.horizontalSpeed;
199 this.movingLeft = false;
200 this.movingRight = false;
201 this.physicsResetX();
204 if(this.vy == this.verticalSpeed)
207 this.movingDown = false;
208 this.movingDown = true;
209 this.physicsResetY();
210 this.vy = this.verticalSpeed;
213 if(this.vy == -this.verticalSpeed)
216 this.movingUp = false;
217 this.movingUp = true;
218 this.physicsResetY();
219 this.vy = -this.verticalSpeed;
222 this.movingUp = false;
223 this.movingDown = false;
224 this.physicsResetY();
227 if(this.vy == -this.verticalSpeed)
230 this.vy = -this.verticalSpeed;
233 this.jumping = false;
236 this.vy = -this.verticalSpeed;
239 this._gravity = value;
241 this.ay = dragonblocks.settings.physics.gravity;
246 return this._gravity;
263 dragonblocks.spawnedEntities = [];
264 dragonblocks.registerOnStarted(_ => {
265 if(dragonblocks.worldIsLoaded)
266 for(let entity of dragonblocks.world.spawnedEntities)
267 new dragonblocks.SpawnedEntity(entity);