implementation of feature ROUNDWORLD

Former-commit-id: b869816eceefc4d728919cd2028ea98cf4d0f505
Former-commit-id: 8dc1d95e49aef406899c8086f053ebb13d416884
This commit is contained in:
Song Minjae
2016-10-23 00:48:05 +09:00
parent 3160ecea16
commit 2b31bb962a
5 changed files with 69 additions and 75 deletions

View File

@@ -85,11 +85,6 @@ constructor(gamename: String) : StateBasedGame(gamename) {
fontGame = GameFontWhite() fontGame = GameFontWhite()
fontSmallNumbers = TinyAlphNum() fontSmallNumbers = TinyAlphNum()
fontControlGuide = SpriteSheetFont(SpriteSheet(
"./assets/graphics/fonts/" +
if (environment == RunningEnvironment.CONSOLE) "keycaps_gamepad.png"
else "keycaps.png", 18, 18)
, ' ')
hasController = gc.input.controllerCount > 0 hasController = gc.input.controllerCount > 0
if (hasController) { if (hasController) {
@@ -176,8 +171,6 @@ constructor(gamename: String) : StateBasedGame(gamename) {
private set private set
lateinit var fontSmallNumbers: Font lateinit var fontSmallNumbers: Font
private set private set
lateinit var fontControlGuide: Font
private set
var joypadLabelStart: Char = 0x00.toChar() // lateinit var joypadLabelStart: Char = 0x00.toChar() // lateinit
var joypadLableSelect:Char = 0x00.toChar() // lateinit var joypadLableSelect:Char = 0x00.toChar() // lateinit

View File

@@ -39,8 +39,8 @@ open class ActorWithBody : Actor(), Visible {
* * Unit: pixel * * Unit: pixel
* !! external class should not hitbox.set(); use setHitboxDimension() and setPosition() * !! external class should not hitbox.set(); use setHitboxDimension() and setPosition()
*/ */
override val hitbox = Hitbox(0.0, 0.0, 0.0, 0.0) override val hitbox = Hitbox(0.0, 0.0, 0.0, 0.0) // Hitbox is implemented using Double;
@Transient val nextHitbox = Hitbox(0.0, 0.0, 0.0, 0.0) @Transient val nextHitbox = Hitbox(0.0, 0.0, 0.0, 0.0) // 52 mantissas ought to be enough for anybody...
/** /**
* Velocity vector for newtonian sim. * Velocity vector for newtonian sim.
@@ -346,7 +346,7 @@ open class ActorWithBody : Actor(), Visible {
// apply our compensation to actual hitbox // apply our compensation to actual hitbox
updateHitbox() updateHitbox()
// make sure the actor does not go out of the map // make sure if the actor tries to go out of the map, loop back instead
clampHitbox() clampHitbox()
} }
@@ -862,8 +862,18 @@ open class ActorWithBody : Actor(), Visible {
} }
private fun clampHitbox() { private fun clampHitbox() {
val worldsizePxl = world.width.times(TSIZE)
hitbox.setPositionFromPoint( hitbox.setPositionFromPoint(
clampW(hitbox.pointedX), clampH(hitbox.pointedY)) //clampW(hitbox.pointedX),
if (hitbox.pointedX < 0)
hitbox.pointedX + worldsizePxl
else if (hitbox.pointedX >= worldsizePxl)
hitbox.pointedX - worldsizePxl
else
hitbox.pointedX, // ROUNDWORLD impl
clampH(hitbox.pointedY)
)
} }
private fun setNewNextHitbox() { private fun setNewNextHitbox() {

View File

@@ -1,9 +1,6 @@
package net.torvald.terrarum.gameworld package net.torvald.terrarum.gameworld
import net.torvald.terrarum.gameactors.Player
import net.torvald.terrarum.gameactors.roundInt
import net.torvald.terrarum.mapdrawer.MapDrawer
import org.dyn4j.geometry.Vector2 import org.dyn4j.geometry.Vector2
import org.newdawn.slick.SlickException import org.newdawn.slick.SlickException
@@ -89,8 +86,8 @@ constructor(//properties
get() = terrainDamage.dataPair get() = terrainDamage.dataPair
fun getTileFromWall(x: Int, y: Int): Int? { fun getTileFromWall(x: Int, y: Int): Int? {
val wall: Int? = layerWall.getTile(x, y) val wall: Int? = layerWall.getTile(x fmod width, y)
val wallDamage: Int? = getWallDamage(x, y) val wallDamage: Int? = getWallDamage(x fmod width, y)
return if (wall == null || wallDamage == null) return if (wall == null || wallDamage == null)
null null
else else
@@ -98,8 +95,8 @@ constructor(//properties
} }
fun getTileFromTerrain(x: Int, y: Int): Int? { fun getTileFromTerrain(x: Int, y: Int): Int? {
val terrain: Int? = layerTerrain.getTile(x, y) val terrain: Int? = layerTerrain.getTile(x fmod width, y)
val terrainDamage: Int? = getTerrainDamage(x, y) val terrainDamage: Int? = getTerrainDamage(x fmod width, y)
return if (terrain == null || terrainDamage == null) return if (terrain == null || terrainDamage == null)
null null
else else
@@ -107,15 +104,15 @@ constructor(//properties
} }
fun getTileFromWire(x: Int, y: Int): Int? { fun getTileFromWire(x: Int, y: Int): Int? {
return layerWire.getTile(x, y) return layerWire.getTile(x fmod width, y)
} }
fun getWallDamage(x: Int, y: Int): Int? { fun getWallDamage(x: Int, y: Int): Int? {
return wallDamage.getData(x, y) return wallDamage.getData(x fmod width, y)
} }
fun getTerrainDamage(x: Int, y: Int): Int? { fun getTerrainDamage(x: Int, y: Int): Int? {
return terrainDamage.getData(x, y) return terrainDamage.getData(x fmod width, y)
} }
/** /**
@@ -127,7 +124,7 @@ constructor(//properties
* @param combinedTilenum (tilenum * 16) + damage * @param combinedTilenum (tilenum * 16) + damage
*/ */
fun setTileWall(x: Int, y: Int, combinedTilenum: Int) { fun setTileWall(x: Int, y: Int, combinedTilenum: Int) {
setTileWall(x, y, (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE) setTileWall(x fmod width, y, (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE)
} }
/** /**
@@ -139,21 +136,21 @@ constructor(//properties
* @param combinedTilenum (tilenum * 16) + damage * @param combinedTilenum (tilenum * 16) + damage
*/ */
fun setTileTerrain(x: Int, y: Int, combinedTilenum: Int) { fun setTileTerrain(x: Int, y: Int, combinedTilenum: Int) {
setTileTerrain(x, y, (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE) setTileTerrain(x fmod width, y, (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE)
} }
fun setTileWall(x: Int, y: Int, tile: Byte, damage: Int) { fun setTileWall(x: Int, y: Int, tile: Byte, damage: Int) {
layerWall.setTile(x, y, tile) layerWall.setTile(x fmod width, y, tile)
wallDamage.setData(x, y, damage) wallDamage.setData(x fmod width, y, damage)
} }
fun setTileTerrain(x: Int, y: Int, tile: Byte, damage: Int) { fun setTileTerrain(x: Int, y: Int, tile: Byte, damage: Int) {
layerTerrain.setTile(x, y, tile) layerTerrain.setTile(x fmod width, y, tile)
terrainDamage.setData(x, y, damage) terrainDamage.setData(x fmod width, y, damage)
} }
fun setTileWire(x: Int, y: Int, tile: Byte) { fun setTileWire(x: Int, y: Int, tile: Byte) {
layerWire.data[y][x] = tile layerWire.data[y][x fmod width] = tile
} }
fun getTileFrom(mode: Int, x: Int, y: Int): Int? { fun getTileFrom(mode: Int, x: Int, y: Int): Int? {
@@ -225,4 +222,6 @@ constructor(//properties
@Transient val SIZEOF: Byte = MapLayer.SIZEOF @Transient val SIZEOF: Byte = MapLayer.SIZEOF
@Transient val LAYERS: Byte = 4 // terrain, wall (terrainDamage + wallDamage), wire @Transient val LAYERS: Byte = 4 // terrain, wall (terrainDamage + wallDamage), wire
} }
} }
infix fun Int.fmod(other: Int) = Math.floorMod(this, other)

View File

@@ -20,7 +20,7 @@ import java.util.*
* Created by minjaesong on 16-01-19. * Created by minjaesong on 16-01-19.
*/ */
object MapCamera { object MapCamera {
val WORLD: GameWorld = Terrarum.ingame.world; val WORLD: GameWorld = Terrarum.ingame.world
var cameraX = 0 var cameraX = 0
private set private set
@@ -237,10 +237,16 @@ object MapCamera {
renderHeight = FastMath.ceil(Terrarum.HEIGHT / Terrarum.ingame.screenZoom) renderHeight = FastMath.ceil(Terrarum.HEIGHT / Terrarum.ingame.screenZoom)
// position - (WH / 2) // position - (WH / 2)
cameraX = Math.round(FastMath.clamp( /*cameraX = Math.round(FastMath.clamp(
player.hitbox.centeredX.toFloat() - renderWidth / 2, TSIZE.toFloat(), WORLD.width * TSIZE - renderWidth - TSIZE.toFloat())) player.hitbox.centeredX.toFloat() - renderWidth / 2, TSIZE.toFloat(), WORLD.width * TSIZE - renderWidth - TSIZE.toFloat()))
cameraY = Math.round(FastMath.clamp( cameraY = Math.round(FastMath.clamp(
player.hitbox.centeredY.toFloat() - renderHeight / 2, TSIZE.toFloat(), WORLD.height * TSIZE - renderHeight - TSIZE.toFloat())) player.hitbox.centeredY.toFloat() - renderHeight / 2, TSIZE.toFloat(), WORLD.height * TSIZE - renderHeight - TSIZE.toFloat()))
*/
cameraX = Math.round( // X only: ROUNDWORLD implementation
player.hitbox.centeredX.toFloat() - renderWidth / 2)
cameraY = Math.round(FastMath.clamp(
player.hitbox.centeredY.toFloat() - renderHeight / 2, TSIZE.toFloat(), WORLD.height * TSIZE - renderHeight - TSIZE.toFloat()))
} }
fun renderBehind(gc: GameContainer, g: Graphics) { fun renderBehind(gc: GameContainer, g: Graphics) {
@@ -259,11 +265,11 @@ object MapCamera {
} }
private fun drawTiles(mode: Int, drawModeTilesBlendMul: Boolean) { private fun drawTiles(mode: Int, drawModeTilesBlendMul: Boolean) {
val for_y_start = MapCamera.div16(MapCamera.cameraY) val for_y_start = MapCamera.cameraY / TSIZE
val for_y_end = MapCamera.clampHTile(for_y_start + MapCamera.div16(MapCamera.renderHeight) + 2) val for_y_end = MapCamera.clampHTile(for_y_start + (MapCamera.renderHeight / TSIZE) + 2)
val for_x_start = MapCamera.div16(MapCamera.cameraX) val for_x_start = MapCamera.cameraX / TSIZE - 1
val for_x_end = MapCamera.clampWTile(for_x_start + MapCamera.div16(MapCamera.renderWidth) + 2) val for_x_end = for_x_start + (MapCamera.renderWidth / TSIZE) + 2
// initialise // initialise
MapCamera.tilesetBook[mode].startUse() MapCamera.tilesetBook[mode].startUse()
@@ -273,22 +279,22 @@ object MapCamera {
for (x in for_x_start..for_x_end - 1) { for (x in for_x_start..for_x_end - 1) {
val thisTile: Int? val thisTile: Int?
if (mode % 3 == MapCamera.WALL) if (mode % 3 == WALL)
thisTile = MapCamera.WORLD.getTileFromWall(x, y) thisTile = WORLD.getTileFromWall(x, y)
else if (mode % 3 == MapCamera.TERRAIN) else if (mode % 3 == TERRAIN)
thisTile = MapCamera.WORLD.getTileFromTerrain(x, y) thisTile = WORLD.getTileFromTerrain(x, y)
else if (mode % 3 == MapCamera.WIRE) else if (mode % 3 == WIRE)
thisTile = MapCamera.WORLD.getTileFromWire(x, y) thisTile = WORLD.getTileFromWire(x, y)
else else
throw IllegalArgumentException() throw IllegalArgumentException()
val noDamageLayer = mode % 3 == MapCamera.WIRE val noDamageLayer = mode % 3 == WIRE
// draw // draw
try { try {
if ( if (
(mode == MapCamera.WALL || mode == MapCamera.TERRAIN) // not an air tile (mode == WALL || mode == TERRAIN) // not an air tile
&& (thisTile ?: 0) > 0 && (thisTile ?: 0) > 0
&& &&
@@ -354,10 +360,10 @@ object MapCamera {
*/ */
fun getNearbyTilesInfo(x: Int, y: Int, mode: Int, mark: Int?): Int { fun getNearbyTilesInfo(x: Int, y: Int, mode: Int, mark: Int?): Int {
val nearbyTiles = IntArray(4) val nearbyTiles = IntArray(4)
nearbyTiles[NEARBY_TILE_KEY_LEFT] = WORLD.getTileFrom(mode, x - 1, y) ?: 4096 nearbyTiles[NEARBY_TILE_KEY_LEFT] = WORLD.getTileFrom(mode, x - 1, y) ?: 4096
nearbyTiles[NEARBY_TILE_KEY_RIGHT] = WORLD.getTileFrom(mode, x + 1, y) ?: 4096 nearbyTiles[NEARBY_TILE_KEY_RIGHT] = WORLD.getTileFrom(mode, x + 1, y) ?: 4096
nearbyTiles[NEARBY_TILE_KEY_UP] = WORLD.getTileFrom(mode, x, y - 1) ?: 4906 nearbyTiles[NEARBY_TILE_KEY_UP] = WORLD.getTileFrom(mode, x , y - 1) ?: 4906
nearbyTiles[NEARBY_TILE_KEY_DOWN] = WORLD.getTileFrom(mode, x, y + 1) ?: 4096 nearbyTiles[NEARBY_TILE_KEY_DOWN] = WORLD.getTileFrom(mode, x , y + 1) ?: 4096
// try for // try for
var ret = 0 var ret = 0
@@ -372,10 +378,10 @@ object MapCamera {
fun getNearbyTilesInfoNonSolid(x: Int, y: Int, mode: Int): Int { fun getNearbyTilesInfoNonSolid(x: Int, y: Int, mode: Int): Int {
val nearbyTiles = IntArray(4) val nearbyTiles = IntArray(4)
nearbyTiles[NEARBY_TILE_KEY_LEFT] = WORLD.getTileFrom(mode, x - 1, y) ?: 4096 nearbyTiles[NEARBY_TILE_KEY_LEFT] = WORLD.getTileFrom(mode, x - 1, y) ?: 4096
nearbyTiles[NEARBY_TILE_KEY_RIGHT] = WORLD.getTileFrom(mode, x + 1, y) ?: 4096 nearbyTiles[NEARBY_TILE_KEY_RIGHT] = WORLD.getTileFrom(mode, x + 1, y) ?: 4096
nearbyTiles[NEARBY_TILE_KEY_UP] = WORLD.getTileFrom(mode, x, y - 1) ?: 4096 nearbyTiles[NEARBY_TILE_KEY_UP] = WORLD.getTileFrom(mode, x , y - 1) ?: 4906
nearbyTiles[NEARBY_TILE_KEY_DOWN] = WORLD.getTileFrom(mode, x, y + 1) ?: 4096 nearbyTiles[NEARBY_TILE_KEY_DOWN] = WORLD.getTileFrom(mode, x , y + 1) ?: 4096
// try for // try for
var ret = 0 var ret = 0
@@ -396,10 +402,10 @@ object MapCamera {
fun getNearbyTilesInfoWallSticker(x: Int, y: Int): Int { fun getNearbyTilesInfoWallSticker(x: Int, y: Int): Int {
val nearbyTiles = IntArray(4) val nearbyTiles = IntArray(4)
val NEARBY_TILE_KEY_BACK = NEARBY_TILE_KEY_UP val NEARBY_TILE_KEY_BACK = NEARBY_TILE_KEY_UP
nearbyTiles[NEARBY_TILE_KEY_LEFT] = WORLD.getTileFrom(TERRAIN, x - 1, y) ?: 4096 nearbyTiles[NEARBY_TILE_KEY_LEFT] = WORLD.getTileFrom(TERRAIN, x - 1, y) ?: 4096
nearbyTiles[NEARBY_TILE_KEY_RIGHT] = WORLD.getTileFrom(TERRAIN, x + 1, y) ?: 4096 nearbyTiles[NEARBY_TILE_KEY_RIGHT] = WORLD.getTileFrom(TERRAIN, x + 1, y) ?: 4096
nearbyTiles[NEARBY_TILE_KEY_DOWN] = WORLD.getTileFrom(TERRAIN, x, y + 1) ?: 4096 nearbyTiles[NEARBY_TILE_KEY_DOWN] = WORLD.getTileFrom(TERRAIN, x , y + 1) ?: 4096
nearbyTiles[NEARBY_TILE_KEY_BACK] = WORLD.getTileFrom(WALL, x, y) ?: 4096 nearbyTiles[NEARBY_TILE_KEY_BACK] = WORLD.getTileFrom(WALL, x , y) ?: 4096
try { try {
if (TilePropCodex.getProp(nearbyTiles[NEARBY_TILE_KEY_DOWN]).isSolid) if (TilePropCodex.getProp(nearbyTiles[NEARBY_TILE_KEY_DOWN]).isSolid)
@@ -438,20 +444,6 @@ object MapCamera {
} }
} }
fun div16(x: Int): Int = x and 0x7FFFFFFF shr 4
fun mod16(x: Int): Int = x and 15
fun quantise16(x: Int): Int = x and 0xFFFFFFF0.toInt()
fun clampW(x: Int): Int {
if (x < 0) {
return 0
} else if (x > WORLD.width * TSIZE) {
return WORLD.width * TSIZE
} else {
return x
}
}
fun clampH(x: Int): Int { fun clampH(x: Int): Int {
if (x < 0) { if (x < 0) {
return 0 return 0
@@ -482,11 +474,11 @@ object MapCamera {
} }
} }
fun getRenderStartX(): Int = div16(cameraX) fun getRenderStartX(): Int = cameraX / TSIZE
fun getRenderStartY(): Int = div16(cameraY) fun getRenderStartY(): Int = cameraY / TSIZE
fun getRenderEndX(): Int = clampWTile(getRenderStartX() + div16(renderWidth) + 2) fun getRenderEndX(): Int = clampWTile(getRenderStartX() +(renderWidth / TSIZE) + 2)
fun getRenderEndY(): Int = clampHTile(getRenderStartY() + div16(renderHeight) + 2) fun getRenderEndY(): Int = clampHTile(getRenderStartY() +(renderHeight / TSIZE) + 2)
fun isConnectSelf(b: Int?): Boolean = TILES_CONNECT_SELF.contains(b) fun isConnectSelf(b: Int?): Boolean = TILES_CONNECT_SELF.contains(b)
fun isConnectMutual(b: Int?): Boolean = TILES_CONNECT_MUTUAL.contains(b) fun isConnectMutual(b: Int?): Boolean = TILES_CONNECT_MUTUAL.contains(b)
@@ -497,4 +489,4 @@ object MapCamera {
fun tileInCamera(x: Int, y: Int) = fun tileInCamera(x: Int, y: Int) =
x >= cameraX.div(TSIZE) && y >= cameraY.div(TSIZE) && x >= cameraX.div(TSIZE) && y >= cameraY.div(TSIZE) &&
x <= cameraX.plus(renderWidth).div(TSIZE) && y <= cameraY.plus(renderWidth).div(TSIZE) x <= cameraX.plus(renderWidth).div(TSIZE) && y <= cameraY.plus(renderWidth).div(TSIZE)
} }

View File

@@ -38,10 +38,10 @@ object TileStats {
val noZoomCameraY = Math.round(FastMath.clamp( val noZoomCameraY = Math.round(FastMath.clamp(
player.hitbox.centeredY.toFloat() - renderHeight / 2, TSIZE.toFloat(), map.width * TSIZE - renderHeight - TSIZE.toFloat())) player.hitbox.centeredY.toFloat() - renderHeight / 2, TSIZE.toFloat(), map.width * TSIZE - renderHeight - TSIZE.toFloat()))
val for_x_start = MapCamera.div16(noZoomCameraX) val for_x_start = noZoomCameraX / TSIZE
val for_y_start = MapCamera.div16(noZoomCameraY) val for_y_start = noZoomCameraY / TSIZE
val for_y_end = MapCamera.clampHTile(for_y_start + MapCamera.div16(renderHeight) + 2) val for_y_end = MapCamera.clampHTile(for_y_start + (renderHeight / TSIZE) + 2)
val for_x_end = MapCamera.clampWTile(for_x_start + MapCamera.div16(renderWidth) + 2) val for_x_end = MapCamera.clampWTile(for_x_start + (renderWidth / TSIZE) + 2)
for (y in for_y_start..for_y_end - 1) { for (y in for_y_start..for_y_end - 1) {
for (x in for_x_start..for_x_end - 1) { for (x in for_x_start..for_x_end - 1) {