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

Overview

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.

Comments
  • Introduce ShutdownHook in Zircon

    Introduce ShutdownHook in Zircon

    I'm using zircon as my main graphics in a game, but when i close the terminal and java exits, The audio thread has not been closed, and is likely still running.I have no direct control over the audio thread, so I can't get the thread to check if it's closed. Could a terminal.onClosed(event), or even just an additional InputType to support "terminal closed" be created?

    enhancement 
    opened by N-Morris 15
  • Occassional incorrect window size

    Occassional incorrect window size

    Bug in window sizing: when starting SwingApplication it sometimes starts smaller

    Expected behavior

    SwingApplication size should have always the same size

    Actual behavior

    With no changes is code, the window is sometimes smaller. Added '#' printing to better show the difference:

    correct incorrect

    Steps to reproduce the bug

    It happens even in the simplest possible config, with about 20% chance:

    fun main() {
        SwingApplications.startApplication()
    }
    

    Environment

    Linux Arch: 5.1.3-arch2-1-ARCH Desktop environment: KDE5 Zircon version: 2019.1.2-PREVIEW

    bug help wanted on hold 
    opened by lonski 14
  • Table control for Zircon

    Table control for Zircon

    Request for a table control

    A simple table control, which displays content in cells. Only basic features and no fancy stuff in the beginning (like cells spanning mutliple columns and so forth)

    Rationale

    • useful for dev tools within Zircon and
    • of course also for games (e.g. inventory, loadout view)

    Suggested way of implementing

    • a cell could embed any Zircon controls and facilitating the usage of text (similar like the log control)
    feature 
    opened by coldwarrl 10
  • Multi font support

    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).

    feature 
    opened by adam-arold 10
  • Maven error: Missing artifact

    Maven error: Missing artifact

    I'm trying to add Maven dependencies zircon-core-jvm 2020.1.0-RELEASE and zircon.jvm.swing 2020.1.0-RELEASE to a new Maven Java project using Eclipse, but an error occurs:

    Missing artifact org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:jar:0.3

    screenshot1 screenshot2

    I'm not good at using Maven. Anytime I need to use Maven, I just follow instructions. So it may be just a silly question.

    opened by milekey 7
  • Redraw the swing terminal on Canvas.paint().

    Redraw the swing terminal on Canvas.paint().

    Fixes #77.

    This creates a private Canvas subclass that invokes an onPaint callback.

    This also removes canvas.ignoreRepaint = true. I remember reading somewhere in the Swing docs (can't seem to find it now) that it recommended canvas.setIgnoreRepaint(true), but I believe this is only necessary for real-time rendering. I'm not sure how zircon handles animations, as this library is still new to me, but it definitely doesn't render in real-time when there are no animations playing, so repainting is needed on some platforms.

    Edit: Do you know if there's any other importance to ignoring repaint?

    opened by ghost 7
  • Implement

    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();
        }
    }
    

    feature 
    opened by William-Lake 7
  • All classes that have builders should lock down their constructors.

    All classes that have builders should lock down their constructors.

    Right now classes like AppConfig and ShortcutsConfig have Builder classes that should be used exclusively for constructing instances of those classes, but this isn't guaranteed because the constructors are public, so users could actually use either. Some functionality, like that introduced in #381, assumes users will be using the Builders. Plus it'd be nice to have one Right Way to do things.

    Potentially every class with a builder in our Builders package needs to be examined, but the builders themselves also need to be examined. AppConfigBuilder, for example, itself has a public constructor.

    The end goal here is for there to be one way to build these things, for simplicity for the builder and to make things easier for the Zircon maintainers. Every public API class in Zircon should conform to one of the following patterns:

    1. It has a public constructor and no builder, or
    2. It has an internal constructor, a corresponding builder class (which itself has an internal constructor), and the way you construct the instance is by calling a public TheClass.newBuilder().build() method.

    Phase 0

    1. Identify all classes/constructors/methods that need updating.
    2. If there's a code style guide, we should add what we're doing to it. If there isn't, we should create one.
    3. (Optional) Look into tools available for Kotlin/Java that document API changes between versions.

    Phase 1

    1. Add a @Deprecated annotation to all constructors/methods that are currently public, but shouldn't be.
    2. Add KDoc to each affected class indicating the recommended way of constructing that class.

    Phase 2 (next major version?)

    1. Remove @Deprecated annotations added in Phase 1.
    2. Make constructors/methods internal that should be.
    enhancement 
    opened by nanodeath 6
  • MouseEventType.MOUSE_WHEEL_ROTATED_UP not getting triggered

    MouseEventType.MOUSE_WHEEL_ROTATED_UP not getting triggered

    Describe the bug MouseEventType.MOUSE_WHEEL_ROTATED_UP is not getting triggered, whereas MouseEventType.MOUSE_WHEEL_ROTATED_DOWN works just fine. I tried both 'handleMouseEvents' and 'processMouseEvents' but nothing seems working.

    To Reproduce Steps to reproduce the behavior:

    1. Go to 'ScrollBarExample.kt' provided in examples
    2. Add handleMouseEvents or processMouseEvents on scrollbar1
    3. Run the example
    4. See if MouseEventType.MOUSE_WHEEL_ROTATED_UP is triggered when scroll wheel is scrolled up

    Expected behavior MouseEventType.MOUSE_WHEEL_ROTATED_UP should be triggered

    Screenshots NONE

    Desktop (please complete the following information):

    • OS: ZorinOS based on Ubuntu 18.04.1
    • JDK Version: OpenJDK version "1.8.0_252"
    • Version: Linux Kernel 5.4.0-42-generic

    Smartphone (please complete the following information): NONE

    Additional context I tried using LibgdxApplications in place of SwingApplications but still same result moreover now MOUSE_WHEEL_ROTATED_DOWN is also broken.

    bug 
    opened by siddhantkumarupmanyu 6
  • Request for feature `MultiSelect`

    Request for feature `MultiSelect`

    Request for feature MultiSelect

    I would like to see a small Component to select one value out of a list of possible values. The typical UI-Element would be a drop down menu, but that would need an overlay for the value list, so the simpler way would be to have a left-button and a right-button to scroll through the values. Or speaking in images, two examples: example gif

    Rationale

    There are quite some Components provided by Zircon but none to have a simple way of selecting one value of a fixed list of possibilities. There are radio buttons, but you have to put those together yourself and it takes a lot of space. When you only have one line and a specific width, the MultiSelect like proposed is an easy solution.

    Suggested way of implementing

    I already implemented it in my project as Fragment, but I would expect it to be available in the Components class. It wouldn't be hard to provide it as both, a Component and a Fragment. I am ready to provide a pull reqeust for this feature soon.

    feature 
    opened by Baret 6
  • Implement the `Group` component

    Implement the `Group` component

    Introduction of a group component

    Current behavior

    Currently it is difficult to apply styles to components, which share the same semantics but are not under the same panel or generally speaking, share the same component hierarchy.

    Improved behavior

    You can use a group component to group components together, which share common properties, like styles.

    Suggested way of achieving the improvement

    The group component shall be invisible but else act as a standard container.

    feature 
    opened by coldwarrl 6
  • Windows 10 Coroutine `ConcurrentModificationException` and White Screen Flickering

    Windows 10 Coroutine `ConcurrentModificationException` and White Screen Flickering

    Describe the bug A ConcurrentModificationException from the ArrayList data structure when running. (Also, the screen is 90% of the time completely white when I try running the project on Windows, but fine and doesn't run into any of these issues on my Mac).

    To Reproduce I'm following the Caves of Zircon tutorial right now, and I'm about halfway through Part 11, so:

    1. Clone my progress at https://github.com/fancyplants/zircon-tut
    2. Run the game as usual (there's also a bigger issue that the window most of the time is completely white in both PlayView and StartView.
    3. Press movement keys and see this exception get thrown in a coroutine.
    4. Note: the game still continues running after this point (but it is hard to tell, since the screen is white most of the time as well).
    checkForComodification:1013, ArrayList$Itr (java.util)
    next:967, ArrayList$Itr (java.util)
    filterTo:805, TurnBasedEngine$executeTurn$1 (org.hexworks.amethyst.internal)
    filter:714, TurnBasedEngine$executeTurn$1 (org.hexworks.amethyst.internal)
    invokeSuspend:22, TurnBasedEngine$executeTurn$1 (org.hexworks.amethyst.internal)
    lambda 'with' in 'resumeWith':33, BaseContinuationImpl (kotlin.coroutines.jvm.internal)
    resumeWith:29, BaseContinuationImpl (kotlin.coroutines.jvm.internal)
    lambda 'withCoroutineContext' in 'run':56, DispatchedTask (kotlinx.coroutines)
    withCoroutineContext:45, DispatchedTask (kotlinx.coroutines)
    run:42, DispatchedTask (kotlinx.coroutines)
    runSafely:571, CoroutineScheduler (kotlinx.coroutines.scheduling)
    executeTask:738, CoroutineScheduler$Worker (kotlinx.coroutines.scheduling)
    runWorker:678, CoroutineScheduler$Worker (kotlinx.coroutines.scheduling)
    run:665, CoroutineScheduler$Worker (kotlinx.coroutines.scheduling)
    

    Expected behavior I expect it to run nominally on Windows the same way it runs on Mac (no screen flickering, no exceptions), but it does not.

    Screenshots What the game looks like most of the time: image

    I try to take a screenshot of the game nominally, but as soon as I get a good frame for a few seconds it reverts back to a white screen.

    Desktop (please complete the following information):

    • OS: Windows 10
    • Version 19043.2130

    Additional context Let me know if there's any other way I can help (more info, a live debug session, or even guidance on how I can fix this myself and submit the fix to the repository), since I've tried a bunch of different ways to make roguelikes and this is the one I wanna build my first game idea on!

    opened by fancyplants 0
  • java.lang.InterruptedException when holding down key

    java.lang.InterruptedException when holding down key

    When running the code from PlayerMoveExampleJava.java, I consistently get this exception.

    To reproduce, start the program and hold a direction key (e.g. left) so the character moves all the way across the screen, switch to the other direction if you get near the edge of the screen.

    Within maybe 10-20 seconds of holding down a key like this, the exception will be thrown.

    [DefaultDispatcher-worker-1] ERROR SwingApplication - Render failed
    java.lang.InterruptedException
            at java.base/java.util.concurrent.FutureTask.awaitDone(FutureTask.java:418)
            at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:190)
            at co.touchlab.stately.isolate.BackgroundStateRunner.stateRun(BackgroundStateRunner.kt:18)
            at co.touchlab.stately.isolate.IsoStateKt.createState(IsoState.kt:49)
            at co.touchlab.stately.collections.IsoMutableMap.<init>(IsoMutableMap.kt:8)
            at co.touchlab.stately.collections.IsoMutableMap.<init>(IsoMutableMap.kt:7)
            at io.github.reactivecircus.cache4k.RealCache.<init>(RealCache.kt:39)
            at io.github.reactivecircus.cache4k.RealCache.<init>(RealCache.kt)
            at io.github.reactivecircus.cache4k.CacheBuilderImpl.build(Cache.kt:141)
            at org.hexworks.zircon.internal.util.DefaultCache.<init>(DefaultCache.kt:17)
            at org.hexworks.zircon.internal.util.DefaultCache.<init>(DefaultCache.kt)
            at org.hexworks.zircon.internal.util.DefaultCache.<init>(DefaultCache.kt:9)
            at org.hexworks.zircon.api.util.Cache$Companion.create(Cache.kt:35)
            at org.hexworks.zircon.api.tileset.base.BaseCP437Tileset.<init>(BaseCP437Tileset.kt:42)
            at org.hexworks.zircon.internal.tileset.Java2DCP437Tileset.<init>(Java2DCP437Tileset.kt:27)
            at org.hexworks.zircon.api.SwingApplications$createDefaultFactories$1$1.invoke(SwingApplications.kt:200)
            at org.hexworks.zircon.api.SwingApplications$createDefaultFactories$1$1.invoke(SwingApplications.kt:199)
            at org.hexworks.zircon.internal.tileset.impl.DefaultTilesetFactory.create(DefaultTilesetFactory.kt:16)
            at org.hexworks.zircon.internal.tileset.impl.DefaultTilesetLoader.loadTilesetFrom(DefaultTilesetLoader.kt:26)
            at org.hexworks.zircon.internal.renderer.SwingCanvasRenderer.drawTiles(SwingCanvasRenderer.kt:192)
            at org.hexworks.zircon.internal.renderer.SwingCanvasRenderer.render(SwingCanvasRenderer.kt:150)
            at org.hexworks.zircon.internal.application.impl.BaseApplication.doRender(BaseApplication.kt:130)
            at org.hexworks.zircon.internal.application.impl.BaseApplication.access$doRender(BaseApplication.kt:23)
            at org.hexworks.zircon.internal.application.impl.BaseApplication$startRenderLoop$1.invokeSuspend(BaseApplication.kt:77)
            at org.hexworks.zircon.internal.application.impl.BaseApplication$startRenderLoop$1.invoke(BaseApplication.kt)
            at org.hexworks.zircon.internal.application.impl.BaseApplication$startRenderLoop$1.invoke(BaseApplication.kt)
            at org.hexworks.zircon.internal.application.impl.BaseApplication$1.invokeSuspend(BaseApplication.kt:52)
            at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
            at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
            at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
            at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
            at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
            at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
    
    opened by fooberticus 0
  • EventBus Usage in Caves of Zircon

    EventBus Usage in Caves of Zircon

    Is your feature request related to a problem? Please describe. The event bus was moved from the singleton object Zircon and onto the application state instead. I am following the cavesofzircon tutorial and I am trying to figure out how to create the logging system using the event bus

    Describe the solution you'd like A way to have the application be a singleton in the game

    Describe alternatives you've considered I was going to create a singleton class myself that just slapped the app into it and just query from there, but it seems rudimental and wrong

    opened by lecoqjacob 0
  • Decouple Scrollable views from GameArea

    Decouple Scrollable views from GameArea

    Is your feature request related to a problem? Please describe. GameArea instances currently hold data about the world (GameBlock collection) as well as the view. (Scrollable) This means that if you need to change the view, you need to copy whole object with the complete GameBlock data.

    Describe the solution you'd like I propose to separate GameArea from the Scrollable implementation:

    • Add a GameAreaView or GameAreaCamera, that handles the Scrollable logic, but does not hold any world data and only points to an existing GameArea
    • Either remove the Scrollable interface from GameArea, or give each GameArea a default view/camera to preserve backwards compatibility
    • Let GameAreaComponentRenderer take a view/camera instead of a GameArea

    Describe alternatives you've considered Making the visible part of a GameArea dynamically resizable would also mean that the world data does not have to be copied, but this would miss out on the cool features listed below. While making the views/cameras resizable would also not hurt, the decoupling makes it fairly easy to create a new view/camera, so the actual resizing support can go down in priority.

    Additional context This separation would enable a lot of cool picture-in-picture game features, for example:

    • Item description panels can include an extra 5by5 view of the item and its surroundings, that also updates the same way as the main view.
    • Follow-cams for characters. Surveillance simulator, anyone?
    • Dialogue boxes showing the character you speak to, maybe even using a different projectionMode than the main view.
    opened by LostMekka 0
  • Remove Java code from the core module

    Remove Java code from the core module

    This is a prerequisite for making Zircon truly multi-platform. All code in the jvmMain module needs to be reviewed and either needs to go to commonMain to the platform package or should be left there if it is only for jvm (File handling for example).

    enhancement 
    opened by adam-arold 0
Releases(2020.2.0-RELEASE)
  • 2020.2.0-RELEASE(Dec 12, 2020)

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

    If you are not yet familiar with the project take a look at our Project Page.

    The kdocs can be found here. Javadocs are also coming soon!

    You can grab this release from Maven Central here. More on how to add Zircon as a dependency to your project can be found here.

    Also if you have any questions about this release, feel free to come up to our Discord Server and ask them!

    TL;DR For the Impatient:

    Highlights of this release

    This was a very busy year for us. After the previous release we started focusing on the internals of Zircon. Previously we didn't have an FPS goal nor performance optimizations in the code. The Swing benchmark was running with ~60 FPS with a 80x24 grid and 16x16 tiles. If someone used a full HD screen it was significantly slower, so we added some optimizations. Right now with a full HD screen and 16x16 tiles (that's a size of 120x67) Zircon runs with ~100 FPS in the benchmarks. This means that we achieved a ~8x speedup! The goal for the next release is to have 100 FPS with 8x8 tiles.

    This performance optimization was made possible by some internal refactorings. The rendering model was modified in a way that the renderer no longer queries the state of the TileGrid, but lets all individual Layers and Components render themselves. This also means that internal state is no longer stored in Components, they are rendered whenever it is necessary instead.

    There is also a FastTileGraphics implementation that enables this optimization. It uses an Array internally and it is significantly faster than the old TileGraphics that was using a PersistentList.

    Zircon now also supports StackedTiles. a StackedTile is a composite that has a stack of Tiles within it. This is very useful to create composite tile objects and also for rendering. It also enables the Component system (and the GameArea) to be significantly easier to implement. It is is not yet clear what stacking means take a look at this screenshot!

    There are some new prototypes as well. One of them is an Android renderer!

    Many of you were looking for Javadocs so we also added this to the project! You can find it here. This is kdocs (Kotlin Docs) for now, but soon we'll add proper Javadocs as well! We also started to add code samples within the docs, so you'll be able to see what's what without having to navigate away.

    We also started a proper depreciation cycle now, that Zircon has a significant userbase. When we deprecate something it will be annotated with the @Deprecated annotation, and these things will get removed in the next release. We also documented (in the source code) what to use instead of the things we're going to remove.

    The GameArea received some refurbishments as well. Now the GameArea is rendered using a simple ComponentRenderer which means that you can use any Component for rendering a GameArea. This also means that this component can be a Container and can have additional children! Another addition to the GameArea is filtering. Now you can add filters to a GameArea that looks similar to a Modifier, but it has more parameters including the Position3D of the Block that's being modified in the GameArea. One useful example for this is to implement depth and distance filters. In this example there is a depth filter. The pyramid's colors are all the same, but the filter changes front and top tiles to add a visual effect, and also makes blocks that have a lower z level appear darker. This is how a building looks like with a filter applied.

    Another thing you might have noticed fromt he GIF is that now you can switch between projections on the fly. You can also see it in action in this map generation example.

    We usually refurbish the ColorThemes with each release and this one is no different. There are some now ones as you can see in this example. You can also use them in your games.

    You can now add padding to your Components. Padding is implemented with a ComponentDecoration so it can be added to any component, and it looks like this.

    With this release now we have almost everything in place to implement the rest of the backlog! Here are some prototypes for what's going to be added to the next release including some Fragments that you were waiting for a while now!

    Here is a full list of issues we finished for this release:

    New Features

    • #360: Enable the ModalComponentContainer to try dispatching UIEvents to multiple containers if a container returns Pass
    • #357: Add the option to add padding to a component
    • #355: Add the option to keep the Component's properties when it is attached.
    • #350: Create a filtering mechanism for the GameArea that would enable adding effects to individual Blocks.
    • #359: Enable multiple Fragments to be added to a Container in one go.
    • #91: Add frame rate limiting capability
    • #348: Add a function that will create a TileBuilder out of a Tile
    • #349: Add a function that will create a BlockBuilder out of a Block
    • #339: Create a Tile implementation that's composed of multiple Tiles.
    • #297: Set application icon
    • #299: Create matchers for UIEvents
    • #315: New Fragment: TilesetSelector and ColorThemeSelector
    • #300: Enable the user to set default keyboard shortcuts
    • #296: Add callbacks for Rendering

    Enhancements

    • #345: Document all the API classes properly
    • #325: Create docs pages for each release using Dokka
    • #329: Make Layer implement Layerable
    • #328: Refactor Components to be Layers
    • #353: Use fun interfaces where applicable
    • #352: Refactor builders to use prototypes with defaults.
    • #146: Generate javadoc (Dokka) during build and deploy it to a site
    • #344: Harmonize mutable and accessor mixin names.
    • #338: Optimize Rendering Performance
    • #327: Use a push model instead of a pull one for rendering
    • #332: Checkbox - Alignment & Text
    • #319: Size3d#containsPosition(position: Position3D) should also check for negative values
    • #318: Add new Color Themes
    • #308: Refactor Internal State handling to use Properties
    • #87: Review tint, shade and tone in TileColor

    Bug fixes

    • #336: Moving a Component with anything other than moveTo can lead to failed bounds check
    • #316: RectangleFactory (possibly others, too) ignores shape position
    • #321: MouseEventType.MOUSE_WHEEL_ROTATED_UP not getting triggered
    • #311: Components are not visible in AllComponentsExampleJava
    • #307: Clean up tilesets
    • #305: Libgdx not working in 2020.0.2-PREVIEW
    • #304: Clearing a TileGrid breaks draw operations
    • #230: Occassional incorrect window size
    • #341: Fix the rendering logic in GameArea
    • #302: Blocks are not rendered properly in a GameArea when tiles are not opaque.
    • #277: Hiding with transforming is leaving black background in LayerTransformerExample
    • #301: Component remains activated when space is pressed and focus is lost (pressing Tab)
    • #298: Focus handling keys don't work when using LibGDX

    Road Map

    We've covered a lot of ground in this release, but there are still things to do:

    Credits

    Thank you for all of you out there who helped with this release! Special thanks to Baret, Bergin, Coldwarrl, Luke and Seveen for their contributions!

    Contribute

    If you think that you can contribute or just have an idea feel free to join the discussion on our Discord server.

    Source code(tar.gz)
    Source code(zip)
  • 2020.1.6-HOTFIX(Nov 7, 2020)

  • 2020.1.0-RELEASE(Nov 7, 2020)

  • 2018.3.0-PREVIEW(Aug 9, 2018)

