Skip to content

Commit

Permalink
server-side entity origin x/y
Browse files Browse the repository at this point in the history
  • Loading branch information
evolutionleo committed Nov 28, 2024
1 parent d36e5d3 commit c0a6e8d
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 39 deletions.
4 changes: 2 additions & 2 deletions Client/rooms/r1v1/r1v1.yy

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Client/sprites/sPlayer/sPlayer.yy

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Client/sprites/sWarpPortal/sWarpPortal.yy

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

99 changes: 69 additions & 30 deletions TypescriptServer/src/concepts/entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ class Entity extends EventEmitter {
static object_name:string = 'oUnknownEntity';
type: string;
object_name: string;
// type = Entity.type;
// object_name = Entity.object_name;

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

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

base_size:Point = { x: 64, y: 64 };
scale:Point = { x: 1, y: 1 };
flip:Point = { x: 0, y: 0 };


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

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

Expand Down Expand Up @@ -112,7 +113,7 @@ class Entity extends EventEmitter {
if (typeof value === 'string') {
this._state = this.states[value];
}
// it's a number
// state is a number
// (-1 means keep the old state)
else if (value != -1) {
this._state = value;
Expand All @@ -133,14 +134,13 @@ class Entity extends EventEmitter {
this.id = crypto.randomUUID();
this.room = room;
this.pos = { x, y };
this.spd = { x: 0, y: 0};
this.spd = { x: 0, y: 0 };
this.prev_pos = { x, y };

this.type = this.constructor['type'];
this.object_name = this.constructor['object_name'];

this.createCollider();
this.collider.entity = this;

this.tree.insert(this.collider);
}
Expand Down Expand Up @@ -194,12 +194,15 @@ class Entity extends EventEmitter {
}

public createCollider(x = this.x, y = this.y) {
let pos = {x: x, y: y};
let pos = {
x: x + this.width * (this.collider_origin.x - this.origin.x),
y: y + this.height * (this.collider_origin.y - this.origin.y)
};

// create the collider
switch(this.collider_type) {
case 'box':
this.collider = new BoxCollider(pos, this.width - .01, this.height - .01);
this.collider = new BoxCollider(pos, this.base_size.x - .01, this.base_size.y - .01);
break;
case 'circle':
this.collider = new CircleCollider(pos, this.collider_radius);
Expand All @@ -212,6 +215,10 @@ class Entity extends EventEmitter {
throw 'Unknown collider type: ' + this.collider_type;
}

this.collider.setScale(this.xscale, this.yscale);
this.collider.setAngle(this.angle);
// this.tree.updateBody(this.collider);

this.collider.entity = this;
}

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

protected updateCollider(x = this.x, y = this.y) {
if (this.size.x != this.prev_size.x || this.size.y != this.prev_size.y) {
this.regenerateCollider(x, y);
protected updateCollider(x = this.x, y = this.y, collider = this.collider) {
let pos = {
x: x + this.width * (this.collider_origin.x - this.origin.x),
y: y + this.height * (this.collider_origin.y - this.origin.y)
};

if (collider === this.collider) {
collider.setScale(this.xscale, this.yscale);
collider.setAngle(this.angle);
collider.setPosition(pos.x, pos.y);
}
else {
collider.setPosition(x, y);
}

this.collider.setAngle(this.angle);
this.collider.setPosition(x, y);
this.tree.updateBody(this.collider);
this.tree.updateBody(collider);
}

public checkCollision(x: number = this.x, y: number = this.y, e:Entity):boolean {
this.updateCollider(x, y);
return this.tree.checkCollision(this.collider, e.collider);
public checkCollision(x: number = this.x, y: number = this.y, e:Entity, collider = this.collider):boolean {
this.updateCollider(x, y, collider);

let result = this.tree.checkCollision(collider, e.collider);

// move back the collider
if (collider === this.collider)
this.updateCollider(this.x, this.y);

return result;
}

public placeMeeting(x:number = this.x, y:number = this.y, type:EntityType|string = 'solid'):boolean {
this.updateCollider(x, y);
public placeMeeting(x:number = this.x, y:number = this.y, type:EntityType|string = 'solid', collider = this.collider):boolean {
this.updateCollider(x, y, collider);

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

return this.tree.checkOne(this.collider, (res) => {
let result = this.tree.checkOne(this.collider, (res) => {
let e = res.b.entity;
return e.matchesType(type);
return e && e.matchesType(type);
});

// move back the collider
if (collider === this.collider)
this.updateCollider(this.x, this.y);

return result;
}

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

let entities = [];
this.tree.checkOne(this.collider, (res) => {
this.tree.checkOne(collider, (res) => {
let e = res.b.entity;
if (e.matchesType(type))
if (e && e.matchesType(type))
entities.push(e);
});

// move back the collider
if (collider === this.collider)
this.updateCollider(this.x, this.y);

return entities;
}

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

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

// removes the entity from the room (and triggers the 'remove' event)
public remove() {
this.emit('remove');
let idx = this.room.entities.indexOf(this);
if (idx === -1) { // already removed
return;
}
this.emit('remove');
this.room.entities.splice(idx, 1);
this.tree.remove(this.collider);
}
Expand Down Expand Up @@ -343,11 +379,14 @@ class Entity extends EventEmitter {
let x:number = this.x, y:number = this.y;
let w:number = this.width, h:number = this.height;

let ox = this.origin.x;
let oy = this.origin.y;

return {
left: x,
top: y,
right: x + w,
bottom: y + h
left: x - w*ox,
top: y - h*oy,
right: x + w*(1-ox),
bottom: y + h*(1-oy)
}
}

Expand Down
10 changes: 9 additions & 1 deletion TypescriptServer/src/entities/player.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import trace from '#util/logging';
import Entity from '#concepts/entity';
import Entity, { ColliderType } from '#concepts/entity';
import Client from '#concepts/client';
import Room from '#concepts/room';
import Point from '#types/point';
Expand Down Expand Up @@ -37,6 +37,9 @@ export default class PlayerEntity extends PhysicsEntity {
static object_name = 'oPlayer';

collider_type = 'box';
// collider_type:ColliderType = 'circle';
// collider_radius: number = 16;
collider_origin = { x: 0, y: 0 };

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

origin = {
x: 0.5,
y: 0.5
}

states = { idle: 0, walk: 1 };

client:Client;
Expand Down
5 changes: 5 additions & 0 deletions TypescriptServer/src/entities/warp_portal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ export default class WarpPortal extends Entity {
x: 32,
y: 32
}

origin = {
x: 0.5,
y: 0.5
}

collider_type = 'box';

Expand Down
4 changes: 4 additions & 0 deletions TypescriptServer/src/initializers/08_ping.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
const ping_interval = setInterval(() => {
global.clients.forEach((c) => {
c.sendPing();

if (c.reconnect_timer < 0) {

}
})
}, global.config.ping_interval);

Expand Down

0 comments on commit c0a6e8d

Please sign in to comment.