Giter Site home page Giter Site logo

hexworks / zircon Goto Github PK

View Code? Open in Web Editor NEW
740.0 28.0 135.0 41.73 MB

Zircon is an extensible and user-friendly, multiplatform tile engine.

Home Page: https://hexworks.org/projects/zircon/

License: Apache License 2.0

Kotlin 100.00% Shell 0.01%
zircon multiplatform text-gui roguelike game-development java jvm kotlin scala

zircon's Introduction

Zircon - A user-friendly Tile Engine & Text GUI Tweet

Full Example

Need info? Check the Docs | or Create an issue | Check our project Board | Ask us on Discord | Support us on Patreon | Javadoc / Kdoc

Circle CI Maven Central License Awesome


Table of Contents

Getting Started

If you want to start working with Zircon you can either add it to your project as a Maven dependency or you can try out the skeleton projects (Java, Kotlin) which come with batteries included.

The official documentation site contains a lot of information. The examples are also documented on the Zircon Examples page (under construction), and the best place to start is the Zircon Crash Course.

If you like learning by doing check out the source of Zircon from here and you can run the examples for yourself. If you are using Java start here . Alternatively if you use Kotlin the code can be found here.

If you just want to peruse the Zircon API navigate here. Everything which is intended to be part of the public API is there.

You can find the Javadoc / Kdoc here

If you'd like to talk to us, join us on our Discord Server.

Adding Zircon as a Maven Dependency

Maven:

<dependencies>
    <dependency>
        <groupId>org.hexworks.zircon</groupId>
        <artifactId>zircon.core-jvm</artifactId>
        <version>2021.1.0-RELEASE</version>
    </dependency>
    <!-- use zircon.jvm.libgdx if you want to use LibGDX instead of Swing -->
    <dependency>
        <groupId>org.hexworks.zircon</groupId>
        <artifactId>zircon.jvm.swing</artifactId>
        <version>2021.1.0-RELEASE</version>
    </dependency>
</dependencies>

Gradle:

dependencies {
    implementation "org.hexworks.zircon:zircon.core-jvm:2021.1.0-RELEASE"
    implementation "org.hexworks.zircon:zircon.jvm.swing:2021.1.0-RELEASE"
}

Basic Usage

Once you have the dependencies set up you can start using Zircon by creating a TileGrid:

public class Main {

    public static void main(String[] args) {

        // a TileGrid represents a 2D grid composed of Tiles
        TileGrid tileGrid = SwingApplications.startTileGrid(
                AppConfig.newBuilder()
                        // The number of tiles horizontally, and vertically
                        .withSize(60, 30)
                        // You can choose from a wide array of CP437, True Type or Graphical tilesets
                        // that are built into Zircon
                        .withDefaultTileset(CP437TilesetResources.rexPaint16x16())
                        .build());

        // A Screen is an abstraction that lets you use text GUI Components
        // You can have multiple Screens attached to the same TileGrid to be able to create multiple
        // screens for your app.
        Screen screen = Screen.create(tileGrid);

        // Creating text GUI Components is super simple
        Label label = Components.label()
                .withText("Hello, Zircon!")
                .withAlignment(ComponentAlignments.alignmentWithin(tileGrid, ComponentAlignment.CENTER))
                .build();

        // Screens can hold GUI components
        screen.addComponent(label);

        // Displaying a screen will make it visible. It will also hide a previously shown Screen.
        screen.display();

        // Zircon comes with a plethora of built-in color themes
        screen.setTheme(ColorThemes.arc());
    }
}

The output of this example is:

Zircon Application

Congratulations! Now you are a Zircon user.

Best Practices

The following are some guidelines that can help you if you get stuck:

If you want to build something (a TileGraphics, a Component or anything that is part of the public API) it is almost sure that there is a Builder or a factory object for it. Each type that has a builder will have a newBuilder function you can call to create the corresponding builder: Tile.newBuilder().

If there are multiple classes of objects that can be created there might also be a utility class, like Shapes to create different Shape objects. Your IDE will help you with this.

These classes reside in the org.hexworks.zircon.api package. There are some classes that are grouped together into a single utility class, however. With Components for example, you can obtain Builders for all Components like Components.panel() or Components.checkBox(). Likewise, you can use DrawSurfaces to obtain builders for TileGraphics and TileImage.

