ソースを参照

everythings scales with the tile size constant; added stone / wooden pressure plates (base, texture, snuvi script event); red button texture; added string type for entities; snuvi script commands: tile.scale, entity.getType; Snuvi script events: entity_despawn, entity_spawn, platform.clear

Kajetan Johannes Hammerle 5 年 前
コミット
1189c42c56

+ 30 - 4
levels/00-Tech_Demo.snuvi

@@ -1,6 +1,8 @@
 event.load("level_reset");
 event.load("tile_interact");
 event.load("tile_hit");
+event.load("auto_tile_interact");
+//event.load("entity_spawn");
 
 sgoto(200, @test);
 
@@ -13,12 +15,20 @@ if(event == "level_reset")
 }
 elseif(event == "tile_interact")
 {
-    onInteract(tile_x, tile_y);
+    onInteract(tile_x, tile_y, entity);
 }
 elseif(event == "tile_hit")
 {
     onTileHit(tile_x, tile_y, entity);
 }
+elseif(event == "auto_tile_interact")
+{
+    onAutoInteract(tile_x, tile_y, entity);
+}
+elseif(event == "entity_spawn")
+{
+    print(entity.getType(entity));
+}
 
 goto(@main);
 
@@ -54,12 +64,15 @@ function onLevelReset()
     level.setTile(index, 1, 9, 70);
     level.setTile(index, 4, 8, 71);
     
-    $platform = platform.spawn(tile.toLevelCoord(3), tile.toLevelCoord(3), 5);
-    platform.addmove($platform, tile.toLevelCoord(6), tile.toLevelCoord(9), 1, 2, 50);
+    level.setTile(index, 7, 11, 73);
+    level.setTile(index, 8, 10, 74);
+    
+    $platform = platform.spawn(tile.toLevelCoord(3), tile.toLevelCoord(3), 3);
+    platform.addmove($platform, tile.toLevelCoord(0), tile.toLevelCoord(9), 1, 2, 50);
     platform.addmove($platform, tile.toLevelCoord(3), tile.toLevelCoord(3), 1, 2, 50);
 }
 
-function onInteract(x, y)
+function onInteract(x, y, ent)
 {
     if(x == 0 && y == 12)
     {
@@ -90,3 +103,16 @@ function onTileHit(x, y, ent)
     }
 }
 
+function onAutoInteract(x, y, ent)
+{
+    if(x == 7 && y == 11)
+    {
+        entity.setMotionY(ent, tile.scale(-40));
+    }
+    elseif(x == 8 && y == 10)
+    {
+        //entity.setMotionY(ent, tile.scale(-80));
+        entity.addHealth(entity.getHero(), -1);
+    }
+}
+

BIN
resources/tiles.png


BIN
resources/tiles.xcf


+ 19 - 8
src/me/hammerle/supersnuvi/Game.java

@@ -42,7 +42,7 @@ public class Game extends Engine
     public static final NullTile FALLBACK_TILE = new NullTile();
     
     // tiles
-    private final Tile[] registeredTiles = new Tile[73];
+    private final Tile[] registeredTiles = new Tile[75];
     
     // levels
     private Level currentLevel = null;
@@ -603,12 +603,12 @@ public class Game extends Engine
         registeredTiles[34] = new DecoShroomTile(0.0625f, 0.21875f, 0.125f, 0.25f);
         registeredTiles[35] = new DecoShroomTile(0.0625f, 0.1875f, 0.125f, 0.21875f);
         // ramp
