Skip to content

Commit 3779a0e

Browse files
author
adam-arold
committed
add player movement and scrolling
1 parent d8e7f78 commit 3779a0e

12 files changed

Lines changed: 193 additions & 11 deletions

File tree

src/main/kotlin/org/hexworks/cavesofzircon/GameConfig.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ object GameConfig {
2020
const val WINDOW_WIDTH = 80
2121
const val WINDOW_HEIGHT = 50
2222

23-
val WORLD_SIZE = Sizes.create3DSize(WINDOW_WIDTH - SIDEBAR_WIDTH, WINDOW_HEIGHT - LOG_AREA_HEIGHT, DUNGEON_LEVELS)
23+
val WORLD_SIZE = Sizes.create3DSize(WINDOW_WIDTH * 2, WINDOW_HEIGHT * 2 , DUNGEON_LEVELS)
2424

2525
fun buildAppConfig() = AppConfigs.newConfig()
2626
.enableBetaFeatures()

src/main/kotlin/org/hexworks/cavesofzircon/builders/EntityFactory.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import org.hexworks.amethyst.api.entity.EntityType
66
import org.hexworks.cavesofzircon.attributes.EntityPosition
77
import org.hexworks.cavesofzircon.attributes.EntityTile
88
import org.hexworks.cavesofzircon.attributes.types.Player
9+
import org.hexworks.cavesofzircon.systems.CameraMover
10+
import org.hexworks.cavesofzircon.systems.InputReceiver
11+
import org.hexworks.cavesofzircon.systems.Movable
912
import org.hexworks.cavesofzircon.world.GameContext
1013

1114
fun <T : EntityType> newGameEntityOfType(type: T, init: EntityBuilder<T, GameContext>.() -> Unit) =
@@ -15,7 +18,7 @@ object EntityFactory {
1518

1619
fun newPlayer() = newGameEntityOfType(Player) {
1720
attributes(EntityPosition(), EntityTile(GameTileRepository.PLAYER))
18-
behaviors()
19-
facets()
21+
behaviors(InputReceiver)
22+
facets(Movable, CameraMover)
2023
}
2124
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package org.hexworks.cavesofzircon.commands
2+
3+
enum class CameraMoveDirection {
4+
UP,
5+
DOWN,
6+
LEFT,
7+
RIGHT
8+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package org.hexworks.cavesofzircon.commands
2+
3+
import org.hexworks.amethyst.api.entity.EntityType
4+
import org.hexworks.cavesofzircon.extensions.GameCommand
5+
import org.hexworks.cavesofzircon.extensions.GameEntity
6+
import org.hexworks.cavesofzircon.world.GameContext
7+
import org.hexworks.zircon.api.data.impl.Position3D
8+
9+
data class MoveCamera(override val context: GameContext,
10+
override val source: GameEntity<EntityType>,
11+
val previousPosition: Position3D) : GameCommand<EntityType>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.hexworks.cavesofzircon.commands
2+
3+
import org.hexworks.amethyst.api.entity.EntityType
4+
import org.hexworks.cavesofzircon.extensions.GameCommand
5+
import org.hexworks.cavesofzircon.extensions.GameEntity
6+
import org.hexworks.cavesofzircon.world.GameContext
7+
import org.hexworks.zircon.api.data.impl.Position3D
8+
9+
/**
10+
* A [GameCommand] representing moving [source] to [position].
11+
*/
12+
data class MoveTo(override val context: GameContext,
13+
override val source: GameEntity<EntityType>,
14+
val position: Position3D) : GameCommand<EntityType>

src/main/kotlin/org/hexworks/cavesofzircon/extensions/TypeAliases.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.hexworks.cavesofzircon.extensions
22

3+
import org.hexworks.amethyst.api.Command
34
import org.hexworks.amethyst.api.entity.Entity
45
import org.hexworks.amethyst.api.entity.EntityType
56
import org.hexworks.cavesofzircon.world.GameContext
@@ -13,3 +14,8 @@ typealias AnyGameEntity = Entity<EntityType, GameContext>
1314
* Specializes [Entity] with our [GameContext] type.
1415
*/
1516
typealias GameEntity<T> = Entity<T, GameContext>
17+
18+
/**
19+
* Specializes [Command] with our [GameContext] type.
20+
*/
21+
typealias GameCommand<T> = Command<T, GameContext>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.hexworks.cavesofzircon.systems
2+
3+
import org.hexworks.amethyst.api.Consumed
4+
import org.hexworks.amethyst.api.base.BaseFacet
5+
import org.hexworks.amethyst.api.entity.EntityType
6+
import org.hexworks.cavesofzircon.commands.MoveCamera
7+
import org.hexworks.cavesofzircon.extensions.GameCommand
8+
import org.hexworks.cavesofzircon.extensions.position
9+
import org.hexworks.cavesofzircon.world.GameContext
10+
11+
object CameraMover : BaseFacet<GameContext>() {
12+
13+
override fun executeCommand(command: GameCommand<out EntityType>) = command.responseWhenCommandIs(MoveCamera::class) { cmd ->
14+
val (context, source, previousPosition) = cmd
15+
val world = context.world
16+
val screenPos = source.position - world.visibleOffset() // 1
17+
val halfHeight = world.visibleSize().yLength / 2 // 2
18+
val halfWidth = world.visibleSize().xLength / 2 // 3
19+
val currentPosition = source.position
20+
when { // 4
21+
previousPosition.y > currentPosition.y && screenPos.y < halfHeight -> {
22+
world.scrollOneBackward()
23+
}
24+
previousPosition.y < currentPosition.y && screenPos.y > halfHeight -> {
25+
world.scrollOneForward()
26+
}
27+
previousPosition.x > currentPosition.x && screenPos.x < halfWidth -> {
28+
world.scrollOneLeft()
29+
}
30+
previousPosition.x < currentPosition.x && screenPos.x > halfWidth -> {
31+
world.scrollOneRight()
32+
}
33+
}
34+
Consumed
35+
}
36+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package org.hexworks.cavesofzircon.systems
2+
3+
import org.hexworks.amethyst.api.base.BaseBehavior
4+
import org.hexworks.amethyst.api.entity.EntityType
5+
import org.hexworks.cavesofzircon.commands.MoveTo
6+
import org.hexworks.cavesofzircon.extensions.GameEntity
7+
import org.hexworks.cavesofzircon.extensions.position
8+
import org.hexworks.cavesofzircon.world.GameContext
9+
import org.hexworks.zircon.api.uievent.KeyCode
10+
import org.hexworks.zircon.api.uievent.KeyboardEvent
11+
12+
object InputReceiver : BaseBehavior<GameContext>() {
13+
14+
override fun update(entity: GameEntity<out EntityType>, context: GameContext): Boolean {
15+
val (_, _, uiEvent, player) = context
16+
val currentPos = player.position
17+
if (uiEvent is KeyboardEvent) {
18+
val newPosition = when (uiEvent.code) {
19+
KeyCode.KEY_W -> currentPos.withRelativeY(-1)
20+
KeyCode.KEY_A -> currentPos.withRelativeX(-1)
21+
KeyCode.KEY_S -> currentPos.withRelativeY(1)
22+
KeyCode.KEY_D -> currentPos.withRelativeX(1)
23+
else -> {
24+
currentPos
25+
}
26+
}
27+
player.executeCommand(MoveTo(context, player, newPosition))
28+
}
29+
return true
30+
}
31+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package org.hexworks.cavesofzircon.systems
2+
3+
import org.hexworks.amethyst.api.CommandResponse
4+
import org.hexworks.amethyst.api.Consumed
5+
import org.hexworks.amethyst.api.Pass
6+
import org.hexworks.amethyst.api.Response
7+
import org.hexworks.amethyst.api.base.BaseFacet
8+
import org.hexworks.amethyst.api.entity.EntityType
9+
import org.hexworks.cavesofzircon.attributes.types.Player
10+
import org.hexworks.cavesofzircon.commands.MoveCamera
11+
import org.hexworks.cavesofzircon.commands.MoveTo
12+
import org.hexworks.cavesofzircon.extensions.GameCommand
13+
import org.hexworks.cavesofzircon.extensions.position
14+
import org.hexworks.cavesofzircon.world.GameContext
15+
16+
object Movable : BaseFacet<GameContext>() {
17+
18+
override fun executeCommand(command: GameCommand<out EntityType>) = command.responseWhenCommandIs(MoveTo::class) { (context, entity, position) ->
19+
val world = context.world
20+
val previousPosition = entity.position // 1
21+
var result: Response = Pass
22+
if (world.moveEntity(entity, position)) {
23+
result = if (entity.type == Player) { // 2
24+
CommandResponse(MoveCamera( // 3
25+
context = context,
26+
source = entity,
27+
previousPosition = previousPosition))
28+
} else Consumed
29+
}
30+
result
31+
}
32+
}

src/main/kotlin/org/hexworks/cavesofzircon/view/PlayView.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,23 @@ import org.hexworks.zircon.api.Components
88
import org.hexworks.zircon.api.GameComponents
99
import org.hexworks.zircon.api.component.ComponentAlignment
1010
import org.hexworks.zircon.api.data.Tile
11+
import org.hexworks.zircon.api.extensions.onKeyboardEvent
1112
import org.hexworks.zircon.api.game.ProjectionMode
1213
import org.hexworks.zircon.api.mvc.base.BaseView
14+
import org.hexworks.zircon.api.uievent.KeyboardEventType
15+
import org.hexworks.zircon.api.uievent.Processed
1316

1417
class PlayView(private val game: Game = GameBuilder.defaultGame()) : BaseView() {
1518

1619
override val theme = GameConfig.THEME
1720

1821
override fun onDock() {
1922

23+
screen.onKeyboardEvent(KeyboardEventType.KEY_PRESSED) { event, _ ->
24+
game.world.update(screen, event, game)
25+
Processed
26+
}
27+
2028
val sidebar = Components.panel()
2129
.withSize(GameConfig.SIDEBAR_WIDTH, GameConfig.WINDOW_HEIGHT)
2230
.wrapWithBox()

0 commit comments

Comments
 (0)