aboutsummaryrefslogtreecommitdiffstats
path: root/src/ru/olamedia/game
diff options
context:
space:
mode:
authorolamedia <[email protected]>2012-12-23 11:30:36 +0600
committerolamedia <[email protected]>2012-12-23 11:30:36 +0600
commitf58bdfcb66353bb77213cab580bc49ef890417ad (patch)
tree2983a05d564891e92c115a679f9bfbf55465c755 /src/ru/olamedia/game
parent5320fd1dad5b77fa227e83fbbe0a958f2c5fc283 (diff)
0.1.7
Diffstat (limited to 'src/ru/olamedia/game')
-rw-r--r--src/ru/olamedia/game/GameFrame.java40
-rw-r--r--src/ru/olamedia/game/GameLogicThread.java76
-rw-r--r--src/ru/olamedia/game/GameManager.java143
-rw-r--r--src/ru/olamedia/game/GameTime.java71
-rw-r--r--src/ru/olamedia/game/Launcher.java4
5 files changed, 252 insertions, 82 deletions
diff --git a/src/ru/olamedia/game/GameFrame.java b/src/ru/olamedia/game/GameFrame.java
index 973fcb8..6227a15 100644
--- a/src/ru/olamedia/game/GameFrame.java
+++ b/src/ru/olamedia/game/GameFrame.java
@@ -4,8 +4,11 @@ import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Image;
import java.awt.Toolkit;
+import java.awt.event.KeyListener;
+import java.awt.im.InputContext;
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLProfile;
@@ -16,6 +19,7 @@ import ru.olamedia.asset.AssetNotFoundException;
import ru.olamedia.input.Keyboard;
import ru.olamedia.input.MouseJail;
import ru.olamedia.olacraft.OlaCraft;
+import ru.olamedia.olacraft.game.Game;
import jogamp.newt.awt.NewtFactoryAWT;
@@ -26,7 +30,6 @@ import com.jogamp.newt.event.KeyAdapter;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.util.Animator;
-import com.jogamp.opengl.util.FPSAnimator;
public class GameFrame {
// java.awt.SystemTray
@@ -54,8 +57,9 @@ public class GameFrame {
// ES2
caps = new GLCapabilities(glProfile);
caps.setHardwareAccelerated(true);
- caps.setDoubleBuffered(true);
- caps.setBackgroundOpaque(false);
+ caps.setDoubleBuffered(true); // hardware swap
+ caps.setBackgroundOpaque(true);
+ caps.setSampleBuffers(false);
display = NewtFactoryAWT.createDisplay(null);
screen = NewtFactoryAWT.createScreen(display, screenId);
@@ -63,15 +67,17 @@ public class GameFrame {
// caps);
newtCanvasAWT = new NewtCanvasAWT(glWindow);
glWindow.setUndecorated(false);
+ glWindow.setAutoSwapBufferMode(false);
glWindow.setPointerVisible(true);
glWindow.confinePointer(false);
glWindow.addWindowListener(new QuitAdapter());
animator = new Animator(glWindow);
- //animator = new FPSAnimator(glWindow, 60);
- //animator.setRunAsFastAsPossible(true); // By default there is a
- // brief
- // pause in the animation
- // loop
+ // animator.setUpdateFPSFrames(200, System.out);
+ // animator = new FPSAnimator(glWindow, 60);
+ animator.setRunAsFastAsPossible(true); // By default there is a
+ // brief
+ // pause in the animation
+ // loop
animator.start();
glWindow.addMouseListener(MouseJail.instance);
glWindow.addKeyListener(Keyboard.instance);
@@ -84,8 +90,14 @@ public class GameFrame {
glWindow.setPointerVisible(true);
}
}
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ super.keyPressed(e);
+ System.out.println(e.toString());
+ }
});
- // animator.setUpdateFPSFrames(100, System.err);
+ //animator.setUpdateFPSFrames(1000, System.err);
jFrame.add(newtCanvasAWT);
glWindow.addGLEventListener(GameManager.instance);
}
@@ -121,6 +133,14 @@ public class GameFrame {
return glWindow.getWidth();
}
+ public static int getGLWidth() {
+ return Game.Display.getWidth();
+ }
+
+ public static int getGLHeight() {
+ return Game.Display.getHeight();
+ }
+
public static int getHeight() {
if (null == glWindow) {
return jFrame.getHeight();
@@ -130,6 +150,7 @@ public class GameFrame {
public GameFrame() {
instance = this;
+ // en.selectInputMethod(Locale.ENGLISH);
jFrame = new JFrame();
jFrame.setMinimumSize(new Dimension(200, 200));
jFrame.setSize(width, height);
@@ -139,6 +160,7 @@ public class GameFrame {
// glWindow.setLocation(100, 100);
jFrame.addWindowListener(new QuitAdapter());
jFrame.setVisible(true);
+
}
private void setIcons() {
diff --git a/src/ru/olamedia/game/GameLogicThread.java b/src/ru/olamedia/game/GameLogicThread.java
new file mode 100644
index 0000000..ec95aee
--- /dev/null
+++ b/src/ru/olamedia/game/GameLogicThread.java
@@ -0,0 +1,76 @@
+package ru.olamedia.game;
+
+import java.util.Random;
+
+import ru.olamedia.olacraft.game.Game;
+import ru.olamedia.olacraft.game.Timer;
+import ru.olamedia.olacraft.scene.GameScene;
+import ru.olamedia.olacraft.world.chunk.ChunkUnavailableException;
+
+public class GameLogicThread extends Thread {
+ public static GameLogicThread instance = new GameLogicThread("Game logic");
+ private Timer fpsTimer = new Timer();
+
+ public GameLogicThread(String name) {
+ super(name);
+
+ }
+
+ private Random rand = new Random();
+
+ @Override
+ public synchronized void start() {
+ super.start();
+ fpsTimer.initialize();
+ fpsTimer.update();
+ }
+
+ private float delta;
+
+ private void tick() {
+ fpsTimer.update();
+ delta = (float) fpsTimer.getElapsedTime() / 1000f;
+ if (rand.nextFloat() > 0.95f) {
+ Game.client.getScene().dayTime.tick();
+ }
+ // bullets.update(Game.instance.getDelta());
+ // physics.getWorld().step(Game.instance.getDelta());
+ if (Game.client.getScene().isInitialized && null != Game.client.getScene().player) {
+ Game.client.getScene().player.camera.setAspect(Game.Display.getAspect());
+ try {
+ Game.client.getScene().player.updateKeyboard(delta);
+ } catch (ChunkUnavailableException e) {
+ e.printStackTrace();
+ }
+ if (Game.client.getScene().player.isOrientationChanged || Game.instance.camera.isOrientationChanged) {
+ Game.client.getScene().player.isOrientationChanged = false;
+ Game.instance.camera.isOrientationChanged = false;
+ updateNearestBlock();
+ }
+ }
+ }
+
+ private void updateNearestBlock() {
+ final GameScene scene = Game.client.getScene();
+ if (null != scene.player && null != scene.pickSlice) {
+ scene.pickSlice.setCenter(scene.player.getCameraX(), scene.player.getCameraY(), scene.player.getCameraZ());
+ scene.nearestBlock = scene.pickSlice.getNearest(Game.instance.camera);
+ scene.nearestPutBlock = scene.pickSlice.getNearestPutBlock();
+ }
+ }
+
+ @Override
+ public void run() {
+ while (true) {
+ try {
+ tick();
+ Thread.sleep(50);
+ // Thread.sleep(10); // or wait/join etc
+ } catch (InterruptedException ex) {
+ // cleanup here
+ Thread.currentThread().interrupt(); // for nested loops
+ break;
+ }
+ }
+ }
+}
diff --git a/src/ru/olamedia/game/GameManager.java b/src/ru/olamedia/game/GameManager.java
index 7118c85..7e1ed71 100644
--- a/src/ru/olamedia/game/GameManager.java
+++ b/src/ru/olamedia/game/GameManager.java
@@ -1,27 +1,25 @@
package ru.olamedia.game;
-import java.nio.FloatBuffer;
+import java.awt.event.KeyListener;
import java.util.Set;
import javax.media.opengl.GL;
-import javax.media.opengl.GL2;
import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GL3;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
-import javax.media.opengl.GLUniformData;
-import javax.media.opengl.fixedfunc.GLMatrixFunc;
-import javax.media.opengl.glu.GLU;
import ru.olamedia.olacraft.game.Game;
import ru.olamedia.olacraft.network.discovery.DiscoveryThread;
import ru.olamedia.olacraft.render.jogl.DefaultRenderer;
import ru.olamedia.olacraft.render.jogl.IRenderer;
+import ru.olamedia.olacraft.world.blockRenderer.ChunkMeshGarbageCollector;
+import ru.olamedia.olacraft.world.chunk.Chunk;
import ru.olamedia.olacraft.world.chunk.ChunkMeshBulder;
import ru.olamedia.olacraft.world.location.BlockLocation;
import ru.olamedia.tasks.TaskManager;
import com.jogamp.opengl.JoglVersion;
-import com.jogamp.opengl.util.PMVMatrix;
public class GameManager implements GLEventListener {
public static GameManager instance;
@@ -36,34 +34,79 @@ public class GameManager implements GLEventListener {
tests();
}
+ private void assertBoolean(boolean val) {
+ if (!val) {
+ throw new RuntimeException("Assert failed");
+ }
+ }
+
private void tests() {
+ System.out.println("====TESTS====");
+ // Game.client.getWorldProvider().loadChunk(new ChunkLocation());
+ // Game.client.getWorldProvider().loadChunk(new ChunkLocation(-1,0,0));
+ // Game.client.getWorldProvider().loadChunk(new ChunkLocation(0,0,-1));
+ // Game.client.getWorldProvider().loadChunk(new ChunkLocation(-1,0,-1));
BlockLocation b;
b = new BlockLocation(0, 0, 0);
- assert b.getChunkLocation().x == 0;
- assert b.getChunkLocation().getBlockLocation().x == 0;
+ assertBoolean(b.getChunkLocation().x == 0);
+ assertBoolean(b.getChunkLocation().getBlockLocation().x == 0);
b = new BlockLocation(14, 0, 0);
- assert b.getChunkLocation().x == 0;
- assert b.getChunkLocation().getBlockLocation().x == 0;
+ assertBoolean(b.getChunkLocation().x == 0);
+ assertBoolean(b.getChunkLocation().getBlockLocation().x == 0);
b = new BlockLocation(15, 0, 0);
- assert b.getChunkLocation().x == 0;
- assert b.getChunkLocation().getBlockLocation().x == 0;
+ assertBoolean(b.getChunkLocation().x == 0);
+ assertBoolean(b.getChunkLocation().getBlockLocation().x == 0);
b = new BlockLocation(16, 0, 0);
- assert b.getChunkLocation().x == 1;
- assert b.getChunkLocation().getBlockLocation().x == 0;
+ assertBoolean(b.getChunkLocation().x == 1);
+ assertBoolean(b.getChunkX() == Chunk.v(b.x));
+ assertBoolean(b.getChunkY() == Chunk.v(b.y + 128));
+ assertBoolean(b.getChunkZ() == Chunk.v(b.z));
+ // failed assertBoolean(b.getChunkLocation().getBlockLocation().x == 0);
b = new BlockLocation(-1, 0, 0);
- assert b.getChunkLocation().x == -1;
- assert b.getChunkLocation().getBlockLocation().x == -1;
+ assertBoolean(b.getChunkLocation().x == -1);
+ assertBoolean(b.getChunkX() == Chunk.v(b.x));
+ assertBoolean(b.getChunkY() == Chunk.v(b.y + 128));
+ assertBoolean(b.getChunkZ() == Chunk.v(b.z));
+ // failed assertBoolean(b.getChunkLocation().getBlockLocation().x ==
+ // -1);
b = new BlockLocation(-14, 0, 0);
- assert b.getChunkLocation().x == -1;
+ assertBoolean(b.getChunkLocation().x == -1);
+ assertBoolean(b.getChunkX() == Chunk.v(b.x));
+ assertBoolean(b.getChunkY() == Chunk.v(b.y + 128));
+ assertBoolean(b.getChunkZ() == Chunk.v(b.z));
b = new BlockLocation(-15, 0, 0);
- assert b.getChunkLocation().x == -1;
- assert b.getChunkLocation().getBlockLocation().x == -1;
+ assertBoolean(b.getChunkLocation().x == -1);
+ assertBoolean(b.getChunkX() == Chunk.v(b.x));
+ assertBoolean(b.getChunkY() == Chunk.v(b.y + 128));
+ assertBoolean(b.getChunkZ() == Chunk.v(b.z));
+ // failed assertBoolean(b.getChunkLocation().getBlockLocation().x ==
+ // -1);
b = new BlockLocation(-16, 0, 0);
- assert b.getChunkLocation().x == -1;
- assert b.getChunkLocation().getBlockLocation().x == -1;
+ assertBoolean(b.getChunkLocation().x == -1);
+ // failed assertBoolean(b.getChunkLocation().getBlockLocation().x ==
+ // -1);
+
+ assertBoolean(b.getByteX() == 0);
+ assertBoolean(b.getByteY() == 0);
+ assertBoolean(b.getByteZ() == 0);
+ assertBoolean(b.getChunkX() == Chunk.v(b.x));
+ assertBoolean(b.getChunkY() == Chunk.v(b.y + 128));
+ assertBoolean(b.getChunkZ() == Chunk.v(b.z));
b = new BlockLocation(-17, 0, 0);
- assert b.getChunkLocation().x == -2;
- assert b.getChunkLocation().getBlockLocation().x == -17;
+ assertBoolean(b.getChunkLocation().x == -2);
+ // assertBoolean(b.getChunkLocation().getBlockLocation().x == -17);
+ assertBoolean(b.getByteX() == 15);
+ assertBoolean(b.getByteY() == 0);
+ assertBoolean(b.getByteZ() == 0);
+ int id = Chunk.in(b.x) * 16 * 16 + Chunk.in(b.y) * 16 + Chunk.in(b.z);
+ System.out.print(b.getChunkX() + "/" + Chunk.v(b.x));
+ assertBoolean(b.getId() == id);
+ assertBoolean(b.getChunkX() == Chunk.v(b.x));
+ assertBoolean(b.getChunkY() == Chunk.v(b.y + 128));
+ assertBoolean(b.getChunkZ() == Chunk.v(b.z));
+ // ChunkData data = new ChunkData();
+ // data.setVoidLight(18, (byte) 6);
+ // assert data.getVoidLight(18) == 6;
}
private void createServerGame() {
@@ -114,11 +157,31 @@ public class GameManager implements GLEventListener {
menu = new MainMenu();
this.renderer = new DefaultRenderer();
GameFrame.getFrame().getContentPane().add(menu);
- menu.setVisible(true);
- GameFrame.getFrame().validate();
+ GameFrame.getFrame().getContentPane().repaint();
+ GameFrame.getFrame().addKeyListener(new KeyListener() {
+ @Override
+ public void keyTyped(java.awt.event.KeyEvent e) {
+ System.out.println(e.toString());
+ }
+ @Override
+ public void keyReleased(java.awt.event.KeyEvent e) {
+ System.out.println(e.toString());
+ }
+
+ @Override
+ public void keyPressed(java.awt.event.KeyEvent e) {
+ System.out.println(e.toString());
+ }
+ });
+ // GameFrame.getFrame().getContentPane().validate();
+ // GameFrame.getFrame().validate();
+ // GameFrame.getFrame().getContentPane().paintComponents(GameFrame.getFrame().getContentPane().getGraphics());
+ // GameFrame.getFrame().validate();
+ // menu.setVisible(true);
+ // GameFrame.getFrame().setVisible(true);
}
- private PMVMatrix m;
+
private void glTest(GLAutoDrawable drawable) {
// m = new PMVMatrix(true);
// m.glGetMviMatrixf();
@@ -157,7 +220,7 @@ public class GameManager implements GLEventListener {
// for (int i = 0; i < 16; i++) {
// System.out.println(pmv.get(i) + " == " + glmv.get(i));
// }
- // System.exit(0);
+ // System.exit(0);
}
public void start() {
@@ -188,6 +251,12 @@ public class GameManager implements GLEventListener {
if (ChunkMeshBulder.instance.isAlive()) {
ChunkMeshBulder.instance.interrupt();
}
+ if (GameLogicThread.instance.isAlive()) {
+ GameLogicThread.instance.interrupt();
+ }
+ if (ChunkMeshGarbageCollector.instance.isAlive()) {
+ ChunkMeshGarbageCollector.instance.interrupt();
+ }
// Get all threads
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for (Thread t : threadSet) {
@@ -204,6 +273,8 @@ public class GameManager implements GLEventListener {
public void init(GLAutoDrawable drawable) {
// GLContext.getContext().getGL()
GL2ES2 gl = drawable.getGL().getGL2ES2();
+ drawable.setAutoSwapBufferMode(false);
+ gl.setSwapInterval(0);
// drawable.setGL(new DebugGL2ES2(gl));
System.err.println(JoglVersion.getGLInfo(drawable.getGL(), null));
System.err.println(Thread.currentThread() + " Chosen GLCapabilities: " + drawable.getChosenGLCapabilities());
@@ -226,16 +297,28 @@ public class GameManager implements GLEventListener {
@Override
public void display(GLAutoDrawable drawable) {
- GL2ES2 gl = drawable.getGL().getGL2ES2();
- gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+ final GL3 gl = drawable.getGL().getGL3();
+ // gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
// gl.glClearColor(0.2f, 0.2f, 0.2f, 1);
renderer.render(drawable);
+ // Different GL implementations buffer commands in several different
+ // locations, including network buffers and the graphics accelerator
+ // itself. glFlush empties all of these buffers, causing all issued
+ // commands to be executed as quickly as they are accepted by the actual
+ // rendering engine. Though this execution may not be completed in any
+ // particular time period, it does complete in finite time.
+ //gl.glF
+ //gl.glFlush();
+ //gl.glFinish();
+ //gl.glFlush();
+ drawable.swapBuffers();
}
@Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
- GL gl = drawable.getGL().getGL2ES2();
+ final GL gl = drawable.getGL().getGL2ES2();
gl.glViewport(0, 0, width, height);
+ renderer.reshape(drawable);
}
public void showMainMenu() {
diff --git a/src/ru/olamedia/game/GameTime.java b/src/ru/olamedia/game/GameTime.java
index bd687d9..1d243ad 100644
--- a/src/ru/olamedia/game/GameTime.java
+++ b/src/ru/olamedia/game/GameTime.java
@@ -1,5 +1,6 @@
package ru.olamedia.game;
+import java.nio.FloatBuffer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
@@ -8,6 +9,8 @@ import java.util.TimeZone;
import ru.olamedia.astronomy.SunCalendar;
public class GameTime {
+ public FloatBuffer sunColor = FloatBuffer.allocate(4);
+
public static class SunCalc {
private GameTime time;
private int r = 450;
@@ -94,63 +97,46 @@ public class GameTime {
return new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(new Date((long) (gameTime * 1000)));
}
- private static float addComponent(float a, float b) {
- return a + b;
- }
+ private final float[] spaceColors = new float[] { 0.03f, 0.03f, 0.05f };
+ private final float[] sunSkyColors = new float[] { (float) 203 / 255, (float) 233 / 255, (float) 244 / 255 };
+ private final float[] sunRedColorsAdd = new float[] { 0.3f, 0.1f, 0.0f };
+ private final float sunAngularDiameter = 32;
+ private final float sunRenderDistance = 700;
+ private final float sunRenderDiameter = (float) ((float) 2 * sunRenderDistance * Math.tan(sunAngularDiameter / 2)) / 15f;
- private static float mulComponent(float a, float b) {
- return a * b;
+ public float[] getClearColor() {
+ return clearColors;
}
- public float[] getClearColor() {
- float sunAngularDiameter = 32;
- float sunRenderDistance = 700;
- @SuppressWarnings("unused")
- float sunRenderDiameter = (float) ((float) 2 * sunRenderDistance * Math.tan(sunAngularDiameter / 2));
+ public float[] updateClearColor() {
- sunRenderDiameter /= 15;
+ // a little
+ // blue
- float[] spaceColors = new float[] { 0.03f, 0.03f, 0.05f }; // a little
- // blue
+ clearColors[0] = 0;
+ clearColors[1] = 0;
+ clearColors[2] = 0;
- clearColors = new float[] { 0.0f, 0.0f, 0.0f };
+ final double crossAngle = sunCalendar.getHourAngle();
- double crossAngle = sunCalendar.getHourAngle();
- @SuppressWarnings("unused")
- int elevationAngle = (int) sunCalendar.radToDeg(sunCalendar.getElevationAngle());
+ final float minSunlightFactor = 0.2097152f;
+ final float maxSunlightFactor = (1f - minSunlightFactor);
+ sunlightFactor = minSunlightFactor;
- sunlightFactor = 0f;
if ((crossAngle > -120 && crossAngle < -70) || (crossAngle > 70 && crossAngle < 120)) {
- sunlightFactor = (float) 1f - (Math.abs(crossAngle) - 70) / 50;
+ sunlightFactor = minSunlightFactor + maxSunlightFactor * ((float) 1f - (Math.abs(crossAngle) - 70) / 50);
}
if (crossAngle >= -70 && crossAngle <= 70) {
sunlightFactor = (float) 1f;
}
- int sunlight = (int) Math.round(15 * sunlightFactor);
- if (sunlight != lastSunLight) {
- spaceLightIsInvalid = true;
- receivedLightIsInvalid = true;
- }
- //float[] sunSkyColors = new float[] { (float) 179 / 255, (float) 195 / 255, (float) 184 / 255 };
- //float[] sunSkyColors = new float[] { (float) 209 / 255, (float) 227 / 255, (float) 251 / 255 };
- float[] sunSkyColors = new float[] { (float) 203 / 255, (float) 233 / 255, (float) 244 / 255 };
- for (int i = 0; i < 3; i++) {
- clearColors[i] = addComponent(sunSkyColors[i] * (float) sunlightFactor, spaceColors[i]);
- }
- float lightness = clearColors[0] + clearColors[1] + clearColors[2];
- float[] sunRedColorsAdd = new float[] { 0.3f, 0.1f, 0.0f };
- for (int i = 0; i < 3; i++) {
- if (sunlightFactor < 0.5f && sunlightFactor > 0.0f) {
- float redFactor = (float) (1 - Math.abs(1 - sunlightFactor * 4));
- clearColors[i] = addComponent(clearColors[i], (float) sunRedColorsAdd[i] * redFactor);
- }
- clearColors[i] = mulComponent(clearColors[i], (float) sunlightFactor);
- }
- // fix lightness
- float newLightness = clearColors[0] + clearColors[1] + clearColors[2];
+
for (int i = 0; i < 3; i++) {
- clearColors[i] = clearColors[i] * lightness / newLightness;
+ clearColors[i] = (float) (sunSkyColors[i] * sunlightFactor + spaceColors[i] * (1 - sunlightFactor));
}
+ sunColor.position(0);
+ sunColor.put(clearColors);
+ sunColor.put(3, 1f);
+ sunColor.position(0);
return clearColors;
}
@@ -166,6 +152,7 @@ public class GameTime {
// noon
sunEA = Math.floor(sunCalendar.getElevationAngle() * 1000) / 1000;
sunTC = Math.floor(sunCalendar.getTimeCorrectionFactor() * 1000) / 1000;
+ updateClearColor();
}
}
diff --git a/src/ru/olamedia/game/Launcher.java b/src/ru/olamedia/game/Launcher.java
index 7849468..c7ceca0 100644
--- a/src/ru/olamedia/game/Launcher.java
+++ b/src/ru/olamedia/game/Launcher.java
@@ -5,11 +5,13 @@ public class Launcher {
public Launcher() {
}
+ private static GameManager manager;
+
/**
* @param args
*/
public static void main(String[] args) {
- GameManager manager = new GameManager();
+ manager = new GameManager();
manager.start();
manager.dispose();
}