Fizyka (PhysicsManager)
Phaser Arcade Physics — ciała, prędkości, collidery, overlap i granice świata. Bez własnego silnika fizyki.
Arcade, nie własny silnik#
PhysicsManager to cienka warstwa nad Phaser Arcade Physics. Świadoma decyzja: prosta fizyka AABB wystarcza dla gier 2D, a własny silnik to tysiące linii do utrzymania.
API#
attach(port); detach(); isAttached()
setWorldBounds(x, y, w, h)
attachBody(object); detachBody(object); readPosition(object)
setVelocity(object, vx, vy); getVelocity(object)
setImmovable(object, bool); setCollideWorldBounds(object, bool)
addCollider(a, b, handler?): ColliderHandle
addOverlap(a, b, handler): ColliderHandle
clear(): void
ColliderPair to jeden obiekt albo tablica obiektów — np. findByTag('wall').
Ciało obiektu#
const player = this.createSprite('hero', { x: 100, y: 200 })
this.getPhysics().attachBody(player)
this.getPhysics().setCollideWorldBounds(player, true)
this.getPhysics().setVelocity(player, 0, 0)
Albo przez deskryptor przy tworzeniu:
const wall = this.createRect(280, 24, { x: 520, y: 420, fill: '#3a4256' })
this.getPhysics().attachBody(wall)
this.getPhysics().setImmovable(wall, true)
Granice świata#
this.getPhysics().setWorldBounds(0, 0, 2000, 1400)
Kolizje i overlap#
Collider — fizyczne zderzenie (ciała się odbijają/zatrzymują):
const walls = this.findByTag('wall')
this.getPhysics().addCollider(player, walls)
Overlap — wykrycie przecięcia bez reakcji fizycznej (pickupy, strefy):
const coins = this.findByTag('coin')
this.getPhysics().addOverlap(player, coins, (playerObj, coinObj) => {
this.score += 1
this.playSound('pickup', { channel: 'sfx' })
this.destroyObject(coinObj)
})
Przykład: platformer z fixedUpdate#
class PlatformerScene extends Scene {
private player!: GameObject
private walls: GameObject[] = []
create() {
this.getPhysics().setWorldBounds(0, 0, 2000, 1400)
this.player = this.createSprite('hero', { x: 100, y: 300 })
this.getPhysics().attachBody(this.player)
this.getPhysics().setCollideWorldBounds(this.player, true)
for (const spec of WALLS) {
const wall = this.createRect(spec.width, spec.height, { x: spec.x, y: spec.y })
this.getPhysics().attachBody(wall)
this.getPhysics().setImmovable(wall, true)
this.walls.push(wall)
}
this.getPhysics().addCollider(this.player, this.walls)
}
fixedUpdate() {
const input = this.getInput()
const vx = input.isActionDown('move-right') ? 240 : input.isActionDown('move-left') ? -240 : 0
this.getPhysics().setVelocity(this.player, vx, 0)
}
}
Fizyka w fixedUpdate
Ustawianie prędkości rób w fixedUpdate, nie w update — inaczej przy spadku FPS fizyka stanie się niedeterministyczna. Render może zostać w update z interpolacją przez fixedAlpha.
Sprzątanie#
this.getPhysics().clear()
Przy shutdown() sceny ciała i collidery są usuwane razem z obiektami. clear() przydaje się przy przebudowie poziomu bez zmiany sceny.