diff --git a/src/main/java/cz/jzitnik/game/sprites/Air.java b/src/main/java/cz/jzitnik/game/sprites/Air.java
index 74e0101..0ba015e 100644
--- a/src/main/java/cz/jzitnik/game/sprites/Air.java
+++ b/src/main/java/cz/jzitnik/game/sprites/Air.java
@@ -2,24 +2,23 @@ package cz.jzitnik.game.sprites;
 
 import cz.jzitnik.tui.Sprite;
 
-import java.util.Optional;
-
 public class Air extends Sprite {
-    public String getSprite() {
+    private String resource;
+
+    public Air() {
         StringBuilder sprite = new StringBuilder();
         for (int i = 0; i < 25; i++) {
             sprite.append("\033[48;2;121;166;255m ".repeat(50));
             sprite.append("\n");
         }
-        return sprite.toString();
+        resource = sprite.toString();
+    }
+
+    public String getSprite() {
+        return resource;
     }
 
     public String getSprite(Enum e) {
         throw new RuntimeException("Imposible state");
     }
-
-    @Override
-    public Optional<Class<Enum>> getStates() {
-        return Optional.empty();
-    }
 }
diff --git a/src/main/java/cz/jzitnik/game/sprites/Bed.java b/src/main/java/cz/jzitnik/game/sprites/Bed.java
index 189fa4c..33ce126 100644
--- a/src/main/java/cz/jzitnik/game/sprites/Bed.java
+++ b/src/main/java/cz/jzitnik/game/sprites/Bed.java
@@ -1,29 +1,30 @@
 package cz.jzitnik.game.sprites;
 
-import cz.jzitnik.tui.ResourceLoader;
 import cz.jzitnik.tui.Sprite;
 
-import java.util.Optional;
+import java.util.HashMap;
 
-public class Bed extends Sprite {
+public class Bed extends Sprite<Bed.BedState> {
     public enum BedState {
-        LEFT, RIGHT,
+        LEFT, RIGHT
     }
 
+    public Bed() {
+        loadResources(new HashMap<>() {
+            {
+                put(BedState.LEFT, "bed/left.ans");
+                put(BedState.RIGHT, "bed/right.ans");
+            }
+        }, BedState.class);
+    }
+
+    @Override
     public String getSprite() {
         return getSprite(BedState.LEFT);
     }
 
-    public String getSprite(Enum e) {
-        return ResourceLoader.loadResource(switch (e) {
-            case BedState.LEFT -> "bed/left.ans";
-            case BedState.RIGHT -> "bed/right.ans";
-            default -> throw new IllegalStateException("Unexpected value: " + e);
-        });
-    }
-
     @Override
-    public Optional<Class<BedState>> getStates() {
-        return Optional.of(BedState.class);
+    public String getSprite(BedState key) {
+        return super.getResource(key);
     }
 }
diff --git a/src/main/java/cz/jzitnik/game/sprites/Breaking.java b/src/main/java/cz/jzitnik/game/sprites/Breaking.java
index 63b23e1..ab0d6c2 100644
--- a/src/main/java/cz/jzitnik/game/sprites/Breaking.java
+++ b/src/main/java/cz/jzitnik/game/sprites/Breaking.java
@@ -1,35 +1,35 @@
 package cz.jzitnik.game.sprites;
 
-import cz.jzitnik.tui.ResourceLoader;
 import cz.jzitnik.tui.Sprite;
 
-import java.util.Objects;
-import java.util.Optional;
+import java.util.HashMap;
 
-public class Breaking extends Sprite {
+public class Breaking extends Sprite<Breaking.BreakingState> {
     public enum BreakingState {
         FIRST, SECOND, THIRD
     }
 
+    public Breaking() {
+        loadResources(new HashMap<>() {
+            {
+                put(BreakingState.FIRST, "breaking/1.ans");
+                put(BreakingState.SECOND, "breaking/2.ans");
+                put(BreakingState.THIRD, "breaking/3.ans");
+            }
+        }, BreakingState.class);
+    }
+
     private String fix(String x) {
-        return x.replaceAll("\033\\[38;5;1;48;5;16m", "\033[0m");
-    }
-
-    public String getSprite() {
-        return fix(Objects.requireNonNull(ResourceLoader.loadResource("breaking/1.ans")));
-    }
-
-    public String getSprite(Enum key) {
-        return fix(Objects.requireNonNull(ResourceLoader.loadResource(switch (key) {
-            case BreakingState.FIRST -> "breaking/1.ans";
-            case BreakingState.SECOND -> "breaking/2.ans";
-            case BreakingState.THIRD -> "breaking/3.ans";
-            default -> throw new IllegalStateException("Unexpected value: " + key);
-        })));
+        return x.replaceAll("\\033\\[38;5;1;48;5;16m", "\\033[0m");
     }
 
     @Override
-    public Optional<Class<BreakingState>> getStates() {
-        return Optional.of(BreakingState.class);
+    public String getSprite() {
+        return fix(getSprite(BreakingState.FIRST));
+    }
+
+    @Override
+    public String getSprite(BreakingState key) {
+        return fix(super.getResource(key));
     }
 }
diff --git a/src/main/java/cz/jzitnik/game/sprites/Cow.java b/src/main/java/cz/jzitnik/game/sprites/Cow.java
index 67148d3..27296e9 100644
--- a/src/main/java/cz/jzitnik/game/sprites/Cow.java
+++ b/src/main/java/cz/jzitnik/game/sprites/Cow.java
@@ -1,31 +1,32 @@
 package cz.jzitnik.game.sprites;
 
-import cz.jzitnik.tui.ResourceLoader;
 import cz.jzitnik.tui.Sprite;
 
-import java.util.Optional;
+import java.util.HashMap;
 
-public class Cow extends Sprite {
+public class Cow extends Sprite<Cow.CowState> {
     public enum CowState {
         LEFT, RIGHT, LEFT_HURT, RIGHT_HURT
     }
 
+    public Cow() {
+        loadResources(new HashMap<>() {
+            {
+                put(CowState.LEFT, "mobs/cow/left.ans");
+                put(CowState.RIGHT, "mobs/cow/right.ans");
+                put(CowState.LEFT_HURT, "mobs/cow/lefthurt.ans");
+                put(CowState.RIGHT_HURT, "mobs/cow/righthurt.ans");
+            }
+        }, CowState.class);
+    }
+
+    @Override
     public String getSprite() {
         return getSprite(CowState.RIGHT);
     }
 
-    public String getSprite(Enum e) {
-        return ResourceLoader.loadResource(switch (e) {
-            case CowState.LEFT -> "mobs/cow/left.ans";
-            case CowState.RIGHT -> "mobs/cow/right.ans";
-            case CowState.LEFT_HURT -> "mobs/cow/lefthurt.ans";
-            case CowState.RIGHT_HURT -> "mobs/cow/righthurt.ans";
-            default -> throw new IllegalStateException("Unexpected value: " + e);
-        });
-    }
-
     @Override
-    public Optional<Class<CowState>> getStates() {
-        return Optional.of(CowState.class);
+    public String getSprite(CowState key) {
+        return super.getResource(key);
     }
 }
diff --git a/src/main/java/cz/jzitnik/game/sprites/Dye.java b/src/main/java/cz/jzitnik/game/sprites/Dye.java
index 9de5634..47c221c 100644
--- a/src/main/java/cz/jzitnik/game/sprites/Dye.java
+++ b/src/main/java/cz/jzitnik/game/sprites/Dye.java
@@ -1,44 +1,45 @@
 package cz.jzitnik.game.sprites;
 
-import cz.jzitnik.tui.ResourceLoader;
 import cz.jzitnik.tui.Sprite;
 
-import java.util.Optional;
+import java.util.HashMap;
 
-public class Dye extends Sprite {
+public class Dye extends Sprite<Dye.DyeState> {
     public enum DyeState {
-        WHITE, LIGHT_GRAY, GRAY, BLACK, BROWN, RED, ORANGE, YELLOW, LIME, GREEN, CYAN, LIGHT_BLUE, BLUE, PURPLE, MAGENTA, PINK,
+        WHITE, LIGHT_GRAY, GRAY, BLACK, BROWN, RED, ORANGE, YELLOW, LIME, GREEN, CYAN, LIGHT_BLUE, BLUE, PURPLE,
+        MAGENTA, PINK
     }
 
+    public Dye() {
+        loadResources(new HashMap<>() {
+            {
+                put(DyeState.WHITE, "items/white_dye.ans");
+                put(DyeState.LIGHT_GRAY, "items/light_gray_dye.ans");
+                put(DyeState.GRAY, "items/gray_dye.ans");
+                put(DyeState.BLACK, "items/black_dye.ans");
+                put(DyeState.BROWN, "items/brown_dye.ans");
+                put(DyeState.RED, "items/red_dye.ans");
+                put(DyeState.ORANGE, "items/orange_dye.ans");
+                put(DyeState.YELLOW, "items/yellow_dye.ans");
+                put(DyeState.LIME, "items/lime_dye.ans");
+                put(DyeState.GREEN, "items/green_dye.ans");
+                put(DyeState.CYAN, "items/cyan_dye.ans");
+                put(DyeState.LIGHT_BLUE, "items/light_blue_dye.ans");
+                put(DyeState.BLUE, "items/blue_dye.ans");
+                put(DyeState.PURPLE, "items/purple_dye.ans");
+                put(DyeState.MAGENTA, "items/magenta_dye.ans");
+                put(DyeState.PINK, "items/pink_dye.ans");
+            }
+        }, DyeState.class);
+    }
+
+    @Override
     public String getSprite() {
         return getSprite(DyeState.WHITE);
     }
 
-    public String getSprite(Enum e) {
-        return ResourceLoader.loadResource(switch (e) {
-            case DyeState.WHITE -> "items/white_dye.ans";
-            case DyeState.LIGHT_GRAY -> "items/light_gray_dye.ans";
-            case DyeState.GRAY -> "items/gray_dye.ans";
-            case DyeState.BLACK -> "items/black_dye.ans";
-            case DyeState.BROWN -> "items/brown_dye.ans";
-            case DyeState.RED -> "items/red_dye.ans";
-            case DyeState.ORANGE -> "items/orange_dye.ans";
-            case DyeState.YELLOW -> "items/yellow_dye.ans";
-            case DyeState.LIME -> "items/lime_dye.ans";
-            case DyeState.GREEN -> "items/green_dye.ans";
-            case DyeState.CYAN -> "items/cyan_dye.ans";
-            case DyeState.LIGHT_BLUE -> "items/light_blue_dye.ans";
-            case DyeState.BLUE -> "items/blue_dye.ans";
-            case DyeState.PURPLE -> "items/purple_dye.ans";
-            case DyeState.MAGENTA -> "items/magenta_dye.ans";
-            case DyeState.PINK -> "items/pink_dye.ans";
-
-            default -> throw new IllegalStateException("Unexpected value: " + e);
-        });
-    }
-
     @Override
-    public Optional<Class<DyeState>> getStates() {
-        return Optional.of(DyeState.class);
+    public String getSprite(DyeState key) {
+        return getResource(key);
     }
 }
diff --git a/src/main/java/cz/jzitnik/game/sprites/Farmable.java b/src/main/java/cz/jzitnik/game/sprites/Farmable.java
index 7020ef1..6daa725 100644
--- a/src/main/java/cz/jzitnik/game/sprites/Farmable.java
+++ b/src/main/java/cz/jzitnik/game/sprites/Farmable.java
@@ -1,19 +1,20 @@
 package cz.jzitnik.game.sprites;
 
-import cz.jzitnik.tui.ResourceLoader;
 import cz.jzitnik.tui.Sprite;
 
-import java.util.Optional;
-
-
-public class Farmable extends Sprite {
-    private String[] textures;
+import java.util.HashMap;
 
+public class Farmable extends Sprite<Farmable.FarmableState> {
     public Farmable(String first, String second, String third) {
-        textures = new String[] {first, second, third};
+        loadResources(new HashMap<>() {
+            {
+                put(FarmableState.FIRST, first);
+                put(FarmableState.SECOND, second);
+                put(FarmableState.THIRD, third);
+            }
+        }, FarmableState.class);
     }
 
-
     public enum FarmableState {
         FIRST,
         SECOND,
@@ -24,13 +25,8 @@ public class Farmable extends Sprite {
         return getSprite(getState(0));
     }
 
-    public String getSprite(Enum e) {
-        return ResourceLoader.loadResource(textures[switch (e) {
-            case FarmableState.FIRST -> 0;
-            case FarmableState.SECOND -> 1;
-            case FarmableState.THIRD -> 2;
-            default -> throw new IllegalStateException("Unexpected value: " + e);
-        }]);
+    public String getSprite(FarmableState e) {
+        return getResource(e);
     }
 
     public static FarmableState getState(int num) {
@@ -41,9 +37,4 @@ public class Farmable extends Sprite {
             default -> throw new IllegalStateException("Unexpected value: " + num);
         };
     }
-
-    @Override
-    public Optional<Class<FarmableState>> getStates() {
-        return Optional.of(FarmableState.class);
-    }
 }
diff --git a/src/main/java/cz/jzitnik/game/sprites/Farmland.java b/src/main/java/cz/jzitnik/game/sprites/Farmland.java
index 8504fe4..90b09b7 100644
--- a/src/main/java/cz/jzitnik/game/sprites/Farmland.java
+++ b/src/main/java/cz/jzitnik/game/sprites/Farmland.java
@@ -1,30 +1,29 @@
 package cz.jzitnik.game.sprites;
 
-import cz.jzitnik.tui.ResourceLoader;
 import cz.jzitnik.tui.Sprite;
 
-import java.util.Optional;
+import java.util.HashMap;
 
-public class Farmland extends Sprite {
+public class Farmland extends Sprite<Farmland.FarmlandState> {
     public enum FarmlandState {
         NORMAL,
         WET
     }
 
+    public Farmland() {
+        loadResources(new HashMap<>() {
+            {
+                put(FarmlandState.NORMAL, "farmland.ans");
+                put(FarmlandState.WET, "farmland_wet.ans");
+            }
+        }, FarmlandState.class);
+    }
+
     public String getSprite() {
         return getSprite(FarmlandState.NORMAL);
     }
 
-    public String getSprite(Enum e) {
-        return ResourceLoader.loadResource(switch (e) {
-            case FarmlandState.NORMAL -> "farmland.ans";
-            case FarmlandState.WET -> "farmland_wet.ans";
-            default -> throw new IllegalStateException("Unexpected value: " + e);
-        });
-    }
-
-    @Override
-    public Optional<Class<FarmlandState>> getStates() {
-        return Optional.of(FarmlandState.class);
+    public String getSprite(FarmlandState e) {
+        return getResource(e);
     }
 }
diff --git a/src/main/java/cz/jzitnik/game/sprites/Furnace.java b/src/main/java/cz/jzitnik/game/sprites/Furnace.java
index 79b459b..0bcdf16 100644
--- a/src/main/java/cz/jzitnik/game/sprites/Furnace.java
+++ b/src/main/java/cz/jzitnik/game/sprites/Furnace.java
@@ -1,29 +1,28 @@
 package cz.jzitnik.game.sprites;
 
-import cz.jzitnik.tui.ResourceLoader;
 import cz.jzitnik.tui.Sprite;
 
-import java.util.Optional;
+import java.util.HashMap;
 
-public class Furnace extends Sprite {
+public class Furnace extends Sprite<Furnace.FurnaceState> {
     public enum FurnaceState {
         OFF, ON,
     }
 
+    public Furnace() {
+        loadResources(new HashMap<>() {
+            {
+                put(FurnaceState.OFF, "furnace.ans");
+                put(FurnaceState.ON, "furnace2.ans");
+            }
+        }, FurnaceState.class);
+    }
+
     public String getSprite() {
-        return ResourceLoader.loadResource("furnace.ans");
+        return getSprite(FurnaceState.OFF);
     }
 
-    public String getSprite(Enum e) {
-        return ResourceLoader.loadResource(switch (e) {
-            case FurnaceState.OFF -> "furnace.ans";
-            case FurnaceState.ON -> "furnace2.ans";
-            default -> throw new IllegalStateException("Unexpected value: " + e);
-        });
-    }
-
-    @Override
-    public Optional<Class<FurnaceState>> getStates() {
-        return Optional.of(FurnaceState.class);
+    public String getSprite(FurnaceState e) {
+        return getResource(e);
     }
 }
diff --git a/src/main/java/cz/jzitnik/game/sprites/Heart.java b/src/main/java/cz/jzitnik/game/sprites/Heart.java
index f85319e..16e7c7e 100644
--- a/src/main/java/cz/jzitnik/game/sprites/Heart.java
+++ b/src/main/java/cz/jzitnik/game/sprites/Heart.java
@@ -1,29 +1,28 @@
 package cz.jzitnik.game.sprites;
 
-import cz.jzitnik.tui.ResourceLoader;
 import cz.jzitnik.tui.Sprite;
 
-import java.util.Optional;
+import java.util.HashMap;
 
-public class Heart extends Sprite {
+public class Heart extends Sprite<Heart.HeartState> {
     public enum HeartState {
         OFF, ON,
     }
 
+    public Heart() {
+        loadResources(new HashMap<>() {
+            {
+                put(HeartState.OFF, "gui/heartempty.ans");
+                put(HeartState.ON, "gui/heartfull.ans");
+            }
+        }, HeartState.class);
+    }
+
     public String getSprite() {
         return getSprite(HeartState.OFF);
     }
 
-    public String getSprite(Enum e) {
-        return ResourceLoader.loadResource(switch (e) {
-            case HeartState.OFF -> "gui/heartempty.ans";
-            case HeartState.ON -> "gui/heartfull.ans";
-            default -> throw new IllegalStateException("Unexpected value: " + e);
-        });
-    }
-
-    @Override
-    public Optional<Class<HeartState>> getStates() {
-        return Optional.of(HeartState.class);
+    public String getSprite(HeartState e) {
+        return getResource(e);
     }
 }
diff --git a/src/main/java/cz/jzitnik/game/sprites/Hunger.java b/src/main/java/cz/jzitnik/game/sprites/Hunger.java
index b9f6e7e..1d2a98a 100644
--- a/src/main/java/cz/jzitnik/game/sprites/Hunger.java
+++ b/src/main/java/cz/jzitnik/game/sprites/Hunger.java
@@ -1,29 +1,28 @@
 package cz.jzitnik.game.sprites;
 
-import cz.jzitnik.tui.ResourceLoader;
 import cz.jzitnik.tui.Sprite;
 
-import java.util.Optional;
+import java.util.HashMap;
 
-public class Hunger extends Sprite {
+public class Hunger extends Sprite<Hunger.HungerState> {
     public enum HungerState {
         OFF, ON,
     }
 
+    public Hunger() {
+        loadResources(new HashMap<>() {
+            {
+                put(HungerState.OFF, "gui/hungerempty.ans");
+                put(HungerState.ON, "gui/hungerfull.ans");
+            }
+        }, HungerState.class);
+    }
+
     public String getSprite() {
         return getSprite(HungerState.OFF);
     }
 
-    public String getSprite(Enum e) {
-        return ResourceLoader.loadResource(switch (e) {
-            case HungerState.OFF -> "gui/hungerempty.ans";
-            case HungerState.ON -> "gui/hungerfull.ans";
-            default -> throw new IllegalStateException("Unexpected value: " + e);
-        });
-    }
-
-    @Override
-    public Optional<Class<HungerState>> getStates() {
-        return Optional.of(HungerState.class);
+    public String getSprite(HungerState e) {
+        return getResource(e);
     }
 }
diff --git a/src/main/java/cz/jzitnik/game/sprites/Lava.java b/src/main/java/cz/jzitnik/game/sprites/Lava.java
index d799f14..292643b 100644
--- a/src/main/java/cz/jzitnik/game/sprites/Lava.java
+++ b/src/main/java/cz/jzitnik/game/sprites/Lava.java
@@ -1,17 +1,20 @@
 package cz.jzitnik.game.sprites;
 
-import cz.jzitnik.tui.ResourceLoader;
 import cz.jzitnik.tui.Sprite;
 
 import java.util.Optional;
 
 public class Lava extends Sprite {
+    public Lava() {
+        loadResource("lava.ans");
+    }
+
     public String getSprite() {
         return getSprite(Water.WaterState.FIRST);
     }
 
     public String getSprite(Enum e) {
-        String[] resource = ResourceLoader.loadResource("lava.ans").split("\n");
+        String[] resource = getResource().split("\n");
 
         int numberFormTop = switch (e) {
             case Water.WaterState.FIRST -> 0;
diff --git a/src/main/java/cz/jzitnik/game/sprites/OakDoor.java b/src/main/java/cz/jzitnik/game/sprites/OakDoor.java
index 7e36415..24fa75e 100644
--- a/src/main/java/cz/jzitnik/game/sprites/OakDoor.java
+++ b/src/main/java/cz/jzitnik/game/sprites/OakDoor.java
@@ -3,29 +3,29 @@ package cz.jzitnik.game.sprites;
 import cz.jzitnik.tui.ResourceLoader;
 import cz.jzitnik.tui.Sprite;
 
-import java.util.Optional;
+import java.util.HashMap;
 
-public class OakDoor extends Sprite {
+public class OakDoor extends Sprite<OakDoor.OakDoorState> {
     public enum OakDoorState {
         TOP, BOTTOM, TOPCLOSED, BOTTOMCLOSED
     }
 
+    public OakDoor() {
+        loadResources(new HashMap<>() {
+            {
+                put(OakDoorState.TOP, "oak_door/top.ans");
+                put(OakDoorState.BOTTOM, "oak_door/bottom.ans");
+                put(OakDoorState.TOPCLOSED, "oak_door/topclosed.ans");
+                put(OakDoorState.BOTTOMCLOSED, "oak_door/bottomclosed.ans");
+            }
+        }, OakDoorState.class);
+    }
+
     public String getSprite() {
         return ResourceLoader.loadResource("oak_door/bottomclosed.ans");
     }
 
-    public String getSprite(Enum e) {
-        return ResourceLoader.loadResource(switch (e) {
-            case OakDoorState.TOP -> "oak_door/top.ans";
-            case OakDoorState.BOTTOM -> "oak_door/bottom.ans";
-            case OakDoorState.TOPCLOSED -> "oak_door/topclosed.ans";
-            case OakDoorState.BOTTOMCLOSED -> "oak_door/bottomclosed.ans";
-            default -> throw new IllegalStateException("Unexpected value: " + e);
-        });
-    }
-
-    @Override
-    public Optional<Class<OakDoorState>> getStates() {
-        return Optional.of(OakDoorState.class);
+    public String getSprite(OakDoorState e) {
+        return getResource(e);
     }
 }
diff --git a/src/main/java/cz/jzitnik/game/sprites/Pig.java b/src/main/java/cz/jzitnik/game/sprites/Pig.java
index fbf75cb..4d16656 100644
--- a/src/main/java/cz/jzitnik/game/sprites/Pig.java
+++ b/src/main/java/cz/jzitnik/game/sprites/Pig.java
@@ -1,31 +1,30 @@
 package cz.jzitnik.game.sprites;
 
-import cz.jzitnik.tui.ResourceLoader;
 import cz.jzitnik.tui.Sprite;
 
-import java.util.Optional;
+import java.util.HashMap;
 
-public class Pig extends Sprite {
+public class Pig extends Sprite<Pig.PigState> {
     public enum PigState {
         LEFT, RIGHT, LEFT_HURT, RIGHT_HURT
     }
 
+    public Pig() {
+        loadResources(new HashMap<>() {
+            {
+                put(PigState.LEFT, "mobs/pig/left.ans");
+                put(PigState.RIGHT, "mobs/pig/right.ans");
+                put(PigState.LEFT_HURT, "mobs/pig/lefthurt.ans");
+                put(PigState.RIGHT_HURT, "mobs/pig/righthurt.ans");
+            }
+        }, PigState.class);
+    }
+
     public String getSprite() {
         return getSprite(PigState.RIGHT);
     }
 
-    public String getSprite(Enum e) {
-        return ResourceLoader.loadResource(switch (e) {
-            case PigState.LEFT -> "mobs/pig/left.ans";
-            case PigState.RIGHT -> "mobs/pig/right.ans";
-            case PigState.LEFT_HURT -> "mobs/pig/lefthurt.ans";
-            case PigState.RIGHT_HURT -> "mobs/pig/righthurt.ans";
-            default -> throw new IllegalStateException("Unexpected value: " + e);
-        });
-    }
-
-    @Override
-    public Optional<Class<PigState>> getStates() {
-        return Optional.of(PigState.class);
+    public String getSprite(PigState e) {
+        return getResource(e);
     }
 }
diff --git a/src/main/java/cz/jzitnik/game/sprites/Sheep.java b/src/main/java/cz/jzitnik/game/sprites/Sheep.java
index 4ee44f2..511d2d2 100644
--- a/src/main/java/cz/jzitnik/game/sprites/Sheep.java
+++ b/src/main/java/cz/jzitnik/game/sprites/Sheep.java
@@ -3,9 +3,10 @@ package cz.jzitnik.game.sprites;
 import cz.jzitnik.tui.ResourceLoader;
 import cz.jzitnik.tui.Sprite;
 
+import java.util.HashMap;
 import java.util.Optional;
 
-public class Sheep extends Sprite {
+public class Sheep extends Sprite<Sheep.SheepState> {
     public enum SheepState {
         WHITE_LEFT, WHITE_RIGHT, WHITE_LEFT_HURT, WHITE_RIGHT_HURT,
 
@@ -20,48 +21,47 @@ public class Sheep extends Sprite {
         PINK_LEFT, PINK_RIGHT, PINK_LEFT_HURT, PINK_RIGHT_HURT,
     }
 
+    public Sheep() {
+        loadResources(new HashMap<>() {
+            {
+                put(SheepState.WHITE_LEFT, "mobs/sheep/white/left.ans");
+                put(SheepState.WHITE_RIGHT, "mobs/sheep/white/right.ans");
+                put(SheepState.WHITE_LEFT_HURT, "mobs/sheep/white/lefthurt.ans");
+                put(SheepState.WHITE_RIGHT_HURT, "mobs/sheep/white/righthurt.ans");
+
+                put(SheepState.LIGHT_GRAY_LEFT, "mobs/sheep/light_gray/left.ans");
+                put(SheepState.LIGHT_GRAY_RIGHT, "mobs/sheep/light_gray/right.ans");
+                put(SheepState.LIGHT_GRAY_LEFT_HURT, "mobs/sheep/light_gray/lefthurt.ans");
+                put(SheepState.LIGHT_GRAY_RIGHT_HURT, "mobs/sheep/light_gray/righthurt.ans");
+
+                put(SheepState.GRAY_LEFT, "mobs/sheep/gray/left.ans");
+                put(SheepState.GRAY_RIGHT, "mobs/sheep/gray/right.ans");
+                put(SheepState.GRAY_LEFT_HURT, "mobs/sheep/gray/lefthurt.ans");
+                put(SheepState.GRAY_RIGHT_HURT, "mobs/sheep/gray/righthurt.ans");
+
+                put(SheepState.BLACK_LEFT, "mobs/sheep/black/left.ans");
+                put(SheepState.BLACK_RIGHT, "mobs/sheep/black/right.ans");
+                put(SheepState.BLACK_LEFT_HURT, "mobs/sheep/black/lefthurt.ans");
+                put(SheepState.BLACK_RIGHT_HURT, "mobs/sheep/black/righthurt.ans");
+
+                put(SheepState.BROWN_LEFT, "mobs/sheep/brown/left.ans");
+                put(SheepState.BROWN_RIGHT, "mobs/sheep/brown/right.ans");
+                put(SheepState.BROWN_LEFT_HURT, "mobs/sheep/brown/lefthurt.ans");
+                put(SheepState.BROWN_RIGHT_HURT, "mobs/sheep/brown/righthurt.ans");
+
+                put(SheepState.PINK_LEFT, "mobs/sheep/pink/left.ans");
+                put(SheepState.PINK_RIGHT, "mobs/sheep/pink/right.ans");
+                put(SheepState.PINK_LEFT_HURT, "mobs/sheep/pink/lefthurt.ans");
+                put(SheepState.PINK_RIGHT_HURT, "mobs/sheep/pink/righthurt.ans");
+            }
+        }, SheepState.class);
+    }
+
     public String getSprite() {
-        return getSprite(SheepState.WHITE_RIGHT);
+        return getResource(SheepState.WHITE_RIGHT);
     }
 
-    public String getSprite(Enum e) {
-        return ResourceLoader.loadResource(switch (e) {
-            case SheepState.WHITE_LEFT -> "mobs/sheep/white/left.ans";
-            case SheepState.WHITE_RIGHT -> "mobs/sheep/white/right.ans";
-            case SheepState.WHITE_LEFT_HURT -> "mobs/sheep/white/lefthurt.ans";
-            case SheepState.WHITE_RIGHT_HURT -> "mobs/sheep/white/righthurt.ans";
-
-            case SheepState.LIGHT_GRAY_LEFT -> "mobs/sheep/light_gray/left.ans";
-            case SheepState.LIGHT_GRAY_RIGHT -> "mobs/sheep/light_gray/right.ans";
-            case SheepState.LIGHT_GRAY_LEFT_HURT -> "mobs/sheep/light_gray/lefthurt.ans";
-            case SheepState.LIGHT_GRAY_RIGHT_HURT -> "mobs/sheep/light_gray/righthurt.ans";
-
-            case SheepState.GRAY_LEFT -> "mobs/sheep/gray/left.ans";
-            case SheepState.GRAY_RIGHT -> "mobs/sheep/gray/right.ans";
-            case SheepState.GRAY_LEFT_HURT -> "mobs/sheep/gray/lefthurt.ans";
-            case SheepState.GRAY_RIGHT_HURT -> "mobs/sheep/gray/righthurt.ans";
-
-            case SheepState.BLACK_LEFT -> "mobs/sheep/black/left.ans";
-            case SheepState.BLACK_RIGHT -> "mobs/sheep/black/right.ans";
-            case SheepState.BLACK_LEFT_HURT -> "mobs/sheep/black/lefthurt.ans";
-            case SheepState.BLACK_RIGHT_HURT -> "mobs/sheep/black/righthurt.ans";
-
-            case SheepState.BROWN_LEFT -> "mobs/sheep/brown/left.ans";
-            case SheepState.BROWN_RIGHT -> "mobs/sheep/brown/right.ans";
-            case SheepState.BROWN_LEFT_HURT -> "mobs/sheep/brown/lefthurt.ans";
-            case SheepState.BROWN_RIGHT_HURT -> "mobs/sheep/brown/righthurt.ans";
-
-            case SheepState.PINK_LEFT -> "mobs/sheep/pink/left.ans";
-            case SheepState.PINK_RIGHT -> "mobs/sheep/pink/right.ans";
-            case SheepState.PINK_LEFT_HURT -> "mobs/sheep/pink/lefthurt.ans";
-            case SheepState.PINK_RIGHT_HURT -> "mobs/sheep/pink/righthurt.ans";
-
-            default -> throw new IllegalStateException("Unexpected value: " + e);
-        });
-    }
-
-    @Override
-    public Optional<Class<SheepState>> getStates() {
-        return Optional.of(SheepState.class);
+    public String getSprite(SheepState state) {
+        return getResource(state);
     }
 }
diff --git a/src/main/java/cz/jzitnik/game/sprites/SimpleSprite.java b/src/main/java/cz/jzitnik/game/sprites/SimpleSprite.java
index a241c37..ec8e98e 100644
--- a/src/main/java/cz/jzitnik/game/sprites/SimpleSprite.java
+++ b/src/main/java/cz/jzitnik/game/sprites/SimpleSprite.java
@@ -1,27 +1,17 @@
 package cz.jzitnik.game.sprites;
 
-import cz.jzitnik.tui.ResourceLoader;
 import cz.jzitnik.tui.Sprite;
 
-import java.util.Optional;
-
 public class SimpleSprite extends Sprite {
-    private final String resource;
-
     public SimpleSprite(String resource) {
-        this.resource = resource;
+        loadResource(resource);
     }
 
     public String getSprite() {
-        return ResourceLoader.loadResource(resource).replaceAll("\033\\[38;5;1;48;5;16m", "\033[49m");
+        return getResource().replaceAll("\033\\[38;5;1;48;5;16m", "\033[49m");
     }
 
     public String getSprite(Enum key) {
         throw new RuntimeException("Imposible state");
     }
-
-    @Override
-    public Optional<Class<Enum>> getStates() {
-        return Optional.empty();
-    }
 }
diff --git a/src/main/java/cz/jzitnik/game/sprites/Steve.java b/src/main/java/cz/jzitnik/game/sprites/Steve.java
index 8b936ec..23ac30c 100644
--- a/src/main/java/cz/jzitnik/game/sprites/Steve.java
+++ b/src/main/java/cz/jzitnik/game/sprites/Steve.java
@@ -1,29 +1,28 @@
 package cz.jzitnik.game.sprites;
 
-import cz.jzitnik.tui.ResourceLoader;
 import cz.jzitnik.tui.Sprite;
 
-import java.util.Optional;
+import java.util.HashMap;
 
-public class Steve extends Sprite {
+public class Steve extends Sprite<Steve.SteveState> {
     public enum SteveState {
         FIRST, SECOND,
     }
 
+    public Steve() {
+        loadResources(new HashMap<>() {
+            {
+                put(SteveState.FIRST, "steve1.ans");
+                put(SteveState.SECOND, "steve2.ans");
+            }
+        }, SteveState.class);
+    }
+
     public String getSprite() {
-        return getSprite(SteveState.FIRST);
+        return getResource(SteveState.FIRST);
     }
 
-    public String getSprite(Enum e) {
-        return ResourceLoader.loadResource(switch (e) {
-            case SteveState.FIRST -> "steve1.ans";
-            case SteveState.SECOND -> "steve2.ans";
-            default -> throw new IllegalStateException("Unexpected value: " + e);
-        });
-    }
-
-    @Override
-    public Optional<Class<SteveState>> getStates() {
-        return Optional.of(SteveState.class);
+    public String getSprite(SteveState state) {
+        return getResource(state);
     }
 }
diff --git a/src/main/java/cz/jzitnik/game/sprites/TwoBlockSprite.java b/src/main/java/cz/jzitnik/game/sprites/TwoBlockSprite.java
index bd11e63..b0a4334 100644
--- a/src/main/java/cz/jzitnik/game/sprites/TwoBlockSprite.java
+++ b/src/main/java/cz/jzitnik/game/sprites/TwoBlockSprite.java
@@ -1,37 +1,28 @@
 package cz.jzitnik.game.sprites;
 
-import cz.jzitnik.tui.ResourceLoader;
 import cz.jzitnik.tui.Sprite;
 
-import java.util.Optional;
+import java.util.HashMap;
 
-public class TwoBlockSprite extends Sprite {
+public class TwoBlockSprite extends Sprite<TwoBlockSprite.TwoBlockSpriteState> {
     public enum TwoBlockSpriteState {
         TOP, BOTTOM
     }
 
-    private final String top;
-    private final String bottom;
-
     public TwoBlockSprite(String top, String bottom) {
-        this.top = top;
-        this.bottom = bottom;
+        loadResources(new HashMap<>() {
+            {
+                put(TwoBlockSpriteState.TOP, top);
+                put(TwoBlockSpriteState.BOTTOM, bottom);
+            }
+        }, TwoBlockSpriteState.class);
     }
 
     public String getSprite() {
-        return getSprite(TwoBlockSpriteState.TOP);
+        return getResource(TwoBlockSpriteState.TOP);
     }
 
-    public String getSprite(Enum key) {
-        return ResourceLoader.loadResource(switch (key) {
-            case TwoBlockSpriteState.TOP -> top;
-            case TwoBlockSpriteState.BOTTOM -> bottom;
-            default -> throw new RuntimeException("Invalid state!");
-        });
-    }
-
-    @Override
-    public Optional<Class<Enum>> getStates() {
-        return Optional.empty();
+    public String getSprite(TwoBlockSpriteState state) {
+        return getResource(state);
     }
 }
diff --git a/src/main/java/cz/jzitnik/game/sprites/Water.java b/src/main/java/cz/jzitnik/game/sprites/Water.java
index e6f4785..0f1e6d1 100644
--- a/src/main/java/cz/jzitnik/game/sprites/Water.java
+++ b/src/main/java/cz/jzitnik/game/sprites/Water.java
@@ -1,10 +1,9 @@
 package cz.jzitnik.game.sprites;
 
-import cz.jzitnik.tui.ResourceLoader;
-import cz.jzitnik.tui.Sprite;
-
 import java.util.Optional;
 
+import cz.jzitnik.tui.Sprite;
+
 public class Water extends Sprite {
     public enum WaterState {
         FIRST, SECOND, THIRD, FOURTH, FIFTH;
@@ -21,12 +20,16 @@ public class Water extends Sprite {
         }
     }
 
+    public Water() {
+        loadResource("water.ans");
+    }
+
     public String getSprite() {
         return getSprite(WaterState.FIRST);
     }
 
     public String getSprite(Enum e) {
-        String[] resource = ResourceLoader.loadResource("water.ans").split("\n");
+        String[] resource = getResource().split("\n");
 
         int numberFormTop = switch (e) {
             case WaterState.FIRST -> 0;
@@ -53,6 +56,6 @@ public class Water extends Sprite {
 
     @Override
     public Optional<Class<WaterState>> getStates() {
-        return Optional.of(WaterState.class);
+        return Optional.of(Water.WaterState.class);
     }
 }
diff --git a/src/main/java/cz/jzitnik/game/sprites/Wool.java b/src/main/java/cz/jzitnik/game/sprites/Wool.java
index 087704a..8ac00da 100644
--- a/src/main/java/cz/jzitnik/game/sprites/Wool.java
+++ b/src/main/java/cz/jzitnik/game/sprites/Wool.java
@@ -1,34 +1,32 @@
 package cz.jzitnik.game.sprites;
 
-import cz.jzitnik.tui.ResourceLoader;
 import cz.jzitnik.tui.Sprite;
 
-import java.util.Optional;
+import java.util.HashMap;
 
-public class Wool extends Sprite {
+public class Wool extends Sprite<Wool.WoolState> {
     public enum WoolState {
         WHITE, LIGHT_GRAY, GRAY, BLACK, BROWN, PINK,
     }
 
+    public Wool() {
+        loadResources(new HashMap<>() {
+            {
+                put(WoolState.WHITE, "white_wool.ans");
+                put(WoolState.LIGHT_GRAY, "light_gray_wool.ans");
+                put(WoolState.GRAY, "gray_wool.ans");
+                put(WoolState.BLACK, "black_wool.ans");
+                put(WoolState.BROWN, "brown_wool.ans");
+                put(WoolState.PINK, "pink_wool.ans");
+            }
+        }, WoolState.class);
+    }
+
     public String getSprite() {
-        return getSprite(WoolState.WHITE);
+        return getResource(WoolState.WHITE);
     }
 
-    public String getSprite(Enum e) {
-        return ResourceLoader.loadResource(switch (e) {
-            case WoolState.WHITE -> "white_wool.ans";
-            case WoolState.LIGHT_GRAY -> "light_gray_wool.ans";
-            case WoolState.GRAY -> "gray_wool.ans";
-            case WoolState.BLACK -> "black_wool.ans";
-            case WoolState.BROWN -> "brown_wool.ans";
-            case WoolState.PINK -> "pink_wool.ans";
-
-            default -> throw new IllegalStateException("Unexpected value: " + e);
-        });
-    }
-
-    @Override
-    public Optional<Class<WoolState>> getStates() {
-        return Optional.of(WoolState.class);
+    public String getSprite(WoolState state) {
+        return getResource(state);
     }
 }
diff --git a/src/main/java/cz/jzitnik/game/sprites/WoolItem.java b/src/main/java/cz/jzitnik/game/sprites/WoolItem.java
index 677b626..28e2b22 100644
--- a/src/main/java/cz/jzitnik/game/sprites/WoolItem.java
+++ b/src/main/java/cz/jzitnik/game/sprites/WoolItem.java
@@ -1,34 +1,32 @@
 package cz.jzitnik.game.sprites;
 
-import cz.jzitnik.tui.ResourceLoader;
 import cz.jzitnik.tui.Sprite;
 
-import java.util.Optional;
+import java.util.HashMap;
 
-public class WoolItem extends Sprite {
+public class WoolItem extends Sprite<WoolItem.WoolItemState> {
     public enum WoolItemState {
         WHITE, LIGHT_GRAY, GRAY, BLACK, BROWN, PINK,
     }
 
+    public WoolItem() {
+        loadResources(new HashMap<>() {
+            {
+                put(WoolItemState.WHITE, "items/white_wool.ans");
+                put(WoolItemState.LIGHT_GRAY, "items/light_gray_wool.ans");
+                put(WoolItemState.GRAY, "items/gray_wool.ans");
+                put(WoolItemState.BLACK, "items/black_wool.ans");
+                put(WoolItemState.BROWN, "items/brown_wool.ans");
+                put(WoolItemState.PINK, "items/pink_wool.ans");
+            }
+        }, WoolItemState.class);
+    }
+
     public String getSprite() {
-        return getSprite(WoolItemState.WHITE);
+        return getResource(WoolItemState.WHITE);
     }
 
-    public String getSprite(Enum e) {
-        return ResourceLoader.loadResource(switch (e) {
-            case WoolItemState.WHITE -> "items/white_wool.ans";
-            case WoolItemState.LIGHT_GRAY -> "items/light_gray_wool.ans";
-            case WoolItemState.GRAY -> "items/gray_wool.ans";
-            case WoolItemState.BLACK -> "items/black_wool.ans";
-            case WoolItemState.BROWN -> "items/brown_wool.ans";
-            case WoolItemState.PINK -> "items/pink_wool.ans";
-
-            default -> throw new IllegalStateException("Unexpected value: " + e);
-        });
-    }
-
-    @Override
-    public Optional<Class<WoolItemState>> getStates() {
-        return Optional.of(WoolItemState.class);
+    public String getSprite(WoolItemState state) {
+        return getResource(state);
     }
 }
diff --git a/src/main/java/cz/jzitnik/tui/Sprite.java b/src/main/java/cz/jzitnik/tui/Sprite.java
index 14a7599..3c6ff44 100644
--- a/src/main/java/cz/jzitnik/tui/Sprite.java
+++ b/src/main/java/cz/jzitnik/tui/Sprite.java
@@ -1,11 +1,72 @@
 package cz.jzitnik.tui;
 
+import java.util.HashMap;
 import java.util.Optional;
 
 public abstract class Sprite<E extends Enum<E>> {
+    private HashMap<E, String> resourcesLocation;
+    private HashMap<E, Optional<String>> resources;
+    private String defaultResource;
+    private String defaultResourceLocation;
+    private Class<E> enumClass;
+
+    protected final void loadResources(HashMap<E, String> values, Class<E> enumClass) {
+        resources = new HashMap<>();
+        resourcesLocation = new HashMap<>();
+        for (E key : values.keySet()) {
+            var value = values.get(key);
+            resourcesLocation.put(key, value);
+            resources.put(key, Optional.empty());
+        }
+
+        this.enumClass = enumClass;
+    }
+
+    private String loadResource(E key) {
+        var location = resourcesLocation.get(key);
+        var resource = ResourceLoader.loadResource(location);
+
+        resources.put(key, Optional.of(resource));
+        resourcesLocation.remove(key);
+
+        return resource;
+    }
+
+    protected final void loadResource(String resource) {
+        defaultResourceLocation = resource;
+    }
+
+    private final String loadResource() {
+        var resource = ResourceLoader.loadResource(defaultResourceLocation);
+
+        defaultResource = resource;
+
+        return resource;
+    }
+
+    protected final String getResource(E key) {
+        var resource = resources.get(key);
+
+        if (resource.isEmpty()) {
+            return loadResource(key);
+        } else {
+            return resource.get();
+        }
+    }
+
+    protected final String getResource() {
+        if (defaultResource != null) {
+            return defaultResource;
+        } else {
+            return loadResource();
+        }
+    }
+
     public abstract String getSprite();
 
     public abstract String getSprite(E key);
 
-    public abstract Optional<Class<E>> getStates();
+    public Optional<Class<E>> getStates() {
+        return Optional.ofNullable(enumClass);
+    }
 }