Explorar el Código

tweaking, added sounds, rendering offsets for blocks, new thorns

Kajetan Johannes Hammerle hace 6 años
padre
commit
21360040ac

+ 13 - 13
levels/00.map

@@ -24,20 +24,20 @@
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
--1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
--1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
--1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
--1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+-1, -1, 21, -1, 21, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+-1, -1, 181, -1, 180, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+-1, -1, 180, -1, 180, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+-1, -1, 179, -1, 179, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
--1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 160, -1
--1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 161, -1
--1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
--1, 178, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
--1, 177, -1, -1, -1, 64, 64, -1, -1, 64, 64, 64, 64, 64, 64, 64, -1, -1, -1, -1, -1, -1, 64, 64, -1, -1, 64, 64, 64, 64, 64, 64, 64, -1, -1
--1, 177, -1, -1, -1, -1, -1, -1, 64, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 64, -1, -1, -1, -1, -1, -1, -1, -1, -1
--1, 176, -1, -1, 112, -1, 112, -1, -1, -1, -1, -1, -1, -1, -1, -1, 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 32, -1
--1, 22, 20, 20, 148, 148, 148, 20, 23, -1, -1, 32, -1, -1, -1, -1, -1, -1, 22, 20, 20, 20, 20, 20, 20, 23, -1, -1, 32, -1, -1, -1, -1, -1, -1
--1,  2,  0,  0,  0,  0,  0,  0,  1, 97, 97,  6,  5, 80, 80, -1, -1, -1,  2,  0,  0,  0,  0,  0,  0,  1, 97, 97,  6,  5, 80, 80, -1, -1, -1
+-1, -1, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 161, -1
+-1, -1, -1, -1, 15, -1, -1, -1, -1, -1, -1, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 160, -1
+-1, -1, 15, -1, -1, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+-1, -1, -1, -1, -1, -1, -1, -1, -1, 64, 64, 64, 64, 64, 64, 64, -1, -1, -1, -1, -1, -1, 64, 64, -1, -1, 64, 64, 64, 64, 64, 64, 64, -1, -1
+112, -1, -1, -1, -1, 32, -1, -1, 64, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 64, -1, -1, -1, -1, -1, -1, -1, -1, -1
+-1, -1, 48, -1, 64, -1, 64, 64, -1, -1, -1, -1, -1, -1, -1, -1, 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 32, -1
+20, 20, 20, 148, 148, 148, 148, 20, 23, -1, -1, -1, -1, -1, -1, -1, -1, -1, 22, 20, 20, 20, 20, 20, 20, 23, -1, -1, 32, -1, -1, -1, -1, -1, -1
+-1,  2,  0,  0,  0,  0,  0,  0,  1, 97, 97,  97,  97, 97, 97, -1, -1, -1,  2,  0,  0,  0,  0,  0,  0,  1, 97, 97,  6,  5, 80, 80, -1, -1, -1
  4,  0,  0,  0,  0,  0,  0,  0,  0,  4,  4,  0,  0,  0,  0,  4,  4,  4,  0,  0,  0,  0,  0,  0,  0,  0,  4,  4,  0,  0,  0,  0,  4,  4,  4
 #
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1

BIN
sounds/collect.wav


BIN
sounds/jump.wav


BIN
sounds/jump_on_bounce_shroom.wav


+ 0 - 0
Fabian.wav → sounds/menu_music.wav


BIN
sounds/song1.wav


BIN
sounds/stone_crumbling.wav


BIN
sounds/walk.wav


BIN
sounds/walk_water.wav


+ 18 - 1
src/me/hammerle/supersnuvi/entity/Entity.java

@@ -120,13 +120,15 @@ public class Entity
     // gravity, friction
     //--------------------------------------------------------------------------
     
-    public final void jump()
+    public final boolean jump()
     {
         if(onGround)
         {
             onGround = false;
             motionY += getJumpPower();
+            return true;
         }
+        return false;
     }
     
     public boolean isAffectedByGravity()
@@ -159,6 +161,11 @@ public class Entity
         inWater = b;
     }
     
+    public final boolean isInWater()
+    {
+        return inWater;
+    }
+    
     public final void resetMovementData()
     {
         inWater = false;
@@ -591,4 +598,14 @@ public class Entity
     {
         return image;
     }
+    
+    public double getRenderOffsetX()
+    {
+        return 0;
+    }
+    
+    public double getRenderOffsetY()
+    {
+        return 0;
+    }
 }

