proof-of-concept collision solver, document for penetration compensation in collision solver and ActorWithBody (collide with world), updated README

Former-commit-id: 985edaea09aff8d972ece24e08bd31c378c60f2b
Former-commit-id: 5c8fbd014c2c2edae21cf89f45a96aedc8d8bad9
This commit is contained in:
Song Minjae
2016-04-27 01:25:25 +09:00
parent 7d804f24e7
commit 7efc693c4a
7 changed files with 79 additions and 16 deletions

View File

@@ -3,6 +3,7 @@ package net.torvald.terrarum
import net.torvald.imagefont.GameFontBase
import net.torvald.terrarum.gameactors.*
import net.torvald.terrarum.console.Authenticator
import net.torvald.terrarum.gameactors.collisionsolver.CollisionSolver
import net.torvald.terrarum.gamecontroller.GameController
import net.torvald.terrarum.gamecontroller.Key
import net.torvald.terrarum.gamecontroller.KeyMap
@@ -82,6 +83,8 @@ constructor() : BasicGameState() {
val KEY_LIGHTMAP_RENDER = Key.F7
val KEY_LIGHTMAP_SMOOTH = Key.F8
var DELTA_T: Int = 0
@Throws(SlickException::class)
override fun init(gameContainer: GameContainer, stateBasedGame: StateBasedGame) {
KeyMap.build()
@@ -133,6 +136,8 @@ constructor() : BasicGameState() {
}
override fun update(gc: GameContainer, sbg: StateBasedGame, delta: Int) {
DELTA_T = delta
update_delta = delta
setAppTitle()
@@ -345,7 +350,8 @@ constructor() : BasicGameState() {
i-- // array removed 1 elem, so also decrement counter by 1
}
else {
actorContainer[i].update(gc, delta)
//actorContainer[i].update(gc, delta)
actorContainer[i].start()
}
i++
}

View File

@@ -7,9 +7,16 @@ import org.newdawn.slick.GameContainer
/**
* Created by minjaesong on 16-03-14.
*/
abstract class Actor : Comparable<Actor> {
abstract class Actor : Comparable<Actor>, Runnable {
abstract fun update(gc: GameContainer, delta_t: Int)
abstract protected fun update(gc: GameContainer, delta_t: Int) // use start() for multithreaded env
protected var thread: Thread? = null
fun start() {
thread = Thread(this, "ID: $referenceID")
thread!!.run()
}
/**
* Valid RefID is equal to or greater than 32768.

View File

@@ -28,7 +28,7 @@ open class ActorWithBody constructor() : Actor(), Visible {
/**
* Velocity vector (broken down by axes) for newtonian sim.
* Acceleration: used in code like:
* veloY += 3.0
* veloY += 3.0
* +3.0 is acceleration. You __accumulate__ acceleration to the velocity.
*/
@Volatile var veloX: Float = 0.toFloat()
@@ -121,17 +121,20 @@ open class ActorWithBody constructor() : Actor(), Visible {
@Transient internal var eventMoving = EVENT_MOVE_NONE // cannot collide both X-axis and Y-axis, or else jump control breaks up.
/**
* in milliseconds
* Post-hit invincibility, in milliseconds
*/
@Transient val INVINCIBILITY_TIME = 500
@Transient val INVINCIBILITY_TIME: Int = 500
@Transient private val map: GameMap
@Transient private val MASS_DEFAULT = 60f
@Transient private val MASS_DEFAULT: Float = 60f
internal val physSleep: Boolean
get() = veloX.abs() < 0.5 && veloY.abs() < 0.5
/**
* for collide-to-world compensation
*/
@Transient private var posAdjustX = 0
@Transient private var posAdjustY = 0
@@ -187,6 +190,8 @@ open class ActorWithBody constructor() : Actor(), Visible {
if (elasticity != 0f) elasticity = 0f
}
override fun run() = update(Terrarum.appgc, Terrarum.game.DELTA_T)
override fun update(gc: GameContainer, delta_t: Int) {
if (isUpdate) {
/**

View File

@@ -1,7 +1,8 @@
package net.torvald.terrarum.gameactors
package net.torvald.terrarum.gameactors.collisionsolver
import com.jme3.math.FastMath
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameactors.ActorWithBody
import java.util.*
/**
@@ -26,7 +27,8 @@ object CollisionSolver {
private val collCandidateStack = Stack<CollisionMarkings>()
/**
* @link https://www.toptal.com/game/video-game-physics-part-ii-collision-detection-for-solid-objects
* to see what's going on here, visit
* [this link](https://www.toptal.com/game/video-game-physics-part-ii-collision-detection-for-solid-objects)
*/
fun process() {
// clean up before we go
@@ -112,15 +114,31 @@ object CollisionSolver {
// if they actually makes collision (e.g. player vs ball), solve it
if (a makesCollisionWith b) {
// assuming perfect elastic collision; ignoring 'var elasticity'
val ux_1 = a.veloX
val ux_2 = b.veloX
val uy_1 = a.veloY
val uy_2 = b.veloY
val m1 = a.mass
val m2 = b.mass
val vx_1 = (ux_2 * (m1 - m2) + 2 * m2 * ux_2) / (m1 + m2)
val vx_2 = (ux_2 * (m2 - m1) + 2 * m1 * ux_1) / (m1 + m2)
val vy_1 = (uy_2 * (m1 - m2) + 2 * m2 * uy_2) / (m1 + m2)
val vy_2 = (uy_2 * (m2 - m1) + 2 * m1 * uy_1) / (m1 + m2)
a.veloX = vx_1
a.veloY = vy_1
b.veloX = vx_2
b.veloY = vy_2
}
}
}
private infix fun ActorWithBody.makesCollisionWith(other: ActorWithBody): Boolean {
return false
return true
}
private infix fun ActorWithBody.isCollidingWith(other: ActorWithBody): Boolean {
val ax = this.hitbox.centeredX
val ay = this.hitbox.centeredY

View File

@@ -0,0 +1,11 @@
package net.torvald.terrarum.gameactors.collisionsolver
/**
* multithreaded version of CollisionSolver#solveCollision
* Created by minjaesong on 16-04-26.
*/
internal class SolveByUnit : Runnable {
override fun run() {
throw UnsupportedOperationException()
}
}