Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make ImageAnimationView & ImageDataView Anchorable. Adds PixelAnchorable #1683

Merged
merged 2 commits into from
Jun 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions korge/src/commonMain/kotlin/korlibs/korge/view/Anchorable.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,14 @@ fun <T : Anchorable> T.anchor(ax: Int, ay: Int): T = anchor(Anchor(ax, ay))

fun <T : Anchorable> T.center(): T = anchor(0.5f, 0.5f)
val <T : Anchorable> T.centered: T get() = anchor(0.5f, 0.5f)

interface PixelAnchorable {
@ViewProperty(name = "anchorPixel")
var anchorPixel: Point
}

fun <T : PixelAnchorable> T.anchorPixel(point: Point): T {
this.anchorPixel = point
return this
}

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package korlibs.korge.view.animation
import korlibs.datastructure.*
import korlibs.datastructure.iterators.*
import korlibs.time.*
import korlibs.math.geom.*
import korlibs.memory.*
import korlibs.korge.view.*
import korlibs.korge.view.tiles.*
Expand All @@ -25,7 +26,7 @@ open class ImageAnimationView<T: SmoothedBmpSlice>(
animation: ImageAnimation? = null,
direction: ImageAnimation.Direction? = null,
val createImage: () -> T
) : Container(), Playable {
) : Container(), Playable, PixelAnchorable, Anchorable {
private var nframes: Int = 1

fun createTilemap(): TileMap = TileMap()
Expand All @@ -49,20 +50,35 @@ open class ImageAnimationView<T: SmoothedBmpSlice>(
}
}

internal val anchorContainer = container()
private val computedDirection: ImageAnimation.Direction get() = direction ?: animation?.direction ?: ImageAnimation.Direction.FORWARD
private val layers = fastArrayListOf<View>()
private val layersByName = FastStringMap<View>()
internal val _layers = fastArrayListOf<View>()
private val _layersByName = FastStringMap<View>()
val layers: List<View> get() = _layers
//val layersByName: Map<String, View> get() = _layersByName
val numLayers: Int get() = _layers.size
fun getLayer(index: Int): View = _layers[index]
fun getLayer(name: String): View? = _layersByName[name]
private var nextFrameIn = 0.milliseconds
private var nextFrameIndex = 0
private var dir = +1

fun getLayer(name: String): View? = layersByName[name]
override var anchorPixel: Point = Point.ZERO
set(value) {
field = value
anchorContainer.pos = -value
}
override var anchor: Anchor
get() = Anchor(anchorPixel.x / width, anchorPixel.y / height)
set(value) {
anchorPixel = Point(value.sx * width, value.sy * height)
}

var smoothing: Boolean = true
set(value) {
if (field != value) {
field = value
layers.fastForEach {
_layers.fastForEach {
if (it is SmoothedBmpSlice) it.smoothing = value
}
}
Expand Down Expand Up @@ -128,8 +144,8 @@ open class ImageAnimationView<T: SmoothedBmpSlice>(
onDestroyLayer?.invoke(layer as T)
}
}
layers.clear()
removeChildren()
_layers.clear()
anchorContainer.removeChildren()
dir = +1
val animation = this.animation
if (animation != null) {
Expand All @@ -141,9 +157,9 @@ open class ImageAnimationView<T: SmoothedBmpSlice>(
ImageLayer.Type.TILEMAP -> createTilemap()
ImageLayer.Type.GROUP -> TODO()
}
layers.add(image)
layersByName[layer.name ?: "default"] = image
addChild(image as View)
_layers.add(image)
_layersByName[layer.name ?: "default"] = image
anchorContainer.addChild(image as View)
}
}
setFirstFrame()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package korlibs.korge.view.animation
import korlibs.korge.view.*
import korlibs.image.format.ImageData
import korlibs.korge.view.property.*
import korlibs.math.geom.*

/**
* With imageDataView it is possible to display an image inside a Container or View.
Expand Down Expand Up @@ -54,13 +55,15 @@ open class ImageDataView(
animation: String? = null,
playing: Boolean = false,
smoothing: Boolean = true,
) : Container() {
) : Container(), PixelAnchorable, Anchorable {
// Here we can create repeated in korge-parallax if required
protected open fun createAnimationView(): ImageAnimationView<out SmoothedBmpSlice> {
return imageAnimationView()
}

open val animationView: ImageAnimationView<out SmoothedBmpSlice> = createAnimationView()
override var anchorPixel: Point by animationView::anchorPixel
override var anchor: Anchor by animationView::anchor

fun getLayer(name: String): View? {
return animationView.getLayer(name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,23 +81,23 @@ class ImageAnimationViewTest {
fun testNumberOfChildren() {
// Test if correct number of layers are added as children to the Container
anim.animation = animImages4Layers1
assertEquals(1, anim.children.size)
assertEquals(1, anim.numLayers)
anim.animation = animImages6Layers2
assertEquals(2, anim.children.size)
assertEquals(2, anim.numLayers)
}

@Test
fun testSetFirstFrame() {
// Test if the correct frame is set as first frame
// Here we check if the corresponding targetX value was set as X position of the layer.
anim.animation = animImages4Layers1
assertEquals(1, anim.children[0].xD.toInt())
assertEquals(1, anim.layers[0].xD.toInt())
anim.direction = ImageAnimation.Direction.REVERSE
anim.rewind()
assertEquals(4, anim.children[0].xD.toInt())
assertEquals(4, anim.layers[0].xD.toInt())
anim.animation = animImages6Layers2
assertEquals(6, anim.children[0].xD.toInt())
assertEquals(60, anim.children[1].xD.toInt())
assertEquals(6, anim.layers[0].xD.toInt())
assertEquals(60, anim.layers[1].xD.toInt())
}

// println("children: ${imageanimView.children.size}")
Expand Down