com.torvald → net.torvald

Former-commit-id: 375604da8a20a6ba7cd0a8d05a44add02b2d04f4
Former-commit-id: 287287c5920b07618174d7a7573f049d350ded66
This commit is contained in:
Song Minjae
2016-04-12 12:29:02 +09:00
parent 2a34efb489
commit ac9f5b5138
148 changed files with 473 additions and 524 deletions

View File

@@ -0,0 +1,223 @@
package net.torvald.terrarum.gamemap
import org.newdawn.slick.SlickException
class GameMap
/**
* @param width
* *
* @param height
* *
* @throws SlickException
*/
@Throws(SlickException::class)
constructor(//properties
val width: Int, val height: Int) {
//layers
val layerWall: MapLayer
/**
* Get MapLayer object of terrain
* @return MapLayer terrain layer
*/
val layerTerrain: MapLayer
val layerWire: MapLayer
val wallDamage: PairedMapLayer
val terrainDamage: PairedMapLayer
val spawnX: Int
val spawnY: Int
//public World physWorld = new World( new Vec2(0, -TerrarumMain.game.gravitationalAccel) );
//physics
/** \[m / s^2\] */
var gravitation: Float = 9.8.toFloat()
/** RGB in Integer */
var globalLight: Int = 0
val worldTime: WorldTime
init {
this.spawnX = width / 2
this.spawnY = 200
layerTerrain = MapLayer(width, height)
layerWall = MapLayer(width, height)
layerWire = MapLayer(width, height)
terrainDamage = PairedMapLayer(width, height)
wallDamage = PairedMapLayer(width, height)
globalLight = 0.toChar().toInt()
worldTime = WorldTime()
}
/**
* Get 2d array data of terrain
* @return byte[][] terrain layer
*/
val terrainArray: Array<ByteArray>
get() = layerTerrain.data
/**
* Get 2d array data of wall
* @return byte[][] wall layer
*/
val wallArray: Array<ByteArray>
get() = layerWall.data
/**
* Get 2d array data of wire
* @return byte[][] wire layer
*/
val wireArray: Array<ByteArray>
get() = layerWire.data
/**
* Get paired array data of damage codes.
* Format: 0baaaabbbb, aaaa for x = 0, 2, 4, ..., bbbb for x = 1, 3, 5, ...
* @return byte[][] damage code pair
*/
val damageDataArray: Array<ByteArray>
get() = terrainDamage.dataPair
fun getTileFromWall(x: Int, y: Int): Int? {
val wall: Int? = layerWall.getTile(x, y)
val wallDamage: Int? = getWallDamage(x, y)
return if (wall == null || wallDamage == null)
null
else
wall * PairedMapLayer.RANGE + wallDamage
}
fun getTileFromTerrain(x: Int, y: Int): Int? {
val terrain: Int? = layerTerrain.getTile(x, y)
val terrainDamage: Int? = getTerrainDamage(x, y)
return if (terrain == null || terrainDamage == null)
null
else
terrain * PairedMapLayer.RANGE + terrainDamage
}
fun getTileFromWire(x: Int, y: Int): Int? {
return layerWire.getTile(x, y)
}
fun getWallDamage(x: Int, y: Int): Int? {
return wallDamage.getData(x, y)
}
fun getTerrainDamage(x: Int, y: Int): Int? {
return terrainDamage.getData(x, y)
}
/**
* Set the tile of wall as specified, with damage value of zero.
* @param x
* *
* @param y
* *
* @param combinedTilenum (tilenum * 16) + damage
*/
fun setTileWall(x: Int, y: Int, combinedTilenum: Int) {
setTileWall(x, y, (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE)
}
/**
* Set the tile of wall as specified, with damage value of zero.
* @param x
* *
* @param y
* *
* @param combinedTilenum (tilenum * 16) + damage
*/
fun setTileTerrain(x: Int, y: Int, combinedTilenum: Int) {
setTileTerrain(x, y, (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE)
}
fun setTileWall(x: Int, y: Int, tile: Byte, damage: Int) {
layerWall.setTile(x, y, tile)
wallDamage.setData(x, y, damage)
}
fun setTileTerrain(x: Int, y: Int, tile: Byte, damage: Int) {
layerTerrain.setTile(x, y, tile)
terrainDamage.setData(x, y, damage)
}
fun setTileWire(x: Int, y: Int, tile: Byte) {
layerWire.data[y][x] = tile
}
fun getTileFrom(mode: Int, x: Int, y: Int): Int? {
if (mode == TERRAIN) {
return getTileFromTerrain(x, y)
}
else if (mode == WALL) {
return getTileFromWall(x, y)
}
else if (mode == WIRE) {
return getTileFromWire(x, y)
}
else
throw IllegalArgumentException("illegal mode input: " + mode.toString())
}
fun updateWorldTime(delta: Int) {
worldTime.update(delta)
}
fun terrainIterator(): Iterator<Int> {
return object : Iterator<Int> {
private var iteratorCount = 0
override fun hasNext(): Boolean {
return iteratorCount < width * height
}
override fun next(): Int {
val y = iteratorCount / width
val x = iteratorCount % width
// advance counter
iteratorCount += 1
return getTileFromTerrain(x, y)!!
}
}
}
fun wallIterator(): Iterator<Int> {
return object : Iterator<Int> {
private var iteratorCount = 0
override fun hasNext(): Boolean =
iteratorCount < width * height
override fun next(): Int {
val y = iteratorCount / width
val x = iteratorCount % width
// advance counter
iteratorCount += 1
return getTileFromWall(x, y)!!
}
}
}
companion object {
@Transient val WALL = 0
@Transient val TERRAIN = 1
@Transient val WIRE = 2
@Transient val TILES_SUPPORTED = MapLayer.RANGE * PairedMapLayer.RANGE
@Transient val BITS: Byte = 1 // 1 for Byte, 2 for Char, 4 for Int, 8 for Long
@Transient val LAYERS: Byte = 4 // terrain, wall (terrainDamage + wallDamage), wire
}
}

View File

@@ -0,0 +1,56 @@
package net.torvald.terrarum.gamemap
/**
* Created by minjaesong on 16-01-17.
*/
class MapLayer(var width: Int, var height: Int) : Iterable<Byte> {
internal var data: Array<ByteArray>
init {
data = Array(height) { ByteArray(width) }
}
/**
* Returns an iterator over elements of type `T`.
* @return an Iterator.
*/
override fun iterator(): Iterator<Byte> {
return object : Iterator<Byte> {
private var iteratorCount = 0
override fun hasNext(): Boolean {
return iteratorCount < width * height
}
override fun next(): Byte {
val y = iteratorCount / width
val x = iteratorCount % width
// advance counter
iteratorCount += 1
return data[y][x]
}
}
}
internal fun getTile(x: Int, y: Int): Int? {
return if (x !in 0..width - 1 || y !in 0..height - 1)
null
else
uint8ToInt32(data[y][x])
}
internal fun setTile(x: Int, y: Int, tile: Byte) {
data[y][x] = tile
}
private fun uint8ToInt32(x: Byte): Int = java.lang.Byte.toUnsignedInt(x)
companion object {
@Transient val RANGE = 256
}
}

View File

@@ -0,0 +1,35 @@
package net.torvald.terrarum.gamemap
import net.torvald.point.Point2f
import java.io.Serializable
class MapPoint {
var startPoint: Point2f? = null
private set
var endPoint: Point2f? = null
private set
constructor() {
}
constructor(p1: Point2f, p2: Point2f) {
setPoint(p1, p2)
}
constructor(x1: Int, y1: Int, x2: Int, y2: Int) {
setPoint(x1, y1, x2, y2)
}
fun setPoint(p1: Point2f, p2: Point2f) {
startPoint = p1
endPoint = p2
}
fun setPoint(x1: Int, y1: Int, x2: Int, y2: Int) {
startPoint = Point2f(x1.toFloat(), y1.toFloat())
endPoint = Point2f(x2.toFloat(), y2.toFloat())
}
}

View File

@@ -0,0 +1,86 @@
package net.torvald.terrarum.gamemap
import java.io.Serializable
import java.util.Spliterator
import java.util.function.Consumer
/**
* Created by minjaesong on 16-02-15.
*/
class PairedMapLayer(width: Int, var height: Int) : Iterable<Byte> {
/**
* 0b_xxxx_yyyy, x for lower index, y for higher index
* e.g.
* 0110 1101 is interpreted as
* 6 for tile 0, 13 for tile 1.
*/
internal var dataPair: Array<ByteArray>
var width: Int = 0
init {
this.width = width / 2
dataPair = Array(height) { ByteArray(width / 2) }
}
/**
* Returns an iterator over elements of type `T`.
* Note: this iterator will return combined damage, that is 0bxxxx_yyyy as whole.
* @return an Iterator.
*/
override fun iterator(): Iterator<Byte> {
return object : Iterator<Byte> {
private var iteratorCount = 0
override fun hasNext(): Boolean {
return iteratorCount < width * height
}
override fun next(): Byte {
val y = iteratorCount / width
val x = iteratorCount % width
// advance counter
iteratorCount += 1
return dataPair[y][x]
}
}
}
internal fun getData(x: Int, y: Int): Int? {
return if (x !in 0..width * 2 - 1 || y !in 0..height - 1)
null
else {
if (x and 0x1 == 0)
// higher four bits for i = 0, 2, 4, ...
(java.lang.Byte.toUnsignedInt(dataPair[y][x / 2]) and 0xF0) ushr 4
else
// lower four bits for i = 1, 3, 5, ...
java.lang.Byte.toUnsignedInt(dataPair[y][x / 2]) and 0x0F
}
}
internal fun setData(x: Int, y: Int, data: Int) {
if (data < 0 || data >= 16) throw IllegalArgumentException("[PairedMapLayer] $data: invalid data value.")
if (x and 0x1 == 0)
// higher four bits for i = 0, 2, 4, ...
dataPair[y][x / 2] =
(java.lang.Byte.toUnsignedInt(dataPair[y][x / 2]) and 0x0F
or (data and 0xF shl 4)).toByte()
else
// lower four bits for i = 1, 3, 5, ...
dataPair[y][x / 2] = (java.lang.Byte.toUnsignedInt(dataPair[y][x / 2]) and 0xF0
or (data and 0xF)).toByte()
}
companion object {
@Transient val RANGE = 16
}
}

View File

@@ -0,0 +1,153 @@
package net.torvald.terrarum.gamemap
/**
* Created by minjaesong on 16-01-24.
*/
class WorldTime {
internal var seconds: Int
internal var minutes: Int
internal var hours: Int
internal var yearlyDays: Int //NOT a calendar day
internal var days: Int
internal var months: Int
internal var years: Int
internal var dayOfWeek: Int //0: Mondag-The first day of weekday
internal var timeDelta = 1
@Transient private var realMillisec: Int
val DAY_NAMES = arrayOf(//daynames are taken from Nynorsk (å -> o)
"Mondag", "Tysdag", "Midtedag" //From Islenska Miðvikudagur
, "Torsdag", "Fredag", "Laurdag", "Sundag", "Verdag" //From Norsk word 'verd'
)
val DAY_NAMES_SHORT = arrayOf("Mon", "Tys", "Mid", "Tor", "Fre", "Lau", "Sun", "Ver")
@Transient val REAL_SEC_IN_MILLI = 1000
init {
seconds = 0
minutes = 30
hours = 8
yearlyDays = 1
days = 12
months = 3
years = 125
dayOfWeek = 0
realMillisec = 0
}
fun update(delta: Int) {
//time
realMillisec += delta * timeDelta
seconds = Math.round(GAME_MIN_TO_REAL_SEC.toFloat() / REAL_SEC_IN_MILLI.toFloat() * realMillisec.toFloat())
if (realMillisec >= REAL_SEC_IN_MILLI)
realMillisec -= REAL_SEC_IN_MILLI
kickVariables()
}
/**
* How much time has passed today, in seconds.
* 0 == 6 AM
* @return
*/
fun elapsedSeconds(): Int {
return (HOUR_SEC * hours + MINUTE_SEC * minutes + seconds) % DAY_LENGTH
}
val isLeapYear: Boolean
get() = years % 4 == 0 && years % 100 != 0 || years % 400 == 0
fun setTime(t: Int) {
days += t / DAY_LENGTH
hours = t / HOUR_SEC
minutes = (t - HOUR_SEC * hours) / MINUTE_SEC
seconds = t - minutes * MINUTE_SEC
}
fun addTime(t: Int) {
setTime(elapsedSeconds() + t)
}
fun setTimeDelta(d: Int) {
timeDelta = if (d < 0) 0 else d
}
val dayName: String
get() = DAY_NAMES[dayOfWeek]
private fun kickVariables() {
if (seconds >= MINUTE_SEC) {
seconds = 0
minutes += 1
}
if (minutes >= HOUR_MIN) {
minutes = 0
hours += 1
}
if (hours >= DAY_LENGTH / HOUR_SEC) {
hours = 0
days += 1
yearlyDays += 1
dayOfWeek += 1
}
//calendar (the world calendar)
if (dayOfWeek == 7) {
dayOfWeek = 0
}
if ((months == 12 || months == 7 && isLeapYear) && days == 31) {
dayOfWeek = 7
}
if ((months == 12 || months == 7 && isLeapYear) && days == 32) {
days = 1
months = 1
years++
}
else if ((months == 1 || months == 4 || months == 7 || months == 10) && days > 31) {
days = 1
months++
}
else if (days > 30) {
days = 1
months++
}
if (months > 12) {
months = 1
years++
}
}
fun getFormattedTime(): String {
fun formatMin(min: Int): String {
return if (min < 10) "0${min.toString()}" else min.toString()
}
return "${hours}h${formatMin(minutes)}"
}
fun getDayNameFull(): String = DAY_NAMES[dayOfWeek]
fun getDayNameShort(): String = DAY_NAMES_SHORT[dayOfWeek]
companion object {
/**
* 22h
*/
val DAY_LENGTH = 79200 //must be the multiple of 3600
val HOUR_SEC: Int = 3600
val MINUTE_SEC: Int = 60
val HOUR_MIN: Int = 60
val GAME_MIN_TO_REAL_SEC: Float = 60f
}
}