+ 28 - 3
src/me/hammerle/supersnuvi/entity/Hero.java

@@ -4,6 +4,7 @@ import javafx.scene.image.Image;
 import javafx.scene.input.KeyCode;
 import me.hammerle.supersnuvi.gamelogic.Level;
 import me.hammerle.supersnuvi.input.IKeyHandler;
+import me.hammerle.supersnuvi.util.SoundUtils;
 import me.hammerle.supersnuvi.util.Utils;
 
 public class Hero extends AnimatedEntity
@@ -51,20 +52,26 @@ public class Hero extends AnimatedEntity
         
         if(keyHandler.isKeyDown(KeyCode.SPACE))
         {
-            jump();
+            if(jump())
+            {
+                SoundUtils.playSound(SoundUtils.JUMP);
+            }
+
             /*posX = 96;
             posY= 128;*/
         }
         
         //motionX = -2;
         //motionY = -2;
+        double speed = keyHandler.isKeyDown(KeyCode.SHIFT) ? 4.5 : 3;
+        
         if(keyHandler.isKeyDown(KeyCode.LEFT))
         {
-            setMotionX(-2 * getMaxSpeedModifier());
+            setMotionX(-speed * getMaxSpeedModifier());
         }
         else if(keyHandler.isKeyDown(KeyCode.RIGHT))
         {
-            setMotionX(2 * getMaxSpeedModifier());
+            setMotionX(speed * getMaxSpeedModifier());
         }
         /*if(keyHandler.isKeyDown(KeyCode.UP))
         {
@@ -78,5 +85,23 @@ public class Hero extends AnimatedEntity
         {
             setMotionY(0);
         }*/
+        
+        if(isOnGround() && getPreviousMotionX() != 0)
+        {
+            if(isInWater())
+            {
+                SoundUtils.playSound(SoundUtils.WALK_WATER, false);
+            }
+            else
+            {
+                SoundUtils.playSound(SoundUtils.WALK, false);
+            }           
+        }
     }
+
+    @Override
+    public double getRenderOffsetY()
+    {
+        return -2;
+    }   
 }

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

@@ -117,6 +117,7 @@ public final class Level
         state.resetTiles();
         souls = 0;
         shouldReset = false;
+        done = false;
         Hero h = spawnHero();
         hero = h;
         entities.clear();
@@ -371,7 +372,8 @@ public final class Level
             int endX = Math.min(renderer.getLastVisibleBlockX() + 1, width);
             int endY = Math.min(renderer.getLastVisibleBlockY() + 1, height);
             
-            Image sky = state.getTile(128, 0, 0);
+            Image sky = state.getTile(128).getImage(0, 0);
+            Tile tile;
             int id;
             for(int x = startX; x < endX; x++)
             {
@@ -379,17 +381,26 @@ public final class Level
                 {
                     // drawing background 0
                     // prevents black spots
-                    renderer.drawBlockImage(sky, x, y);
+                    renderer.drawBlockImage(sky, x, y, 0, 0);
                     // end
                     id = background[x][y];
                     if(id != -1)
                     {
-                        renderer.drawBlockImage(state.getTile(id, x, y), x, y);
+                        tile = state.getTile(id);
+                        renderer.drawBlockImage(tile.getImage(x, y), x, y, tile.getRenderOffsetX(), tile.getRenderOffsetY());
                     }
+                }
+            }
+            
+            for(int x = startX; x < endX; x++)
+            {
+                for(int y = startY; y < endY; y++)
+                {
                     id = background2[x][y];
                     if(id != -1)
                     {
-                        renderer.drawBlockImage(state.getTile(id, x, y), x, y);
+                        tile = state.getTile(id);
+                        renderer.drawBlockImage(tile.getImage(x, y), x, y, tile.getRenderOffsetX(), tile.getRenderOffsetY());
                     }
                 }
             }
@@ -399,11 +410,11 @@ public final class Level
             {
                 if(en.drawImageFlipped())
                 {
-                    renderer.drawFlippedImage(en.getImage(), en.getRenderX(), en.getRenderY());
+                    renderer.drawFlippedImage(en.getImage(), en.getRenderX() + en.getRenderOffsetX(), en.getRenderY() + en.getRenderOffsetY());
                 }
                 else
                 {
-                    renderer.drawImage(en.getImage(), en.getRenderX(), en.getRenderY());
+                    renderer.drawImage(en.getImage(), en.getRenderX() + en.getRenderOffsetX(), en.getRenderY() + en.getRenderOffsetY());
                 }
             });
             // end entity rendering
