Hello, all! I just got back into LWJGL, trying to make a simple game. I'm making quite some good progress, and I just started building an Entity and Player class. The trouble is, when I render, it smudges! One thing I have tried is to release the texture every Entity 'tick'. That just makes the texture blank. I tried clearing the buffer bit, but that just makes the background black.
Screen Shot 2013-02-22 at 19.55.40.jpgScreen Shot 2013-02-22 at 20.28.20.jpg
Maybe one of you could point out where I need to insert some code to fix this, or remove code to fix this.
I will now show the code.
Game class:
DisplayScreen class:package cjaf; import org.lwjgl.LWJGLException; import org.lwjgl.opengl.*; public class Game{ public static void main(String[] args) { DisplayScreen ds = new DisplayScreen(); ds.start(640, 480); } }
package cjaf; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import static org.lwjgl.opengl.GL11.*; import org.lwjgl.LWJGLException; import org.lwjgl.opengl.Display; import org.lwjgl.opengl.DisplayMode; import org.newdawn.slick.opengl.Texture; import org.newdawn.slick.opengl.TextureLoader; public class DisplayScreen { public void start(int w, int h){ OnscreenRenderer or = null; or = new OnscreenRenderer(); try { Display.setDisplayMode(new DisplayMode(w, h)); Display.setTitle("CJAF2D"); Display.create(); } catch (LWJGLException e) { e.printStackTrace(); System.exit(911); } or.initGL(); while(!Display.isCloseRequested()){ //Render screen graphics. or.render(); //Update screen. or.update(); Display.update(); Display.sync(60); } Display.destroy(); System.exit(0); } }
The OnscreenRenderer class: (I know, I am using a lot of classes. I just like to keep it clean and neat.)
package cjaf; import static org.lwjgl.opengl.GL11.*; import java.util.ArrayList; import org.lwjgl.opengl.Display; import org.newdawn.slick.opengl.Texture; public class OnscreenRenderer { AdvancedDrawer renderer = new AdvancedDrawer(); Texture stone; int ticks = 0; boolean canStart = true; boolean hasOneSecondPassed = false; Thread t = new Thread(new Runnable(){ public void run(){ while(true){ try{ Thread.sleep(1000); }catch(Exception e){} Display.setTitle("CJAF2D - TPS: " + ticks); ticks = 0; } } }); ArrayList<Entity> e = new ArrayList<Entity>(); EntityHandler entityHandler = new EntityHandler(e); public OnscreenRenderer(){ t.start(); } public void initGL(){ stone = renderer.getTexture("stone.png"); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, 640, 480, 0, 1, -1); glMatrixMode(GL_MODELVIEW); glEnable(GL_TEXTURE_2D); } /**Render onscreen stuff**/ public void render(){ cleanScr(); //Clears the screen. renderer.drawTexture(stone, 0, 0, 640, 480); renderer.drawLine(305, 240, 335, 240); renderer.drawLine(320, 225, 320, 255); /* * Handle the entities. */ entityHandler.init(); } public void update(){ /* * This is where we start checking for input. */ /* * Above should be all of the update code. * Below is the tick incrementer. */ tick(); } /** * * Cleans the screen. */ public void cleanScr(){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } public void tick(){ ticks++; renderer.updateMouse(); } }
AdvancedDrawer class: (The problem MIGHT lie here....)
package cjaf; import static org.lwjgl.opengl.GL11.*; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.Display; import org.newdawn.slick.opengl.Texture; import org.newdawn.slick.opengl.TextureLoader; public class AdvancedDrawer { public int mouseX, mouseY; static final byte AD_FILL_RECT = 0; static final byte AD_NORM_RECT = 1; /** * Draws a line. It does this by connecting two points together. * @param pOneX : The x position of the first point. * @param pOneY : The y position of the first point. * @param pTwoX : The x position of the second point. * @param pTwoY : The y position of the second point.**/ public void drawLine(int pOneX, int pOneY, int pTwoX, int pTwoY){ glBegin(GL_LINES); glVertex2i(pOneX, pOneY); glVertex2i(pTwoX, pTwoY); glEnd(); } /** * Draws a rectangle. * @param x : The x position of the rectangle. * @param y : The y position of the rectangle. * @param w : The width of the rectangle. * @param h : The height of the rectangle. * @param option : The option of how to draw the rectangle * VALS: * 0 / AD_FILL_RECT: * Draws a rectangle filed. * 1 / AD_NORM_RECT: * Draws a normal rectangle.**/ public void drawRect(int x, int y, int w, int h, byte option){ switch (option) { case 0: glBegin(GL_QUADS); glVertex2i(x, y); glVertex2i(x+w, y); glVertex2i(x+w, y+h); glVertex2i(x, y+h); glEnd(); break; case 1: glBegin(GL_LINES); drawLine(x, y, x+w, y); drawLine(x+w, y, x+w, y+h); drawLine(x, y, x, y+h); drawLine(x, y+h, x+w, h+y); glEnd(); break; default: glBegin(GL_LINES); drawLine(x, y, x+w, y); drawLine(x+w, y, x+w, y+h); drawLine(x, y, x, y+h); drawLine(x, y+h, x+w, h+y); glEnd(); } } public void drawTri(){ } public Location getCenterOfScreen(){ return (new Location((640 / 2), (480 / 2))); } public void drawTexture(Texture texture, int x, int y, int w, int h){ texture.bind(); glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex2i(x, y); glTexCoord2f(1, 0); glVertex2i(x+w, y); glTexCoord2f(1, 1); glVertex2i(x+w, y+h); glTexCoord2f(0, 1); glVertex2i(x, y+h); glEnd(); } public Texture getTexture(String img){ try { return TextureLoader.getTexture("PNG", new FileInputStream(new File("res/"+img))); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } throw new RuntimeException("I found no file with the name "+img+"!"); } public void updateMouse(){ mouseX = Mouse.getX(); mouseY = Mouse.getY(); } }
The Location class: (It sounds useless, but whatever.)
package cjaf; public class Location { //Nice, clean, short code. :D private int x, y; public Location(int x, int y){ this.x = x; this.y = y; } int getX(){ return x; } int getY(){ return y; } void setX(int x){ this.x = x; } void setY(int y){ this.y = y; } void add(int x, int y){ this.x += x; this.y += y; } }
The Entity class:
package cjaf; import org.newdawn.slick.opengl.Texture; public abstract class Entity { protected Location loc; protected Texture texture; protected AdvancedDrawer renderer = new AdvancedDrawer(); protected byte health, maxHealth; public Location getLocation(){ return loc; } public void setLocation(Location loc){ this.loc = loc; } public byte getHealth(){ return health; } public byte getMaxHealth(){ return maxHealth; } public void setTexture(String file){ texture = renderer.getTexture(file); } public void draw(){ renderer.drawTexture(texture, loc.getX(), loc.getY(), 64, 64); } public void remove(){ } abstract void tick(); }
The EntityHandler class: (I think the bug lies here.
Please tell me if I am using an inefficient method of updating the Entity. I'm not very good with rendering and updating efficiently.)
package cjaf; import java.util.ArrayList; public class EntityHandler { AdvancedDrawer renderer = new AdvancedDrawer(); ArrayList<Entity> e; public EntityHandler(ArrayList<Entity> e){ this.e = e; } public void init(){ Player p = new Player(renderer.getCenterOfScreen()); p.draw(); e.add(p); /* * Handle entities. */ handle(); } public void handle(){ for(Entity ent : e){ ent.tick(); } } }
And finally, the Player class:
package cjaf; import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT; import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT; import static org.lwjgl.opengl.GL11.glClear; import org.lwjgl.input.Keyboard; public class Player extends Entity { public Player(Location loc){ this.loc = loc; this.setTexture("entities/player/player.png"); } void tick() { this.draw(); if(Keyboard.isKeyDown(Keyboard.KEY_W)){ getLocation().add(0, -1); }else if(Keyboard.isKeyDown(Keyboard.KEY_A)){ getLocation().add(-1, 0); }else if(Keyboard.isKeyDown(Keyboard.KEY_S)){ getLocation().add(0, 1); }else if(Keyboard.isKeyDown(Keyboard.KEY_D)){ getLocation().add(1, 0); } } }
Ok, I'm really sorry if the code gave you a headache reading.
But I try to make it as neat as possible.