瀏覽代碼

startscreen level (generated level data), startscreen hero ai, level interface

Kajetan Johannes Hammerle 5 年之前
父節點
當前提交
12cd30f796
共有 24 個文件被更改,包括 922 次插入82 次删除
  1. 10 4
      src/me/hammerle/supersnuvi/Game.java
  2. 19 5
      src/me/hammerle/supersnuvi/entity/Entity.java
  3. 17 5
      src/me/hammerle/supersnuvi/entity/EntityBuilder.java
  4. 14 14
      src/me/hammerle/supersnuvi/entity/components/ai/HumanController.java
  5. 3 3
      src/me/hammerle/supersnuvi/entity/components/ai/LondonerController.java
  6. 86 0
      src/me/hammerle/supersnuvi/entity/components/ai/StartScreenHeroController.java
  7. 28 0
      src/me/hammerle/supersnuvi/gamelogic/ILevel.java
  8. 14 2
      src/me/hammerle/supersnuvi/gamelogic/Level.java
  9. 8 0
      src/me/hammerle/supersnuvi/gamelogic/LevelData.java
  10. 673 0
      src/me/hammerle/supersnuvi/gamelogic/StartScreenLevel.java
  11. 6 7
      src/me/hammerle/supersnuvi/tiles/BottledSoulTile.java
  12. 6 7
      src/me/hammerle/supersnuvi/tiles/CrumblingStoneTile.java
  13. 2 2
      src/me/hammerle/supersnuvi/tiles/GoalTile.java
  14. 2 2
      src/me/hammerle/supersnuvi/tiles/KillTile.java
  15. 4 4
      src/me/hammerle/supersnuvi/tiles/Location.java
  16. 3 3
      src/me/hammerle/supersnuvi/tiles/NullTile.java
  17. 3 2
      src/me/hammerle/supersnuvi/tiles/SlipperyTile.java
  18. 2 1
      src/me/hammerle/supersnuvi/tiles/SpikeTile.java
  19. 2 2
      src/me/hammerle/supersnuvi/tiles/StartTile.java
  20. 7 7
      src/me/hammerle/supersnuvi/tiles/Tile.java
  21. 2 2
      src/me/hammerle/supersnuvi/tiles/TrampolinTile.java
  22. 3 2
      src/me/hammerle/supersnuvi/tiles/WaterTile.java
  23. 6 6
      src/me/hammerle/supersnuvi/util/BlockDataStorage.java
  24. 2 2
      src/me/hammerle/supersnuvi/util/Face.java

+ 10 - 4
src/me/hammerle/supersnuvi/Game.java

@@ -9,6 +9,7 @@ import me.hammerle.snuviengine.api.FontRenderer;
 import me.hammerle.snuviengine.api.KeyBinding;
 import me.hammerle.snuviengine.api.Shader;
 import me.hammerle.supersnuvi.gamelogic.Level;
+import me.hammerle.supersnuvi.gamelogic.StartScreenLevel;
 import me.hammerle.supersnuvi.savegame.SimpleConfig;
 import me.hammerle.supersnuvi.tiles.*;
 import me.hammerle.supersnuvi.util.SoundUtils;
@@ -40,6 +41,7 @@ public class Game extends Engine
     private Level currentLevel = null;
     private final Level[] levels;
     private int levelIndex = 0;
+    private final StartScreenLevel startScreenLevel = new StartScreenLevel();
     
     // config and savegames
     private final SimpleConfig config = new SimpleConfig("options.txt", true);
@@ -148,6 +150,9 @@ public class Game extends Engine
         {
             SoundUtils.playSound(SoundUtils.Sound.MENU_MUSIC);
             SoundUtils.stopSound(SoundUtils.Sound.SONG_1);
+            
+            startScreenLevel.tick();
+            
             switch(screen)
             {
                 case 0: // start screen
@@ -295,6 +300,7 @@ public class Game extends Engine
             currentLevel.renderTick(lag);
             return;
         }
+        startScreenLevel.renderTick(lag);
         Shader.translateTo(0.0f, 0.0f);
         Shader.updateMatrix();
         switch(screen)
@@ -318,7 +324,7 @@ public class Game extends Engine
                 Shader.setColorEnabled(true);
                 
                 // brown background
-                cr.drawRectangle(0, 0, width, height, COLOR_BROWN); 
+                //cr.drawRectangle(0, 0, width, height, COLOR_BROWN); 
                 
                 Shader.setBlendingEnabled(true);
                 cr.drawRectangle(left, top, right, bottom, COLOR_OVERLAY);
@@ -354,7 +360,7 @@ public class Game extends Engine
                 Shader.setColorEnabled(true);
                 
                 // brown background
-                cr.drawRectangle(0, 0, width, height, COLOR_BROWN); 
+                //cr.drawRectangle(0, 0, width, height, COLOR_BROWN); 
                 
                 Shader.setBlendingEnabled(true);
                 cr.drawRectangle(left, top, right, bottom, COLOR_OVERLAY);
@@ -391,7 +397,7 @@ public class Game extends Engine
                 Shader.setColorEnabled(true);
                 
                 // brown background
-                cr.drawRectangle(0, 0, width, height, COLOR_BROWN); 
+                //cr.drawRectangle(0, 0, width, height, COLOR_BROWN); 
                 
                 Shader.setBlendingEnabled(true);
                 cr.drawRectangle(left, top, right, bottom, COLOR_OVERLAY);
@@ -468,7 +474,7 @@ public class Game extends Engine
                 Shader.setColorEnabled(true);
                 
                 // brown background
-                cr.drawRectangle(0, 0, width, height, COLOR_BROWN); 
+                //cr.drawRectangle(0, 0, width, height, COLOR_BROWN); 
                 
                 Shader.setBlendingEnabled(true);
                 cr.drawRectangle(left, top, right, bottom, COLOR_OVERLAY);

+ 19 - 5
src/me/hammerle/supersnuvi/entity/Entity.java

@@ -6,7 +6,7 @@ import me.hammerle.supersnuvi.entity.components.Energy;
 import me.hammerle.supersnuvi.entity.components.Health;
 import me.hammerle.supersnuvi.entity.components.ItemCollector;
 import me.hammerle.supersnuvi.entity.components.Movement;
-import me.hammerle.supersnuvi.gamelogic.Level;
+import me.hammerle.supersnuvi.gamelogic.ILevel;
 import me.hammerle.supersnuvi.util.CollisionObject;
 import me.hammerle.supersnuvi.util.Face;
 import me.hammerle.supersnuvi.util.Utils;
@@ -37,10 +37,10 @@ public final class Entity
     private float motionY;
     
     // a flag indicating that the entity is on the ground
-    private boolean onGround = false;
+    private boolean onGround = true;
     
     // the level of the entity
-    private final Level level;
+    private final ILevel level;
     
     // entity components
     protected Controller controller;
@@ -52,7 +52,7 @@ public final class Entity
     // face
     private Face face = Face.RIGHT;
     
-    protected Entity(Level level, float x, float y, CollisionObject box)
+    protected Entity(ILevel level, float x, float y, CollisionObject box)
     {
         lastPosX = x;
         lastPosY = y;
@@ -77,7 +77,7 @@ public final class Entity
         this.itemCollector =  ItemCollector.NULL;
     }
     
-    public Level getLevel()
+    public ILevel getLevel()
     {
         return level;
     }   
@@ -137,6 +137,15 @@ public final class Entity
         return posY;
     }
     