@@ -415,7 +426,8 @@ public final class Level
                     id = foreground[x][y];
                     if(id != -1)
                     {
-                        renderer.drawBlockImage(state.getTile(id, x, y), x, y);
+                        tile = state.getTile(id);
+                        renderer.drawBlockImage(tile.getImage(x, y), x, y, tile.getRenderOffsetX(), tile.getRenderOffsetY());
                     }
                 }
             }
@@ -426,7 +438,7 @@ public final class Level
             renderer.fillRec(0, 0, w, BottledSoulTile.IMAGE.getHeight(), TRANSPARENT_WHITE);
             
             renderer.drawFixedImage(BottledSoulTile.IMAGE, 0, 0);
-            renderer.prepareStringDrawing(Color.BLACK);
+            renderer.prepareStringDrawing(Color.BLACK);            
             double d = (BottledSoulTile.IMAGE.getHeight() - renderer.getLineHeight()) / 2;
             renderer.drawString(s, BottledSoulTile.IMAGE.getWidth(), d);
             renderer.stopStringDrawing();

+ 20 - 10
src/me/hammerle/supersnuvi/gamelogic/StateRenderer.java

@@ -10,6 +10,7 @@ import me.hammerle.supersnuvi.input.IKeyHandler;
 import me.hammerle.supersnuvi.rendering.IGameRenderer;
 import me.hammerle.supersnuvi.savegame.SimpleConfig;
 import me.hammerle.supersnuvi.tiles.*;
+import me.hammerle.supersnuvi.util.SoundUtils;
 
 public class StateRenderer
 {
@@ -110,25 +111,28 @@ public class StateRenderer
         registeredTiles.put(161, new GoalTile("end/end2"));
         
         // thorns
-        registeredTiles.put(176, new KillTile("thorns/thorns_bottom"));
-        registeredTiles.put(177, new KillTile("thorns/thorns_mid"));
-        registeredTiles.put(178, new KillTile("thorns/thorns_top"));
+        registeredTiles.put(176, new KillTile("thorns/thorns_bottom", 2));
+        registeredTiles.put(177, new KillTile("thorns/thorns_mid", 2));
+        registeredTiles.put(178, new KillTile("thorns/thorns_top", 2));
+        registeredTiles.put(179, new KillTile("thorns/thorns_bottom", -3));
+        registeredTiles.put(180, new KillTile("thorns/thorns_mid", -3));
+        registeredTiles.put(181, new KillTile("thorns/thorns_top", -3));
         
         // decoration shrooms
-        registeredTiles.put(208, new BaseTile("shrooms/shroom"));
-        registeredTiles.put(209, new BaseTile("shrooms/shroom2"));
-        registeredTiles.put(210, new BaseTile("shrooms/shroom3"));
-        registeredTiles.put(211, new BaseTile("shrooms/shroom4"));
+        registeredTiles.put(208, new DecoShroomTile("shrooms/shroom"));
+        registeredTiles.put(209, new DecoShroomTile("shrooms/shroom2"));
+        registeredTiles.put(210, new DecoShroomTile("shrooms/shroom3"));
+        registeredTiles.put(211, new DecoShroomTile("shrooms/shroom4"));
     }
     
-    public Image getTile(int id, int x, int y)
+    public Tile getTile(int id)
     {
         Tile tile = registeredTiles.get(id);
         if(tile == null)
         {
-            return FALLBACK_TILE.getImage(x, y);
+            return FALLBACK_TILE;
         }
-        return tile.getImage(x, y);
+        return tile;
     }
     
     public Tile getInteractionTile(int id)
@@ -188,6 +192,9 @@ public class StateRenderer
     {
         if(currentLevel != null)
         {
+            SoundUtils.playSound(SoundUtils.SONG_1, false);
+            SoundUtils.stopSound(SoundUtils.MENU_MUSIC);
+            
             currentLevel.tick(keys);
             
             // doing that here to prevent concurent modification
@@ -212,6 +219,9 @@ public class StateRenderer
         }
         else
         {
+            SoundUtils.playSound(SoundUtils.MENU_MUSIC, false);
+            SoundUtils.stopSound(SoundUtils.SONG_1);
+            
             if(keys.isKeyJustReleased(KeyCode.ENTER) > 0)
             {
                 currentLevel = levels[levelIndex];

+ 9 - 17
src/me/hammerle/supersnuvi/rendering/GameRenderer.java

@@ -13,6 +13,7 @@ import javafx.scene.media.MediaPlayer;
 import javafx.scene.paint.Color;
 import javafx.scene.paint.Paint;
 import me.hammerle.supersnuvi.input.KeyHandler;
+import me.hammerle.supersnuvi.util.SoundUtils;
 import me.hammerle.text.SnuviTextPainter;
 
 public class GameRenderer extends AnimationTimer implements IGameRenderer
@@ -66,6 +67,8 @@ public class GameRenderer extends AnimationTimer implements IGameRenderer
         registerEvents();
         
         this.state = new StateRenderer(this);
+        
+        SoundUtils.loadSounds();
     }
     
     private void registerEvents()
@@ -96,9 +99,6 @@ public class GameRenderer extends AnimationTimer implements IGameRenderer
         });
     }
     