-        registeredTiles[36] = new Ramp(0.375f, 0.0f, 0.4375f, 0.0625f, 0.0f, Tile.SIZE, Tile.SIZE, 0.0f);
-        registeredTiles[37] = new Ramp(0.4375f, 0.0f, 0.5f, 0.0625f, 0.0f, Tile.SIZE, Tile.SIZE, Tile.SIZE * 0.5f);
-        registeredTiles[38] = new Ramp(0.5f, 0.0f, 0.5625f, 0.0625f, 0.0f, Tile.SIZE * 0.5f, Tile.SIZE, 0.0f);
-        registeredTiles[39] = new Ramp(0.375f, 0.0625f, 0.4375f, 0.125f, Tile.SIZE, Tile.SIZE, 0.0f, 0.0f);
-        registeredTiles[40] = new Ramp(0.4375f, 0.0625f, 0.5f, 0.125f, Tile.SIZE, Tile.SIZE, 0.0f, Tile.SIZE * 0.5f);
-        registeredTiles[41] = new Ramp(0.5f, 0.0625f, 0.5625f, 0.125f, Tile.SIZE, Tile.SIZE * 0.5f, 0.0f, 0.0f);
+        registeredTiles[36] = new RampTile(0.375f, 0.0f, 0.4375f, 0.0625f, 0.0f, Tile.SIZE, Tile.SIZE, 0.0f);
+        registeredTiles[37] = new RampTile(0.4375f, 0.0f, 0.5f, 0.0625f, 0.0f, Tile.SIZE, Tile.SIZE, Tile.SIZE * 0.5f);
+        registeredTiles[38] = new RampTile(0.5f, 0.0f, 0.5625f, 0.0625f, 0.0f, Tile.SIZE * 0.5f, Tile.SIZE, 0.0f);
+        registeredTiles[39] = new RampTile(0.375f, 0.0625f, 0.4375f, 0.125f, Tile.SIZE, Tile.SIZE, 0.0f, 0.0f);
+        registeredTiles[40] = new RampTile(0.4375f, 0.0625f, 0.5f, 0.125f, Tile.SIZE, Tile.SIZE, 0.0f, Tile.SIZE * 0.5f);
+        registeredTiles[41] = new RampTile(0.5f, 0.0625f, 0.5625f, 0.125f, Tile.SIZE, Tile.SIZE * 0.5f, 0.0f, 0.0f);
         
         // london stuff
         // street
@@ -632,6 +632,10 @@ public class Game extends Engine
         registeredTiles[71] = new HeadHitOnceTile(0.625f, 0.0f, 0.6875f, 0.0625f, 0.6875f, 0.0f, 0.75f, 0.0625f);
         // button
         registeredTiles[72] = new InteractTile(0.75f, 0.0f, 0.8125f, 0.0625f);
+        // 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);
     }
     
     public Tile getTile(int id)
@@ -747,6 +751,7 @@ public class Game extends Engine
         
         snuviParser.registerFunction("tile.totilecoord", (sc, in) -> (double) Utils.toBlock(in[0].getFloat(sc)));
         snuviParser.registerFunction("tile.tolevelcoord", (sc, in) -> (double) Utils.toCoord(in[0].getInt(sc)));
+        snuviParser.registerFunction("tile.scale", (sc, in) -> in[0].getDouble(sc) * Tile.SIZE_SCALE);
         
         snuviParser.registerFunction("entity.gethero", (sc, in) -> currentLevel.getHero());
         snuviParser.registerFunction("entity.getx", (sc, in) -> (double) ((Entity) in[0].get(sc)).getX());
@@ -801,6 +806,7 @@ public class Game extends Engine
             ent.setPosition(0.0f, Float.MAX_VALUE * 0.5f);
             return Void.TYPE;
         });
+        snuviParser.registerFunction("entity.gettype", (sc, in) -> ((Entity) in[0].get(sc)).getType());
         
         snuviParser.registerFunction("platform.spawn", (sc, in) -> 
         {
@@ -811,7 +817,12 @@ public class Game extends Engine
         snuviParser.registerFunction("platform.addmove", (sc, in) -> 
         {
             PlatformController controller = (PlatformController) ((Entity) in[0].get(sc)).getController();
-            controller.addMoveData(in[1].getFloat(sc), in[2].getFloat(sc), in[3].getFloat(sc), in[4].getFloat(sc), in[5].getInt(sc));
+            controller.addMoveData(in[1].getFloat(sc), in[2].getFloat(sc), in[3].getFloat(sc) * Tile.SIZE_SCALE, in[4].getFloat(sc) * Tile.SIZE_SCALE, in[5].getInt(sc));
+            return Void.TYPE;
+        });
+        snuviParser.registerFunction("platform.clear", (sc, in) -> 
+        {
+            ((PlatformController) ((Entity) in[0].get(sc)).getController()).clearMoveData();
             return Void.TYPE;
         });
     }

+ 11 - 2
src/me/hammerle/supersnuvi/entity/Entity.java

@@ -7,13 +7,14 @@ 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.ILevel;
+import me.hammerle.supersnuvi.tiles.Tile;
 import me.hammerle.supersnuvi.util.CollisionObject;
 import me.hammerle.supersnuvi.util.Face;
 import me.hammerle.supersnuvi.util.Utils;
 
 public final class Entity
 {
-    public static final float GRAVITY = 8.0f;
+    public static final float GRAVITY = 8.0f * Tile.SIZE_SCALE;
     public static final float STEP = 0.0625f;
     // this one is a little bit bigger to prevent wrong calculation
     // while joing upwars
@@ -52,7 +53,9 @@ public final class Entity
     // face
     private Face face = Face.RIGHT;
     
-    protected Entity(ILevel level, float x, float y, CollisionObject box)
+    private final String type;
+    
+    protected Entity(String type, ILevel level, float x, float y, CollisionObject box)
     {
         lastPosX = x;
         lastPosY = y;
@@ -68,6 +71,7 @@ public final class Entity
         motionY = 0.0f;
         
         this.level = level;
+        this.type = type;
     }
     
     public ILevel getLevel()
@@ -75,6 +79,11 @@ public final class Entity
         return level;
     }   
     
+    public String getType()
+    {
+        return type;
+    }
+    
     //--------------------------------------------------------------------------
     // components
     //--------------------------------------------------------------------------

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

@@ -7,7 +7,6 @@ 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.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;
@@ -21,7 +20,7 @@ public final class EntityBuilder
 {
     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));