Owner
Hexworks
Hexworks is a friendly bunch of developers and artists who focus on providing multiplatform open source libraries and tools.
Hexworks
An extensible multilanguage static code analyzer.

PMD - source code analyzer PMD is a source code analyzer. It finds common programming flaws like unused variables, empty catch blocks, unnecessary obj

PMD 4.1k Dec 29, 2022
Helper functions for making Approvals-Java more Kotlin friendly

Approvals-Kt Helper functions for making Approvals-Java more Kotlin-friendly Usage Verify using Approvals-Kt import com.github.greghynds.approvals.Kot

Greg Hynds 2 Oct 18, 2021
A TODO list app with location reminders that remind the user to do something when the user is at a specific location

Project Title Location Reminder Getting Started A TODO list app with location reminders that remind the user to do something when the user is at a spe

Raghav Saboo 0 Dec 5, 2021
A Hello World and Template for the KorGe game engine

Korge Hello World and Template This is a Hello World and Template for the KorGe game engine. Using gradle with kotlin-dsl. You can open this project i

Kiet 0 May 1, 2022
A sample skeleton backend app built using Spring Boot kotlin, Expedia Kotlin Graphql, Reactive Web that can be deployed to Google App Engine Flexible environmennt

spring-kotlin-gql-gae This is a sample skeleton of a backend app that was built using: Spring Boot(Kotlin) Reactive Web Sprinng Data R2DBC with MYSQL

