Browse Source

pushable boxes, fixed water friction, londoner attacked / hurt fixed, crumbling stones falling fixed, silent sound exception, fixed slippery slime

Kajetan Johannes Hammerle 4 years ago
parent
commit
fb8ecefb6b

+ 2 - 0
levels/00-Tech_Demo.snuvi

@@ -73,6 +73,8 @@ function onLevelReset()
     $platform = platform.spawn(tile.toLevelCoord(4), tile.toLevelCoord(11), 3);
     platform.addmove($platform, tile.toLevelCoord(4), tile.toLevelCoord(10), 6, 9, 1);
     platform.addmove($platform, tile.toLevelCoord(3), tile.toLevelCoord(6), 6, 9, 1);
+    
+    entity.spawn(5, tile.toLevelCoord(11), tile.toLevelCoord(4));
 }
 
 function onInteract(x, y, ent)

BIN
resources/tiles.png


BIN
resources/tiles.xcf


+ 2 - 2
slot1.txt

@@ -11,11 +11,11 @@ level.02-Out_of_Reach.map=true
 level.02-Out_of_Reach.map.bottles=10
 level.02-Out_of_Reach.map.time=9.674999999999985
 level.02-Parabola.map=true
-level.02-Parabola.map.bottles=2
+level.02-Parabola.map.bottles=4
 level.02-Parabola.map.time=15.950043
 level.04-Like_Ice.map=true
 level.04-Like_Ice.map.bottles=13
 level.04-Like_Ice.map.time=20.69997
 level.04-Out_of_Reach.map=true
 level.04-Out_of_Reach.map.bottles=8
-level.04-Out_of_Reach.map.time=36.54973
+level.04-Out_of_Reach.map.time=10.950024

+ 1 - 1
src/me/hammerle/supersnuvi/Game.java

@@ -651,7 +651,7 @@ public class Game extends Engine
         // wooden pressure plate
         registeredTiles[73] = new PressureTile(0.568359375f, 0.072265625f, 0.619140625f, 0.078125f);
         // stone pressure plate
-        registeredTiles[74] = new PressureTile(0.568359375f, 0.087890625f, 0.619140625f, 0.09375f);
+        registeredTiles[74] = new PressureTile(0.568359375f, 0.087890625f, 0.619140625f, 0.09375f);        
     }
     
     public Tile getTile(int id)

+ 113 - 128
src/me/hammerle/supersnuvi/entity/Entity.java

@@ -1,7 +1,5 @@
 package me.hammerle.supersnuvi.entity;
 
-import java.util.ArrayList;
-import java.util.List;
 import me.hammerle.supersnuvi.entity.components.ai.Controller;
 import me.hammerle.supersnuvi.entity.components.Energy;
 import me.hammerle.supersnuvi.entity.components.Health;
@@ -17,7 +15,7 @@ import me.hammerle.supersnuvi.entity.components.IDespawn;
 public final class Entity
 {
     public static final float GRAVITY = 8.0f * Tile.SIZE_SCALE;
-    public static final float STEP = 0.0625f;
+    public static final float STEP = 0.015625f;
     // this one is a little bit bigger to prevent wrong calculation
     // while going upwards
     public static final float UP_STEP = STEP + 0.00390625f;
@@ -37,6 +35,7 @@ public final class Entity
     // the motion, reduced by the movement collision check
     private final Vector motion = new Vector();
     // the friction reducing motion each tick
+    private final Vector baseFriction = new Vector(0.0f, 1.0f);
     private final Vector friction = new Vector(0.0f, 1.0f);
     // a flag indicating that the entity is on the ground
     private boolean onGround = true;
@@ -49,6 +48,7 @@ public final class Entity
     private final IDespawn onDespawn;
     // the type of the entity, used by snuvi script
     private final String type;
+    private Face direction = Face.NULL;
     
     protected Entity(float width, float height, Controller c, Health h, Energy e, Movement m, ItemCollector ic, IDespawn d, String type)
     {
@@ -192,9 +192,14 @@ public final class Entity
         motion.add(x, y);
     }
     
-    public void setFriction(float fx, float fy)
+    public void setBaseFriction(float fx, float fy)
     {
-        friction.set(fx, fy);
+        baseFriction.set(fx, fy);
+    }
+    
+    public Vector getFriction()
+    {
+        return friction;
     }
     
     public boolean isAt(float x, float y)
@@ -229,6 +234,11 @@ public final class Entity
         return false;
     }
     