If you want to work with external files like tilesets or REXPaint files check the same package (org.hexworks.zircon.api), and look for classes that end with *Resources. There are a bunch of built-in tilesets for example which you can choose from, but you can also load your own.

The rule of thumb is that if you need something external there is probably a *Resources class for it (like the CP437TilesetResources).

You can use anything you can find in the API package, they are part of the public API, and safe to use. The internal package however is considered private to Zircon so keep in mind that they can change any time.

Some topics are explained in depth in the documentation.

If you want to see some example code take a look at the examples project here. Most examples have identical Java and Kotlin variants.

If all else fails read the javadocs. API classes are well documented.

If you have any problems that are not answered here feel free to ask us at the Hexworks Discord server.

Features at a Glance

Drawing

You can find detailed documentation about drawing here.

The most basic operation Zircon supports is drawing. You can draw individual Tiles or TileGraphics objects on your TileGrid. a TileGraphics object is composed of Tiles. This is a powerful tool, and you can implement more complex features using simple draw operations. In fact the component system is implemented on top of drawing, layering and input handling features.

If you use REXPaint to design your programs, the good news is that you can import your .xp files as well. Read more about it here.

You can also use Modifiers in your Tiles such as blink, verticalFlip or glow. For a full list, check this factory object. Modifiers can either change the texture (like the ones above) or the Tile itself:

Modifiers

Input handling

Read about input handling in the docs here.

Both the TileGrid and the Screen interfaces implement UIEventSource which means that you can listen for user inputs using them. This includes keystrokes and mouse input as well.

Layering

Layering is detailed here. For a primer on Screens go here.

Both the TileGrid and the Screen interfaces implement Layerable which means that you can add Layers on top of them. Every Layerable can have an arbitrary amount of Layers. Layers are like TileGraphics objects, and you can also have transparency in them which can be used to create fancy effects. Components are also Layers themselves. Take a look:

Layers

Text GUI Components

You can read more about the Component System on the documentation page. Color themes are detailed here.

Components are GUI controls which can be used for showing content to the user (Labels, Paragraphs, etc.), enabling them to interact with your program (Buttons, Sliders, etc.) or to hold other components (Panels for example).

These components are rather simple, and you can expect them to work in a way you might be familiar with:

  • You can click on them (press and release are different events).
  • You can attach event listeners on them.
  • Zircon implements focus handling, so you can navigate between the components using the [Tab] key (forwards) or the [Shift]+[Tab] keystroke (backwards).
  • Components can be hovered, and you can also apply color themes to them.

What's more is that you can apply ColorThemes to Components. There are a bunch of built-in themes, and you can also create your own.

To see a full list of available Components take a look at the Components factory object or navigate to the component docs page.

This is an example of how components look in action:

All Components

Animations:

Read more about Animations in the docs.

Animations are supported out of the box. You can either create them programmatically, or statically using Zircon's own animation format: .zap (Zircon Animation Package). More about that here. This is how an animation looks like:

Animation Example

Shape and box drawing

The shape documentation page can be found here.

You can draw Shapes like rectangles and triangles by using one of the ShapeFactory implementations. What's supported out of the box is triangle, rectangle and line. The former two have filled versions as well. Check out the Shapes factory object here .

Fonts and Tilesets

The documentation page for tilesets is here.

Zircon comes with a bunch of built-in fonts tilesets. These come in 3 flavors:

  • CP437 tilesets (More on using them here)
  • True Type Fonts
  • and Graphical tilesets (Usage info here)

Zircon also comes with its own tileset format (ztf: Zircon Tileset Format) which is very easy to use. It is detailed here.

Road Map

If you want to see a new feature feel free to create a new Issue or discuss it with us on Discord. Here are some features which are either under way or planned:

If you'd like to give any of these a shot feel free to contribute.

License

Zircon is made available under the Apache 2.0 License.

Credits

Zircon is created and maintained by Addamsson, Coldwarrl, G3ldrin, Milonoir, Seveen and many others.

We're open to suggestions, feel free to message us on Discord or open an issue. Pull requests are also welcome!

Zircon is powered by:

IDEA Kotlin Yourkit

Thanks

Thanks to the folks over at Dwarf Fortress Tileset Repository for letting us bundle their tilesets.

Thanks to Kyzrati who let us bundle the REXPaint Tilesets into Zircon!

Zircon comes bundled with the Nethack Tileset.

