You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _docs/2d/animations.md
+96-1Lines changed: 96 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -47,6 +47,10 @@ Creating an `AnimationPlayer` expects a type parameter as well. This needs to ma
47
47
**Playing an animation in a loop:**
48
48
49
49
```kotlin
50
+
val batch =SpriteBatch(this)
51
+
val viewport =ExtendViewport(480, 270)
52
+
val camera = viewport.camera
53
+
50
54
val atlas:TextureAtlas= resourcesVfs["tiles.atlas.json"].readAtlas()
51
55
val heroRun:Animation<TextureSlice> = atlas.getAnimation("heroRun")
52
56
@@ -56,12 +60,22 @@ anim.playLooped(heroRun)
56
60
onRender { dt ->
57
61
gl.clear(ClearBufferMask.COLOR_BUFFER_BIT)
58
62
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
+
}
59
69
}
60
70
```
61
71
62
72
**Playing an animation a specific amount of times:**
63
73
64
74
```kotlin
75
+
val batch =SpriteBatch(this)
76
+
val viewport =ExtendViewport(480, 270)
77
+
val camera = viewport.camera
78
+
65
79
val atlas:TextureAtlas= resourcesVfs["tiles.atlas.json"].readAtlas()
66
80
val heroRun:Animation<TextureSlice> = atlas.getAnimation("heroRun")
67
81
val heroIdle:Animation<TextureSlice> = atlas.getAnimation("heroIdle")
@@ -73,6 +87,12 @@ anim.play(heroIdle, times = 5) // stops after 5 play throughs
73
87
onRender { dt ->
74
88
gl.clear(ClearBufferMask.COLOR_BUFFER_BIT)
75
89
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
+
}
76
96
}
77
97
```
78
98
@@ -84,7 +104,7 @@ val heroRun: Animation<TextureSlice> = atlas.getAnimation("heroRun")
84
104
85
105
val anim =AnimaationPlayer<TextureSlice>().apply {
86
106
onFrameChange = { index ->
87
-
if(index ==2) {
107
+
if(index ==2) {
88
108
// do something
89
109
}
90
110
}
@@ -104,3 +124,78 @@ anim.playLooped(heroRun)
104
124
105
125
anim.stop() // stops the current animation from playing
106
126
```
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
Copy file name to clipboardExpand all lines: _docs/2d/cameras-and-viewports.md
+10-25Lines changed: 10 additions & 25 deletions
Original file line number
Diff line number
Diff line change
@@ -18,20 +18,16 @@ The camera allows us to:
18
18
19
19
### Orthographic Camera
20
20
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`.
22
22
23
23
```kotlin
24
-
val camera =OrthographicCamera(graphics.width, graphics.height).apply {
val camera =OrthographicCamera(graphics.width, graphics.height)
27
25
```
28
26
29
27
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).
30
28
31
29
```kotlin
32
-
val camera =OrthographicCamera(graphics.width, graphics.height).apply {
val camera =OrthographicCamera(graphics.width, graphics.height)
35
31
36
32
onRender {
37
33
gl.clear(ClearBufferMask.COLOR_BUFFER_BIT)
@@ -43,30 +39,25 @@ onRender {
43
39
}
44
40
```
45
41
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:
47
43
48
44
```kotlin
49
45
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
52
48
}
53
49
```
54
50
55
51
## Using a Viewport
56
52
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.
58
54
59
55
```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
67
58
```
68
59
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:
70
61
71
62
```kotlin
72
63
onResize { width, height ->
@@ -85,12 +76,6 @@ viewport2.apply(context)
85
76
// draw using the second viewport
86
77
```
87
78
88
-
If we are using a _Camera_ we can access the _Viewport_ directly:
Copy file name to clipboardExpand all lines: _docs/overview/context-and-contextlistener.md
+6-2Lines changed: 6 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -13,17 +13,21 @@ To get access to a `Context` instance we can create a [ContextListener](https://
13
13
14
14
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.
15
15
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.
17
17
18
18
```kotlin
19
19
overridesuspendfun Context.start() {
20
-
onRender { dt ->
20
+
val unsubscribeRender =onRender { dt ->
21
21
// render logic
22
22
gl.clear(ClearBufferMask.COLOR_BUFFER_BIT)
23
23
}
24
24
25
25
onPostRender { dt ->
26
26
// the same as render but runs after any render callbacks
27
+
28
+
if (input.isKeyJustPressed(Keys.ENTER)) {
29
+
unsubscribeRender() // we removed the render callback!
0 commit comments