+        Entity hero = new Entity("Hero", level, x, y, CollisionBox.createScaledTileBox(0.0f, 0.15625f, 0.84375f, 2.0f));
         hero.controller = new HumanController(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);
@@ -32,7 +31,7 @@ public final class EntityBuilder
     
     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));
+        Entity hero = new Entity("Hero", level, x, y, CollisionBox.createScaledTileBox(0.0f, 0.15625f, 0.84375f, 2.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);
@@ -43,7 +42,7 @@ public final class EntityBuilder
     
     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));
+        Entity londoner = new Entity(evil ? "EvilLondoner" : "Londoner", level, x, y, CollisionBox.createScaledTileBox(0.21875f, 0.59375f, 0.65625f, 2.0f));
         londoner.controller = new LondonerController(londoner, evil);
         londoner.health = new DefaultHealth(londoner, IDeath.NULL, 100.0f, null, null, null);
         londoner.energy = new DefaultEnergy(londoner, 100.0f);
@@ -53,7 +52,7 @@ public final class EntityBuilder
     
     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));
+        Entity stone = new Entity("CrumblingStone", level, x, y, CollisionBox.DEFAULT_TILE_BOX);
         stone.controller = new StoneController(stone);
         stone.move = new StoneMovement(stone);
         stone.health = new NoHealth(stone);