Some True Type fonts are used from Google Fonts.

Thanks to VileR for the Oldschool Font Pack which we bundled into Zircon.

zircon's People

Contributors

adam-arold avatar baret avatar coldwarrl avatar daggerbot avatar duckydude20 avatar entelente avatar geldrin avatar irmen avatar kamildoleglo avatar klaus-hauschild-xom avatar lesbiangunshow avatar lucyletour avatar milonoir avatar mrbergin avatar msklosak avatar nanodeath avatar qeqeqe avatar riscy avatar rspindler avatar seveen avatar soywiz avatar strangeoptics avatar wleroux avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zircon's Issues

TextCharacterString support

TextCharacterStrings are an aggregation of TextCharacters into an array. You can draw a TextCharacterString onto any DrawSurface and you can expect it to behave in a way like handwriting would (if a string does not fit in a line it continues in a new line).

Text wrapping is managed by TextWrap which is an enum with NO_WRAPPING and WRAP options.

TextCharacterString comes with its own builder and you can create them in a simple way from plain Java Strings.

Clarify "no metadata found exception" when trying non-printable characters.

If the user tries to add a non-printable character to the screen (ASCII 1 to 31) Zircon throws an exception right now:

       // excerpt from Java2DFont.kt
        require(hasDataForChar(textCharacter.getCharacter())) {
            "No metadata exists for character: '${textCharacter.getCharacter().toInt()}'!"
        }
        val filtered = metadata[textCharacter.getCharacter()]!!.filter { it.tags.containsAll(tags.toList()) }
        require(filtered.isNotEmpty()) {
            "No metadata found for tag(s): ${tags.joinToString()}"
        }