Dario Mungoi 7 Sep 17, 2022
Image Processing Engine with GUI

Image Processing Engine with GUI Imperial College London Department of Computing Third Year Software Engineer Group Project Supervisor: Dr. Pancham Sh

null 1 Jan 14, 2022
My own approach to what I think an Android MVVM project with Clean Architecture should look like with Dagger-Hilt as Dependency Injector engine

MVVM Project Hilt Introducción Este proyecto es mi visión particular, ni mejor ni peor (sólo una más) que cualquier otra aproximación a lo que yo enti

Antonio Fdez. Alabarce 7 Dec 16, 2022
Jetpack Compose for Desktop and Web, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.

Jetpack Compose for Desktop and Web, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.

JetBrains 10k Jan 7, 2023
The app is composed of 2 screens, first is the profile screen, it has the user_name and address pinned at the top and then it lists all of this user’s albums.

The app is composed of 2 screens, first is the profile screen, it has the user_name and address pinned at the top and then it lists all of this user’s albums. When you press on any album it navigates to the second screen which is an album details screen that contains list of the images in an recyclerview grid. Also you have search bar that you can filter within the photos album by the image title.

Mahmoud Ibrahim 4 Jul 10, 2022
A webapp which generates a simple Discord profile banner image in real-time which shows user's status and activity.