-    //public boolean once = true;
-    //public MediaPlayer mediaPlayer;
-    
     @Override
     public void handle(long now) 
     {
@@ -113,14 +113,6 @@ public class GameRenderer extends AnimationTimer implements IGameRenderer
             prepareRendering();
             state.tick(keys);
         }
-        
-        /*if(once)
-        {
-            once = false;
-            Media sound = new Media(new File("Fabian.wav").toURI().toString());
-            mediaPlayer = new MediaPlayer(sound);
-        }
-        mediaPlayer.play();*/
     }
     
     private void prepareRendering()
@@ -223,9 +215,9 @@ public class GameRenderer extends AnimationTimer implements IGameRenderer
     }
     
     @Override
-    public void drawBlockImage(Image image, int x, int y)
+    public void drawBlockImage(Image image, int x, int y, double offX, double offY)
     {
-        context.drawImage(image, offsetX + x * TILE_SIZE, offsetY - (y + 1) * TILE_SIZE);
+        context.drawImage(image, offsetX + x * TILE_SIZE + offX, offsetY - (y + 1) * TILE_SIZE + offY);
     }
     
     @Override
@@ -252,25 +244,25 @@ public class GameRenderer extends AnimationTimer implements IGameRenderer
     @Override
     public int getFirstVisibleBlockX()
     {
-        return Math.max(0, (int) (cameraX / TILE_SIZE));
+        return Math.max(0, (int) (cameraX / TILE_SIZE) - 1);
     }
     
     @Override
     public int getFirstVisibleBlockY()
     {
-        return Math.max(0, (int) (cameraY / TILE_SIZE));
+        return Math.max(0, (int) (cameraY / TILE_SIZE) - 1);
     }
     
     @Override
     public int getLastVisibleBlockX()
     {
-        return getFirstVisibleBlockX() + (int) (canvas.getWidth() / TILE_SIZE);
+        return getFirstVisibleBlockX() + (int) (canvas.getWidth() / TILE_SIZE) + 2;
     }
     
     @Override
     public int getLastVisibleBlockY()
     {
-        return getFirstVisibleBlockY() + (int) (canvas.getHeight()/ TILE_SIZE);
+        return getFirstVisibleBlockY() + (int) (canvas.getHeight()/ TILE_SIZE) + 2;
     }
     
     @Override

+ 3 - 1
src/me/hammerle/supersnuvi/rendering/IGameRenderer.java

@@ -105,8 +105,10 @@ public interface IGameRenderer
      * @param image the image
      * @param x the x coord of the position
      * @param y the y coord of the position
+     * @param offsetX x coord offset
+     * @param offsetY y coord offset
      */