This needs to be clarified so users will know what the problem is:

  • If textCharacter has a non-printable character (can be checked with TextUtils#isPrintableCharacter the exception should be something like

    "Can't find font texture region for non-printable character 'x'"

  • If there is no metadata (texture) for the given tag it should also be more clear like

    "Can't find font texture region for tag(s): x,y,z"

Floating windows

A Floating window is an Component which can have an arbitrary position on the screen over any ordinary Component. This means that the boundary check should be relaxed for floating windows and they should be able to be added anywhere.

The caveat is that a floating window should not overlap with any other floating window.

Depends on #24 because it will introduce the Layerable stack
Related to #22 because Drag'n drop is the main use case for moving floating windows

Graphical tile format specification

There should be a simple format for monospaced tilesets (like with Dwarf Fortress tilesets but supporting Unicode). The format should also contain metadata about the image - character lookup.

If there are more images for a character they should be differentiated (by tagging possibly).

This format should be specified as part of this task.

Bitmap font loading

There should be an option to load fonts as bitmaps (using BMFont exports for example). Currently there is a custom loader which loads CP437 based Dwarf Fortress tilesets. There should be another one which reads custom tileset files (this format should be researched and implemented in #6 ).

Behaviors

There are some common behaviors already implemented (like CursorHolder). This should be extended to graphical objects supporting:

  • Shadow
  • Scroll
  • Border
  • DragNDrop

Implement "Log" Component

Summary

A "Log" refers to a GUI component, often used in roguelike games to display information to the user about a variety of events.

A dedicated "Log" Component would be a useful way to easily provide this functionality in a GUI.

Example

The Orc's attack hits!
The Orc attacks you!
You missed...
You attacked the Orc!

Work Around

The current work around is to use a TextImage:

  1. Create TextImage for your preferred size
  2. Draw a box around it via BoxBuilder
  3. Update TextImage with each of your log messages via TextImage's putText() method

For Example

public class Playground {

    public static void main(String[] args) {
        final Terminal terminal = TerminalBuilder.newBuilder()
                .font(CP437TilesetResource.REX_PAINT_20X20.toFont())
                .initialTerminalSize(Size.of(10, 5))
                .build();

        final TextImage img = TextImageBuilder.newBuilder()
                .size(Size.of(10, 5))
                .build(); // we create a new image to draw onto the terminal

        img.setForegroundColor(ANSITextColor.WHITE);
        img.setBackgroundColor(ANSITextColor.BLUE); // `putText` will use these

        BoxBuilder.newBuilder()
                .boxType(BoxType.DOUBLE)
                .size(Size.of(10, 5))
                .style(StyleSetBuilder.newBuilder()
                        .foregroundColor(ANSITextColor.CYAN)
                        .backgroundColor(ANSITextColor.BLUE)
                        .build())
                .build()
                .drawOnto(img, Position.DEFAULT_POSITION); // we create a box and draw it onto the image

        final List<String> logElements = new ArrayList<>();
        logElements.add("foo");
        logElements.add("bar"); // our log entries

        for(int i = 0; i < logElements.size(); i++) {
            img.putText(logElements.get(i), Position.OFFSET_1x1.withRelativeRow(i)); // we have to offset because of the box
        }

        terminal.draw(img, Position.DEFAULT_POSITION); // you have to draw each time the image changes

        terminal.flush();
    }
}

Half-width `Font` support

Support for using multiple fonts which can be half-width (eg. using a 16x16 font with a 8x16 Font).

Related: #31

Modal support (dialogs)

Currently we use ComponentsLayerable:

class ComponentsLayerable(
        private val layerable: Layerable,
        private val components: DefaultContainer)
    : Layerable by layerable {

    override val layers: List<Layer>
        get() = components.toFlattenedLayers().plus(layerable.layers)
}

which composes a simple Layerable and a Container to manage both Components and simple Layers.

This should be improved by having a stack of Layerables:

  • At the bottom there should be Components
  • Above Components should be ModalComponents which have a size of the screen so the user can't interact with ordinary Components below a modal.
  • At the top there are the "ordinary" Layers.

Things to do:

  • Add addModal next to addComponent to ComponentContainer.
  • Implement the layers stack in CompoentContainer instead of what we have now in TileGridScreen
  • Factor out focus handling from DefaultComponentContainer into its own class

Uniform Font handling

Currently Zircon uses java.awt.Font for fonts. This needs to be abstracted so a custom tileset or font can be used. This new Font should also be used for real fonts (like the ones which come from ttf files) and tilesets together but should be differentiated based on the format they store the data (BufferedImage for swing and Texture for Libgdx for example).

Fix weird ANSITextColor bug

If any ANSITextColor enum constant is referenced from a unit test weird things happen like NoClassDefFoundErrors or NullPointerExceptions. This should be investigated. It is not sure whether this is a Kotlin issue or a Java one.

Embedding images/bitmaps

Possibility for embedding images/bitmaps

Currently it is not possible to embed an arbitrary image/bitmap (e.g. a background image)

Rationale

Embed background images or as a GUI element

Suggested way of implementing

Ideally, an approach like the TextImage would be provided to embed images.
Also it might be useful to have a dedicated component for embedding a bitmap as a GUI control

Wrong symbol/glyph is displayed

I'm trying to render the following simple sub-part of a screen:

bug_zircon_1

This gets rendered correctly.

Now look at the following image:
bug_zircon2

The 'X' symbol in the row 'X P I' has changed to 'T P I ' (By intention by setting the appropriate TextCharacter). Now this has the effect that the '8' in the Mark 48 text gets changed to Mark 4T too!

Analysis

  • My application definitly sets the text 'Mark 48'
  • I've set a break point in the function drawCharacter in class ApplicationTerminal.kt. Here also the correct char ('8') is provided and in line 134 of the same class the called function 'drawFontTextureRegion' correctly seems to take the valid char 'bitmap' from the font.

Sometimes debugging has the effect that the correct char is rendered!
See
bug_zircon_3

I've set a conditional breakpoint in the mentioned function of ApplicationTerminal.kt . Since this slowed down the application considerably, I've seen once that the '8' got replaced by 'T' after a couple of seconds.

Remarks:

  • The thread, which calls the zircon API functions to draw that view is not the thread, which has created the screen and other zircon artifacts.
  • I've tried to use screen.display() instead of screen.refresh() but that does not help.

Snipped how the text is rendered

def drawSimpleAttribute(simpleAttribute: SimpleAttribute, xPos: Int): Unit = {
      val attrDrawable =
        if (simpleAttribute.bgColor.isEmpty)
          TextCharacterStringBuilder.newBuilder()
            .text(simpleAttribute.getValue)
            .foregroundColor(surface.fxToTextColor(simpleAttribute.fgColor))
            .build()
        else
          TextCharacterStringBuilder.newBuilder()
            .text(simpleAttribute.getValue)
            .foregroundColor(surface.fxToTextColor(simpleAttribute.fgColor))
            .backgroundColor(surface.fxToTextColor(simpleAttribute.bgColor.get))
            .build()

      surface.screen.draw(attrDrawable, surface.getAbsolutePosition(Position.of(xPos, simpleAttribute.y + model.startYPos)))
    }

If the experts also have no clue, I'll have to write a comprehensive test app, trying to reproduce this issue.

TileColor transformations

TextColor should support transform operations:

  • tint: adding a different color to this one
  • shade: lighten or darken the color
  • invert: flip the color to its opposite (blue vs red for example)

These operations should go into the TextColor interface and work in a way which is consistent with all other operations on immutable objects: they should create a new TextColor object with the result of the operation.

The implementations should go into DefaultTextColor.

More information about how tinting and shading works can be found here.

Custom .ttf font loading

There should be an option for loading custom ttf fonts. This is possible using java.awt.Font and not hard to implement. This task depends on #2

REXPaint loader implementation

A REXPaint file should be loaded into a Set of Layers. Since REXPaint does not store font information this task is not related to font-based tasks. We need to look into this

Input does not catch keystroke <CTRL>+Z on Windows 10 and Ubuntu 17.10

Bug in Input/key stroke: CTRL+Z (and probably other combinations) do not work

Expected behavior

Ctrl+Z should be catched correctly, that is keystroke.getCharacter should return 'z'

Actual behavior

keystroke.getCharacter returns '\u001A' 26
Tested on Windows 10 + Ubuntu 17.10 using JDK 9.0.1

Steps to reproduce the bug

import org.codetome.zircon.api.Position
import org.codetome.zircon.api.Size
import org.codetome.zircon.api.builder.TerminalBuilder
import org.codetome.zircon.api.builder.TextImageBuilder
import org.codetome.zircon.api.resource.CP437TilesetResource
import java.util.function.Consumer

object InputTest {

    @JvmStatic
    fun main(args: Array<String>) {
        val terminal = TerminalBuilder.newBuilder()
                .initialTerminalSize(Size.of(32, 16))
                .font(CP437TilesetResource.REX_PAINT_18X18.toFont())
                .build()

        val screen = TerminalBuilder.createScreenFor(terminal)

        val textImage = TextImageBuilder.newBuilder().size(Size(10, 10)).build()
        textImage.putText("hi", Position(2, 2))

        screen.setCharacterAt(Position.of(2, 2), 'e')

        screen.onInput(listener = Consumer { input ->
            run {
                if (input.isKeyStroke())
                    println(input.asKeyStroke().toString())
            }
        })

        screen.display()


    }
}

Remark: Issues seems to be within AWT: KeyEvent also already the wrong character

Multi font support

A new pair of behaviors (FontOverrideSupport and FontOverride) will be introduced.

FontOverrideSupport will be implemented in Layerable, Terminal and Screen while FontOverriede will be implemented in Component, Layer and Terminal.

FontOverrideSupport is an internal interface which is responsible for knowing what Font Size can be used in them (this comes from the TerminalBuilder which a Terminal is built from and can't be changed later).

FontOverride holds a reference to a Font object which will be used when drawing. If you try to add / draw / etc an object which implements FontOverride to an object which implements FontOverrideSupport, the Font's size will be checked against the information in the object implementing FontOverrideSupport. If the Size does not fit the object will throw an exception.

The current rule is that there can be one font Size for each Terminal object and every other object must use Fonts with that size.

As a later feature half-width fonts will be also supported (eg. 16x16 + 8x16).

JavaFx support for terminal

There should be a Terminal implementation which uses JavaFx instead of Swing.

See conversation with Adam:

So this is how it works:
We have a VirtualTerminal class: https://github.com/Hexworks/zircon/blob/master/src/main/kotlin/org/codetome/zircon/internal/terminal/virtual/VirtualTerminal.kt
this handles all the "virtual" aspects of the Terminal interface
including dirty checking, resizing, and modifying its contents (TextCharacters, Layers, etc)
this basically means that you only have to implement the rendering logic if you want to have a JavaFX implementation
but
We have the renderig logic which is common to Java2D implementations in Java2DTerminalImplementation : https://github.com/Hexworks/zircon/blob/master/src/main/kotlin/org/codetome/zircon/internal/terminal/swing/Java2DTerminalImplementation.kt
This class handles the lifecycle of the underlying GUI framework, like onCreated and onDestroyed
and it also handles how drawing happens (cursor, coloring, TextCharacters and such)
and what we have in mind right now is to make this class generic
by extracting all Java2D specific aspects
and using interfaces to represent them
so after this refactor implementing something like a JavaFX version will be much easier

So that issue should be on hold until the mentioned refactoring is done.

Additional built-in Modifiers

Some extra modifiers will be added:

  • GaussianBlur
  • MotionBlur
  • Glow
  • RayShade
  • Sharpen
  • TextShadow

For each parameterized Modifier an accompanying Builder will be added.

Moving the mouse over the left hand side generates exception.

Using a tiled window manager that allows floating windows, when moving the mouse beyond the left hand side it generates the following exception

AWT-EventQueue-0] ERROR org.codetome.zircon.internal.terminal.swing.SwingTerminal$listener$1 - position for mouse event 'java.lang.IllegalArgumentException: A position must have a column and a row number which is greater than or equal to 0!' was out of bounds. It is dropped.
java.lang.IllegalArgumentException: A position must have a column and a row number which is greater than or equal to 0!
	at org.codetome.zircon.api.Position.<init>(Position.kt:14)
	at org.codetome.zircon.api.Position$Companion.of(Position.kt:181)
	at org.codetome.zircon.internal.terminal.swing.TerminalMouseListener.addActionToKeyQueue(TerminalMouseListener.kt:77)
	at org.codetome.zircon.internal.terminal.swing.TerminalMouseListener.mouseExited(TerminalMouseListener.kt:53)
	at java.awt.Component.processMouseEvent(Component.java:6539)
	at java.awt.Component.processEvent(Component.java:6298)
	at java.awt.Component.dispatchEventImpl(Component.java:4889)
	at java.awt.Component.dispatchEvent(Component.java:4711)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
	at java.awt.EventQueue.access$500(EventQueue.java:97)
	at java.awt.EventQueue$3.run(EventQueue.java:709)
	at java.awt.EventQueue$3.run(EventQueue.java:703)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90)
	at java.awt.EventQueue$4.run(EventQueue.java:731)
	at java.awt.EventQueue$4.run(EventQueue.java:729)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

Support for Dwarf Fortress tilesets

Dwarf Fortress tilesets need to be supported.

  • First custom font support needs to be done
  • Then the DF tilesets need to be moved and set up to the project resources
  • Then they should be made available through a custom enum

Screen layering support

The Screen class should support layering. A layer is an additional 2d plane over or under the Screen layer which is drawn accordingly (from bottom to top).
A Layer should be a TextImage and should support all operations defined on it.
A Layer should support visibility toggling.

Bug in TextCharacterString

If a TextCharacterString has a length of 1, it crashes with

at org.codetome.zircon.internal.graphics.DefaultTextCharacterString.drawOnto(DefaultTextCharacterString.kt:35) at org.codetome.zircon.internal.terminal.virtual.VirtualTerminal.draw(VirtualTerminal.kt:66) at org.codetome.zircon.internal.screen.TerminalScreen.draw(TerminalScreen.kt)

(Iterator is exhausted)

Example:

object Sandbox {

    @JvmStatic
    fun main(args: Array<String>) {
        val terminal = TerminalBuilder.newBuilder()
                .initialTerminalSize(Size.of(32, 16))
                .font(CP437TilesetResource.REX_PAINT_18X18.toFont())
                .build();

        val screen = TerminalBuilder.createScreenFor(terminal)

        val stringOfLength1 = "D"
        val textDrawable = TextCharacterStringBuilder.newBuilder()
                .text(stringOfLength1)
                .build()

        screen.draw(textDrawable, Position.of(0,0))

        screen.display()
    }

}

Adding a component to a container which has no font before attaching that container to a Screen leads to font error.

Example:

Exception in thread "main" kotlin.NotImplementedError: An operation is not implemented.
	at org.codetome.zircon.internal.font.impl.FontSettings$NO_FONT$1.getWidth(FontSettings.kt:18)
	at org.codetome.zircon.api.font.Font$DefaultImpls.getSize(Font.kt:45)
	at org.codetome.zircon.internal.font.impl.FontSettings$NO_FONT$1.getSize(FontSettings.kt:11)
	at org.codetome.zircon.internal.component.impl.DefaultContainer.addComponent(DefaultContainer.kt:46)
	at org.codetome.zircon.examples.interactive.ShootingExample.main(ShootingExample.java:91)

This is because the container like a Panel does not have a Font by default. The reason for this is that if we would have had a default font with any size it would have lead to an error if the user would have used a different sized font as our default.
Since the user sets the font for the whole Screen we can't add a component to another container component until a Font is set for it.

This needs to be clarified in the error message above!

Animation Layers

Animations should be specialized Layers. An animation is basically a linked list of Layers which represent some animation. An Animation can be moving, or stationary and consists of frames. Animations should be governed by a simplified GameLoop pattern. Some characteristics:

  • Orientation (enum) <-- this can be STATIONARY or some direction like RIGHT
  • Step time (how much to wait for next frame)
  • Repeat (whether the frames should repeat themselves
  • Auto-remove (whether the Animation should be removed after the last frame

Map Component prototype

A MapComponent is a game-related component which

  • is scrollable, to be able to cover an area which is bigger than a terminal screen
  • can accept an arbitrary backend which supplies the data which should be displayed in the MapComponent. This can be done by writing an interface, MapSegment which abstracts the means of providing TextCharacter and Layer information for the MapComponent.

For the first prototype version an abstraction for a 2D space is desired, but this needs to be extendable to a 3D segment (x, y, z).

README examples problems

I'm trying out examples in the README. First problem: enableModifier is not a function of Terminal. Eg:

terminal.enableModifier(Modifiers.VERTICAL_FLIP);

Component system

A basic component system should be implemented. Depends on:

  • Layering support
  • TextGraphics

First controls to implement:

  • Button
  • CheckBox
  • Label
  • RadioButton
  • TextField
  • Dialog
  • Composite

Character improvements

Characters should support some additional Modifiers like

  • VERTICAL_FLIP
  • HORIZONTAL_FLIP
  • INVISIBLE

Setting the TRANSPARENT background for TextImage does not work

If I run the code below a black background is drawn for the TextImage. This bug should be investigated.

Example:

        final Terminal terminal = TerminalBuilder.newBuilder()
                .font(CP437TilesetResource.REX_PAINT_20X20.toFont())
                .initialTerminalSize(Size.of(10, 5))
                .build();

        final TextImage img = TextImageBuilder.newBuilder()
                .size(Size.of(10, 5))
                .build(); // we create a new image to draw onto the terminal

        img.setForegroundColor(ANSITextColor.WHITE);
        img.setBackgroundColor(TextColorFactory.TRANSPARENT); // `putText` will use these

        BoxBuilder.newBuilder()
                .boxType(BoxType.DOUBLE)
                .size(Size.of(10, 5))
                .style(StyleSetBuilder.newBuilder()
                        .foregroundColor(ANSITextColor.CYAN)
                        .backgroundColor(ANSITextColor.BLUE)
                        .build())
                .build()
                .drawOnto(img, Position.DEFAULT_POSITION); // we create a box and draw it onto the image

        final List<String> logElements = new ArrayList<>();
        logElements.add("foo");
        logElements.add("bar"); // our log entries

        for(int i = 0; i < logElements.size(); i++) {
            img.putText(logElements.get(i), Position.OFFSET_1x1.withRelativeRow(i)); // we have to offset because of the box
        }

        terminal.draw(img, Position.DEFAULT_POSITION); // you have to draw each time the image changes

        terminal.flush();

Result:
image

Player handler for GameComponent

Player handler

A Player handler should be a simple utility for handling the player @ and it should also take into account scrolling.

Rationale

This is a common enough feature for roguelikes.

Suggested way of implementing

A PlayerHandler should handle how the player is added to a GameComponent as a layer (TextImage) and how it should be positioned when the user moves the player to the edges (in this case it won't stay in the center).

Fix and test TextBox

Improvement for TextBox

Current behavior

Currently, the TextBox is not tested and its implementation needs some refurbishment.
Tests should be written for the use cases (including the corner cases) and the implementation should be refactored according to the changes made in Scrollable.

Drag n Drop support

Drag'n drop will work for floating windows in the first implementation.

A FloatingWindow can be dragged when the mouse is pressed anywhere over its DragHandle (an arbitrary region over the component configured by the user) region.

On the drag event the window should be repositioned and its bounds checked with other floating windows.

Related to #23 which will use this
Depends on #24 since it will introduce the layerable stack

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.