+    public Face getDirection()
+    {
+        return direction;
+    }
+    
     //--------------------------------------------------------------------------
     // ticking
     //--------------------------------------------------------------------------
@@ -240,16 +250,20 @@ public final class Entity
         lastMotion.set(0.0f, 0.0f);
         
         // reset own force
-        ownForce.set(0.0f, 0.0f);
-        
-        // remeber last position for rendering
-        lastPos.set(pos);
+        ownForce.set(0.0f, 0.0f);      
         
         // update onGround before controller tick
         onGround = isOnTileGround(level);
         if(onGround)
         {
-            motion.setY(0.0f);
+            if(!move.canMoveOnTiles())
+            {
+                motion.setY(0.0f);
+            }
+        }
+        else
+        {
+            friction.set(0.2f, 1.0f);
         }
         
         // tick components
@@ -262,13 +276,31 @@ public final class Entity
         {
             motion.addY(GRAVITY * move.getGravityFactor());
         }
-
+        
         // apply friction
         motion.mul(friction);
+        if(move.isInWater())
+        {
+            motion.mul(friction);
+            move.setInWater(false);
+        }
+        friction.set(baseFriction);
         
         // modify current motion by own force
         motion.add(ownForce);
         
+        if(ownForce.getX() < 0.0f)
+        {
+            direction = Face.LEFT;
+        }
+        else if(ownForce.getX() > 0.0f)
+        {
+            direction = Face.RIGHT;
+        }
+    }
+    
+    public void tickCollision(Level level)
+    {
         // (entity <-> tile) collision
         doTileCollision(level);
         // (entity <-> entity) collision
@@ -276,6 +308,11 @@ public final class Entity
         {
             controller.onCollideWithEntity(this, ent, getCollidingFace(ent));
         });
+        
+        slideOnEdge(level);
+        
+        // remeber last position for rendering
+        lastPos.set(pos);
     }
     
     public int move(Level level)
@@ -287,8 +324,10 @@ public final class Entity
         Vector maxMotion = new Vector();
         maxMotion.set(motion);
         
-        reduceMotionByTiles(level);   
-        reduceMotionByEntities(level);    
+        if(!move.canMoveOnEntities() || !move.canMoveOnTiles())
+        {
+            reduceMotion(level);
+        }
         pos.add(motion);
         
         int r = (motion.getX() == 0.0f && motion.getY() == 0.0f) ? 0 : 1;
@@ -363,112 +402,12 @@ public final class Entity
         }
     }
     
