Skip to content

Commit 22aa1d6

Browse files
authored
Merge pull request #2 from littlektframework/0.3
0.3
2 parents f5f8193 + 61dd61c commit 22aa1d6

File tree

5 files changed

+236
-33
lines changed

5 files changed

+236
-33
lines changed

_docs/2d/animations.md

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ Creating an `AnimationPlayer` expects a type parameter as well. This needs to ma
4747
**Playing an animation in a loop:**
4848

4949
```kotlin
50+
val batch = SpriteBatch(this)
51+
val viewport = ExtendViewport(480, 270)
52+
val camera = viewport.camera
53+
5054
val atlas: TextureAtlas = resourcesVfs["tiles.atlas.json"].readAtlas()
5155
val heroRun: Animation<TextureSlice> = atlas.getAnimation("heroRun")
5256

@@ -56,12 +60,22 @@ anim.playLooped(heroRun)
5660
onRender { dt ->
5761
gl.clear(ClearBufferMask.COLOR_BUFFER_BIT)
5862
anim.update(dt) // handles requesting the next frames in the current animation
63+
camera.update()
64+
batch.use(camera.viewProjection) { batch ->
65+
anim.currentKeyFrame?.let { // use the current key frame of the animation to render
66+
batch.draw(it, 50f, 50f, scaleX = 5f, scaleY = 5f)
67+
}
68+
}
5969
}
6070
```
6171

6272
**Playing an animation a specific amount of times:**
6373

6474
```kotlin
75+
val batch = SpriteBatch(this)
76+
val viewport = ExtendViewport(480, 270)
77+
val camera = viewport.camera
78+
6579
val atlas: TextureAtlas = resourcesVfs["tiles.atlas.json"].readAtlas()
6680
val heroRun: Animation<TextureSlice> = atlas.getAnimation("heroRun")
6781
val heroIdle: Animation<TextureSlice> = atlas.getAnimation("heroIdle")
@@ -73,6 +87,12 @@ anim.play(heroIdle, times = 5) // stops after 5 play throughs
7387
onRender { dt ->
7488
gl.clear(ClearBufferMask.COLOR_BUFFER_BIT)
7589
anim.update(dt)
90+
camera.update()
91+
batch.use(camera.viewProjection) { batch ->
92+
anim.currentKeyFrame?.let {
93+
batch.draw(it, 50f, 50f, scaleX = 5f, scaleY = 5f)
94+
}
95+
}
7696
}
7797
```
7898

@@ -84,7 +104,7 @@ val heroRun: Animation<TextureSlice> = atlas.getAnimation("heroRun")
84104