DiscordProfileBanner This tool generates a Discord profile banner image in realtime. I wrote it for use in my AniList profile. An example in action: H

Quanta 11 Oct 17, 2022
myMaps displays a list of maps, each of which show user-defined markers with a title, description, and location.

My Maps Trevor Carrell myMaps displays a list of maps, each of which show user-defined markers with a title, description, and location. The user can a

null 0 Nov 1, 2021
An application that allows the user to update variety of smartphones that are used such as iPhone and Android

PhoneApplication An application that allows the user to update variety of smartphones such as iPhone and Android. This application allows users to add

Pankaj Singh 1 Nov 28, 2021
A simple App which fetches data from NewYork times api and show news to the user

Stay-TheNewsApp This is a simple java app, which fetches data from NewYork times api and show news to the user, News can be seen from various categori

Gautam Garg 0 Dec 7, 2021
Github User App for searching Github Users and get several information from it.

GithubUserApp Github User App for searching Github Users and get several information from it. This code implement with Coroutines, Retrofit, Architect

Wahyu Hendiarto W. 0 Apr 16, 2022
Task Manager feat. real-time competitive system and user engagement

Dira Что из себя представляет Dira? Android-приложение Directa (сокр. Dira) - это планер, который способен улучшить жизнь пользователей. Он позволяет

Konstantin Albatov 4 Sep 28, 2022
This Kotlin Multiplatform library is for accessing the TMDB API to get movie and TV show content. Using for Android, iOS, and JS projects.

Website | Forum | Documentation | TMDb 3 API Get movie and TV show content from TMDb in a fast and simple way. TMDb API This library gives access to T

Moviebase 37 Dec 29, 2022
:blue_book: A diary application optimized for user experience.

Easy Diary README of Korean(한국어) This is a diary application optimized for user experience. Demo videos Basic function preview Support Features 01. Wr

Bulbasaur 316 Jan 1, 2023
An Online Meme Sharing app with swipeable vidoes, user can like, share different videos, each viewpager item has one video to show.

MemesSharing An Online Meme Sharing app with swipeable vidoes, user can like, share different videos, each viewpager item has one video to show. 1. Fl

Vikas Bajpayee 13 Aug 6, 2022
A server which delivers client configuration settings to an end-user over http.

RuneTopic HTTP Server A server which delivers client configuration settings to an end-user over http. Setup Guide You can host a http server with Dock

Runetopic 2 Dec 1, 2021