logic gate actually blinking sprites

This commit is contained in:
minjaesong
2024-03-04 21:39:21 +09:00
parent 4602cb5bc1
commit caf238d6df
3 changed files with 51 additions and 18 deletions

View File

@@ -56,7 +56,7 @@ open class Electric : FixtureBase {
}
companion object {
const val ELECTIC_THRESHOLD_HIGH = 0.9
const val ELECTRIC_THRESHOLD_HIGH = 0.9
const val ELECTRIC_THRESHOLD_LOW = 0.1
const val ELECTRIC_THRESHOLD_EDGE_DELTA = 0.7
}
@@ -108,6 +108,28 @@ open class Electric : FixtureBase {
}
}
/**
* returns true if at least one of following condition is `true`
* - `getWireStateAt(x, y, "digital_bit").x` is equal to or greater than `ELECTIC_THRESHOLD_HIGH`
* - `getWireEmissionAt(x, y).x` is equal to or greater than `ELECTIC_THRESHOLD_HIGH`
*
* This function does NOT check if the given port receives/emits `digital_bit` signal; if not, the result is undefined.
*/
fun isSignalHigh(offsetX: Int, offsetY: Int) =
getWireStateAt(offsetX, offsetY, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH ||
getWireEmissionAt(offsetX, offsetY).x >= ELECTRIC_THRESHOLD_HIGH
/**
* returns true if at least one of following condition is `true`
* - `getWireStateAt(x, y, "digital_bit").x` is equal to or lesser than `ELECTRIC_THRESHOLD_LOW`
* - `getWireEmissionAt(x, y).x` is equal to or lesser than `ELECTRIC_THRESHOLD_LOW`
*
* This function does NOT check if the given port receives/emits `digital_bit` signal; if not, the result is undefined.
*/
fun isSignalLow(offsetX: Int, offsetY: Int) =
getWireStateAt(offsetX, offsetY, "digital_bit").x <= ELECTRIC_THRESHOLD_LOW ||
getWireEmissionAt(offsetX, offsetY).x <= ELECTRIC_THRESHOLD_LOW
fun getWireEmissionAt(offsetX: Int, offsetY: Int): Vector2 {
return wireEmission[pointToBlockBoxIndex(offsetY, offsetY)] ?: Vector2()
}
@@ -153,7 +175,7 @@ open class Electric : FixtureBase {
}
val index = pointToBlockBoxIndex(x, y)
if (new.x - oldSinkStatus[index].x >= ELECTRIC_THRESHOLD_EDGE_DELTA && new.x >= ELECTIC_THRESHOLD_HIGH)
if (new.x - oldSinkStatus[index].x >= ELECTRIC_THRESHOLD_EDGE_DELTA && new.x >= ELECTRIC_THRESHOLD_HIGH)
risingEdgeIndices.add(index)
else if (oldSinkStatus[index].x - new.x >= ELECTRIC_THRESHOLD_EDGE_DELTA && new.x <= ELECTRIC_THRESHOLD_LOW)
fallingEdgeIndices.add(index)

View File

@@ -103,19 +103,19 @@ class FixtureSignalBlocker : Electric, Reorientable {
private val I: Boolean
get() = when (orientation) {
0 -> getWireStateAt(0, 0, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
1 -> getWireStateAt(1, 0, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
2 -> getWireStateAt(1, 1, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
3 -> getWireStateAt(0, 1, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
0 -> getWireStateAt(0, 0, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH
1 -> getWireStateAt(1, 0, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH
2 -> getWireStateAt(1, 1, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH
3 -> getWireStateAt(0, 1, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH
else -> throw IllegalStateException("Orientation not in range ($orientation)")
}
private val J: Boolean
get() = when (orientation) {
0 -> getWireStateAt(0, 1, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
1 -> getWireStateAt(0, 0, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
2 -> getWireStateAt(1, 0, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
3 -> getWireStateAt(1, 1, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
0 -> getWireStateAt(0, 1, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH
1 -> getWireStateAt(0, 0, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH
2 -> getWireStateAt(1, 0, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH
3 -> getWireStateAt(1, 1, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH
else -> throw IllegalStateException("Orientation not in range ($orientation)")
}
@@ -127,21 +127,32 @@ class FixtureSignalBlocker : Electric, Reorientable {
3 -> 0 to 0
else -> throw IllegalStateException("Orientation not in range ($orientation)")
}
setWireEmissionAt(x, y, Vector2(I nimply J, 0.0))
val output = I nimply J
setWireEmissionAt(x, y, Vector2(output.toDouble(), 0.0))
// update sprite
val one = getWireStateAt(0, 0, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH || getWireEmissionAt(0, 0).x >= ELECTIC_THRESHOLD_HIGH
val two = getWireStateAt(1, 0, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH || getWireEmissionAt(1, 0).x >= ELECTIC_THRESHOLD_HIGH
val four = getWireStateAt(0, 1, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH || getWireEmissionAt(0, 1).x >= ELECTIC_THRESHOLD_HIGH
val eight = getWireStateAt(1, 1, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH || getWireEmissionAt(1, 1).x >= ELECTIC_THRESHOLD_HIGH
val one = isSignalHigh(0, 0)
val two = isSignalHigh(1, 0)
val four = isSignalHigh(0, 1)
val eight = isSignalHigh(1, 1)
// WHY READING FROM wireEmission DOES NOT WORK????
// fixme actually read from wireEmission as the gate's output has propagation delay but current sprite "hack" does not consider it
val state = one.toInt(0) or two.toInt(1) or four.toInt(2) or eight.toInt(3)
var state = one.toInt(0) or two.toInt(1) or four.toInt(2) or eight.toInt(3)
state = state or when (orientation) {
0 -> 2
1 -> 8
2 -> 4
3 -> 1
else -> throw IllegalStateException("Orientation not in range ($orientation)")
} * output
(sprite as SheetSpriteAnimation).currentRow = state
(spriteEmissive as SheetSpriteAnimation).currentRow = state
}
private infix fun Boolean.nimply(other: Boolean) = (this && !other).toInt().toDouble()
private infix fun Boolean.nimply(other: Boolean) = (this && !other).toInt()
override fun updateSignal() {
updateK()

View File

@@ -51,6 +51,6 @@ class FixtureSignalBulb : Electric {
override fun updateImpl(delta: Float) {
super.updateImpl(delta)
light(getWireStateAt(0, 0, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH)
light(getWireStateAt(0, 0, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH)
}
}