-    private void reduceMotionByEntities(Level level)
+    private boolean isCollidingWithTiles(int startX, int startY, int endX, int endY, Level level)
     {
-        if(motion.getX() == 0.0f && motion.getY() == 0.0f)
+        if(move.canMoveOnTiles())
         {
-            return;
-        }
-        
-        float mx = motion.getX();
-        float my = motion.getY();
-        
-        float oldPosX = pos.getX();
-        float oldPosY = pos.getY();
-
-        while(mx != 0.0 || my != 0.0)
-        {
-            if(mx != 0.0f)
-            {
-                float oldX = pos.getX();
-                if(mx < 0.0)
-                {
-                    if(mx > -STEP)
-                    {
-                        pos.addX(mx);
-                        mx = 0.0f;
-                    }
-                    else
-                    {
-                        pos.addX(-STEP);
-                        mx += STEP;
-                    }
-                }
-                else if(mx > 0.0)
-                {
-                    if(mx < STEP)
-                    {
-                        pos.addX(mx);
-                        mx = 0.0f;
-                    }
-                    else
-                    {
-                        pos.addX(STEP);
-                        mx -= STEP;
-                    }
-                }
-
-                List<Entity> list = isCollidingWithEntities(level);
-                for(Entity ent : list)
-                {
-                    if(move.isSolid() || ent.move.isSolid())
-                    {
-                        //controller.onCollideWithEntity(this, ent, getCollidingFace(ent));
-                        pos.setX(oldX);
-                        mx = 0.0f;
-                    }
-                }
-            }
-            if(my != 0.0f)
-            {
-                float oldY = pos.getY();
-
-                if(my < 0.0)
-                {
-                    if(my > -STEP)
-                    {
-                        pos.addY(my);
-                        my = 0.0f;
-                    }
-                    else
-                    {
-                        pos.addY(-STEP);
-                        my += STEP;
-                    }
-                }
-                else if(my > 0.0)
-                {
-                    if(my < STEP)
-                    {
-                        pos.addY(my);
-                        my = 0.0f;
-                    }
-                    else
-                    {
-                        pos.addY(STEP);
-                        my -= STEP;
-                    }
-                }
-
-                List<Entity> list = isCollidingWithEntities(level);
-                for(Entity ent : list)
-                {
-                    if(move.isSolid() || ent.move.isSolid())
-                    {
-                        //controller.onCollideWithEntity(this, ent, getCollidingFace(ent));
-                        pos.setY(oldY);
-                        my = 0.0f;
-                    }
-                }
-            }
+            return false;
         }
-
-        motion.set(pos.getX() - oldPosX, pos.getY() - oldPosY);
-        pos.set(oldPosX, oldPosY);
-    }
-    
-    private boolean isCollidingWithTiles(int startX, int startY, int endX, int endY, Level level)
-    {
         float minX = getX();
         float minY = getY();
         float maxX = minX + width;
@@ -486,22 +425,25 @@ public final class Entity
         return false;
     }
     
-    private List<Entity> isCollidingWithEntities(Level level)
+    private boolean isCollidingWithEntities(Level level)
     {
+        if(move.canMoveOnEntities())
+        {
+            return false;
+        }
         float minX = pos.getX();
         float minY = pos.getY();
         float maxX = pos.getX() + width;
         float maxY = pos.getY() + height;
-        ArrayList<Entity> list = new ArrayList<>();
         for(Entity ent : level.getEntities())
         {
             if(ent == this)
             {
                 continue;
             }
-            if(ent.isColliding(minX, minY, maxX, maxY))
+            if(ent.isColliding(minX, minY, maxX, maxY) && (move.isSolid() || ent.move.isSolid()))
             {
-                list.add(ent);
+                return true;
             }
         }
         for(Entity ent : level.getEntitiesInQueue())
@@ -510,17 +452,17 @@ public final class Entity
             {
                 continue;
             }
-            if(ent.isColliding(minX, minY, maxX, maxY))
+            if(ent.isColliding(minX, minY, maxX, maxY) && (move.isSolid() || ent.move.isSolid()))
             {
-                list.add(ent);
+                return true;
             }
         }
-        return list;
+        return false;
     }
 
-    public void reduceMotionByTiles(Level level)
+    public void reduceMotion(Level level)
     {
-        if(move.canMoveEverywhere() || (motion.getX() == 0.0f && motion.getY() == 0.0f))
+        if(motion.getX() == 0.0f && motion.getY() == 0.0f)
         {
             return;
         }
@@ -590,10 +532,10 @@ public final class Entity
                     }
                 }
 
-                if(isCollidingWithTiles(startX, startY, endX, endY, level))
+                if(isCollidingWithTiles(startX, startY, endX, endY, level) || isCollidingWithEntities(level))
                 {
                     pos.addY(-UP_STEP);
-                    if(isCollidingWithTiles(startX, startY, endX, endY, level))
+                    if(isCollidingWithTiles(startX, startY, endX, endY, level) || isCollidingWithEntities(level))
                     {
                         pos.addY(UP_STEP);
                         pos.setX(oldX);
@@ -632,7 +574,7 @@ public final class Entity
                     }
                 }
 
