I've been trying to implement this solution (https://algorithmist.com/wiki/UVa_10672_-_Marbles_on_a_tree) to this kattis problem (https://open.kattis.com/problems/marblestree). This is a graph theory problem involving a tree and a greedy algorithm similar to DFS. My code works for the sample test case, but generates a run-time exception on the second test case. The problem is, I have no idea where the exception is happening or what the exception is - Kattis gives me no hints. This isn't a memory exceeded or time exceeded deal, as kattis has a seperate notification for those errors; something somewhere is generating an explicit run-time exception and I have no idea where. My guess is that the exception is happening somewhere in the while loop with the condition "que.size() > 0", but I cant find where. Here is the code:
import java.util.*;
import java.io.*;
public class marblestree
{
public static ArrayList<ArrayList<Integer>> adjList = new ArrayList<>();
public static ArrayList<Integer> values = new ArrayList<>();
public static ArrayList<Integer> leaves = new ArrayList<>();
public static void main(String args[]) throws IOException
{
Scanner in = new Scanner(System.in);
int n = 1;
while (n > 0)
{
n = in.nextInt();
if (n == 0)
break;
for (int i = 0; i < n; i++)
{
adjList.add(new ArrayList<Integer>());
}
for (int j = 0; j < n; j++)
{
in.nextInt();
values.add(in.nextInt());
int adjNum = in.nextInt();
for (int m = 0; m < adjNum; m++)
{
adjList.get(in.nextInt() - 1).add(j);
}
if (adjNum == 0)
leaves.add(j);
}
//System.out.println("adjList: " + adjList);
//handle case
LinkedList<Integer> que = new LinkedList<>();
for (Integer y : leaves)
{
que.add(y);
}
int moves = 0;
adjList.get(0).add(0);
while (que.size() > 0)
{
//System.out.println("next, this is currently the que: " + que);
//System.out.println("and these are the values at each vertex:" + values);
int now = que.poll();
if (now != 0)
{
if (adjList.get(now).get(0) > 0 && !que.contains(adjList.get(now).get(0)))
que.add(adjList.get(now).get(0));
moves += Math.abs(values.get(now) - 1);
values.set(adjList.get(now).get(0), values.get(adjList.get(now).get(0)) + (values.get(now) - 1));
values.set(now, 1);
}
}
System.out.println(moves);
adjList = new ArrayList<>();
values = new ArrayList<>();
leaves = new ArrayList<>();
}
}
}
I have a smg file that contains different articles. Now I would like to use prefix tree data structure to establish baseline word counts for the entire corpus of documents. A sample of the file can be found below:
<REUTERS TOPICS="YES" LEWISSPLIT="TRAIN" CGISPLIT="TRAINING-SET"
OLDID="5544" NEWID="1">
<DATE>26-FEB-1987 15:01:01.79</DATE>
<TOPICS><D>cocoa</D></TOPICS>
<PLACES><D>el-salvador</D><D>usa</D><D>uruguay</D></PLACES>
<PEOPLE></PEOPLE>
<ORGS></ORGS>
<EXCHANGES></EXCHANGES>
<COMPANIES></COMPANIES>
<UNKNOWN>
C T
f0704reute
u f BC-BAHIA-COCOA-REVIEW 02-26 0105</UNKNOWN>
<TEXT>
<TITLE>BAHIA COCOA REVIEW</TITLE>
<DATELINE> SALVADOR, Feb 26 - </DATELINE><BODY>
Some text here.
Reuter
</BODY></TEXT>
</REUTERS>
Any advice on how to establish the baseline word counts?
use trie data structure to load strings and retrieve suggestions faster
public class Trie
{
public struct Letter
{
public const string Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static implicit operator Letter(char c)
{
c = c.ToString().ToUpper().ToCharArray().First();
return new Letter() { Index = Chars.IndexOf(c) };
}
public int Index;
public char ToChar()
{
return Chars[Index];
}
public override string ToString()
{
return Chars[Index].ToString();
}
}
public class Node
{
public string Word;
public bool IsTerminal { get { return Word != null; } }
public Dictionary<Letter, Node> Edges = new Dictionary<Letter, Node>();
}
public Node Root = new Node();
public Trie(string[] words)
{
for (int w = 0; w < words.Length; w++)
{
var word = words[w];
var node = Root;
for (int len = 1; len <= word.Length; len++)
{
var letter = word[len - 1];
Node next;
if (!node.Edges.TryGetValue(letter, out next))
{
next = new Node();
if (len == word.Length)
{
next.Word = word;
}
node.Edges.Add(letter, next);
}
node = next;
}
}
}
public List<string> GetSuggestions(string word, int max)
{
List<string> outPut = new List<string>();
var node = Root;
int i = 0;
foreach (var l in word)
{
Node cNode;
if (node.Edges.TryGetValue(l, out cNode))
{
node = cNode;
}
else
{
if (i == word.Length - 1)
return outPut;
}
i++;
}
GetChildWords(node, ref outPut, max);
return outPut;
}
public void GetChildWords(Node n, ref List<string> outWords, int Max)
{
if (n.IsTerminal && outWords.Count < Max)
outWords.Add(n.Word);
foreach (var item in n.Edges)
{
GetChildWords(item.Value, ref outWords, Max);
}
}
}
I have a TableView with a list of items (Transaction) and want it to sort, so that all positive values are above the negative ones. This is the only requirement.
What I have until now:
expensesTableView.sortPolicyProperty().set(
new Callback<TableView<Transaction>, Boolean>() {
#Override
public Boolean call(TableView<Transaction> param) {
Comparator<Transaction> c = (a, b) -> {
if (a.getValue().contains("-") ^ b.getValue().contains("-")) { //getValue() returns a String
return a.getValue().contains("-") ? 1 : -1;
}
return 0;
};
FXCollections.sort(expensesTableView.getItems(), c);
return true;
};
});
This wasn't my idea, I found this on the net, so don't ask if it looks like a strange way to achieve that. The real problem is, that the table doesn't sort on its own when a new item is added/edited/deleted. I need to click the header 3 times and then it does what I want.
How can I have a list that is always sorted correctly?
I tried adding a ChangeListener and sort on change. But besides that this is an ugly way to do that, it didn't even work... I'm at the end of ideas.
The bitwise OR in the comparator didn't work in my tests, so I've changed it to a normal one, and it's also not checking for change in the value of items from the list.
I wonder if it might be more efficient to do a numeric check rather than a String check, negatives could still sort out below, but I guess the conversion might cost more?
My first idea with SortedList in the comments was actually related to keeping the original sorted order, to be restored after the user has changed the sort, so was off the mark.
Edited to add: Just to clarify, it's the act of keeping the source list sorted that keeps the table list sorted.
public class TestApp extends Application {
private int c;
private ObservableList<TestTransaction> sortedOL;
private final Comparator<TestTransaction> comp = (TestTransaction a, TestTransaction b) -> {
if (a.getValue().contains("-") || b.getValue().contains("-")) {
return a.getValue().contains("-") ? 1 : -1;
}
return 0;
};
private TableView<TestTransaction> tableView;
#Override
public void start(Stage primaryStage) {
ArrayList<TestTransaction> rawList = new ArrayList<>();
for (int i = 1; i < 20; i++) {
int v = i * 3;
if (v % 2 > 0) {
v = v * -1;
}
c = i;
rawList.add(new TestTransaction(Integer.toString(v), "Item " + c));
}
sortedOL = FXCollections.observableArrayList(rawList);
sortedOL.addListener((ListChangeListener.Change<? extends TestTransaction> c1) -> {
if (c1.next() && (c1.wasAdded() || c1.wasRemoved())) {
FXCollections.sort(sortedOL, comp);
}
});
FXCollections.sort(sortedOL, comp);
tableView = new TableView<>(sortedOL);
TableColumn<TestTransaction,String> valCol = new TableColumn<>("Value");
valCol.setCellValueFactory(new PropertyValueFactory("value"));
TableColumn<TestTransaction,String> nameCol = new TableColumn<>("Name");
nameCol.setCellValueFactory(new PropertyValueFactory("name"));
tableView.getColumns().setAll(valCol, nameCol);
BorderPane tpane = new BorderPane();
Button btnAdd = new Button("Add");
btnAdd.setOnAction(a -> {addTransaction();});
ToolBar tb = new ToolBar(btnAdd);
tpane.setTop(tb);
tpane.setCenter(tableView);
tpane.setPrefSize(600, 600);
Scene scene = new Scene(tpane, 600, 600);
primaryStage.setTitle("Test");
primaryStage.setScene(scene);
primaryStage.show();
}
private void addTransaction() {
c++;
int v = (int) Math.floor(Math.random() * 50);
if (v % 2 > 0) {
v = v * -1;
}
sortedOL.add(new TestTransaction(Integer.toString(v), "New Item " + c));
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
public class TestTransaction {
private String value;
private String name;
public TestTransaction(String value, String name) {
this.value = value;
this.name = name;
}
/**
* #return the value
*/
public String getValue() {
return value;
}
/**
* #return the name
*/
public String getName() {
return name;
}
}
If you want to use SortedList, meaning you could inline the comparator:
sortedOL = FXCollections.observableArrayList(rawList);
SortedList sorted = new SortedList(sortedOL, comp);
tableView = new TableView<>(sorted);
I have creating this treetable
Now I want to sum up th children values and show the result in the parent cell under the related column. For example for Function 7 in column 2 and row 2 I want to right 2.0, and for Function 11 column 4 row 4 right 1.0 (function 12 + function 13)
Here is the code which produces the treetable.
root.setExpanded(true);
Set<String> combinedKeys = new HashSet<>(dc.getCombiFunc().keySet());
Set<String> funcAllKeys = new HashSet<>(dc.getSortedfuncAll().keySet());
funcAllKeys.removeAll(dc.getCombiFunc().keySet());
for (List<String> value : dc.getCombiFunc().values()) {
funcAllKeys.removeAll(value);
}
for (String valueremained : funcAllKeys) {
ArrayList<String> tempNameId = new ArrayList<>();
tempNameId.add(dc.getSortedfuncAll().get(valueremained));
// all elements which are not in combined functions (They are all
// orphan)
root.getChildren().add(new TreeItem<String>(tempNameId.get(0)));
}
// Getting Keys that have children//////
Set<String> keyFromcombined = new HashSet<>();
List<String> valueOfCombined = new ArrayList<String>();
for (Entry<String, List<String>> ent : dc.getCombiFunc().entrySet()) {
for (int i = 0; i < ent.getValue().size(); i++)
valueOfCombined.add(ent.getValue().get(i));
}
List<String> rootKeyList = new ArrayList<>();
for (String key : combinedKeys) {
if (!valueOfCombined.contains((key))) {
keyFromcombined.add(dc.getFuncAll().get(key));
rootKeyList.add(key);
}
}
String[] rootKeys = rootKeyList.toArray(new String[rootKeyList.size()]);
// ////////////////treetable////////////////////////////
treeTable.setRoot(root);
Arrays.stream(rootKeys).forEach(
rootKey -> root.getChildren().add(
createTreeItem(dc.getCombiFunc(), rootKey)));
// ////////////////First column/////////////////////////
TreeTableColumn<String, String> firstColumn = new TreeTableColumn<>("");
treeTable.getColumns().add(firstColumn);// Tree column
firstColumn.setPrefWidth(50);
firstColumn
.setCellValueFactory(new Callback<CellDataFeatures<String, String>, ObservableValue<String>>() {
public ObservableValue<String> call(
CellDataFeatures<String, String> p) {
return new ReadOnlyStringWrapper(p.getValue()
.getValue());
}
});
// //////////////////Rest Columns////////////////////////
for (Entry<String, String> ent : dc.getSortedAssignedOrg().entrySet()) {
TreeTableColumn<String, ArrayList<String>> col = new TreeTableColumn<>();
Label label = new Label(ent.getValue());
col.setGraphic(label);
label.setTooltip(new Tooltip(label.getText()));// tooltip for column
// headers
col.setPrefWidth(45);
// cell Value Factory////////////////////////
col.setCellValueFactory(new Callback<TreeTableColumn.CellDataFeatures<String, ArrayList<String>>, ObservableValue<ArrayList<String>>>() {
#Override
public ObservableValue<ArrayList<String>> call(
CellDataFeatures<String, ArrayList<String>> param) {
TreeMap<String, List<String>> temp = (TreeMap<String, List<String>>) dc
.getFuncTypeOrg().clone();
ArrayList<String> result = new ArrayList<>();
for (int i = 0; i < dc.getFuncTypeOrg().size(); i++) {
List<String> list = temp.firstEntry().getValue();
String key = temp.firstEntry().getKey();
if (list.get(1).equals(param.getValue().getValue())
&& !list.get(5).equals(label.getText())) {
result.add("white");
}
if (!root.isLeaf()) {
result.add("parent");
}
if (list.get(1).equals(param.getValue().getValue())
&& list.get(5).equals(label.getText())) {
result.add(0, list.get(2));// weight
if (list.size() > 6) {
result.add(1, list.get(list.size() - 1));// color
result.add(2, list.get(6));// App component
}
else
// result.add("white");
result.add("noOrg");
} else
temp.remove(key);
}
return new ReadOnlyObjectWrapper<ArrayList<String>>(result);
}
}); // end cell Value Factory
// //////////////cellfactory/////////////////////////
col.setCellFactory(new Callback<TreeTableColumn<String, ArrayList<String>>, TreeTableCell<String, ArrayList<String>>>() {
#Override
public TreeTableCell<String, ArrayList<String>> call(
TreeTableColumn<String, ArrayList<String>> param) {
return new TreeTableCell<String, ArrayList<String>>() {
public void updateItem(ArrayList<String> item,
boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setStyle("");
setText("");
} else if (item.contains("Green")) {
float weightInt = Float.parseFloat(item.get(0));
float res = weightInt * 1;
String resString = Float.toString(res);
this.setStyle("-fx-background-color:green");
setTooltip(new Tooltip(item.get(2)));
setText(resString);
} else if (item.contains("yellow")) {
this.setStyle("-fx-background-color:yellow");
setTooltip(new Tooltip(item.get(2)));
setText("0");
} else if (item.contains("white")) {
this.setStyle("-fx-background-color:linear-gradient(black, white); ");
// setText("DD");
} else if (item.contains("parent")) {
for (int i = 0; i < dc.getFuncTypeOrg().size(); i++) {
}
String text = param.getCellData(root).get(0);
// setText(text);
}
}
};
};
});// end cell factory
treeTable.getColumns().add(col);
}//end for loop col
TreeMap temp clones dc.getFuncTypeOrg(). In this TreeMap I have value for each child (color and the number). then in cellfactory i multiply value in color ( green = 1 and yellow = 0). Outside the loop I thought to make a treemap containg each parent as key and all it's children as value. Then I can sum up children values together and make a treemap in which first key is parent and as value the required value(or just string ArrayList ). After that I can check the name of cell in cellFactory and if it is a parent just right the value in the cell. I have been told how i can get treeitem values, and i am now here :
//after col loop ends
TreeMap<String, List<TreeItem<String>>> mytreemap = new TreeMap<>();
TreeMap<String, List<String>> parChild = new TreeMap<>();
for(TreeItem node: root.getChildren()){
if(!node.isLeaf())
mytreemap.put(node.getValue().toString(), node.getChildren());
}
for(Entry<String, List<TreeItem<String>>> ent: mytreemap.entrySet()){
for(TreeItem myItem : ent.getValue()){
// how can i fill parChild with parent as key and all its children as value?
System.out.println(ent.getKey()+" "+myItem.getValue());
}
}
treeTable.setPrefWidth(1200);
treeTable.setPrefHeight(500);
treeTable.setShowRoot(false);
treeTable.setTableMenuButtonVisible(true);
return treeTable; }
Here at setCellFactory
else if (item.contains("parent")) {
for (int i = 0; i < dc.getFuncTypeOrg().size(); i++) {
}
i can get the roots. Is there a way to do a recursion (up to the number of children and subchildren for that root cell) and add their value together and setText the parent cell to that value?
You can use onEditCommit method to add all childern values and show them in parent cell. For example
column1.setOnEditCommit((evt) -> {
//finalsing value of the cell
evt.getRowValue().getValue().setCellValue((evt.getNewValue()));
//Returns all the sibblings of the current cell
ObservableList<TreeItem> children = evt.getRowValue().getParent().getChildren();
int parentValue = 0;
for (TreeItem<> child : children) {
parentValue = parentValue + Integer.valueOf(child.getValue().getCellValue());
}
evt.getRowValue().getParent().getValue().setCellValue(parentValue);
});
Today I was going to pack my game into a Jar to provide to a friend who codes and wanted to see a nice glitch I managed to create. When I went to make it a Runnable jar it would load up in the Command Prompt but throw Resource Not Found errors for Sounds (.ogg's), which was fine because they werent going to be used in the Debug mode it was set to. Then it threw a NullPointerException in TileHanlder.class at initTileMap() line 137.
I am at a loss so I came to StackOverflow because I have spent nearly my entire day on getting a working Jar. I have also tried JarSplice.
My main question is if there is any anomalies you notice or something I didnt do that is leading to resources not being found in the .jar.
ALL CODE AND RESOURCES WERE IN THE SAME JAR, ONE JAR FOR EVERYTHING there were not multiple jars
For ALL my code (it is OpenSource after all: Game Source Code)
Level.java (The class calling AssetHandler and TileHandler)
public class Level extends BasicGameState {
public MapHandler map = new MapHandler();
public AssetHandler asset = new AssetHandler();
static OutputHandler out = new OutputHandler();
public GameContainer container;
public StateBasedGame game;
public static float MouseX = 0;
public static float MouseY = 0;
public float RectX = 0;
public float RectY = 0;
public int tileAmount = 0;
public static int mapID = 1;
public static int delta;
public static int score = 0;
private static int EntityAmount = 0;
private static int ActiveEntityAmount = 0;
private int FPS = 0;
public static Image mapImage;
public static TileHandler Tile = new TileHandler();
public Point mousePoint;
public Circle mouseCirc;
public static Player p;
public static Enemy Blinky, Pinky, Inky, Clyde;
public static EntityAI AGGRESSIVE, AMBUSH, HIT_RUN, SORTOFRANDOM;
public Level(int id) {
}
#Override
public void init(GameContainer container, StateBasedGame game) throws SlickException {
MapHandler.mapRect();
mapID = MapHandler.getMapID();
MapHandler.deployMap(mapID);
try {
asset.initAssets();
OutputHandler.initFont();
} catch (AssetException e) {
e.printStackTrace();
}
TileHandler.initTileMap();
container.setUpdateOnlyWhenVisible(true);
container.setShowFPS(false);
container.setSmoothDeltas(false);
container.setVerbose(true);
this.container = container;
this.game = game;
AGGRESSIVE = new RedAI();
AMBUSH = new PinkAI();
HIT_RUN = new BlueAI();
SORTOFRANDOM = new OrangeAI();
p = new Player("Player1");
Blinky = new Enemy("Shadow", AGGRESSIVE);
Pinky = new Enemy("Speedy", AMBUSH);
Inky = new Enemy("Bashful", HIT_RUN);
Clyde = new Enemy("Pokey", SORTOFRANDOM);
}
#Override
public void render(GameContainer container, StateBasedGame game, Graphics g) throws SlickException {
Tile.drawTileMap(TileHandler.tileLayer, TileHandler.tMapTiles, g);
if (Reference.debug) {
displayTileBounds(TileHandler.tileLayer, g);
}
drawEntities();
drawStrings(g);
}
#Override
public void update(GameContainer container, StateBasedGame game, int delta) throws SlickException {
Input in = container.getInput();
MouseX = in.getMouseX();
MouseY = in.getMouseY();
RectX = MapHandler.Map32.getX();
RectY = MapHandler.Map32.getY();
EntityAmount = Entity.entityList.size();
ActiveEntityAmount = Enemy.enemyList.size() + Projectile.activeProjectiles.size() + 1;
Level.delta = delta;
Reference.defProjectileVelocity = .13f * Level.delta;
p.update(in);
updateNonPlayerEntities();
FPS = container.getFPS();
}
#Override
public int getID() {
return 2;
}
/** #deprecated **/
#Deprecated
protected void drawMap(Graphics g) {
g.drawImage(mapImage, Reference.MAP_X, Reference.MAP_Y);
}
protected void drawStrings(Graphics g) {
if (Reference.debug) {
OutputHandler.write("FPS: " + Integer.toString(FPS), 11, 10);
OutputHandler.write(String.format("Mouse X: %s, Mouse Y: %s", MouseX, MouseY), 11, 30);
OutputHandler.write(String.format("Rect X: %s, Y: %s", RectX, RectY), 11, 50);
OutputHandler.write("Amount of Tiles: " + (TileHandler.tileLayer.length * TileHandler.tileLayer[0].length), 11, 70);
OutputHandler.write(String.format("Amount of Entities = %s", Integer.toString(EntityAmount)), 11, 90);
OutputHandler.write(String.format("Active Entities = %s", Integer.toString(ActiveEntityAmount)), 11, 110);
out.write("Currently Loaded: " + p.isReloaded(), 11, 130);
OutputHandler.write("Amount of Entities is Accumulative", 11, 666);
} else {
String curTime = Reference.getTime();
String scoreStr = Reference.convertScore(score);
OutputHandler.write("Time: " + curTime, 11, 10);
OutputHandler.write("Score: " + scoreStr, 550, 10);
}
}
protected void displayTileBounds(Rectangle[][] tileLayer, Graphics g) {
g.setColor(Color.white);
for (int x = 0; x < tileLayer.length; x++) {
for (int y = 0; y < tileLayer[0].length; y++) {
g.fill(tileLayer[x][y]);
}
}
g.setColor(Color.magenta);
for (int s = 0; s < TileHandler.collisionTiles.size(); s++) {
Rectangle r = TileHandler.collisionTiles.get(s);
g.fill(r);
}
g.setColor(Color.orange);
g.fill(p.boundingBox);
for (int z = 0; z < Entity.teleportingTiles.length; z++) {
Rectangle r = Entity.teleportingTiles[z];
g.fill(r);
}
}
protected void drawEntities() {
ArrayList<Entity> list = Entity.entityList;
for (int i = 0; i < list.size(); i++) {
list.get(i).drawEntity(list.get(i));
}
}
protected void updateNonPlayerEntities() {
ArrayList<Enemy> list = Enemy.enemyList;
for (int i = 0; i < list.size(); i++) {
list.get(i).update();
}
ArrayList<Projectile> pList = Projectile.activeProjectiles;
for (int p = 0; p < pList.size(); p++) {
pList.get(p).update();
}
}
}
The AssetHandler (Game-Handlers-AssetHandler.java) Sounds are the THIRD TO LAST METHOD
public class AssetHandler {
public static boolean isComplete = false;
private static String musPath = "res/Sounds/";
static TileHandler tile;
private static int tsize = 32;
private static String spritesPath = "res/GameSprites/Maze Game/sprites.png";
private static String terrainPath = "res/GameSprites/Maze Game/terrain.png";
private static String twPath = "res/GameSprites/Maze Game/animation/tankToWest.png";
private static String tePath = "res/GameSprites/Maze Game/animation/tankToEast.png";
private static String tnPath = "res/GameSprites/Maze Game/animation/tankToNorth.png";
private static String tsPath = "res/GameSprites/Maze Game/animation/tankToSouth.png";
private static String bwPath = "res/GameSprites/Maze Game/animation/blueToWest.png";
private static String bePath = "res/GameSprites/Maze Game/animation/blueToEast.png";
private static String bnPath = "res/GameSprites/Maze Game/animation/blueToNorth.png";
private static String bsPath = "res/GameSprites/Maze Game/animation/blueToSouth.png";
private static String rePath, rwPath, rsPath, rnPath;
private static String pePath, pwPath, psPath, pnPath;
private static String oePath, owPath, osPath, onPath;
public static Music titleMus1, titleMus2, titleMus3, loadingScreenMus1, loadingScreenMus2, loadingScreenMus3;
public static Sound tankMove, tankFire, tankExplode, tankSurrender, tankRetreat;
public static void initSounds() {
System.out.println("Initializing Main Menu Music...");
try {
titleMus1 = new Music(musPath + "title/titlefirst.ogg");
titleMus2 = new Music(musPath + "title/titlesecond.ogg");
titleMus3 = new Music(musPath + "title/titlethird.ogg");
System.out.println("Initialized Main Menu Music!...");
} catch (SlickException e) {
e.printStackTrace();
System.out.println("ERROR: Initializing Main Menu Sounds at " + "com.treehouseelite.tank.game.handlers.AssetHandler" + " : initSounds() Method, First Try/Catch");
}
System.out.println("Initializing Loading Screen Music...");
try {
loadingScreenMus1 = new Music(musPath + "levels or loading screens/ActionBuilder.ogg");
loadingScreenMus2 = new Music(musPath + "levels or loading screens/StruggleforSurvival.ogg");
loadingScreenMus3 = new Music(musPath + "levels or loading screens/SurrealSomber.ogg");
} catch (SlickException e) {
e.printStackTrace();
System.out.println("ERROR: Initializing Loading Screen Sounds at " + "com.treehouseelite.tank.game.handlers.AssetHandler" + " : initSounds() Method, Second Try/Catch");
}
initSFX();
initsComplete();
}
private static void initsComplete() {
System.out.println("========================ALL ASSETS INITIALIZED========================");
}
public static void initSFX() {
try {
tankMove = new Sound("res/Sounds/SFX/tankMove.wav");
} catch (SlickException e) {
e.printStackTrace();
} finally {
System.out.println("All Sound Effects Initialized...");
}
}
}
TileHandler.java (Game-Handlers-TileHandler.java)
public class TileHandler {
public static String mapPath = "res/World/level_";
public static int bg, paths, collision;
public static Image[][] tMapTiles = new Image[25][20];
public static boolean[][] collidableTile = new boolean[25][20];
static Graphics g = new Graphics();
static AssetHandler asset = new AssetHandler();
// The Amount of Image is too damn high!
static TiledMap tMap;
public static int wFrame = 0;
private static int id;
public static Rectangle[][] tileLayer = new Rectangle[25][20];
public static ArrayList<Rectangle> collisionTiles = new ArrayList<Rectangle>(500);
public TileHandler() {
}
public TileHandler(int id, Rectangle rect) {
TileHandler.id = id;
try {
createTiles(id, rect);
} catch (SlickException e) {
e.printStackTrace();
}
}
protected void createTiles(int id, Rectangle layer) throws SlickException {
// Scans 0,0 to 0,20 of the tiles and then moves down the x line
// gettings tiles
// 0,0 = tileLayer[0][0]
mapPath = String.format("res/World/level_%s.tmx", id);
tMap = new TiledMap(mapPath);
bg = tMap.getLayerIndex("background");
paths = tMap.getLayerIndex("paths");
collision = tMap.getLayerIndex("collision");
// Constructs a Grid of Rectangles based on the Map's Top Left point
for (int i = 0; i < tileLayer.length; i++) {
for (int y = 0; y < tileLayer[0].length; y++) {
Rectangle tile = new Rectangle((i + Reference.MAP_X) + (i * Reference.TILE_SIZE), (y + Reference.MAP_Y) + (y * Reference.TILE_SIZE), 32, 32);
tileLayer[i][y] = tile;
}
}
/*
* for(int x = 0; x<collisionTiles.length; x++){ for(int y = 0;
* y<collisionTiles[0].length; y++){ Rectangle tile = new
* Rectangle((x+Reference.MAP_X) + (x*31),
* (y+Reference.MAP_Y+14)+(y*31),32,32); collisionTiles[x][y] = tile; }
* }
*/
}
/** #deprecated */
#Deprecated
public static void initSprites(Rectangle[][] layer) {
bg = tMap.getLayerIndex("background");
paths = tMap.getLayerIndex("paths");
collision = tMap.getLayerIndex("collision");
System.out.println("Initialized Sprites!");
}
// Initializes all tiles and put them into Image and Boolean Arrays
// Boolean Array for later use with determining whether the player or entity
// can be there. (collidableTile)
// Image array holds the tiles (tMapTiles)
public static void initTileMap() {
new Graphics();
// Getting Tiles based off Tile ID's
/** DIRT PATH MAPS (Dev Map, Level 1) **/
if ((id == 0) || (id == 1)) {
for (int x = 0; x < tileLayer.length; x++) {
for (int y = 0; y < tileLayer[0].length; y++) {
Rectangle r = new Rectangle(tileLayer[x][y].getX(), tileLayer[x][y].getY(), 32, 32);
if (tMap.getTileId(x, y, bg) == 1) {
tMapTiles[x][y] = AssetHandler.sparseGrass;
}
if (tMap.getTileId(x, y, collision) == 2) {
tMapTiles[x][y] = AssetHandler.water11;
collisionTiles.add(r);
}
if (tMap.getTileId(x, y, collision) == 57) {
tMapTiles[x][y] = AssetHandler.concrete1;
collisionTiles.add(r);
}
if (tMap.getTileId(x, y, collision) == 71) {
tMapTiles[x][y] = AssetHandler.concrete2;
// collisionTiles.add(new
// Rectangle(tileLayer[x][y].getX(),
// tileLayer[x][y].getY()+14, 32, 32)) ;
collisionTiles.add(r);
}
if (tMap.getTileId(x, y, collision) == 85) {
tMapTiles[x][y] = AssetHandler.concrete3;
collisionTiles.add(r);
}
if (tMap.getTileId(x, y, collision) == 72) {
tMapTiles[x][y] = AssetHandler.metal1;
collisionTiles.add(r);
}
if (tMap.getTileId(x, y, collision) == 58) {
tMapTiles[x][y] = AssetHandler.metal2;
collisionTiles.add(r);
}
if (tMap.getTileId(x, y, paths) == 50) {
tMapTiles[x][y] = AssetHandler.hDirtPath;
}
if (tMap.getTileId(x, y, paths) == 60) {
tMapTiles[x][y] = AssetHandler.dirtPath;
}
if (tMap.getTileId(x, y, paths) == 59) {
tMapTiles[x][y] = AssetHandler.dirtPathTurn4;
}
if (tMap.getTileId(x, y, paths) == 73) {
tMapTiles[x][y] = AssetHandler.dirtPathTurn3;
}
if (tMap.getTileId(x, y, paths) == 79) {
tMapTiles[x][y] = AssetHandler.dirtThreewayRight;
}
if (tMap.getTileId(x, y, paths) == 46) {
tMapTiles[x][y] = AssetHandler.dirtPathTurn1;
}
if (tMap.getTileId(x, y, paths) == 37) {
tMapTiles[x][y] = AssetHandler.hDirtCrossing1;
}
if ((tMap.getTileId(x, y, paths) == 80) || (tMap.getTileId(x, y, paths) == 88)) {
tMapTiles[x][y] = AssetHandler.dirtThreewayLeft;
}
if (tMap.getTileId(x, y, paths) == 102) {
tMapTiles[x][y] = AssetHandler.dirtThreewayDown;
}
if (tMap.getTileId(x, y, paths) == 74) {
tMapTiles[x][y] = AssetHandler.dirtPathTurn2;
}
if (tMap.getTileId(x, y, paths) == 107) {
tMapTiles[x][y] = AssetHandler.dirtThreewayUp;
}
if (tMap.getTileId(x, y, paths) == 88) {
tMapTiles[x][y] = AssetHandler.dirtCrossroads;
}
}
}
}
}
public void drawTileMap(Rectangle[][] layer, Image[][] tiles, Graphics g) {
// Loops through the Image array and places tile based on the Top Left
// corner of the Rectangle in the rectangle array
// Rectangle Array = layer (tileLayer was passed)
// Image Array = tiles (tMapTiles was passed)
// Asset Refers to Asset Handler
for (int x = 0; x < layer.length; x++) {
for (int y = 0; y < layer[0].length; y++) {
g.drawImage(tiles[x][y], layer[x][y].getX(), layer[x][y].getY());
// Below here is image detection for the placement of Animations
if (tiles[x][y] == AssetHandler.water11) {
AssetHandler.vRiver1.draw(layer[x][y].getX(), layer[x][y].getY());
AssetHandler.vRiver1.start();
AssetHandler.vRiver1.update(Level.delta);
} else if (tiles[x][y] == AssetHandler.hDirtCrossing1) {
AssetHandler.hDirtCrossing.draw(layer[x][y].getX(), layer[x][y].getY());
AssetHandler.hDirtCrossing.start();
AssetHandler.hDirtCrossing.update(Level.delta);
}
}
}
}
}
Finally, MapHandler.java -- Very Sparsely used, Main goal is to intialize a TileHandler object to construct the tile grid for constructing the TiledMap.
public class MapHandler {
public static AssetHandler asset = new AssetHandler();
static Image devMap;
Image map_1;
Image map_2;
Image map_3;
public static Rectangle Map32;
public MapHandler() {
}
// Sends a Rectangle set Around the Map Image to TileHandler
// to construct a grid of 32x32 Rectangles inside the Map's Rectangle
public static void deployMap(int id) {
if (id == 0) {
new TileHandler(id, Map32);
}
}
// Randomly Generates a Map ID corresponding to a Level_X.tmx
// Currently set to 0 for development purposes
public static int getMapID() {
new Random();
return 0;
// return id;
}
/* Create the Rectangle and Grid */
public static void mapRect() throws SlickException {
System.out.println("Initializing Rectangular Plane...");
Map32 = new Rectangle(Reference.GUI_WIDTH / 24, Reference.GUI_HEIGHT / 24, 800, 640);
System.out.println("Map32 Initialized!...");
}
}
If You need ANY other resources or information than please let me know and I will be happy to provide so I can get over this. I will also be thinking of other ways, Thank you for any responses!
THINGS WERE CUT OUT DUE TO THE 30k Char Limit on the question text box. Mostly in the insanely crowded AssetHandler.java, it is still there in the git repository though.
I had the very same problem. After searching for a while, I came across this neat solution. See this LWJGL forum post.
public static void main(String[] args) throws SlickException {
/* Set lwjgl library path so that LWJGL finds the natives depending on the OS. */
String osName = System.getProperty("os.name");
// Get .jar dir. new File(".") and property "user.dir" will not work if .jar is called from
// a different directory, e.g. java -jar /someOtherDirectory/myApp.jar
String nativeDir = "";
try {
nativeDir = new File(GameMain.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getParent();
} catch (URISyntaxException uriEx) {
try {
// Try to resort to current dir. May still fail later due to bad start dir.
uriEx.printStackTrace();
nativeDir = new File(".").getCanonicalPath();
} catch (IOException ioEx) {
// Completely failed
ioEx.printStackTrace();
JOptionPane.showMessageDialog(new JFrame(), "Failed to locate native library directory. " +
"Error:\n" + ioEx.toString(), "Error", JOptionPane.ERROR_MESSAGE);
System.exit(-1);
}
}
// Append library subdir
nativeDir += File.separator + "lib" + File.separator + "native" + File.separator;
if (osName.startsWith("Windows")) {
nativeDir += "windows";
} else if (osName.startsWith("Linux") || osName.startsWith("FreeBSD")) {
nativeDir += "linux";
} else if (osName.startsWith("Mac OS X")) {
nativeDir += "macosx";
} else if (osName.startsWith("Solaris") || osName.startsWith("SunOS")) {
nativeDir += "solaris";
} else {
JOptionPane.showMessageDialog(new JFrame(), "Unsupported OS: " + osName + ". Exiting.",
"Error", JOptionPane.ERROR_MESSAGE);
System.exit(-1);
}
System.setProperty("org.lwjgl.librarypath", nativeDir);
}
Bear in mind that you need a lib folder in the same directory. I have mine stored outside of the .jar, but it may be possible to have it inside as well. Also note that it needs to happen before you do any LWJGL stuff, so the main method is a good place.