package client.game;
import static org.lwjgl.opengl.GL11.*;
import general.datastructures.Rectangle;
import general.datastructures.Vector2f;
import general.exceptions.IllegalPlayerCountException;
import general.helperclasses.Math;
import java.io.IOException;
import java.util.Vector;
import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.PixelFormat;
import client.ogl.Texture;
import client.ogl.TextureLoader;
import server.UnitManager;
import server.player.HumanPlayer;
import server.player.Player;
import server.sprite.Sprite;
import server.world.OldMap;
/**
*
* @author Tim Meurer
* @version 0.5.0
* @since 0.5.0
*
*/
public abstract class Game extends Thread{
protected final String GAME_TITLE;
protected final boolean FULLSCREEN;
protected final int HORIZONTAL_RESOLUTION;
protected final int VERTICAL_RESOLUTION;
protected final int AA_SAMPLES;
protected final int FRAMERATE;
protected final boolean VSYNC;
protected UnitManager unitManager;
protected boolean isFinished = false;
protected Rectangle viewport;
protected OldMap map;
protected Vector<Player> players;
protected int playercount;
public OldMap getMap()
{
return map;
}
public Player getPlayer(int id)
{
//TODO fehler ueberpruefung
return players.elementAt(id);
}
public Rectangle getViewport()
{
return this.viewport;
}
public UnitManager getUnitManager()
{
return this.unitManager;
}
public Game(String title, boolean fullscreen, int horizontal_resolution, int vertical_resolution, int AA_Samples, int target_Framerate, boolean V_Sync)
{
this.GAME_TITLE = title;
this.FULLSCREEN = fullscreen;
this.VERTICAL_RESOLUTION = vertical_resolution;
this.HORIZONTAL_RESOLUTION = horizontal_resolution;
this.AA_SAMPLES = AA_Samples;
this.FRAMERATE = target_Framerate;
this.VSYNC = V_Sync;
}
protected void init() throws LWJGLException, IllegalPlayerCountException, IOException
{
viewport = new Rectangle(0, HORIZONTAL_RESOLUTION, 0, VERTICAL_RESOLUTION);
oglInit();
map = OldMap.createTemplateMap(OldMap.TEMPLATE_ISLAND, 2);
unitManager = new UnitManager(this);
players = new Vector<Player>();
//TODO
players.add(new HumanPlayer(this, unitManager.getThreadGroup(), "Human-Player",map.getSpawnPoint(0)));
}
private void oglInit() throws LWJGLException
{
DisplayMode[] dm = Display.getAvailableDisplayModes();
for(DisplayMode mode :dm)
{
if((mode.getWidth() == HORIZONTAL_RESOLUTION) && (mode.getHeight() == VERTICAL_RESOLUTION) && (mode.getBitsPerPixel() == 32) && (mode.getFrequency()==60) )
{
System.out.println(mode.toString());
Display.setDisplayMode(mode);
break;
}
}
//Display.setDisplayMode(dm[0]);
Display.setTitle(GAME_TITLE);
Display.setFullscreen(false);
Display.create(new PixelFormat(8,0,0,AA_SAMPLES));
//vsync
Display.setVSyncEnabled(VSYNC);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, Display.getDisplayMode().getWidth(), Display.getDisplayMode().getHeight(), 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.4f);
glClearColor(0.1f, 0.5f, 1.0f, 1.0f);
TextureLoader.init();
TextureLoader.setDirectory("client/assets/textures/");
}
public void run()
{
try {
long oldtime = getTime();
long gametime = getTime() - oldtime;
long counter = 0;
long fpstime = 0;
this.init();
while (!isFinished)
{
if(counter>100)
{
System.out.println("Graphic-FPS: "+(float)counter/((float)(getTime()-fpstime)/1000));
counter = 0;
fpstime = getTime();
}
if (Display.isCloseRequested())
{
isFinished = true;
}
gametime = getTime() - oldtime;
oldtime = getTime();
this.update(gametime);
this.draw(gametime);
counter++;
//Display.sync(60);
}
this.cleanup();
} catch (LWJGLException e) {
e.printStackTrace();
System.out.println("Das Spiel wurde unerwartet beendet!");
} catch (IllegalPlayerCountException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
protected void cleanup()
{
unitManager.cleanup();
Display.destroy();
}
public void drawSprite(int id)
{
Sprite s = unitManager.getSprite(id);
Texture tex = s.getTexture();
Vector2f wc_position = s.getPosition();
float rotation = s.getRotation();
if(map.isInMap(Math.worldToMap(wc_position, map.getTilesize())) && viewport.scale_cpy(1.1f).isInside(wc_position))
{
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
glPushMatrix();
tex.bind();
glTranslatef(Math.worldToScreen(wc_position.x(),viewport.getLeft()), Math.worldToScreen(wc_position.y(),viewport.getTop()), 0f);
glRotatef(rotation, 0, 0, 1.0f);
//glTranslatef(-texture.getImageWidth()/2, -texture.getImageHeight()/2, 0);
glVertexPointer(2, 0, s.getVertexBuffer());
glTexCoordPointer(2, 0, s.getTextureBuffer());
glDrawArrays(GL_QUADS, 0, 4);
glPopMatrix();
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}
}
public void drawMap()
{
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
glPushMatrix();
for(int mapX=(int)(viewport.getLeft() / map.getTilesize())-1; mapX<=(viewport.getRight() / map.getTilesize())+1; mapX++)
{
for(int mapY=(int)(viewport.getTop() / map.getTilesize()-1); mapY<=(viewport.getBottom() / map.getTilesize())+1; mapY++)
{
if(map.isInMap(new Vector2f(mapX, mapY)))
{
float screenX = Math.mapToScreen(mapX, viewport.getLeft(), map.getTilesize());
float screenY = Math.mapToScreen(mapY, viewport.getTop(), map.getTilesize());
map.BindMapTexture(map.getData(mapX, mapY));
glTranslatef(screenX, screenY, 0f);
glVertexPointer(2, 0, map.getVertexBuffer());
glTexCoordPointer(2, 0, map.getTextureBuffer());
glDrawArrays(GL_QUADS, 0, 4);
glTranslatef(-screenX, -screenY, 0f);
}
}
}
glPopMatrix();
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}
public void draw(long gametime)
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
drawMap();
for(int i=0; i<unitManager.getSpriteCount(); i++)
{
drawSprite(i);
}
Display.update();
}
protected void handleInput()
{
while(Keyboard.next())
{
int key = Keyboard.getEventKey();
if(key == Keyboard.KEY_ESCAPE)
{
isFinished = true;
}
else if(key == Keyboard.KEY_ADD)
{
if(Keyboard.getEventKeyState())
{
String name = "Panzer " + (unitManager.getSpriteCount()+1);
//TODO playerID anpassen
//Vector2f spawnpos = new Vector2f(Math.screenToMap(Mouse.getX(), viewport.getLeft(), map.getTilesize()), Math.screenToMap(VERTICAL_RESOLUTION-Mouse.getY(), viewport.getLeft(), map.getTilesize()));
Vector2f sc_spawnpos = new Vector2f(Mouse.getX(),VERTICAL_RESOLUTION-Mouse.getY());
unitManager.createSprite(name, "tank.png", sc_spawnpos, 1, players.elementAt(0));
}
}
}
if(Keyboard.isKeyDown(Keyboard.KEY_LEFT))
{
viewport.move(new Vector2f(-2f, 0));
}
else if(Keyboard.isKeyDown(Keyboard.KEY_RIGHT))
{
viewport.move(new Vector2f(2f, 0));
}
if(Keyboard.isKeyDown(Keyboard.KEY_UP))
{
viewport.move(new Vector2f(0, -2f));
}
else if(Keyboard.isKeyDown(Keyboard.KEY_DOWN))
{
viewport.move(new Vector2f(0, 2f));
}
while(Mouse.next())
{
int mouseButton = Mouse.getEventButton();
Vector2f sc_mousePos = new Vector2f(Mouse.getX(),VERTICAL_RESOLUTION-Mouse.getY());
//System.out.println(mousePos);
if(mouseButton == 0 && Mouse.getEventButtonState())
{
((HumanPlayer)players.get(0)).selectSprite(sc_mousePos);
}
else if (mouseButton == 1 && Mouse.getEventButtonState())
{
System.out.println(sc_mousePos);
((HumanPlayer)players.get(0)).spriteAction(sc_mousePos);
}
}
}
public abstract void update(long gametime);
private static long timerTicksPerSecond = Sys.getTimerResolution();
public static long getTime()
{
//return System.currentTimeMillis();
return (Sys.getTime() * 1000) / timerTicksPerSecond;
}
}