+    public void setPosition(float x, float y)
+    {
+        lastPosX = x;
+        lastPosY = y;
+        posX = x;
+        posY = y;
+        box.reset().offset(posX, posY);
+    }
+    
     public float getLastX()
     {
         return lastPosX;
@@ -157,6 +166,11 @@ public final class Entity
         return posY + box.getHeight() * 0.5f;
     }
     
+    public float getHeight()
+    {
+        return box.getHeight();
+    }
+    
     public Face getFace()
     {
         if(motionX == 0.0f)

+ 17 - 5
src/me/hammerle/supersnuvi/entity/EntityBuilder.java

@@ -6,18 +6,19 @@ import me.hammerle.supersnuvi.entity.components.DefaultEnergy;
 import me.hammerle.supersnuvi.entity.components.StoneMovement;
 import me.hammerle.supersnuvi.entity.components.ai.HumanController;
 import me.hammerle.supersnuvi.entity.components.ai.LondonerController;
-import me.hammerle.supersnuvi.gamelogic.Level;
+import me.hammerle.supersnuvi.gamelogic.ILevel;
 import me.hammerle.supersnuvi.tiles.Tile;
 import me.hammerle.supersnuvi.entity.components.IDeath;
 import me.hammerle.supersnuvi.entity.components.ItemCollector;
 import me.hammerle.supersnuvi.entity.components.NoHealth;
+import me.hammerle.supersnuvi.entity.components.ai.StartScreenHeroController;
 import me.hammerle.supersnuvi.entity.components.ai.StoneController;
 import me.hammerle.supersnuvi.util.CollisionBox;
 import me.hammerle.supersnuvi.util.SoundUtils.Sound;
 
 public final class EntityBuilder 
 {
-    public static Entity buildHero(Level level, float x, float y)
+    public static Entity buildHero(ILevel level, float x, float y)
     {
         Entity hero = new Entity(level, x, y, new CollisionBox(0.0f, 5.0f, 27.0f, 64.0f));
         hero.controller = new HumanController(hero);
@@ -28,7 +29,18 @@ public final class EntityBuilder
         return hero;
     }
     
-    public static Entity buildLondoner(Level level, float x, float y, boolean evil)
+    public static Entity buildStartScreenHero(ILevel level, float x, float y)
+    {
+        Entity hero = new Entity(level, x, y, new CollisionBox(0.0f, 5.0f, 27.0f, 64.0f));
+        hero.controller = new StartScreenHeroController(hero);
+        hero.health = new DefaultHealth(hero, (ent) -> ent.getLevel().scheduleReset(), 100.0f, null, Sound.MIRROR_CRACK, Sound.MIRROR_BREAK);
+        hero.energy = new DefaultEnergy(hero, 100.0f);
+        hero.move = new DefaultMovement(hero, 12.0f, 0.0f, 50.0f);
+        hero.itemCollector = ItemCollector.HERO;
+        return hero;
+    }
+    
+    public static Entity buildLondoner(ILevel level, float x, float y, boolean evil)
     {
         Entity londoner = new Entity(level, x, y, new CollisionBox(7.0f, 19.0f, 21.0f, 64.0f));
         londoner.controller = new LondonerController(londoner, evil);
@@ -38,7 +50,7 @@ public final class EntityBuilder
         return londoner;
     }
     
-    public static Entity buildCrumblingStone(Level level, float x, float y)
+    public static Entity buildCrumblingStone(ILevel level, float x, float y)
     {
         Entity stone = new Entity(level, x, y, new CollisionBox(0.0f, 0.0f, Tile.SIZE, Tile.SIZE));
         stone.controller = new StoneController(stone);
@@ -47,7 +59,7 @@ public final class EntityBuilder
         return stone;
     }
     
-    public static Entity fromId(int id, Level level, float x, float y)
+    public static Entity fromId(int id, ILevel level, float x, float y)
     {
         switch(id)
         {

+ 14 - 14
src/me/hammerle/supersnuvi/entity/components/ai/HumanController.java

@@ -11,34 +11,34 @@ import me.hammerle.supersnuvi.util.Utils;
 
 public class HumanController extends Controller
 {
-    private final static int SIZE = 1024;
+    protected final static int SIZE = 1024;
     private final static Texture HERO = new Texture("resources/hero.png");
     
-    private float ox = 0.0f;
-    private float oy = 0.0f;
-    private float w = 0.0f;
-    private float h = 0.0f;
-    private float tx = 0.0f;
-    private float ty = 0.0f;
+    protected float ox = 0.0f;
+    protected float oy = 0.0f;
+    protected float w = 0.0f;
+    protected float h = 0.0f;
+    protected float tx = 0.0f;
+    protected float ty = 0.0f;
     
-    private int walkFrame = 0;
+    protected int walkFrame = 0;
     private int idleCounter = 0;
-    private int idleFrame = 0;
-    private int deathFrame = 0;
+    protected int idleFrame = 0;
+    protected int deathFrame = 0;
 
     public HumanController(Entity ent) 
     {
         super(ent);
     }
     
-    private void nextWalkFrame()
+    protected void nextWalkFrame()
     {
         deathFrame = 0;
         idleFrame = 0;
         walkFrame = (walkFrame + 1) % 9;
     }
     
-    private void nextIdleFrame()
+    protected void nextIdleFrame()
     {
         deathFrame = 0;
         walkFrame = 0;
@@ -50,14 +50,14 @@ public class HumanController extends Controller
         }
     }
     
-    private void nextDeathFrame()
+    protected void nextDeathFrame()
     {
         walkFrame = 0;
         idleFrame = 0;
         deathFrame++;
     }
     
-    private void resetFrames()
+    protected void resetFrames()
     {
         deathFrame = 0;
         walkFrame = 0;

+ 3 - 3
src/me/hammerle/supersnuvi/entity/components/ai/LondonerController.java

@@ -222,7 +222,7 @@ public class LondonerController extends Controller
     {
         if(hasRedEyes())
         {
-            if(!(loc.getTile() instanceof Ramp) && face.getOpposite() == ent.getFace() && ent.getMotionX() == 0.0f)
+            if(!(loc.getTile() instanceof Ramp) && face == ent.getFace() && ent.getMotionX() == 0.0f)
             {
                 shouldJump = true;
             }
@@ -234,10 +234,10 @@ public class LondonerController extends Controller
                 switch(face)
                 {
                     case LEFT:
-                        direction = Face.LEFT;
+                        direction = Face.RIGHT;
                         break;
                     case RIGHT:
-                        direction = Face.RIGHT;
+                        direction = Face.LEFT;
                         break;
                 }
             }

+ 86 - 0
src/me/hammerle/supersnuvi/entity/components/ai/StartScreenHeroController.java

@@ -0,0 +1,86 @@
+package me.hammerle.supersnuvi.entity.components.ai;
+
+import me.hammerle.supersnuvi.entity.Entity;
+import me.hammerle.supersnuvi.tiles.Location;
+import me.hammerle.supersnuvi.tiles.Ramp;
+import me.hammerle.supersnuvi.util.Face;
+
+public class StartScreenHeroController extends HumanController
+{
+    private boolean shouldJump = false;
+    
+    public StartScreenHeroController(Entity ent) 
+    {
+        super(ent);
+    }
+    
+    @Override
+    public void tick() 
+    {
+        if(ent.getHealth().isDead())
+        {
+            ox = ent.getFace() == Face.RIGHT ? 0.0f: -37.0f;
+            oy = 0.0f;
+            h = 64.0f;
+            w = 64.0f;
+            
+            tx = (deathFrame * 64.0f) / SIZE;
+            if(deathFrame < 16)
+            {
+                ty = 192.0f / SIZE;
+            }
+            else
+            {
+                ty = 256.0f / SIZE;
+            }
+            
+            nextDeathFrame();
+            return;
+        }
+        
+        ent.setMotionX(ent.getMovement().getVelocityX());
+        
+        if(shouldJump)
+        {
+            shouldJump = false;
+            ent.getMovement().jump();
+        }
+        
+        ox = ent.getFace() == Face.RIGHT ? 0.0f: -5.0f;
+        oy = 0.0f;
+        h = 64.0f;
+        w = 32.0f;
+        
+        if(ent.isOnGround())
+        {
+            if(ent.getMotionX() == 0.0f)
+            {
+                tx = (idleFrame * 32.0f) / SIZE;
+                ty = 128.0f / SIZE;
+                nextIdleFrame();
+            }
+            else
+            {               
+                tx = (96.0f + walkFrame * 32.0f) / SIZE;
+                ty = 0.0f;
+                nextWalkFrame();
+            }
+        }
+        else
+        {
+            resetFrames();
+            tx = 0.0f;
+            ty = 0.0f;
+        }
+    }
+
+    @Override
+    public void onCollideWithTile(Location loc, Face face)
+    {
+        if(face == Face.RIGHT && !(loc.getTile() instanceof Ramp))
+        {
+            shouldJump = true;
+        }
+    }
+}
+

+ 28 - 0
src/me/hammerle/supersnuvi/gamelogic/ILevel.java

@@ -0,0 +1,28 @@
+package me.hammerle.supersnuvi.gamelogic;
+
+import java.util.List;
+import me.hammerle.supersnuvi.entity.Entity;
+import me.hammerle.supersnuvi.tiles.Location;
+import me.hammerle.supersnuvi.util.CollisionObject;
+
+public interface ILevel
+{
+    public int getWidth();
+    public int getHeight();
+    
+    public Entity getHero();
+    
+    public void spawnEntity(Entity ent);
+    
+    public void scheduleReset();
+    public void finishLevel();
+    
+    public void increaseSouls(int score);
+    
+    public void updateTile(int layer, int x, int y);
+    public void updateTile(int x, int y);
+    
+    public List<CollisionObject> getMovementBoxesAt(CollisionObject box, Entity not);
+    public List<Location> getCollisionBoxesAt(CollisionObject cb);
+    public List<Entity> getEntitiesCollidingWith(Entity not, CollisionObject cb);
+}

+ 14 - 2
src/me/hammerle/supersnuvi/gamelogic/Level.java

@@ -17,9 +17,9 @@ import me.hammerle.supersnuvi.tiles.Tile;
 import me.hammerle.supersnuvi.util.CollisionObject;
 import me.hammerle.supersnuvi.util.Utils;
 
-public final class Level 
+public final class Level implements ILevel
 {
-    private final static float ERROR = 1f / 65536f;
+    public final static float ERROR = 1f / 65536f;
     
     public final static Texture TILES = new Texture("resources/tiles.png");
     private final static Texture GUI = new Texture("resources/gui.png");
@@ -138,6 +138,7 @@ public final class Level
     // basic stuff
     // -------------------------------------------------------------------------
 
+    @Override
     public Entity getHero()
     {
         return hero;
@@ -153,6 +154,7 @@ public final class Level
         return name;
     }
     
+    @Override
     public void finishLevel()
     {
         shouldReset = true;
@@ -169,6 +171,7 @@ public final class Level
         return shouldReset;
     }
     
+    @Override
     public void scheduleReset()
     {
         shouldReset = true;
@@ -210,6 +213,7 @@ public final class Level
         return false;
     }
     
+    @Override
     public void spawnEntity(Entity ent)
     {
         spawnQueue.add(ent);
@@ -245,6 +249,7 @@ public final class Level
         return newHero;
     }
     
+    @Override
     public void increaseSouls(int score)
     {
         souls += score;
@@ -270,11 +275,13 @@ public final class Level
         return time;
     }  
     
+    @Override
     public int getWidth()
     {
         return data.getWidth();
     }
     
+    @Override
     public int getHeight()
     {
         return data.getHeight();
@@ -411,6 +418,7 @@ public final class Level
         return y;
     }
     
+    @Override
     public void updateTile(int layer, int x, int y)
     {
         if(layer > data.getBackgroundIndex())
@@ -420,6 +428,7 @@ public final class Level
         meshes[layer][x / meshSize][y / meshSize].clear();
     }
     
+    @Override
     public void updateTile(int x, int y)
     {
         updateTile(data.getBackgroundIndex(), x, y);
@@ -627,6 +636,7 @@ public final class Level
         return Game.get().getTile(i).getMovementBox(x, y, this).reset().offset(Utils.toCoord(x), Utils.toCoord(y));
     }
     
+    @Override
     public List<CollisionObject> getMovementBoxesAt(CollisionObject box, Entity not)
     {
         List<CollisionObject> boxes;
@@ -668,6 +678,7 @@ public final class Level
         return tile.getCollisionBox(x, y, this).reset().offset(Utils.toCoord(x), Utils.toCoord(y));
     }
     
+    @Override
     public List<Location> getCollisionBoxesAt(CollisionObject cb)
     {
         LinkedList<Location> boxes = new LinkedList<>();
@@ -689,6 +700,7 @@ public final class Level
         return boxes;
     }
     
+    @Override
     public List<Entity> getEntitiesCollidingWith(Entity not, CollisionObject cb)
     {
         return entities.values().stream().filter(ent -> ent != not && ent.getBox().isColliding(cb)).collect(Collectors.toList());

+ 8 - 0
src/me/hammerle/supersnuvi/gamelogic/LevelData.java

@@ -127,6 +127,10 @@ public class LevelData
     
     public boolean save()
     {
+        if(file == null)
+        {
+            return false;
+        }
         try
         {
             try(FileOutputStream out = new FileOutputStream(file)) 
@@ -198,6 +202,10 @@ public class LevelData
     
     public boolean load()
     {
+        if(file == null)
+        {
+            return false;
+        }
         try
         {
             try (FileInputStream in = new FileInputStream(file)) 

+ 673 - 0
src/me/hammerle/supersnuvi/gamelogic/StartScreenLevel.java

@@ -0,0 +1,673 @@
+package me.hammerle.supersnuvi.gamelogic;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+import java.util.stream.Collectors;
+import me.hammerle.snuviengine.api.Shader;
+import me.hammerle.snuviengine.api.TextureRenderer;
+import me.hammerle.supersnuvi.Game;
+import me.hammerle.supersnuvi.entity.Entity;
+import me.hammerle.supersnuvi.entity.EntityBuilder;
+import me.hammerle.supersnuvi.tiles.Location;
+import me.hammerle.supersnuvi.tiles.Tile;
+import me.hammerle.supersnuvi.util.CollisionObject;
+import me.hammerle.supersnuvi.util.Utils;
+
+public final class StartScreenLevel implements ILevel
+{
+    private final LevelData data;
+ 
+    private final HashMap<Integer, Entity> entities = new HashMap<>();
+    private final LinkedList<Entity> spawnQueue = new LinkedList<>();
+    private final Entity hero;
+    private int entityCounter = 0;
+   
+    private float cameraX = 0.0f;
+    private float cameraY = 0.0f;
+    private float oldCameraX = 0.0f;
+    private float oldCameraY = 0.0f;
+    
+    private float heroSpawnX;
+    private float heroSpawnY;
+    
+    private final int meshSize = 16;
+    private final int meshLayers;
+    private final int meshWidth;
+    private final int meshHeight;
+    private final TextureRenderer[][][] meshes;   
+    
+    public StartScreenLevel()
+    {
+        hero = EntityBuilder.buildStartScreenHero(this, 0.0f, 0.0f);
+        spawnEntity(hero);
+        
+        this.data = generate();
+
+        meshLayers = data.getLayers() - 1;
+        meshWidth = (int) Math.ceil((double) data.getWidth() / meshSize);
+        meshHeight = (int) Math.ceil((double) data.getHeight() / meshSize);
+        meshes = new TextureRenderer[meshLayers][meshWidth][meshHeight];
+        for(int l = 0; l < meshLayers; l++)
+        {
+            for(int mx = 0; mx < meshWidth; mx++)
+            {
+                for(int my = 0; my < meshHeight; my++)
+                {
+                    meshes[l][mx][my] = new TextureRenderer(meshSize * meshSize * 2);
+                }
+            }
+        }
+        
+        oldCameraX = -getViewX(hero.getCenterX());
+        oldCameraY = -getViewY(hero.getCenterY());
+        cameraX = oldCameraX;
+        cameraY = oldCameraY;
+    }
+    
+    private void placeLamp(LevelData ld, int ox, int oy)
+    {
+        ox -= 2;
+        oy -= 3;
+        for(int x = 0; x < 5; x++)
+        {
+            for(int y = 0; y < 5; y++)
+            {
+                ld.setTile(3, ox + x, y + oy, 45 + 5 * y + x);
+            }
+        }  
+    }
+    
+    private LevelData generate()
+    {
+        int modules = 20;
+        int l = 4;
+        int w = modules * 10;
+        int h = 50;
+        int hh = h / 2;
+        
+        heroSpawnX = 0;
+        heroSpawnY = (hh - 2) * Tile.SIZE;
+        hero.setPosition(heroSpawnX, heroSpawnY);
+        
+        LevelData ld = new LevelData(null, 1, l, w, h);
+        
+        // fill background with london background tile and clear foreground
+        for(int x = 0; x < w; x++)
+        {
+            for(int y = 0; y < h; y++)
+            {
+                ld.setTile(0, x, y, 44);
+                ld.setTile(3, x, y, -1);
+            }
+        }
+        
+        // base interact layer
+        for(int x = 0; x < w; x++)
+        {
+            for(int y = 0; y < hh; y++)
+            {
+                ld.setTile(1, x, y, -1);
+            }
+            for(int y = hh; y < h; y++)
+            {
+                ld.setTile(1, x, y, 43);
+            }
+        }
+        
+        // generate modules
+        Random r = new Random();
+        // base ground for start and end
+        for(int x = 0; x < 10; x++)
+        {
+            ld.setTile(1, x, hh, 42);
+        }
+        for(int x = 0; x < 10; x++)
+        {
+            ld.setTile(1, x + (modules - 1) * 10, hh, 42);
+        }
+        
+        for(int i = 1; i < modules - 1; i++)
+        {
+            int ox = i * 10; 
+            switch(r.nextInt(9))
+            {
+                case 0:
+                    ld.setTile(1, ox, hh, 42);
+                    ld.setTile(1, ox + 1, hh, 42);
+                    ld.setTile(1, ox + 7, hh, 42);
+                    ld.setTile(1, ox + 8, hh, 42);
+                    ld.setTile(1, ox + 9, hh, 42);
+                    
+                    ld.setTile(1, ox + 2, hh - 1, 36);
+                    ld.setTile(1, ox + 3, hh - 1, 43);
+                    ld.setTile(1, ox + 4, hh - 1, 43);
+                    ld.setTile(1, ox + 5, hh - 1, 43);
+                    ld.setTile(1, ox + 6, hh - 1, 43);
+                    
+                    ld.setTile(1, ox + 3, hh - 2, 36);
+                    ld.setTile(1, ox + 4, hh - 2, 43);
+                    ld.setTile(1, ox + 5, hh - 2, 43);
+                    ld.setTile(1, ox + 6, hh - 2, 43);
+                    
+                    ld.setTile(1, ox + 4, hh - 3, 36);
+                    ld.setTile(1, ox + 5, hh - 3, 42);
+                    ld.setTile(1, ox + 6, hh - 3, 42);
+                    
+                    placeLamp(ld, ox + 5, hh - 4);
+                    break;
+                case 1:
+                    ld.setTile(1, ox, hh - 1, 37);
+                    ld.setTile(1, ox + 1, hh - 1, 38);
+                    ld.setTile(1, ox + 2, hh - 1, 43);
+                    ld.setTile(1, ox + 3, hh - 1, 43);
+                    ld.setTile(1, ox + 4, hh - 1, 43);
+                    ld.setTile(1, ox + 5, hh - 1, 43);
+                    ld.setTile(1, ox + 6, hh - 1, 43);
+                    ld.setTile(1, ox + 7, hh - 1, 43);
+                    ld.setTile(1, ox + 8, hh - 1, 41);
+                    ld.setTile(1, ox + 9, hh - 1, 40);
+                    
+                    ld.setTile(1, ox + 2, hh - 2, 37);
+                    ld.setTile(1, ox + 3, hh - 2, 38);
+                    ld.setTile(1, ox + 4, hh - 2, 42);
+                    ld.setTile(1, ox + 5, hh - 2, 42);
+                    ld.setTile(1, ox + 6, hh - 2, 41);
+                    ld.setTile(1, ox + 7, hh - 2, 40);
+                    
+                    placeLamp(ld, ox + 4, hh - 3);
+                    break;
+                case 2:
+                    for(int x = 0; x < 5; x++)
+                    {
+                        for(int y = 0; y < 3; y++)
+                        {
+                            ld.setTile(1, ox + x + 3, hh - y, 43);
+                        }
+                    }
+                    
+                    for(int x = 0; x < 2; x++)
+                    {
+                        for(int y = 0; y < 3; y++)
+                        {
+                            ld.setTile(1, ox + x + 6, hh - y - 3, 43);
+                        }
+                    }
+                    
+                    ld.setTile(1, ox, hh, 42);
+                    ld.setTile(1, ox + 1, hh, 42);
+                    ld.setTile(1, ox + 2, hh, 42);
+                    ld.setTile(1, ox + 3, hh - 3, 42);
+                    ld.setTile(1, ox + 4, hh - 3, 42);
+                    ld.setTile(1, ox + 5, hh - 3, 42);
+                    ld.setTile(1, ox + 6, hh - 6, 42);
+                    ld.setTile(1, ox + 7, hh - 6, 42);
+                    ld.setTile(1, ox + 8, hh, 42);
+                    ld.setTile(1, ox + 9, hh, 42);
+                    
+                    placeLamp(ld, ox + 3, hh - 4);
+                    break;
+                case 3:
+                    ld.setTile(1, ox, hh, 42);
+                    ld.setTile(1, ox + 1, hh, 42);
+                    ld.setTile(1, ox + 2, hh + 1, 42);
+                    ld.setTile(1, ox + 3, hh + 1, 42);
+                    ld.setTile(1, ox + 4, hh + 2, 42);
+                    ld.setTile(1, ox + 5, hh + 2, 42);
+                    ld.setTile(1, ox + 6, hh + 3, 42);
+                    ld.setTile(1, ox + 7, hh + 3, 42);
+                    ld.setTile(1, ox + 8, hh, 42);
+                    ld.setTile(1, ox + 9, hh, 42);
+                    
+                    placeLamp(ld, ox + 6, hh + 2);
+                    
+                    for(int x = 0; x < 6; x += 2)
+                    {
+                        for(int x2 = x; x2 < 6; x2++)
+                        {
+                            ld.setTile(1, ox + x2 + 2, hh + (x / 2), -1);
+                        }
+                    }
+                    break;
+                case 4:
+                    for(int x = 0; x < 10; x++)
+                    {
+                        ld.setTile(1, x + ox, hh, 42);
+                    }
+                    placeLamp(ld, ox + 5, hh - 1);
+                    break;
+                case 5:
+                    for(int x = 0; x < 6; x++)
+                    {
+                        for(int y = 0; y < 4; y++)
+                        {
+                            ld.setTile(1, x + ox + 2, hh + y, -1);
+                        }
+                    }
+                    for(int x = 0; x < 2; x++)
+                    {
+                        for(int y = 0; y < 3; y++)
+                        {
+                            ld.setTile(1, x + ox + 4, hh + y + 4, -1);
+                        }
+                    }
+                    ld.setTile(1, ox, hh, 42);
+                    ld.setTile(1, ox + 1, hh, 42);
+                    ld.setTile(1, ox + 2, hh + 4, 42);
+                    ld.setTile(1, ox + 3, hh + 4, 42);
+                    ld.setTile(1, ox + 4, hh + 7, 42);
+                    ld.setTile(1, ox + 5, hh + 7, 42);
+                    ld.setTile(1, ox + 6, hh + 4, 42);
+                    ld.setTile(1, ox + 7, hh + 4, 42);
+                    ld.setTile(1, ox + 8, hh, 42);
+                    ld.setTile(1, ox + 9, hh, 42);
+                    placeLamp(ld, ox + 3, hh + 3);
+                    break;
+                case 6:
+                {
+                    int start = 0;
+                    int end = 10;
+                    int y = 0;
+                    while(start < end)
+                    {
+                        for(int x = start; x < end; x++)
+                        {
+                            ld.setTile(1, x + ox, hh - y, 43);
+                        }
+                        ld.setTile(1, start + ox, hh - y, 42);
+                        ld.setTile(1, end - 1 + ox, hh - y, 42);
+                        y++;
+                        start++;
+                        end--;
+                    }
+                    break;
+                }
+                case 7:
+                    ld.setTile(1, ox, hh, 41);
+                    ld.setTile(1, ox + 1, hh, 40);
+                    ld.setTile(1, ox + 2, hh, -1);
+                    ld.setTile(1, ox + 3, hh, -1);
+                    ld.setTile(1, ox + 4, hh, -1);
+                    ld.setTile(1, ox + 5, hh, -1);
+                    ld.setTile(1, ox + 6, hh, -1);
+                    ld.setTile(1, ox + 7, hh, -1);
+                    ld.setTile(1, ox + 8, hh, 37);
+                    ld.setTile(1, ox + 9, hh, 38);
+                    
+                    ld.setTile(1, ox + 2, hh + 1, 41);
+                    ld.setTile(1, ox + 3, hh + 1, 40);
+                    ld.setTile(1, ox + 4, hh + 1, -1);
+                    ld.setTile(1, ox + 5, hh + 1, -1);
+                    ld.setTile(1, ox + 6, hh + 1, 37);
+                    ld.setTile(1, ox + 7, hh + 1, 38);
+                    
+                    ld.setTile(1, ox + 4, hh + 2, 42);
+                    ld.setTile(1, ox + 5, hh + 2, 42);
+                    
+                    placeLamp(ld, ox + 4, hh + 1);
+                    break;
+                case 8:
+                    for(int x = 0; x < 8; x++)
+                    {
+                        for(int y = 0; y < 7; y++)
+                        {
+                            ld.setTile(1, x + ox + 1, hh + y, -1);
+                        }
+                    }
+                    ld.setTile(1, ox, hh, 42);
+                    ld.setTile(1, ox + 9, hh, 42);
+                    for(int x = 1; x < 9; x++)
+                    {
+                        ld.setTile(1, ox + x, hh + 7, 42);
+                    }
+                    placeLamp(ld, ox + 4, hh + 6);
+                    ld.setTile(1, ox + 8, hh + 6,5);
+                    break;
+            }
+        }
+        
+        return ld;
+    }
+
+    // -------------------------------------------------------------------------
+    // basic stuff
+    // -------------------------------------------------------------------------
+
+    @Override
+    public Entity getHero()
+    {
+        return hero;
+    }
+    
+    @Override
+    public void finishLevel()
+    {
+    }
+    
+    @Override
+    public void scheduleReset()
+    {
+    }
+    
+    @Override
+    public void spawnEntity(Entity ent)
+    {
+        spawnQueue.add(ent);
+    }
+    
+    @Override
+    public void increaseSouls(int score)
+    {
+    }
+    
+    @Override
+    public int getWidth()
+    {
+        return data.getWidth();
+    }
+    
+    @Override
+    public int getHeight()
+    {
+        return data.getHeight();
+    }
+
+    // -------------------------------------------------------------------------
+    // tick
+    // -------------------------------------------------------------------------
+    
+    public void tick()
+    {
+        Game.get().tickTiles();
+
+        // doing entity logic first
+        entities.values().removeIf(entity -> 
+        {
+            entity.tick();
+            return entity.getHealth().shouldDespawn();
+        });
+        
+        if(!spawnQueue.isEmpty())
+        {
+            spawnQueue.forEach(ent -> entities.put(entityCounter++, ent));
+            spawnQueue.clear();
+        }
+        
+        if(hero.getX() > data.getWidth() * Tile.SIZE)
+        {
+            hero.setPosition(heroSpawnX, heroSpawnY);
+            // calculate new camera position
+            cameraX = -getViewX(hero.getCenterX());
+            cameraY = -getViewY(hero.getCenterY());
+            oldCameraX = cameraX;
+            oldCameraY = cameraY;
+        }
+        else
+        {
+            // calculate new camera position
+            oldCameraX = cameraX;
+            oldCameraY = cameraY;
+            cameraX = -getViewX(hero.getCenterX());
+            cameraY = -getViewY(hero.getCenterY());
+        }
+
+        // entity spawn layer after camera update
+        int startX = (int) (-cameraX / Tile.SIZE);
+        int startY = (int) (-cameraY / Tile.SIZE);
+        int endX = Math.min((int) Math.ceil((-cameraX + Shader.getViewWidth()) / Tile.SIZE), data.getWidth());
+        int endY = Math.min((int) Math.ceil((-cameraY + Shader.getViewHeight()) / Tile.SIZE), data.getWidth());
+        data.forEachEntity((x, y, tile) -> 
+        {
+            if(tile > 0)
+            {
+                data.deactivateEntity(x, y);
+
+                Entity ent = EntityBuilder.fromId(tile, this, Utils.toCoord(x), Utils.toCoord(y));
+                if(ent != null)
+                {
+                    entities.put(entityCounter++, ent);
+                }
+            }
+        }, startX, endX, startY, endY);
+    }   
+    
+    private float getViewX(float x) 
+    {
+        x -= Shader.getViewWidth() >> 1;
+        if(x < 0)
+        {
+            return 0;
+        }
+        float max = data.getWidth() * Tile.SIZE - Shader.getViewWidth();
+        if(x > max)
+        {
+            return max;
+        }
+        return x;
+    }
+    
+    private float getViewY(float y) 
+    {
+        y -= Shader.getViewHeight() >> 1;
+        if(y < 0)
+        {
+            return 0;
+        }
+        float max = data.getHeight() * Tile.SIZE - Shader.getViewHeight();
+        if(y > max)
+        {
+            return max;
+        }
+        return y;
+    }
+    
+    @Override
+    public void updateTile(int layer, int x, int y)
+    {
+        if(layer > data.getBackgroundIndex())
+        {
+            layer--;
+        }
+        meshes[layer][x / meshSize][y / meshSize].clear();
+    }
+    
+    @Override
+    public void updateTile(int x, int y)
+    {
+        updateTile(data.getBackgroundIndex(), x, y);
+    }
+    
+    private void drawMesh(int l, int tl, int mx, int my)
+    {
+        TextureRenderer tr = meshes[l][mx][my];
+        if(!tr.isBuilt())
+        {
+            int tsx = mx * meshSize;
+            int tsy = my * meshSize;
+            int tex = Math.min(tsx + meshSize, data.getWidth());
+            int tey = Math.min(tsy + meshSize, data.getHeight());
+            for(int x = tsx; x < tex; x++)
+            {
+                for(int y = tsy; y < tey; y++)
+                {
+                    Tile t = Game.get().getTile(data.getTile(tl, x, y));
+                    if(t.shouldRender(x, y, this))
+                    {
+                        float minX = x * Tile.SIZE + t.getOffsetX();
+                        float minY = y * Tile.SIZE + t.getOffsetY();
+                        tr.addRectangle(minX, minY, 
+                                minX + t.getWidth(), minY + t.getHeight(), 
+                                t.getTextureMinX() + Level.ERROR, t.getTextureMinY() + Level.ERROR,
+                                t.getTextureMaxX() - Level.ERROR, t.getTextureMaxY() - Level.ERROR);
+                    }
+                }
+            }
+            tr.build();
+        }
+        meshes[l][mx][my].draw();
+    }
+    
+    public void renderTick(float lag)
+    {
+        float camX = Utils.interpolate(oldCameraX, cameraX, lag);
+        float camY = Utils.interpolate(oldCameraY, cameraY, lag);
+        
+        //System.out.println("CAM " + hero.getCenterX()+ " " + hero.getCenterY());
+        //System.out.println("CAM " + oldCameraX + " " + oldCameraY + " " + cameraX + " " + cameraY);
+
+        Shader.translateTo(camX, camY);
+        Shader.updateMatrix();
+
+        int startX = (int) (-camX / (meshSize * Tile.SIZE));
+        int startY = (int) (-camY / (meshSize * Tile.SIZE));
+        int endX = (int) Math.ceil((-camX + Shader.getViewWidth()) / (meshSize * Tile.SIZE));
+        int endY = (int) Math.ceil((-camY + Shader.getViewHeight()) / (meshSize * Tile.SIZE));
+
+        startX = Math.min(Math.max(startX, 0), meshWidth);
+        startY = Math.min(Math.max(startY, 0), meshHeight);
+        endX = Math.min(Math.max(endX, 0), meshWidth);
+        endY = Math.min(Math.max(endY, 0), meshHeight);
+
+        // background
+        Shader.setColorEnabled(false);
+        Shader.setTextureEnabled(true);
+        Shader.setBlendingEnabled(true);
+        Level.TILES.bind();
+
+        int fromLayer = 0;
+        int toLayer = data.getBackgroundIndex() + 1;
+
+        for(int l = fromLayer; l < toLayer; l++)
+        {
+            for(int mx = startX; mx < endX; mx++)
+            {
+                for(int my = startY; my < endY; my++)
+                {
+                    drawMesh(l, l, mx, my);
+                }
+            }
+        }
+
+        // entities
+
+        entities.values().forEach(entity -> 
+        {
+            entity.renderTick(lag);
+        });
+        
+        // foreground
+        Shader.setColorEnabled(false);
+        Shader.setTextureEnabled(true);
+        Shader.setBlendingEnabled(true);
+        Level.TILES.bind();
+
+        fromLayer = toLayer + 1;
+        toLayer = data.getLayers();
+
+        for(int l = fromLayer; l < toLayer; l++)
+        {
+            for(int mx = startX; mx < endX; mx++)
+            {
+                for(int my = startY; my < endY; my++)
+                {
+                    drawMesh(l - 1, l, mx, my);
+                }
+            }
+        }
+    }
+    
+    // -------------------------------------------------------------------------
+    // collision box, interaction layer
+    // -------------------------------------------------------------------------
+    
+    private Tile getInteractionTile(int x, int y)
+    {
+        int i = data.getInteractionTile(x, y);
+        if(i == -1)
+        {
+            return Game.FALLBACK_TILE;
+        }
+        return Game.get().getTile(i);
+    }
+    
+    private CollisionObject getMovementBox(int x, int y)
+    {
+        int i = data.getInteractionTile(x, y);
+        if(i == -1)
+        {
+            return CollisionObject.NULL_BOX;
+        }
+        return Game.get().getTile(i).getMovementBox(x, y, this).reset().offset(Utils.toCoord(x), Utils.toCoord(y));
+    }
+    
+    @Override
+    public List<CollisionObject> getMovementBoxesAt(CollisionObject box, Entity not)
+    {
+        List<CollisionObject> boxes;
+        if(not != null)
+        {
+            boxes = getEntitiesCollidingWith(not, box).stream().map(ent -> ent.getBox()).collect(Collectors.toList());
+        }
+        else
+        {
+            boxes = new LinkedList<>();
+        }
+        int startX = Utils.toBlock(box.getMinX());
+        int endX = Utils.toBlock(box.getMaxX());
+        int startY = Utils.toBlock(box.getMinY());
+        int endY = Utils.toBlock(box.getMaxY());
+        
+        for(int x = startX; x <= endX; x++)
+        {
+            for(int y = startY; y <= endY; y++)
+            {
+                CollisionObject cb = getMovementBox(x, y);
+                if(cb.mayCollide(box) && cb != CollisionObject.NULL_BOX)
+                {
+                    boxes.add(cb.copy());
+                }
+            }
+        }
+        return boxes;
+    }
+    
+    private CollisionObject getCollisionBox(int x, int y)
+    {
+        int i = data.getInteractionTile(x, y);
+        if(i == -1)
+        {
+            return CollisionObject.NULL_BOX;
+        }
+        Tile tile = Game.get().getTile(i);
+        return tile.getCollisionBox(x, y, this).reset().offset(Utils.toCoord(x), Utils.toCoord(y));
+    }
+    
+    @Override
+    public List<Location> getCollisionBoxesAt(CollisionObject cb)
+    {
+        LinkedList<Location> boxes = new LinkedList<>();
+        int startX = Utils.toBlock(cb.getMinX());
+        int endX = Utils.toBlock(cb.getMaxX());
+        int startY = Utils.toBlock(cb.getMinY());
+        int endY = Utils.toBlock(cb.getMaxY());
+        
+        for(int x = startX; x <= endX; x++)
+        {
+            for(int y = startY; y <= endY; y++)
+            {
+                if(getCollisionBox(x, y).isColliding(cb))
+                {
+                    boxes.add(new Location(getInteractionTile(x, y), this, x, y));
+                }
+            }
+        }
+        return boxes;
+    }
+    
+    @Override
+    public List<Entity> getEntitiesCollidingWith(Entity not, CollisionObject cb)
+    {
+        return entities.values().stream().filter(ent -> ent != not && ent.getBox().isColliding(cb)).collect(Collectors.toList());
+    }
+}

+ 6 - 7
src/me/hammerle/supersnuvi/tiles/BottledSoulTile.java

@@ -1,8 +1,7 @@
 package me.hammerle.supersnuvi.tiles;
 
-import java.util.HashSet;
 import me.hammerle.supersnuvi.entity.Entity;
-import me.hammerle.supersnuvi.gamelogic.Level;
+import me.hammerle.supersnuvi.gamelogic.ILevel;
 import me.hammerle.supersnuvi.util.BlockDataStorage;
 import me.hammerle.supersnuvi.util.CollisionBox;
 import me.hammerle.supersnuvi.util.CollisionObject;
@@ -22,7 +21,7 @@ public class BottledSoulTile extends BaseTile
     }
 
     @Override
-    public void onEntityCollide(Entity ent, int x, int y, Face face, Level l) 
+    public void onEntityCollide(Entity ent, int x, int y, Face face, ILevel l) 
     {
         if(ent.getItemCollector().canCollect())
         {
@@ -40,7 +39,7 @@ public class BottledSoulTile extends BaseTile
     }
     
     @Override
-    public CollisionObject getCollisionBox(int x, int y, Level l) 
+    public CollisionObject getCollisionBox(int x, int y, ILevel l) 
     {
         if(states.contains(x, y, l))
         {
@@ -50,19 +49,19 @@ public class BottledSoulTile extends BaseTile
     }
 
     @Override
-    public boolean shouldAiUseCollisionBox(int x, int y, Level l) 
+    public boolean shouldAiUseCollisionBox(int x, int y, ILevel l) 
     {
         return false;
     }
     
     @Override
-    public boolean shouldRender(int x, int y, Level l) 
+    public boolean shouldRender(int x, int y, ILevel l) 
     {
         return !states.contains(x, y, l);
     }
     
     @Override
-    public void reset(Level l) 
+    public void reset(ILevel l) 
     {
         states.clear(l);
     } 

+ 6 - 7
src/me/hammerle/supersnuvi/tiles/CrumblingStoneTile.java

@@ -1,9 +1,8 @@
 package me.hammerle.supersnuvi.tiles;
 
-import java.util.HashSet;
 import me.hammerle.supersnuvi.entity.Entity;
 import me.hammerle.supersnuvi.entity.EntityBuilder;
-import me.hammerle.supersnuvi.gamelogic.Level;
+import me.hammerle.supersnuvi.gamelogic.ILevel;
 import me.hammerle.supersnuvi.util.BlockDataStorage;
 import me.hammerle.supersnuvi.util.CollisionBox;
 import me.hammerle.supersnuvi.util.CollisionObject;
@@ -23,7 +22,7 @@ public class CrumblingStoneTile extends BaseTile
     }
 
     @Override
-    public CollisionObject getCollisionBox(int x, int y, Level l) 
+    public CollisionObject getCollisionBox(int x, int y, ILevel l) 
     {
         if(states.contains(x, y, l))
         {
@@ -33,7 +32,7 @@ public class CrumblingStoneTile extends BaseTile
     }
 
     @Override
-    public CollisionObject getMovementBox(int x, int y, Level l) 
+    public CollisionObject getMovementBox(int x, int y, ILevel l) 
     {
         if(states.contains(x, y, l))
         {
@@ -43,7 +42,7 @@ public class CrumblingStoneTile extends BaseTile
     }
 
     @Override
-    public void onEntityCollide(Entity ent, int x, int y, Face face, Level l) 
+    public void onEntityCollide(Entity ent, int x, int y, Face face, ILevel l) 
     {
         super.onEntityCollide(ent, x, y, face, l);
         if(face == Face.UP)
@@ -58,13 +57,13 @@ public class CrumblingStoneTile extends BaseTile
     }
 
     @Override
-    public boolean shouldRender(int x, int y, Level l)
+    public boolean shouldRender(int x, int y, ILevel l)
     {
         return !states.contains(x, y, l);
     }
 
     @Override
-    public void reset(Level l) 
+    public void reset(ILevel l) 
     {
         states.clear(l);
     } 

+ 2 - 2
src/me/hammerle/supersnuvi/tiles/GoalTile.java

@@ -1,7 +1,7 @@
 package me.hammerle.supersnuvi.tiles;
 
 import me.hammerle.supersnuvi.entity.Entity;
-import me.hammerle.supersnuvi.gamelogic.Level;
+import me.hammerle.supersnuvi.gamelogic.ILevel;
 import me.hammerle.supersnuvi.util.CollisionBox;
 import me.hammerle.supersnuvi.util.Face;
 
@@ -14,7 +14,7 @@ public class GoalTile extends BaseTile
     }
 
     @Override
-    public void onEntityCollide(Entity ent, int x, int y, Face face, Level l) 
+    public void onEntityCollide(Entity ent, int x, int y, Face face, ILevel l) 
     {
         if(ent.getItemCollector().isHero())
         {

+ 2 - 2
src/me/hammerle/supersnuvi/tiles/KillTile.java

@@ -1,7 +1,7 @@
 package me.hammerle.supersnuvi.tiles;
 
 import me.hammerle.supersnuvi.entity.Entity;
-import me.hammerle.supersnuvi.gamelogic.Level;
+import me.hammerle.supersnuvi.gamelogic.ILevel;
 import me.hammerle.supersnuvi.util.CollisionBox;
 import me.hammerle.supersnuvi.util.Face;
 
@@ -14,7 +14,7 @@ public class KillTile extends BaseTile
     }
 
     @Override
-    public void onEntityCollide(Entity ent, int x, int y, Face face, Level l) 
+    public void onEntityCollide(Entity ent, int x, int y, Face face, ILevel l) 
     {
         super.onEntityCollide(ent, x, y, face, l);
         ent.getHealth().addHealth(-14.3f);

+ 4 - 4
src/me/hammerle/supersnuvi/tiles/Location.java

@@ -1,15 +1,15 @@
 package me.hammerle.supersnuvi.tiles;
 
-import me.hammerle.supersnuvi.gamelogic.Level;
+import me.hammerle.supersnuvi.gamelogic.ILevel;
 
 public class Location 
 {
     private final Tile tile;
-    private final Level l;
+    private final ILevel l;
     private final int x;
     private final int y;
     
-    public Location(Tile tile, Level l, int x, int y)
+    public Location(Tile tile, ILevel l, int x, int y)
     {
         this.tile = tile;
         this.l = l;
@@ -22,7 +22,7 @@ public class Location
         return tile;
     }
     
-    public Level getLevel() 
+    public ILevel getLevel() 
     {
         return l;
     }

+ 3 - 3
src/me/hammerle/supersnuvi/tiles/NullTile.java

@@ -1,6 +1,6 @@
 package me.hammerle.supersnuvi.tiles;
 
-import me.hammerle.supersnuvi.gamelogic.Level;
+import me.hammerle.supersnuvi.gamelogic.ILevel;
 
 public class NullTile extends Tile
 {
@@ -9,13 +9,13 @@ public class NullTile extends Tile
     }
 
     @Override
-    public boolean shouldRender(int x, int y, Level l)
+    public boolean shouldRender(int x, int y, ILevel l)
     {
         return false;
     }
 
     @Override
-    public boolean shouldAiUseCollisionBox(int x, int y, Level l)
+    public boolean shouldAiUseCollisionBox(int x, int y, ILevel l)
     {
         return false;
     }

+ 3 - 2
src/me/hammerle/supersnuvi/tiles/SlipperyTile.java

@@ -1,7 +1,8 @@
 package me.hammerle.supersnuvi.tiles;
 
 import me.hammerle.supersnuvi.entity.Entity;
-import me.hammerle.supersnuvi.gamelogic.Level;
+import me.hammerle.supersnuvi.gamelogic.ILevel;
+import me.hammerle.supersnuvi.gamelogic.ILevel;
 import me.hammerle.supersnuvi.util.Face;
 
 public class SlipperyTile extends BaseBoxTile
@@ -12,7 +13,7 @@ public class SlipperyTile extends BaseBoxTile
     }
 
     @Override
-    public void onEntityCollide(Entity ent, int x, int y, Face face, Level l) 
+    public void onEntityCollide(Entity ent, int x, int y, Face face, ILevel l) 
     {
         if(face == Face.UP)
         {

+ 2 - 1
src/me/hammerle/supersnuvi/tiles/SpikeTile.java

@@ -2,6 +2,7 @@ package me.hammerle.supersnuvi.tiles;
 
 import me.hammerle.snuviengine.api.Texture;
 import me.hammerle.supersnuvi.entity.Entity;
+import me.hammerle.supersnuvi.gamelogic.ILevel;
 import me.hammerle.supersnuvi.gamelogic.Level;
 import me.hammerle.supersnuvi.util.CollisionBox;
 import me.hammerle.supersnuvi.util.Face;
@@ -25,7 +26,7 @@ public class SpikeTile extends BaseTile
     }
 
     @Override
-    public void onEntityCollide(Entity ent, int x, int y, Face face, Level l) 
+    public void onEntityCollide(Entity ent, int x, int y, Face face, ILevel l) 
     {
         super.onEntityCollide(ent, x, y, face, l);
         if(frame >= 1)

+ 2 - 2
src/me/hammerle/supersnuvi/tiles/StartTile.java

@@ -1,11 +1,11 @@
 package me.hammerle.supersnuvi.tiles;
 
-import me.hammerle.supersnuvi.gamelogic.Level;
+import me.hammerle.supersnuvi.gamelogic.ILevel;
 
 public class StartTile extends Tile
 {
     @Override
-    public boolean shouldRender(int x, int y, Level l)
+    public boolean shouldRender(int x, int y, ILevel l)
     {
         return false;
     }

+ 7 - 7
src/me/hammerle/supersnuvi/tiles/Tile.java

@@ -1,7 +1,7 @@
 package me.hammerle.supersnuvi.tiles;
 
 import me.hammerle.supersnuvi.entity.Entity;
-import me.hammerle.supersnuvi.gamelogic.Level;
+import me.hammerle.supersnuvi.gamelogic.ILevel;
 import me.hammerle.supersnuvi.util.CollisionObject;
 import me.hammerle.supersnuvi.util.Face;
 
@@ -65,7 +65,7 @@ public abstract class Tile
         return this;
     }
     
-    public CollisionObject getCollisionBox(int x, int y, Level l)
+    public CollisionObject getCollisionBox(int x, int y, ILevel l)
     {
         if(collisionBox != null)
         {
@@ -74,12 +74,12 @@ public abstract class Tile
         return CollisionObject.NULL_BOX.reset();
     }
     
-    public boolean shouldAiUseCollisionBox(int x, int y, Level l)
+    public boolean shouldAiUseCollisionBox(int x, int y, ILevel l)
     {
         return true;
     }
     
-    public CollisionObject getMovementBox(int x, int y, Level l)
+    public CollisionObject getMovementBox(int x, int y, ILevel l)
     {
         if(movementCollision != null)
         {
@@ -88,7 +88,7 @@ public abstract class Tile
         return CollisionObject.NULL_BOX.reset();
     }
     
-    public void onEntityCollide(Entity ent, int x, int y, Face face, Level l)
+    public void onEntityCollide(Entity ent, int x, int y, Face face, ILevel l)
     {
         
     }
@@ -97,7 +97,7 @@ public abstract class Tile
     {
     }
     
-    public void reset(Level l)
+    public void reset(ILevel l)
     {
     }
     
@@ -146,7 +146,7 @@ public abstract class Tile
         return Tile.SIZE;
     }
     
-    public boolean shouldRender(int x, int y, Level l)
+    public boolean shouldRender(int x, int y, ILevel l)
     {
         return true;
     }

+ 2 - 2
src/me/hammerle/supersnuvi/tiles/TrampolinTile.java

@@ -1,7 +1,7 @@
 package me.hammerle.supersnuvi.tiles;
 
 import me.hammerle.supersnuvi.entity.Entity;
-import me.hammerle.supersnuvi.gamelogic.Level;
+import me.hammerle.supersnuvi.gamelogic.ILevel;
 import me.hammerle.supersnuvi.util.Face;
 import me.hammerle.supersnuvi.util.SoundUtils;
 
@@ -13,7 +13,7 @@ public class TrampolinTile extends BaseBoxTile
     }
 
     @Override
-    public void onEntityCollide(Entity ent, int x, int y, Face face, Level l) 
+    public void onEntityCollide(Entity ent, int x, int y, Face face, ILevel l) 
     {
         if(face == Face.UP)
         {

+ 3 - 2
src/me/hammerle/supersnuvi/tiles/WaterTile.java

@@ -2,6 +2,7 @@ package me.hammerle.supersnuvi.tiles;
 
 import me.hammerle.snuviengine.api.Texture.Animation;
 import me.hammerle.supersnuvi.entity.Entity;
+import me.hammerle.supersnuvi.gamelogic.ILevel;
 import me.hammerle.supersnuvi.gamelogic.Level;
 import me.hammerle.supersnuvi.util.CollisionBox;
 import me.hammerle.supersnuvi.util.CollisionObject;
@@ -27,7 +28,7 @@ public class WaterTile extends BaseTile
     }
 
     @Override
-    public void onEntityCollide(Entity ent, int x, int y, Face face, Level l) 
+    public void onEntityCollide(Entity ent, int x, int y, Face face, ILevel l) 
     {
         super.onEntityCollide(ent, x, y, face, l);
         ent.getMovement().setInWater(true);
@@ -38,7 +39,7 @@ public class WaterTile extends BaseTile
     }
 
     @Override
-    public boolean shouldAiUseCollisionBox(int x, int y, Level l)
+    public boolean shouldAiUseCollisionBox(int x, int y, ILevel l)
     {
         return false;
     }

+ 6 - 6
src/me/hammerle/supersnuvi/util/BlockDataStorage.java

@@ -2,7 +2,7 @@ package me.hammerle.supersnuvi.util;
 
 import java.util.HashSet;
 import java.util.Objects;
-import me.hammerle.supersnuvi.gamelogic.Level;
+import me.hammerle.supersnuvi.gamelogic.ILevel;
 
 public class BlockDataStorage
 {
@@ -10,9 +10,9 @@ public class BlockDataStorage
     {
         private final int x;
         private final int y;
-        private final Level level;
+        private final ILevel level;
         
-        private Data(int x, int y, Level level)
+        private Data(int x, int y, ILevel level)
         {
             this.x = x;
             this.y = y;
@@ -64,17 +64,17 @@ public class BlockDataStorage
         
     }
     
-    public boolean add(int x, int y, Level level)
+    public boolean add(int x, int y, ILevel level)
     {
         return data.add(new Data(x, y, level));
     }
     
-    public boolean contains(int x, int y, Level level)
+    public boolean contains(int x, int y, ILevel level)
     {
         return data.contains(new Data(x, y, level));
     }
     
-    public void clear(Level level)
+    public void clear(ILevel level)
     {
         data.removeIf(d -> d.level == level);
     }

+ 2 - 2
src/me/hammerle/supersnuvi/util/Face.java

@@ -4,8 +4,8 @@ import me.hammerle.supersnuvi.entity.Entity;
 
 public enum Face 
 {
-    LEFT(Entity.STEP, 0),
-    RIGHT(-Entity.STEP, 0),
+    LEFT(-Entity.STEP, 0),
+    RIGHT(Entity.STEP, 0),
     UP(0, -Entity.STEP),
     DOWN(0, Entity.STEP);