Java Game Application Working in Eclipse, but not as a .jar (Slick2D + LWJGL)
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.
No comments:
Post a Comment