Initial Commit
This commit is contained in:
65
.gitignore
vendored
Normal file
65
.gitignore
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
### Intellij ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
bin/
|
||||
|
||||
# User-specific stuff:
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/dictionaries
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.xml
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# CMake
|
||||
cmake-build-debug/
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.iws
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# IntelliJ
|
||||
/out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
### Intellij Patch ###
|
||||
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
|
||||
|
||||
# *.iml
|
||||
# modules.xml
|
||||
# .idea/misc.xml
|
||||
# *.ipr
|
||||
|
||||
# Sonarlint plugin
|
||||
.idea/sonarlint
|
||||
|
||||
# End of https://www.gitignore.io/api/intellij
|
||||
22
.idea/TileGameEditor.iml
generated
Normal file
22
.idea/TileGameEditor.iml
generated
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/res" type="java-resource" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="docs" level="project" />
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$MODULE_DIR$/../../../Libraries/Java/PCollections/build/libs/pcollections-2.1.3-SNAPSHOT.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
</component>
|
||||
</module>
|
||||
6
.idea/misc.xml
generated
Normal file
6
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="false" project-jdk-name="1.8 (1)" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/bin" />
|
||||
</component>
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/TileGameEditor.iml" filepath="$PROJECT_DIR$/.idea/TileGameEditor.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
121
DesignDocument.txt
Normal file
121
DesignDocument.txt
Normal file
@@ -0,0 +1,121 @@
|
||||
Design Document for Nytework Tile Engine Version 0.1.0
|
||||
|
||||
This document describes the theoretical design of the Nytework Tile Engine,
|
||||
Version 0.1.0. This Document was initially written by Aaron Helton, on July
|
||||
10th, 2017.
|
||||
|
||||
The Nytework Tile Engine is designed primarily for four main component pieces.
|
||||
The first two pieces describe the two different, physical pieces of software.
|
||||
These are the Editor, and the Interpreter. The other two pieces describe the
|
||||
Engine Implementation, and are colloquially known as the Upper Engine (UE) and
|
||||
the Lower Engine (LE).
|
||||
|
||||
Physical Softare
|
||||
|
||||
The Nytework Tile Engine has two main pieces of software. The first is the
|
||||
Editor, which is responsible for creating and working with elements of the Upper
|
||||
Engine, hereon referred to as the UE.
|
||||
|
||||
Editor
|
||||
The Editor is what allows potential RPG Game Creators to interface with
|
||||
the Nytework Tile Engine's Upper Layer, where much of the game-specific
|
||||
logic is designed, implemented, and tested. The Editor allows Game
|
||||
Developers and Designers alike to collaborate on Games, which are
|
||||
represented in a file format known simply as the NTE format, which is the
|
||||
format in which individual are distributed and run. This format is described
|
||||
later in the Design Document.
|
||||
|
||||
The Editor is different from the Interpreter, in that, individual games
|
||||
cannot be "run" from the editor, and the editor does not implement the logic
|
||||
necessary for the game to actually interface with the host operating system.
|
||||
Instead, the editor is primarily focused on the more abstract part of creating
|
||||
the actual game, and as such provides tools, utilities, and functionality
|
||||
related specifically to designing, creating, debugging, and releasing these
|
||||
games. The Editor does, however, provide the capability to execute the
|
||||
interpreter with the WIP Game, so that functionality is not lost.
|
||||
|
||||
The Editor UI consists of a few, relatively simple elements. The center of
|
||||
the Editor is always dominated by the whatever TileMap is currently being
|
||||
worked on. Everything else, however, is configurable. Other elements of the
|
||||
editor are presented in "docks", which can be freely moved about, removed,
|
||||
expanded or shrunk, or added. These docks each provides various utilities
|
||||
for editing portions of the TileMap, the Tiles themselves, the Quests
|
||||
subsystem, the Actor Subsystem, or any other configurable portion of the
|
||||
Upper Engine.
|
||||
|
||||
|
||||
The Lower Engine
|
||||
The Lower Engine is primarily implemented in the Interperter (See:
|
||||
Interperter), and is focused primarly on communicating with the host system.
|
||||
It is the implementation of the various subsystems that the Upper Engine may
|
||||
utilize, such at the Actor Subsystem, Tile Subsystem, and the Quest
|
||||
Subsystem. Much of the functionality is focused on providing a basis
|
||||
specifically for RPG games.
|
||||
|
||||
The Lower Engine is responsible for the providing the environment,
|
||||
libraries, tools, and any other utilities needed for the execution of Upper
|
||||
Engine scripts. The Lower Engine directly interfaces with the host system to
|
||||
create all the graphics necessary to render scenes as specified by the Upper
|
||||
Engine.
|
||||
|
||||
The Lower Engine also managed some higher-level functionality that can't be
|
||||
easily accomplished by the UE, such as swapping out the current map,
|
||||
scrolling the screen, etc.
|
||||
|
||||
+--------------------------------------------------------------------------+
|
||||
| Lower Engine |
|
||||
+--------------------------------------------------------------------------+
|
||||
| Quest Subsystem |
|
||||
+--------------------------------------------------------------------------+
|
||||
| Map Subsystem | |
|
||||
+------------------------------+-------------------------------+ |
|
||||
| Actor Subsystem | Tile Subsystem | Networking|
|
||||
+--------------------------------------------------------------+ |
|
||||
|File IO | Image Manipulation | Configuration | Error Handling | |
|
||||
+--------------------------------------------------------------------------+
|
||||
Fig 1.
|
||||
|
||||
|
||||
The Interpreter
|
||||
The Interpreter is the implementation of the Lower Engine, and is the piece
|
||||
of software used to execute NTE games from .NTE files. It does this by first
|
||||
indexing the NTE file to generate a Virtual File System that can be used by
|
||||
the game for IO Purposes. Once the resources have been indexed,
|
||||
|
||||
|
||||
|
||||
|
||||
NTE File Spec:
|
||||
NTE is a PKZIP file format that contains the following standard entries:
|
||||
|
||||
Main.yaml -> Describes various global properties about the game, such
|
||||
as its name, version, creators/credits, and what to do
|
||||
at game startup based on various boolean entries.
|
||||
|
||||
Contents.yaml -> Contains a generated list of game resources, which
|
||||
is used by the interpreter to build an index for
|
||||
the game's VFS.
|
||||
|
||||
Maps.yaml -> Contains a list of the maps, providing their UUID and
|
||||
|
||||
|
||||
|
||||
Interpreter Process:
|
||||
|
||||
Startup
|
||||
Read and Unzip .NTE file.
|
||||
Read Main.yaml and set various global properties
|
||||
Read Contents.yaml and create a VFS Index
|
||||
|
||||
If Main.yaml specified a Splash Screen:
|
||||
Load Resources/Splash.png and display as specified size.
|
||||
If Main.yaml specified to show Splash Progress:
|
||||
Display progress of loading according to settings in Main.yaml
|
||||
|
||||
Read Maps.yaml and generate Map Index
|
||||
Read Actors.yaml and generate Actor Index
|
||||
Read Quests.yaml and generate Quest Index
|
||||
Read Scripts.yaml and generate a Script Index
|
||||
|
||||
Once all indexes have been generated, load the Title Screen.
|
||||
|
||||
11
TileGameEditor.iml
Normal file
11
TileGameEditor.iml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
BIN
res/Water.png
Normal file
BIN
res/Water.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
124
src/com/aargonian/com/aargonian/tile/TileImpl.java
Normal file
124
src/com/aargonian/com/aargonian/tile/TileImpl.java
Normal file
@@ -0,0 +1,124 @@
|
||||
package com.aargonian.com.aargonian.tile;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.pcollections.HashPMap;
|
||||
import org.pcollections.HashTreePMap;
|
||||
|
||||
/**
|
||||
* Created by aargonian on 7/4/17.
|
||||
*/
|
||||
public class TileImpl
|
||||
{
|
||||
/**
|
||||
* Very important magic string values used by the tile class for common properties/values
|
||||
*/
|
||||
public static final String PROPERTY_TILETYPE = "TileType";
|
||||
public static final String PROPERTY_IMG = "ImageRef";
|
||||
public static final String VALUE_TRUE = "True";
|
||||
public static final String VALUE_FALSE = "False";
|
||||
|
||||
private final HashPMap<String, String> properties;
|
||||
private final HashPMap<String, Object> resources;
|
||||
private int hash = 0;
|
||||
|
||||
public TileImpl(Map<String, String> startingProperties, Map<String, Object> startingResources)
|
||||
{
|
||||
if(startingProperties != null && startingProperties.size() > 0)
|
||||
this.properties = HashTreePMap.from(startingProperties);
|
||||
else
|
||||
this.properties = null;
|
||||
|
||||
if(startingResources != null && startingResources.size() > 0)
|
||||
this.resources = HashTreePMap.from(startingResources);
|
||||
else
|
||||
this.resources = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
TileImpl tile = (TileImpl) o;
|
||||
|
||||
if (properties != null ? !properties.equals(tile.properties) : tile.properties != null) return false;
|
||||
return resources != null ? resources.equals(tile.resources) : tile.resources == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = hash;
|
||||
if(result == 0) {
|
||||
result = properties != null ? properties.hashCode() : 0;
|
||||
result = 31 * result + (resources != null ? resources.hashCode() : 0);
|
||||
hash = result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private TileImpl(HashPMap<String, String> implProperties, HashPMap<String, Object> implResources)
|
||||
{
|
||||
this.properties = implProperties;
|
||||
this.resources = implResources;
|
||||
}
|
||||
|
||||
public TileImpl removeProperty(String property)
|
||||
{
|
||||
if(properties == null)
|
||||
return this;
|
||||
return new TileImpl(properties.minus(property), resources);
|
||||
}
|
||||
|
||||
public String getProperty(String property)
|
||||
{
|
||||
if(properties == null)
|
||||
return null;
|
||||
return properties.get(property);
|
||||
}
|
||||
|
||||
public TileImpl setProperty(String property, String value)
|
||||
{
|
||||
if(properties == null)
|
||||
return new TileImpl(HashTreePMap.singleton(property, value), resources);
|
||||
return new TileImpl(properties.plus(property, value), resources);
|
||||
}
|
||||
|
||||
public boolean hasProperty(String property)
|
||||
{
|
||||
if(properties == null)
|
||||
return false;
|
||||
return properties.containsKey(property) && properties.get(property) != null;
|
||||
}
|
||||
|
||||
public TileImpl removeResource(String resource)
|
||||
{
|
||||
if(resources == null)
|
||||
return this;
|
||||
return new TileImpl(properties, resources.minus(resource));
|
||||
}
|
||||
|
||||
public Object getResource(String resource)
|
||||
{
|
||||
if(resources == null)
|
||||
return null;
|
||||
return resources.get(resource);
|
||||
}
|
||||
|
||||
public TileImpl setResource(String resourceKey, Object resource)
|
||||
{
|
||||
if(resources == null)
|
||||
return new TileImpl(properties, HashTreePMap.singleton(resourceKey, resource));
|
||||
return new TileImpl(properties, resources.plus(resourceKey, resource));
|
||||
}
|
||||
|
||||
public boolean hasResource(String resourceKey)
|
||||
{
|
||||
if(resources == null)
|
||||
return false;
|
||||
return resources.containsKey(resourceKey) && resources.get(resourceKey) != null;
|
||||
}
|
||||
|
||||
}
|
||||
124
src/com/aargonian/com/aargonian/tile/TileMap.java
Normal file
124
src/com/aargonian/com/aargonian/tile/TileMap.java
Normal file
@@ -0,0 +1,124 @@
|
||||
package com.aargonian.com.aargonian.tile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Created by aargonian on 7/4/17.
|
||||
*/
|
||||
public class TileMap
|
||||
{
|
||||
private int rows;
|
||||
private int columns;
|
||||
|
||||
private final ArrayList<TileImpl> tilesImplementations;
|
||||
private final Tile[] tiles;
|
||||
|
||||
public TileMap(int columns, int rows)
|
||||
{
|
||||
this.columns = columns;
|
||||
this.rows = rows;
|
||||
tilesImplementations = new ArrayList<TileImpl>();
|
||||
tilesImplementations.add(new TileImpl(null, null));
|
||||
tilesImplementations.get(0).setProperty(TileImpl.PROPERTY_TILETYPE, "EmptyTile");
|
||||
tiles = new Tile[columns * rows];
|
||||
for(int i = 0; i < tiles.length; i++)
|
||||
{
|
||||
tiles[i] = new Tile(tilesImplementations.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
public void addTileImplementation(TileImpl impl)
|
||||
{
|
||||
tilesImplementations.add(impl);
|
||||
}
|
||||
|
||||
public ArrayList<TileImpl> getTileImplementations()
|
||||
{
|
||||
return tilesImplementations;
|
||||
}
|
||||
|
||||
public int getRows() {
|
||||
return rows;
|
||||
}
|
||||
public int getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
private final void setTileImplementation(Tile tile, TileImpl newImpl)
|
||||
{
|
||||
for(TileImpl implementation : tilesImplementations)
|
||||
{
|
||||
if(implementation.hashCode() == newImpl.hashCode())
|
||||
{
|
||||
if(implementation.equals(newImpl))
|
||||
{
|
||||
tile.setTileImplementation(implementation);
|
||||
newImpl = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
//For loop found no duplicates. Add the new implementation to the list.
|
||||
tilesImplementations.add(newImpl);
|
||||
tile.setTileImplementation(newImpl);
|
||||
}
|
||||
|
||||
public String getTilePropertyAt(String property, int x, int y)
|
||||
{
|
||||
return tiles[(y * columns) + x].getTileImplementation().getProperty(property);
|
||||
}
|
||||
|
||||
public void setTilePropertyAt(String property, String value, int x, int y)
|
||||
{
|
||||
Tile tile = tiles[(y*columns) + x];
|
||||
TileImpl newImpl = tile.getTileImplementation().setProperty(property, value);
|
||||
setTileImplementation(tile, newImpl);
|
||||
}
|
||||
|
||||
public Object getTileResourceAt(String resource, int x, int y)
|
||||
{
|
||||
return tiles[(y*columns) + x].getTileImplementation().getResource(resource);
|
||||
}
|
||||
|
||||
public void setTileResourceAt(String resourceKey, Object resource, int x, int y)
|
||||
{
|
||||
Tile tile = tiles[(y*columns)+x];
|
||||
TileImpl newImpl = tile.getTileImplementation().setResource(resourceKey, resource);
|
||||
setTileImplementation(tile, newImpl);
|
||||
}
|
||||
|
||||
private final class Tile
|
||||
{
|
||||
private TileImpl implementation;
|
||||
|
||||
public Tile(TileImpl impl)
|
||||
{
|
||||
this.implementation = impl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
Tile tile = (Tile) o;
|
||||
|
||||
return implementation.equals(tile.implementation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return implementation.hashCode();
|
||||
}
|
||||
|
||||
public void setTileImplementation(TileImpl impl)
|
||||
{
|
||||
this.implementation = impl;
|
||||
}
|
||||
|
||||
public TileImpl getTileImplementation()
|
||||
{
|
||||
return this.implementation;
|
||||
}
|
||||
}
|
||||
}
|
||||
37
src/com/aargonian/editor/EditableTileSheet.java
Normal file
37
src/com/aargonian/editor/EditableTileSheet.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package com.aargonian.editor;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by aargonian on 7/13/17.
|
||||
*
|
||||
* The EditableTileSheet Class is an implementation for a collection of Tiles arranged within a Sheet, as used by the editing
|
||||
* program. Although this can be thought of in the traditional TileSheet sense (and in fact, a TileSheet can be
|
||||
* constructed from a TileSheetReader from an actual TileSheet image), the EditableTileSheet is mutable, and doesn't
|
||||
* keep each tile instance as a subimage within a larger sheet, unless written out by a TileSheetWriter. Instead,
|
||||
* individual tile images can be added or removed from the set at will.
|
||||
*
|
||||
*/
|
||||
public class EditableTileSheet
|
||||
{
|
||||
/*
|
||||
* An EditableTileSheet is the backing model for the TileSheets dock of the editor, and as such implements the Observer
|
||||
* pattern for the sake of a cleaner MVC implementation.
|
||||
*/
|
||||
private final List<Image> tileImages;
|
||||
|
||||
/**
|
||||
* Creates an empty EditableTileSheet.
|
||||
*/
|
||||
public EditableTileSheet()
|
||||
{
|
||||
tileImages = new ArrayList<Image>();
|
||||
}
|
||||
|
||||
public EditableTileSheet(List<Image> tileImages)
|
||||
{
|
||||
this.tileImages = tileImages;
|
||||
}
|
||||
}
|
||||
83
src/com/aargonian/editor/GameFrame.java
Normal file
83
src/com/aargonian/editor/GameFrame.java
Normal file
@@ -0,0 +1,83 @@
|
||||
package com.aargonian.editor;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Created by aargonian on 7/8/17.
|
||||
*/
|
||||
public class GameFrame {
|
||||
public static final String PROG_TITLE = "TileEditor 0.1.0";
|
||||
|
||||
public static void main(String[] args) {
|
||||
EventQueue.invokeLater(() ->
|
||||
{
|
||||
GameFrame.setupUI();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
//TODO: Add an Icon Image
|
||||
private static final JFrame setupFrame()
|
||||
{
|
||||
JFrame frame = new JFrame(PROG_TITLE);
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
||||
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
if(screenSize.width <= 1024 || screenSize.height <= 800) {
|
||||
frame.setExtendedState(JFrame.MAXIMIZED_BOTH); //maximize by default if the screen is really small
|
||||
} else {
|
||||
frame.setSize((int)Math.round(screenSize.width * 0.8), (int)Math.round(screenSize.height * 0.8));
|
||||
frame.setLocationRelativeTo(null); //Centers the frame
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the pane that holds the different tile implementations the user may choose to put into the editor.
|
||||
* @return The Tile Pane Component, Fully Constructed
|
||||
*/
|
||||
private static final JComponent setupTilesPanel()
|
||||
{
|
||||
throw new UnsupportedOperationException("Not Supported Yet.");
|
||||
}
|
||||
|
||||
public static final void setupUI()
|
||||
{
|
||||
JFrame frame = setupFrame();
|
||||
|
||||
/*
|
||||
TileMap map = new TileMap(10, 10);
|
||||
map.setTileResourceAt(TileImpl.PROPERTY_IMG, ImageReader.readImage("res/Water.png"), 2, 2);
|
||||
|
||||
TileMapDisplay.OptionsBuilder displayOptions = new TileMapDisplay.OptionsBuilder();
|
||||
displayOptions = displayOptions
|
||||
.tileSize(32, 32)
|
||||
.displaySize(640, 480)
|
||||
.borderColor(Color.black);
|
||||
TileMapDisplay currentTileMapDisplay = new TileMapDisplay(displayOptions);
|
||||
currentTileMapDisplay.setCurrentTileMap(map);
|
||||
System.out.println("TILE MAP DISPLAY WIDTH: " + currentTileMapDisplay.getPreferredSize().getWidth());
|
||||
System.out.println("TILE MAP DISPLAY HEIGHT: " + currentTileMapDisplay.getPreferredSize().getHeight());
|
||||
|
||||
frame.add(currentTileMapDisplay);
|
||||
*/
|
||||
|
||||
ArrayList<Image> images = new ArrayList<>(6);
|
||||
for(int i = 0; i < 20; i++)
|
||||
{
|
||||
images.add(ImageReader.readImage("res/Water.png"));
|
||||
}
|
||||
TilesetDisplay display = new TilesetDisplay(32, images);
|
||||
frame.add(display);
|
||||
frame.pack();
|
||||
frame.setLocationRelativeTo(null);
|
||||
frame.setVisible(true);
|
||||
|
||||
/*
|
||||
currentTileMapDisplay.repaint();
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
23
src/com/aargonian/editor/ImageReader.java
Normal file
23
src/com/aargonian/editor/ImageReader.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package com.aargonian.editor;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Created by aargonian on 7/8/17.
|
||||
*/
|
||||
public class ImageReader
|
||||
{
|
||||
public static final BufferedImage readImage(String imagePath)
|
||||
{
|
||||
try {
|
||||
BufferedImage img = ImageIO.read(new File(imagePath));
|
||||
return img;
|
||||
} catch(IOException ex) {
|
||||
System.err.println("Exception Occurred: " + ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
132
src/com/aargonian/editor/TileMapDisplay.java
Normal file
132
src/com/aargonian/editor/TileMapDisplay.java
Normal file
@@ -0,0 +1,132 @@
|
||||
package com.aargonian.editor;
|
||||
|
||||
import com.aargonian.com.aargonian.tile.TileImpl;
|
||||
import com.aargonian.com.aargonian.tile.TileMap;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Created by aargonian on 7/8/17.
|
||||
*/
|
||||
public class TileMapDisplay extends JComponent
|
||||
{
|
||||
private TileMap tileMap;
|
||||
private final OptionsBuilder options;
|
||||
private static final OptionsBuilder DEFAULT_OPTIONS =
|
||||
new OptionsBuilder().borderColor(Color.black).displaySize(640, 480).tileSize(32, 32);
|
||||
|
||||
public TileMapDisplay()
|
||||
{
|
||||
this.options = DEFAULT_OPTIONS;
|
||||
}
|
||||
|
||||
public TileMapDisplay(OptionsBuilder options)
|
||||
{
|
||||
this.options = options;
|
||||
this.setPreferredSize(new Dimension(options.displayWidth(), options.displayHeight()));
|
||||
}
|
||||
|
||||
public OptionsBuilder getOptions()
|
||||
{
|
||||
return options;
|
||||
}
|
||||
|
||||
public void setCurrentTileMap(TileMap map)
|
||||
{
|
||||
this.tileMap = map;
|
||||
}
|
||||
|
||||
public TileMap getCurrentTileMap()
|
||||
{
|
||||
return this.tileMap;
|
||||
}
|
||||
|
||||
public void paint(Graphics g)
|
||||
{
|
||||
Graphics2D g2 = (Graphics2D)g;
|
||||
g2.setColor(options.borderColor());
|
||||
g2.fillRect(0, 0, this.getWidth(), this.getHeight());
|
||||
for(int x = 0; x < tileMap.getColumns(); x++)
|
||||
{
|
||||
for(int y = 0; y < tileMap.getRows(); y++)
|
||||
{
|
||||
Image img = (Image)tileMap.getTileResourceAt(TileImpl.PROPERTY_IMG, x, y);
|
||||
if(img != null)
|
||||
g2.drawImage(img,
|
||||
x*options.tileWidth(), y*options.tileHeight(), options.tileWidth(), options.tileHeight(),
|
||||
null);
|
||||
else
|
||||
{
|
||||
GradientPaint defPaint = new GradientPaint(x*options.tileWidth(), y*options.tileHeight(),
|
||||
Color.white, (x+1)*options.tileWidth(), (y+1)*options.tileHeight, Color.black);
|
||||
g2.setPaint(defPaint);
|
||||
g2.fillRect(x*options.tileWidth(), y*options.tileHeight(), options.tileWidth(), options.tileHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final class OptionsBuilder
|
||||
{
|
||||
private int tileWidth = 32;
|
||||
private int tileHeight = 32;
|
||||
private int displayWidth = 640;
|
||||
private int displayHeight = 480;
|
||||
private Color borderColor = Color.black;
|
||||
private boolean fullscreen = false;
|
||||
|
||||
public OptionsBuilder tileWidth(int width)
|
||||
{
|
||||
this.tileWidth = width <= 0 ? 0 : width;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OptionsBuilder tileHeight(int height)
|
||||
{
|
||||
this.tileHeight = height <= 0 ? 0 : height;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OptionsBuilder tileSize(int width, int height)
|
||||
{
|
||||
return this.tileWidth(width).tileHeight(height);
|
||||
}
|
||||
|
||||
public OptionsBuilder borderColor(Color c)
|
||||
{
|
||||
this.borderColor = c;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OptionsBuilder displayWidth(int width)
|
||||
{
|
||||
this.displayWidth = width <= 0 ? 0 : width;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OptionsBuilder displayHeight(int height)
|
||||
{
|
||||
this.displayHeight = height <= 0 ? 0 : height;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OptionsBuilder displaySize(int width, int height)
|
||||
{
|
||||
return this.displayWidth(width).displayHeight(height);
|
||||
}
|
||||
|
||||
public OptionsBuilder fullscreen(boolean value)
|
||||
{
|
||||
this.fullscreen = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int tileWidth() { return tileWidth; }
|
||||
public int tileHeight() { return tileHeight; }
|
||||
public int displayWidth() { return displayWidth; }
|
||||
public int displayHeight() { return displayHeight; }
|
||||
public Color borderColor() { return borderColor; }
|
||||
public boolean fulllscreen() { return fullscreen; }
|
||||
}
|
||||
}
|
||||
49
src/com/aargonian/editor/TilesetDisplay.java
Normal file
49
src/com/aargonian/editor/TilesetDisplay.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package com.aargonian.editor;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Created by aargonian on 7/9/17.
|
||||
*
|
||||
* This class implements a display for a set of tiles.
|
||||
*/
|
||||
public final class TilesetDisplay extends JComponent
|
||||
{
|
||||
private final ArrayList<Image> images;
|
||||
private int tileSize;
|
||||
|
||||
public TilesetDisplay(int tileSize, ArrayList<Image> tileImages)
|
||||
{
|
||||
if(tileImages == null)
|
||||
throw new NullPointerException("Passed Image Set is Null.");
|
||||
this.images = tileImages;
|
||||
this.tileSize = tileSize;
|
||||
}
|
||||
|
||||
public void addImageToDisplay(Image img)
|
||||
{
|
||||
images.add(img);
|
||||
}
|
||||
|
||||
public void removeImageFromDisplay(Image img)
|
||||
{
|
||||
images.remove(img);
|
||||
}
|
||||
|
||||
//Todo: Update this to use a scrollpane and avoid divide by zero.
|
||||
@Override
|
||||
public void paintComponent(Graphics g)
|
||||
{
|
||||
g.setColor(Color.gray);
|
||||
g.fillRect(0,0, getWidth(), getHeight());
|
||||
int columns = (int)(getWidth()/tileSize);
|
||||
if(columns != 0) { // Avoid divide by zero and simply display nothing.
|
||||
for (int i = 0; i < images.size(); i++) {
|
||||
g.drawImage(images.get(i),
|
||||
(i % columns) * tileSize, ((int) (i / columns)) * tileSize, tileSize, tileSize, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user