Last active
September 28, 2015 16:48
-
-
Save Darkhogg/1467056 to your computer and use it in GitHub Desktop.
Scaffolding for a Slick2D game for Ludum Dare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Generic scaffolding for fast deploying of Slick2D games. | |
* Includes a `Main` class with a `main` method that serves as an entry point for applications. | |
* Includes a class within `Main`, `Main$WrapperGame`, which wraps the actual `Game` implementation for use with the Slick2D `AppletLoader` class, which also serves as a common starting point for the `main` method. | |
* Includes an automatic modification of the `java.library.path` system property which *adds* the path `lib/natives-*system*` to the path, where *system* is one of `linux`, `windows`, `mac` or `solaris`. | |
* Includes a basic class `MyGame` ready to be filled with the game implementation. | |
* Includes an HTML file with an applet ready to be used. | |
* Includes an Ant buildfile ready to be executed, which generates an executable JAR file, a ZIP containing that JAR and the `lib` folder, and a `README.txt` file, if present; and another ZIP file with the `src`, `res` and `lib` folders. | |
To start working with this, you will need to refactor the included classes. Be careful to update all references to the classes. For your own convenience, everything is packed so that the only thing references from the outside is the `Main` class. | |
The applet and buildfile assumes the following directory tree: | |
``` | |
/ | |
src/ | |
**/*.java | |
res/ | |
bin/ | |
**/*.class | |
lib/ | |
applet/ | |
*_natives.jar | |
lwjgl_util_applet.jar | |
natives-*/ | |
*.(so|dll|...) | |
*.jar | |
README.txt | |
``` | |
In summary: | |
* The source files goes in a `src` directory, with the typical structure of a Java source folder | |
* Any resources which are not Java sources goes under the `res` directory | |
* The compiled Java classes *AND* a copy of the resources goes under the `bin` directory. This is the only directory that enters the JAR file. | |
* The LWJGL and Slick JAR files goes under the `lib` directory | |
* Native JAR files and the LWJGL applet JAR goes under `lib/applet` | |
* Native librearies goes under `lib/natives-*system*` | |
# Dependencies | |
The obvious dependencies are LWJGL and Slick2D. An extra dependency is the `OperatingSystem` class, which you can find here: <https://github.com/Darkhogg/DhJavaUtils/blob/master/src/es/darkhogg/util/OperatingSystem.java> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" | |
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |
<html> | |
<head> | |
<title>MyGame</title> | |
<style type="text/css"> | |
body { | |
background: #333; | |
color: white; | |
} | |
a { | |
color: red; | |
text-decoration: none; | |
} | |
b { | |
font-style: italic; | |
} | |
</style> | |
</head> | |
<body> | |
<applet | |
code="org.lwjgl.util.applet.AppletLoader" | |
archive="lib/applet/lwjgl_util_applet.jar" | |
codebase="." | |
width="640" height="480" > | |
<param name="al_title" value="MyGame"/> | |
<param name="al_main" value="org.newdawn.slick.AppletGameContainer"/> | |
<param name="al_jars" value="Game.jar, lib/lwjgl.jar, lib/lwjgl_util.jar, lib/jinput.jar, lib/slick.jar, lib/slick-util.jar"/> | |
<param name="al_logo" value="appletlogo.gif"/> | |
<param name="al_progressbar" value="appletprogress.gif"/> | |
<param name="game" value="Main$WrapperGame" /> | |
<param name="al_windows" value="lib/applet/windows_natives.jar"/> | |
<param name="al_linux" value="lib/applet/linux_natives.jar"/> | |
<param name="al_mac" value="lib/applet/macosx_natives.jar"/> | |
<param name="al_solaris" value="lib/applet/solaris_natives.jar"/> | |
<param name="separate_jvm" value="true"/> | |
</applet> | |
<p> | |
Description goes here | |
</p> | |
</body> | |
<html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<project name="MyGame" default="all"> | |
<property name="dir.src" value="src" /> | |
<property name="dir.res" value="res" /> | |
<property name="dir.bin" value="bin" /> | |
<property name="dir.lib" value="lib" /> | |
<property name="file.jar" value="Game.jar" /> | |
<property name="file.zip.bin" value="Game-Bin.zip" /> | |
<property name="file.zip.src" value="Game-Source.zip" /> | |
<!-- Builds a JAR file containing all classes --> | |
<target name="jar"> | |
<!-- generate the classpath --> | |
<manifestclasspath property="classpath" jarfile="${file.jar}"> | |
<classpath> | |
<fileset dir="${dir.lib}" includes="**/*.jar" /> | |
</classpath> | |
</manifestclasspath> | |
<!-- generate the JAR --> | |
<jar destfile="${file.jar}"> | |
<fileset dir="${dir.bin}" includes="**" /> | |
<manifest> | |
<attribute name="Main-Class" value="Main" /> | |
<attribute name="Class-Path" value="${classpath}" /> | |
</manifest> | |
</jar> | |
<!-- Add executable permissions to the owner of the JAR --> | |
<chmod perm="u+x" file="${file.jar}" /> | |
</target> | |
<!-- Builds a ZIP file containing the generated JAR and the library folder --> | |
<target name="zip-bin" depends="jar"> | |
<zip destfile="${file.zip.bin}"> | |
<fileset dir="." includes="${dir.lib}/**,${file.jar},README.txt" excludes="**/applet/**" /> | |
</zip> | |
</target> | |
<!-- Builds a ZIP file containing the library, source and resources folders --> | |
<target name="zip-src"> | |
<zip destfile="${file.zip.src}"> | |
<fileset dir="." includes="${dir.lib}/**,${dir.src}/**,${dir.res}/**,README.txt" excludes="**/applet/**"/> | |
</zip> | |
</target> | |
<!-- Builds everything --> | |
<target name="all" depends="jar,zip-bin,zip-src" /> | |
</project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.lang.reflect.Field; | |
import org.lwjgl.Sys; | |
import org.newdawn.slick.AppGameContainer; | |
import org.newdawn.slick.Game; | |
import org.newdawn.slick.GameContainer; | |
import org.newdawn.slick.Graphics; | |
import org.newdawn.slick.Image; | |
import org.newdawn.slick.ImageBuffer; | |
import org.newdawn.slick.Input; | |
import org.newdawn.slick.SlickException; | |
import org.newdawn.slick.imageout.ImageOut; | |
import org.newdawn.slick.util.Log; | |
import es.darkhogg.util.OperatingSystem; | |
/** | |
* A class that serves as an entry point for the game | |
*/ | |
public final class Main { | |
/** | |
* Modifies the <tt>java.library.path</tt> system property so it contains the appropriate folder with the LWJGL | |
* natives | |
*/ | |
private static void setupLibraryPath () throws SecurityException, NoSuchFieldException, IllegalAccessException { | |
OperatingSystem os = OperatingSystem.getCurrent(); | |
// If the OS is supported by LWJGL (Linux, Mac, Windows, Solaris) | |
if ( os == OperatingSystem.LINUX | os == OperatingSystem.MAC | os == OperatingSystem.SOLARIS | |
| os == OperatingSystem.WINDOWS ) | |
{ | |
String dirname = "natives-" + os.getName().toLowerCase(); | |
String pathsep = System.getProperty( "path.separator" ); | |
String dirsep = System.getProperty( "file.separator" ); | |
String oldlibpath = System.getProperty( "java.library.path" ); | |
// <oldpath>;lib/natives-os | |
String newlibpath = oldlibpath + pathsep + "lib" + dirsep + dirname; | |
System.setProperty( "java.library.path", newlibpath ); | |
// Propagate the change | |
Field fieldSysPath = ClassLoader.class.getDeclaredField( "sys_paths" ); | |
fieldSysPath.setAccessible( true ); | |
if ( fieldSysPath != null ) { | |
fieldSysPath.set( System.class.getClassLoader(), null ); | |
} | |
} | |
} | |
/** | |
* Launches the game using an <tt>AppGameContainer</tt> | |
* | |
* @param args | |
* Command line arguments, currently ignored | |
*/ | |
public static void main ( String[] args ) { | |
try { | |
setupLibraryPath(); | |
AppGameContainer container = new AppGameContainer( new WrapperGame() ); | |
container.start(); | |
} catch ( Throwable ex ) { | |
fatal( ex ); | |
} | |
} | |
/** | |
* Prints the exception in the console and an alert window and exits | |
* | |
* @param ex | |
* The exception that caused the fatal error | |
*/ | |
/* package */static void fatal ( Throwable ex ) { | |
Log.error( ex ); | |
Sys.alert( "Fatal Error", "fatal error ocurred during game execution: " + ex.toString() ); | |
System.exit( 1 ); | |
} | |
/** | |
* A class that wraps the main game class so both the application and applet have a common entry point | |
*/ | |
public static final class WrapperGame implements Game { | |
private final Game game = new MyGame(); | |
private Image buffer = null; | |
private Input input = null; | |
@Override | |
public boolean closeRequested () { | |
return game.closeRequested(); | |
} | |
@Override | |
public String getTitle () { | |
return game.getTitle(); | |
} | |
@Override | |
public void init ( GameContainer cont ) throws SlickException { | |
cont.setForceExit( false ); | |
cont.setShowFPS( true ); | |
game.init( cont ); | |
} | |
@Override | |
public void update ( GameContainer cont, int delta ) throws SlickException { | |
if ( input == null ) { | |
input = cont.getInput(); | |
} | |
if ( input.isKeyPressed( Input.KEY_F12 ) ) { | |
long millis = System.currentTimeMillis(); | |
String ssname = "screenshot-" + millis + ".png"; | |
Log.info( "Saving screenshot in '" + ssname + "'" ); | |
ImageOut.write( buffer, ImageOut.PNG, ssname ); | |
} | |
game.update( cont, delta ); | |
} | |
@Override | |
public void render ( GameContainer cont, Graphics gr ) throws SlickException { | |
if ( buffer == null ) { | |
buffer = new ImageBuffer( MyGame.WIDTH, MyGame.HEIGHT ).getImage( Image.FILTER_NEAREST ); | |
} | |
Graphics bufgr = buffer.getGraphics(); | |
game.render( cont, bufgr ); | |
gr.drawImage( buffer, | |
0f, 0f, MyGame.WIDTH*MyGame.SCALE, MyGame.HEIGHT*MyGame.SCALE, | |
0f, 0f, MyGame.WIDTH, MyGame.HEIGHT ); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.newdawn.slick.Game; | |
import org.newdawn.slick.GameContainer; | |
import org.newdawn.slick.Graphics; | |
import org.newdawn.slick.SlickException; | |
public final class MyGame implements Game { | |
/* package */static final int WIDTH = 320; | |
/* package */static final int HEIGHT = 240; | |
/* package */static final int SCALE = 2; | |
@Override | |
public boolean closeRequested () { | |
return true; | |
} | |
@Override | |
public String getTitle () { | |
return "MyGame"; | |
} | |
@Override | |
public void init ( GameContainer cont ) throws SlickException { | |
} | |
@Override | |
public void update ( GameContainer cont, int delta ) throws SlickException { | |
} | |
@Override | |
public void render ( GameContainer cont, Graphics gr ) throws SlickException { | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment