Explorar el Código

depth testing, blending, entity collision tests

Kajetan Johannes Hammerle hace 5 años
padre
commit
8c019dcc5b

+ 1 - 2
shaders/fragment.fs

@@ -1,6 +1,6 @@
 #version 430
 
-layout (location = 0) in vec2 pos;
+layout (location = 0) in vec3 pos;
 layout (location = 1) in vec2 tex;
 layout (location = 2) in vec4 vertexColor;
 
@@ -8,7 +8,6 @@ layout (binding = 0) uniform sampler2D samp;
 
 uniform mat4 viewMatrix;
 uniform mat4 modelMatrix;
-uniform float depth;
 uniform vec3 ambientLight;
 
 struct Light 

+ 3 - 4
shaders/vertex.vs

@@ -1,6 +1,6 @@
 #version 430
 
-layout (location = 0) in vec2 pos;
+layout (location = 0) in vec3 pos;
 layout (location = 1) in vec2 tex;
 layout (location = 2) in vec4 vertexColor;
 
@@ -8,7 +8,6 @@ layout (binding = 0) uniform sampler2D samp;
 
 uniform mat4 viewMatrix;
 uniform mat4 modelMatrix;
-uniform float depth;
 uniform vec3 ambientLight;
 
 struct Light 
@@ -30,9 +29,9 @@ out vec4 vColor;
 
 void main(void)
 { 
-    loc = pos;
+    loc = pos.xy;
 
-    gl_Position = viewMatrix * modelMatrix * vec4(pos, depth, 1.0);
+    gl_Position = viewMatrix * modelMatrix * vec4(pos, 1.0);
 
     tc = tex;
     vColor = vertexColor;

+ 22 - 18
src/me/hammerle/snuviengine/api/ColorRenderer.java

@@ -15,11 +15,13 @@ public class ColorRenderer
     private ByteBuffer buffer = BufferUtils.createByteBuffer(48);
     
     private final static int BUFFER_BYTE_LENGTH = 1024 * 1024;
-    private final static int OBJECT_LENGTH = 48;
+    private final static int OBJECT_LENGTH = 64;
     
     private int offset = BUFFER_BYTE_LENGTH - OBJECT_LENGTH;
     
-    public ColorRenderer()
+    private float depth = 0.0f;
+    
+    protected ColorRenderer()
     {
         Shader.addTask(() -> 
         {
@@ -32,10 +34,17 @@ public class ColorRenderer
             glEnableVertexAttribArray(0);
             glEnableVertexAttribArray(2);
             
-            glVertexAttribPointer(0, 2, GL_FLOAT, false, 12, 0);
-            glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, true, 12, 8);
+            // 128 k - 130k
+            
+            glVertexAttribPointer(0, 3, GL_FLOAT, false, 16, 0);
+            glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, true, 16, 12);
         });
     }
+    
+    public void setDepth(float depth)
+    {
+        this.depth = depth;
+    }
 
     public void drawRectangle(float minX, float minY, float maxX, float maxY, int color)
     {
@@ -56,19 +65,23 @@ public class ColorRenderer
         float fcolor = Float.intBitsToFloat(color);
         
         tbuffer.putFloat(minX);
-        tbuffer.putFloat(maxY);        
+        tbuffer.putFloat(maxY);   
+        tbuffer.putFloat(depth);  
         tbuffer.putFloat(fcolor);
         
         tbuffer.putFloat(minX);
-        tbuffer.putFloat(minY);        
+        tbuffer.putFloat(minY);   
+        tbuffer.putFloat(depth);  
         tbuffer.putFloat(fcolor);
         
         tbuffer.putFloat(maxX);
-        tbuffer.putFloat(maxY);        
+        tbuffer.putFloat(maxY);  
+        tbuffer.putFloat(depth);  
         tbuffer.putFloat(fcolor);
         
         tbuffer.putFloat(maxX);
-        tbuffer.putFloat(minY);        
+        tbuffer.putFloat(minY);  
+        tbuffer.putFloat(depth);  
         tbuffer.putFloat(fcolor);
         
         tbuffer.flip();
@@ -76,15 +89,6 @@ public class ColorRenderer
         glUnmapBuffer(GL_ARRAY_BUFFER);
         
         GLHelper.glBindVertexArray(vao);
-        glDrawArrays(GL_TRIANGLE_STRIP, offset / 12, 4);
-    }
-    
-    public void delete()
-    {
-        buffer = null;
-        glDeleteVertexArrays(vao);
-        glDeleteBuffers(vbo);
-        vao = -1;
-        vbo = -1;
+        glDrawArrays(GL_TRIANGLE_STRIP, offset / 16, 4);
     }
 }

+ 2 - 2
src/me/hammerle/snuviengine/api/Engine.java

@@ -117,11 +117,11 @@ public abstract class Engine
             fpsSum -= fps[fpsIndex];
             fps[fpsIndex] = time - lastFrame;
             fpsSum += fps[fpsIndex];
-            fpsIndex = (fpsIndex + 1) % fps.length;
             lag += fps[fpsIndex];
+            fpsIndex = (fpsIndex + 1) % fps.length;
             lastFrame = time;
             currentFps = (1_000_000_000.0 * fps.length) / fpsSum;
-            
+
             while(lag >= nanosPerTick)
             {
                 lag -= nanosPerTick;

+ 1 - 10
src/me/hammerle/snuviengine/api/FontRenderer.java

@@ -73,7 +73,7 @@ public class FontRenderer
     
     private int offset = BUFFER_BYTE_LENGTH - OBJECT_LENGTH;
     
-    public FontRenderer()
+    protected FontRenderer()
     {
         Shader.addTask(() -> 
         {
@@ -239,13 +239,4 @@ public class FontRenderer
     {
         return FONT_SIZE + LINE_STEP;
     }
-
-    public void delete()
-    {
-        buffer = null;
-        glDeleteVertexArrays(vao);
-        glDeleteBuffers(vbo);
-        vao = -1;
-        vbo = -1;
-    }
 }

+ 49 - 21
src/me/hammerle/snuviengine/api/Shader.java

@@ -8,10 +8,8 @@ import java.util.LinkedList;
 import java.util.List;
 import org.lwjgl.BufferUtils;
 import static org.lwjgl.opengl.GL11.*;
-import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER;
-import static org.lwjgl.opengl.GL15.glBindBuffer;
+import static org.lwjgl.opengl.GL14.*;
 import static org.lwjgl.opengl.GL20.*;
-import static org.lwjgl.opengl.GL30.glBindVertexArray;
 
 public final class Shader
 {
@@ -25,13 +23,14 @@ public final class Shader
     
     protected static boolean initDone = false;
     
+    private final static FontRenderer FONT_RENDERER = new FontRenderer();
+    private final static ColorRenderer COLOR_RENDERER = new ColorRenderer();
+    
     // uniform stuff
     private static int unifViewMatrix = -1;
     private static int unifModelMatrix = -1;
     private static MatrixStack modelMatrix;
     
-    private static int unifDepth = -1;
-    
     private static int unifAmbientLight = -1;
     private static int[][] unifLight;
     
@@ -51,9 +50,6 @@ public final class Shader
         modelMatrix = new MatrixStack(20);
         updateMatrix();
         
-        unifDepth = glGetUniformLocation(program, "depth");
-        setDepth(0.0f);
-        
         unifAmbientLight = glGetUniformLocation(program, "ambientLight");
         setAmbientLight(1.0f, 1.0f, 1.0f);
         
@@ -69,13 +65,13 @@ public final class Shader
         }
         
         unifUseTexture = glGetUniformLocation(program, "useTexture");
-        setTextureUsing(false);
+        setTextureEnabled(false);
         
         unifUseColor = glGetUniformLocation(program, "useColor");
-        setColorUsing(false);
+        setColorEnabled(false);
         
         unifUseLight = glGetUniformLocation(program, "useLight");
-        setLightUsing(false);
+        setLightEnabled(false);
         
         setViewPort(width, height);
         initDone = true;
@@ -95,6 +91,16 @@ public final class Shader
         }
     }
     
+    public static FontRenderer getFontRenderer()
+    {
+        return FONT_RENDERER;
+    }
+    
+    public static ColorRenderer getColorRenderer()
+    {
+        return COLOR_RENDERER;
+    }
+    
     private static void updateViewMatrix()
     {
         FloatBuffer buffer = BufferUtils.createFloatBuffer(16);
@@ -111,12 +117,12 @@ public final class Shader
         
         buffer.put(0.0f);
         buffer.put(0.0f);
-        buffer.put(1.0f);
+        buffer.put(-1.0f / height);
         buffer.put(0.0f);
         
         buffer.put(-1.0f);
         buffer.put(1.0f);
-        buffer.put(0.0f);
+        buffer.put(0.5f);
         buffer.put(1.0f);
         
         buffer.flip();
@@ -188,11 +194,6 @@ public final class Shader
         modelMatrix.rotate(angle);
     }
     
-    public static void setDepth(float depth)
-    {
-        glUniform1f(unifDepth, depth);
-    }
-    
     public static void setAmbientLight(float r, float g, float b)
     {
         glUniform3f(unifAmbientLight, r, g, b);
@@ -224,21 +225,48 @@ public final class Shader
         glUniform1f(unifLight[index][2], strength);
     }
     
-    public static void setTextureUsing(boolean use)
+    public static void setTextureEnabled(boolean use)
     {
         glUniform1i(unifUseTexture, use ? 1 : 0);
     }
     
-    public static void setColorUsing(boolean use)
+    public static void setColorEnabled(boolean use)
     {
         glUniform1i(unifUseColor, use ? 1 : 0);
     }
     
-    public static void setLightUsing(boolean use)
+    public static void setLightEnabled(boolean use)
     {
         glUniform1i(unifUseLight, use ? 1 : 0);
     }
     
+    public static void setDepthTestEnabled(boolean use)
+    {
+        if(use)
+        {
+            glEnable(GL_DEPTH_TEST);
+            glDepthFunc(GL_LEQUAL);
+        }
+        else
+        {
+            glDisable(GL_DEPTH_TEST);
+        }
+    }
+    
+    public static void setBlendingEnabled(boolean use)
+    {
+        if(use)
+        {
+            glEnable(GL_BLEND);
+            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+            glBlendEquation(GL_FUNC_ADD);
+        }
+        else
+        {
+            glDisable(GL_BLEND);
+        }
+    }
+    
     // -------------------------------------------------------------------------
     // general stuff
     // -------------------------------------------------------------------------

+ 22 - 28
src/me/hammerle/snuviengine/api/Texture.java

@@ -4,8 +4,6 @@ import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.IOException;
 import java.nio.IntBuffer;
-import java.util.LinkedList;
-import java.util.List;
 import javax.imageio.ImageIO;
 import org.lwjgl.BufferUtils;
 import static org.lwjgl.opengl.GL11.*;
@@ -14,7 +12,7 @@ import static org.lwjgl.opengl.GL30.*;
 
 public class Texture
 {
-    private class Animation
+    public class Animation
     {
         private IntBuffer[] data;
         private int[] wi;
@@ -67,7 +65,7 @@ public class Texture
             }
         }
         
-        private void nextFrame()
+        public void nextFrame()
         {
             GLHelper.glBindTexture(texture);
             glTexSubImage2D(GL_TEXTURE_2D, 0, offsetX, offsetY, wi[index], he[index], GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data[index]);
@@ -77,28 +75,13 @@ public class Texture
     
     private int texture = -1; 
     private final String path;
-    private int w = -1;
-    private int h = -1;
-    
-    private final List<Animation> animations = new LinkedList<>();
+    private final int w;
+    private final int h;
+    private IntBuffer buffer;
     
     public Texture(String path)
     {
         this.path = path;
-        Shader.addTask(() -> loadTexture());
-    }
-    
-    public void addAnimation(int offsetX, int offsetY, String... paths)
-    {
-        Shader.addTask(() -> animations.add(new Animation(offsetX, offsetY, paths)));
-    }
-    
-    private void loadTexture()
-    {
-        if(texture != -1)
-        {
-            throw new TextureException("a texture is already loaded");
-        }
         
         BufferedImage image;
         try
@@ -112,7 +95,7 @@ public class Texture
         
         w = image.getWidth();
         h = image.getHeight();
-        IntBuffer buffer = BufferUtils.createIntBuffer(w * h);
+        buffer = BufferUtils.createIntBuffer(w * h);
         for(int y = 0; y < h; y++)
         {
             for(int x = 0; x < w; x++)
@@ -123,6 +106,21 @@ public class Texture
         }
         buffer.flip();
         
+        Shader.addTask(() -> loadTexture());
+    }
+    
+    public Animation addAnimation(int offsetX, int offsetY, String... paths)
+    {
+        return new Animation(offsetX, offsetY, paths);
+    }
+    
+    private void loadTexture()
+    {
+        if(texture != -1)
+        {
+            throw new TextureException("a texture is already loaded");
+        }
+        
         texture = glGenTextures();
         
         GLHelper.glBindTexture(texture);
@@ -131,6 +129,7 @@ public class Texture
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, buffer);
+        buffer = null;
         glGenerateMipmap(GL_TEXTURE_2D);
     }    
 
@@ -142,10 +141,5 @@ public class Texture
         }
         GLHelper.glBindTexture(texture);
     }
-    
-    public void nextFrame()
-    {
-        animations.forEach(a -> a.nextFrame());
-    }
 }
 

+ 142 - 0
src/me/hammerle/snuviengine/game/BoxList.java

@@ -0,0 +1,142 @@
+package me.hammerle.snuviengine.game;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class BoxList
+{
+    private static final double MAX_SIZE = 1;
+    
+    public static class Node
+    {
+        private Node next;
+        private Node previous;
+        private Entity ent;
+        private int x;
+        private int y;
+    }
+    
+    private final double boxMinX;
+    private final double boxMinY;
+    private final double boxMaxX;
+    private final double boxMaxY;
+    
+    private final double size;
+    
+    private final Node[][] nodes;
+    
+    private Node freeNodes = null;
+    
+    private final int partionX;
+    private final int partionY;
+    
+    public int amount = 0;
+        
+    public BoxList(double x1, double y1, double x2, double y2, double size)
+    {
+        this.size = size;
+        
+        boxMinX = Math.min(x1, x2);
+        boxMinY = Math.min(y1, y2);
+        
+        partionX = (int) Math.ceil((Math.max(x1, x2) - boxMinX) / size);
+        partionY = (int) Math.ceil((Math.max(y1, y2) - boxMinX) / size);
+        
+        boxMaxX = partionX * size;
+        boxMaxY = partionY * size;
+        
+        System.out.println(boxMinX + " " + boxMaxX);
+        System.out.println(boxMinY + " " + boxMaxY);
+        System.out.println(partionX + " " + partionY);
+        
+        nodes = new Node[partionX][partionY];
+        
+        for(int i = 0; i < 10000; i++)
+        {
+            Node n = new Node();
+            n.next = freeNodes;
+            freeNodes = n;
+        }
+    }
+    
+    public Node add(Entity ent)
+    {
+        int x = Math.max(Math.min((int) (((ent.xPos + ent.width / 2) + boxMinX) / size), partionX - 1), 0);
+        int y = Math.max(Math.min((int) (((ent.yPos + ent.height / 2) + boxMinY) / size), partionY - 1), 0);
+        
+        amount++;
+        
+        Node n = freeNodes;
+        freeNodes = n.next;
+        n.next = null;
+        
+        n.ent = ent;
+        n.x = x;
+        n.y = y;
+        
+        if(nodes[x][y] == null)
+        {
+            nodes[x][y] = n;
+        }
+        else
+        {
+            n.next = nodes[x][y];
+            nodes[x][y].previous = n;
+            nodes[x][y] = n;
+        }
+        return n;
+    }
+    
+    public void remove(Node n)
+    {
+        if(n.previous != null)
+        {
+            n.previous.next = n.next;
+        }
+        else
+        {
+            nodes[n.x][n.y] = n.next;
+        }
+        
+        if(n.next != null)
+        {
+            n.next.previous = n.previous;
+        }
+        
+        n.previous = null;
+        n.ent = null;
+        
+        n.next = freeNodes;
+        freeNodes = n;
+        
+        amount--;
+    }
+    
+    public List<Entity> getAllEntitiesAt(Entity not, double minX, double minY, double maxX, double maxY)
+    {
+        int sx = Math.max(Math.min((int) ((minX + boxMinX - MAX_SIZE) / size), partionX - 1), 0);
+        int sy = Math.max(Math.min((int) ((minY + boxMinY - MAX_SIZE) / size), partionY - 1), 0);
+        int ex = Math.max(Math.min((int) Math.ceil((maxX + boxMinX + MAX_SIZE) / size), partionX - 1), 0);
+        int ey = Math.max(Math.min((int) Math.ceil((maxY + boxMinY + MAX_SIZE) / size), partionY - 1), 0);
+        
+        List<Entity> list = new LinkedList<>();
+        
+        for(int x = sx; x <= ex; x++)
+        {
+            for(int y = sy; y <= ey; y++)
+            {
+                Node n = nodes[x][y];
+                while(n != null)
+                {
+                    if(not != n.ent && n.ent.isColliding(minX, minY, maxX, maxY))
+                    {
+                        list.add(n.ent);
+                    }
+                    n = n.next;
+                }
+            }
+        }
+        
+        return list;
+    } 
+}