-    public void drawBlockImage(Image image, int x, int y);
+    public void drawBlockImage(Image image, int x, int y, double offsetX, double offsetY);
     
     /** Sets the stroke color
      *

+ 2 - 0
src/me/hammerle/supersnuvi/tiles/BottledSoulTile.java

@@ -7,6 +7,7 @@ import me.hammerle.supersnuvi.entity.Hero;
 import me.hammerle.supersnuvi.gamelogic.StateRenderer;
 import me.hammerle.supersnuvi.util.CollisionBox;
 import me.hammerle.supersnuvi.util.Face;
+import me.hammerle.supersnuvi.util.SoundUtils;
 import me.hammerle.supersnuvi.util.Utils;
 
 public class BottledSoulTile extends Tile
@@ -29,6 +30,7 @@ public class BottledSoulTile extends Tile
         {
             if(states.add(getKey(x, y)))
             {
+                SoundUtils.playSound(SoundUtils.COLLECT);
                 ent.getLevel().increaseSouls();
             }
         }

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

@@ -6,6 +6,7 @@ import me.hammerle.supersnuvi.entity.Entity;
 import me.hammerle.supersnuvi.gamelogic.StateRenderer;
 import me.hammerle.supersnuvi.util.CollisionBox;
 import me.hammerle.supersnuvi.util.Face;
+import me.hammerle.supersnuvi.util.SoundUtils;
 import me.hammerle.supersnuvi.util.Utils;
 
 public class CrumblingStoneTile extends Tile
@@ -44,7 +45,12 @@ public class CrumblingStoneTile extends Tile
         super.onEntityCollide(ent, x, y, face);
         if(face == Face.UP)
         {
-            states.putIfAbsent(getKey(x, y), 0);
+            long key = getKey(x, y);
+            if(!states.containsKey(key))
+            {
+                states.put(getKey(x, y), 0);
+                SoundUtils.playSound(SoundUtils.STONE_CRUMBLING, true);
+            }
         }
     }
 

+ 15 - 0
src/me/hammerle/supersnuvi/tiles/DecoShroomTile.java

@@ -0,0 +1,15 @@
+package me.hammerle.supersnuvi.tiles;
+
+public class DecoShroomTile extends BaseTile
+{
+    public DecoShroomTile(String path) 
+    {
+        super(path);
+    }
+
+    @Override
+    public double getRenderOffsetY() 
+    {
+        return 2;
+    }
+}

+ 6 - 0
src/me/hammerle/supersnuvi/tiles/GoalTile.java

@@ -21,4 +21,10 @@ public class GoalTile extends BaseTile
             ent.getLevel().finishLevel();
         }
     }
+
+    @Override
+    public double getRenderOffsetY() 
+    {
+        return 1;
+    } 
 }

+ 13 - 2
src/me/hammerle/supersnuvi/tiles/KillTile.java

@@ -2,13 +2,18 @@ package me.hammerle.supersnuvi.tiles;
 
 import me.hammerle.supersnuvi.entity.Entity;
 import me.hammerle.supersnuvi.entity.Hero;
+import me.hammerle.supersnuvi.util.CollisionBox;
 import me.hammerle.supersnuvi.util.Face;
 
-public class KillTile extends BaseBoxTile
+public class KillTile extends BaseTile
 {
-    public KillTile(String path) 
+    private final double offsetY;
+    
+    public KillTile(String path, double offsetY) 
     {
         super(path);
+        this.offsetY = offsetY;
+        super.setCollisionBox(CollisionBox.createScaledBox(0.1, 0.1, 0.9, 0.9));
     }
 
     @Override
@@ -20,4 +25,10 @@ public class KillTile extends BaseBoxTile
             ent.getLevel().scheduleReset();
         }
     }
+
+    @Override
+    public double getRenderOffsetY() 
+    {
+        return offsetY;
+    }
 }

+ 2 - 2
src/me/hammerle/supersnuvi/tiles/SlipperyTile.java

@@ -15,8 +15,8 @@ public class SlipperyTile extends BaseBoxTile
     {
         if(face == Face.UP)
         {
-            double motionX = ent.getMotionX() * 0.98d;
-            if(Math.abs(motionX) > 0.1)
+            double motionX = ent.getMotionX() * 0.985d;
+            if(Math.abs(motionX) > 0.05)
             {
                 ent.setMotionX(motionX);
             }

+ 7 - 6
src/me/hammerle/supersnuvi/tiles/SpikeTile.java

@@ -17,14 +17,15 @@ public class SpikeTile extends Tile
     {
         counter = 0;
         frame = 0;
-        images = new Image[7];
+        images = new Image[8];
         images[0] = Utils.getTileImage("spike_trap/spike_trap_frame5");
         images[1] = images[0];
         images[2] = images[0];
-        images[3] = Utils.getTileImage("spike_trap/spike_trap_frame1");
-        images[4] = Utils.getTileImage("spike_trap/spike_trap_frame2");
-        images[5] = Utils.getTileImage("spike_trap/spike_trap_frame3");
-        images[6] = Utils.getTileImage("spike_trap/spike_trap_frame4");
+        images[3] = images[0];
+        images[4] = Utils.getTileImage("spike_trap/spike_trap_frame1");
+        images[5] = Utils.getTileImage("spike_trap/spike_trap_frame2");
+        images[6] = Utils.getTileImage("spike_trap/spike_trap_frame3");
+        images[7] = Utils.getTileImage("spike_trap/spike_trap_frame4");
         super.setCollisionBox(CollisionBox.createScaledBox(0.1, 0.1, 0.9, 0.9));
     }
 
@@ -32,7 +33,7 @@ public class SpikeTile extends Tile
     public void onEntityCollide(Entity ent, int x, int y, Face face) 
     {
         super.onEntityCollide(ent, x, y, face);
-        if(frame >= 3 && ent instanceof Hero)
+        if(frame >= 4 && ent instanceof Hero)
         {
             ent.getLevel().scheduleReset();
         }

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

@@ -111,4 +111,14 @@ public abstract class Tile
     public void reset()
     {
     }
+    
+    public double getRenderOffsetX()
+    {
+        return 0;
+    }
+    
+    public double getRenderOffsetY()
+    {
+        return 0;
+    }
 }

+ 11 - 2
src/me/hammerle/supersnuvi/tiles/TrampolinTile.java

@@ -2,6 +2,7 @@ package me.hammerle.supersnuvi.tiles;
 
 import me.hammerle.supersnuvi.entity.Entity;
 import me.hammerle.supersnuvi.util.Face;
+import me.hammerle.supersnuvi.util.SoundUtils;
 
 public class TrampolinTile extends BaseBoxTile
 {
@@ -16,7 +17,9 @@ public class TrampolinTile extends BaseBoxTile
         super.onEntityCollide(ent, x, y, face);
         if(face == Face.UP)
         {
-            double motionY = ent.getPreviousMotionY();
+            ent.setMotionY(ent.getJumpPower() * 1.5);
+            SoundUtils.playSound(SoundUtils.JUMP_ON_BOUNCE_SHROOM);
+            /*double motionY = ent.getPreviousMotionY();
             if(motionY < 0)
             {
                 motionY *= -0.9;
@@ -24,7 +27,13 @@ public class TrampolinTile extends BaseBoxTile
                 {
                     ent.setMotionY(motionY);
                 }
-            }
+            }*/
         }
     }