-                if(isCollidingWithTiles(startX, startY, endX, endY, level))
+                if(isCollidingWithTiles(startX, startY, endX, endY, level) || isCollidingWithEntities(level))
                 {
                     my = 0.0f;
                     pos.setY(oldY);
@@ -644,6 +586,49 @@ public final class Entity
         pos.set(oldPosX, oldPosY);
     }
     
+    private void slideOnEdge(Level level)
+    {
+        float minY = pos.getY() + height;
+        float maxY = pos.getY() + height + STEP * 2;
+        
+        float minX = pos.getX();
+        float midX = pos.getX() + width * 0.5f;
+        float maxX = pos.getX() + width;
+        
+        int startX = Utils.toBlock(minX);
+        int startY = Utils.toBlock(minY);
+        int endX = Utils.toBlock(maxX);
+        int endY = Utils.toBlock(maxY);
+        
+        int leftEdges = 0;
+        int rightEdges = 0;
+
+        for(int x = startX; x <= endX; x++)
+        {
+            for(int y = startY; y <= endY; y++)
+            {
+                Tile t = level.getInteractionTile(x, y);
+                if(t.isMoveColliding(minX, minY, midX, maxY, x, y, level))
+                {
+                    rightEdges++;
+                }
+                if(t.isMoveColliding(midX, minY, maxX, maxY, x, y, level))
+                {
+                    leftEdges++;
+                }
+            }
+        }
+        
+        if(leftEdges == 0)
+        {
+            applyForce(STEP * 25, 0.0f);
+        }
+        if(rightEdges == 0)
+        {
+            applyForce(-STEP * 25, 0.0f);
+        }
+    }
+    
     public void renderTick(float lag)
     {
         controller.renderTick(this, lag);

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

@@ -1,5 +1,6 @@
 package me.hammerle.supersnuvi.entity;
 
+import me.hammerle.supersnuvi.entity.components.BoxMovement;
 import me.hammerle.supersnuvi.entity.components.DefaultHealth;
 import me.hammerle.supersnuvi.entity.components.DefaultMovement;
 import me.hammerle.supersnuvi.entity.components.DefaultEnergy;
@@ -16,6 +17,7 @@ import me.hammerle.supersnuvi.util.SoundUtils.Sound;
 import me.hammerle.supersnuvi.gamelogic.Level;
 import me.hammerle.supersnuvi.tiles.Tile;
 import me.hammerle.supersnuvi.entity.components.IDespawn;
+import me.hammerle.supersnuvi.entity.components.ai.BoxController;
 
 public final class EntityBuilder 
 {
@@ -25,7 +27,7 @@ public final class EntityBuilder
                 new HumanController(), 
                 new DefaultHealth(null, Sound.MIRROR_CRACK, Sound.MIRROR_BREAK), 
                 new DefaultEnergy(),
-                new DefaultMovement(12.0f, 0.0f, 50.0f), 
+                new DefaultMovement(12.0f, 0.0f, 50.0f, false), 
                 ItemCollector.HERO, 
                 (ent) -> level.scheduleReset(), 
                 "Hero");
@@ -39,7 +41,7 @@ public final class EntityBuilder
                 new StartScreenHeroController(), 
                 new DefaultHealth(null, Sound.MIRROR_CRACK, Sound.MIRROR_BREAK), 
                 new DefaultEnergy(),
-                new DefaultMovement(12.0f, 0.0f, 50.0f), 
+                new DefaultMovement(12.0f, 0.0f, 50.0f, false), 
                 ItemCollector.HERO, 
                 (ent) -> level.scheduleReset(), 
                 "Hero");
@@ -53,7 +55,7 @@ public final class EntityBuilder
                 new LondonerController(evil), 
                 new DefaultHealth(null, null, null),
                 new DefaultEnergy(),
-                new DefaultMovement(3.0f, 0.0f, 50.0f),
+                new DefaultMovement(3.0f, 0.0f, 50.0f, true),
                 ItemCollector.NULL,
                 IDespawn.NULL, 
                 evil ? "EvilLondoner" : "Londoner");
