This is a mono java class game demonstration to play with ABC of game development.
see gist project for details
Build with :
$> mvn clean compile
Play with :
$> mvn exec:java
McG.
This is a mono java class game demonstration to play with ABC of game development.
see gist project for details
Build with :
$> mvn clean compile
Play with :
$> mvn exec:java
McG.
/** | |
* Project -=-=( DemoGame )=-=- | |
* | |
* This project aims at demobstrate basics for simple game. | |
* | |
* @author Frédéric Delorme <[email protected]> | |
* @since 2019 | |
*/ | |
import java.awt.Color; | |
import java.awt.Dimension; | |
import java.awt.Font; | |
import java.awt.Graphics2D; | |
import java.awt.Point; | |
import java.awt.RadialGradientPaint; | |
import java.awt.Rectangle; | |
import java.awt.RenderingHints; | |
import java.awt.event.ComponentAdapter; | |
import java.awt.event.ComponentEvent; | |
import java.awt.event.KeyEvent; | |
import java.awt.event.KeyListener; | |
import java.awt.geom.Ellipse2D; | |
import java.awt.image.BufferStrategy; | |
import java.awt.image.BufferedImage; | |
import java.nio.charset.StandardCharsets; | |
import java.util.ArrayList; | |
import java.util.Collections; | |
import java.util.Comparator; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.ResourceBundle; | |
import javax.swing.JFrame; | |
/** | |
* A <code>DemoGame</code> class to demonstrate some basics to create a simple | |
* java game. | |
* | |
* This will implement all needed operations from capturing user | |
* <code>input()</code>, <code>update(float)</code> of game compoenets to | |
* <code>render(Garphics2D)</code> the objects in field of view. | |
* | |
* @author Frédéric Delorme | |
* @since 2019 | |
*/ | |
public class DemoGame implements KeyListener { | |
private static long goIndex = 0; | |
public class Configuration { | |
private ResourceBundle bundle = ResourceBundle.getBundle("game"); | |
public String title = bundle.getString("game.title"); | |
public int width = Integer.parseInt(bundle.getString("game.screen.width")); | |
public int height = Integer.parseInt(bundle.getString("game.screen.height")); | |
public int debug = Integer.parseInt(bundle.getString("game.debug")); | |
public int nbObjects = Integer.parseInt(bundle.getString("game.scene.objects.max")); | |
public int nbLights = Integer.parseInt(bundle.getString("game.scene.lights.max")); | |
public float scale = Float.parseFloat(bundle.getString("game.screen.scale")); | |
} | |
/** | |
* GameObject type of renndering definition. | |
* | |
* The <code>GameObjectType</code> define the nature of the object to be | |
* display. | |
* | |
* @author Frédéric Delorme <[email protected]> | |
* @since 2019 | |
*/ | |
public enum GameObjectType { | |
RECTANGLE, CIRCLE, IMAGE | |
} | |
/** | |
* Type of Light to be rendered. | |
*/ | |
public enum LightType { | |
CONE, SPHERE, AMBIANT; | |
} | |
/** | |
* Internal Class to manipulate simple Vector2D. | |
* | |
* @author Frédéric Delorme | |
* | |
*/ | |
public class Vector2D { | |
public double x, y; | |
public Vector2D() { | |
x = 0.0; | |
y = 0.0; | |
} | |
/** | |
* @param x | |
* @param y | |
*/ | |
public Vector2D(double x, double y) { | |
super(); | |
this.x = x; | |
this.y = y; | |
} | |
/** | |
* Compute distance between this vector and the vector <code>v</code>. | |
* | |
* @param v | |
* the vector to compute distance with. | |
* @return | |
*/ | |
public double distance(Vector2D v) { | |
double v0 = x - v.x; | |
double v1 = y - v.y; | |
return Math.sqrt(v0 * v0 + v1 * v1); | |
} | |
/** | |
* Normalization of this vector. | |
*/ | |
public Vector2D normalize() { | |
// sets length to 1 | |
// | |
double length = Math.sqrt(x * x + y * y); | |
if (length != 0.0) { | |
double s = 1.0f / (float) length; | |
x = x * s; | |
y = y * s; | |
} | |
return new Vector2D(x, y); | |
} | |
/** | |
* Add the <code>v</code> vector to this vector. | |
* | |
* @param v | |
* the vector to add to this vector. | |
* @return this. | |
*/ | |
public Vector2D add(Vector2D v) { | |
x += v.x; | |
y += v.y; | |
return this; | |
} | |
/** | |
* Multiply vector by a factor. | |
* | |
* @param factor | |
* the factor to multiply the vector by. | |
* @return this. | |
*/ | |
public Vector2D multiply(float factor) { | |
x *= factor; | |
y *= factor; | |
return this; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see java.lang.Object#toString() | |
*/ | |
@Override | |
public String toString() { | |
StringBuilder builder = new StringBuilder(); | |
builder.append("(").append(x).append(",").append(y).append(")"); | |
return builder.toString(); | |
} | |
/** | |
* Substract the Vector2D v to this current and return result. | |
* | |
* @param v | |
* vector2D to be substracted. | |
* @return Vector2D resulting of substraction. | |
*/ | |
public Vector2D substract(Vector2D v) { | |
return new Vector2D(x - v.x, y - v.y); | |
} | |
/** | |
* Dot product for current instance {@link Vector2D} and the <code>v1</code> | |
* vector. | |
* | |
* @param v1 | |
* @return | |
*/ | |
public double dot(Vector2D v1) { | |
return this.x * v1.x + this.y * v1.y; | |
} | |
} | |
/** | |
* The <code>GameObject</code> class defines any object managed and displayed by | |
* the game. | |
* | |
* @author Frédéric Delorme <[email protected]> | |
* @since 2019 | |
*/ | |
public class GameObject { | |
private final int id = (int) goIndex++; | |
public String name = "noname_" + id; | |
public BufferedImage imageBuffer; | |
public Vector2D position = new Vector2D(); | |
public Vector2D size = new Vector2D(); | |
public Vector2D speed = new Vector2D(); | |
public Vector2D acceleration = new Vector2D(); | |
public int layer = 0; | |
public boolean fixed = false; | |
public int priority = 0; | |
public Rectangle bbox; | |
public GameObjectType type; | |
public Color foregroundColor = Color.RED; | |
public Color shadowColor = new Color(0.0f, 0.0f, 0.0f, 0.7f); | |
public Color backgroundColor = Color.BLACK; | |
public Map<String, Object> attributes = new HashMap<>(); | |
public GameObject(final String name, final double x, final double y, final double width, final double height) { | |
this.name = name; | |
this.position = new Vector2D(x,y); | |
this.size = new Vector2D(width, height); | |
this.type = GameObjectType.RECTANGLE; | |
} | |
public void update(final DemoGame dg, final long elapsed) { | |
position.x += speed.x * elapsed; | |
position.y += speed.y * elapsed; | |
} | |
public void setPosition(final double x, final double y) { | |
this.position.x = x; | |
this.position.y = y; | |
} | |
public void setSpeed(final double dx, final double dy) { | |
this.speed.x = dx; | |
this.speed.y = dy; | |
} | |
public void setAcceleration(final double ax, final double ay) { | |
this.acceleration.x = ax; | |
this.acceleration.y = ay; | |
} | |
} | |
/** | |
* The Camera Object will follow a target with a tweenfactor to delay camera | |
* move regarding object to be tracked. | |
* | |
* @author Frédéric Delorme <[email protected]> | |
* @since 2019 | |
*/ | |
class Camera extends GameObject { | |
private GameObject target; | |
private final double tweenFactor; | |
public Camera(final String name, final GameObject target, final double tweenFactor) { | |
super(name, 0, 0, 0, 0); | |
this.tweenFactor = tweenFactor; | |
this.target = target; | |
} | |
public void setTarget(final GameObject target) { | |
this.target = target; | |
} | |
@Override | |
public void update(final DemoGame dg, final long elapsed) { | |
position.x += position.x + (position.x - target.position.x) * elapsed * tweenFactor; | |
position.y += position.y + (position.y - target.position.y) * elapsed * tweenFactor; | |
} | |
public void preRender(final DemoGame dg, final Graphics2D g) { | |
g.translate(-position.x, -position.y); | |
} | |
public void postRender(final DemoGame dg, final Graphics2D g) { | |
g.translate(position.x, position.y); | |
} | |
} | |
/** | |
* Light is the LIght object for the Game. | |
*/ | |
public class Light extends GameObject { | |
LightType type; | |
GameObject target; | |
float intensity; | |
float[] dist = { 0f, 1f }; | |
Color[] colors = { new Color(0.0f, 0.0f, 0.0f, 0.0f), new Color(0.0f, 0.0f, 0.0f, 1.0f) }; | |
public Light(final String name, final LightType type, final double x, final double y, final double radius, | |
final float intensity, final GameObject target) { | |
super(name, x, y, radius, radius); | |
this.intensity = intensity; | |
this.type = type; | |
this.target = target; | |
} | |
} | |
/** | |
* The rendering class to draw anything on screen. | |
*/ | |
public class Renderer { | |
private DemoGame dg; | |
private JFrame jf; | |
BufferedImage screenBuffer; | |
BufferedImage lightBuffer; | |
BufferStrategy bs; | |
private final List<Camera> cameras = new ArrayList<>(); | |
private Camera camera; | |
public Renderer(DemoGame dg) { | |
super(); | |
this.dg = dg; | |
} | |
public void initialize() { | |
jf = new JFrame("DemoGame"); | |
final Dimension dim = new Dimension((int) (screenWidth * screenScale), (int) (screenHeight * screenScale)); | |
jf.setSize(dim); | |
jf.setPreferredSize(dim); | |
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | |
jf.addKeyListener(dg); | |
// create drawing buffers | |
screenBuffer = new BufferedImage(screenWidth, screenHeight, BufferedImage.TYPE_INT_ARGB); | |
lightBuffer = new BufferedImage(screenWidth, screenHeight, BufferedImage.TYPE_INT_ARGB); | |
// DisplayMode dm = | |
// GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode(); | |
jf.addComponentListener(new ComponentAdapter() { | |
public void componentResized(ComponentEvent componentEvent) { | |
float ratio = (float) dim.width / (float) dim.height; | |
float w = componentEvent.getComponent().getWidth(); | |
Dimension dim = new Dimension((int) w, (int) (w / ratio)); | |
jf.setSize(dim); | |
jf.setMaximumSize(dim); | |
jf.setMinimumSize(dim); | |
jf.setPreferredSize(dim); | |
jf.pack(); | |
} | |
}); | |
jf.setIgnoreRepaint(true); | |
jf.enableInputMethods(true); | |
jf.setLocationByPlatform(true); | |
jf.setLocationRelativeTo(null); | |
jf.setVisible(true); | |
bs = jf.getBufferStrategy(); | |
if (bs == null) { | |
jf.createBufferStrategy(4); | |
bs = jf.getBufferStrategy(); | |
} | |
jf.pack(); | |
jf.setVisible(true); | |
} | |
/** | |
* constrain go position to the Screen size. | |
* | |
* @param go | |
*/ | |
public void constrainToViewport(GameObject go) { | |
if (go.position.x + go.size.x > screenBuffer.getWidth()) { | |
go.position.x = screenBuffer.getWidth() - go.size.y; | |
go.speed.x = -go.speed.x; | |
} | |
if (go.position.y + go.size.y > screenBuffer.getHeight()) { | |
go.position.y = screenBuffer.getHeight() - go.size.y; | |
go.speed.y = -go.speed.y; | |
} | |
if (go.position.x < 0) { | |
go.position.x = 0; | |
go.speed.x = -go.speed.x; | |
} | |
if (go.position.y < 0) { | |
go.position.y = 0; | |
go.speed.y = -go.speed.y; | |
} | |
} | |
private void renderLight(DemoGame dg, Graphics2D g, Light l) { | |
switch (l.type) { | |
case SPHERE: | |
l.colors = new Color[] { l.foregroundColor, new Color(0.0f, 0.0f, 0.0f, 0.0f) }; | |
final RadialGradientPaint rgp = new RadialGradientPaint(new Point((int) l.position.x, (int) l.position.y), (int) l.size.x, | |
l.dist, l.colors); | |
g.setPaint(rgp); | |
g.fill(new Ellipse2D.Double(l.position.x - l.size.x, l.position.y - l.size.x, l.size.x * 2, l.size.x * 2)); | |
break; | |
case CONE: | |
// TODO implement the CONE light type | |
break; | |
case AMBIANT: | |
// TODO implement the AMBIANT light type | |
break; | |
} | |
} | |
private void renderGameObject(DemoGame dg, Graphics2D g, GameObject o) { | |
final double xRatio = (dg.screenWidth / o.position.x) * dg.light.position.x; | |
final double yRatio = (dg.screenHeight / o.position.y) * dg.light.position.x; | |
switch (o.type) { | |
case RECTANGLE: | |
g.setColor(o.shadowColor); | |
g.fillRect((int) (o.position.x + xRatio), (int) (o.position.y + yRatio), (int) o.size.x, (int) o.size.y); | |
g.setColor(o.foregroundColor); | |
g.fillRect((int) o.position.x, (int) o.position.y, (int) o.size.x, (int) o.size.y); | |
g.setColor(Color.BLACK); | |
g.drawRect((int) o.position.x, (int) o.position.y, (int) o.size.x, (int) o.size.y); | |
break; | |
case CIRCLE: | |
g.setColor(o.shadowColor); | |
g.fillOval((int) (o.position.x + xRatio), (int) (o.position.y + yRatio), (int) o.size.x, (int) o.size.y); | |
g.setColor(o.foregroundColor); | |
g.fillOval((int) o.position.x, (int) o.position.y, (int) o.size.x, (int) o.size.y); | |
g.setColor(Color.BLACK); | |
g.drawOval((int) o.position.x, (int) o.position.y, (int) o.size.x, (int) o.size.y); | |
break; | |
case IMAGE: | |
g.drawImage(o.imageBuffer, (int) o.position.x, (int) o.position.y, null); | |
break; | |
} | |
} | |
public void render(float realFPS) { | |
final Graphics2D g = (Graphics2D) screenBuffer.createGraphics(); | |
final Graphics2D lg = (Graphics2D) lightBuffer.createGraphics(); | |
// set Antialias for image and text rendering. | |
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); | |
// g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, | |
// RenderingHints.VALUE_TEXT_ANTIALIAS_GASP); | |
// clear image | |
g.setColor(Color.BLUE); | |
g.fillRect(0, 0, screenWidth, screenHeight); | |
// draw all objects | |
for (final GameObject go : objects) { | |
if (camera != null && !go.fixed) { | |
camera.preRender(dg, g); | |
} | |
renderGameObject(dg, g, go); | |
if (camera != null && !go.fixed) { | |
camera.postRender(dg, g); | |
} | |
} | |
if (debug > 1) { | |
g.setColor(new Color(0.6f, 0.6f, 0.6f, 0.6f)); | |
g.fillRect(0, screenHeight - 20, screenWidth, 20); | |
g.setColor(Color.ORANGE); | |
g.setFont(g.getFont().deriveFont(7)); | |
g.drawString(String.format("fps:%03d", realFps), 10, screenHeight - 8); | |
} | |
drawLights(g, false); | |
drawHUD(g); | |
g.dispose(); | |
// render image to real screen (applying scale factor) | |
renderToScreen(); | |
} | |
private void drawLights(Graphics2D gl, boolean clear) { | |
gl.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); | |
// gl.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, | |
// RenderingHints.VALUE_TEXT_ANTIALIAS_GASP); | |
if (clear) { | |
// Clear Light buffer | |
gl.setColor(new Color(0.0f, 0.0f, 0.0f, 0.6f)); | |
gl.clearRect(0, 0, lightBuffer.getWidth(), lightBuffer.getHeight()); | |
} | |
// draw all Lights | |
// gl.setComposite(AlphaComposite.DstIn); | |
for (final Light light : lights) { | |
// move camera according to settings | |
if (camera != null && !light.fixed) { | |
camera.preRender(dg, gl); | |
} | |
renderLight(dg, gl, light); | |
// move camera back according to settings | |
if (camera != null && !light.fixed) { | |
camera.postRender(dg, gl); | |
} | |
} | |
} | |
private void drawHUD(final Graphics2D g) { | |
Color shadowColor = new Color(0.3f, 0.3f, 0.3f, 0.8f); | |
// Draw Score | |
final int score = (Integer) player.attributes.get("score"); | |
drawOutLinedText(g, String.format("%05d", score), 4, 30, Color.WHITE, Color.BLACK, shadowColor, 4); | |
// Draw Life | |
final String lifeOn = new String("♥".getBytes(), StandardCharsets.UTF_8); | |
final String lifeOff = new String("♡".getBytes(), StandardCharsets.UTF_8); | |
final int life = (Integer) player.attributes.get("life"); | |
final int maxLife = (Integer) player.attributes.get("life-max"); | |
lifeStr = rep(life, lifeOn) + rep(maxLife - life, lifeOff); | |
drawOutLinedText(g, String.format("%s", lifeStr), screenWidth - 90, 30, Color.RED, Color.BLACK, shadowColor, | |
4); | |
} | |
private String rep(int a, final String k) { | |
if (a <= 0) { | |
return ""; | |
} else { | |
a--; | |
return k + rep(a, k); | |
} | |
} | |
/** | |
* Switch from active camera to <code>name</code> camera. | |
* | |
* @param name name of the camera to be active. | |
* @return | |
*/ | |
public Camera switchCamera(final String name) { | |
for (final Camera cam : renderer.cameras) { | |
if (cam.name.equals(name)) { | |
return cam; | |
} | |
} | |
return null; | |
} | |
private void renderToScreen() { | |
if (jf != null) { | |
final Graphics2D g = (Graphics2D) jf.getGraphics(); | |
if (g != null) { | |
g.drawImage(screenBuffer, 0, 0, jf.getWidth(), jf.getHeight(), 0, 0, screenWidth, screenHeight, | |
Color.BLACK, null); | |
/* | |
* if (lights.size() > 0) { g.drawImage(lightBuffer, 0, 0, jf.getWidth(), | |
* jf.getHeight(), 0, 0, screenWidth, screenHeight, null); } | |
*/ | |
g.dispose(); | |
} | |
} | |
} | |
} | |
private boolean exitRequest = false; | |
private final long fps = 60; | |
private long realFps = 0; | |
private final String[] argc; | |
Renderer renderer; | |
private final boolean[] keys = new boolean[65536]; | |
private final boolean[] previousKeys = new boolean[65536]; | |
private int screenWidth = 320, screenHeight = 200; | |
private float screenScale = 2.0f; | |
private final List<Light> lights = new ArrayList<>(); | |
private Light light; | |
private final List<GameObject> objects = new ArrayList<>(); | |
private GameObject player; | |
private String lifeStr = ""; | |
private int debug = 0; | |
public DemoGame(final String[] argc) { | |
super(); | |
this.argc = argc; | |
} | |
public void initialize() { | |
Configuration config = new Configuration(); | |
analyzeArgc(config); | |
renderer = new Renderer(this); | |
renderer.initialize(); | |
load(config); | |
} | |
public void load(Configuration config) { | |
player = new GameObject("player", screenWidth / 2, screenHeight / 2, 16, 16); | |
player.foregroundColor = Color.BLUE; | |
player.priority = 10; | |
player.attributes.put("life", new Integer(6)); | |
player.attributes.put("life-max", new Integer(6)); | |
player.attributes.put("score", new Integer(0)); | |
addObject(player); | |
for (int i = 0; i < config.nbObjects; i++) { | |
final double x = (Math.random() * screenWidth); | |
final double y = (Math.random() * screenHeight); | |
final float dx = (float) (Math.random() * 0.2f) + 0.05f; | |
final float dy = (float) (Math.random() * 0.2f) + 0.05f; | |
final GameObject go = new GameObject("object_" + i, x, y, 8, 8); | |
go.setSpeed(dx, dy); | |
go.priority = 100; | |
go.type = GameObjectType.CIRCLE; | |
go.foregroundColor = Color.ORANGE; | |
go.foregroundColor = new Color((float) Math.random(), (float) Math.random(), (float) Math.random()); | |
addObject(go); | |
} | |
for (int i = 0; i < config.nbLights; i++) { | |
final Light light = new Light("light_" + i, LightType.SPHERE, (double) (Math.random() * screenWidth), | |
(double) (Math.random() * screenHeight), (double) (Math.random() * 300.0 + 50.0), | |
(float) Math.random(), null); | |
light.foregroundColor = new Color((float) Math.random(), (float) Math.random(), (float) Math.random(), | |
0.8f); | |
final float dx = (float) (Math.random() * 0.02f) + 0.005f; | |
final float dy = (float) (Math.random() * 0.02f) + 0.005f; | |
light.setSpeed(dx, dy); | |
addObject(light); | |
} | |
final Camera cam = new Camera("cam", player, 0.02f); | |
addObject(cam); | |
} | |
public void loop() { | |
long startTime = System.currentTimeMillis(); | |
long previousTime = startTime; | |
long cumulatedTime = 0; | |
long framesCounter = 0; | |
while (!exitRequest) { | |
startTime = System.currentTimeMillis(); | |
final long elapsed = startTime - previousTime; | |
input(); | |
update(elapsed); | |
cumulatedTime += elapsed; | |
framesCounter += 1; | |
if (cumulatedTime > 1000) { | |
cumulatedTime = 0; | |
realFps = framesCounter; | |
framesCounter = 0; | |
} | |
render(realFps); | |
final long wait = (1000 / fps) - (System.currentTimeMillis() - startTime); | |
if (wait > 0) { | |
try { | |
Thread.sleep(wait); | |
} catch (final InterruptedException e) { | |
System.out.println(String.format("Unable to wait %d wait ms", wait)); | |
} | |
} | |
previousTime = startTime; | |
} | |
} | |
public void input() { | |
if (keys[KeyEvent.VK_ESCAPE]) { | |
exitRequest = true; | |
} | |
player.setSpeed(0.0f, 0.0f); | |
if (keys[KeyEvent.VK_UP]) { | |
player.speed.y = -0.2f; | |
} | |
if (keys[KeyEvent.VK_DOWN]) { | |
player.speed.y = 0.2f; | |
} | |
if (keys[KeyEvent.VK_LEFT]) { | |
player.speed.x = -0.2f; | |
} | |
if (keys[KeyEvent.VK_RIGHT]) { | |
player.speed.x = 0.2f; | |
} | |
if (keys[KeyEvent.VK_SPACE]) { | |
} | |
} | |
public void update(final long elapsed) { | |
for (final GameObject go : objects) { | |
go.update(this, elapsed); | |
renderer.constrainToViewport(go); | |
} | |
} | |
public void render(final long realFps) { | |
renderer.render(realFps); | |
} | |
public void run() { | |
System.out.println("Run game"); | |
initialize(); | |
loop(); | |
System.out.println("Game stopped"); | |
System.exit(0); | |
} | |
public void keyTyped(final KeyEvent e) { | |
} | |
public void keyPressed(final KeyEvent e) { | |
this.previousKeys[e.getKeyCode()] = this.keys[e.getKeyCode()]; | |
this.keys[e.getKeyCode()] = true; | |
} | |
public void keyReleased(final KeyEvent e) { | |
this.previousKeys[e.getKeyCode()] = this.keys[e.getKeyCode()]; | |
this.keys[e.getKeyCode()] = false; | |
} | |
public void drawOutLinedText(final Graphics2D g, final String text, final int x, final int y, final Color textColor, | |
final Color borderColor, final Color shadowColor, final int shadowOffset) { | |
final Font f = g.getFont(); | |
g.setFont(f.deriveFont(16.0f)); | |
g.setColor(shadowColor); | |
g.drawString(text, x + shadowOffset, y + shadowOffset); | |
g.setColor(borderColor); | |
g.drawString(text, x - 1, y); | |
g.drawString(text, x, y - 1); | |
g.drawString(text, x + 1, y); | |
g.drawString(text, x, y + 1); | |
g.setColor(textColor); | |
g.drawString(text, x, y); | |
g.setFont(f); | |
} | |
/** | |
* Analyze the argc array and set corresponding values. | |
*/ | |
private void analyzeArgc(Configuration config) { | |
screenWidth = config.width; | |
screenHeight = config.height; | |
screenScale = config.scale; | |
debug = config.debug; | |
for (final String arg : argc) { | |
System.out.println(String.format("arg: %s", arg)); | |
if (arg.contains("=")) { | |
final String[] parts = arg.toLowerCase().split("="); | |
switch (parts[0]) { | |
// Debug parameter value | |
case "d": | |
case "debug": | |
this.debug = Integer.parseInt(parts[1]); | |
break; | |
// Height parameter value | |
case "h": | |
case "height": | |
this.screenHeight = Integer.parseInt(parts[1]); | |
break; | |
// Width parameter value | |
case "w": | |
case "width": | |
this.screenWidth = Integer.parseInt(parts[1]); | |
break; | |
// Scale parameter value | |
case "s": | |
case "scale": | |
this.screenScale = Float.parseFloat(parts[1]); | |
break; | |
// Unknown parameter ! | |
default: | |
System.out.println(String.format("Unknown arguments '%s'", arg)); | |
break; | |
} | |
} | |
} | |
} | |
/** | |
* Add a GameObject to the objects to be managed by the game. | |
* | |
* If the Gameobject is a <code>Camera</code> instance, it will be added to the | |
* <code>cameras</code> List, and if not camera active, set to default one. | |
* | |
* @param go the GameObject to be added to the game engine. | |
*/ | |
public void addObject(final GameObject go) { | |
if (go instanceof Camera) { | |
if (renderer.camera == null) { | |
renderer.camera = (Camera) go; | |
} | |
renderer.cameras.add((Camera) go); | |
} else if (go instanceof Light) { | |
if (light == null) { | |
light = (Light) go; | |
} | |
lights.add((Light) go); | |
} else { | |
if (!objects.contains(go)) { | |
objects.add(go); | |
Collections.sort(objects, new Comparator<GameObject>() { | |
public int compare(final GameObject g1, final GameObject g2) { | |
return (g1.layer < g2.layer ? 1 : (g1.priority < g2.priority ? 1 : -1)); | |
} | |
}); | |
} | |
} | |
} | |
/** | |
* The main entry point for this awesome demo ! | |
*/ | |
public static void main(final String[] argc) { | |
final DemoGame dg = new DemoGame(argc); | |
dg.run(); | |
} | |
} |
game.title=test | |
game.screen.width=400 | |
game.screen.height=260 | |
game.screen.scale=2.0 | |
game.debug=0 | |
game.scene.objects.max=50 | |
game.scene.lights.max=5 |
<project xmlns="http://maven.apache.org/POM/4.0.0" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
<modelVersion>4.0.0</modelVersion> | |
<groupId>core</groupId> | |
<artifactId>oneclassgame</artifactId> | |
<version>0.0.1-SNAPSHOT</version> | |
<name>OneClassGame</name> | |
<description>A one class project (but with subclasses)</description> | |
<properties> | |
<maven.compiler.source>1.8</maven.compiler.source> | |
<maven.compiler.target>1.8</maven.compiler.target> | |
<project.mainClass>DemoGame</project.mainClass> | |
</properties> | |
<build> | |
<plugins> | |
<plugin> | |
<groupId>org.codehaus.mojo</groupId> | |
<artifactId>exec-maven-plugin</artifactId> | |
<version>1.6.0</version> | |
<executions> | |
<execution> | |
<goals> | |
<goal>java</goal> | |
</goals> | |
</execution> | |
</executions> | |
<configuration> | |
<mainClass>${project.mainClass}</mainClass> | |
</configuration> | |
</plugin> | |
</plugins> | |
</build> | |
</project> |