mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
moving platform kinda working
This commit is contained in:
@@ -93,12 +93,37 @@ abstract class PhysContraption() : ActorWithBody() {
|
||||
rider.walledBottom = true
|
||||
}
|
||||
|
||||
// --- Step 2: Mount detection (riders are now at correct positions) ---
|
||||
// --- Step 2a: Check existing riders for dismount ---
|
||||
// Uses a stricter (more negative) velocity threshold than mounting
|
||||
// to create hysteresis and prevent oscillation from small controllerV.y
|
||||
// residuals near the mount threshold boundary.
|
||||
|
||||
val ridersToRemove = ArrayList<ActorID>()
|
||||
val currentRiders = ArrayList<ActorWithBody>()
|
||||
for (riderId in actorsRiding.toList()) {
|
||||
val rider = INGAME.getActorByID(riderId) as? ActorWithBody
|
||||
if (rider == null) {
|
||||
ridersToRemove.add(riderId)
|
||||
continue
|
||||
}
|
||||
|
||||
val feetY = rider.hitbox.endY
|
||||
val platTop = hitbox.startY
|
||||
val feetNear = feetY >= platTop - MOUNT_TOLERANCE_ABOVE &&
|
||||
feetY <= platTop + MOUNT_TOLERANCE_BELOW
|
||||
val horizontalOverlap = rider.hitbox.endX > hitbox.startX &&
|
||||
rider.hitbox.startX < hitbox.endX
|
||||
// Detect real jumps (not small residuals) — threshold is 4x the mount threshold
|
||||
val combinedVelY = rider.externalV.y + (rider.controllerV?.y ?: 0.0)
|
||||
val isJumping = combinedVelY < JUMP_THRESHOLD_Y * 4.0
|
||||
|
||||
if (!feetNear || !horizontalOverlap || isJumping) {
|
||||
dismount(rider)
|
||||
}
|
||||
}
|
||||
ridersToRemove.forEach { actorsRiding.remove(it) }
|
||||
|
||||
// --- Step 2b: Mount detection for new candidates ---
|
||||
|
||||
// Check all active actors + actorNowPlaying
|
||||
val candidates = ArrayList<ActorWithBody>()
|
||||
INGAME.actorContainerActive.forEach {
|
||||
if (it is ActorWithBody && it !== this && it !is PhysContraption) {
|
||||
@@ -108,36 +133,21 @@ abstract class PhysContraption() : ActorWithBody() {
|
||||
INGAME.actorNowPlaying?.let { candidates.add(it) }
|
||||
|
||||
for (actor in candidates) {
|
||||
if (isActorOnTop(actor)) {
|
||||
if (!actorsRiding.contains(actor.referenceID)) {
|
||||
// New rider — mount and snap
|
||||
if (!actorsRiding.contains(actor.referenceID) && isActorOnTop(actor)) {
|
||||
mount(actor)
|
||||
snapRiderToSurface(actor)
|
||||
if (actor.externalV.y > 0.0) {
|
||||
// Landing on the contraption kills all vertical velocity.
|
||||
// controllerV.y must also be zeroed: during a jump-then-fall,
|
||||
// controllerV.y stays negative (jump impulse) while externalV.y
|
||||
// goes positive (gravity). Zeroing only externalV.y would leave
|
||||
// a net upward velocity that immediately triggers dismount.
|
||||
actor.externalV.y = 0.0
|
||||
}
|
||||
actor.controllerV?.let { it.y = 0.0 }
|
||||
actor.walledBottom = true
|
||||
}
|
||||
currentRiders.add(actor)
|
||||
}
|
||||
}
|
||||
|
||||
// --- Step 3: Dismount actors no longer on top ---
|
||||
val currentRiderIds = currentRiders.map { it.referenceID }.toSet()
|
||||
for (riderId in actorsRiding.toList()) {
|
||||
if (riderId !in currentRiderIds) {
|
||||
val rider = INGAME.getActorByID(riderId)
|
||||
if (rider is ActorWithBody) {
|
||||
dismount(rider)
|
||||
}
|
||||
else {
|
||||
ridersToRemove.add(riderId)
|
||||
}
|
||||
}
|
||||
}
|
||||
ridersToRemove.forEach { actorsRiding.remove(it) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Geometry check: is this actor positioned on top of the contraption such that
|
||||
* it should be considered a rider? Subclasses override for different geometries.
|
||||
|
||||
@@ -18,7 +18,7 @@ import kotlin.math.sin
|
||||
class ActorTestPlatform : ActorMovingPlatform(8) {
|
||||
|
||||
/** Movement pattern index (0-3). */
|
||||
private val pattern: Int = 1//(0..3).random()
|
||||
private val pattern: Int = (0..3).random()
|
||||
|
||||
/** Speed in pixels per tick (2.0 to 4.0). */
|
||||
private val speed: Double = 2.0 + Math.random() * 2.0
|
||||
|
||||
Reference in New Issue
Block a user