85105
val anim = AnimaationPlayer<TextureSlice>().apply {
86106
onFrameChange = { index ->
87-
if(index == 2) {
107+
if (index == 2) {
88108
// do something
89109
}
90110
}
@@ -104,3 +124,78 @@ anim.playLooped(heroRun)
104124

105125
anim.stop() // stops the current animation from playing
106126
```
127+
128+
### Registering Animation States
129+
130+
Instead of having to handle playing animations manually we can register a state with a predicate that will automatically trigger the animation to play. Each state has a `priority` as well as a `predicate` that needs to return `true` in order to trigger. An animation with a higher `priority` will play over an animation with a lower `priority`.
131+
132+
```kotlin
133+
val batch = SpriteBatch(this)
134+
val viewport = ExtendViewport(480, 270)
135+
val camera = viewport.camera
136+
137+
val atlas: TextureAtlas = resourcesVfs["tiles.atlas.json"].readAtlas()
138+
val anim = AnimationPlayer<TextureSlice>()
139+
val atlas = resourcesVfs["tiles.atlas.json"].readAtlas()
140+
val heroSleep = atlas.getAnimation("heroSleeping")
141+
val heroSlingShot = atlas.getAnimation("heroSlingShot")
142+
val heroIdle = atlas.getAnimation("heroIdle", 250.milliseconds)
143+
val heroWakeup = atlas.getAnimation("heroWakeUp")
144+
val heroRun = atlas.getAnimation("heroRun")
145+
val heroRoll = atlas.getAnimation("heroRoll", 250.milliseconds)
146+
147+
var shouldSleep = false
148+
var shouldWakeup = false
149+
var shouldRun = false
150+
var shouldRoll = false
151+
152+
anim.apply {
153+
// register all the animation states here.
154+
registerState(heroRoll, 11) { shouldRoll }
155+
registerState(heroWakeup, 10) { shouldWakeup }
156+
registerState(heroRun, 5) { shouldRun }
157+
registerState(heroSleep, 5) { shouldSleep }
158+
registerState(heroIdle, 0) // returns true by default.
159+
}
160+
161+
162+
onRender { dt ->
163+
gl.clearColor(Color.CLEAR)
164+
gl.clear(ClearBufferMask.COLOR_BUFFER_BIT)
165+
166+
if (input.isKeyJustPressed(Key.NUM1)) {
167+
shouldSleep = !shouldSleep
168+
}
169+
170+
if (input.isKeyJustPressed(Key.NUM2)) {
171+
shouldWakeup = !shouldWakeup
172+
}
173+
174+
if (input.isKeyJustPressed(Key.NUM3)) {
175+
shouldRun = !shouldRun
176+
}
177+
178+
if (input.isKeyJustPressed(Key.NUM4)) {
179+
shouldRoll = !shouldRoll
180+
}
181+
182+
if (input.isKeyJustPressed(Key.ENTER)) {
183+
// we can play an animation over any current animation state
184+
anim.play(heroSlingShot)
185+
}
186+
187+
if(input.isKeyJustPressed(Key.SPACE)) {
188+
// we can play an animation over any current animation state
189+
anim.play(heroRoll, 2.seconds)
190+
}
191+
192+
193+
anim.update(dt)
194+
camera.update()
195+
batch.use(camera.viewProjection) { batch ->
196+
anim.currentKeyFrame?.let {
197+
batch.draw(it, 50f, 50f, scaleX = 5f, scaleY = 5f)
198+
}
199+
}
200+
}
201+
```

_docs/2d/cameras-and-viewports.md

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,16 @@ The camera allows us to:
1818

1919
### Orthographic Camera
2020

21-
By default, a _Camera_ uses the default implementation of _Viewport_. This will stretch and shrink the items that are rendered on screen unless we change the cameras viewport to something else.
21+
By default, a _Camera_ doesn't contain or use a _Viewport_. It contains two properties that can be used to calculate the `projection` matrix: `virtualWidth` and `virtualHeight`.
2222

2323
```kotlin
24-
val camera = OrthographicCamera(graphics.width, graphics.height).apply {
25-
viewport = ScreenViewport(graphics.width, graphics.height)
26-
}
24+
val camera = OrthographicCamera(graphics.width, graphics.height)
2725
```
2826

2927
When using a camera we want to make sure we call the `update()` method on it before doing any rendering to ensure it updates that its matrices are up to date. We then can use the `viewProjection` matrix in the _Camera_ class to render to a [SpriteBatch](/docs/2d/spritebatch).
3028

3129
```kotlin
32-
val camera = OrthographicCamera(graphics.width, graphics.height).apply {
33-
viewport = ScreenViewport(graphics.width, graphics.height)
34-
}
30+
val camera = OrthographicCamera(graphics.width, graphics.height)
3531

3632
onRender {
3733
gl.clear(ClearBufferMask.COLOR_BUFFER_BIT)
@@ -43,30 +39,25 @@ onRender {
4339
}
4440
```
4541

46-
We can also update the _Viewport_ of the _Camera_ when the game window resizes:
42+
We can also update the `virtualWidth` and `virtualHeight` of the _Camera_ when the game window resizes:
4743

4844
```kotlin
4945
onResize { width, height ->
50-
// this will update the viewport size and update the cameras matrices
51-
camera.update(width, height, context)
46+
camera.virtualWidth = width
47+
camera.virtualHeight = height
5248
}
5349
```
5450

5551
## Using a Viewport
5652

57-
When using a _Camera_, we are already indirectly using a _Viewport_. A _Camera_ manages its own _Viewport_ and can be manipulated directly on the camera itself.
53+
Instead of managing the size of the camera ourselves, we can use a _Viewport_ instead to handle the sizing. When creating a new _Viewport_ we can either pass in our own _Camera_ instance or let the viewport create its own which we then can reference.
5854

5955
```kotlin
60-
// this will update the internal viewport to the following virtual sizes
61-
camera.virtualWidth = 480
62-
camera.virtualHeight = 270
63-
64-
65-
viewport.virtualWidth = 480
66-
viewport.virtualHeight = 480
56+
val viewport = ExtendViewport(480, 270)
57+
val camera: OrthographicCamera = viewport.camera
6758
```
6859

69-
Resizing a viewport is also done in the _Camera_ class but can also be done directly on the _Viewport_ itself:
60+
A viewport can be resized by using the `update()` method which will also update the _Camera_ instance:
7061

7162
```kotlin
7263
onResize { width, height ->
@@ -85,12 +76,6 @@ viewport2.apply(context)
8576
// draw using the second viewport
8677
```
8778

88-
If we are using a _Camera_ we can access the _Viewport_ directly:
89-
90-
```kotlin
91-
camera.viewport.apply(context)
92-
```
93-
9479
## Types of Viewports
9580

9681
### Stretch Viewport

_docs/overview/context-and-contextlistener.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,21 @@ To get access to a `Context` instance we can create a [ContextListener](https://
1313

1414
As stated above, the context contains all the references to the actual "meat" of LittleKt. The `Context` itself is just an interface that is implemented for each target platform. Through the access we can poll for input, add input processors, access the virtual file system, load assets through resources, store data, and even determine what platform it is currently running on run.
1515

16-
The context also provides creating callbacks for certain events such as rendering, resizing, and disposing. We can add as many callbacks as we needed. They will be called in the order they were added.
16+
The context also provides creating callbacks for certain events such as rendering, resizing, and disposing. We can add as many callbacks as we needed. They will be called in the order they were added. Anytime we subscribe to an event, it returns a callback that we can invoke to unsubscribe.
1717

1818
```kotlin
1919
override suspend fun Context.start() {
20-
onRender { dt ->
20+
val unsubscribeRender = onRender { dt ->
2121
// render logic
2222
gl.clear(ClearBufferMask.COLOR_BUFFER_BIT)
2323
}
2424

2525
onPostRender { dt ->
2626
// the same as render but runs after any render callbacks
27+
28+
if (input.isKeyJustPressed(Keys.ENTER)) {
29+
unsubscribeRender() // we removed the render callback!
30+
}
2731
}
2832

2933
onResize { width, height ->

_docs/scene-graph/creating-a-scene.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,12 @@ onRender { dt ->
8282

8383
// we will need to make if we do other rendering with another camera / viewport
8484
// that we call GL.viewport using viewport.apply(context)
85-
camera.viewport.apply(context)
85+
viewport.apply(context)
8686
camera.update()
8787
}
8888

8989
onResize { width, height ->
90-
camera.update(width, height, context)
90+
viewport.update(width, height, context)
9191
scene.resize(width, height)
9292
}
9393

0 commit comments

Comments
 (0)