@@ -62,7 +61,7 @@ public final class EntityBuilder
     
     public static Entity buildPlatform(ILevel level, float x, float y, int tx)
     {
-        Entity platform = new Entity(level, x, y, new CollisionBox(1.0f, 0.0f, 1.0f + Tile.SIZE * tx, 25.0f));
+        Entity platform = new Entity("Platform", level, x, y, CollisionBox.createScaledTileBox(0.03125f, 0.0f, 0.03125f + tx, 0.78125f));
         platform.controller = new PlatformController(platform);
         platform.move = new StoneMovement(platform);
         return platform;

+ 4 - 3
src/me/hammerle/supersnuvi/entity/components/DefaultMovement.java

@@ -1,6 +1,7 @@
 package me.hammerle.supersnuvi.entity.components;
 
 import me.hammerle.supersnuvi.entity.Entity;
+import me.hammerle.supersnuvi.tiles.Tile;
 
 public class DefaultMovement extends Movement
 {
@@ -13,9 +14,9 @@ public class DefaultMovement extends Movement
     public DefaultMovement(Entity ent, float vx, float vy, float jumpPower) 
     {
         super(ent);
-        this.jumpPower = jumpPower;
-        this.vx = vx;
-        this.vy = vy;
+        this.jumpPower = jumpPower * Tile.SIZE_SCALE;
+        this.vx = vx * Tile.SIZE_SCALE;
+        this.vy = vy * Tile.SIZE_SCALE;
     }
     
     private float getFactor()

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

@@ -4,6 +4,7 @@ import me.hammerle.snuviengine.api.Shader;
 import me.hammerle.snuviengine.api.Texture;
 import me.hammerle.supersnuvi.Keys;
 import me.hammerle.supersnuvi.entity.Entity;
+import me.hammerle.supersnuvi.tiles.Tile;
 import me.hammerle.supersnuvi.util.Face;
 import me.hammerle.supersnuvi.util.SoundUtils;
 import me.hammerle.supersnuvi.util.SoundUtils.Sound;
@@ -70,20 +71,15 @@ public class HumanController extends Controller
         return deathFrame < 17;
     }
     
-    private float smoothMove(float current, float max)
-    {
-        return current + (max - current) * 0.5f;
-    }
-    
     @Override
     public void tick() 
     {
         if(ent.getHealth().isDead())
         {
-            ox = ent.getFace() == Face.RIGHT ? 0.0f: -37.0f;
+            ox = ent.getFace() == Face.RIGHT ? 0.0f: -1.15625f * Tile.SIZE;
             oy = 0.0f;
-            h = 64.0f;
-            w = 64.0f;
+            h = 2.0f;
+            w = 2.0f;
             
             tx = (deathFrame * 64.0f) / SIZE;
             if(deathFrame < 16)
@@ -127,10 +123,10 @@ public class HumanController extends Controller
             }
         }
         
-        ox = ent.getFace() == Face.RIGHT ? 0.0f: -5.0f;
+        ox = ent.getFace() == Face.RIGHT ? 0.0f : -0.15625f * Tile.SIZE;
         oy = 0.0f;
-        h = 64.0f;
-        w = 32.0f;
+        h = 2.0f;
+        w = 1.0f;
         
         if(ent.isOnGround())
         {
@@ -179,19 +175,19 @@ public class HumanController extends Controller
         float m2;
         if(ent.getFace() == Face.LEFT)
         {
-            m1 = w;
+            m1 = w * Tile.SIZE;
             m2 = 0.0f;
         }
         else
         {
             m1 = 0.0f;
-            m2 = w;
+            m2 = w * Tile.SIZE;
         }
         Shader.getTextureRenderer().drawRectangle(
                 x + ox + m1, y + oy, 
-                x + ox + m2, y + oy + h, 
+                x + ox + m2, y + oy + h * Tile.SIZE, 
                 tx, ty, 
-                tx + (w / SIZE), ty + (h / SIZE));
+                tx + (w * 32.0f / SIZE), ty + (h * 32.0f / SIZE));
         
         if(ent.getHealth().wasHurt() || ent.getHealth().wasHealed())
         {

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

@@ -4,7 +4,8 @@ import me.hammerle.snuviengine.api.Shader;
 import me.hammerle.snuviengine.api.Texture;
 import me.hammerle.supersnuvi.entity.Entity;
 import me.hammerle.supersnuvi.tiles.Location;
-import me.hammerle.supersnuvi.tiles.Ramp;
+import me.hammerle.supersnuvi.tiles.RampTile;
+import me.hammerle.supersnuvi.tiles.Tile;
 import me.hammerle.supersnuvi.util.Face;
 import me.hammerle.supersnuvi.util.SoundUtils;
 import me.hammerle.supersnuvi.util.Utils;
@@ -57,7 +58,7 @@ public class LondonerController extends Controller
             {
                 if(transformFrame < 3)
                 {
-                    ox = ent.getFace() == Face.RIGHT ? 0.0f: -36.0f;
+                    ox = ent.getFace() == Face.RIGHT ? 0.0f: -1.125f * Tile.SIZE;
                     tx = transformFrame * 0.125f + 0.125f;
                     ty = 0.375f;
                     transformFrame++;
@@ -72,7 +73,7 @@ public class LondonerController extends Controller
         
         if(ent.getHealth().isDead())
         {
-            ox = ent.getFace() == Face.RIGHT ? -32.0f: -4.0f;
+            ox = ent.getFace() == Face.RIGHT ? -Tile.SIZE: -0.125f * Tile.SIZE;
             
             tx = deathFrame * 0.125f;
             ty = hasRedEyes() ? 0.125f : 0.25f;
@@ -131,21 +132,21 @@ public class LondonerController extends Controller
         {
             hurt.getHealth().addHealthPercent(-0.1f);
 
-            hurt.setMotionY(ent.getMotionY() - 20.0f);
+            hurt.setMotionY(ent.getMotionY() - 20.0f * Tile.SIZE_SCALE);
 
             if(ent.getCenterX() < hurt.getCenterX())
             {
-                hurt.setMotionX(hurt.getMotionX() + 10.0f);
+                hurt.setMotionX(hurt.getMotionX() + 10.0f * Tile.SIZE_SCALE);
             }
             else
             {
-                hurt.setMotionX(hurt.getMotionX() - 10.0f);
+                hurt.setMotionX(hurt.getMotionX() - 10.0f * Tile.SIZE_SCALE);
             }
             
             hurt = null;
         }
         
-        ox = ent.getFace() == Face.RIGHT ? 0.0f: -36.0f;
+        ox = ent.getFace() == Face.RIGHT ? 0.0f: -1.125f * Tile.SIZE;
         
         if(ent.isOnGround())
         {
@@ -195,17 +196,17 @@ public class LondonerController extends Controller
         float m2;
         if(ent.getFace() == Face.LEFT)
         {
-            m1 = 64.0f;
+            m1 = 2.0f * Tile.SIZE;
             m2 = 0.0f;
         }
         else
         {
             m1 = 0.0f;
-            m2 = 64.0f;
+            m2 = 2.0f * Tile.SIZE;
         }
         Shader.getTextureRenderer().drawRectangle(
                 x + ox + m1, y,
-                x + ox + m2, y + 64.0f, 
+                x + ox + m2, y + 2.0f * Tile.SIZE, 
                 tx, ty, 
                 tx + 0.125f, ty + 0.125f);
         
@@ -221,7 +222,7 @@ public class LondonerController extends Controller
     {
         if(hasRedEyes())
         {
-            if(!(loc.getTile() instanceof Ramp) && face == ent.getFace() && ent.getMotionX() == 0.0f)
+            if(!(loc.getTile() instanceof RampTile) && face == ent.getFace() && ent.getMotionX() == 0.0f)
             {
                 shouldJump = true;
             }

+ 6 - 26
src/me/hammerle/supersnuvi/entity/components/ai/StartScreenHeroController.java

@@ -2,7 +2,8 @@ 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.tiles.RampTile;
+import me.hammerle.supersnuvi.tiles.Tile;
 import me.hammerle.supersnuvi.util.Face;
 
 public class StartScreenHeroController extends HumanController
@@ -17,27 +18,6 @@ public class StartScreenHeroController extends HumanController
     @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)
@@ -46,10 +26,10 @@ public class StartScreenHeroController extends HumanController
             ent.getMovement().jump();
         }
         
-        ox = ent.getFace() == Face.RIGHT ? 0.0f: -5.0f;
+        ox = ent.getFace() == Face.RIGHT ? 0.0f : -0.15625f * Tile.SIZE;
         oy = 0.0f;
-        h = 64.0f;
-        w = 32.0f;
+        h = 2.0f;
+        w = 1.0f;
         
         if(ent.isOnGround())
         {
@@ -77,7 +57,7 @@ public class StartScreenHeroController extends HumanController
     @Override
     public void onCollideWithTile(Location loc, Face face)
     {
-        if(face == Face.RIGHT && !(loc.getTile() instanceof Ramp))
+        if(face == Face.RIGHT && !(loc.getTile() instanceof RampTile))
         {
             shouldJump = true;
         }

+ 2 - 1
src/me/hammerle/supersnuvi/entity/components/ai/StoneController.java

@@ -3,6 +3,7 @@ package me.hammerle.supersnuvi.entity.components.ai;
 import me.hammerle.snuviengine.api.Shader;
 import me.hammerle.snuviengine.api.Texture;
 import me.hammerle.supersnuvi.entity.Entity;
+import me.hammerle.supersnuvi.tiles.Tile;
 import me.hammerle.supersnuvi.util.Utils;
 
 public class StoneController extends Controller
@@ -32,7 +33,7 @@ public class StoneController extends Controller
         float row = (frame / 16) * 0.3125f;
         float column = (frame % 16) * 0.0625f;
         Shader.getTextureRenderer().drawRectangle(
-                x, y, x + 32.0f, y + 160.0f, 
+                x, y, x + Tile.SIZE, y + 5.0f * Tile.SIZE, 
                 column, row, column + 0.0625f, row + 0.3125f);
     }
 

+ 20 - 3
src/me/hammerle/supersnuvi/gamelogic/Level.java

@@ -207,7 +207,7 @@ public final class Level implements ILevel
         Entity h = spawnHero(true);
         hero = h;
         entities.clear();
-        entities.put(entityCounter++, h);
+        spawnEntity(hero);
         
         for(int l = 0; l < meshLayers; l++)
         {
@@ -220,6 +220,8 @@ public final class Level implements ILevel
             }
         }
         
+        messages.clear();
+        
         callEvent("level_reset");
         return false;
     }
@@ -313,12 +315,27 @@ public final class Level implements ILevel
             entities.values().removeIf(entity -> 
             {
                 entity.tick();
-                return entity.getHealth().shouldDespawn();
+                if(entity.getHealth().shouldDespawn())
+                {
+                    callEvent("entity_despawn", (sc) -> 
+                    {
+                        sc.setVar("entity", entity);
+                    }, null);
+                    return true;
+                }
+                return false;
             });
             
             if(!spawnQueue.isEmpty())
             {
-                spawnQueue.forEach(ent -> entities.put(entityCounter++, ent));
+                spawnQueue.forEach(ent -> 
+                {
+                    entities.put(entityCounter++, ent);
+                    callEvent("entity_spawn", (sc) -> 
+                    {
+                        sc.setVar("entity", ent);
+                    }, null);
+                });
                 spawnQueue.clear();
             }
             

+ 1 - 4
src/me/hammerle/supersnuvi/tiles/HeadHitTile.java

@@ -21,10 +21,7 @@ public class HeadHitTile extends BaseBoxTile
                 sc.setVar("tile_x", (double) x);
                 sc.setVar("tile_y", (double) y);
                 sc.setVar("entity", ent);
-            }, (sc) -> 
-            {
-                
-            });
+            }, null);
         }
     }
 }

