added "lightBox" to the interface Luminous; determines which area of the actor is luminous, and modified lightmapRenderer code accordingly

Former-commit-id: d7d9c33977b0fa2fd505cd070cf1cb6da0bdc0db
Former-commit-id: cf7c96f2ff891e07622ac0657811ea9de2cbd7c5
This commit is contained in:
Song Minjae
2016-06-20 13:14:41 +09:00
parent e926dd84db
commit e62f8feda5
15 changed files with 122 additions and 49 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 B

View File

@@ -3,4 +3,4 @@
|0..4095|Tiles|
|4096..32767|Items|
|32768..0x7FFFFFFF|Actors|
|0x80000000L..0xFFFFFFFFL|Faction|
|0x80000000..0xFFFFFFFF (all negative number)|Faction|

View File

@@ -14,7 +14,7 @@ abstract class Actor : Comparable<Actor>, Runnable {
/**
* Valid RefID is equal to or greater than 32768.
* @return Reference ID. (32768-0xFFFF_FFFF)
* @return Reference ID. (32768-0x7FFF_FFFF)
*/
abstract var referenceID: Int
@@ -22,10 +22,11 @@ abstract class Actor : Comparable<Actor>, Runnable {
override fun equals(other: Any?) = referenceID == (other as Actor).referenceID
override fun hashCode() = referenceID
override fun toString() = "Actor, " + if (actorValue.getAsString(AVKey.NAME).isNullOrEmpty())
"ID: ${hashCode()}"
else
"ID: ${hashCode()} (${actorValue.getAsString(AVKey.NAME)})"
override fun toString() = "Actor, " +
if (actorValue.getAsString(AVKey.NAME).isNullOrEmpty())
"ID: ${hashCode()}"
else
"ID: ${hashCode()} (${actorValue.getAsString(AVKey.NAME)})"
override fun compareTo(other: Actor): Int = (this.referenceID - other.referenceID).sign()
fun Int.sign(): Int = if (this > 0) 1 else if (this < 0) -1 else this

View File

@@ -18,7 +18,7 @@ import org.newdawn.slick.Graphics
*
* Created by minjaesong on 16-03-14.
*/
open class ActorWithBody constructor() : Actor(), Visible {
open class ActorWithBody : Actor(), Visible {
override var actorValue: ActorValue = ActorValue()
@@ -65,10 +65,11 @@ open class ActorWithBody constructor() : Actor(), Visible {
override var referenceID: Int = generateUniqueReferenceID()
/**
* Positions: top-left point
* * Position: top-left point
* * Unit: pixel
*/
override val hitbox = Hitbox(0.0,0.0,0.0,0.0)
@Transient val nextHitbox = Hitbox(0.0,0.0,0.0,0.0)
override val hitbox = Hitbox(0.0, 0.0, 0.0, 0.0)
@Transient val nextHitbox = Hitbox(0.0, 0.0, 0.0, 0.0)
/**
* Physical properties.
@@ -194,7 +195,7 @@ open class ActorWithBody constructor() : Actor(), Visible {
internal var walledRight = false
init {
// any initialiser goes here...
}
/**
@@ -251,7 +252,7 @@ open class ActorWithBody constructor() : Actor(), Visible {
physSleep = false
}
override fun update(gc: GameContainer, delta_t: Int) {
override fun update(gc: GameContainer, delta: Int) {
if (isUpdate) {
// make NoClip work for player
@@ -549,15 +550,14 @@ open class ActorWithBody constructor() : Actor(), Visible {
val ccdTryMax = 400
var ccdCount = 0
//if (ccdDelta.x.abs() >= SLEEP_THRE || ccdDelta.y.abs() >= SLEEP_THRE) { // regular situation
// CCD to delta while still colliding
while ((isColliding(CONTACT_AREA_LEFT) || isColliding(CONTACT_AREA_RIGHT)
while (((ccdDelta.x.abs() >= SLEEP_THRE) || (ccdDelta.y.abs() >= SLEEP_THRE))
&& (isColliding(CONTACT_AREA_LEFT) || isColliding(CONTACT_AREA_RIGHT)
|| isColliding(CONTACT_AREA_TOP) || isColliding(CONTACT_AREA_BOTTOM))
&& ccdCount < ccdTryMax
) {
nextHitbox.translate(ccdDelta)
ccdCount += 1
}
&& ccdCount < ccdTryMax
) {
nextHitbox.translate(ccdDelta)
ccdCount += 1
}
//}
/*else { // stuck while standing still
// CCD upward
@@ -586,7 +586,7 @@ open class ActorWithBody constructor() : Actor(), Visible {
private fun applyNormalForce() {
if (!isNoCollideWorld) {
// axis Y
if (moveDelta.y >= 0) { // check downward
if (moveDelta.y > SLEEP_THRE) { // check downward
if (isColliding(CONTACT_AREA_BOTTOM) || isColliding(CONTACT_AREA_BOTTOM, 0, 1)) {
// the actor is hitting the ground
hitAndReflectY()
@@ -596,7 +596,7 @@ open class ActorWithBody constructor() : Actor(), Visible {
grounded = false
}
}
else if (moveDelta.y < 0) { // check upward
else if (moveDelta.y < SLEEP_THRE) { // check upward
grounded = false
if (isColliding(CONTACT_AREA_TOP) || isColliding(CONTACT_AREA_TOP, 0, -1)) {
// the actor is hitting the ceiling
@@ -606,7 +606,7 @@ open class ActorWithBody constructor() : Actor(), Visible {
}
}
// axis X
if (moveDelta.x > 0) { // check right
if (moveDelta.x > SLEEP_THRE) { // check right
if ((isColliding(CONTACT_AREA_RIGHT) && !isColliding(CONTACT_AREA_LEFT))
|| (isColliding(CONTACT_AREA_RIGHT, 1, 0) && !isColliding(CONTACT_AREA_LEFT, 0, -1))) {
// the actor is hitting the right wall
@@ -615,7 +615,7 @@ open class ActorWithBody constructor() : Actor(), Visible {
else {
}
}
else if (moveDelta.x < 0) { // check left
else if (moveDelta.x < SLEEP_THRE) { // check left
// System.out.println("collidingleft");
if ((isColliding(CONTACT_AREA_LEFT) && !isColliding(CONTACT_AREA_RIGHT))
|| (isColliding(CONTACT_AREA_LEFT, -1, 0) && !isColliding(CONTACT_AREA_RIGHT, 1, 0))) {

View File

@@ -22,7 +22,7 @@ class DroppedItem constructor(itemID: Int) : ActorWithBody() {
ItemPropCodex.getProp(itemID).mass
}
override fun update(gc: GameContainer, delta_t: Int) {
override fun update(gc: GameContainer, delta: Int) {
}

View File

@@ -0,0 +1,26 @@
package net.torvald.terrarum.gameactors
import net.torvald.spriteanimation.SpriteAnimation
/**
* Created by minjaesong on 16-06-17.
*/
open class FixturesBase : ActorWithBody() {
/** Binary flags. Indicates that other actor (player) can pass in the direction.
* - (0: No collision)
* - 1: Top
* - 2: Right
* - 4: Bottom
* - 8: Left
* For example, flag of 4 is good for tables; player can stand on, which means
* downward movement is blocked within the fixtures' AABB.
*/
var collisionFlag: Int = 0
/**
* Normally if player is standing on the fixtures (with flag 4), pressing DOWN wiil allow
* player to get down. Setting this flag TRUE will block such movement (player cannot get down)
*/
var cannotPassThru = false
}

View File

@@ -0,0 +1,35 @@
package net.torvald.terrarum.gameactors
import net.torvald.spriteanimation.SpriteAnimation
import net.torvald.terrarum.tileproperties.TileNameCode
import net.torvald.terrarum.tileproperties.TilePropCodex
/**
* Created by minjaesong on 16-06-17.
*/
class FixturesTikiTorch : FixturesBase(), Luminous {
override var luminosity: Int
get() = TilePropCodex.getProp(TileNameCode.TORCH).luminosity
set(value) {
throw UnsupportedOperationException()
}
override val lightBox: Hitbox = Hitbox(3.0, 0.0, 4.0, 3.0)
init {
isVisible = true
super.setDensity(1200)
setHitboxDimension(10, 24, 0, 0)
sprite = SpriteAnimation()
sprite!!.setDimension(10, 27)
sprite!!.setSpriteImage("res/graphics/sprites/fixtures/tiki_torch.png")
sprite!!.setDelay(200)
sprite!!.setRowsAndFrames(1, 1)
sprite!!.setAsVisible()
actorValue[AVKey.BASEMASS] = 1.0
actorValue[AVKey.LUMINOSITY] = TilePropCodex.getProp(TileNameCode.TORCH).luminosity
}
}

View File

@@ -8,17 +8,18 @@ interface Luminous {
/**
* Recommended implementation:
*
override var luminosity: Char
get() = if (actorValue.get("luminosity") != null) {
actorValue.get("luminosity") as Char
}
else {
0 as Char
}
override var luminosity: Int
get() = actorValue.getAsInt(AVKey.LUMINOSITY) ?: 0
set(value) {
actorValue.set("luminosity", value)
actorValue[AVKey.LUMINOSITY] = value
}
*/
var luminosity: Int
/**
* Arguments:
*
* Hitbox(x-offset, y-offset, width, height)
*/
val lightBox: Hitbox
}

View File

@@ -8,11 +8,11 @@ import org.newdawn.slick.Graphics
/**
* Created by minjaesong on 16-03-14.
*/
class PhysTestBall : ActorWithBody {
class PhysTestBall : ActorWithBody() {
private var color = Color.orange
constructor(): super() {
init {
setHitboxDimension(16, 16, 0, 0)
isVisible = true
actorValue[AVKey.BASEMASS] = 10.0

View File

@@ -17,7 +17,7 @@ import java.util.*
* Created by minjaesong on 16-03-14.
*/
class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, LandHolder {
class Player : ActorWithBody(), Controllable, Pocketed, Factionable, Luminous, LandHolder {
/**
* empirical value.
@@ -71,6 +71,8 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
set(value) {
actorValue[AVKey.LUMINOSITY] = value
}
override val lightBox: Hitbox
get() = Hitbox(0.0, 0.0, hitbox.width, hitbox.height) // use getter; dimension of the player may change by time.
companion object {
@Transient internal const val ACCEL_MULT_IN_FLIGHT: Double = 0.21 // TODO air control still too 'slippery' with 0.31, lower the value!
@@ -87,20 +89,19 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
* @throws SlickException
*/
@Throws(SlickException::class)
constructor() : super() {
init {
isVisible = true
referenceID = PLAYER_REF_ID
referenceID = PLAYER_REF_ID // forcibly set ID
super.setDensity(BASE_DENSITY)
}
override fun update(gc: GameContainer, delta_t: Int) {
override fun update(gc: GameContainer, delta: Int) {
if (vehicleRiding is Player)
throw RuntimeException("Attempted to 'ride' " + "player object.")
super.update(gc, delta_t)
super.update(gc, delta)
updateSprite(delta_t)
updateSprite(delta)
updateMovementControl()

View File

@@ -29,7 +29,7 @@ object LightmapRenderer {
* 8-Bit RGB values
*/
private val lightmap: Array<IntArray> = Array(LIGHTMAP_HEIGHT) { IntArray(LIGHTMAP_WIDTH) }
private val lanternMap = ArrayList<Lantern>(Terrarum.game.ACTORCONTAINER_INITIAL_SIZE)
private val lanternMap = ArrayList<Lantern>(Terrarum.game.ACTORCONTAINER_INITIAL_SIZE * 4)
private val AIR = TileNameCode.AIR
@@ -172,12 +172,19 @@ object LightmapRenderer {
// scan for luminous actors and store their lighting info to the lanterns
lanternMap.clear()
Terrarum.game.actorContainer.forEach { it ->
if (it is Luminous && it is Visible)
lanternMap.add(Lantern(
it.hitbox.centeredX.div(TSIZE).round(),
it.hitbox.centeredY.div(TSIZE).round(),
it.luminosity
))
if (it is Luminous && it is Visible) {
// put lanterns to the area the luminantBox is occupying
val lightBox = it.lightBox
val lightBoxX = it.hitbox.posX + lightBox.posX
val lightBoxY = it.hitbox.posY + lightBox.posY
val lightBoxW = lightBox.width
val lightBoxH = lightBox.height
for (y in lightBoxY.div(TSIZE).floorInt()
..lightBoxY.plus(lightBoxH).div(TSIZE).floorInt())
for (x in lightBoxX.div(TSIZE).floorInt()
..lightBoxX.plus(lightBoxW).div(TSIZE).floorInt())
lanternMap.add(Lantern(x, y, it.luminosity))
}
}
try {
@@ -623,6 +630,7 @@ object LightmapRenderer {
private fun Float.sqrt() = FastMath.sqrt(this)
private fun Float.inv() = 1f / this
fun Float.floor() = FastMath.floor(this)
fun Double.floorInt() = Math.floor(this).toInt()
fun Float.round(): Int = Math.round(this)
fun Double.round(): Int = Math.round(this).toInt()
fun Float.ceil() = FastMath.ceil(this)

View File

@@ -0,0 +1 @@
*.{psd,tga,ogg} filter=lfs diff=lfs merge=lfs -text