@@ -82,15 +84,29 @@ public final class EntityBuilder
                 new PlatformController(),
                 Health.NULL,
                 Energy.NULL,
-                StoneMovement.STONE,
+                StoneMovement.PLATFORM,
                 ItemCollector.NULL,
                 IDespawn.NULL,
                 "Platform");
         platform.setPosition(x, y);
-        platform.setFriction(0.0f, 0.0f);
+        platform.setBaseFriction(0.0f, 0.0f);
         return platform;
     }
     
+    public static Entity buildBox(Level level, float x, float y, int type)
+    {
+        Entity box = new Entity(Tile.SIZE, Tile.SIZE,
+                new BoxController(type),
+                Health.NULL,
+                Energy.NULL,
+                new BoxMovement(),
+                ItemCollector.NULL,
+                IDespawn.NULL,
+                "Box");
+        box.setPosition(x, y);
+        return box;
+    }
+    
     public static Entity fromId(int id, Level level, float x, float y)
     {
         switch(id)
@@ -99,6 +115,12 @@ public final class EntityBuilder
                 return buildLondoner(level, x, y, true);
             case 2:
                 return buildLondoner(level, x, y, false);
+            case 3:
+                return buildBox(level, x, y, 0);
+            case 4:
+                return buildBox(level, x, y, 1);
+            case 5:
+                return buildBox(level, x, y, 2);
         }
         return null;
     }

+ 18 - 0
src/me/hammerle/supersnuvi/entity/components/BoxMovement.java

@@ -0,0 +1,18 @@
+package me.hammerle.supersnuvi.entity.components;
+
+import me.hammerle.supersnuvi.entity.Entity;
+
+public class BoxMovement extends Movement
+{
+    @Override
+    public boolean isSolid()
+    {
+        return true;
+    }
+
+    @Override
+    public boolean hasGravity(Entity ent)
+    {
+        return true;
+    }
+}

+ 10 - 2
src/me/hammerle/supersnuvi/entity/components/DefaultMovement.java

@@ -10,13 +10,15 @@ public class DefaultMovement extends Movement
     private final float vx;
     private final float vy;
     private float friction = 1.0f;
+    private boolean solid;
     
-    public DefaultMovement(float vx, float vy, float jumpPower) 
+    public DefaultMovement(float vx, float vy, float jumpPower, boolean solid) 
     {
         this.jumpPower = jumpPower * Tile.SIZE_SCALE;
         this.vx = vx * Tile.SIZE_SCALE;
         this.vy = vy * Tile.SIZE_SCALE;
-    }
+        this.solid = solid;
+    } 
     
     private float getFactor()
     {
@@ -76,4 +78,10 @@ public class DefaultMovement extends Movement
     {
         return friction;
     }
+
+    @Override
+    public boolean isSolid()
+    {
+        return solid;
+    }
 }

+ 6 - 1
src/me/hammerle/supersnuvi/entity/components/Movement.java

@@ -16,7 +16,12 @@ public class Movement
         return 0.0f;
     }
     
-    public boolean canMoveEverywhere()
+    public boolean canMoveOnTiles()
+    {
+        return false;
+    }
+    
+    public boolean canMoveOnEntities()
     {
         return false;
     }

+ 13 - 3
src/me/hammerle/supersnuvi/entity/components/StoneMovement.java

@@ -4,10 +4,14 @@ import me.hammerle.supersnuvi.entity.Entity;
 
 public class StoneMovement extends Movement
 {
-    public final static StoneMovement STONE = new StoneMovement();
+    public final static StoneMovement STONE = new StoneMovement(true);
+    public final static StoneMovement PLATFORM = new StoneMovement(false);
+    
+    private final boolean entityPassing;
 
-    private StoneMovement()
+    private StoneMovement(boolean entityPassing)
     {
+        this.entityPassing = entityPassing;
     }
     
     @Override
@@ -23,7 +27,7 @@ public class StoneMovement extends Movement
     }
     
     @Override
-    public boolean canMoveEverywhere() 
+    public boolean canMoveOnTiles() 
     {
         return true;
     }  
