Skip to content

Commit c0a6e8d

Browse files
committed
server-side entity origin x/y
1 parent d36e5d3 commit c0a6e8d

File tree

7 files changed

+95
-39
lines changed

7 files changed

+95
-39
lines changed

Client/rooms/r1v1/r1v1.yy

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Client/sprites/sPlayer/sPlayer.yy

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Client/sprites/sWarpPortal/sWarpPortal.yy

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

TypescriptServer/src/concepts/entity.ts

+69-30
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ class Entity extends EventEmitter {
5353
static object_name:string = 'oUnknownEntity';
5454
type: string;
5555
object_name: string;
56-
// type = Entity.type;
57-
// object_name = Entity.object_name;
5856

5957
is_solid = false;
6058
is_static = false;
@@ -63,12 +61,14 @@ class Entity extends EventEmitter {
6361
pos:Point; // keep in mind that the coordinates are always set to a whole number (to achieve pixel-perfect collisions)
6462
spd:Point; // speed in pixels per second, can be fractional
6563
angle:number = 0;
64+
origin:Point = {x: 0, y: 0}; // origin from 0 (top/left) to 1 (bottom/right)
6665

6766
prev_pos:Point;
6867
serialized:SerializedEntity; // save the last serialized version of this entity (to compare changes)
6968

7069
base_size:Point = { x: 64, y: 64 };
7170
scale:Point = { x: 1, y: 1 };
71+
flip:Point = { x: 0, y: 0 };
7272

7373

7474
// the custom variables that need sending with the entitiy
@@ -84,6 +84,7 @@ class Entity extends EventEmitter {
8484

8585
collider:Collider = null; // a polygon or a circle
8686
collider_type:ColliderType|string = 'box';
87+
collider_origin:Point = {x: 0, y: 0};
8788
collider_radius:number = this.width/2; // only relevant when collider_type is 'circle'
8889
collider_vertices:Point[] = []; // if this is not overridden, a default rectangle collider will be used
8990

@@ -112,7 +113,7 @@ class Entity extends EventEmitter {
112113
if (typeof value === 'string') {
113114
this._state = this.states[value];
114115
}
115-
// it's a number
116+
// state is a number
116117
// (-1 means keep the old state)
117118
else if (value != -1) {
118119
this._state = value;
@@ -133,14 +134,13 @@ class Entity extends EventEmitter {
133134
this.id = crypto.randomUUID();
134135
this.room = room;
135136
this.pos = { x, y };
136-
this.spd = { x: 0, y: 0};
137+
this.spd = { x: 0, y: 0 };
137138
this.prev_pos = { x, y };
138139

139140
this.type = this.constructor['type'];
140141
this.object_name = this.constructor['object_name'];
141142

142143
this.createCollider();
143-
this.collider.entity = this;
144144

145145
this.tree.insert(this.collider);
146146
}
@@ -194,12 +194,15 @@ class Entity extends EventEmitter {
194194
}
195195

196196
public createCollider(x = this.x, y = this.y) {
197-
let pos = {x: x, y: y};
197+
let pos = {
198+
x: x + this.width * (this.collider_origin.x - this.origin.x),
199+
y: y + this.height * (this.collider_origin.y - this.origin.y)
200+
};
198201

199202
// create the collider
200203
switch(this.collider_type) {
201204
case 'box':
202-
this.collider = new BoxCollider(pos, this.width - .01, this.height - .01);
205+
this.collider = new BoxCollider(pos, this.base_size.x - .01, this.base_size.y - .01);
203206
break;
204207
case 'circle':
205208
this.collider = new CircleCollider(pos, this.collider_radius);
@@ -212,6 +215,10 @@ class Entity extends EventEmitter {
212215
throw 'Unknown collider type: ' + this.collider_type;
213216
}
214217

218+
this.collider.setScale(this.xscale, this.yscale);
219+
this.collider.setAngle(this.angle);
220+
// this.tree.updateBody(this.collider);
221+
215222
this.collider.entity = this;
216223
}
217224

@@ -224,46 +231,72 @@ class Entity extends EventEmitter {
224231
this.tree.insert(this.collider);
225232
}
226233

227-
protected updateCollider(x = this.x, y = this.y) {
228-
if (this.size.x != this.prev_size.x || this.size.y != this.prev_size.y) {
229-
this.regenerateCollider(x, y);
234+
protected updateCollider(x = this.x, y = this.y, collider = this.collider) {
235+
let pos = {
236+
x: x + this.width * (this.collider_origin.x - this.origin.x),
237+
y: y + this.height * (this.collider_origin.y - this.origin.y)
238+
};
239+
240+
if (collider === this.collider) {
241+
collider.setScale(this.xscale, this.yscale);
242+
collider.setAngle(this.angle);
243+
collider.setPosition(pos.x, pos.y);
244+
}
245+
else {
246+
collider.setPosition(x, y);
230247
}
231248

232-
this.collider.setAngle(this.angle);
233-
this.collider.setPosition(x, y);
234-
this.tree.updateBody(this.collider);
249+
this.tree.updateBody(collider);
235250
}
236251

237-
public checkCollision(x: number = this.x, y: number = this.y, e:Entity):boolean {
238-
this.updateCollider(x, y);
239-
return this.tree.checkCollision(this.collider, e.collider);
252+
public checkCollision(x: number = this.x, y: number = this.y, e:Entity, collider = this.collider):boolean {
253+
this.updateCollider(x, y, collider);
254+
255+
let result = this.tree.checkCollision(collider, e.collider);
256+
257+
// move back the collider
258+
if (collider === this.collider)
259+
this.updateCollider(this.x, this.y);
260+
261+
return result;
240262
}
241263

242-
public placeMeeting(x:number = this.x, y:number = this.y, type:EntityType|string = 'solid'):boolean {
243-
this.updateCollider(x, y);
264+
public placeMeeting(x:number = this.x, y:number = this.y, type:EntityType|string = 'solid', collider = this.collider):boolean {
265+
this.updateCollider(x, y, collider);
244266

245267
this.prev_size = {x: this.size.x, y: this.size.y}
246268

247-
return this.tree.checkOne(this.collider, (res) => {
269+
let result = this.tree.checkOne(this.collider, (res) => {
248270
let e = res.b.entity;
249-
return e.matchesType(type);
271+
return e && e.matchesType(type);
250272
});
273+
274+
// move back the collider
275+
if (collider === this.collider)
276+
this.updateCollider(this.x, this.y);
277+
278+
return result;
251279
}
252280

253-
public placeMeetingAll<T = Entity>(x:number = this.x, y:number = this.y, type:EntityType|string = 'solid'):T[] {
254-
this.updateCollider(x, y);
281+
public placeMeetingAll<T = Entity>(x:number = this.x, y:number = this.y, type:EntityType|string = 'solid', collider = this.collider):T[] {
282+
this.updateCollider(x, y, collider);
255283

256284
let entities = [];
257-
this.tree.checkOne(this.collider, (res) => {
285+
this.tree.checkOne(collider, (res) => {
258286
let e = res.b.entity;
259-
if (e.matchesType(type))
287+
if (e && e.matchesType(type))
260288
entities.push(e);
261289
});
290+
291+
// move back the collider
292+
if (collider === this.collider)
293+
this.updateCollider(this.x, this.y);
294+
262295
return entities;
263296
}
264297

265298
isOutsideRoom(x = this.x, y = this.y):boolean {
266-
let bbox = this.bbox; // this is an optimization btw
299+
let bbox = this.bbox; // don't call the getter every time
267300

268301
return bbox.left - this.x + x > this.room.width
269302
|| bbox.right - this.x + x < 0
@@ -301,8 +334,11 @@ class Entity extends EventEmitter {
301334

302335
// removes the entity from the room (and triggers the 'remove' event)
303336
public remove() {
304-
this.emit('remove');
305337
let idx = this.room.entities.indexOf(this);
338+
if (idx === -1) { // already removed
339+
return;
340+
}
341+
this.emit('remove');
306342
this.room.entities.splice(idx, 1);
307343
this.tree.remove(this.collider);
308344
}
@@ -343,11 +379,14 @@ class Entity extends EventEmitter {
343379
let x:number = this.x, y:number = this.y;
344380
let w:number = this.width, h:number = this.height;
345381

382+
let ox = this.origin.x;
383+
let oy = this.origin.y;
384+
346385
return {
347-
left: x,
348-
top: y,
349-
right: x + w,
350-
bottom: y + h
386+
left: x - w*ox,
387+
top: y - h*oy,
388+
right: x + w*(1-ox),
389+
bottom: y + h*(1-oy)
351390
}
352391
}
353392

TypescriptServer/src/entities/player.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import trace from '#util/logging';
2-
import Entity from '#concepts/entity';
2+
import Entity, { ColliderType } from '#concepts/entity';
33
import Client from '#concepts/client';
44
import Room from '#concepts/room';
55
import Point from '#types/point';
@@ -37,6 +37,9 @@ export default class PlayerEntity extends PhysicsEntity {
3737
static object_name = 'oPlayer';
3838

3939
collider_type = 'box';
40+
// collider_type:ColliderType = 'circle';
41+
// collider_radius: number = 16;
42+
collider_origin = { x: 0, y: 0 };
4043

4144
collision_type = 'discrete' as CollisionType;
4245
precise_collisions = true;
@@ -56,6 +59,11 @@ export default class PlayerEntity extends PhysicsEntity {
5659
y: 2
5760
}
5861

62+
origin = {
63+
x: 0.5,
64+
y: 0.5
65+
}
66+
5967
states = { idle: 0, walk: 1 };
6068

6169
client:Client;

TypescriptServer/src/entities/warp_portal.ts

+5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ export default class WarpPortal extends Entity {
1717
x: 32,
1818
y: 32
1919
}
20+
21+
origin = {
22+
x: 0.5,
23+
y: 0.5
24+
}
2025

2126
collider_type = 'box';
2227

TypescriptServer/src/initializers/08_ping.ts

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
const ping_interval = setInterval(() => {
22
global.clients.forEach((c) => {
33
c.sendPing();
4+
5+
if (c.reconnect_timer < 0) {
6+
7+
}
48
})
59
}, global.config.ping_interval);
610

0 commit comments

Comments
 (0)