Skip to content

Commit

Permalink
progress
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-arold committed Dec 16, 2017
1 parent 5a12976 commit cd3f116
Show file tree
Hide file tree
Showing 4 changed files with 210 additions and 77 deletions.
Expand Up @@ -4,6 +4,7 @@ import org.codetome.zircon.api.Beta
import org.codetome.zircon.api.Size
import org.codetome.zircon.api.TextCharacter
import org.codetome.zircon.api.graphics.TextImage
import java.util.*

@Beta
interface GameArea {
Expand Down Expand Up @@ -37,4 +38,5 @@ interface GameArea {
* Returns the number of levels this [GameArea] has.
*/
fun getLevelCount() = getSize().height

}
Expand Up @@ -10,6 +10,7 @@ import org.codetome.zircon.api.component.ColorTheme
import org.codetome.zircon.api.component.ComponentStyles
import org.codetome.zircon.api.font.Font
import org.codetome.zircon.api.graphics.Layer
import org.codetome.zircon.api.graphics.TextImage
import org.codetome.zircon.api.input.Input
import org.codetome.zircon.api.sam.TextCharacterTransformer
import org.codetome.zircon.api.util.darkenColorByPercent
Expand All @@ -27,6 +28,7 @@ class GameComponent @JvmOverloads constructor(private val gameArea: GameArea,
initialFont: Font,
position: Position,
componentStyles: ComponentStyles,
private val projectionMode: ProjectionMode = ProjectionMode.TOP_DOWN,
boundable: DefaultBoundable = DefaultBoundable(
size = visibleSize.to2DSize(),
position = position),
Expand Down Expand Up @@ -70,19 +72,30 @@ class GameComponent @JvmOverloads constructor(private val gameArea: GameArea,
val allLevelCount = scrollable.getVirtualSpaceSize().height
val startLevel = scrollable.getVisibleOffset().z
val percentage: Double = 1.0.div(visibleLevelCount.toDouble())
var levelCount = 1
return (startLevel until Math.min(startLevel + visibleLevelCount, allLevelCount)).toList().flatMap { levelIdx ->
val currPercentage = percentage.times(levelCount)
levelCount++
gameArea.getSegmentAt(

val result = mutableListOf<Layer>()

// TODO: refactor this to be functional
(startLevel until Math.min(startLevel + visibleLevelCount, allLevelCount)).forEach { levelIdx ->
val segment = gameArea.getSegmentAt(
offset = Position3D.from2DPosition(getVisibleOffset().to2DPosition(), levelIdx),
size = getBoundableSize()).layers
}.map {
LayerBuilder.newBuilder()
.textImage(it)
.offset(getPosition())
.build()
size = getBoundableSize())

segment.layers.forEach {
val img = if(projectionMode == ProjectionMode.TOP_DOWN) {
it
} else {
it.toSubImage(
offset = Position.of(0, levelIdx),
size = it.getBoundableSize().withRelativeRows(-levelIdx))
}
result.add(LayerBuilder.newBuilder()
.textImage(img)
.offset(getPosition())
.build())
}
}
return result
}

private fun refreshVirtualSpaceSize() {
Expand Down
@@ -0,0 +1,6 @@
package org.codetome.zircon.api.beta.component

enum class ProjectionMode {
TOP_DOWN,
ISOMETRIC
}
244 changes: 178 additions & 66 deletions src/test/kotlin/org/codetome/zircon/beta/Playground.kt
Expand Up @@ -2,90 +2,202 @@ package org.codetome.zircon.beta

import org.codetome.zircon.api.Position
import org.codetome.zircon.api.Size
import org.codetome.zircon.api.animation.Animation
import org.codetome.zircon.api.animation.AnimationHandler
import org.codetome.zircon.api.animation.AnimationResource
import org.codetome.zircon.api.builder.TerminalBuilder
import org.codetome.zircon.api.component.builder.ColorThemeBuilder
import org.codetome.zircon.api.Symbols
import org.codetome.zircon.api.beta.component.GameComponent
import org.codetome.zircon.api.beta.component.ProjectionMode
import org.codetome.zircon.api.beta.component.Size3D
import org.codetome.zircon.api.beta.component.TextImageGameArea
import org.codetome.zircon.api.builder.*
import org.codetome.zircon.api.color.ANSITextColor
import org.codetome.zircon.api.color.TextColorFactory
import org.codetome.zircon.api.component.builder.PanelBuilder
import org.codetome.zircon.api.component.builder.TextBoxBuilder
import org.codetome.zircon.api.graphics.TextImage
import org.codetome.zircon.api.input.InputType
import org.codetome.zircon.api.resource.CP437TilesetResource
import org.codetome.zircon.api.resource.ColorThemeResource
import org.codetome.zircon.internal.graphics.BoxType
import java.util.*
import java.util.function.Consumer

object Playground {

@JvmStatic
fun main(args: Array<String>) {
val text = """
Look no further, Zircon is a right tool
for the job.
Zircon is a Text GUI library which targets
multiple platforms and designed
specifically for game developers.
It is usable out of the box for all JVM
languages including Java, Kotlin and Scala.
Things Zircon knows:
- Animations
- A component system with built-in
components for games
- Layering
- Mouse and keyboard input handling
- Shape and box drawing
- Fonts and tilesets
- REXPaint file loading
- Color themes, and more...
"""
val skullAnim: Animation = AnimationResource
.loadAnimationFromFile("src/test/resources/animations/skull.zap")
.loopCount(0)
.setPositionForAll(Position.OFFSET_1x1)
.build()
private val TERMINAL_WIDTH = 60
private val TERMINAL_HEIGHT = 30
private val SIZE = Size.of(TERMINAL_WIDTH, TERMINAL_HEIGHT)
private val FONT = CP437TilesetResource.REX_PAINT_16X16.toFont()
private val LEVEL_COUNT = 10
private val VISIBLE_LEVEL_COUNT = 5


val screen = TerminalBuilder.newBuilder()
.font(CP437TilesetResource.ROGUE_YUN_16X16.toFont())
.initialTerminalSize(Size.of(60, skullAnim.getCurrentFrame().getSize().rows + 2))
.buildScreen()
val WALL_COLOR = TextColorFactory.fromString("#333333")
val ROOF_COLOR = TextColorFactory.fromString("#4d4d4d")
val TC = TextCharacterBuilder.newBuilder()
.build()
val WALL_WITH_FULL_WINDOW = TC.withCharacter(Symbols.SINGLE_LINE_HORIZONTAL)
.withBackgroundColor(WALL_COLOR)
.withForegroundColor(ROOF_COLOR)
val WALL_WITH_NARROW_WINDOW = TC.withCharacter('-')
.withBackgroundColor(WALL_COLOR)
.withForegroundColor(ROOF_COLOR)

val skullPanel = PanelBuilder.newBuilder()
.size(skullAnim.getCurrentFrame().getSize() + Size.of(2, 2))
.wrapWithBox()
.boxType(BoxType.DOUBLE)
val BUILDING_INSIDE = TC.withCharacter('#')
.withBackgroundColor(WALL_COLOR)
.withForegroundColor(ROOF_COLOR)

val BUILDING_ROOF = TC.withBackgroundColor(ROOF_COLOR)
.withForegroundColor(WALL_COLOR)
.withCharacter(' ')
val BUILDING_ROOF_TOP_LEFT = BUILDING_ROOF.withCharacter(Symbols.SINGLE_LINE_TOP_LEFT_CORNER)
val BUILDING_ROOF_TOP_RIGHT = BUILDING_ROOF.withCharacter(Symbols.SINGLE_LINE_TOP_RIGHT_CORNER)
val BUILDING_ROOF_BOT_LEFT = BUILDING_ROOF.withCharacter(Symbols.SINGLE_LINE_BOTTOM_LEFT_CORNER)
val BUILDING_ROOF_BOT_RIGHT = BUILDING_ROOF.withCharacter(Symbols.SINGLE_LINE_BOTTOM_RIGHT_CORNER)

val BUILDING_WITH_FULL_WINDOWS_2X2_LEVEL = TextImageBuilder.newBuilder()
.toCopy(arrayOf(
arrayOf(BUILDING_INSIDE, BUILDING_INSIDE),
arrayOf(BUILDING_INSIDE, BUILDING_INSIDE),
arrayOf(WALL_WITH_FULL_WINDOW, WALL_WITH_FULL_WINDOW)))
.size(Size.of(2, 3))
.build()

val BUILDING_WITH_NARROW_WINDOWS_2X2_LEVEL = TextImageBuilder.newBuilder()
.toCopy(arrayOf(
arrayOf(BUILDING_INSIDE, BUILDING_INSIDE),
arrayOf(BUILDING_INSIDE, BUILDING_INSIDE),
arrayOf(WALL_WITH_NARROW_WINDOW, WALL_WITH_NARROW_WINDOW)))
.size(Size.of(2, 3))
.build()

val BUILDING_2X2_ROOF_0 = TextImageBuilder.newBuilder()
.toCopy(arrayOf(
arrayOf(BUILDING_ROOF_TOP_LEFT, BUILDING_ROOF_TOP_RIGHT),
arrayOf(BUILDING_ROOF_BOT_LEFT, BUILDING_ROOF_BOT_RIGHT)))
.size(Size.of(2, 3))
.build()
val BUILDING_2X2_ROOF_1 = TextImageBuilder.newBuilder()
.toCopy(arrayOf(
arrayOf(BUILDING_ROOF, BUILDING_ROOF),
arrayOf(BUILDING_ROOF, BUILDING_ROOF)))
.size(Size.of(2, 3))
.build()

val BASE_STYLE = StyleSetBuilder.newBuilder()
.foregroundColor(TextColorFactory.fromString("#214100"))
.backgroundColor(TextColorFactory.fromString("#4d6600"))
.build()

val SIMPLE_ANTENNA = TextCharacterBuilder.newBuilder()
.backgroundColor(ROOF_COLOR)
.foregroundColor(WALL_COLOR)
.character(Symbols.ARROW_UP)
.build()

val BASE_4X4 = TextImageBuilder.newBuilder()
.filler(TextCharacterBuilder.newBuilder()
.backgroundColor(BASE_STYLE.getBackgroundColor())
.foregroundColor(BASE_STYLE.getForegroundColor())
.build())
.size(Size.of(4, 4))
.build().apply {
setStyleFrom(BASE_STYLE)
setCharacterAt(Position.of(0, 0), Symbols.CLUB)
setCharacterAt(Position.of(0, 2), '"')
setCharacterAt(Position.of(1, 3), Symbols.SPADES)
setCharacterAt(Position.of(3, 3), '"')
}

@JvmStatic
fun main(args: Array<String>) {

val terminal = TerminalBuilder.newBuilder()
.font(FONT)
.initialTerminalSize(SIZE)
.build()
val contentPanel = PanelBuilder.newBuilder()
.boxType(BoxType.DOUBLE)
.size(screen.getBoundableSize()
.withRelativeColumns(-skullPanel.getBoundableSize().columns))
.position(skullPanel.getBoundableSize().toRightPosition())
.title("Do you plan to make a roguelike?")
val screen = TerminalBuilder.createScreenFor(terminal)
screen.setCursorVisibility(false) // we don't want the cursor right now

val gamePanel = PanelBuilder.newBuilder()
.size(screen.getBoundableSize().withColumns(60))
.title("Game area")
.wrapWithBox()
.boxType(BoxType.TOP_BOTTOM_DOUBLE)
.build()

val disabledTextBox = TextBoxBuilder.newBuilder()
.text(text)
.size(contentPanel.getEffectiveSize())
.build()
val gameAreaSize = Size3D.from2DSize(gamePanel.getBoundableSize()
.minus(Size.of(2, 2)), VISIBLE_LEVEL_COUNT)


screen.addComponent(skullPanel)
screen.addComponent(contentPanel)
contentPanel.addComponent(disabledTextBox)
val levels = HashMap<Int, List<TextImage>>()
for (i in 0 until LEVEL_COUNT) {
levels.put(i, listOf(TextImageBuilder.newBuilder()
.size(gameAreaSize.to2DSize())
.build()))
}

val theme = ColorThemeResource.SOLARIZED_DARK_CYAN.getTheme()
skullPanel.applyColorTheme(ColorThemeBuilder.newBuilder()
.accentColor(theme.getAccentColor())
.brightForegroundColor(theme.getBrightForegroundColor())
.darkForegroundColor(theme.getDarkForegroundColor())
.build())
contentPanel.applyColorTheme(theme)
val gameArea = TextImageGameArea(Size3D.from2DSize(gameAreaSize.to2DSize(), LEVEL_COUNT), levels)

disabledTextBox.disable()
val gameComponent = GameComponent(
gameArea = gameArea,
visibleSize = gameAreaSize,
initialFont = CP437TilesetResource.PHOEBUS_16X16.toFont(),
position = Position.DEFAULT_POSITION,
componentStyles = ComponentStylesBuilder.DEFAULT,
projectionMode = ProjectionMode.ISOMETRIC)
screen.addComponent(gamePanel)
gamePanel.addComponent(gameComponent)

val animationHandler = AnimationHandler(screen)
animationHandler.addAnimation(skullAnim)
val level0 = levels[0]!![0]
val floor = TextCharacterBuilder.newBuilder()
.backgroundColor(TextColorFactory.fromString("#665233"))
.foregroundColor(TextColorFactory.TRANSPARENT)
.build()
level0.fetchCells().forEach { (position) -> level0.setCharacterAt(position, floor) }

draw2x2Building(levels, Position.of(5, 6))
draw2x2Building(levels, Position.of(6, 10))
draw2x2Building(levels, Position.of(18, 21))
draw2x2Building(levels, Position.of(26, 9))
draw2x2Building(levels, Position.of(39, 15))
draw2x2Building(levels, Position.of(48, 12))


screen.applyColorTheme(ColorThemeResource.SOLARIZED_DARK_CYAN.getTheme())
screen.onInput(Consumer { input ->
if (InputType.PageUp === input.getInputType()) {
gameComponent.scrollOneUp()
}
if (InputType.PageDown === input.getInputType()) {
gameComponent.scrollOneDown()
}
screen.drainLayers()
val visibleOffset = gameComponent.getVisibleOffset()
screen.pushLayer(LayerBuilder.newBuilder()
.textImage(TextCharacterStringBuilder.newBuilder()
.backgroundColor(TextColorFactory.TRANSPARENT)
.foregroundColor(TextColorFactory.fromString("#aaaadd"))
.text(String.format("Position: (x=%s, y=%s, z=%s)", visibleOffset.x, visibleOffset.y, visibleOffset.z))
.build()
.toTextImage())
.offset(Position.of(21, 1))
.build())
screen.refresh()
})
screen.display()
}

private fun draw2x2Building(levels: Map<Int, List<TextImage>>, pos: Position) {
val random = Random()
var lastLevel = levels[0]!![0]
lastLevel.draw(BASE_4X4, pos.withRelativeColumn(-1))
val wall = if (random.nextInt(2) == 0) BUILDING_WITH_FULL_WINDOWS_2X2_LEVEL else BUILDING_WITH_NARROW_WINDOWS_2X2_LEVEL
(0 until random.nextInt(7) + 1).forEach {
val level = levels[it]!![0]
level.draw(wall, pos)
lastLevel = level
}
lastLevel.draw(if (random.nextInt(2) == 0) BUILDING_2X2_ROOF_0 else BUILDING_2X2_ROOF_1, pos)
if(random.nextInt(2) == 1) {
lastLevel.setCharacterAt(pos, SIMPLE_ANTENNA)
}
}
}

0 comments on commit cd3f116

Please sign in to comment.