浏览代码

entity spawn layer spawns entities (spawn by id), entities are despawned when they are out of the map or killed, fixed rendering bug with death animation

Kajetan Johannes Hammerle 7 年之前
父节点
当前提交
44c07accc4

+ 6 - 6
src/me/hammerle/supersnuvi/entity/Entity.java

@@ -157,6 +157,11 @@ public final class Entity
         return posY;
     }
     
+    public boolean isOutOfMap()
+    {
+        return posY < -height;
+    }
+    
     //--------------------------------------------------------------------------
     // ticking
     //--------------------------------------------------------------------------
@@ -167,7 +172,7 @@ public final class Entity
         health.tick();
         movePenalty.reset();
         
-        if(isAffectedByGravity())
+        if(move.isAffectedByGravity())
         {
             motionY -= GRAVITY;
         }
@@ -212,11 +217,6 @@ public final class Entity
     //--------------------------------------------------------------------------
     // gravity, friction
     //--------------------------------------------------------------------------
-
-    public boolean isAffectedByGravity()
-    {
-        return true;
-    }
     
     public boolean isOnGround()
     {

+ 30 - 7
src/me/hammerle/supersnuvi/entity/EntityBuilder.java

@@ -12,19 +12,13 @@ import me.hammerle.supersnuvi.entity.components.MovementPenalty;
 import me.hammerle.supersnuvi.entity.components.ai.EntityController;
 import me.hammerle.supersnuvi.entity.components.ai.FollowHeroController;
 import me.hammerle.supersnuvi.entity.components.ai.HumanController;
+import me.hammerle.supersnuvi.entity.components.ai.WalkController;
 import me.hammerle.supersnuvi.entity.components.animator.HeroAnimator;
 import me.hammerle.supersnuvi.entity.components.animator.EntityAnimator;
 import me.hammerle.supersnuvi.gamelogic.Level;
 
 public final class EntityBuilder 
 {
-    private final Entity ent;
-    
-    private EntityBuilder(Entity ent)
-    {
-        this.ent = ent;
-    }
-    
     public static EntityBuilder newBuilder(Level level, double x, double y, double width, double height)
     {
         return new EntityBuilder(new Entity(level, x, y, width, height));
@@ -64,6 +58,35 @@ public final class EntityBuilder
         return hero;
     }
     
+    public static Entity fromId(int id, Level level, double x, double y)
+    {
+        switch(id)
+        {
+            case 1:
+                return buildTest(level, x, y);
+            case 2:
+            {
+                Entity ent = new Entity(level, x, y, 32.0, 64.0);
+                ent.animator = new HeroAnimator(ent);
+                ent.controller = new WalkController(ent, 1);
+                ent.health = new DefaultHealth(ent, Death.NULL, 100.0);
+                ent.move = new DefaultMovement(ent, enti -> 12);
+                ent.movePenalty = new LandMovement(ent);
+                return ent;
+            }
+        }
+        return null;
+    }
+    
+    
+    
+    private final Entity ent;
+    
+    private EntityBuilder(Entity ent)
+    {
+        this.ent = ent;
+    }
+    
     public EntityBuilder setController(EntityController controller)
     {
         ent.controller = controller;

+ 14 - 0
src/me/hammerle/supersnuvi/entity/components/DefaultHealth.java

@@ -10,6 +10,7 @@ public class DefaultHealth extends Health
     private int hurtTicks;
     
     private int deathTicks;
+    private boolean isDead;
     
     public DefaultHealth(Entity ent, Death death, double maxHealth) 
     {
@@ -17,6 +18,7 @@ public class DefaultHealth extends Health
         this.maxHealth = maxHealth;
         this.health = maxHealth;
         this.deathTicks = -1;
+        this.isDead = false;
     }
 
     @Override
@@ -37,8 +39,14 @@ public class DefaultHealth extends Health
             if(deathTicks > ent.getAnimator().getDeathTicks())
             {
                 death.onDeath(ent);
+                isDead = true;
             }
         }
+        else if(ent.isOutOfMap())
+        {
+            death.onDeath(ent);
+            isDead = true;
+        }
     }
 
     @Override
@@ -47,6 +55,12 @@ public class DefaultHealth extends Health
         return deathTicks != -1;
     }
     
+    @Override
+    public boolean shouldDespawn() 
+    {
+        return isDead;
+    }
+    
     @Override
     public boolean wasHurt() 
     {

+ 6 - 0
src/me/hammerle/supersnuvi/entity/components/DefaultMovement.java

@@ -29,4 +29,10 @@ public class DefaultMovement extends Movement
     {
         return jump.getJumpPower(ent) * ent.getMovementPenalty().getFactor();
     }
+
+    @Override
+    public boolean isAffectedByGravity()
+    {
+        return true;
+    }
 }

+ 5 - 0
src/me/hammerle/supersnuvi/entity/components/Health.java

@@ -23,6 +23,11 @@ public class Health extends Component
         return false;
     }
     
+    public boolean shouldDespawn() 
+    {
+        return false;
+    }
+    
     public boolean wasHurt()
     {
         return false;

+ 9 - 0
src/me/hammerle/supersnuvi/entity/components/Movement.java

@@ -24,4 +24,13 @@ public class Movement extends Component
     {
         return 0.0;
     }
+    
+    //--------------------------------------------------------------------------
+    // gravity
+    //--------------------------------------------------------------------------
+    
+    public boolean isAffectedByGravity()
+    {
+        return false;
+    }
 }

+ 4 - 0
src/me/hammerle/supersnuvi/entity/components/ai/FollowHeroController.java

