Parcourir la source

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

Kajetan Johannes Hammerle il y a 4 ans
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 = 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(4), tile.toLevelCoord(10), 6, 9, 1);
     platform.addmove($platform, tile.toLevelCoord(3), tile.toLevelCoord(6), 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)
 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.bottles=10
 level.02-Out_of_Reach.map.time=9.674999999999985
 level.02-Out_of_Reach.map.time=9.674999999999985
 level.02-Parabola.map=true
 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.02-Parabola.map.time=15.950043
 level.04-Like_Ice.map=true
 level.04-Like_Ice.map=true
 level.04-Like_Ice.map.bottles=13
 level.04-Like_Ice.map.bottles=13
 level.04-Like_Ice.map.time=20.69997
 level.04-Like_Ice.map.time=20.69997
 level.04-Out_of_Reach.map=true
 level.04-Out_of_Reach.map=true
 level.04-Out_of_Reach.map.bottles=8
 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
         // wooden pressure plate
         registeredTiles[73] = new PressureTile(0.568359375f, 0.072265625f, 0.619140625f, 0.078125f);
         registeredTiles[73] = new PressureTile(0.568359375f, 0.072265625f, 0.619140625f, 0.078125f);
         // stone pressure plate
         // 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)
     public Tile getTile(int id)

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

@@ -1,7 +1,5 @@
 package me.hammerle.supersnuvi.entity;
 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.ai.Controller;
 import me.hammerle.supersnuvi.entity.components.Energy;
 import me.hammerle.supersnuvi.entity.components.Energy;
 import me.hammerle.supersnuvi.entity.components.Health;
 import me.hammerle.supersnuvi.entity.components.Health;
@@ -17,7 +15,7 @@ import me.hammerle.supersnuvi.entity.components.IDespawn;
 public final class Entity
 public final class Entity
 {
 {
     public static final float GRAVITY = 8.0f * Tile.SIZE_SCALE;
     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
     // this one is a little bit bigger to prevent wrong calculation
     // while going upwards
     // while going upwards
     public static final float UP_STEP = STEP + 0.00390625f;
     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
     // the motion, reduced by the movement collision check
     private final Vector motion = new Vector();
     private final Vector motion = new Vector();
     // the friction reducing motion each tick
     // 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);
     private final Vector friction = new Vector(0.0f, 1.0f);
     // a flag indicating that the entity is on the ground
     // a flag indicating that the entity is on the ground
     private boolean onGround = true;
     private boolean onGround = true;
@@ -49,6 +48,7 @@ public final class Entity
     private final IDespawn onDespawn;
     private final IDespawn onDespawn;
     // the type of the entity, used by snuvi script
     // the type of the entity, used by snuvi script
     private final String type;
     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)
     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);
         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)
     public boolean isAt(float x, float y)
@@ -229,6 +234,11 @@ public final class Entity
         return false;
         return false;
     }
     }
     
     
+    public Face getDirection()
+    {
+        return direction;
+    }
+    
     //--------------------------------------------------------------------------
     //--------------------------------------------------------------------------
     // ticking
     // ticking
     //--------------------------------------------------------------------------
     //--------------------------------------------------------------------------
@@ -240,16 +250,20 @@ public final class Entity
         lastMotion.set(0.0f, 0.0f);
         lastMotion.set(0.0f, 0.0f);
         
         
         // reset own force
         // 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
         // update onGround before controller tick
         onGround = isOnTileGround(level);
         onGround = isOnTileGround(level);
         if(onGround)
         if(onGround)
         {
         {
-            motion.setY(0.0f);
+            if(!move.canMoveOnTiles())
+            {
+                motion.setY(0.0f);
+            }
+        }
+        else
+        {
+            friction.set(0.2f, 1.0f);
         }
         }
         
         
         // tick components
         // tick components
@@ -262,13 +276,31 @@ public final class Entity
         {
         {
             motion.addY(GRAVITY * move.getGravityFactor());
             motion.addY(GRAVITY * move.getGravityFactor());
         }
         }
-
+        
         // apply friction
         // apply friction
         motion.mul(friction);
         motion.mul(friction);
+        if(move.isInWater())
+        {
+            motion.mul(friction);
+            move.setInWater(false);
+        }
+        friction.set(baseFriction);
         
         
         // modify current motion by own force
         // modify current motion by own force
         motion.add(ownForce);
         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
         // (entity <-> tile) collision
         doTileCollision(level);
         doTileCollision(level);
         // (entity <-> entity) collision
         // (entity <-> entity) collision