+ 4 - 12
src/me/hammerle/snuviengine/game/Chat.java

@@ -13,8 +13,6 @@ public class Chat
     private int viewLenght = 5;
     private final int lineLenght = 20;
     
-    private final FontRenderer fr = Game.FONT_RENDERER;
-    
     public Chat()
     {
         for(int i = 0; i < chat.length; i++)
@@ -26,9 +24,6 @@ public class Chat
         {
             addString(String.valueOf(i).toCharArray());
         }
-
-        System.out.println("____________________");
-        System.out.print(chat);
     }
     
     private void nextWriteIndex()
@@ -50,8 +45,6 @@ public class Chat
             distance = chat.length - viewIndex + writeIndex;
         }
         
-        System.out.println("D" + distance);
-        
         if(distance - 1 == viewLenght)
         {
             viewIndex = (viewIndex + 1) % chat.length;
@@ -105,10 +98,8 @@ public class Chat
     
     public void tick()
     {
-        //System.out.println(Game.DOWN.getTime() + " " +Game.DOWN.isDown());
         if(((Game.DOWN.getTime() + 15) & 0x7) == 0)
         {
-            System.out.println(Game.DOWN.getTime());
             if((viewIndex + viewLenght) % chat.length != writeIndex)
             {
                 viewIndex = (viewIndex + 1) % chat.length;
@@ -117,7 +108,6 @@ public class Chat
         
         if(((Game.UP.getTime() + 15) & 0x7) == 0)
         {
-            System.out.println(viewIndex + " " + startIndex);
             if(viewIndex != startIndex)
             {
                 viewIndex--;
@@ -131,11 +121,13 @@ public class Chat
     
     public void renderTick()
     {
-        Shader.setTextureUsing(true);
-        Shader.setColorUsing(true);
+        Shader.setTextureEnabled(true);
+        Shader.setColorEnabled(true);
         float x = 0.0f;
         float y = 0.0f;
         
+        FontRenderer fr = Shader.getFontRenderer();
+        
         int i = viewIndex;
         int end = (viewIndex + viewLenght) % chat.length;
         while(i != end)

+ 207 - 0
src/me/hammerle/snuviengine/game/Entity.java

@@ -0,0 +1,207 @@
+package me.hammerle.snuviengine.game;
+
+import java.util.List;
+import me.hammerle.snuviengine.api.Shader;
+import me.hammerle.snuviengine.game.BoxList.Node;
+
+public class Entity
+{
+    public Game game;
+    
+    public double xPos;
+    public double yPos;
+    public double width;
+    public double height;
+    
+    public double vx = 0.0f;
+    public double vy = 0.0f;
+    
+    public Node node;
+    
+    public Entity(Game game, double width, double height)
+    {
+        this.game = game;
+        xPos = 0.0f;
+        yPos = 0.0f;
+        this.width = width;
+        this.height = height;
+        
+        vx = 0.5;
+        vy = 0.5;
+    }
+    
+    private boolean isColliding(Entity ent)
+    {
+        return xPos + width > ent.xPos && ent.xPos + ent.width > xPos &&
+                yPos + height > ent.yPos && ent.yPos + ent.height > yPos;
+    }
+    
+    public boolean isColliding(double minX, double minY, double maxX, double maxY)
+    {
+        return xPos + width > minX && maxX > xPos &&
+                yPos + height > minY && maxY > yPos;
+    }
+    
+    public void tick()
+    {
+        if(vx == 0.0 && vy == 0.0)
+        {
+            return;
+        }
+        
+        double step = 0.0625;
+        double lvx = vx;
+        double lvy = vy;
+        
+        game.entities.remove(node);
+        node = null;
+        
+        List<Entity> list = game.entities.getAllEntitiesAt(this, 
+                xPos + ((vx < 0) ? vx : 0), 
+                yPos + ((vy < 0) ? vy : 0), 
+                xPos + width + ((vx > 0) ? vx : 0), 
+                yPos + height + ((vy > 0) ? vy : 0));
+        if(list.isEmpty())
+        {
+            xPos += vx;
+            if(xPos < 0 || xPos > 400)
+            {
+                xPos -= vx;
+            }
+            
+            yPos += vy;
+            if(yPos < 0 || yPos > 300)
+            {
+                yPos -= vy;
+            }
+            
+            node = game.entities.add(this);
+            return;
+        }
+        
+        while(lvx != 0.0 || lvy != 0.0)
+        {
+            double oldXPos = xPos;
+            double oldYPos = yPos;
+            
+            if(lvx < 0.0)
+            {
+                if(lvx > -step)
+                {
+                    xPos += lvx;
+                    lvx = 0.0;
+                }
+                else
+                {
+                    xPos -= step;
+                    lvx += step;
+                }
+            }
+            else if(lvx > 0.0)
+            {
+                if(lvx < step)
+                {
+                    xPos += lvx;
+                    lvx = 0.0;
+                }
+                else
+                {
+                    xPos += step;
+                    lvx -= step;
+                }
+            }
+            
+            if(xPos > 400 || xPos < 0)
+            {
+                lvx = 0.0f;
+                xPos = oldXPos;
+            }
+            else
+            {
+                for(Entity ent : list)
+                {
+                    if(this.isColliding(ent))
+                    {
+                        lvx = 0.0f;
+                        xPos = oldXPos;
+                        break;
+                    }
+                }
+            }
+            
+            if(lvy < 0.0)
+            {
+                if(lvy > -step)
+                {
+                    yPos += lvy;
+                    lvy = 0.0;
+                }
+                else
+                {
+                    yPos -= step;
+                    lvy += step;
+                }
+            }
+            else if(lvy > 0.0)
+            {
+                if(lvy < step)
+                {
+                    yPos += lvy;
+                    lvy = 0.0;
+                }
+                else
+                {
+                    yPos += step;
+                    lvy -= step;
+                }
+            }
+            
+            if(yPos > 300 || yPos < 0)
+            {
+                lvy = 0.0f;
+                yPos = oldYPos;
+            }
+            else
+            {
+                for(Entity ent : list)
+                {
+                    if(this.isColliding(ent))
+                    {
+                        lvy = 0.0f;
+                        yPos = oldYPos;
+                        break;
+                    }
+                }
+            }
+        }
+        
+        node = game.entities.add(this);
+    }
+    
+    public void renderTick()
+    {
+        Shader.getColorRenderer().setDepth((float) yPos);
+        Shader.getColorRenderer().drawRectangle(
+                (float) xPos, 
+                (float) yPos, 
+                (float) (xPos + width), 
+                (float) (yPos + height), 
+                0x770000FF);
+    }
+    
+    public double getX()
+    {
+        return xPos;
+    }
+    
+    public double getY()
+    {
+        return yPos;
+    }
+    
+    public void setPosition(double x, double y)
+    {
+        xPos = x;
+        yPos = y;
+    }
+}

+ 64 - 17
src/me/hammerle/snuviengine/game/Game.java

@@ -1,8 +1,9 @@
 package me.hammerle.snuviengine.game;
 
-import me.hammerle.snuviengine.api.ColorRenderer;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
 import me.hammerle.snuviengine.api.Engine;
-import me.hammerle.snuviengine.api.FontRenderer;
 import me.hammerle.snuviengine.api.KeyBinding;
 import me.hammerle.snuviengine.api.KeyHandler;
 import me.hammerle.snuviengine.api.Shader;
@@ -18,19 +19,27 @@ public class Game extends Engine
     public final static KeyBinding LEFT = KeyHandler.register(GLFW_KEY_LEFT);
     public final static KeyBinding RIGHT = KeyHandler.register(GLFW_KEY_RIGHT);
     
-    private final ColorRenderer cr = new ColorRenderer();
     private final TextureRenderer tr = new TextureRenderer();
     private final Texture t = new Texture("images/out3.png");
     
-    public final static FontRenderer FONT_RENDERER = new FontRenderer();
-    
-    private final Chat chat = new Chat();
-    
-    float angle = 0.0f;
+    public BoxList entities = new BoxList(0.0, 0.0, 400.0, 300.0, 1.0);
+    private final List<Entity> list = new LinkedList<>();
     
     public Game()
     {
-        t.addAnimation(0, 0, "images/water1.png", "images/water2.png", "images/water3.png", "images/water2.png");
+        Random r = new Random(100);
+        for(int i = 0; i < 5000; i++)
+        {
+            Entity ent = new Entity(this, r.nextDouble() * 2.0, r.nextDouble() * 2.0);
+            ent.setPosition(r.nextDouble() * 400.0, r.nextDouble() * 300);
+            ent.node = entities.add(ent);
+            list.add(ent);
+        }
+        
+        Hero hero = new Hero(this, 5.0, 5.0);
+        hero.setPosition(450.0, 200);
+        hero.node = entities.add(hero);
+        list.add(hero);
     }
     
     @Override
@@ -38,23 +47,61 @@ public class Game extends Engine
     {
     }
 
+    private int c = 0;
+    
     @Override
     public void tick()
     {        
-        angle += 0.5f;
-        chat.tick();
+        CLOCK.start();
+        list.forEach(ent -> ent.tick());
+        CLOCK.stop();
+        CLOCK.printTime(entities.amount + " Time: ");
+        
+        /*if(!list.isEmpty())
+        {
+            Entity ent = list.remove(c);
+            entities.remove(ent.node);
+        }
+
+        if(!list.isEmpty())
+        {
+            Entity ent = list.remove(c);
+            entities.remove(ent.node);
+        }
+
+        if(!list.isEmpty())
+        {
+            Entity ent = list.remove(c);
+            entities.remove(ent.node);
+        }*/
     }
     
-    private static final Clock clock = new Clock(1000);
+    private static final Clock CLOCK = new Clock(100);
     
     @Override
     public void renderTick()
     {
-        clock.start();
+        Shader.setTextureEnabled(false);
+        Shader.setColorEnabled(true);
+
+        //Shader.setDepthTestUsing(true);
+        list.forEach(ent -> ent.renderTick());
+        //Shader.getColorRenderer().drawRectangle(0.0f, 0.0f, 100.0f, 100.0f, 0xFF0000FF);
+
+        /*for(int i = 0; i < 400; i++)
         {
-            chat.renderTick();
-        }
-        clock.stop();
-        //clock.printTime("Time: ");
+            Shader.getColorRenderer().drawRectangle(0.0f, i * 2.0f, 20.0f, i * 2.0f + 1, 0xFFFFFFFF);
+        }*/
+
+        //hader.setDepthTestUsing(false);
+
+        /*Shader.setBlendingEnabled(false);
+
+        Shader.setTextureEnabled(true);
+        Shader.setColorEnabled(true);
+        for(int i = 0; i < 20; i++)
+        {
+            Shader.getFontRenderer().drawString(0, i * 9, true, "Das ist ein Test.");
+        }*/
     }
 }

+ 56 - 0
src/me/hammerle/snuviengine/game/Hero.java

@@ -0,0 +1,56 @@
+package me.hammerle.snuviengine.game;
+
+import me.hammerle.snuviengine.api.Shader;
+
+public class Hero extends Entity
+{
+    public Hero(Game game, double width, double height)
+    {
+        super(game, width, height);
+    }
+    
+    @Override
+    public void renderTick()
+    {
+        Shader.getColorRenderer().setDepth((float) yPos);
+        Shader.getColorRenderer().drawRectangle(
+                (float) xPos, 
+                (float) yPos, 
+                (float) (xPos + width), 
+                (float) (yPos + height), 
+                0xAAFF0000);
+    }
+
+    @Override
+    public void tick()
+    {
+        double nvx = .0;
+        double nvy = 0.0;
+        double speed = 3;
+        
+        if(Game.DOWN.isDown())
+        {
+            nvy += speed;
+        }
+        
+        if(Game.UP.isDown())
+        {
+            nvy -= speed;
+        }
+        
+        if(Game.LEFT.isDown())
+        {
+            nvx -= speed;
+        }
+        
+        if(Game.RIGHT.isDown())
+        {
+            nvx += speed;
+        }
+        
+        vx = nvx;
+        vy = nvy;
+        
+        super.tick();
+    }
+}

+ 2 - 2
src/me/hammerle/snuviengine/util/Clock.java

@@ -2,8 +2,8 @@ package me.hammerle.snuviengine.util;
 
 public class Clock
 {
-    private int dataLength;
-    private long[] data;
+    private final int dataLength;
+    private final long[] data;
     private int index = 0;
     private long sum = 0;
     private long time;