@@ -19,6 +19,10 @@ public class FollowHeroController extends EntityController
     @Override
     public void tick() 
     {
+        if(ent.getHealth().isDead())
+        {
+            return;
+        }
         Entity hero = ent.getLevel().getHero();
         if(hero.squaredDistance(ent) <= 102400)
         {

+ 4 - 0
src/me/hammerle/supersnuvi/entity/components/ai/WalkController.java

@@ -17,6 +17,10 @@ public class WalkController extends EntityController
     @Override
     public void tick() 
     {
+        if(ent.getHealth().isDead())
+        {
+            return;
+        }
         ent.setMotionX(motion);
     }
 

+ 1 - 0
src/me/hammerle/supersnuvi/entity/components/animator/HeroAnimator.java

@@ -220,6 +220,7 @@ public class HeroAnimator extends EntityAnimator
         
         if(ent.getHealth().isDead())
         {
+            x -= (drawImageFlipped() ? ent.getWidth() : 0);
             if(frameBody >= DEATH.length)
             {
                 frameBody = 0;

+ 28 - 21
src/me/hammerle/supersnuvi/gamelogic/Level.java

@@ -8,6 +8,7 @@ import java.util.TreeSet;
 import java.util.stream.Collectors;
 import me.hammerle.supersnuvi.entity.Entity;
 import me.hammerle.supersnuvi.entity.EntityBuilder;
+import me.hammerle.supersnuvi.rendering.Game;
 import me.hammerle.supersnuvi.tiles.BottledSoulTile;
 import me.hammerle.supersnuvi.tiles.Location;
 import me.hammerle.supersnuvi.tiles.StartTile;
@@ -81,21 +82,12 @@ public final class Level
             spawns.add(new Point(5, 5));
         }
         
-        /*if(name.equals("00-Tech Demo"))
+        if(name.equals("00-Tech Demo"))
         {
-            data.addLayer();
-            int index = data.getLayers() - 1;
-            data.clearLayer(index);
-            int width = data.getWidth();
-            int height = data.getHeight();
-            for(int x = 10; x < width; x++)
-            {
-                for(int y = 0; y < height; y++)
-                {
-                    data.setTile(index, x, y, 224 + Math.min(15, x - 10));
-                }
-            }
-        }*/
+            int index = data.getBackgroundIndex() + 1;
+            data.setTile(index, 5, 5, 2);
+            data.setTile(index, 30, 5, 1);
+        }
         
         resetLevel();
         
@@ -136,6 +128,7 @@ public final class Level
     public void resetLevel()
     {
         state.resetTiles();
+        data.activateEntities();
         souls = 0;
         shouldReset = false;
         done = false;
@@ -184,20 +177,34 @@ public final class Level
     {
         if(worldLoaded)
         {
-            if(hero.getY() < 0)
-            {
-                resetLevel();
-                return;
-            }
-            
             time += 0.0125;
             
             state.tickTiles();
             
+            // entity spawn layer
+            int startX = renderer.getFirstVisibleBlockX();
+            int startY = renderer.getFirstVisibleBlockY();
+            int endX = Math.min(renderer.getLastVisibleBlockX() + 1, data.getWidth());
+            int endY = Math.min(renderer.getLastVisibleBlockY() + 1, data.getHeight());
+            data.forEachEntity((x, y, tile) -> 
+            {
+                if(tile > 0)
+                {
+                    data.deactivateEntity(x, y);
+                    
+                    Entity ent = EntityBuilder.fromId(tile, this, renderer.toCoord(x), renderer.toCoord(y));
+                    if(ent != null)
+                    {
+                        entities.put(entityCounter++, ent);
+                    }
+                }
+            }, startX, endX, startY, endY);
+            
             // doing entity logic first
-            entities.values().forEach(entity -> 
+            entities.values().removeIf(entity -> 
             {
                 entity.tick();
+                return entity.getHealth().shouldDespawn();
             });
         }
     }   

+ 24 - 1
src/me/hammerle/supersnuvi/gamelogic/LevelData.java

@@ -401,6 +401,27 @@ public class LevelData
         tiles[layer][x][y] = value;
     }
     
+    // -------------------------------------------------------------------------
+    // entity layer
+    // -------------------------------------------------------------------------
+    
+    public void deactivateEntity(int x, int y)
+    {
+        tiles[bIndex + 1][x][y] = -Math.abs(tiles[bIndex + 1][x][y]);
+    }
+    
+    public void activateEntities()
+    {
+        int[][] ent = tiles[bIndex + 1];
+        forEachEntity((x, y, tile) -> 
+        {
+            if(tile < 0)
+            {
+                ent[x][y] = Math.abs(ent[x][y]);
+            }
+        }, 0, width, 0, height);
+    }
+    
     // -------------------------------------------------------------------------
     // tile iterators
     // -------------------------------------------------------------------------
@@ -450,11 +471,13 @@ public class LevelData
             ex = Math.min(width, ex);
             ey = Math.min(height, ey);
             
+            int[][] ent = tiles[l];
+            
             for(int x = sx; x < ex; x++)
             {
                 for(int y = sy; y < ey; y++)
                 {
-                    c.consume(x, y, tiles[l][x][y]);
+                    c.consume(x, y, ent[x][y]);
                 }
             }
         }

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

@@ -34,7 +34,7 @@ public class SpikeTile extends Tile
         super.onEntityCollide(ent, x, y, face);
         if(frame >= 4)
         {
-            ent.getHealth().addHealth(-0.05);
+            ent.getHealth().addHealth(-0.4);
         }
     }