@@ -33,4 +37,10 @@ public class StoneMovement extends Movement
     {
         return true;
     }
+
+    @Override
+    public boolean canMoveOnEntities()
+    {
+        return entityPassing;
+    }
 }

+ 45 - 0
src/me/hammerle/supersnuvi/entity/components/ai/BoxController.java

@@ -0,0 +1,45 @@
+package me.hammerle.supersnuvi.entity.components.ai;
+
+import me.hammerle.snuviengine.api.Shader;
+import me.hammerle.supersnuvi.entity.Entity;
+import me.hammerle.supersnuvi.rendering.LevelRenderer;
+import me.hammerle.supersnuvi.tiles.Tile;
+import me.hammerle.supersnuvi.util.Face;
+import me.hammerle.supersnuvi.util.Utils;
+
+public class BoxController extends Controller
+{
+    private final float startX;
+    private final float endX;
+    
+    public BoxController(int type)
+    {
+        startX = (256.0f + Tile.SIZE * type) / 512.0f;
+        endX = (288.0f + Tile.SIZE * type) / 512.0f;
+    }
+
+    @Override
+    public void renderTick(Entity ent, float lag)
+    {
+        float x = Utils.interpolate(ent.getLastX(), ent.getX(), lag);
+        float y = Utils.interpolate(ent.getLastY(), ent.getY(), lag);
+        LevelRenderer.TILES.bind();      
+        Shader.getTextureRenderer().drawRectangle(x, y,
+                x + ent.getWidth(), y + ent.getHeight(), 
+                startX, 0.125f, 
+                endX, 0.1875f);
+    }
+
+    @Override
+    public void onCollideWithEntity(Entity ent, Entity other, Face face)
+    {
+        if(face == Face.LEFT && other.getOwnForceX() > 0.0f)
+        {
+            ent.applyForce(other.getOwnForceX(), 0.0f);
+        }
+        else if(face == Face.RIGHT && other.getOwnForceX() < 0.0f)
+        {
+            ent.applyForce(other.getOwnForceX(), 0.0f);
+        }
+    }
+}

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

@@ -35,8 +35,7 @@ public class LondonerController extends Controller
     
     private boolean shouldJump = false;
     
-    private Entity hurt = null;
-    private Entity attacker = null;
+    private int hurtTicks = 0;
     
     public LondonerController(boolean evil) 
     {
@@ -57,6 +56,11 @@ public class LondonerController extends Controller
     @Override
     public void tick(Entity ent, Level level) 
     {
+        if(hurtTicks > 0)
+        {
+            hurtTicks--;
+        }
+        
         if(evil)
         {
             if(transformFrame != -1)
@@ -99,10 +103,12 @@ public class LondonerController extends Controller
             if(hx < ent.getCenterX())
             {
                 ent.applyOwnForce(-ent.getMovement().getVelocityX(), 0.0f);
+                direction = Face.LEFT;
             }
             else
             {
                 ent.applyOwnForce(ent.getMovement().getVelocityX(), 0.0f);
+                direction = Face.RIGHT;
             }
         }
         else
@@ -124,33 +130,6 @@ public class LondonerController extends Controller
             shouldJump = false;
         }
         
-        if(attacker != null)
-        {
-            ent.getHealth().addHealthPercent(-0.201f);
-            attacker.applyForce(0.0f, -attacker.getMovement().getJumpPower() * 0.5f);
-            
-            attacker = null;
-            hurt = null;
-        }
-        
-        if(hurt != null)
-        {
-            hurt.getHealth().addHealthPercent(-0.1f);
-
-            hurt.applyForce(0.0f, -20.0f * Tile.SIZE_SCALE);
-
-            if(ent.getCenterX() < hurt.getCenterX())
-            {
-                hurt.applyForce(10.0f * Tile.SIZE_SCALE, 0.0f);
-            }
-            else
-            {
-                hurt.applyForce(-10.0f * Tile.SIZE_SCALE, 0.0f);
-            }
-            
-            hurt = null;
-        }
-        
         ox = direction == Face.RIGHT ? 0.0f: -1.125f * Tile.SIZE;
         
         if(ent.isOnGround())
@@ -266,9 +245,22 @@ public class LondonerController extends Controller
         {
             case LEFT:
             case RIGHT:
-                if(ent.getItemCollector().isHero() && hasRedEyes())
+                if(hurtTicks > 0)
+                {
+                    return;
+                }
+                if(other.getItemCollector().isHero() && hasRedEyes())
                 {
-                    hurt = ent;
+                    other.getHealth().addHealthPercent(-0.1f);
+                    other.applyForce(0.0f, -20.0f * Tile.SIZE_SCALE);
+                    if(ent.getCenterX() < other.getCenterX())
+                    {
+                        other.applyForce(20.0f * Tile.SIZE_SCALE, 0.0f);
+                    }
+                    else
+                    {
+                        other.applyForce(-20.0f * Tile.SIZE_SCALE, 0.0f);
+                    }
                 }
                 else
                 {
@@ -276,7 +268,9 @@ public class LondonerController extends Controller
                 }
                 break;
             case UP:
-                attacker = ent;
+                ent.getHealth().addHealthPercent(-0.201f);
+                other.applyForce(0.0f, -other.getMotionY() - other.getMovement().getJumpPower() * 0.5f);
+                hurtTicks = 10;
                 break;
         }
     }

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

