Browse Source

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 6 years ago
parent
commit
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);
         }
     }