+
+    @Override
+    public double getRenderOffsetY() 
+    {
+        return 2;
+    }
 }

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

@@ -44,7 +44,7 @@ public class WaterTile extends Tile
         double motionY = ent.getMotionY();
         if(motionY < 0)
         {
-            motionY *= 0.8d;
+            motionY *= 0.92d;
             if(Math.abs(motionY) < 0.1)
             {
                 motionY = 0;

+ 68 - 0
src/me/hammerle/supersnuvi/util/SoundUtils.java

@@ -0,0 +1,68 @@
+package me.hammerle.supersnuvi.util;
+
+import java.io.File;
+import javafx.scene.media.Media;
+import javafx.scene.media.MediaPlayer;
+
+public class SoundUtils 
+{
+    public static void loadSounds()
+    {
+    }
+    
+    public final static MediaPlayer COLLECT = getMedia("collect");
+    public final static MediaPlayer JUMP = getMedia("jump");
+    public final static MediaPlayer JUMP_ON_BOUNCE_SHROOM = getMedia("jump_on_bounce_shroom");
+    public final static MediaPlayer STONE_CRUMBLING = getMedia("stone_crumbling");
+    public final static MediaPlayer WALK = getMedia("walk");
+    public final static MediaPlayer WALK_WATER = getMedia("walk_water");
+    
+    public final static MediaPlayer MENU_MUSIC = getMedia("menu_music", true);
+    public final static MediaPlayer SONG_1 = getMedia("song1", true);
+    
+    public static MediaPlayer getMedia(String path, boolean loop)
+    {
+        Media sound = new Media(new File("sounds/" + path + ".wav").toURI().toString());
+        MediaPlayer mp = new MediaPlayer(sound);
+        if(loop)
+        {
+            mp.setOnEndOfMedia(() -> 
+            {
+                mp.seek(mp.getStartTime());
+            });
+        }
+        else
+        {
+            mp.setOnEndOfMedia(() -> 
+            {
+                mp.seek(mp.getStartTime());
+                mp.stop();
+            });
+        }
+        return mp;
+    }
+    
+    public static MediaPlayer getMedia(String path)
+    {
+        return getMedia(path, false);
+    }
+    
+    public static void playSound(MediaPlayer mp, boolean reset)
+    {
+        if(reset)
+        {
+            mp.seek(mp.getStartTime());
+        }
+        mp.play();
+    }
+    
+    public static void playSound(MediaPlayer mp)
+    {
+        playSound(mp, true);
+    }
+    
+    public static void stopSound(MediaPlayer mp)
+    {
+        mp.stop();
+    }
+}