@@ -34,6 +34,9 @@ public class PlatformController extends Controller
     private final ArrayList<MoveData> dataList = new ArrayList<>();
     private int moveIndex = 0;
     private int waitTicks = 0;
+    
+    private int samePosX = 0;
+    private int samePosY = 0;
   
     @Override
     public boolean isAnimated()

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

@@ -3,7 +3,6 @@ package me.hammerle.supersnuvi.gamelogic;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.LinkedList;
-import java.util.List;
 import java.util.function.Consumer;
 import me.hammerle.snuviscript.code.Script;
 import me.hammerle.supersnuvi.Game;
@@ -11,7 +10,6 @@ import me.hammerle.supersnuvi.entity.Entity;
 import me.hammerle.supersnuvi.entity.EntityBuilder;
 import me.hammerle.supersnuvi.rendering.Light;
 import me.hammerle.supersnuvi.rendering.TileUpdater;
-import me.hammerle.supersnuvi.tiles.Location;
 import me.hammerle.supersnuvi.tiles.Tile;
 import me.hammerle.supersnuvi.util.Utils;
 
@@ -134,9 +132,17 @@ public abstract class Level
             }
             return false;
         });
+        entities.values().forEach(ent -> ent.tickCollision(this));
+        int loops = 20;
         int changes = 1;
         while(changes > 0)
         {
+            loops--;
+            if(loops == 0)
+            {
+                System.out.println(System.nanoTime() + " Loop end reached ...");
+                break;
+            }
             changes = 0;
             for(Entity ent : entities.values())
             {

+ 6 - 0
src/me/hammerle/supersnuvi/math/Vector.java

@@ -68,6 +68,12 @@ public class Vector implements IVector
         x *= v.x;
         y *= v.y;
     }
+    
+    public void mul(float fx, float fy)
+    {
+        x *= fx;
+        y *= fy;
+    }
 
     @Override
     public float getX()

+ 1 - 1
src/me/hammerle/supersnuvi/tiles/CrumblingStoneTile.java

@@ -32,7 +32,7 @@ public class CrumblingStoneTile extends BaseMoveCollisionTile
     @Override
     public void onEntityCollide(Entity ent, int x, int y, Face face, Level l) 
     {
-        if(face == Face.UP && !ent.getMovement().canMoveEverywhere() && states.add(x, y, l))
+        if(face == Face.UP && !ent.getMovement().canMoveOnTiles() && states.add(x, y, l))
         {
             l.getTileUpdater().add(l.getData().getBackgroundIndex(), x, y);      
             l.spawnEntity(EntityBuilder.buildCrumblingStone(l, Utils.toCoord(x), Utils.toCoord(y)));

+ 0 - 39
src/me/hammerle/supersnuvi/tiles/Location.java

@@ -1,39 +0,0 @@
-package me.hammerle.supersnuvi.tiles;
-
-import me.hammerle.supersnuvi.gamelogic.Level;
-
-public class Location 
-{
-    private final Tile tile;
-    private final Level l;
-    private final int x;
-    private final int y;
-    
-    public Location(Tile tile, Level l, int x, int y)
-    {
-        this.tile = tile;
-        this.l = l;
-        this.x = x;
-        this.y = y;        
-    }
-
-    public Tile getTile() 
-    {
-        return tile;
-    }
-    
-    public Level getLevel() 
-    {
-        return l;
-    }
-
-    public int getX() 
-    {
-        return x;
-    }
-
-    public int getY() 
-    {
-        return y;
-    }
-}

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

@@ -14,13 +14,9 @@ public class SlipperyTile extends BaseBoxTile
     @Override
     public void onEntityCollide(Entity ent, int x, int y, Face face, Level l) 
     {
-        /*if(face == Face.UP)
+        if(face == Face.UP)
         {
-            if(ent.getPreMotionY() != Entity.GRAVITY && Math.abs(ent.getMotionX()) <= 0.07)
-            {
-                ent.setMotionX(ent.getFace() == Face.RIGHT ? 5.0f : -5.0f);
-            }
-            ent.getMovement().setFrictionFactor(0.85f);
-        }*/
+            ent.getFriction().set(0.65f, 1.0f);
+        }
     }
 }

+ 5 - 0
src/me/hammerle/supersnuvi/tiles/Tile.java

@@ -95,4 +95,9 @@ public abstract class Tile
     {
         return Face.NULL;
     }
+    
+    public final boolean hasMoveBox(Level l)
+    {
+        return isMoveColliding(0.0f, 0.0f, Tile.SIZE, Tile.SIZE, 0, 0, l);
+    }
 }

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