@@ -276,6 +308,11 @@ public final class Entity
         {
         {
             controller.onCollideWithEntity(this, ent, getCollidingFace(ent));
             controller.onCollideWithEntity(this, ent, getCollidingFace(ent));
         });
         });
+        
+        slideOnEdge(level);
+        
+        // remeber last position for rendering
+        lastPos.set(pos);
     }
     }
     
     
     public int move(Level level)
     public int move(Level level)
@@ -287,8 +324,10 @@ public final class Entity
         Vector maxMotion = new Vector();
         Vector maxMotion = new Vector();
         maxMotion.set(motion);
         maxMotion.set(motion);
         
         
-        reduceMotionByTiles(level);   
-        reduceMotionByEntities(level);    
+        if(!move.canMoveOnEntities() || !move.canMoveOnTiles())
+        {
+            reduceMotion(level);
+        }
         pos.add(motion);
         pos.add(motion);
         
         
         int r = (motion.getX() == 0.0f && motion.getY() == 0.0f) ? 0 : 1;
         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 minX = getX();
         float minY = getY();
         float minY = getY();
         float maxX = minX + width;
         float maxX = minX + width;
@@ -486,22 +425,25 @@ public final class Entity
         return false;
         return false;
     }
     }
     
     
-    private List<Entity> isCollidingWithEntities(Level level)
+    private boolean isCollidingWithEntities(Level level)
     {
     {
+        if(move.canMoveOnEntities())
+        {
+            return false;
+        }
         float minX = pos.getX();
         float minX = pos.getX();
         float minY = pos.getY();
         float minY = pos.getY();
         float maxX = pos.getX() + width;
         float maxX = pos.getX() + width;
         float maxY = pos.getY() + height;
         float maxY = pos.getY() + height;
-        ArrayList<Entity> list = new ArrayList<>();
         for(Entity ent : level.getEntities())
         for(Entity ent : level.getEntities())
         {
         {
             if(ent == this)
             if(ent == this)
             {
             {
                 continue;
                 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())
         for(Entity ent : level.getEntitiesInQueue())
@@ -510,17 +452,17 @@ public final class Entity
             {
             {
                 continue;
                 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;
             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);
                     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.addY(UP_STEP);
                         pos.setX(oldX);
                         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;
                     my = 0.0f;
                     pos.setY(oldY);
                     pos.setY(oldY);
@@ -644,6 +586,49 @@ public final class Entity
         pos.set(oldPosX, oldPosY);
         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)
     public void renderTick(float lag)
     {
     {
         controller.renderTick(this, lag);
         controller.renderTick(this, lag);

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

@@ -1,5 +1,6 @@
 package me.hammerle.supersnuvi.entity;
 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.DefaultHealth;
 import me.hammerle.supersnuvi.entity.components.DefaultMovement;
 import me.hammerle.supersnuvi.entity.components.DefaultMovement;
 import me.hammerle.supersnuvi.entity.components.DefaultEnergy;
 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.gamelogic.Level;
 import me.hammerle.supersnuvi.tiles.Tile;
 import me.hammerle.supersnuvi.tiles.Tile;
 import me.hammerle.supersnuvi.entity.components.IDespawn;
 import me.hammerle.supersnuvi.entity.components.IDespawn;
+import me.hammerle.supersnuvi.entity.components.ai.BoxController;
 
 
 public final class EntityBuilder 
 public final class EntityBuilder 
 {
 {
@@ -25,7 +27,7 @@ public final class EntityBuilder
                 new HumanController(), 
                 new HumanController(), 
                 new DefaultHealth(null, Sound.MIRROR_CRACK, Sound.MIRROR_BREAK), 
                 new DefaultHealth(null, Sound.MIRROR_CRACK, Sound.MIRROR_BREAK), 
                 new DefaultEnergy(),
                 new DefaultEnergy(),
-                new DefaultMovement(12.0f, 0.0f, 50.0f), 
+                new DefaultMovement(12.0f, 0.0f, 50.0f, false), 
                 ItemCollector.HERO, 
                 ItemCollector.HERO, 
                 (ent) -> level.scheduleReset(), 
                 (ent) -> level.scheduleReset(), 
                 "Hero");
                 "Hero");
@@ -39,7 +41,7 @@ public final class EntityBuilder
                 new StartScreenHeroController(), 
                 new StartScreenHeroController(), 
                 new DefaultHealth(null, Sound.MIRROR_CRACK, Sound.MIRROR_BREAK), 
                 new DefaultHealth(null, Sound.MIRROR_CRACK, Sound.MIRROR_BREAK), 
                 new DefaultEnergy(),
                 new DefaultEnergy(),
-                new DefaultMovement(12.0f, 0.0f, 50.0f), 
+                new DefaultMovement(12.0f, 0.0f, 50.0f, false), 
                 ItemCollector.HERO, 
                 ItemCollector.HERO, 
                 (ent) -> level.scheduleReset(), 
                 (ent) -> level.scheduleReset(), 
                 "Hero");
                 "Hero");
@@ -53,7 +55,7 @@ public final class EntityBuilder
                 new LondonerController(evil), 
                 new LondonerController(evil), 
                 new DefaultHealth(null, null, null),
                 new DefaultHealth(null, null, null),
                 new DefaultEnergy(),
                 new DefaultEnergy(),
-                new DefaultMovement(3.0f, 0.0f, 50.0f),
+                new DefaultMovement(3.0f, 0.0f, 50.0f, true),
                 ItemCollector.NULL,
                 ItemCollector.NULL,
                 IDespawn.NULL, 
                 IDespawn.NULL, 
                 evil ? "EvilLondoner" : "Londoner");
                 evil ? "EvilLondoner" : "Londoner");
@@ -82,15 +84,29 @@ public final class EntityBuilder
                 new PlatformController(),
                 new PlatformController(),
                 Health.NULL,
                 Health.NULL,
                 Energy.NULL,
                 Energy.NULL,
-                StoneMovement.STONE,
+                StoneMovement.PLATFORM,
                 ItemCollector.NULL,
                 ItemCollector.NULL,
                 IDespawn.NULL,
                 IDespawn.NULL,
                 "Platform");
                 "Platform");
         platform.setPosition(x, y);
         platform.setPosition(x, y);
-        platform.setFriction(0.0f, 0.0f);
+        platform.setBaseFriction(0.0f, 0.0f);
         return platform;
         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)
     public static Entity fromId(int id, Level level, float x, float y)
     {
     {
         switch(id)
         switch(id)
@@ -99,6 +115,12 @@ public final class EntityBuilder
                 return buildLondoner(level, x, y, true);
                 return buildLondoner(level, x, y, true);
             case 2:
             case 2:
                 return buildLondoner(level, x, y, false);
                 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;
         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 vx;
     private final float vy;
     private final float vy;
     private float friction = 1.0f;
     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.jumpPower = jumpPower * Tile.SIZE_SCALE;
         this.vx = vx * Tile.SIZE_SCALE;
         this.vx = vx * Tile.SIZE_SCALE;
         this.vy = vy * Tile.SIZE_SCALE;
         this.vy = vy * Tile.SIZE_SCALE;
-    }
+        this.solid = solid;
+    } 
     
     
     private float getFactor()
     private float getFactor()
     {
     {
@@ -76,4 +78,10 @@ public class DefaultMovement extends Movement
     {
     {
         return friction;
         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;
         return 0.0f;
     }
     }
     
     
-    public boolean canMoveEverywhere()
+    public boolean canMoveOnTiles()
+    {
+        return false;
+    }
+    
+    public boolean canMoveOnEntities()
     {
     {
         return false;
         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 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
     @Override
@@ -23,7 +27,7 @@ public class StoneMovement extends Movement
     }
     }
     
     
     @Override
     @Override
-    public boolean canMoveEverywhere() 
+    public boolean canMoveOnTiles() 
     {
     {
         return true;
         return true;
     }  
     }  
@@ -33,4 +37,10 @@ public class StoneMovement extends Movement
     {
     {
         return true;
         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 boolean shouldJump = false;
     
     
-    private Entity hurt = null;
-    private Entity attacker = null;
+    private int hurtTicks = 0;
     
     
     public LondonerController(boolean evil) 
     public LondonerController(boolean evil) 
     {
     {
@@ -57,6 +56,11 @@ public class LondonerController extends Controller
     @Override
     @Override
     public void tick(Entity ent, Level level) 
     public void tick(Entity ent, Level level) 
     {
     {
+        if(hurtTicks > 0)
+        {
+            hurtTicks--;
+        }
+        
         if(evil)
         if(evil)
         {
         {
             if(transformFrame != -1)
             if(transformFrame != -1)
@@ -99,10 +103,12 @@ public class LondonerController extends Controller
             if(hx < ent.getCenterX())
             if(hx < ent.getCenterX())
             {
             {
                 ent.applyOwnForce(-ent.getMovement().getVelocityX(), 0.0f);
                 ent.applyOwnForce(-ent.getMovement().getVelocityX(), 0.0f);
+                direction = Face.LEFT;
             }
             }
             else
             else
             {
             {
                 ent.applyOwnForce(ent.getMovement().getVelocityX(), 0.0f);
                 ent.applyOwnForce(ent.getMovement().getVelocityX(), 0.0f);
+                direction = Face.RIGHT;
             }
             }
         }
         }
         else
         else
@@ -124,33 +130,6 @@ public class LondonerController extends Controller
             shouldJump = false;
             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;
         ox = direction == Face.RIGHT ? 0.0f: -1.125f * Tile.SIZE;
         
         
         if(ent.isOnGround())
         if(ent.isOnGround())
@@ -266,9 +245,22 @@ public class LondonerController extends Controller
         {
         {
             case LEFT:
             case LEFT:
             case RIGHT:
             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
                 else
                 {
                 {
@@ -276,7 +268,9 @@ public class LondonerController extends Controller
                 }
                 }
                 break;
                 break;
             case UP:
             case UP:
-                attacker = ent;
+                ent.getHealth().addHealthPercent(-0.201f);
+                other.applyForce(0.0f, -other.getMotionY() - other.getMovement().getJumpPower() * 0.5f);
+                hurtTicks = 10;
                 break;
                 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 final ArrayList<MoveData> dataList = new ArrayList<>();
     private int moveIndex = 0;
     private int moveIndex = 0;
     private int waitTicks = 0;
     private int waitTicks = 0;
+    
+    private int samePosX = 0;
+    private int samePosY = 0;
   
   
     @Override
     @Override
     public boolean isAnimated()
     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.Collection;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.LinkedList;
-import java.util.List;
 import java.util.function.Consumer;
 import java.util.function.Consumer;
 import me.hammerle.snuviscript.code.Script;
 import me.hammerle.snuviscript.code.Script;
 import me.hammerle.supersnuvi.Game;
 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.entity.EntityBuilder;
 import me.hammerle.supersnuvi.rendering.Light;
 import me.hammerle.supersnuvi.rendering.Light;
 import me.hammerle.supersnuvi.rendering.TileUpdater;
 import me.hammerle.supersnuvi.rendering.TileUpdater;
-import me.hammerle.supersnuvi.tiles.Location;
 import me.hammerle.supersnuvi.tiles.Tile;
 import me.hammerle.supersnuvi.tiles.Tile;
 import me.hammerle.supersnuvi.util.Utils;
 import me.hammerle.supersnuvi.util.Utils;
 
 
@@ -134,9 +132,17 @@ public abstract class Level
             }
             }
             return false;
             return false;
         });
         });
+        entities.values().forEach(ent -> ent.tickCollision(this));
+        int loops = 20;
         int changes = 1;
         int changes = 1;
         while(changes > 0)
         while(changes > 0)
         {
         {
+            loops--;
+            if(loops == 0)
+            {
+                System.out.println(System.nanoTime() + " Loop end reached ...");
+                break;
+            }
             changes = 0;
             changes = 0;
             for(Entity ent : entities.values())
             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;
         x *= v.x;
         y *= v.y;
         y *= v.y;
     }
     }
+    
+    public void mul(float fx, float fy)
+    {
+        x *= fx;
+        y *= fy;
+    }
 
 
     @Override
     @Override
     public float getX()
     public float getX()

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

@@ -32,7 +32,7 @@ public class CrumblingStoneTile extends BaseMoveCollisionTile
     @Override
     @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, 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.getTileUpdater().add(l.getData().getBackgroundIndex(), x, y);      
             l.spawnEntity(EntityBuilder.buildCrumblingStone(l, Utils.toCoord(x), Utils.toCoord(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
     @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, 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;
         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.util.Face;
 import me.hammerle.supersnuvi.gamelogic.Level;
 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, 
     private final static Animation WATER = LevelRenderer.TILES.addAnimation(160, 0, 
             "resources/water/water_frame1.png", "resources/water/water_frame2.png",
             "resources/water/water_frame1.png", "resources/water/water_frame2.png",
@@ -19,10 +19,9 @@ public class WaterTile extends BaseTile
     
     
     public WaterTile(int level) 
     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;
         this.level = level;
-        //super.setCollisionBox(CollisionBox.createScaledTileBox(0.03125f, getOffsetY() / Tile.SIZE, 0.96875f, 1.0f));
-        //super.setMovementBox(CollisionObject.NULL_BOX);
     }
     }
 
 
     @Override
     @Override
@@ -30,10 +29,6 @@ public class WaterTile extends BaseTile
     {
     {
         super.onEntityCollide(ent, x, y, face, l);
         super.onEntityCollide(ent, x, y, face, l);
         ent.getMovement().setInWater(true);
         ent.getMovement().setInWater(true);
-        //if(ent.getMotionY() > 0.0f)
-        //{
-        //    ent.setMotionY(0.0f);
-        //}
     }
     }
 
 
     @Override
     @Override

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

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