mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-12 03:24:06 +09:00
lightning bolt WIP, player sprite declaration macro
Former-commit-id: d4999cda37bff2aa27615183aa125bfbc8cfa975 Former-commit-id: 224aee51d4fb7e5fe9d11bf3c0cc758a5604251d
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
package net.torvald.point
|
package net.torvald.point
|
||||||
|
|
||||||
|
import net.torvald.terrarum.gameactors.sqr
|
||||||
|
import net.torvald.terrarum.gameactors.sqrt
|
||||||
import org.dyn4j.geometry.Vector2
|
import org.dyn4j.geometry.Vector2
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,4 +48,6 @@ class Point2d(var x: Double, var y: Double) : Cloneable {
|
|||||||
operator fun div(other: Point2d) = Point2d(x / other.x, y / other.y)
|
operator fun div(other: Point2d) = Point2d(x / other.x, y / other.y)
|
||||||
|
|
||||||
fun toVector() = Vector2(x, y)
|
fun toVector() = Vector2(x, y)
|
||||||
|
|
||||||
|
fun length(other: Point2d) = ((this.x - other.x).sqr() + (this.y - other.y).sqr()).sqrt()
|
||||||
}
|
}
|
||||||
|
|||||||
8
src/net/torvald/random/NoiseGenerator1D.kt
Normal file
8
src/net/torvald/random/NoiseGenerator1D.kt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
package net.torvald.random
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 16-10-28.
|
||||||
|
*/
|
||||||
|
interface NoiseGenerator1D {
|
||||||
|
fun get(x: Double): Double
|
||||||
|
}
|
||||||
18
src/net/torvald/random/TileableValueNoise.kt
Normal file
18
src/net/torvald/random/TileableValueNoise.kt
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package net.torvald.random
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate value noise that is always "tileably looped" every x in loopSize.
|
||||||
|
*
|
||||||
|
* Created by minjaesong on 16-10-28.
|
||||||
|
*/
|
||||||
|
class TileableValueNoise(
|
||||||
|
val octaves: Int, val persistency: Double,
|
||||||
|
val loopSize: Double = 1.0, val seed: Long? = null
|
||||||
|
) : NoiseGenerator1D {
|
||||||
|
|
||||||
|
val rng = if (seed != null) HQRNG(seed) else HQRNG()
|
||||||
|
|
||||||
|
override fun get(x: Double): Double {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,8 @@ package net.torvald.terrarum
|
|||||||
|
|
||||||
|
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
|
import net.torvald.point.Point2d
|
||||||
|
import net.torvald.random.HQRNG
|
||||||
import net.torvald.terrarum.gameactors.floorInt
|
import net.torvald.terrarum.gameactors.floorInt
|
||||||
import net.torvald.terrarum.gameactors.roundInt
|
import net.torvald.terrarum.gameactors.roundInt
|
||||||
import net.torvald.terrarum.virtualcomputer.terminal.ALException
|
import net.torvald.terrarum.virtualcomputer.terminal.ALException
|
||||||
@@ -9,6 +11,7 @@ import org.apache.commons.csv.CSVRecord
|
|||||||
import org.lwjgl.BufferUtils
|
import org.lwjgl.BufferUtils
|
||||||
import org.lwjgl.openal.AL
|
import org.lwjgl.openal.AL
|
||||||
import org.lwjgl.openal.AL10
|
import org.lwjgl.openal.AL10
|
||||||
|
import org.newdawn.slick.Color
|
||||||
import org.newdawn.slick.GameContainer
|
import org.newdawn.slick.GameContainer
|
||||||
import org.newdawn.slick.Graphics
|
import org.newdawn.slick.Graphics
|
||||||
import org.newdawn.slick.state.BasicGameState
|
import org.newdawn.slick.state.BasicGameState
|
||||||
@@ -27,117 +30,57 @@ class StateTestingSandbox : BasicGameState() {
|
|||||||
|
|
||||||
|
|
||||||
override fun init(container: GameContainer?, game: StateBasedGame?) {
|
override fun init(container: GameContainer?, game: StateBasedGame?) {
|
||||||
playTone()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val sampleRate = 22050
|
val lightning_start = Point2d(50.0, 200.0)
|
||||||
private var beepSource: Int? = null
|
val lightning_end = Point2d(750.0, 200.0)
|
||||||
private var beepBuffer: Int? = null
|
|
||||||
|
|
||||||
/**
|
val bolt = LightingBolt(lightning_start, lightning_end, 20)
|
||||||
* @param duration : milliseconds
|
|
||||||
*/
|
|
||||||
private fun makeAudioData(duration: Int, freq: Float): ByteBuffer {
|
|
||||||
val audioData = BufferUtils.createByteBuffer(duration.times(sampleRate).div(1000))
|
|
||||||
|
|
||||||
val realDuration = duration * sampleRate / 1000
|
|
||||||
val chopSize = freq * 2f / sampleRate
|
|
||||||
|
|
||||||
val amp = Math.max(4600f / freq, 1f)
|
|
||||||
val nHarmonics = 4
|
|
||||||
|
|
||||||
val transitionThre = 1150f
|
|
||||||
|
|
||||||
if (freq < transitionThre) { // chopper generator (for low freq)
|
|
||||||
for (x in 0..realDuration - 1) {
|
|
||||||
var sine: Float = amp * FastMath.cos(FastMath.PI * x * chopSize)
|
|
||||||
if (sine > 1f) sine = 1f
|
|
||||||
else if (sine < -1f) sine = -1f
|
|
||||||
audioData.put(
|
|
||||||
(0.5f + 0.5f * sine).times(0xFF).toByte()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else { // harmonics generator (for high freq)
|
|
||||||
for (x in 0..realDuration - 1) {
|
|
||||||
var sine: Float = 0f
|
|
||||||
for (k in 0..nHarmonics) { // mix only odd harmonics to make squarewave
|
|
||||||
sine += (1f / (2*k + 1)) *
|
|
||||||
FastMath.sin((2*k + 1) * FastMath.PI * x * chopSize)
|
|
||||||
}
|
|
||||||
audioData.put(
|
|
||||||
(0.5f + 0.5f * sine).times(0xFF).toByte()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
audioData.rewind()
|
|
||||||
|
|
||||||
return audioData
|
|
||||||
}
|
|
||||||
|
|
||||||
var audioData: ByteBuffer? = null
|
|
||||||
|
|
||||||
private fun playTone() {
|
|
||||||
if (audioData == null) audioData = makeAudioData(5000, 27.5f)
|
|
||||||
|
|
||||||
|
|
||||||
if (!AL.isCreated()) AL.create()
|
|
||||||
|
|
||||||
|
|
||||||
// Clear error stack.
|
|
||||||
AL10.alGetError()
|
|
||||||
|
|
||||||
beepBuffer = AL10.alGenBuffers()
|
|
||||||
checkALError()
|
|
||||||
|
|
||||||
try {
|
|
||||||
AL10.alBufferData(beepBuffer!!, AL10.AL_FORMAT_MONO8, audioData, sampleRate)
|
|
||||||
checkALError()
|
|
||||||
|
|
||||||
beepSource = AL10.alGenSources()
|
|
||||||
checkALError()
|
|
||||||
|
|
||||||
try {
|
|
||||||
AL10.alSourceQueueBuffers(beepSource!!, beepBuffer!!)
|
|
||||||
checkALError()
|
|
||||||
|
|
||||||
AL10.alSource3f(beepSource!!, AL10.AL_POSITION, 0f, 0f, 1f)
|
|
||||||
AL10.alSourcef(beepSource!!, AL10.AL_REFERENCE_DISTANCE, 1f)
|
|
||||||
AL10.alSourcef(beepSource!!, AL10.AL_MAX_DISTANCE, 1f)
|
|
||||||
AL10.alSourcef(beepSource!!, AL10.AL_GAIN, 0.3f)
|
|
||||||
checkALError()
|
|
||||||
|
|
||||||
AL10.alSourcePlay(beepSource!!)
|
|
||||||
checkALError()
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (e: ALException) {
|
|
||||||
AL10.alDeleteSources(beepSource!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e: ALException) {
|
|
||||||
if (beepSource != null) AL10.alDeleteSources(beepSource!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun update(container: GameContainer?, game: StateBasedGame?, delta: Int) {
|
override fun update(container: GameContainer?, game: StateBasedGame?, delta: Int) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom implementation of Util.checkALError() that uses our custom exception.
|
|
||||||
private fun checkALError() {
|
|
||||||
val errorCode = AL10.alGetError()
|
|
||||||
if (errorCode != AL10.AL_NO_ERROR) {
|
|
||||||
throw ALException(errorCode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
override fun getID() = Terrarum.STATE_ID_TEST_SHIT
|
override fun getID() = Terrarum.STATE_ID_TEST_SHIT
|
||||||
|
|
||||||
override fun render(container: GameContainer?, game: StateBasedGame?, g: Graphics?) {
|
override fun render(container: GameContainer, game: StateBasedGame, g: Graphics) {
|
||||||
|
g.color = Color.white
|
||||||
|
g.lineWidth = 3f
|
||||||
|
|
||||||
|
//g.drawLine(lightning_start, lightning_end)
|
||||||
|
bolt.draw(g)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Graphics.drawLine(p1: Point2d, p2: Point2d) {
|
||||||
|
drawLine(p1.x.toFloat(), p1.y.toFloat(), p2.x.toFloat(), p2.y.toFloat())
|
||||||
|
}
|
||||||
|
|
||||||
|
class LightingBolt(val start: Point2d, val end: Point2d, val segments: Int) {
|
||||||
|
val mainBolt = LinkedList<Point2d>() //Pair<Length, Y-Pos>
|
||||||
|
|
||||||
|
val boltYDev = 20.0
|
||||||
|
|
||||||
|
init {
|
||||||
|
val length = start.length(end)
|
||||||
|
|
||||||
|
for (i in 0..segments - 1) {
|
||||||
|
mainBolt.add(
|
||||||
|
Point2d(
|
||||||
|
start.x + length / segments * i,
|
||||||
|
start.y + HQRNG().nextFloat().times(2.0).minus(1.0).times(boltYDev)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun draw(g: Graphics) {
|
||||||
|
for (i in 0..segments - 1) {
|
||||||
|
val startpoint = mainBolt[i]
|
||||||
|
val endpoint = if (i == segments - 1) end else mainBolt[i + 1]
|
||||||
|
|
||||||
|
g.drawLine(startpoint, endpoint)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,8 +23,8 @@ open class ActorWithBody : Actor(), Visible {
|
|||||||
override var referenceID: Int = generateUniqueReferenceID()
|
override var referenceID: Int = generateUniqueReferenceID()
|
||||||
override var actorValue: ActorValue = ActorValue()
|
override var actorValue: ActorValue = ActorValue()
|
||||||
|
|
||||||
@Transient var sprite: SpriteAnimation? = null
|
@Transient internal var sprite: SpriteAnimation? = null
|
||||||
@Transient var spriteGlow: SpriteAnimation? = null
|
@Transient internal var spriteGlow: SpriteAnimation? = null
|
||||||
|
|
||||||
@Transient private val world: GameWorld = Terrarum.ingame.world
|
@Transient private val world: GameWorld = Terrarum.ingame.world
|
||||||
|
|
||||||
@@ -229,6 +229,16 @@ open class ActorWithBody : Actor(), Visible {
|
|||||||
// some initialiser goes here...
|
// some initialiser goes here...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun makeNewSprite(w: Int, h: Int) {
|
||||||
|
sprite = SpriteAnimation()
|
||||||
|
sprite!!.setDimension(w, h)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun makeNewSpriteGlow(w: Int, h: Int) {
|
||||||
|
spriteGlow = SpriteAnimation()
|
||||||
|
spriteGlow!!.setDimension(w, h)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param w
|
* @param w
|
||||||
* @param h
|
* @param h
|
||||||
@@ -1016,6 +1026,7 @@ fun Double.roundInt(): Int = Math.round(this).toInt()
|
|||||||
fun Float.roundInt(): Int = Math.round(this).toInt()
|
fun Float.roundInt(): Int = Math.round(this).toInt()
|
||||||
fun Double.abs() = Math.abs(this)
|
fun Double.abs() = Math.abs(this)
|
||||||
fun Double.sqr() = this * this
|
fun Double.sqr() = this * this
|
||||||
|
fun Double.sqrt() = Math.sqrt(this)
|
||||||
fun Int.abs() = if (this < 0) -this else this
|
fun Int.abs() = if (this < 0) -this else this
|
||||||
fun Double.bipolarClamp(limit: Double) =
|
fun Double.bipolarClamp(limit: Double) =
|
||||||
if (this > 0 && this > limit) limit
|
if (this > 0 && this > limit) limit
|
||||||
|
|||||||
@@ -17,8 +17,7 @@ object PlayerBuilderCynthia {
|
|||||||
p.actorValue["__selectedtile"] = 16
|
p.actorValue["__selectedtile"] = 16
|
||||||
|
|
||||||
|
|
||||||
p.sprite = SpriteAnimation()
|
p.makeNewSprite(26, 42)
|
||||||
p.sprite!!.setDimension(26, 42)
|
|
||||||
p.sprite!!.setSpriteImage("assets/graphics/sprites/test_player_2.png")
|
p.sprite!!.setSpriteImage("assets/graphics/sprites/test_player_2.png")
|
||||||
p.sprite!!.setDelay(200)
|
p.sprite!!.setDelay(200)
|
||||||
p.sprite!!.setRowsAndFrames(1, 1)
|
p.sprite!!.setRowsAndFrames(1, 1)
|
||||||
|
|||||||
@@ -21,15 +21,13 @@ object PlayerBuilderSigrid {
|
|||||||
|
|
||||||
p.referenceID = 0x51621D // the only constant of this procedural universe
|
p.referenceID = 0x51621D // the only constant of this procedural universe
|
||||||
|
|
||||||
p.sprite = SpriteAnimation()
|
p.makeNewSprite(28, 51)
|
||||||
p.sprite!!.setDimension(28, 51)
|
|
||||||
p.sprite!!.setSpriteImage("assets/graphics/sprites/test_player.png")
|
p.sprite!!.setSpriteImage("assets/graphics/sprites/test_player.png")
|
||||||
p.sprite!!.setDelay(200)
|
p.sprite!!.setDelay(200)
|
||||||
p.sprite!!.setRowsAndFrames(1, 1)
|
p.sprite!!.setRowsAndFrames(1, 1)
|
||||||
p.sprite!!.setAsVisible()
|
p.sprite!!.setAsVisible()
|
||||||
|
|
||||||
p.spriteGlow = SpriteAnimation()
|
p.makeNewSpriteGlow(28, 51)
|
||||||
p.spriteGlow!!.setDimension(28, 51)
|
|
||||||
p.spriteGlow!!.setSpriteImage("assets/graphics/sprites/test_player_glow.png")
|
p.spriteGlow!!.setSpriteImage("assets/graphics/sprites/test_player_glow.png")
|
||||||
p.spriteGlow!!.setDelay(200)
|
p.spriteGlow!!.setDelay(200)
|
||||||
p.spriteGlow!!.setRowsAndFrames(1, 1)
|
p.spriteGlow!!.setRowsAndFrames(1, 1)
|
||||||
|
|||||||
@@ -258,6 +258,9 @@ object WorldGenerator {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* http://accidentalnoise.sourceforge.net/minecraftworlds.html
|
* http://accidentalnoise.sourceforge.net/minecraftworlds.html
|
||||||
|
*
|
||||||
|
* TODO have it seamless
|
||||||
|
* use MappingMode.SEAMLESS_XY ?
|
||||||
*/
|
*/
|
||||||
private fun raise3(): Array<BitSet> {
|
private fun raise3(): Array<BitSet> {
|
||||||
val noiseMap = Array(HEIGHT, { BitSet(WIDTH) })
|
val noiseMap = Array(HEIGHT, { BitSet(WIDTH) })
|
||||||
|
|||||||
Reference in New Issue
Block a user