+ 1 - 0
src/me/hammerle/supersnuvi/tiles/InteractTile.java

@@ -30,6 +30,7 @@ public class InteractTile extends BaseTile
             {
                 sc.setVar("tile_x", (double) x);
                 sc.setVar("tile_y", (double) y);
+                sc.setVar("entity", ent);
             }, null);
         }
     }

+ 62 - 0
src/me/hammerle/supersnuvi/tiles/PressureTile.java

@@ -0,0 +1,62 @@
+package me.hammerle.supersnuvi.tiles;
+
+import me.hammerle.supersnuvi.entity.Entity;
+import me.hammerle.supersnuvi.gamelogic.ILevel;
+import me.hammerle.supersnuvi.util.CollisionBox;
+import me.hammerle.supersnuvi.util.CollisionObject;
+import me.hammerle.supersnuvi.util.Face;
+
+public class PressureTile extends BaseTile
+{
+    public PressureTile(float tMinX, float tMinY, float tMaxX, float tMaxY)
+    {
+        super(tMinX, tMinY, tMaxX, tMaxY);
+        super.setCollisionBox(CollisionBox.createScaledTileBox(0.09375f, 0.90625f, 0.90625f, 1.0f));
+        super.setMovementBox(CollisionObject.NULL_BOX);
+
+    }
+    
+    @Override
+    public float getWidth()
+    {
+        return Tile.SIZE * 0.8125f;
+    }
+
+    @Override
+    public float getOffsetX()
+    {
+        return Tile.SIZE * 0.09375f;
+    }
+
+    @Override
+    public float getHeight()
+    {
+        return Tile.SIZE * 0.09375f;
+    }
+
+    @Override
+    public float getOffsetY()
+    {
+        return Tile.SIZE * 0.90625f;
+    }
+
+    @Override
+    public boolean shouldAiUseCollisionBox(int x, int y, ILevel l)
+    {
+        return false;
+    }
+
+    @Override
+    public void onEntityCollide(Entity ent, int x, int y, Face face, ILevel l)
+    {
+        if(face == Face.UP)
+        {
+            l.callEvent("auto_tile_interact", (sc) -> 
+            {
+                sc.setVar("tile_x", (double) x);
+                sc.setVar("tile_y", (double) y);
+                sc.setVar("entity", ent);
+            }, null);
+        }
+    }
+}

+ 2 - 2
src/me/hammerle/supersnuvi/tiles/Ramp.java → src/me/hammerle/supersnuvi/tiles/RampTile.java

@@ -3,9 +3,9 @@ package me.hammerle.supersnuvi.tiles;
 import me.hammerle.supersnuvi.gamelogic.ILevel;
 import me.hammerle.supersnuvi.util.CollisionLine;
 
-public class Ramp extends BaseTile
+public class RampTile extends BaseTile
 {
-    public Ramp(float tMinX, float fMinY, float tMaxX, float tMaxY, float x1, float y1, float x2, float y2)
+    public RampTile(float tMinX, float fMinY, float tMaxX, float tMaxY, float x1, float y1, float x2, float y2)
     {
         super(tMinX, fMinY, tMaxX, tMaxY);
         

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

@@ -8,6 +8,7 @@ import me.hammerle.supersnuvi.util.Face;
 public abstract class Tile 
 {
     public final static int SIZE = 32;
+    public final static float SIZE_SCALE = SIZE / 32.0f;
     
     private CollisionObject movementCollision;
     private CollisionObject collisionBox;