add terrain collision
This commit is contained in:
+11
-4
@@ -28,15 +28,22 @@ export default class Entity {
|
||||
set y(value) { this.position.y = value }
|
||||
|
||||
get collidables() {
|
||||
return this.game?.entities.filter((e) => e.id != this.id).map((e) => e.collider)
|
||||
const entityColliders = (this.game?.entities ?? []).filter((e) => e.id != this.id).map((e) => e.collider)
|
||||
const terrainColliders = (this.game?.terrains ?? []).map((t) => t.colliders).flat()
|
||||
|
||||
return entityColliders.concat(terrainColliders)
|
||||
}
|
||||
|
||||
get collider() {
|
||||
return new SAT.Circle(new SAT.Vector(this.x, this.y), this.radius)
|
||||
}
|
||||
|
||||
isColliding(collider) {
|
||||
return SATX.colliding(this.collider, collider)
|
||||
get colliders() {
|
||||
return [this.collider]
|
||||
}
|
||||
|
||||
isColliding(...colliders) {
|
||||
return SATX.collideObjects(this.collider, colliders)
|
||||
}
|
||||
|
||||
moveAction(x, y) {
|
||||
@@ -71,7 +78,7 @@ export default class Entity {
|
||||
const position = distance <= speed ? fixedDest : stepTaken
|
||||
|
||||
const collider = Entity.collider(position.x, position.y, this.radius)
|
||||
const isColliding = this.collidables.some((c) => SATX.colliding(collider, c))
|
||||
const isColliding = SATX.collideObjects(collider, this.collidables)
|
||||
|
||||
if (!isColliding) {
|
||||
this.position.copy(position)
|
||||
|
||||
+7
-11
@@ -42,25 +42,21 @@ app.listen(port, () => {
|
||||
|
||||
const entity1 = new Entity()
|
||||
entity1.id = '1'
|
||||
entity1.teleport(100, 100)
|
||||
entity1.radius = 35
|
||||
entity1.teleport(350, 500)
|
||||
entity1.radius = 50
|
||||
game.spawn_entity(entity1)
|
||||
|
||||
const entity2 = new Entity()
|
||||
entity2.id = '2'
|
||||
entity2.teleport(200, 100)
|
||||
entity2.teleport(800, 100)
|
||||
entity2.radius = 35
|
||||
game.spawn_entity(entity2)
|
||||
|
||||
const vertices = [
|
||||
{ x: 0, y: 0 },
|
||||
{ x: 20, y: 0 },
|
||||
{ x: 20, y: 20 },
|
||||
{ x: 10, y: 20 },
|
||||
{ x: 10, y: 5 },
|
||||
{ x: 5, y: 5 },
|
||||
{ x: 5, y: 20 },
|
||||
{ x: 0, y: 20 },
|
||||
{ x: 400, y: 400 },
|
||||
{ x: 600, y: 400 },
|
||||
{ x: 600, y: 600 },
|
||||
{ x: 400, y: 600 },
|
||||
]
|
||||
|
||||
const terrain1 = new Terrain(vertices)
|
||||
|
||||
+5
-1
@@ -1,7 +1,7 @@
|
||||
import SAT from 'sat'
|
||||
|
||||
export default class SATX {
|
||||
static colliding(collider1, collider2) {
|
||||
static collideObject(collider1, collider2) {
|
||||
if (collider1 instanceof SAT.Circle && collider2 instanceof SAT.Circle) {
|
||||
return SAT.testCircleCircle(collider1, collider2)
|
||||
}
|
||||
@@ -20,4 +20,8 @@ export default class SATX {
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
static collideObjects(collider1, colliders) {
|
||||
return colliders.some((c) => this.collideObject(collider1, c))
|
||||
}
|
||||
}
|
||||
|
||||
+2
-6
@@ -23,10 +23,6 @@ export default class Terrain {
|
||||
state() {
|
||||
return {
|
||||
...this,
|
||||
position: {
|
||||
x: this.x,
|
||||
y: this.y,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,8 +37,8 @@ export default class Terrain {
|
||||
const indicesToPolygon = (indices) => {
|
||||
const satPoints = [
|
||||
new SAT.Vector(...points.shape[indices[0]].toArray()),
|
||||
new SAT.Vector(...points.shape[indices[1]].toArray()),
|
||||
new SAT.Vector(...points.shape[indices[2]].toArray()),
|
||||
new SAT.Vector(...points.shape[indices[1]].clone().sub(points.shape[indices[0]]).toArray()),
|
||||
new SAT.Vector(...points.shape[indices[2]].clone().sub(points.shape[indices[0]]).toArray()),
|
||||
]
|
||||
|
||||
return new SAT.Polygon(satPoints[0], [new SAT.Vector(), satPoints[1], satPoints[2]])
|
||||
|
||||
Reference in New Issue
Block a user