@@ -6,7 +6,7 @@ import me.hammerle.supersnuvi.rendering.LevelRenderer;
 import me.hammerle.supersnuvi.util.Face;
 import me.hammerle.supersnuvi.gamelogic.Level;
 
-public class WaterTile extends BaseTile
+public class WaterTile extends BaseCollisionTile
 {
     private final static Animation WATER = LevelRenderer.TILES.addAnimation(160, 0, 
             "resources/water/water_frame1.png", "resources/water/water_frame2.png",
@@ -19,10 +19,9 @@ public class WaterTile extends BaseTile
     
     public WaterTile(int level) 
     {
-        super(0.3125f, 0.00390625f * (15 - level), 0.375f, 0.0625f);
+        super(0.3125f, 0.00390625f * (15 - level), 0.375f, 0.0625f, 
+                0.03125f * Tile.SIZE, Tile.SIZE - (Tile.SIZE / 16) * (level + 1), 0.96875f * Tile.SIZE, Tile.SIZE);
         this.level = level;
-        //super.setCollisionBox(CollisionBox.createScaledTileBox(0.03125f, getOffsetY() / Tile.SIZE, 0.96875f, 1.0f));
-        //super.setMovementBox(CollisionObject.NULL_BOX);
     }
 
     @Override
@@ -30,10 +29,6 @@ public class WaterTile extends BaseTile
     {
         super.onEntityCollide(ent, x, y, face, l);
         ent.getMovement().setInWater(true);
-        //if(ent.getMotionY() > 0.0f)
-        //{
-        //    ent.setMotionY(0.0f);
-        //}
     }
 
     @Override

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

@@ -81,7 +81,7 @@ public class SoundUtils
             catch(Exception ex)
             {
                 System.out.println("Sound '" + f + "' failed.");
-                ex.printStackTrace();
+                //ex.printStackTrace();
             }
         }
         
@@ -142,7 +142,7 @@ public class SoundUtils
             catch(Exception ex)
             {
                 System.out.println("Sound '" + f + "' failed.");
-                ex.printStackTrace();
+                //ex.printStackTrace();
             }
         }