diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..f63bc049776ab3ec747d02ffe7c5fade3059026d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+/target
+/.idea
+*.iml
+
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..19edbafc627e4d560897199b353fac6ad0463909
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>au.edu.unimelb.cis</groupId>
+    <artifactId>bagel</artifactId>
+    <version>0.1-SNAPSHOT</version>
+    <packaging>jar</packaging>
+
+    <build>
+        <sourceDirectory>src/</sourceDirectory>
+        <plugins>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>11</source>
+                    <target>11</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <properties>
+        <maven.compiler.source>11</maven.compiler.source>
+        <maven.compiler.target>11</maven.compiler.target>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>io.github.eleanor-em</groupId>
+            <artifactId>bagel</artifactId>
+            <version>1.9.3</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/res/ActorExtensionPack/Actor/Chest/chest_0.png b/res/ActorExtensionPack/Actor/Chest/chest_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..b8d5cb316963b29b40d77318a35170a4dc5cefeb
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Chest/chest_0.png differ
diff --git a/res/ActorExtensionPack/Actor/Chest/chest_1.png b/res/ActorExtensionPack/Actor/Chest/chest_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..80fc40a39bd0758d6dc3b4d8fff460ddfb6394ec
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Chest/chest_1.png differ
diff --git a/res/ActorExtensionPack/Actor/FireSkull/fireBall_0.png b/res/ActorExtensionPack/Actor/FireSkull/fireBall_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..0bdf1684da40cf566fc43f21c6dff2fe6bdb126d
Binary files /dev/null and b/res/ActorExtensionPack/Actor/FireSkull/fireBall_0.png differ
diff --git a/res/ActorExtensionPack/Actor/FireSkull/fireBall_1.png b/res/ActorExtensionPack/Actor/FireSkull/fireBall_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..6e04338e591b90be7537c64cb43a4f750209483a
Binary files /dev/null and b/res/ActorExtensionPack/Actor/FireSkull/fireBall_1.png differ
diff --git a/res/ActorExtensionPack/Actor/FireSkull/fireBall_2.png b/res/ActorExtensionPack/Actor/FireSkull/fireBall_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..02597aba9e4cab56df03354fcec31bcd2524d695
Binary files /dev/null and b/res/ActorExtensionPack/Actor/FireSkull/fireBall_2.png differ
diff --git a/res/ActorExtensionPack/Actor/FireSkull/skull_attack_idle_0.png b/res/ActorExtensionPack/Actor/FireSkull/skull_attack_idle_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..ec2b8efa388bb5c1604c16820f20b475d19e4d49
Binary files /dev/null and b/res/ActorExtensionPack/Actor/FireSkull/skull_attack_idle_0.png differ
diff --git a/res/ActorExtensionPack/Actor/FireSkull/skull_attack_idle_1.png b/res/ActorExtensionPack/Actor/FireSkull/skull_attack_idle_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..172f0e55174b41ad48360f0f11db629f443ab9e4
Binary files /dev/null and b/res/ActorExtensionPack/Actor/FireSkull/skull_attack_idle_1.png differ
diff --git a/res/ActorExtensionPack/Actor/FireSkull/skull_attack_idle_2.png b/res/ActorExtensionPack/Actor/FireSkull/skull_attack_idle_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..0f984c3803f30fdf7ecc54c7ef115831b296274a
Binary files /dev/null and b/res/ActorExtensionPack/Actor/FireSkull/skull_attack_idle_2.png differ
diff --git a/res/ActorExtensionPack/Actor/FireSkull/skull_attack_idle_3.png b/res/ActorExtensionPack/Actor/FireSkull/skull_attack_idle_3.png
new file mode 100644
index 0000000000000000000000000000000000000000..43c2cb40c7e60b31bf02906d6d7b9e555433bc1d
Binary files /dev/null and b/res/ActorExtensionPack/Actor/FireSkull/skull_attack_idle_3.png differ
diff --git a/res/ActorExtensionPack/Actor/FireSkull/skull_normal_idle_0.png b/res/ActorExtensionPack/Actor/FireSkull/skull_normal_idle_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..5297d738d28b54c3346762131a1ae79e99291744
Binary files /dev/null and b/res/ActorExtensionPack/Actor/FireSkull/skull_normal_idle_0.png differ
diff --git a/res/ActorExtensionPack/Actor/FireSkull/skull_normal_idle_1.png b/res/ActorExtensionPack/Actor/FireSkull/skull_normal_idle_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..ab13caf20f0528010e36d8df1903f886bf934a22
Binary files /dev/null and b/res/ActorExtensionPack/Actor/FireSkull/skull_normal_idle_1.png differ
diff --git a/res/ActorExtensionPack/Actor/FireSkull/skull_normal_idle_2.png b/res/ActorExtensionPack/Actor/FireSkull/skull_normal_idle_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..71127c262ed3c6d1e013500f841d9aec49b5c7e8
Binary files /dev/null and b/res/ActorExtensionPack/Actor/FireSkull/skull_normal_idle_2.png differ
diff --git a/res/ActorExtensionPack/Actor/FireSkull/skull_normal_idle_3.png b/res/ActorExtensionPack/Actor/FireSkull/skull_normal_idle_3.png
new file mode 100644
index 0000000000000000000000000000000000000000..28c8c1b0a6fddebbf96474831c5a1e2882881bc5
Binary files /dev/null and b/res/ActorExtensionPack/Actor/FireSkull/skull_normal_idle_3.png differ
diff --git a/res/ActorExtensionPack/Actor/Knight/knight_left_idle_0.png b/res/ActorExtensionPack/Actor/Knight/knight_left_idle_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..6d2e46b6ead2f4f2a4b32ce1536cd963d625a00e
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Knight/knight_left_idle_0.png differ
diff --git a/res/ActorExtensionPack/Actor/Knight/knight_left_idle_1.png b/res/ActorExtensionPack/Actor/Knight/knight_left_idle_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..3e3c4a2a448ab0ce2436a224002747bc1e8a48b1
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Knight/knight_left_idle_1.png differ
diff --git a/res/ActorExtensionPack/Actor/Knight/knight_left_walk_0.png b/res/ActorExtensionPack/Actor/Knight/knight_left_walk_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..cf237444842c4828ef75161fd0842e96e8e87d63
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Knight/knight_left_walk_0.png differ
diff --git a/res/ActorExtensionPack/Actor/Knight/knight_left_walk_1.png b/res/ActorExtensionPack/Actor/Knight/knight_left_walk_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..5e0c406463677bc942ea3f543fffe5fb9d660937
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Knight/knight_left_walk_1.png differ
diff --git a/res/ActorExtensionPack/Actor/Knight/knight_right_idle_0.png b/res/ActorExtensionPack/Actor/Knight/knight_right_idle_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..bfc7111a234e602886992eaee8ae536dac4d5966
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Knight/knight_right_idle_0.png differ
diff --git a/res/ActorExtensionPack/Actor/Knight/knight_right_idle_1.png b/res/ActorExtensionPack/Actor/Knight/knight_right_idle_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..1144b6b4ecf40ab20a430b1d336877e7515921ff
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Knight/knight_right_idle_1.png differ
diff --git a/res/ActorExtensionPack/Actor/Knight/knight_right_walk_0.png b/res/ActorExtensionPack/Actor/Knight/knight_right_walk_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..368d0f75fb929433f5f4345736b422f8b599a1e1
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Knight/knight_right_walk_0.png differ
diff --git a/res/ActorExtensionPack/Actor/Knight/knight_right_walk_1.png b/res/ActorExtensionPack/Actor/Knight/knight_right_walk_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..7564943ac07593877e4f948c2b184a134728e679
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Knight/knight_right_walk_1.png differ
diff --git a/res/ActorExtensionPack/Actor/Magnet/magnet_triggered_0.png b/res/ActorExtensionPack/Actor/Magnet/magnet_triggered_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..02ed0c3396732902a2018ad4ea74c99d7d98fd56
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Magnet/magnet_triggered_0.png differ
diff --git a/res/ActorExtensionPack/Actor/Magnet/magnet_triggered_1.png b/res/ActorExtensionPack/Actor/Magnet/magnet_triggered_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..836c08fdae4f086dc1e097f768693fc13ef96581
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Magnet/magnet_triggered_1.png differ
diff --git a/res/ActorExtensionPack/Actor/Magnet/magnet_triggered_2.png b/res/ActorExtensionPack/Actor/Magnet/magnet_triggered_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..daac24431f8aabfe35a002c0365bc12e7f6135b1
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Magnet/magnet_triggered_2.png differ
diff --git a/res/ActorExtensionPack/Actor/Magnet/magnet_untriggered_0.png b/res/ActorExtensionPack/Actor/Magnet/magnet_untriggered_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..a0ed1bb59a753f12d498ef66c0ed5149bcfaaabe
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Magnet/magnet_untriggered_0.png differ
diff --git a/res/ActorExtensionPack/Actor/Magnet/magnet_untriggered_1.png b/res/ActorExtensionPack/Actor/Magnet/magnet_untriggered_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..bfb529dc27e065343f6f107d4f292c69d1feec32
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Magnet/magnet_untriggered_1.png differ
diff --git a/res/ActorExtensionPack/Actor/Magnet/magnet_untriggered_2.png b/res/ActorExtensionPack/Actor/Magnet/magnet_untriggered_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..0b827e9401b82acbe64da720e17959eb5476b902
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Magnet/magnet_untriggered_2.png differ
diff --git a/res/ActorExtensionPack/Actor/Portal/portal_0.png b/res/ActorExtensionPack/Actor/Portal/portal_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..2cd0e1010ddcbd10d0d0b9c8ded9623e36df375b
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Portal/portal_0.png differ
diff --git a/res/ActorExtensionPack/Actor/Portal/portal_1.png b/res/ActorExtensionPack/Actor/Portal/portal_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..2a7b613cba0329d6f55dc34a803aab2fb13c70a1
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Portal/portal_1.png differ
diff --git a/res/ActorExtensionPack/Actor/Portal/portal_2.png b/res/ActorExtensionPack/Actor/Portal/portal_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..9af279d3ecbffcafdc9596f11fe243702199184a
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Portal/portal_2.png differ
diff --git a/res/ActorExtensionPack/Actor/Skeleton/skeleton_down_idle_0.png b/res/ActorExtensionPack/Actor/Skeleton/skeleton_down_idle_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..028d99a6e262d0b23cb2a14288ef9b53ecba6173
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Skeleton/skeleton_down_idle_0.png differ
diff --git a/res/ActorExtensionPack/Actor/Skeleton/skeleton_down_idle_1.png b/res/ActorExtensionPack/Actor/Skeleton/skeleton_down_idle_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..afcfa91c37096bd0ba4a9fc654eb652a1e9529e2
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Skeleton/skeleton_down_idle_1.png differ
diff --git a/res/ActorExtensionPack/Actor/Skeleton/skeleton_down_idle_2.png b/res/ActorExtensionPack/Actor/Skeleton/skeleton_down_idle_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..a8e4c051d0ec9b79ed25c5b61e29290e483ccecb
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Skeleton/skeleton_down_idle_2.png differ
diff --git a/res/ActorExtensionPack/Actor/Skeleton/skeleton_down_walk_0.png b/res/ActorExtensionPack/Actor/Skeleton/skeleton_down_walk_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..81126dca0dd109253e84e439f439f1ac18971918
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Skeleton/skeleton_down_walk_0.png differ
diff --git a/res/ActorExtensionPack/Actor/Skeleton/skeleton_down_walk_1.png b/res/ActorExtensionPack/Actor/Skeleton/skeleton_down_walk_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..c8175cab5e946f8fa27b9edc5c1bb89ebc850cc2
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Skeleton/skeleton_down_walk_1.png differ
diff --git a/res/ActorExtensionPack/Actor/Skeleton/skeleton_up_idle_0.png b/res/ActorExtensionPack/Actor/Skeleton/skeleton_up_idle_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..fd9442089191775bbdd94f506841a0b7dbd02dbc
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Skeleton/skeleton_up_idle_0.png differ
diff --git a/res/ActorExtensionPack/Actor/Skeleton/skeleton_up_idle_1.png b/res/ActorExtensionPack/Actor/Skeleton/skeleton_up_idle_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..f0e3c7b530bfff616b7dca31b9e7fe73783aecce
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Skeleton/skeleton_up_idle_1.png differ
diff --git a/res/ActorExtensionPack/Actor/Skeleton/skeleton_up_idle_2.png b/res/ActorExtensionPack/Actor/Skeleton/skeleton_up_idle_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..1b8676a49771c00a7e010ddc0e31eb6b383e2573
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Skeleton/skeleton_up_idle_2.png differ
diff --git a/res/ActorExtensionPack/Actor/Skeleton/skeleton_up_walk_0.png b/res/ActorExtensionPack/Actor/Skeleton/skeleton_up_walk_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..56bb5861823dc82901a976f8758504dcacd84d34
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Skeleton/skeleton_up_walk_0.png differ
diff --git a/res/ActorExtensionPack/Actor/Skeleton/skeleton_up_walk_1.png b/res/ActorExtensionPack/Actor/Skeleton/skeleton_up_walk_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..6bd4a35ad83cb67e214e93ce00f5abbbad9a6b5c
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Skeleton/skeleton_up_walk_1.png differ
diff --git a/res/ActorExtensionPack/Actor/Spider/spider_idle_0.png b/res/ActorExtensionPack/Actor/Spider/spider_idle_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..d23d8d603f116813f6c5a7d899de2cf43e4e5a50
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Spider/spider_idle_0.png differ
diff --git a/res/ActorExtensionPack/Actor/Spider/spider_idle_1.png b/res/ActorExtensionPack/Actor/Spider/spider_idle_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..f22e8de1327f4cbe85ead4969b7ff45955078537
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Spider/spider_idle_1.png differ
diff --git a/res/ActorExtensionPack/Actor/Spider/spider_move_0.png b/res/ActorExtensionPack/Actor/Spider/spider_move_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..76103d1123b3b7f5394834e54c267089bbe72de6
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Spider/spider_move_0.png differ
diff --git a/res/ActorExtensionPack/Actor/Spider/spider_move_1.png b/res/ActorExtensionPack/Actor/Spider/spider_move_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..85bbdb9f212cafa8026e2b6fa6bc9f24b200703f
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Spider/spider_move_1.png differ
diff --git a/res/ActorExtensionPack/Actor/Spider/spider_move_2.png b/res/ActorExtensionPack/Actor/Spider/spider_move_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..0e87d49224148d9431f91057b2fd75f8fa8d250b
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Spider/spider_move_2.png differ
diff --git a/res/ActorExtensionPack/Actor/Spider/spider_move_3.png b/res/ActorExtensionPack/Actor/Spider/spider_move_3.png
new file mode 100644
index 0000000000000000000000000000000000000000..bfc44f41afee1e1c7198715b39ec9dfd37e90586
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Spider/spider_move_3.png differ
diff --git a/res/ActorExtensionPack/Actor/TeleportEffect/effect_0.png b/res/ActorExtensionPack/Actor/TeleportEffect/effect_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..1f08a6b09e44dda34084dd304f7f865664bea3c1
Binary files /dev/null and b/res/ActorExtensionPack/Actor/TeleportEffect/effect_0.png differ
diff --git a/res/ActorExtensionPack/Actor/TeleportEffect/effect_1.png b/res/ActorExtensionPack/Actor/TeleportEffect/effect_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..ae5cfc983f77b6f10d595b4fb331f54dffb6be6d
Binary files /dev/null and b/res/ActorExtensionPack/Actor/TeleportEffect/effect_1.png differ
diff --git a/res/ActorExtensionPack/Actor/TeleportEffect/effect_2.png b/res/ActorExtensionPack/Actor/TeleportEffect/effect_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..61b8e992a64b447ef3b23b396b1e53b58e74bd2d
Binary files /dev/null and b/res/ActorExtensionPack/Actor/TeleportEffect/effect_2.png differ
diff --git a/res/ActorExtensionPack/Actor/TeleportEffect/effect_3.png b/res/ActorExtensionPack/Actor/TeleportEffect/effect_3.png
new file mode 100644
index 0000000000000000000000000000000000000000..f5c424e31dd7e74328d07102d3b2bb89db35550e
Binary files /dev/null and b/res/ActorExtensionPack/Actor/TeleportEffect/effect_3.png differ
diff --git a/res/ActorExtensionPack/Actor/Trap/trap_0.png b/res/ActorExtensionPack/Actor/Trap/trap_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..4d1e4c20f23424cad59c4089d016a4e3477437ad
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Trap/trap_0.png differ
diff --git a/res/ActorExtensionPack/Actor/Trap/trap_1.png b/res/ActorExtensionPack/Actor/Trap/trap_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..baf2d84400ea8fa8c6f17734d6b1acad6c268584
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Trap/trap_1.png differ
diff --git a/res/ActorExtensionPack/Actor/Trap/trap_2.png b/res/ActorExtensionPack/Actor/Trap/trap_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..458b387fcca1601402b7ed7d6938f22c53c894c5
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Trap/trap_2.png differ
diff --git a/res/ActorExtensionPack/Actor/WallMaker/wallMaker.png b/res/ActorExtensionPack/Actor/WallMaker/wallMaker.png
new file mode 100644
index 0000000000000000000000000000000000000000..8a66d84536863f33534e5575fe70db2b4a93a888
Binary files /dev/null and b/res/ActorExtensionPack/Actor/WallMaker/wallMaker.png differ
diff --git a/res/ActorExtensionPack/Actor/WallMaker/wall_horizontal_0.png b/res/ActorExtensionPack/Actor/WallMaker/wall_horizontal_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..fd065adfc5425bf86869f1671cfbff3cc934e846
Binary files /dev/null and b/res/ActorExtensionPack/Actor/WallMaker/wall_horizontal_0.png differ
diff --git a/res/ActorExtensionPack/Actor/WallMaker/wall_horizontal_1.png b/res/ActorExtensionPack/Actor/WallMaker/wall_horizontal_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..81bd55d75c35b7f6b6012463aaee445378272dfc
Binary files /dev/null and b/res/ActorExtensionPack/Actor/WallMaker/wall_horizontal_1.png differ
diff --git a/res/ActorExtensionPack/Actor/WallMaker/wall_vertical_0.png b/res/ActorExtensionPack/Actor/WallMaker/wall_vertical_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..6787f8763975083c276fb9bf3dfe26ef36ed05c5
Binary files /dev/null and b/res/ActorExtensionPack/Actor/WallMaker/wall_vertical_0.png differ
diff --git a/res/ActorExtensionPack/Actor/WallMaker/wall_vertical_1.png b/res/ActorExtensionPack/Actor/WallMaker/wall_vertical_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..7f429294b85f6a03ff166e80a98e094bca1f2261
Binary files /dev/null and b/res/ActorExtensionPack/Actor/WallMaker/wall_vertical_1.png differ
diff --git a/res/ActorExtensionPack/Actor/Witch/magicBall_0.png b/res/ActorExtensionPack/Actor/Witch/magicBall_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..4467577532840386cec97a2b61261f31f3ca717f
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Witch/magicBall_0.png differ
diff --git a/res/ActorExtensionPack/Actor/Witch/magicBall_1.png b/res/ActorExtensionPack/Actor/Witch/magicBall_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..e3d2c2b1f5769534c8bba140c9e4aa404c2afc5c
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Witch/magicBall_1.png differ
diff --git a/res/ActorExtensionPack/Actor/Witch/magicBall_2.png b/res/ActorExtensionPack/Actor/Witch/magicBall_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..e43d27c7e5497d5c299b58c65dec15e8a6bb9de9
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Witch/magicBall_2.png differ
diff --git a/res/ActorExtensionPack/Actor/Witch/witch_idle_0.png b/res/ActorExtensionPack/Actor/Witch/witch_idle_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..806d30c5ca597c31adc657e99ee6f92b9433de3b
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Witch/witch_idle_0.png differ
diff --git a/res/ActorExtensionPack/Actor/Witch/witch_idle_1.png b/res/ActorExtensionPack/Actor/Witch/witch_idle_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..89a06be7754785afaeeefa35a015390d12eafbb8
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Witch/witch_idle_1.png differ
diff --git a/res/ActorExtensionPack/Actor/Witch/witch_walk_0.png b/res/ActorExtensionPack/Actor/Witch/witch_walk_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..806d30c5ca597c31adc657e99ee6f92b9433de3b
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Witch/witch_walk_0.png differ
diff --git a/res/ActorExtensionPack/Actor/Witch/witch_walk_1.png b/res/ActorExtensionPack/Actor/Witch/witch_walk_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..870c63247ba191a06da635d500f1f1732020c2c2
Binary files /dev/null and b/res/ActorExtensionPack/Actor/Witch/witch_walk_1.png differ
diff --git a/res/ActorExtensionPack/Extra/AnotherHat.png b/res/ActorExtensionPack/Extra/AnotherHat.png
new file mode 100644
index 0000000000000000000000000000000000000000..6c2aa7b03749b8b3ea2bf25d851b600e7360abb3
Binary files /dev/null and b/res/ActorExtensionPack/Extra/AnotherHat.png differ
diff --git a/res/ActorExtensionPack/Extra/CoolHat.png b/res/ActorExtensionPack/Extra/CoolHat.png
new file mode 100644
index 0000000000000000000000000000000000000000..46fe772c3bc0d7fbddae8b03579ea095c9c9d600
Binary files /dev/null and b/res/ActorExtensionPack/Extra/CoolHat.png differ
diff --git a/res/ActorExtensionPack/Extra/SomeSword.png b/res/ActorExtensionPack/Extra/SomeSword.png
new file mode 100644
index 0000000000000000000000000000000000000000..fb309a4f48f2953ce37e8e755e23097d534287d8
Binary files /dev/null and b/res/ActorExtensionPack/Extra/SomeSword.png differ
diff --git a/res/ActorExtensionPack/Extra/m0.png b/res/ActorExtensionPack/Extra/m0.png
new file mode 100644
index 0000000000000000000000000000000000000000..1de6d9f17f2f5c59c7b790f7c0ab22c318797c4f
Binary files /dev/null and b/res/ActorExtensionPack/Extra/m0.png differ
diff --git a/res/ActorExtensionPack/Extra/m1.png b/res/ActorExtensionPack/Extra/m1.png
new file mode 100644
index 0000000000000000000000000000000000000000..e37a8562a3361e13408c9252ccc03b48a4b18633
Binary files /dev/null and b/res/ActorExtensionPack/Extra/m1.png differ
diff --git a/res/ActorExtensionPack/Extra/m2.png b/res/ActorExtensionPack/Extra/m2.png
new file mode 100644
index 0000000000000000000000000000000000000000..946f38d45079e07d01170cc8c0d16d17d704972d
Binary files /dev/null and b/res/ActorExtensionPack/Extra/m2.png differ
diff --git a/res/ActorExtensionPack/Extra/p0.png b/res/ActorExtensionPack/Extra/p0.png
new file mode 100644
index 0000000000000000000000000000000000000000..380402bfe229569776ec41be9ac9280d1cc1068b
Binary files /dev/null and b/res/ActorExtensionPack/Extra/p0.png differ
diff --git a/res/ActorExtensionPack/Extra/p1.png b/res/ActorExtensionPack/Extra/p1.png
new file mode 100644
index 0000000000000000000000000000000000000000..b19863be22841a4bda5a88d14e0ac03b615b8d1d
Binary files /dev/null and b/res/ActorExtensionPack/Extra/p1.png differ
diff --git a/res/ActorExtensionPack/Extra/p2.png b/res/ActorExtensionPack/Extra/p2.png
new file mode 100644
index 0000000000000000000000000000000000000000..62bdc9e7fca594077374ea1b3bb1ba56ea697cde
Binary files /dev/null and b/res/ActorExtensionPack/Extra/p2.png differ
diff --git a/res/ActorExtensionPack/Extra/pixil-frame-0 (10).png b/res/ActorExtensionPack/Extra/pixil-frame-0 (10).png
new file mode 100644
index 0000000000000000000000000000000000000000..55ef7dd5c2baaa36fdd3ee5833e898f5b64aaa3f
Binary files /dev/null and b/res/ActorExtensionPack/Extra/pixil-frame-0 (10).png differ
diff --git a/res/ActorExtensionPack/Extra/pixil-frame-0 (11).png b/res/ActorExtensionPack/Extra/pixil-frame-0 (11).png
new file mode 100644
index 0000000000000000000000000000000000000000..8d0e13d083575b40265b90a669ab90bb75a89e7f
Binary files /dev/null and b/res/ActorExtensionPack/Extra/pixil-frame-0 (11).png differ
diff --git a/res/ActorExtensionPack/Extra/pixil-frame-0 (13).png b/res/ActorExtensionPack/Extra/pixil-frame-0 (13).png
new file mode 100644
index 0000000000000000000000000000000000000000..06d5776e2374aacdb99a32733b2d822563b565c4
Binary files /dev/null and b/res/ActorExtensionPack/Extra/pixil-frame-0 (13).png differ
diff --git a/res/ActorExtensionPack/Extra/pixil-frame-0 (14).png b/res/ActorExtensionPack/Extra/pixil-frame-0 (14).png
new file mode 100644
index 0000000000000000000000000000000000000000..3ec2325cd3acd484af4b365315e387c1730a81b6
Binary files /dev/null and b/res/ActorExtensionPack/Extra/pixil-frame-0 (14).png differ
diff --git a/res/ActorExtensionPack/Extra/pixil-frame-0 (15).png b/res/ActorExtensionPack/Extra/pixil-frame-0 (15).png
new file mode 100644
index 0000000000000000000000000000000000000000..7c71c47b33ff46a01209b6c0a1bfb0899ea7e4f2
Binary files /dev/null and b/res/ActorExtensionPack/Extra/pixil-frame-0 (15).png differ
diff --git a/res/ActorExtensionPack/Extra/pixil-frame-0 (9).png b/res/ActorExtensionPack/Extra/pixil-frame-0 (9).png
new file mode 100644
index 0000000000000000000000000000000000000000..bab2ef53c3c250950702c7dcf9205ae48a34302b
Binary files /dev/null and b/res/ActorExtensionPack/Extra/pixil-frame-0 (9).png differ
diff --git a/res/ActorExtensionPack/Extra/pixil-frame-0.png b/res/ActorExtensionPack/Extra/pixil-frame-0.png
new file mode 100644
index 0000000000000000000000000000000000000000..0e6b7c78a498b6c0b83a03b82598d4f6dced6573
Binary files /dev/null and b/res/ActorExtensionPack/Extra/pixil-frame-0.png differ
diff --git a/res/ActorExtensionPack/Extra/ship0.png b/res/ActorExtensionPack/Extra/ship0.png
new file mode 100644
index 0000000000000000000000000000000000000000..da09def1e1ecfaf136580218c6ec568e5817d22c
Binary files /dev/null and b/res/ActorExtensionPack/Extra/ship0.png differ
diff --git a/res/ActorExtensionPack/Extra/ship1.png b/res/ActorExtensionPack/Extra/ship1.png
new file mode 100644
index 0000000000000000000000000000000000000000..5921c81d478c9da89770b6d94e7cba23e25293cc
Binary files /dev/null and b/res/ActorExtensionPack/Extra/ship1.png differ
diff --git a/res/ActorExtensionPack/Extra/ship2.png b/res/ActorExtensionPack/Extra/ship2.png
new file mode 100644
index 0000000000000000000000000000000000000000..7c18e2e8855c31cdf49278aae85f7f033ec37d8f
Binary files /dev/null and b/res/ActorExtensionPack/Extra/ship2.png differ
diff --git a/res/ActorExtensionPack/Extra/ship3.png b/res/ActorExtensionPack/Extra/ship3.png
new file mode 100644
index 0000000000000000000000000000000000000000..c9bc7ded656c5ea87277690b815fd9ac67a9d7da
Binary files /dev/null and b/res/ActorExtensionPack/Extra/ship3.png differ
diff --git a/res/ActorExtensionPack/Extra/ship4.png b/res/ActorExtensionPack/Extra/ship4.png
new file mode 100644
index 0000000000000000000000000000000000000000..476bb72a729176d636b08a356b9bfed85817926d
Binary files /dev/null and b/res/ActorExtensionPack/Extra/ship4.png differ
diff --git a/res/ActorExtensionPack/Extra/ship5.png b/res/ActorExtensionPack/Extra/ship5.png
new file mode 100644
index 0000000000000000000000000000000000000000..de2564c0a019cb23150739a3366d0b44c9e8de32
Binary files /dev/null and b/res/ActorExtensionPack/Extra/ship5.png differ
diff --git a/res/ActorExtensionPack/Extra/ship6.png b/res/ActorExtensionPack/Extra/ship6.png
new file mode 100644
index 0000000000000000000000000000000000000000..6c6025ac3e83fddebde31f2ed4d0ba7f76300fb5
Binary files /dev/null and b/res/ActorExtensionPack/Extra/ship6.png differ
diff --git a/res/ActorExtensionPack/Extra/ship7.png b/res/ActorExtensionPack/Extra/ship7.png
new file mode 100644
index 0000000000000000000000000000000000000000..c894bc4ff5d725cd7470b7d5ec11dbe33ba7028c
Binary files /dev/null and b/res/ActorExtensionPack/Extra/ship7.png differ
diff --git a/res/ActorExtensionPack/Font/8-bit-pusab.ttf b/res/ActorExtensionPack/Font/8-bit-pusab.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..22d5e69e7c62cfeb7fba6560b4d9c8e8665a1c75
Binary files /dev/null and b/res/ActorExtensionPack/Font/8-bit-pusab.ttf differ
diff --git a/res/ActorExtensionPack/Font/Mario-Kart-DS.ttf b/res/ActorExtensionPack/Font/Mario-Kart-DS.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..011a9061a08463aa9a794d71acca8d438ad34b7b
Binary files /dev/null and b/res/ActorExtensionPack/Font/Mario-Kart-DS.ttf differ
diff --git a/res/ActorExtensionPack/Level/Bones.csv b/res/ActorExtensionPack/Level/Bones.csv
new file mode 100644
index 0000000000000000000000000000000000000000..56c0aef083a9ea7102bfd7007a22621351d9f537
--- /dev/null
+++ b/res/ActorExtensionPack/Level/Bones.csv
@@ -0,0 +1,20 @@
+Skeleton,6,10,0,9
+Skeleton,7,1,2,10
+Skeleton,8,2,2,8
+Skeleton,9,9,0,8
+Skull,5,1,0,4
+Skull,5,10,2,4
+Skeleton,7,3,2,5
+Skeleton,10,7,0,5
+Skeleton,5,7,0,4
+Knight,14,5
+Chest,1,5
+Skull,3,3,0,6
+SignUp,10,1
+SignLeft,11,1
+SignRight,12,1
+SignDown,13,1
+SignUp,10,2
+SignLeft,11,2
+SignRight,12,2
+SignDown,13,2
diff --git a/res/ActorExtensionPack/Level/Bones.txt b/res/ActorExtensionPack/Level/Bones.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7ecdf8acc350cd9c14f8114356058cbc4911c941
--- /dev/null
+++ b/res/ActorExtensionPack/Level/Bones.txt
@@ -0,0 +1,2 @@
+Level 12: Bones
+Only the bravest can pass this level.
\ No newline at end of file
diff --git a/res/ActorExtensionPack/Level/Easy.csv b/res/ActorExtensionPack/Level/Easy.csv
new file mode 100644
index 0000000000000000000000000000000000000000..1d516a7e35343c26e558a17ebc810d9c9474192a
--- /dev/null
+++ b/res/ActorExtensionPack/Level/Easy.csv
@@ -0,0 +1,6 @@
+Knight,11,6
+Chest,1,1
+SignUp,1,6
+SignLeft,9,4
+SignRight,10,4
+SignDown,11,4
diff --git a/res/ActorExtensionPack/Level/Easy.txt b/res/ActorExtensionPack/Level/Easy.txt
new file mode 100644
index 0000000000000000000000000000000000000000..55d1da8a6caf4caa438cc4a2931968ed2f0dc7e4
--- /dev/null
+++ b/res/ActorExtensionPack/Level/Easy.txt
@@ -0,0 +1,9 @@
+Level-1: Easy One
+Oh there is a chest.
+I need to plan my route to get    there.
+Hint: Using shadowSign to        change the direction.
+Hint: Click the sign to use it.
+Hint: If the position is                unwanted
+Hint: Please use the garbage     can to remove the sign.
+Hint: Lastly, dont forget to       close the garbage  can.
+Interesting fact: The white      dot on the knight is an               accident   :-<
\ No newline at end of file
diff --git a/res/ActorExtensionPack/Level/EmptyMap.csv b/res/ActorExtensionPack/Level/EmptyMap.csv
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/res/ActorExtensionPack/Level/MagicTower.csv b/res/ActorExtensionPack/Level/MagicTower.csv
new file mode 100644
index 0000000000000000000000000000000000000000..9e689b61e199e9fde84a0958235dc3421c62b56c
--- /dev/null
+++ b/res/ActorExtensionPack/Level/MagicTower.csv
@@ -0,0 +1,14 @@
+Knight,13,6
+WallMaker,11,1,11,7
+WallMaker,11,7,11,1
+WallMaker,6,10,6,4
+WallMaker,6,4,6,10
+Chest,3,6
+WallMaker,5,4,3,4
+WallMaker,3,4,5,4
+SignDown,12,6
+SignLeft,12,9
+SignUp,8,9
+SignLeft,8,2
+SignDown,2,2
+SignRight,2,6
diff --git a/res/ActorExtensionPack/Level/MagicTower.txt b/res/ActorExtensionPack/Level/MagicTower.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7067047c8dd56c6dcba8acae16c947d0d09bfb68
--- /dev/null
+++ b/res/ActorExtensionPack/Level/MagicTower.txt
@@ -0,0 +1,4 @@
+Level 6: Magic Tower
+Magic tower can make a                lightning.
+Hint: Just dont touch them
+Interesting fact: The magic     Tower is called wall maker in   the source code.
\ No newline at end of file
diff --git a/res/ActorExtensionPack/Level/MeteorShower.csv b/res/ActorExtensionPack/Level/MeteorShower.csv
new file mode 100644
index 0000000000000000000000000000000000000000..5aea49e287dfb40b0965b163e4b0bb01b0961908
--- /dev/null
+++ b/res/ActorExtensionPack/Level/MeteorShower.csv
@@ -0,0 +1,14 @@
+Witch,3,2,0,7
+Witch,4,9,2,6
+Witch,1,9,2,5
+Witch,2,7,2,6
+Chest,1,4
+Knight,13,5
+SignUp,12,5
+SignLeft,12,1
+SignDown,6,1
+SignLeft,6,2
+SignUp,4,2
+SignLeft,4,1
+SignDown,1,1
+Witch,3,6,0,4
diff --git a/res/ActorExtensionPack/Level/MeteorShower.txt b/res/ActorExtensionPack/Level/MeteorShower.txt
new file mode 100644
index 0000000000000000000000000000000000000000..bba3a2df784ebcd48e36ba3cd5b893cbf12d863d
--- /dev/null
+++ b/res/ActorExtensionPack/Level/MeteorShower.txt
@@ -0,0 +1,2 @@
+Level 14: Meteor Shower
+Tons of fire balls
\ No newline at end of file
diff --git a/res/ActorExtensionPack/Level/MonsterParty.csv b/res/ActorExtensionPack/Level/MonsterParty.csv
new file mode 100644
index 0000000000000000000000000000000000000000..04bf6ed6921e16f309fe924f3c56c556382dd3dd
--- /dev/null
+++ b/res/ActorExtensionPack/Level/MonsterParty.csv
@@ -0,0 +1,38 @@
+WallMaker,9,4,9,10
+WallMaker,9,10,9,4
+WallMaker,4,1,4,7
+WallMaker,4,7,4,1
+Trap,10,2,0
+Trap,7,2,1
+Trap,8,6,1
+Trap,8,10,0
+Trap,8,9,1
+Trap,7,8,1
+Knight,13,9
+SignUp,12,9
+SignLeft,12,2
+SignDown,6,2
+SignRight,6,3
+SignDown,7,3
+SignRight,7,4
+SignLeft,8,5
+SignDown,7,5
+SignLeft,7,10
+SignLeft,2,5
+SignUp,1,5
+Chest,1,1
+Witch,2,8,2,5
+Skull,3,3,0,5
+Spider,2,6,1,2,2
+SignUp,1,10
+Spider,1,9,1,0,5
+Portal,10,5,5,7
+Portal,5,7,10,5
+Skeleton,5,4,1,4
+SignDown,8,4
+Skeleton,11,8,0,6
+Skeleton,11,1,2,7
+Spider,12,7,3,2,2
+Spider,14,3,3,2,4
+Skeleton,10,3,1,4
+Skeleton,2,9,1,4
diff --git a/res/ActorExtensionPack/Level/MonsterParty.txt b/res/ActorExtensionPack/Level/MonsterParty.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2b195efe7bb156df2a38552a5255d8c37b8ad66e
--- /dev/null
+++ b/res/ActorExtensionPack/Level/MonsterParty.txt
@@ -0,0 +1,3 @@
+Level 15: Monster Party
+This one is really hard.
+no joking.
\ No newline at end of file
diff --git a/res/ActorExtensionPack/Level/MoreSkeleton.csv b/res/ActorExtensionPack/Level/MoreSkeleton.csv
new file mode 100644
index 0000000000000000000000000000000000000000..24bc3221ea4d722c486e98ae1faf5b5610ee6925
--- /dev/null
+++ b/res/ActorExtensionPack/Level/MoreSkeleton.csv
@@ -0,0 +1,10 @@
+Chest,2,5,,
+Skeleton,1,4,1,3
+Skeleton,3,6,3,3
+Skeleton,1,7,0,3
+Skeleton,3,3,2,3
+Knight,9,5,,
+SignDown,8,5,,
+SignLeft,8,6,,
+SignUp,2,6,,
+SignRight,1,1,,
diff --git a/res/ActorExtensionPack/Level/MoreSkeleton.txt b/res/ActorExtensionPack/Level/MoreSkeleton.txt
new file mode 100644
index 0000000000000000000000000000000000000000..5023760d449cd40db7891bb13c92d7b0d4d5d593
--- /dev/null
+++ b/res/ActorExtensionPack/Level/MoreSkeleton.txt
@@ -0,0 +1,2 @@
+Level 3: More Skeleton
+Is that a dance party?
diff --git a/res/ActorExtensionPack/Level/Portal.csv b/res/ActorExtensionPack/Level/Portal.csv
new file mode 100644
index 0000000000000000000000000000000000000000..6f1e5b675311e95ef5b9aaed76445ca083b508f6
--- /dev/null
+++ b/res/ActorExtensionPack/Level/Portal.csv
@@ -0,0 +1,10 @@
+Knight,14,6
+Chest,1,1
+Portal,11,4,2,6
+Portal,2,6,11,4
+WallMaker,9,1,9,10
+WallMaker,9,10,9,1
+SignUp,11,6
+SignLeft,2,1
+SignDown,3,6
+SignRight,11,1
diff --git a/res/ActorExtensionPack/Level/Portal.txt b/res/ActorExtensionPack/Level/Portal.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2d1c5f730c371aef30a761edb1bc872be290816d
--- /dev/null
+++ b/res/ActorExtensionPack/Level/Portal.txt
@@ -0,0 +1,4 @@
+Level 7: Portal
+We cant directly move to the    chest!
+What should we do?
+Hint: use the portal
\ No newline at end of file
diff --git a/res/ActorExtensionPack/Level/Seapider.csv b/res/ActorExtensionPack/Level/Seapider.csv
new file mode 100644
index 0000000000000000000000000000000000000000..fb8371806bf8d8ee55c115d5b41fddd66e54dfcb
--- /dev/null
+++ b/res/ActorExtensionPack/Level/Seapider.csv
@@ -0,0 +1,17 @@
+Spider,9,4,3,2,4
+Spider,5,4,1,2,4
+Chest,7,6
+Spider,5,8,1,0,3
+Spider,9,8,3,0,3
+Spider,8,6,3,2,2
+Spider,6,6,1,0,2
+Spider,7,7,1,0,2
+Spider,7,5,3,2,2
+Knight,12,6
+SignUp,11,6
+SignLeft,11,5
+SignDown,9,5
+SignLeft,9,6
+SignRight,12,5
+SignDown,10,7
+SignLeft,10,8
diff --git a/res/ActorExtensionPack/Level/Seapider.txt b/res/ActorExtensionPack/Level/Seapider.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f6659b8fd3da0c4632119b9d8887b8ee4ccb8de0
--- /dev/null
+++ b/res/ActorExtensionPack/Level/Seapider.txt
@@ -0,0 +1,7 @@
+Level 5: Seapider
+Sea + Spider
+HaHaHaHaHaHa
+HaHaHa
+Ha
+...
+Actually Im not good at make     a joke     :-<
\ No newline at end of file
diff --git a/res/ActorExtensionPack/Level/Skeleton.csv b/res/ActorExtensionPack/Level/Skeleton.csv
new file mode 100644
index 0000000000000000000000000000000000000000..ffe04845dbcca8a973d946cde3284adcd13d061d
--- /dev/null
+++ b/res/ActorExtensionPack/Level/Skeleton.csv
@@ -0,0 +1,8 @@
+Chest,1,1
+Skeleton,2,1,2,3
+Skeleton,1,2,1,3
+SignDown,11,5
+SignRight,8,3
+Knight,5,6
+SignUp,7,6
+SignLeft,7,1
diff --git a/res/ActorExtensionPack/Level/Skeleton.txt b/res/ActorExtensionPack/Level/Skeleton.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ac5bd26033a21f9739eaa694c5a519479ab3df62
--- /dev/null
+++ b/res/ActorExtensionPack/Level/Skeleton.txt
@@ -0,0 +1,5 @@
+Level 2: Skeleton
+This time there are two             Skeletons aound the chest.
+Hint: Red eye moves Left and      Right
+Hint: Blue eye moves Up and       Down
+Interesting Fact: the lower       body animation comes from       Micheal Jackson
diff --git a/res/ActorExtensionPack/Level/Skull.csv b/res/ActorExtensionPack/Level/Skull.csv
new file mode 100644
index 0000000000000000000000000000000000000000..d2da4d431450b65ccb7b3d38a98faca7e952213f
--- /dev/null
+++ b/res/ActorExtensionPack/Level/Skull.csv
@@ -0,0 +1,6 @@
+Skull,4,3,0,6
+Chest,1,5
+Skull,4,9,2,5
+Knight,13,6
+SignUp,6,6
+SignLeft,6,5
diff --git a/res/ActorExtensionPack/Level/Skull.txt b/res/ActorExtensionPack/Level/Skull.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f5c5eaa58f91aa59a745e167853347092940097e
--- /dev/null
+++ b/res/ActorExtensionPack/Level/Skull.txt
@@ -0,0 +1,4 @@
+Level 11: Skull
+They can shoot fire ball.
+Watch out!!!
+interesting fact: skull's head comes from skeleton.
\ No newline at end of file
diff --git a/res/ActorExtensionPack/Level/Spider.csv b/res/ActorExtensionPack/Level/Spider.csv
new file mode 100644
index 0000000000000000000000000000000000000000..962b3ff962029dd9581511fb365da6b2d5aa237a
--- /dev/null
+++ b/res/ActorExtensionPack/Level/Spider.csv
@@ -0,0 +1,10 @@
+Spider,3,1,3,2,2
+Chest,1,1
+Knight,4,4
+Spider,1,3,1,0,1
+SignUp,2,4
+SignLeft,2,2
+SignUp,1,2
+SignRight,3,3
+SignRight,3,5
+SignDown,1,4
diff --git a/res/ActorExtensionPack/Level/Spider.txt b/res/ActorExtensionPack/Level/Spider.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9377921ccd456b920e3ee0801a6e1a3819920963
--- /dev/null
+++ b/res/ActorExtensionPack/Level/Spider.txt
@@ -0,0 +1,4 @@
+Level 4: Spider
+Spider moves in diagonal          direction.
+Hint: nope
+Interesting Fact: The idea        of spider comes from a "Bug"     movement of the Skeleton
\ No newline at end of file
diff --git a/res/ActorExtensionPack/Level/TTTTraps!!!!!!!!!!!!!.csv b/res/ActorExtensionPack/Level/TTTTraps!!!!!!!!!!!!!.csv
new file mode 100644
index 0000000000000000000000000000000000000000..7ebd95295a2658da675ef7dae0d77fb6beb3b53d
--- /dev/null
+++ b/res/ActorExtensionPack/Level/TTTTraps!!!!!!!!!!!!!.csv
@@ -0,0 +1,90 @@
+Knight,14,4,,
+SignDown,5,4,,
+SignRight,5,8,,
+SignDown,10,8,,
+Chest,10,9,,
+Trap,5,9,1,
+Trap,6,9,0,
+Trap,7,9,1,
+Trap,8,9,1,
+Trap,9,9,1,
+Trap,4,9,1,
+Trap,4,8,1,
+Trap,5,7,0,
+Trap,4,7,0,
+Trap,6,8,0,
+Trap,6,7,1,
+Trap,7,8,1,
+Trap,8,8,0,
+Trap,8,7,1,
+Trap,9,8,1,
+Trap,3,9,0,
+Trap,3,8,1,
+Trap,3,7,1,
+Trap,3,6,1,
+Trap,4,6,0,
+Trap,5,6,1,
+Trap,6,6,1,
+Trap,10,7,0,
+Trap,9,7,1,
+Trap,11,9,1,
+Trap,11,8,0,
+Trap,11,7,1,
+Trap,12,7,1,
+Trap,13,7,0,
+Trap,12,8,1,
+Trap,13,8,0,
+Trap,14,7,1,
+Trap,12,9,0,
+Trap,13,9,1,
+Trap,7,6,0,
+Trap,8,6,1,
+Trap,9,6,0,
+Trap,10,6,1,
+Trap,11,6,1,
+Trap,12,6,0,
+Trap,13,6,1,
+Trap,14,6,0,
+Trap,3,3,1,
+Trap,3,5,0,
+Trap,14,9,1,
+WallMaker,14,2,3,2,
+WallMaker,3,2,14,2,
+WallMaker,2,3,2,9,
+WallMaker,2,9,2,3,
+WallMaker,3,10,14,10,
+WallMaker,14,10,3,10,
+Trap,4,5,1,
+Trap,4,4,0,
+Trap,4,3,0,
+Trap,5,5,0,
+Trap,5,3,1,
+Trap,6,5,0,
+Trap,9,5,1,
+Trap,8,5,1,
+Trap,14,5,0,
+Trap,13,5,1,
+Trap,12,5,1,
+Trap,11,5,0,
+Trap,6,4,0,
+Trap,6,3,1,
+Trap,14,3,1,
+Trap,13,3,1,
+Trap,13,4,1,
+Trap,12,3,1,
+Trap,7,3,0,
+Trap,7,4,1,
+Trap,8,4,0,
+Trap,8,3,1,
+Trap,9,3,1,
+Trap,10,4,0,
+Trap,11,4,1,
+Trap,10,3,1,
+Trap,11,3,1,
+Trap,12,4,0,
+SignUp,7,7,,
+SignRight,7,5,,
+SignLeft,10,5,,
+SignUp,3,4,,
+SignUp,14,8,,
+SignLeft,9,4,,
diff --git a/res/ActorExtensionPack/Level/TTTTraps!!!!!!!!!!!!!.txt b/res/ActorExtensionPack/Level/TTTTraps!!!!!!!!!!!!!.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2ef0364601291dd2311c6f4474515ec21a6d1763
--- /dev/null
+++ b/res/ActorExtensionPack/Level/TTTTraps!!!!!!!!!!!!!.txt
@@ -0,0 +1,4 @@
+Level 10: TTrappppps!!!!
+!!!!!!!!!!!!!!!!!!!!!
+Hint: Consider the empty block
+Interesting fact: all maps        comes from the make level
\ No newline at end of file
diff --git a/res/ActorExtensionPack/Level/Trap!!!.csv b/res/ActorExtensionPack/Level/Trap!!!.csv
new file mode 100644
index 0000000000000000000000000000000000000000..9cb1d1ddf6c4a935b2085764a18e556cd568fca7
--- /dev/null
+++ b/res/ActorExtensionPack/Level/Trap!!!.csv
@@ -0,0 +1,14 @@
+Knight,12,6
+Trap,6,6,1
+Trap,5,7,1
+Trap,4,6,0
+Trap,5,5,1
+Chest,5,6
+Trap,6,7,1
+Trap,4,7,1
+Trap,4,5,1
+Trap,6,5,1
+SignUp,9,6
+SignLeft,9,4
+SignDown,3,4
+SignRight,3,6
diff --git a/res/ActorExtensionPack/Level/Trap!!!.txt b/res/ActorExtensionPack/Level/Trap!!!.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d4eb062c78bda7d80a9dea2d88cea99c11a3f072
--- /dev/null
+++ b/res/ActorExtensionPack/Level/Trap!!!.txt
@@ -0,0 +1,4 @@
+Level 9: Traps!!!!!!
+!!!!!!!!
+Hint: I think you can find the   different trap.
+Interesting fact: trap is the   least offensive actor
\ No newline at end of file
diff --git a/res/ActorExtensionPack/Level/WhereAmI.csv b/res/ActorExtensionPack/Level/WhereAmI.csv
new file mode 100644
index 0000000000000000000000000000000000000000..0e2067ee533c7eb2603535ff1633ed6cee87887e
--- /dev/null
+++ b/res/ActorExtensionPack/Level/WhereAmI.csv
@@ -0,0 +1,41 @@
+Portal,11,7,7,3
+Portal,7,3,11,7
+Portal,8,9,3,5
+Portal,3,5,8,9
+Portal,4,5,14,1
+Portal,14,1,4,5
+Portal,4,4,6,7
+Portal,6,7,4,4
+Knight,14,5
+SignLeft,12,7
+SignDown,6,3
+SignRight,6,6
+SignDown,8,6
+SignLeft,3,8
+SignUp,1,8
+Chest,1,1
+Portal,8,5,9,2
+Portal,9,2,8,5
+Portal,12,3,13,8
+Portal,13,8,12,3
+WallMaker,10,10,10,1
+WallMaker,10,1,10,10
+WallMaker,5,1,5,10
+WallMaker,5,10,5,1
+Portal,9,7,4,1
+Portal,4,1,9,7
+Portal,2,4,2,9
+Portal,2,9,2,4
+Portal,4,9,6,9
+Portal,6,9,4,9
+Portal,2,7,3,2
+Portal,3,2,2,7
+Portal,7,5,6,1
+Portal,6,1,7,5
+Portal,6,4,6,5
+Portal,6,5,6,4
+Portal,11,4,13,6
+Portal,13,6,11,4
+SignDown,12,5
+Portal,11,5,11,8
+Portal,11,8,11,5
diff --git a/res/ActorExtensionPack/Level/WhereAmI.txt b/res/ActorExtensionPack/Level/WhereAmI.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ad8bb289ad0a112d6301488ba9fa79c9af397524
--- /dev/null
+++ b/res/ActorExtensionPack/Level/WhereAmI.txt
@@ -0,0 +1,4 @@
+Level 8: Where am I
+What the ......
+Interesting fact: To be honest,I spent more than 20 minutes       on this level 
+because I forgot how I placed them. :->
\ No newline at end of file
diff --git a/res/ActorExtensionPack/Level/Witch.csv b/res/ActorExtensionPack/Level/Witch.csv
new file mode 100644
index 0000000000000000000000000000000000000000..40f3248f52e19a1bbf1ae7dd1edfb6dc2db9f0a4
--- /dev/null
+++ b/res/ActorExtensionPack/Level/Witch.csv
@@ -0,0 +1,7 @@
+Witch,3,9,2,5
+Witch,3,3,0,5
+Knight,10,4
+Chest,1,6
+SignDown,7,4
+SignLeft,7,5
+SignDown,1,5
diff --git a/res/ActorExtensionPack/Level/Witch.txt b/res/ActorExtensionPack/Level/Witch.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6bbde2b71c712d23bed5b01d0203efd10ddb68d6
--- /dev/null
+++ b/res/ActorExtensionPack/Level/Witch.txt
@@ -0,0 +1,3 @@
+Level 13: Witch
+one Witch == two Skulls
+Interesting Fact: witch needs to cast to the "Level" to shoot fire ball. Sounds magic. 
\ No newline at end of file
diff --git a/res/ActorExtensionPack/Map/DungeonMap.png b/res/ActorExtensionPack/Map/DungeonMap.png
new file mode 100644
index 0000000000000000000000000000000000000000..689dc0e922aa7887a36fa701e448af5b80389c0a
Binary files /dev/null and b/res/ActorExtensionPack/Map/DungeonMap.png differ
diff --git a/res/ActorExtensionPack/Sound/mp3/ButtonPressed.mp3 b/res/ActorExtensionPack/Sound/mp3/ButtonPressed.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..1a6292c87967941c5da8ca0989cea11efffd35d1
Binary files /dev/null and b/res/ActorExtensionPack/Sound/mp3/ButtonPressed.mp3 differ
diff --git a/res/ActorExtensionPack/Sound/mp3/DeadSound.mp3 b/res/ActorExtensionPack/Sound/mp3/DeadSound.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..6feb80b7c3ade4194ba58da6ff879bbac343ecc6
Binary files /dev/null and b/res/ActorExtensionPack/Sound/mp3/DeadSound.mp3 differ
diff --git a/res/ActorExtensionPack/Sound/mp3/FunkyBGM.mp3 b/res/ActorExtensionPack/Sound/mp3/FunkyBGM.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..dd329eaf010b32a494266c1bd9c8e17d4ebdee13
Binary files /dev/null and b/res/ActorExtensionPack/Sound/mp3/FunkyBGM.mp3 differ
diff --git a/res/ActorExtensionPack/Sound/mp3/GameStartBGM.mp3 b/res/ActorExtensionPack/Sound/mp3/GameStartBGM.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..73f7beb84da649626af862b889dbb929bea6744d
Binary files /dev/null and b/res/ActorExtensionPack/Sound/mp3/GameStartBGM.mp3 differ
diff --git a/res/ActorExtensionPack/Sound/mp3/StartMenuBGM.mp3 b/res/ActorExtensionPack/Sound/mp3/StartMenuBGM.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..8ff109c9bffcd9b8a8fde25d2bae5c6c411d580d
Binary files /dev/null and b/res/ActorExtensionPack/Sound/mp3/StartMenuBGM.mp3 differ
diff --git a/res/ActorExtensionPack/Sound/mp3/Teleport.mp3 b/res/ActorExtensionPack/Sound/mp3/Teleport.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..03e90b504e93f128ac76e2ee90a02e2576d348f1
Binary files /dev/null and b/res/ActorExtensionPack/Sound/mp3/Teleport.mp3 differ
diff --git a/res/ActorExtensionPack/Sound/mp3/gameOver.mp3 b/res/ActorExtensionPack/Sound/mp3/gameOver.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..c6b56e9d7b17a8f88bf695a0573b10c3e639a035
Binary files /dev/null and b/res/ActorExtensionPack/Sound/mp3/gameOver.mp3 differ
diff --git a/res/ActorExtensionPack/Sound/mp3/magicShoot.mp3 b/res/ActorExtensionPack/Sound/mp3/magicShoot.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..be005a8a1aabbe5fe6161d958c8767f139dbf8f6
Binary files /dev/null and b/res/ActorExtensionPack/Sound/mp3/magicShoot.mp3 differ
diff --git a/res/ActorExtensionPack/Sound/mp3/magicWall.mp3 b/res/ActorExtensionPack/Sound/mp3/magicWall.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..ee382a96f600ec381a6425d5e1100696a8cfe5f5
Binary files /dev/null and b/res/ActorExtensionPack/Sound/mp3/magicWall.mp3 differ
diff --git a/res/ActorExtensionPack/Sound/mp3/spiderWalking.mp3 b/res/ActorExtensionPack/Sound/mp3/spiderWalking.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..5de4384b2ecd955f2edf45a980e6c53eea831d57
Binary files /dev/null and b/res/ActorExtensionPack/Sound/mp3/spiderWalking.mp3 differ
diff --git a/res/ActorExtensionPack/Sound/mp3/teleport2.mp3 b/res/ActorExtensionPack/Sound/mp3/teleport2.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..c6381b6af189211b69b208f74aff181f2aaade9f
Binary files /dev/null and b/res/ActorExtensionPack/Sound/mp3/teleport2.mp3 differ
diff --git a/res/ActorExtensionPack/Sound/mp3/walking.mp3 b/res/ActorExtensionPack/Sound/mp3/walking.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..fa5311bbad084a193f430e219f8a85048ef1961b
Binary files /dev/null and b/res/ActorExtensionPack/Sound/mp3/walking.mp3 differ
diff --git a/res/ActorExtensionPack/Sound/mp3/walkingMedium.mp3 b/res/ActorExtensionPack/Sound/mp3/walkingMedium.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..94dd427fb635715e082698e7cf87155a2250269f
Binary files /dev/null and b/res/ActorExtensionPack/Sound/mp3/walkingMedium.mp3 differ
diff --git a/res/ActorExtensionPack/Sound/mp3/walkingSlow.mp3 b/res/ActorExtensionPack/Sound/mp3/walkingSlow.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..01c8a47b1926b821a26ec5e704046c150a12868d
Binary files /dev/null and b/res/ActorExtensionPack/Sound/mp3/walkingSlow.mp3 differ
diff --git a/res/ActorExtensionPack/Sound/wav/ButtonPressed.wav b/res/ActorExtensionPack/Sound/wav/ButtonPressed.wav
new file mode 100644
index 0000000000000000000000000000000000000000..954d5915c70c50a23aed900628c6c307a18f62e7
Binary files /dev/null and b/res/ActorExtensionPack/Sound/wav/ButtonPressed.wav differ
diff --git a/res/ActorExtensionPack/Sound/wav/DeadSound.wav b/res/ActorExtensionPack/Sound/wav/DeadSound.wav
new file mode 100644
index 0000000000000000000000000000000000000000..3ac83904a06b47808ba48cd18225013883696840
Binary files /dev/null and b/res/ActorExtensionPack/Sound/wav/DeadSound.wav differ
diff --git a/res/ActorExtensionPack/Sound/wav/FunkyBGM.wav b/res/ActorExtensionPack/Sound/wav/FunkyBGM.wav
new file mode 100644
index 0000000000000000000000000000000000000000..b41b8ed959761e6080499a1b1b5a8d1868bf89df
Binary files /dev/null and b/res/ActorExtensionPack/Sound/wav/FunkyBGM.wav differ
diff --git a/res/ActorExtensionPack/Sound/wav/StartMenuBGM.wav b/res/ActorExtensionPack/Sound/wav/StartMenuBGM.wav
new file mode 100644
index 0000000000000000000000000000000000000000..79479df96f6e4e268d98f57f1617f5564c2376ff
Binary files /dev/null and b/res/ActorExtensionPack/Sound/wav/StartMenuBGM.wav differ
diff --git a/res/ActorExtensionPack/Sound/wav/Teleport.wav b/res/ActorExtensionPack/Sound/wav/Teleport.wav
new file mode 100644
index 0000000000000000000000000000000000000000..ca21cc75bc1d0e595c404ff93eab12831014a28f
Binary files /dev/null and b/res/ActorExtensionPack/Sound/wav/Teleport.wav differ
diff --git a/res/ActorExtensionPack/Sound/wav/gameOver.wav b/res/ActorExtensionPack/Sound/wav/gameOver.wav
new file mode 100644
index 0000000000000000000000000000000000000000..2e287d0f9ded70fbb74ef4bf12108bc6defaaac0
Binary files /dev/null and b/res/ActorExtensionPack/Sound/wav/gameOver.wav differ
diff --git a/res/ActorExtensionPack/Sound/wav/lose.wav b/res/ActorExtensionPack/Sound/wav/lose.wav
new file mode 100644
index 0000000000000000000000000000000000000000..5819b38d9254d73d8aa73a85df496483f245c396
Binary files /dev/null and b/res/ActorExtensionPack/Sound/wav/lose.wav differ
diff --git a/res/ActorExtensionPack/Sound/wav/magicShoot.wav b/res/ActorExtensionPack/Sound/wav/magicShoot.wav
new file mode 100644
index 0000000000000000000000000000000000000000..046162cb0277bca3e6198c55467794ad9d596039
Binary files /dev/null and b/res/ActorExtensionPack/Sound/wav/magicShoot.wav differ
diff --git a/res/ActorExtensionPack/Sound/wav/magicWall.wav b/res/ActorExtensionPack/Sound/wav/magicWall.wav
new file mode 100644
index 0000000000000000000000000000000000000000..486acd327c53ecbbf777b7b47c6e2f190bae25f4
Binary files /dev/null and b/res/ActorExtensionPack/Sound/wav/magicWall.wav differ
diff --git a/res/ActorExtensionPack/Sound/wav/makeScheme.wav b/res/ActorExtensionPack/Sound/wav/makeScheme.wav
new file mode 100644
index 0000000000000000000000000000000000000000..0f5b8f16d45c1f93316f01feae36c7f19ad7cde6
Binary files /dev/null and b/res/ActorExtensionPack/Sound/wav/makeScheme.wav differ
diff --git a/res/ActorExtensionPack/Sound/wav/spiderWalking.wav b/res/ActorExtensionPack/Sound/wav/spiderWalking.wav
new file mode 100644
index 0000000000000000000000000000000000000000..82347420e57008ab52776763ff43fdb34f1d7cf7
Binary files /dev/null and b/res/ActorExtensionPack/Sound/wav/spiderWalking.wav differ
diff --git a/res/ActorExtensionPack/Sound/wav/startScheme.wav b/res/ActorExtensionPack/Sound/wav/startScheme.wav
new file mode 100644
index 0000000000000000000000000000000000000000..4531348856c5e7041d152442e625bf60eb1cae53
Binary files /dev/null and b/res/ActorExtensionPack/Sound/wav/startScheme.wav differ
diff --git a/res/ActorExtensionPack/Sound/wav/teleport2.wav b/res/ActorExtensionPack/Sound/wav/teleport2.wav
new file mode 100644
index 0000000000000000000000000000000000000000..4e4649e6570fcd2c8c9430b37b163f5fa991150e
Binary files /dev/null and b/res/ActorExtensionPack/Sound/wav/teleport2.wav differ
diff --git a/res/ActorExtensionPack/Sound/wav/walking.wav b/res/ActorExtensionPack/Sound/wav/walking.wav
new file mode 100644
index 0000000000000000000000000000000000000000..c065e101cc87501a4321bd04747419e7e10b18f0
Binary files /dev/null and b/res/ActorExtensionPack/Sound/wav/walking.wav differ
diff --git a/res/ActorExtensionPack/Sound/wav/walkingMedium.wav b/res/ActorExtensionPack/Sound/wav/walkingMedium.wav
new file mode 100644
index 0000000000000000000000000000000000000000..5e50919c8ddfaeeee70c9962175b62e6c0b0fb31
Binary files /dev/null and b/res/ActorExtensionPack/Sound/wav/walkingMedium.wav differ
diff --git a/res/ActorExtensionPack/Sound/wav/walkingSlow.wav b/res/ActorExtensionPack/Sound/wav/walkingSlow.wav
new file mode 100644
index 0000000000000000000000000000000000000000..9f0f4a54397f5fc4cf0e16408e4ca6ecb8de6970
Binary files /dev/null and b/res/ActorExtensionPack/Sound/wav/walkingSlow.wav differ
diff --git a/res/ActorExtensionPack/Sound/wav/win.wav b/res/ActorExtensionPack/Sound/wav/win.wav
new file mode 100644
index 0000000000000000000000000000000000000000..9973188b8ff60bd5426a314db00d75a24fd661fc
Binary files /dev/null and b/res/ActorExtensionPack/Sound/wav/win.wav differ
diff --git a/res/ActorExtensionPack/UI/LevelMenu.png b/res/ActorExtensionPack/UI/LevelMenu.png
new file mode 100644
index 0000000000000000000000000000000000000000..0994f439ca291537f2067fcc77b02b24ea22a101
Binary files /dev/null and b/res/ActorExtensionPack/UI/LevelMenu.png differ
diff --git a/res/ActorExtensionPack/UI/Source/UI001.png b/res/ActorExtensionPack/UI/Source/UI001.png
new file mode 100644
index 0000000000000000000000000000000000000000..f2677093b22345f0bfbad3f8094205061b22632f
Binary files /dev/null and b/res/ActorExtensionPack/UI/Source/UI001.png differ
diff --git a/res/ActorExtensionPack/UI/Source/UI001.psd b/res/ActorExtensionPack/UI/Source/UI001.psd
new file mode 100644
index 0000000000000000000000000000000000000000..4af59aa42a64a1375ee7ec630a4c58a064a14046
Binary files /dev/null and b/res/ActorExtensionPack/UI/Source/UI001.psd differ
diff --git a/res/ActorExtensionPack/UI/Source/graphicriver-YCWoU5da-game-ui-pixel-art.zip b/res/ActorExtensionPack/UI/Source/graphicriver-YCWoU5da-game-ui-pixel-art.zip
new file mode 100644
index 0000000000000000000000000000000000000000..089b258eae5a409c12c0c34274d83d5cf4738fc2
Binary files /dev/null and b/res/ActorExtensionPack/UI/Source/graphicriver-YCWoU5da-game-ui-pixel-art.zip differ
diff --git a/res/ActorExtensionPack/UI/bblueButton.png b/res/ActorExtensionPack/UI/bblueButton.png
new file mode 100644
index 0000000000000000000000000000000000000000..4e90001c42fd63b159bd2902d1fd5709d550dd32
Binary files /dev/null and b/res/ActorExtensionPack/UI/bblueButton.png differ
diff --git a/res/ActorExtensionPack/UI/blueButton.png b/res/ActorExtensionPack/UI/blueButton.png
new file mode 100644
index 0000000000000000000000000000000000000000..4019c7251ea17ad0b17644cd22c2a40cc781a1dd
Binary files /dev/null and b/res/ActorExtensionPack/UI/blueButton.png differ
diff --git a/res/ActorExtensionPack/UI/clayButton.png b/res/ActorExtensionPack/UI/clayButton.png
new file mode 100644
index 0000000000000000000000000000000000000000..06ba0615d14335255f3509bb75fdb98480fc1bdf
Binary files /dev/null and b/res/ActorExtensionPack/UI/clayButton.png differ
diff --git a/res/ActorExtensionPack/UI/coin.png b/res/ActorExtensionPack/UI/coin.png
new file mode 100644
index 0000000000000000000000000000000000000000..9499a0349f48350b6ead9077a65c614a3cc8ff6f
Binary files /dev/null and b/res/ActorExtensionPack/UI/coin.png differ
diff --git a/res/ActorExtensionPack/UI/dialogueBox.png b/res/ActorExtensionPack/UI/dialogueBox.png
new file mode 100644
index 0000000000000000000000000000000000000000..ffa6c73ae34ebf8eedce110ff8348e5db3ae0eaf
Binary files /dev/null and b/res/ActorExtensionPack/UI/dialogueBox.png differ
diff --git a/res/ActorExtensionPack/UI/flagl.png b/res/ActorExtensionPack/UI/flagl.png
new file mode 100644
index 0000000000000000000000000000000000000000..657874d0cdbac4ff554bc32e986b6fbaf12c2c90
Binary files /dev/null and b/res/ActorExtensionPack/UI/flagl.png differ
diff --git a/res/ActorExtensionPack/UI/flagm.png b/res/ActorExtensionPack/UI/flagm.png
new file mode 100644
index 0000000000000000000000000000000000000000..69e1795735fee131821e8ccd45376b8b8ce00502
Binary files /dev/null and b/res/ActorExtensionPack/UI/flagm.png differ
diff --git a/res/ActorExtensionPack/UI/flagr.png b/res/ActorExtensionPack/UI/flagr.png
new file mode 100644
index 0000000000000000000000000000000000000000..449d6fd89239d95b1b4c8c852b771125529cd39e
Binary files /dev/null and b/res/ActorExtensionPack/UI/flagr.png differ
diff --git a/res/ActorExtensionPack/UI/hide.png b/res/ActorExtensionPack/UI/hide.png
new file mode 100644
index 0000000000000000000000000000000000000000..7335756615902cae5b9ead918d8b7a1f57d3cb27
Binary files /dev/null and b/res/ActorExtensionPack/UI/hide.png differ
diff --git a/res/ActorExtensionPack/UI/home.png b/res/ActorExtensionPack/UI/home.png
new file mode 100644
index 0000000000000000000000000000000000000000..69a424c8f48b3b0ededed746a7146e6975de7fd3
Binary files /dev/null and b/res/ActorExtensionPack/UI/home.png differ
diff --git a/res/ActorExtensionPack/UI/inventoryLeft.png b/res/ActorExtensionPack/UI/inventoryLeft.png
new file mode 100644
index 0000000000000000000000000000000000000000..07230c6d67d22e00a081ae83b8ec83ac4f372664
Binary files /dev/null and b/res/ActorExtensionPack/UI/inventoryLeft.png differ
diff --git a/res/ActorExtensionPack/UI/inventoryMiddle.png b/res/ActorExtensionPack/UI/inventoryMiddle.png
new file mode 100644
index 0000000000000000000000000000000000000000..dabf9fbcc9889f3802fd5c3dacdf215feeb30047
Binary files /dev/null and b/res/ActorExtensionPack/UI/inventoryMiddle.png differ
diff --git a/res/ActorExtensionPack/UI/inventoryRight.png b/res/ActorExtensionPack/UI/inventoryRight.png
new file mode 100644
index 0000000000000000000000000000000000000000..174bf6a54f089c5896efdebd5ec1c2b9ffaabfe7
Binary files /dev/null and b/res/ActorExtensionPack/UI/inventoryRight.png differ
diff --git a/res/ActorExtensionPack/UI/level.png b/res/ActorExtensionPack/UI/level.png
new file mode 100644
index 0000000000000000000000000000000000000000..9e64a8b42d6e5c3e72ea9f18c7a32c36948542e0
Binary files /dev/null and b/res/ActorExtensionPack/UI/level.png differ
diff --git a/res/ActorExtensionPack/UI/levelBackBottom.png b/res/ActorExtensionPack/UI/levelBackBottom.png
new file mode 100644
index 0000000000000000000000000000000000000000..60b04d3b528ef5b5a6f720ff14bc107b34d91b1a
Binary files /dev/null and b/res/ActorExtensionPack/UI/levelBackBottom.png differ
diff --git a/res/ActorExtensionPack/UI/levelBackMiddle.png b/res/ActorExtensionPack/UI/levelBackMiddle.png
new file mode 100644
index 0000000000000000000000000000000000000000..a982122b8f5d1a6254f5ff4fef6477b42e477587
Binary files /dev/null and b/res/ActorExtensionPack/UI/levelBackMiddle.png differ
diff --git a/res/ActorExtensionPack/UI/levelBackUp.png b/res/ActorExtensionPack/UI/levelBackUp.png
new file mode 100644
index 0000000000000000000000000000000000000000..40d24f8a0eaca740ea2f94a040b822c99be4888c
Binary files /dev/null and b/res/ActorExtensionPack/UI/levelBackUp.png differ
diff --git a/res/ActorExtensionPack/UI/levelButton.png b/res/ActorExtensionPack/UI/levelButton.png
new file mode 100644
index 0000000000000000000000000000000000000000..86d812a776efcf35e9e80bef4431d600b9794f4e
Binary files /dev/null and b/res/ActorExtensionPack/UI/levelButton.png differ
diff --git a/res/ActorExtensionPack/UI/lock.png b/res/ActorExtensionPack/UI/lock.png
new file mode 100644
index 0000000000000000000000000000000000000000..791338a6940aaf4e4e38b5b1ce4215a8102d7d19
Binary files /dev/null and b/res/ActorExtensionPack/UI/lock.png differ
diff --git a/res/ActorExtensionPack/UI/next.png b/res/ActorExtensionPack/UI/next.png
new file mode 100644
index 0000000000000000000000000000000000000000..ff94112660c1263cd9106dab11b1f9b42b9707b0
Binary files /dev/null and b/res/ActorExtensionPack/UI/next.png differ
diff --git a/res/ActorExtensionPack/UI/no.png b/res/ActorExtensionPack/UI/no.png
new file mode 100644
index 0000000000000000000000000000000000000000..4061b8baac7c0901dcb8fbbc5215154e3edc9095
Binary files /dev/null and b/res/ActorExtensionPack/UI/no.png differ
diff --git a/res/ActorExtensionPack/UI/prev.png b/res/ActorExtensionPack/UI/prev.png
new file mode 100644
index 0000000000000000000000000000000000000000..822e79a5eb91959297a5e6f8ff1cc79cde072777
Binary files /dev/null and b/res/ActorExtensionPack/UI/prev.png differ
diff --git a/res/ActorExtensionPack/UI/progressBar/0.png b/res/ActorExtensionPack/UI/progressBar/0.png
new file mode 100644
index 0000000000000000000000000000000000000000..43f2432b281f0b8179d5d2fefcb983afd7d29c2b
Binary files /dev/null and b/res/ActorExtensionPack/UI/progressBar/0.png differ
diff --git a/res/ActorExtensionPack/UI/progressBar/1.png b/res/ActorExtensionPack/UI/progressBar/1.png
new file mode 100644
index 0000000000000000000000000000000000000000..0ae79bf4eff80bdd1932381f2dbcc5f60ef8da92
Binary files /dev/null and b/res/ActorExtensionPack/UI/progressBar/1.png differ
diff --git a/res/ActorExtensionPack/UI/progressBar/2.png b/res/ActorExtensionPack/UI/progressBar/2.png
new file mode 100644
index 0000000000000000000000000000000000000000..ea3d3747f84aecbac259f06ed180816fd261778a
Binary files /dev/null and b/res/ActorExtensionPack/UI/progressBar/2.png differ
diff --git a/res/ActorExtensionPack/UI/progressBar/3.png b/res/ActorExtensionPack/UI/progressBar/3.png
new file mode 100644
index 0000000000000000000000000000000000000000..c79569f75924c656dc9065c3387886cdd2646520
Binary files /dev/null and b/res/ActorExtensionPack/UI/progressBar/3.png differ
diff --git a/res/ActorExtensionPack/UI/progressBar/4.png b/res/ActorExtensionPack/UI/progressBar/4.png
new file mode 100644
index 0000000000000000000000000000000000000000..f174adbe8689e53e8e56cbd3c4f42c0c2fad5122
Binary files /dev/null and b/res/ActorExtensionPack/UI/progressBar/4.png differ
diff --git a/res/ActorExtensionPack/UI/progressBar/5.png b/res/ActorExtensionPack/UI/progressBar/5.png
new file mode 100644
index 0000000000000000000000000000000000000000..c1c0f98a1b08cc5fc3c1568e0726c8c60fa51d9d
Binary files /dev/null and b/res/ActorExtensionPack/UI/progressBar/5.png differ
diff --git a/res/ActorExtensionPack/UI/progressBar/6.png b/res/ActorExtensionPack/UI/progressBar/6.png
new file mode 100644
index 0000000000000000000000000000000000000000..f229b9deb9e639a193b66c5d7799e5c5804cabe6
Binary files /dev/null and b/res/ActorExtensionPack/UI/progressBar/6.png differ
diff --git a/res/ActorExtensionPack/UI/progressBar/7.png b/res/ActorExtensionPack/UI/progressBar/7.png
new file mode 100644
index 0000000000000000000000000000000000000000..7bfe6dac6d7d0126de9fe22f046201f8819d6ff2
Binary files /dev/null and b/res/ActorExtensionPack/UI/progressBar/7.png differ
diff --git a/res/ActorExtensionPack/UI/progressBar/8.png b/res/ActorExtensionPack/UI/progressBar/8.png
new file mode 100644
index 0000000000000000000000000000000000000000..68d842667e6593c63f5b1bc28f7f35a466124fa7
Binary files /dev/null and b/res/ActorExtensionPack/UI/progressBar/8.png differ
diff --git a/res/ActorExtensionPack/UI/progressBar/9.png b/res/ActorExtensionPack/UI/progressBar/9.png
new file mode 100644
index 0000000000000000000000000000000000000000..68d842667e6593c63f5b1bc28f7f35a466124fa7
Binary files /dev/null and b/res/ActorExtensionPack/UI/progressBar/9.png differ
diff --git a/res/ActorExtensionPack/UI/redButton.png b/res/ActorExtensionPack/UI/redButton.png
new file mode 100644
index 0000000000000000000000000000000000000000..46c1105802952c125e54894d3454e2ee371f5891
Binary files /dev/null and b/res/ActorExtensionPack/UI/redButton.png differ
diff --git a/res/ActorExtensionPack/UI/remove.png b/res/ActorExtensionPack/UI/remove.png
new file mode 100644
index 0000000000000000000000000000000000000000..fdb270a174fa7debbf3a5f4f0e42f309741aab26
Binary files /dev/null and b/res/ActorExtensionPack/UI/remove.png differ
diff --git a/res/ActorExtensionPack/UI/removeCancel.png b/res/ActorExtensionPack/UI/removeCancel.png
new file mode 100644
index 0000000000000000000000000000000000000000..c640a14cb4798cedfb449d6acc88eaf1c376b738
Binary files /dev/null and b/res/ActorExtensionPack/UI/removeCancel.png differ
diff --git a/res/ActorExtensionPack/UI/restart.png b/res/ActorExtensionPack/UI/restart.png
new file mode 100644
index 0000000000000000000000000000000000000000..96a6d49aa92a4208d6ccda28b696c4e5ba072292
Binary files /dev/null and b/res/ActorExtensionPack/UI/restart.png differ
diff --git a/res/ActorExtensionPack/UI/selectFrame.png b/res/ActorExtensionPack/UI/selectFrame.png
new file mode 100644
index 0000000000000000000000000000000000000000..a4829d69878f5ba5fb38bdc99440200d55a3f06f
Binary files /dev/null and b/res/ActorExtensionPack/UI/selectFrame.png differ
diff --git a/res/ActorExtensionPack/UI/show.png b/res/ActorExtensionPack/UI/show.png
new file mode 100644
index 0000000000000000000000000000000000000000..1e49210382a92b461d59a6ed271d4d76b3ddb3f8
Binary files /dev/null and b/res/ActorExtensionPack/UI/show.png differ
diff --git a/res/ActorExtensionPack/UI/start.png b/res/ActorExtensionPack/UI/start.png
new file mode 100644
index 0000000000000000000000000000000000000000..efdd606ba70e07f7bf3c2ce381eaaa6c2ae5c9f5
Binary files /dev/null and b/res/ActorExtensionPack/UI/start.png differ
diff --git a/res/ActorExtensionPack/UI/startpage.png b/res/ActorExtensionPack/UI/startpage.png
new file mode 100644
index 0000000000000000000000000000000000000000..4ade3825912a1290bd2aa6db4fd737bf1cabfa1c
Binary files /dev/null and b/res/ActorExtensionPack/UI/startpage.png differ
diff --git a/res/ActorExtensionPack/UI/t.png b/res/ActorExtensionPack/UI/t.png
new file mode 100644
index 0000000000000000000000000000000000000000..3ff1afff4439a206cc4748159bd5209b086d728f
Binary files /dev/null and b/res/ActorExtensionPack/UI/t.png differ
diff --git a/res/ActorExtensionPack/UI/target_invalid.png b/res/ActorExtensionPack/UI/target_invalid.png
new file mode 100644
index 0000000000000000000000000000000000000000..ee3474adf00942d4cf9cf50a43d66e1828a98b80
Binary files /dev/null and b/res/ActorExtensionPack/UI/target_invalid.png differ
diff --git a/res/ActorExtensionPack/UI/target_valid.png b/res/ActorExtensionPack/UI/target_valid.png
new file mode 100644
index 0000000000000000000000000000000000000000..6c59f738762a944f2b0771359278155700a1e292
Binary files /dev/null and b/res/ActorExtensionPack/UI/target_valid.png differ
diff --git a/res/ActorExtensionPack/UI/yes.png b/res/ActorExtensionPack/UI/yes.png
new file mode 100644
index 0000000000000000000000000000000000000000..480c572dd572f43366f0942b12ce5b2148c5059a
Binary files /dev/null and b/res/ActorExtensionPack/UI/yes.png differ
diff --git a/res/VeraMono.ttf b/res/VeraMono.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..139f0b4311ad2e0369a347b3be6c46e6c2b730d5
Binary files /dev/null and b/res/VeraMono.ttf differ
diff --git a/res/conformable.otf b/res/conformable.otf
new file mode 100644
index 0000000000000000000000000000000000000000..52cf623d896c065914bd1b06c0462919b54f6ff3
Binary files /dev/null and b/res/conformable.otf differ
diff --git a/res/credit.txt b/res/credit.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f6f02fb54d9f5584a2a3ffa6f5fff2c06a09b5e9
--- /dev/null
+++ b/res/credit.txt
@@ -0,0 +1,5 @@
+Tree: https://opengameart.org/content/tree-9
+Grass: https://opengameart.org/content/grass-tiles-0
+Cherry: https://opengameart.org/content/four-pixel-fruits (shiru8bit)
+Fence + signs: https://opengameart.org/content/greenlands-tile-set-orthographic
+Puddle: https://opengameart.org/content/puddle-corpses
\ No newline at end of file
diff --git a/res/images/background.png b/res/images/background.png
new file mode 100644
index 0000000000000000000000000000000000000000..a6601996a24eebf1b568ad8e05d2e137a030b52e
Binary files /dev/null and b/res/images/background.png differ
diff --git a/res/images/cherries.png b/res/images/cherries.png
new file mode 100644
index 0000000000000000000000000000000000000000..5fe12c125756f01c2c2f0e4fe3959cf7ab1e6941
Binary files /dev/null and b/res/images/cherries.png differ
diff --git a/res/images/down.png b/res/images/down.png
new file mode 100644
index 0000000000000000000000000000000000000000..5a822d1b4cdd3770c6c0a354d77ee67a40ea88f3
Binary files /dev/null and b/res/images/down.png differ
diff --git a/res/images/fence.png b/res/images/fence.png
new file mode 100644
index 0000000000000000000000000000000000000000..b29aa3375869f3bd3bacc4ff4d49fc031d0e7898
Binary files /dev/null and b/res/images/fence.png differ
diff --git a/res/images/gatherer.png b/res/images/gatherer.png
new file mode 100644
index 0000000000000000000000000000000000000000..f5cbb64ea2886c01dd62a25efef2be4bdbf0c227
Binary files /dev/null and b/res/images/gatherer.png differ
diff --git a/res/images/gold-tree.png b/res/images/gold-tree.png
new file mode 100644
index 0000000000000000000000000000000000000000..c110136f71240b7d8dbc44f6b3adf0eb3c712e22
Binary files /dev/null and b/res/images/gold-tree.png differ
diff --git a/res/images/hoard.png b/res/images/hoard.png
new file mode 100644
index 0000000000000000000000000000000000000000..52092e88e55fbb2eed0e382b1f56cd388b791d08
Binary files /dev/null and b/res/images/hoard.png differ
diff --git a/res/images/left.png b/res/images/left.png
new file mode 100644
index 0000000000000000000000000000000000000000..4145701234a3d05ee463d0caa4bccf1cfdf1cf5f
Binary files /dev/null and b/res/images/left.png differ
diff --git a/res/images/pad.png b/res/images/pad.png
new file mode 100644
index 0000000000000000000000000000000000000000..4df34cb2b7bca3caaa4f3d2ddaabdf8642e34e6d
Binary files /dev/null and b/res/images/pad.png differ
diff --git a/res/images/pool.png b/res/images/pool.png
new file mode 100644
index 0000000000000000000000000000000000000000..b6828384f3f9e64a78620bd2d8215b6a949a0b84
Binary files /dev/null and b/res/images/pool.png differ
diff --git a/res/images/right.png b/res/images/right.png
new file mode 100644
index 0000000000000000000000000000000000000000..b385f325c4f48379aa5d92acd9df036f002bbbbd
Binary files /dev/null and b/res/images/right.png differ
diff --git a/res/images/thief.png b/res/images/thief.png
new file mode 100644
index 0000000000000000000000000000000000000000..a5d15154c65b74a324a56ebb4caeeda0f885d4f6
Binary files /dev/null and b/res/images/thief.png differ
diff --git a/res/images/tree.png b/res/images/tree.png
new file mode 100644
index 0000000000000000000000000000000000000000..b055ab043bb0b72e2839cdeef1aebcb12175e547
Binary files /dev/null and b/res/images/tree.png differ
diff --git a/res/images/up.png b/res/images/up.png
new file mode 100644
index 0000000000000000000000000000000000000000..b772ce7c5d159e08044e5575733b49b9ed4b9e5f
Binary files /dev/null and b/res/images/up.png differ
diff --git a/res/levelGenerateData.txt b/res/levelGenerateData.txt
new file mode 100644
index 0000000000000000000000000000000000000000..dec2bf5d6199c7cd0d84f3dc1e76a73ccc336302
--- /dev/null
+++ b/res/levelGenerateData.txt
@@ -0,0 +1 @@
+19
\ No newline at end of file
diff --git a/res/worlds/harvest.csv b/res/worlds/harvest.csv
new file mode 100644
index 0000000000000000000000000000000000000000..4b430f5538b6f37678670779b8b39e5228a883e8
--- /dev/null
+++ b/res/worlds/harvest.csv
@@ -0,0 +1,4 @@
+Tree,384,384
+Stockpile,768,384
+Gatherer,512,384
+Fence,256,384
\ No newline at end of file
diff --git a/res/worlds/product.csv b/res/worlds/product.csv
new file mode 100644
index 0000000000000000000000000000000000000000..f4e42d74a5b7d2195d7f403e612df5f3d6bb7134
--- /dev/null
+++ b/res/worlds/product.csv
@@ -0,0 +1,36 @@
+SignRight,256,0
+Pad,320,0
+Fence,192,0
+SignDown,128,64
+SignRight,128,512
+Stockpile,192,192
+SignUp,256,192
+Hoard,256,128
+SignDown,384,128
+SignRight,384,512
+SignUp,448,512
+SignUp,448,384
+Pad,448,448
+Hoard,448,192
+Hoard,448,64
+GoldenTree,512,64
+SignLeft,512,384
+SignUp,192,512
+Hoard,640,64
+Fence,0,192
+Tree,64,192
+Tree,576,192
+Tree,640,192
+SignLeft,640,512
+SignDown,448,0
+Fence,960,192
+SignLeft,896,0
+Pad,896,128
+SignDown,832,128
+Gatherer,192,192
+Gatherer,512,192
+Thief,0,704
+SignRight,0,256
+SignDown,64,256
+SignRight,64,640
+SignUp,192,640
diff --git a/res/worlds/sum.csv b/res/worlds/sum.csv
new file mode 100644
index 0000000000000000000000000000000000000000..110e2cb2aa7c09d2c7e4165b261bbb8b122a5d14
--- /dev/null
+++ b/res/worlds/sum.csv
@@ -0,0 +1,18 @@
+Fence,384,64
+Fence,64,128
+Tree,128,128
+Gatherer,256,128
+Stockpile,384,128
+Fence,0,192
+Tree,64,192
+Tree,128,192
+Gatherer,256,192
+Stockpile,384,192
+SignUp,384,576
+Hoard,512,128
+SignRight,512,64
+SignDown,576,64
+SignDown,576,128
+SignLeft,576,576
+SignUp,512,192
+Thief,384,704
diff --git a/res/worlds/test.csv b/res/worlds/test.csv
new file mode 100644
index 0000000000000000000000000000000000000000..cf3e49a620cdac65f121212dd4caf2cf057e6d65
--- /dev/null
+++ b/res/worlds/test.csv
@@ -0,0 +1 @@
+Knight,384,384
\ No newline at end of file
diff --git a/src/Animation/Animation.java b/src/Animation/Animation.java
new file mode 100644
index 0000000000000000000000000000000000000000..719d78596b2e70eea07280ea051d6a2c5f0ddb0d
--- /dev/null
+++ b/src/Animation/Animation.java
@@ -0,0 +1,59 @@
+package Animation;
+
+import myUtil.Vec2D;
+import bagel.Drawing;
+import bagel.Image;
+
+import java.util.ArrayList;
+
+public class Animation {
+
+    private static final int FRAME_REFRESH_TICK = 200;
+    private static final int RESET = 0;
+
+    private ArrayList<Image> animation;
+
+    private long previousTime;
+    private int elapsedTime;
+
+    private int frame;
+
+    public Animation() {
+        animation = new ArrayList<Image>();
+        elapsedTime = RESET;
+        previousTime = System.currentTimeMillis();
+        frame = 0;
+    }
+
+    public void addFrame(Image frame) {
+        animation.add(frame);
+    }
+
+    public void replay() {
+        frame = 0;
+    }
+
+    public void playAt(Vec2D position) {
+        animation.get(frame).drawFromTopLeft(position.x, position.y);
+        if (notTick()) {
+            return;
+        }
+        frame++;
+        frame = frame % animation.size();
+    }
+
+    private boolean notTick() {
+        //calculate elapsed time
+        long currentTime = System.currentTimeMillis();
+        elapsedTime += currentTime - previousTime;
+        previousTime = currentTime;
+
+        //check for tick
+        if (elapsedTime <= FRAME_REFRESH_TICK) {
+            return true;
+        }
+        //reset elapsedTime
+        elapsedTime = RESET;
+        return false;
+    }
+}
diff --git a/src/Animation/AnimationStateManager.java b/src/Animation/AnimationStateManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..d0bef7371737efc3fed59ba1beafd105c9bbfe62
--- /dev/null
+++ b/src/Animation/AnimationStateManager.java
@@ -0,0 +1,26 @@
+package Animation;
+
+import myUtil.Vec2D;
+
+import java.util.ArrayList;
+
+public class AnimationStateManager {
+    ArrayList<Animation> animations;
+    Animation current;
+
+    public AnimationStateManager() {
+        animations = new ArrayList<Animation>();
+    }
+
+    public void add(Animation animation) {
+        animations.add(animation);
+    }
+
+    public void toState(int state) {
+        current = animations.get(state);
+    }
+
+    public void playAt(Vec2D position) {
+        current.playAt(position);
+    }
+}
diff --git a/src/Level/BeginnerPanel.java b/src/Level/BeginnerPanel.java
new file mode 100644
index 0000000000000000000000000000000000000000..27c6fbf509ded6cf665818e2c0befd6a7c99b341
--- /dev/null
+++ b/src/Level/BeginnerPanel.java
@@ -0,0 +1,71 @@
+package Level;
+
+import Listener.MouseListener;
+import UI.Pane;
+import UI.TextBox;
+import bagel.Image;
+import bagel.util.Colour;
+import myUtil.Vec2D;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+
+public class BeginnerPanel extends Pane {
+    private int dialogBox;
+
+    private String filename;
+
+    private ArrayList<String> content;
+
+    private int currentIndex;
+
+    TextBox textBox = new TextBox("", 600, new Vec2D(220, 120), Colour.WHITE);
+
+    private Vec2D position = new Vec2D(50, 50);
+
+    public BeginnerPanel(String filename) {
+        super();
+        this.filename = filename;
+        currentIndex = 0;
+        content = new ArrayList<>();
+        load();
+    }
+
+    public void load() {
+        dialogBox = add(new Image("res/ActorExtensionPack/UI/dialogueBox.png"));
+
+        try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
+            String line;
+            while ((line = br.readLine()) != null) {
+                content.add(line);
+            }
+
+        } catch (IOException e) {
+            System.err.println(e);
+        }
+    }
+    private static final int FONT_SIZE = 40;
+    @Override
+    public void display() {
+        getSource().get(dialogBox).drawFromTopLeft(position.x, position.y);
+
+        textBox.setStr(content.get(currentIndex));
+        textBox.setFontSize(FONT_SIZE);
+        textBox.display();
+    }
+
+    public boolean response() {
+        currentIndex++;
+        if (currentIndex == content.size()) {
+            return false;
+        }
+        return true;
+    }
+
+    public BeginnerPanel clone() {
+        BeginnerPanel newBeginnerPanel = new BeginnerPanel(filename);
+        return newBeginnerPanel;
+    }
+}
diff --git a/src/Level/Dialogue.java b/src/Level/Dialogue.java
new file mode 100644
index 0000000000000000000000000000000000000000..a315bd37481ebf80ce375d37546d39fc5b035d23
--- /dev/null
+++ b/src/Level/Dialogue.java
@@ -0,0 +1,4 @@
+package Level;
+
+public class Dialogue {
+}
diff --git a/src/Level/EndPanel.java b/src/Level/EndPanel.java
new file mode 100644
index 0000000000000000000000000000000000000000..068b7d03126e67a951eb9d86493223e27d667049
--- /dev/null
+++ b/src/Level/EndPanel.java
@@ -0,0 +1,64 @@
+package Level;
+
+import Music.MusicPlayer;
+import Music.MusicPlayerManager;
+import Page.GameStage;
+import UI.Pane;
+import UI.TextBox;
+import bagel.Image;
+import bagel.util.Colour;
+import myUtil.Vec2D;
+
+public class EndPanel extends Pane {
+    Level castToLevel;
+
+    private int upPart;
+    private int middlePart;
+    private int bottomPart;
+
+    private static final Vec2D UP_POSITION = new Vec2D(220, 200);
+    private static final Vec2D MIDDLE_POSITION1 = new Vec2D(220, 300);
+    private static final Vec2D MIDDLE_POSITION2 = new Vec2D(220, 400);
+    private static final Vec2D BOTTOM_POSITION = new Vec2D(220, 500);
+
+    private int deadSound;
+
+    public EndPanel(Level castToLevel) {
+        this.castToLevel = castToLevel;
+        deadSound = MusicPlayerManager.getInstance().addMusic(new MusicPlayer("res/ActorExtensionPack/Sound/wav/DeadSound.wav"));
+    }
+
+    private final static int TITLE_SIZE = 100;
+
+    TextBox title = new TextBox("...", 1000, new Vec2D(150,380), Colour.WHITE);
+
+    private boolean playSound = false;
+
+    @Override
+    public void display() {
+        if (!playSound) {
+            MusicPlayerManager.getInstance().stopAll();
+            if (castToLevel.state == Level.WIN) {
+                MusicPlayerManager.getInstance().playMixed(GameStage.wining, MusicPlayer.NONE);
+            } else if (castToLevel.state == Level.LOSE) {
+                MusicPlayerManager.getInstance().playMixed(deadSound, MusicPlayer.NONE);
+                MusicPlayerManager.getInstance().playMixed(GameStage.lose, MusicPlayer.NONE);
+
+            }
+            playSound = true;
+        }
+        if (castToLevel.state == Level.WIN) {
+            title.setStr("         WIN");
+        } else {
+            title.setStr("        LOSE");
+        }
+
+        title.setFontSize(TITLE_SIZE);
+
+        title.display();
+    }
+
+    public void setPlaySound(boolean playSound) {
+        this.playSound = playSound;
+    }
+}
diff --git a/src/Level/Level.java b/src/Level/Level.java
new file mode 100644
index 0000000000000000000000000000000000000000..a70881ae5ebb33632bdbe03702c7ed1cd8c87aff
--- /dev/null
+++ b/src/Level/Level.java
@@ -0,0 +1,576 @@
+package Level;
+
+import Listener.MouseListener;
+import Music.MusicPlayer;
+import Music.MusicPlayerManager;
+import Page.GameStage;
+import UI.Button;
+import actor.*;
+import bagel.Image;
+import myUtil.MyMath;
+import myUtil.Vec2D;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+public class Level {
+    public static  final int TILED_LENGTH = 64;
+    public static  final int HALF_TILED_LENGTH = 32;
+    //map identifier
+    public static final String DUNGEON = "Dungeon";
+    public static final String GRASS = "Grass";
+
+    //stage identifier
+    private static final int BEGINNER_STAGE = -1;
+    private static final int SELECT_STAGE = 0;
+    private static final int SIMULATION_STAGE = 1;
+    private static final int END_STAGE = 2;
+
+    //actor identifier
+    protected static final String KNIGHT = "Knight";
+    protected static final String SKELETON = "Skeleton";
+    protected static final String HORIZON = "Horizon";
+    protected static final String VERTICAL = "Vertical";
+    protected static final String WALL_MAKER = "WallMaker";
+    protected static final String TRAP = "Trap";
+    protected static final String SKULL = "Skull";
+    protected static final String PORTAL = "Portal";
+    protected static final String WITCH = "Witch";
+    protected static final String CHEST = "Chest";
+    protected static final String SPIDER = "Spider";
+    protected static final String SIGN_UP = "SignUp";
+    protected static final String SIGN_DOWN = "SignDown";
+    protected static final String SIGN_LEFT = "SignLeft";
+    protected static final String SIGN_RIGHT = "SignRight";
+
+    //indexing for csv reader
+    private final int actorName = 0;
+    private final int actorX = 1;
+    private final int actorY = 2;
+    private final int extraActorX = 3;
+    private final int extraActorY = 4;
+    private final int extraInfo0 = 3;
+    private final int extraInfo1 = 4;
+    private final int extraInfo2 = 2;
+
+    //refreshRate
+    public static final int STEP_REFRESH = 63;
+    public static final int HALF_REFRESH = 31;
+
+    public static final int OK = 0;
+
+    //Direction constant
+    protected static final int UP = 0;
+    protected static final int RIGHT = 1;
+    protected static final int DOWN = 2;
+    protected static final int LEFT = 3;
+
+    private int currentStage;
+    private Image worldMap;
+    private ArrayList<Actor> actors;
+    private ArrayList<Actor> pending;
+
+    private String worldType;
+    private String filename;
+    private boolean[] playMode;
+
+    public static final int WIN = 1;
+    public static final int CONTINUING = 0;
+    public static final int LOSE = -1;
+
+    protected int state = CONTINUING;
+
+    SelectPanel selectPanel;
+    EndPanel endPanel;
+
+    private BeginnerPanel beginnerPanel;
+
+    private boolean hasBeginnerPanel = false;
+
+    Button restartButton = new Button(new Image("res/ActorExtensionPack/UI/restart.png"), new Vec2D(817, 0)) {
+        @Override
+        public void event() {
+            if (currentStage != SELECT_STAGE) {
+                restart();
+            }
+        }
+    };
+    Button startButton = new Button(new Image("res/ActorExtensionPack/UI/start.png"), new Vec2D(885, 0)) {
+        @Override
+        public void event() {
+            if (currentStage != SIMULATION_STAGE) {
+                currentStage = SIMULATION_STAGE;
+            }
+            for (Actor inputActor : selectPanel.planning) {
+                actors.add(inputActor.clone());
+            }
+        }
+    };
+    Button homeButton = new Button(new Image("res/ActorExtensionPack/UI/home.png"), new Vec2D(955, 0)) {
+        @Override
+        public void event() {
+            MusicPlayerManager.getInstance().stopAll();
+            GameStage.getInstance().goTo(GameStage.START_PAGE + GameStage.LOADING);
+            actors.clear();
+            currentStage = SELECT_STAGE;
+            selectPanel.planning.clear();
+        }
+    };
+
+    private String beginnerFilename;
+
+    public Level(String worldType, String filename, String beginnerFilename, boolean[] playMode) {
+        this.worldType = worldType;
+        //initialize map skin
+        if (worldType.equals(DUNGEON)) {
+            worldMap = new Image("res/ActorExtensionPack/Map/DungeonMap.png");
+        } else if (worldType.equals(GRASS)) {
+            worldMap = new Image("res/images/background.png");
+        }
+
+        //initialize stage
+        currentStage = BEGINNER_STAGE;
+
+        //initialize actor
+        actors = new ArrayList<>();
+        pending = new ArrayList<>();
+
+        endPanel = new EndPanel(this);
+
+        this.beginnerFilename = beginnerFilename;
+
+        this.playMode = playMode;
+
+        this.filename = filename;
+
+        loadCSV(filename);
+
+        hasBeginnerPanel = true;
+
+        selectPanel = new SelectPanel(this, playMode);
+
+        beginnerPanel = new BeginnerPanel(beginnerFilename);
+    }
+
+    public Level(String worldType, String filename, boolean[] playMode) {
+        this.worldType = worldType;
+        //initialize map skin
+        if (worldType.equals(DUNGEON)) {
+            worldMap = new Image("res/ActorExtensionPack/Map/DungeonMap.png");
+        } else if (worldType.equals(GRASS)) {
+            worldMap = new Image("res/images/background.png");
+        }
+
+        //initialize stage
+        currentStage = SELECT_STAGE;
+
+        //initialize actor
+        actors = new ArrayList<>();
+        pending = new ArrayList<>();
+
+        endPanel = new EndPanel(this);
+
+        this.playMode = playMode;
+
+        this.filename = filename;
+
+        loadCSV(filename);
+
+        selectPanel = new SelectPanel(this, playMode);
+    }
+
+    public void update(float frameInUnit) {
+        if (currentStage == BEGINNER_STAGE) {
+            displayAll();
+            selectPanel.display();
+            beginnerPanel.display();
+            if (MouseListener.getInstance().leftClick()) {
+                if (!beginnerPanel.response()) {
+                    currentStage = SELECT_STAGE;
+                }
+            }
+        } else if (currentStage == SELECT_STAGE) {
+            displayAll();
+            selectUpdate();
+            selectPanel.event();
+
+            startButton.display();
+            homeButton.display();
+
+            startButton.onClick();
+            homeButton.onClick();
+        } else if (currentStage == SIMULATION_STAGE) {
+            for (Actor target : actors) {
+                target.setMoving(true);
+            }
+            simulationUpdate(frameInUnit);
+            if (state == WIN || state == LOSE) {
+                currentStage = END_STAGE;
+            }
+
+            restartButton.display();
+            homeButton.display();
+
+            restartButton.onClick();
+            homeButton.onClick();
+        } else if (currentStage == END_STAGE) {
+            displayAll();
+            endPanel.display();
+            if (state == LOSE || this instanceof MakeLevel) {
+                restartButton.onClick();
+                restartButton.display();
+            }
+        }
+    }
+
+    private int endCheck() {
+        int checkState = CONTINUING;
+        for (Actor actor : actors) {
+            if (actor instanceof Knight) {
+                if (((Knight) actor).isCarrying()) {
+                    state = WIN;
+                }
+                if (actor.isDestroyed()) {
+                    state = LOSE;
+                }
+            }
+        }
+        return state;
+    }
+
+    private void selectUpdate() {
+        selectPanel.display();
+    }
+
+    private void simulationUpdate(float frameInUnit) {
+        for (Actor target : actors) {
+            target.animationUpdate();
+        }
+        if (frameInUnit == HALF_REFRESH) {
+            for (Actor target : actors) {
+                if (target instanceof Projectile) {
+                    target.behavior();
+                }
+            }
+            applyProjectileInteraction();
+        }
+        if (frameInUnit == STEP_REFRESH) {
+            for (Actor target : actors) {
+                target.behavior();
+            }
+            applyInteraction();
+            applyProjectileInteraction();
+        }
+
+        state = endCheck();
+        Collection<Actor> list = actors;;
+        list.removeIf(actor -> actor.isDestroyed());
+
+        actors.addAll(pending);
+        pending.clear();
+
+        Collections.sort(actors);
+
+        displayAll();
+    }
+
+    private void displayAll() {
+        //display background
+        worldMap.drawFromTopLeft(0,0);
+        //update Animation
+        for (Actor target : actors) {
+            target.animationUpdate();
+        }
+        //display actor
+        for (Actor target : actors) {
+            target.display();
+        }
+    }
+
+    private void applyInteraction() {
+        for (Actor actor : actors) {
+            for (Actor target : actors) {
+                if (actor != target && actor.getPosition().equals(target.getPosition()) && !(target instanceof Projectile)) {
+                    target.onInteract(actor);
+                }
+            }
+        }
+    }
+
+    private void applyProjectileInteraction() {
+        for (Actor projectile : actors) {
+            if (projectile instanceof  Projectile) {
+                for (Actor target : actors) {
+                    if (projectile.getPosition().equals(target.getPosition())) {
+                        projectile.onInteract(target);
+                    }
+                }
+            }
+        }
+    }
+
+    public void loadCSV(String filename) {
+        String line = "";
+
+        try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
+            int lineNum = 1;
+            while ((line = br.readLine()) != null) {
+                String[] actorInfo = line.split(",");
+
+                //check for actor type and add to actor list
+                if (actorInfo[actorName].equals(KNIGHT)) {
+                    readKnight(actorInfo, filename, lineNum);
+                } else if (actorInfo[actorName].equals(SKELETON)) {
+                    readSkeleton(actorInfo, filename, lineNum);
+                } else if (actorInfo[actorName].equals(WALL_MAKER)) {
+                    readWallMaker(actorInfo, filename, lineNum);
+                } else if (actorInfo[actorName].equals(TRAP)) {
+                    readTrap(actorInfo, filename, lineNum);
+                } else if (actorInfo[actorName].equals(SKULL)) {
+                    readSkull(actorInfo, filename, lineNum);
+                } else if (actorInfo[actorName].equals(PORTAL)) {
+                    readPortal(actorInfo, filename, lineNum);
+                } else if (actorInfo[actorName].equals(WITCH)) {
+                    readWitch(actorInfo, filename, lineNum);
+                } else if (actorInfo[actorName].equals(CHEST)) {
+                    readChest(actorInfo, filename, lineNum);
+                } else if (actorInfo[actorName].equals(SPIDER)) {
+                    readSpider(actorInfo, filename, lineNum);
+                } else if (actorInfo[actorName].equals(SIGN_UP)) {
+                    readSign(actorInfo, filename, lineNum, UP);
+                }  else if (actorInfo[actorName].equals(SIGN_DOWN)) {
+                    readSign(actorInfo, filename, lineNum, DOWN);
+                }  else if (actorInfo[actorName].equals(SIGN_LEFT)) {
+                    readSign(actorInfo, filename, lineNum, LEFT);
+                }  else if (actorInfo[actorName].equals(SIGN_RIGHT)) {
+                    readSign(actorInfo, filename, lineNum, RIGHT);
+                }  else {
+                    System.out.println("error: in file \"" + filename +"\" at line " + lineNum);
+                    System.exit(-1);
+                }
+                lineNum++;
+            }
+
+        } catch (IOException e) {
+            System.out.println("error: file \"" + filename + "\" not found");
+            System.exit(-1);
+        }
+
+    }
+
+    public void add(Actor actor) {
+        Collections.sort(actors);
+        actors.add(actor);
+    }
+
+    public void pend(Actor actor) {
+        pending.add(actor);
+    }
+
+    private void readKnight(String[] actorInfo, String filename, int lineNum) {
+        //check spawn point
+        Vec2D spawnPoint = new Vec2D();
+        spawnPoint.set(checkInt(actorInfo[actorX], filename, lineNum) * TILED_LENGTH,
+                checkInt(actorInfo[actorY], filename, lineNum) * TILED_LENGTH);
+        //add actor
+        add(new Knight(spawnPoint));
+
+    }
+
+    private void readTrap(String[] actorInfo, String filename, int lineNum) {
+        //check spawn point
+        Vec2D spawnPoint = new Vec2D();
+        spawnPoint.set(checkInt(actorInfo[actorX], filename, lineNum) * TILED_LENGTH,
+                checkInt(actorInfo[actorY], filename, lineNum) * TILED_LENGTH);
+        //add actor
+        add(new Trap(spawnPoint, checkInt(actorInfo[extraInfo0], filename, lineNum)));
+
+    }
+
+    private void readChest(String[] actorInfo, String filename, int lineNum) {
+        //check spawn point
+        Vec2D spawnPoint = new Vec2D();
+        spawnPoint.set(checkInt(actorInfo[actorX], filename, lineNum) * TILED_LENGTH,
+                checkInt(actorInfo[actorY], filename, lineNum) * TILED_LENGTH);
+        //add actor
+        add(new Chest(spawnPoint));
+
+    }
+
+    private void readSign(String[] actorInfo, String filename, int lineNum, int direction) {
+        //check spawn point
+        Vec2D spawnPoint = new Vec2D();
+        spawnPoint.set(checkInt(actorInfo[actorX], filename, lineNum) * TILED_LENGTH,
+                checkInt(actorInfo[actorY], filename, lineNum) * TILED_LENGTH);
+        //add actor
+        add(new Sign(spawnPoint, direction));
+
+    }
+
+    private void readWallMaker(String[] actorInfo, String filename, int lineNum) {
+        //check spawn point
+        Vec2D spawnPoint1 = new Vec2D();
+        Vec2D spawnPoint2 = new Vec2D();
+        spawnPoint1.set(checkInt(actorInfo[actorX], filename, lineNum) * TILED_LENGTH,
+                checkInt(actorInfo[actorY], filename, lineNum) * TILED_LENGTH);
+        spawnPoint2.set(checkInt(actorInfo[extraActorX], filename, lineNum) * TILED_LENGTH,
+                checkInt(actorInfo[extraActorY], filename, lineNum) * TILED_LENGTH);
+        //add wall maker
+        Actor wallMaker1 = new WallMaker(spawnPoint1);
+        Actor wallMaker2 = new WallMaker(spawnPoint2, ((WallMaker) wallMaker1).getRelateID());
+        add(wallMaker1);
+        add(wallMaker2);
+        //add lightning
+        float start = MyMath.min(spawnPoint1.x, spawnPoint2.x);
+        int lightningType = Lightning.HORIZON;
+        float end = MyMath.max(spawnPoint1.x, spawnPoint2.x);
+
+        if (spawnPoint1.x == spawnPoint2.x) {
+            start = MyMath.min(spawnPoint1.y, spawnPoint2.y);
+            lightningType = Lightning.VERTICAL;
+            end = MyMath.max(spawnPoint1.y, spawnPoint2.y);
+        }
+
+        for (int i = (int) (start + TILED_LENGTH); i < end; i += TILED_LENGTH) {
+            if (lightningType == Lightning.VERTICAL) {
+                add(new Lightning(new Vec2D(spawnPoint1.x, i), lightningType, ((WallMaker) wallMaker1).getRelateID()));
+            } else if (lightningType == Lightning.HORIZON) {
+                add(new Lightning(new Vec2D(i, spawnPoint1.y), lightningType, ((WallMaker) wallMaker1).getRelateID()));
+            }
+        }
+    }
+
+    private void readPortal(String[] actorInfo, String filename, int lineNum) {
+        //check spawn point
+        Vec2D spawnPoint1 = new Vec2D();
+        Vec2D spawnPoint2 = new Vec2D();
+        spawnPoint1.set(checkInt(actorInfo[actorX], filename, lineNum) * TILED_LENGTH,
+                checkInt(actorInfo[actorY], filename, lineNum) * TILED_LENGTH);
+        spawnPoint2.set(checkInt(actorInfo[extraActorX], filename, lineNum) * TILED_LENGTH,
+                checkInt(actorInfo[extraActorY], filename, lineNum) * TILED_LENGTH);
+        //add wall maker
+
+        add(new Portal(spawnPoint1, spawnPoint2, this));
+    }
+
+    private void readSkeleton(String[] actorInfo, String filename, int lineNum) {
+        //check spawn point
+        Vec2D spawnPoint = new Vec2D();
+        spawnPoint.set(checkInt(actorInfo[actorX], filename, lineNum) * TILED_LENGTH,
+                checkInt(actorInfo[actorY], filename, lineNum) * TILED_LENGTH);
+
+        //add attribute
+        add(new Skeleton(spawnPoint, checkInt(actorInfo[extraInfo0], filename, lineNum), checkInt(actorInfo[extraInfo1], filename, lineNum)));
+    }
+
+    private void readSpider(String[] actorInfo, String filename, int lineNum) {
+        //check spawn point
+        Vec2D spawnPoint = new Vec2D();
+        spawnPoint.set(checkInt(actorInfo[actorX], filename, lineNum) * TILED_LENGTH,
+                checkInt(actorInfo[actorY], filename, lineNum) * TILED_LENGTH);
+
+        //add attribute
+        add(new Spider(spawnPoint, checkInt(actorInfo[extraInfo0], filename, lineNum), checkInt(actorInfo[extraInfo1], filename, lineNum), checkInt(actorInfo[extraInfo2], filename, lineNum)));
+    }
+
+    private void readSkull(String[] actorInfo, String filename, int lineNum) {
+        //check spawn point
+        Vec2D spawnPoint = new Vec2D();
+        spawnPoint.set(checkInt(actorInfo[actorX], filename, lineNum) * TILED_LENGTH,
+                checkInt(actorInfo[actorY], filename, lineNum) * TILED_LENGTH);
+
+        //add attribute
+        Actor skull  = new Skull(spawnPoint, checkInt(actorInfo[extraInfo0], filename, lineNum), checkInt(actorInfo[extraInfo1], filename, lineNum));
+        ((Skull) skull).setCastToLevel(this);
+        add(skull);
+
+    }
+
+    private void readWitch(String[] actorInfo, String filename, int lineNum) {
+        //check spawn point
+        Vec2D spawnPoint = new Vec2D();
+        spawnPoint.set(checkInt(actorInfo[actorX], filename, lineNum) * TILED_LENGTH,
+                checkInt(actorInfo[actorY], filename, lineNum) * TILED_LENGTH);
+
+        //add attribute
+        Actor witch  = new Witch(spawnPoint, checkInt(actorInfo[extraInfo0], filename, lineNum), checkInt(actorInfo[extraInfo1], filename, lineNum));
+        ((Witch) witch).setCastToLevel(this);
+        add(witch);
+
+    }
+
+    private int checkInt(String integer, String filename, int lineNum) {
+        int result = 0;
+        try {
+            result = Integer.parseInt(integer);
+        } catch (ArrayIndexOutOfBoundsException e) {
+            System.out.println("error: in file \"" + filename +"\" at line " + lineNum);
+            System.exit(-1);
+        } catch (NumberFormatException e) {
+            System.out.println("error: in file \"" + filename +"\" at line " + lineNum);
+            System.exit(-1);
+        }
+        return result;
+    }
+
+    public ArrayList<Actor> getActors() {
+        return actors;
+    }
+
+    public void restart() {
+        actors.clear();
+        currentStage = SELECT_STAGE;
+        state = CONTINUING;
+        MusicPlayerManager.getInstance().stopAll();
+        MusicPlayerManager.getInstance().playSingleTrack(GameStage.playMusic, MusicPlayer.LOOP_OPTION);
+        endPanel.setPlaySound(false);
+        loadCSV(filename);
+        Collection<Actor> list = actors;;
+        list.removeIf(actor -> actor instanceof Sign);
+    }
+     public Level clone() {
+        Level newLevel = null;
+        if (hasBeginnerPanel) {
+            newLevel = new Level(worldType, filename, beginnerFilename, playMode);
+        } else {
+            newLevel = new Level(worldType, filename, playMode);
+        }
+        return newLevel;
+     }
+
+    public String getWorldType() {
+        return worldType;
+    }
+
+    public String getFilename() {
+        return filename;
+    }
+
+    public boolean[] getPlayMode() {
+        return playMode;
+    }
+
+    public ArrayList<Actor> getPending() {
+        return pending;
+    }
+
+    public SelectPanel getSelectPanel() {
+        return selectPanel;
+    }
+
+    public int getState() {
+        return state;
+    }
+
+    public void setBeginnerPanel(BeginnerPanel beginnerPanel) {
+        this.beginnerPanel = beginnerPanel;
+    }
+
+    public void setCurrentStage(int currentStage) {
+        this.currentStage = currentStage;
+    }
+}
diff --git a/src/Level/LevelManager.java b/src/Level/LevelManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..9a72d6c4b979207b5ad15783cc0d91e7cc298f13
--- /dev/null
+++ b/src/Level/LevelManager.java
@@ -0,0 +1,46 @@
+package Level;
+
+import java.util.ArrayList;
+
+public class LevelManager {
+    private static LevelManager levelManager = null;
+
+    ArrayList<Level> levels = new ArrayList<Level>();
+
+    private static final String[] levelName = {"Easy", "Skeleton", "More Skeleton", "Spider", "Seapider", "MagicTower",
+    "Portal", "Where am I", "Watch out", "Feet with Holes", "Fire Bone", "Bones", "Magic", "Meteor Shower"
+    , "Monster Party"};
+
+    public static final boolean[] PLAYING_INVENTORY = {false, false, false, false, false, false, false, false, true, true, true, true, false};
+    public static final boolean[] MAKING_INVENTORY = {true, true, true, true, true, true, true, true, true, true, true, true, true};
+
+    private LevelManager() {
+        levels.add(new Level(Level.DUNGEON, "res/ActorExtensionPack/Level/Easy.csv", "res/ActorExtensionPack/Level/Easy.txt", PLAYING_INVENTORY));
+        levels.add(new Level(Level.DUNGEON, "res/ActorExtensionPack/Level/Skeleton.csv", "res/ActorExtensionPack/Level/Skeleton.txt", PLAYING_INVENTORY));
+        levels.add(new Level(Level.DUNGEON, "res/ActorExtensionPack/Level/MoreSkeleton.csv", "res/ActorExtensionPack/Level/MoreSkeleton.txt", PLAYING_INVENTORY));
+        levels.add(new Level(Level.DUNGEON, "res/ActorExtensionPack/Level/Spider.csv", "res/ActorExtensionPack/Level/Spider.txt", PLAYING_INVENTORY));
+        levels.add(new Level(Level.DUNGEON, "res/ActorExtensionPack/Level/Seapider.csv", "res/ActorExtensionPack/Level/Seapider.txt", PLAYING_INVENTORY));
+        levels.add(new Level(Level.DUNGEON, "res/ActorExtensionPack/Level/MagicTower.csv", "res/ActorExtensionPack/Level/MagicTower.txt", PLAYING_INVENTORY));
+        levels.add(new Level(Level.DUNGEON, "res/ActorExtensionPack/Level/Portal.csv", "res/ActorExtensionPack/Level/Portal.txt", PLAYING_INVENTORY));
+        levels.add(new Level(Level.DUNGEON, "res/ActorExtensionPack/Level/WhereAmI.csv", "res/ActorExtensionPack/Level/WhereAmI.txt", PLAYING_INVENTORY));
+        levels.add(new Level(Level.DUNGEON, "res/ActorExtensionPack/Level/Trap!!!.csv", "res/ActorExtensionPack/Level/Trap!!!.txt", PLAYING_INVENTORY));
+        levels.add(new Level(Level.DUNGEON, "res/ActorExtensionPack/Level/TTTTraps!!!!!!!!!!!!!.csv", "res/ActorExtensionPack/Level/TTTTraps!!!!!!!!!!!!!.txt", PLAYING_INVENTORY));
+        levels.add(new Level(Level.DUNGEON, "res/ActorExtensionPack/Level/Skull.csv", "res/ActorExtensionPack/Level/Skull.txt", PLAYING_INVENTORY));
+        levels.add(new Level(Level.DUNGEON, "res/ActorExtensionPack/Level/Bones.csv", "res/ActorExtensionPack/Level/Bones.txt", PLAYING_INVENTORY));
+        levels.add(new Level(Level.DUNGEON, "res/ActorExtensionPack/Level/Witch.csv", "res/ActorExtensionPack/Level/Witch.txt", PLAYING_INVENTORY));
+        levels.add(new Level(Level.DUNGEON, "res/ActorExtensionPack/Level/MeteorShower.csv", "res/ActorExtensionPack/Level/MeteorShower.txt", PLAYING_INVENTORY));
+        levels.add(new Level(Level.DUNGEON, "res/ActorExtensionPack/Level/MonsterParty.csv", "res/ActorExtensionPack/Level/MonsterParty.txt", PLAYING_INVENTORY));
+    }
+
+    public static LevelManager getInstance() {
+        if (levelManager == null) {
+            levelManager = new LevelManager();
+        }
+        return levelManager;
+    }
+
+    public Level getLevel(int num) {
+        return levels.get(num-1).clone();
+    }
+
+}
diff --git a/src/Level/MakeLevel.java b/src/Level/MakeLevel.java
new file mode 100644
index 0000000000000000000000000000000000000000..4823c9a3def55d3df08fcbd431481a21cc0ace0b
--- /dev/null
+++ b/src/Level/MakeLevel.java
@@ -0,0 +1,111 @@
+package Level;
+
+import Music.MusicPlayer;
+import Music.MusicPlayerManager;
+import Page.GameStage;
+import actor.*;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import static java.nio.file.StandardOpenOption.APPEND;
+import static java.nio.file.StandardOpenOption.CREATE;
+
+public class MakeLevel extends Level {
+    public MakeLevel(String worldType, String filename, boolean[] playMode) {
+        super(worldType, filename, playMode);
+    }
+
+    public void generate() {
+        Path file = Paths.get("res/levelGenerateData.txt");
+        int newName = 0;
+
+        try (BufferedReader reader = Files.newBufferedReader(file)) {
+            String line = null;
+            if ((line = reader.readLine()) != null) {
+                newName = Integer.parseInt(line.replace("\n", ""));
+            }
+        } catch (IOException e) {
+            System.err.format("IOException: %s%n", e);
+            System.exit(-1);
+        }
+
+        try (BufferedWriter writer = Files.newBufferedWriter(file)) {
+            writer.write("" + (newName + 1), 0, ("" + (newName + 1)).length());
+        } catch (IOException e) {
+            System.err.format("IOException: %s%n", e);
+            System.exit(-1);
+        }
+
+        file = Paths.get("res/ActorExtensionPack/Level/MyLevel/MyLevel" + newName + ".csv");
+
+        byte data[] = makeLevelFileString().getBytes();
+
+        try (OutputStream out = new BufferedOutputStream(
+                Files.newOutputStream(file, CREATE, APPEND))) {
+            out.write(data, 0, data.length);
+        } catch (IOException e) {
+            System.err.println(e);
+            System.exit(-1);
+        }
+    }
+
+    @Override
+    public MakeLevel clone() {
+        return new MakeLevel(getWorldType(), getFilename(), LevelManager.MAKING_INVENTORY);
+    }
+
+    public String makeLevelFileString() {
+        String s = "";
+        for (Actor actor : getSelectPanel().planning) {
+            if (actor instanceof Knight) {
+                s = s + KNIGHT + "," + (int)(actor.getPosition().x/TILED_LENGTH) + "," + (int)(actor.getPosition().y/TILED_LENGTH) + "\n";
+            } else if (actor instanceof Skeleton) {
+                s = s + SKELETON + "," + (int)(actor.getPosition().x/TILED_LENGTH) + "," + (int)(actor.getPosition().y/TILED_LENGTH) + "," + actor.getDirection() + "," + ((Skeleton) actor).getWanderLoop() + "\n";
+            } else if (actor instanceof Trap) {
+                s = s + TRAP + "," + (int)(actor.getPosition().x/TILED_LENGTH) + "," + (int)(actor.getPosition().y/TILED_LENGTH) + "," + ((Trap)actor).getOn() + "\n";
+            } else if (actor instanceof Spider) {
+                s = s + SPIDER + "," + (int)(actor.getPosition().x/TILED_LENGTH) + "," + (int)(actor.getPosition().y/TILED_LENGTH) + "," + ((Spider) actor).getDirection0() + "," + ((Spider) actor).getDirection1() + "," + ((Spider) actor).getWanderLoop() + "\n";
+            } else if (actor instanceof Skull) {
+                s = s + SKULL + "," + (int)(actor.getPosition().x/TILED_LENGTH) + "," + (int)(actor.getPosition().y/TILED_LENGTH) + "," + actor.getDirection() + "," + ((Skull) actor).getWanderLoop() + "\n";
+            } else if (actor instanceof Portal) {
+                s = s + PORTAL + "," + (int)(actor.getPosition().x/TILED_LENGTH) + "," + (int)(actor.getPosition().y/TILED_LENGTH) + ",";
+                for (Actor actor1 : getSelectPanel().planning) {
+                    if (actor1 != actor && actor1 instanceof Portal && ((Portal) actor).getPairID() == ((Portal) actor1).getPairID()) {
+                        s = s + (int)(actor1.getPosition().x/TILED_LENGTH) + "," + (int)(actor1.getPosition().y/TILED_LENGTH) + "\n";
+                    }
+                }
+            } else if (actor instanceof WallMaker) {
+                s = s + WALL_MAKER + "," + (int)(actor.getPosition().x/TILED_LENGTH) + "," + (int)(actor.getPosition().y/TILED_LENGTH) + ",";
+                for (Actor actor1 : getSelectPanel().planning) {
+                    if (actor1 != actor && actor1 instanceof WallMaker && ((WallMaker) actor).getRelateID() == ((WallMaker) actor1).getRelateID()) {
+                        s = s + (int)(actor1.getPosition().x/TILED_LENGTH) + "," + (int)(actor1.getPosition().y/TILED_LENGTH) + "\n";
+                    }
+                }
+            } else if (actor instanceof Witch) {
+                s = s + WITCH + "," + (int)(actor.getPosition().x/TILED_LENGTH) + "," + (int)(actor.getPosition().y/TILED_LENGTH) + "," + actor.getDirection() + "," + ((Witch) actor).getWanderLoop() + "\n";
+            } else if (actor instanceof Sign) {
+                if (actor.getDirection() == UP) {
+                    s = s + SIGN_UP + "," + (int)(actor.getPosition().x/TILED_LENGTH) + "," + (int)(actor.getPosition().y/TILED_LENGTH) + "\n";
+                } else if (actor.getDirection() == RIGHT) {
+                    s = s + SIGN_RIGHT + "," + (int)(actor.getPosition().x/TILED_LENGTH) + "," + (int)(actor.getPosition().y/TILED_LENGTH) + "\n";
+                } else if (actor.getDirection() == DOWN) {
+                    s = s + SIGN_DOWN + "," + (int)(actor.getPosition().x/TILED_LENGTH) + "," + (int)(actor.getPosition().y/TILED_LENGTH) + "\n";
+                } else if (actor.getDirection() == LEFT) {
+                    s = s + SIGN_LEFT + "," + (int)(actor.getPosition().x/TILED_LENGTH) + "," + (int)(actor.getPosition().y/TILED_LENGTH) + "\n";
+                }
+            } else if (actor instanceof Chest) {
+                s = s + CHEST + "," + (int)(actor.getPosition().x/TILED_LENGTH) + "," + (int)(actor.getPosition().y/TILED_LENGTH) + "\n";
+            }
+        }
+        return s;
+    }
+
+    @Override
+    public void restart() {
+        super.restart();
+        MusicPlayerManager.getInstance().playSingleTrack(GameStage.makeMusic, MusicPlayer.NONE);
+    }
+}
diff --git a/src/Level/MyLevelManager.java b/src/Level/MyLevelManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..6abb5016daa358e234aa59d462923eba6e0e8781
--- /dev/null
+++ b/src/Level/MyLevelManager.java
@@ -0,0 +1,45 @@
+package Level;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.stream.Stream;
+
+public class MyLevelManager {
+    private static MyLevelManager myLevelManager = null;
+
+    ArrayList<Level> levels = new ArrayList<Level>();
+
+    private MyLevelManager() {
+        try (Stream<Path> paths = Files.walk(Paths.get("res/ActorExtensionPack/Level/MyLevel"))) {
+            paths
+                    .filter(Files::isRegularFile)
+                    .forEach(path -> levels.add(new Level(Level.DUNGEON, path.toString(), LevelManager.PLAYING_INVENTORY)));
+
+        } catch (IOException e) {
+            System.out.println("Fail to read my level data");
+            System.exit(-1);
+        }
+    }
+
+    public static MyLevelManager getInstance() {
+        if (myLevelManager == null) {
+            myLevelManager = new MyLevelManager();
+        }
+        return myLevelManager;
+    }
+
+    public Level getLevel(int num) {
+        return levels.get(num - 1).clone();
+    }
+
+    public int getSize() {
+        return levels.size();
+    }
+
+    public static void refresh() {
+        myLevelManager = new MyLevelManager();
+    }
+}
diff --git a/src/Level/SelectButton.java b/src/Level/SelectButton.java
new file mode 100644
index 0000000000000000000000000000000000000000..38694fb784f787e821bd4f10e92c5144988ec92f
--- /dev/null
+++ b/src/Level/SelectButton.java
@@ -0,0 +1,59 @@
+package Level;
+
+import Listener.MouseListener;
+import UI.AABB;
+import UI.Button;
+import UI.FontManager;
+import actor.Actor;
+import actor.Knight;
+import actor.Skeleton;
+import actor.WallMaker;
+import bagel.Drawing;
+import bagel.Image;
+import myUtil.Vec2D;
+
+public class SelectButton extends Button {
+    //properties
+    private SelectPanel castToPanel;
+    private Actor actor;
+    private int amount;
+    private Vec2D position;
+
+    public SelectButton(Image button, Vec2D position, Actor actor, int amount) {
+        super(button, position);
+        this.actor = actor;
+        this.amount = amount;
+        this.position = position.clone();
+    }
+
+    @Override
+    public void event() {
+        if (castToPanel.selected == null && amount != 0) {
+            amount--;
+            castToPanel.getAmount().put(actor, amount);
+            castToPanel.selected = actor;
+        }
+    }
+
+    @Override
+    public void display() {
+        super.display();
+        FontManager.sizeFont(20).drawString("" + amount, position.x, position.y);
+    }
+
+    public void setCastToPanel(SelectPanel castToPanel) {
+        this.castToPanel = castToPanel;
+    }
+
+    public void setActor(Actor actor) {
+        this.actor = actor;
+    }
+
+    public void setAmount(int amount) {
+        this.amount = amount;
+    }
+
+    public int getAmount() {
+        return amount;
+    }
+}
diff --git a/src/Level/SelectPanel.java b/src/Level/SelectPanel.java
new file mode 100644
index 0000000000000000000000000000000000000000..f9ac974b7ee7e2d4ed164febb0df312f35fa0358
--- /dev/null
+++ b/src/Level/SelectPanel.java
@@ -0,0 +1,717 @@
+package Level;
+
+import Listener.MouseListener;
+import UI.Button;
+import UI.Pane;
+import actor.*;
+import bagel.Image;
+import myUtil.MyMath;
+import myUtil.Vec2D;
+
+import java.util.*;
+
+import static actor.Trap.OFF;
+
+public class SelectPanel extends Pane {
+    //select component
+    protected Actor selected = null;
+
+    private Level castToLevel;
+
+    //worked level
+    Vec2D position = new Vec2D(0,640);
+    Vec2D framePosition = new Vec2D(28,680);
+    Vec2D itemOffset = new Vec2D(0,5);
+    Vec2D itemGap = new Vec2D(100,0);
+
+    //Direction constant
+    protected static final int UP = 0;
+    protected static final int RIGHT = 1;
+    protected static final int DOWN = 2;
+    protected static final int LEFT = 3;
+
+    //default value
+    protected static int INVALID = -1;
+    protected static String VOID = "";
+
+    //default value
+    private int start = 0;
+    private int end = 10;
+    private boolean hide = false;
+    private boolean remove = false;
+
+    //pane component
+    private int leftPart;
+    private int middlePart;
+    private int rightPart;
+    private int targetValid;
+    private int targetInvalid;
+
+    private int target = targetValid;
+
+    //limit
+    private static final int MAX_ITEM_DISPLAY = 10;
+
+    private static final int LEFT_WIDTH = 68;
+    private static final int MIDDLE_WIDTH = 64;
+    private static final int RIGHT_WIDTH = 68;
+    private static final int SELECT_FRAME_WIDTH = 72;
+    private static final int FRAME_WIDTH = 28;
+    private static final int WIDTH = 1024;
+    private static final int OFFSET = -5;
+
+    private ArrayList<Actor> selectActor;
+    HashMap<Actor, Integer> amount;
+
+    ArrayList<SelectButton> buttons = new ArrayList<SelectButton>();
+    ArrayList<Actor> planning;
+
+    private boolean place = false;
+    private Vec2D storedPosition = new Vec2D();
+
+    Button nextButton = new Button(new Image("res/ActorExtensionPack/UI/next.png"), new Vec2D(1000, 680)) {
+        @Override
+        public void event() {
+            nextItem();
+        }
+    };
+    Button prevButton = new Button(new Image("res/ActorExtensionPack/UI/prev.png"), new Vec2D(5, 680)) {
+        @Override
+        public void event() {
+            prevItem();
+        }
+    };
+
+    Button hideButton = new Button(new Image("res/ActorExtensionPack/UI/hide.png"), new Vec2D(470, 625)) {
+        @Override
+        public void event() {
+            hide = true;
+        }
+    };
+    Button showButton = new Button(new Image("res/ActorExtensionPack/UI/show.png"), new Vec2D(470, 740)) {
+        @Override
+        public void event() {
+            hide = false;
+        }
+    };
+    Button deleteButton = new Button(new Image("res/ActorExtensionPack/UI/remove.png"), new Vec2D(928, 608)) {
+        @Override
+        public void event() {
+            remove = true;
+        }
+    };
+    Button deleteCancelButton = new Button(new Image("res/ActorExtensionPack/UI/removeCancel.png"), new Vec2D(928, 608)) {
+        @Override
+        public void event() {
+            remove = false;
+        }
+    };
+
+    private static final int INFINITY = 99;
+
+    public SelectPanel(Level castToLevel, boolean chosen[]) {
+        super();
+        selectActor = new ArrayList<>();
+        planning = new ArrayList<>();
+        amount = new HashMap<>();
+        //add all types of actor
+        selectActor.add(new Knight(new Vec2D()));
+        selectActor.add(new Skeleton(new Vec2D(), RIGHT, INVALID));
+        selectActor.add(new Trap(new Vec2D(), OFF));
+        selectActor.add(new Spider(new Vec2D(), RIGHT, UP, INVALID));
+        selectActor.add(new Skull(new Vec2D(), UP, INVALID));
+        selectActor.add(new Portal(new Vec2D(), INVALID, null));
+        selectActor.add(new WallMaker(new Vec2D()));
+        selectActor.add(new Witch(new Vec2D(), UP, INVALID));
+        selectActor.add(new Sign(new Vec2D(), UP));
+        selectActor.add(new Sign(new Vec2D(), LEFT));
+        selectActor.add(new Sign(new Vec2D(), RIGHT));
+        selectActor.add(new Sign(new Vec2D(), DOWN));
+        selectActor.add(new Chest(new Vec2D()));
+
+        //remove unwanted
+        for (int i = 0; i < chosen.length; i++) {
+            selectActor.get(i).animationUpdate();
+            if (!chosen[i]) {
+                selectActor.get(i).setRemove(true);
+            }
+        }
+
+        for (Actor actor : selectActor) {
+            if (actor instanceof Knight || actor instanceof Chest) {
+                amount.put(actor, 1);
+            } else if (actor instanceof Sign && chosen == LevelManager.PLAYING_INVENTORY) {
+                amount.put(actor, 0);
+            } else {
+                amount.put(actor, INFINITY);
+            }
+        }
+
+        for (Actor readActor : castToLevel.getActors()) {
+            if (readActor instanceof Sign) {
+                for (Actor reference : selectActor) {
+                    if (reference instanceof Sign && readActor.getDirection() == reference.getDirection()) {
+                        amount.put(reference, amount.get(reference) + 1);
+                        break;
+                    }
+                }
+            }
+        }
+
+        Collection<Actor> list = castToLevel.getActors();;
+        list.removeIf(actor -> actor instanceof Sign);
+
+        Collection<Actor> sList = selectActor;
+        sList.removeIf(actor -> actor.isRemove());
+
+        this.castToLevel = castToLevel;
+
+        load();
+    }
+
+    public void load() {
+        leftPart = add(new Image("res/ActorExtensionPack/UI/inventoryLeft.png"));
+        middlePart = add(new Image("res/ActorExtensionPack/UI/inventoryMiddle.png"));
+        rightPart = add(new Image("res/ActorExtensionPack/UI/inventoryRight.png"));
+        targetValid = add(new Image("res/ActorExtensionPack/UI/target_valid.png"));
+        targetInvalid = add(new Image("res/ActorExtensionPack/UI/target_invalid.png"));
+
+        for (int i = 0, j = OFFSET; i  < MyMath.min(MAX_ITEM_DISPLAY, selectActor.size()); i++, j+=FRAME_WIDTH) {
+            buttons.add(new SelectButton(new Image("res/ActorExtensionPack/UI/selectFrame.png"),new Vec2D(framePosition.x + j, framePosition.y), selectActor.get(i), amount.get(selectActor.get(i))));
+            buttons.get(i).setCastToPanel(this);
+            j+=SELECT_FRAME_WIDTH;
+        }
+    }
+
+    @Override
+    public void display() {
+        for (Actor actor : planning) {
+            actor.display();
+        }
+
+        //place event
+        if (!remove) {
+            placeUpdate();
+            for (Actor actor : planning) {
+                if (getGridPosition().equals(actor.getPosition()) && MouseListener.getInstance().leftClick()) {
+                    if (actor instanceof Trap) {
+                        ((Trap) actor).trigger();
+                        actor.animationUpdate();
+                    }
+                }
+            }
+        } else {
+            if (selected != null) {
+                for (Actor reference : selectActor) {
+                    if (selected.getClass() == reference.getClass()) {
+                        if (!(selected instanceof Sign) && selected.getClass() == reference.getClass()) {
+                            amount.put(reference, amount.get(reference) + 1);
+                        } else if ((selected instanceof Sign) && (reference instanceof Sign) && selected.getDirection() == reference.getDirection()) {
+                            amount.put(reference, amount.get(reference) + 1);
+                        }
+                    }
+                }
+            }
+            selected = null;
+            storedPosition = new Vec2D();
+            place = false;
+            deleteUpdate();
+        }
+
+        if (!hide) {
+            //draw back board
+            getSource().get(leftPart).drawFromTopLeft(position.x, position.y);
+            for (int i = LEFT_WIDTH; i < WIDTH; i += MIDDLE_WIDTH) {
+                getSource().get(middlePart).drawFromTopLeft(position.x+i, position.y);
+            }
+            getSource().get(rightPart).drawFromTopLeft(WIDTH-RIGHT_WIDTH, position.y);
+
+            //draw item frame
+            for (Button button : buttons) {
+                button.display();
+            }
+
+            //draw function button
+            nextButton.display();
+            prevButton.display();
+
+            //draw actor
+            for (int i = start, j = 0; i < MyMath.min(end, selectActor.size()); i++, j++) {
+                int offset = i - start;
+                selectActor.get(i).getAnimationManager().playAt(framePosition.out_add(itemOffset).out_addN(offset, itemGap));
+                //update button
+                buttons.get(j).setActor(selectActor.get(i));
+                buttons.get(j).setAmount(amount.get(selectActor.get(i)));
+            }
+        }
+
+
+        if (hide) {
+            showButton.display();
+        } else {
+            hideButton.display();
+        }
+
+        if (remove) {
+            deleteCancelButton.display();
+        } else {
+            deleteButton.display();
+        }
+
+        //draw selected actor
+        if (selected != null) {
+            //selected.getAnimationManager().playAt(MouseListener.getInstance().position().out_sub(MOUSE_OFFSET));
+            getSource().get(target).drawFromTopLeft(getGridPosition().x, getGridPosition().y);
+            selected.getAnimationManager().playAt(getGridPosition());
+        }
+    }
+
+    public void event() {
+        if (!hide) {
+            //check mouse event
+            for (int i = 0; i  < MyMath.min(MAX_ITEM_DISPLAY, selectActor.size()); i++) {
+                buttons.get(i).onClick();
+            }
+
+            nextButton.onClick();
+            prevButton.onClick();
+        }
+
+        if (hide) {
+            showButton.onClick();
+        } else {
+            hideButton.onClick();
+        }
+
+        if (remove) {
+            deleteCancelButton.onClick();
+        } else {
+            deleteButton.onClick();
+        }
+    }
+
+    protected void nextItem() {
+        if (end + 1 > selectActor.size()) return;
+
+        end++;
+        start++;
+    }
+
+    protected void prevItem() {
+        if (start - 1 < 0) return;
+
+        end--;
+        start--;
+    }
+
+    public void deleteUpdate() {
+        if (remove && MouseListener.getInstance().leftClick()) {
+            Actor planningRemove = null;
+            for (Actor actor : planning) {
+                if (actor.getPosition().equals(getGridPosition())) {
+                    planningRemove = actor;
+                    for (Actor reference : selectActor) {
+                        if (!(actor instanceof Sign) && actor.getClass() == reference.getClass()) {
+                            amount.put(reference, amount.get(reference) + 1);
+                        } else if ((actor instanceof Sign) && (reference instanceof Sign) && actor.getDirection() == reference.getDirection()) {
+                            amount.put(reference, amount.get(reference) + 1);
+                        }
+                    }
+                    break;
+                }
+            }
+            if (planningRemove instanceof WallMaker) {
+                int id = ((WallMaker) planningRemove).getRelateID();
+                Collection<Actor> list = planning;
+                list.removeIf(actor -> actor instanceof WallMaker && ((WallMaker) actor).getRelateID() == id);
+                list.removeIf(actor -> actor instanceof Lightning && ((Lightning) actor).getRelateID() == id);
+            } else if (planningRemove instanceof Lightning) {
+                int id = ((Lightning) planningRemove).getRelateID();
+                Collection<Actor> list = planning;
+                list.removeIf(actor -> actor instanceof WallMaker && ((WallMaker) actor).getRelateID() == id);
+                list.removeIf(actor -> actor instanceof Lightning && ((Lightning) actor).getRelateID() == id);
+            } else if (planningRemove instanceof Portal) {
+                int id = ((Portal) planningRemove).getPairID();
+                Collection<Actor> list = planning;
+                list.removeIf(actor -> actor instanceof Portal && ((Portal) actor).getPairID() == id);
+            } else {
+                planning.remove(planningRemove);
+            }
+        }
+    }
+
+    public void placeUpdate() {
+        checkValidation();
+        if (selected == null) {
+            return;
+        }
+        if (MouseListener.getInstance().rightClick()) {
+            amount.put(selected, amount.get(selected) + 1);
+            selected = null;
+            storedPosition = new Vec2D();
+            place = false;
+            return;
+        }
+        if (selected instanceof Knight) {
+            placeKnight();
+        } else if (selected instanceof Skeleton) {
+            placeSkeleton();
+        } else if (selected instanceof Trap) {
+            placeTrap();
+        } else if (selected instanceof Spider) {
+            placeSpider();
+        } else if (selected instanceof Skull) {
+            placeSkull();
+        } else if (selected instanceof Portal) {
+            placePortal();
+        } else if (selected instanceof WallMaker) {
+            placeWallMaker();
+        } else if (selected instanceof Witch) {
+            placeWitch();
+        } else if (selected instanceof Sign) {
+            placeSign(selected.getDirection());
+        } else if (selected instanceof Chest) {
+            placeChest();
+        }
+    }
+
+    private void invalidPlace() {
+        target = targetInvalid;
+    }
+
+    private void validPlace() {
+        target = targetValid;
+    }
+
+    private void checkValidation() {
+        for (Actor target : castToLevel.getActors()) {
+            if (target.getPosition().equals(getGridPosition())) {
+                invalidPlace();
+                return;
+            }
+        }
+        for (Actor target : planning) {
+            if (target.getPosition().equals(getGridPosition())) {
+                invalidPlace();
+                return;
+            }
+        }
+        if (!MyMath.between(64, 1024 - 64, MouseListener.getInstance().position().x)
+                || !MyMath.between(64, 768 - 64, MouseListener.getInstance().position().y) ) {
+            invalidPlace();
+            return;
+        }
+        validPlace();
+    }
+
+    private boolean place(Actor actor, Vec2D position) {
+        planning.add(actor);
+        return true;
+    }
+
+    public void setCastToLevel(Level castToLevel) {
+        this.castToLevel = castToLevel;
+    }
+
+    private static Vec2D getGridPosition() {
+        float xDiff = MouseListener.getInstance().position().x % Level.TILED_LENGTH;
+        float yDiff = MouseListener.getInstance().position().y % Level.TILED_LENGTH;
+
+        return MouseListener.getInstance().position().out_sub(new Vec2D(xDiff, yDiff));
+    }
+
+    private void placeKnight() {
+        if (MouseListener.getInstance().leftClick() && target == targetValid) {
+            Actor knight = new Knight(getGridPosition());
+            knight.animationUpdate();
+            if (place(knight, getGridPosition())) {
+                selected = null;
+            }
+        }
+    }
+
+    private void placeSkull() {
+        Actor skull = new Skull(storedPosition, UP, INVALID);
+
+        //set spawn point
+        if (!place) {
+            if (MouseListener.getInstance().leftClick()) {
+                storedPosition.set(getGridPosition());
+                place = true;
+            }
+        } else {
+            // ensure the attribute
+            if (getGridPosition().x != storedPosition.x) {
+                invalidPlace();
+            } else if (getGridPosition().equals(storedPosition)) {
+                invalidPlace();
+            } else if (MouseListener.getInstance().leftClick() && target == targetValid) {
+                int direction = UP;
+                float wander = MyMath.diff(getGridPosition().y, storedPosition.y);
+                if (getGridPosition().y <= storedPosition.y) {
+                    direction = DOWN;
+                }
+
+                skull = new Skull(storedPosition, direction, (int) (wander / Level.TILED_LENGTH + 1));
+                ((Skull) skull).setCastToLevel(castToLevel);
+
+                planning.add(skull);
+
+                selected = null;
+                place = false;
+                storedPosition = new Vec2D();
+            }
+
+            skull.animationUpdate();
+            skull.display();
+        }
+
+    }
+
+    private void placeWitch() {
+        Actor witch = new Witch(storedPosition, UP, INVALID);
+
+        //set spawn point
+        if (!place) {
+            if (MouseListener.getInstance().leftClick()) {
+                storedPosition.set(getGridPosition());
+                place = true;
+            }
+        } else {
+            // ensure the attribute
+            if (getGridPosition().x != storedPosition.x) {
+                invalidPlace();
+            } else if (getGridPosition().equals(storedPosition)) {
+                invalidPlace();
+            } else if (MouseListener.getInstance().leftClick() && target == targetValid) {
+                int direction = UP;
+                float wander = MyMath.diff(getGridPosition().y, storedPosition.y);
+                if (getGridPosition().y <= storedPosition.y) {
+                    direction = DOWN;
+                }
+
+                witch = new Witch(storedPosition, direction, (int) (wander / Level.TILED_LENGTH + 1));
+                ((Witch) witch).setCastToLevel(castToLevel);
+
+                planning.add(witch);
+                selected = null;
+                place = false;
+                storedPosition = new Vec2D();
+            }
+
+            witch.animationUpdate();
+            witch.display();
+        }
+
+    }
+
+    private void placePortal() {
+        Actor portal = new Portal(storedPosition, INVALID, castToLevel);
+
+        //set spawn point
+        if (!place) {
+            if (MouseListener.getInstance().leftClick()) {
+                storedPosition.set(getGridPosition());
+                place = true;
+            }
+        } else {
+            if (getGridPosition().equals(storedPosition)) {
+                invalidPlace();
+            } else {
+                // ensure the attribute
+                if (MouseListener.getInstance().leftClick() && target == targetValid) {
+                    portal = new Portal(getGridPosition(), storedPosition, planning, castToLevel);
+                    planning.add(portal);
+                    selected = null;
+                    place = false;
+                    storedPosition = new Vec2D();
+                }
+
+                portal.animationUpdate();
+                portal.display();
+            }
+        }
+
+    }
+
+    private void placeSpider() {
+        Actor spider = new Spider(storedPosition, RIGHT, UP, INVALID);
+
+        //set spawn point
+        if (!place) {
+            if (MouseListener.getInstance().leftClick()) {
+                storedPosition.set(getGridPosition());
+                place = true;
+            }
+        } else {
+            // ensure the attribute
+            if (MyMath.abs(getGridPosition().x - storedPosition.x) != MyMath.abs(getGridPosition().y - storedPosition.y)) {
+                invalidPlace();
+            } else if (getGridPosition().equals(storedPosition)) {
+                invalidPlace();
+            } else {
+                if (MouseListener.getInstance().leftClick() && target == targetValid) {
+                    int direction0 = LEFT;
+                    if (MouseListener.getInstance().position().x > storedPosition.x) {
+                        direction0 = RIGHT;
+                    }
+
+                    int direction1 = DOWN;
+                    if (MouseListener.getInstance().position().y < storedPosition.y) {
+                        direction1 = UP;
+                    }
+
+                    //set attribute
+                    float wander = MyMath.diff(getGridPosition().x, storedPosition.x);
+
+                    spider = new Spider(storedPosition, direction0, direction1, (int) (wander / Level.TILED_LENGTH));
+                    planning.add(spider);
+
+                    selected = null;
+                    place = false;
+                    storedPosition = new Vec2D();
+                }
+            }
+
+            spider.animationUpdate();
+            spider.display();
+        }
+
+    }
+
+    private void placeWallMaker() {
+        Actor wallMaker1 = new WallMaker(storedPosition, INVALID);
+
+        //set spawn point
+        if (!place) {
+            if (MouseListener.getInstance().leftClick()) {
+                storedPosition.set(getGridPosition());
+                place = true;
+            }
+        } else {
+            // ensure the attribute
+            if (getGridPosition().x != storedPosition.x && getGridPosition().y != storedPosition.y) {
+                invalidPlace();
+            } else if (getGridPosition().equals(storedPosition)) {
+                invalidPlace();
+            } else {
+                if (MouseListener.getInstance().leftClick() && target == targetValid) {
+                    wallMaker1 = new WallMaker(storedPosition);
+                    planning.add(wallMaker1);
+                    Actor wallMaker2 = new WallMaker(getGridPosition(), ((WallMaker) wallMaker1).getRelateID());
+                    planning.add(wallMaker2);
+                    Vec2D spawnPoint1 = storedPosition;
+                    Vec2D spawnPoint2 = getGridPosition();
+                    float start = MyMath.min(spawnPoint1.x, spawnPoint2.x);
+                    int lightningType = Lightning.HORIZON;
+                    float end = MyMath.max(spawnPoint1.x, spawnPoint2.x);
+
+                    if (spawnPoint1.x == spawnPoint2.x) {
+                        start = MyMath.min(spawnPoint1.y, spawnPoint2.y);
+                        lightningType = Lightning.VERTICAL;
+                        end = MyMath.max(spawnPoint1.y, spawnPoint2.y);
+                    }
+
+                    for (int i = (int) (start + Level.TILED_LENGTH); i < end; i += Level.TILED_LENGTH) {
+                        if (lightningType == Lightning.VERTICAL) {
+                            planning.add(new Lightning(new Vec2D(spawnPoint1.x, i), lightningType, ((WallMaker) wallMaker1).getRelateID()));
+                        } else if (lightningType == Lightning.HORIZON) {
+                            planning.add(new Lightning(new Vec2D(i, spawnPoint1.y), lightningType, ((WallMaker) wallMaker1).getRelateID()));
+                        }
+                    }
+
+                    selected = null;
+                    place = false;
+                    storedPosition = new Vec2D();
+                }
+            }
+
+            wallMaker1.animationUpdate();
+            wallMaker1.display();
+        }
+
+    }
+
+    private void placeSkeleton() {
+        Actor skeleton = new Skeleton(storedPosition, Skeleton.TYPE_HORIZON, INVALID);
+        //set attribute
+        int type = Skeleton.TYPE_HORIZON;
+        float wander = MyMath.diff(getGridPosition().x, storedPosition.x);
+        if (getGridPosition().x == storedPosition.x) {
+            type = Skeleton.TYPE_VERTICAL;
+            wander = MyMath.diff(getGridPosition().y, storedPosition.y);
+        }
+        ((Skeleton) skeleton).setCurrentType(type);
+        ((Skeleton) skeleton).setWanderLoop((int) (wander / Level.TILED_LENGTH + 1));
+
+        //set spawn point
+        if (!place) {
+            if (MouseListener.getInstance().leftClick()) {
+                storedPosition.set(getGridPosition());
+                place = true;
+            }
+        } else {
+            // ensure the attribute
+            if (getGridPosition().x != storedPosition.x && getGridPosition().y != storedPosition.y) {
+                invalidPlace();
+            } else {
+                if (MouseListener.getInstance().leftClick() && target == targetValid) {
+                    if (getGridPosition().x > storedPosition.x) {
+                        skeleton.setDirection(RIGHT);
+                    } else if (getGridPosition().x < storedPosition.x) {
+                        skeleton.setDirection(LEFT);
+                    }
+
+                    if (getGridPosition().y > storedPosition.y) {
+                        skeleton.setDirection(DOWN);
+                    } else if (getGridPosition().y < storedPosition.y) {
+                        skeleton.setDirection(UP);
+                    }
+
+                    planning.add(skeleton);
+                    selected = null;
+                    place = false;
+                    storedPosition = new Vec2D();
+                }
+            }
+
+            skeleton.animationUpdate();
+            skeleton.display();
+        }
+
+    }
+
+    private void placeTrap() {
+        if (MouseListener.getInstance().leftClick() && target == targetValid) {
+            Actor trap = new Trap(getGridPosition(), OFF);
+            trap.animationUpdate();
+            if (place(trap, getGridPosition())) {
+                selected = null;
+            }
+        }
+    }
+
+    private void placeChest() {
+        if (MouseListener.getInstance().leftClick() && target == targetValid) {
+            Actor chest = new Chest(getGridPosition());
+            chest.animationUpdate();
+            if (place(chest, getGridPosition())) {
+                selected = null;
+            }
+        }
+    }
+
+    private void placeSign(int direction) {
+        if (MouseListener.getInstance().leftClick() && target == targetValid) {
+            Actor sign = new Sign(getGridPosition(), direction);
+            sign.animationUpdate();
+            if (place(sign, getGridPosition())) {
+                selected = null;
+            }
+        }
+    }
+
+    public HashMap<Actor, Integer> getAmount() {
+        return amount;
+    }
+}
diff --git a/src/Listener/MouseListener.java b/src/Listener/MouseListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..933d6436061e5fe79809c95ad6faf19503e778bb
--- /dev/null
+++ b/src/Listener/MouseListener.java
@@ -0,0 +1,54 @@
+package Listener;
+
+import myUtil.Vec2D;
+import bagel.Input;
+import bagel.MouseButtons;
+
+public class MouseListener {
+    private static MouseListener mouseListener = null;
+    private static Vec2D mousePosition = null;
+    private static boolean leftClick = false;
+    private static boolean rightClick = false;
+
+    private MouseListener() {
+    }
+
+    public static MouseListener getInstance() {
+        if (mouseListener == null) {
+            mouseListener = new MouseListener();
+        }
+        return mouseListener;
+    }
+
+    public Vec2D position() {
+        return mousePosition;
+    }
+
+    public boolean rightClick() {
+        return rightClick;
+    }
+
+    public boolean leftClick() {
+        return leftClick;
+    }
+
+    public void listen(Input input) {
+        if (mousePosition == null) {
+            mousePosition = new Vec2D(input.getMouseX(), input.getMouseY());
+        }
+        mousePosition.set(input.getMouseX(), input.getMouseY());
+        if (input.wasPressed(MouseButtons.LEFT)) {
+            leftClick = true;
+        } else {
+            leftClick = false;
+        }
+
+        if (input.wasPressed(MouseButtons.RIGHT)) {
+            rightClick = true;
+        } else {
+            rightClick = false;
+        }
+    }
+
+
+}
diff --git a/src/Music/MusicPlayer.java b/src/Music/MusicPlayer.java
new file mode 100644
index 0000000000000000000000000000000000000000..b5c3d3ae5b798abd3cf933e72fa6354b288374eb
--- /dev/null
+++ b/src/Music/MusicPlayer.java
@@ -0,0 +1,52 @@
+package Music;
+
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import java.io.File;
+import java.io.FileInputStream;
+
+public class MusicPlayer {
+    private final String musicPath;
+    private Clip player;
+    private boolean isPlaying = false;
+
+    public static final int NONE = 0;
+    public static final int LOOP_OPTION = 1;
+
+    public MusicPlayer(String path) {
+        musicPath = path;
+    }
+
+    public void play() {
+        play(0);
+    }
+
+    public void play(int option) {
+        if (isPlaying) {
+            player.close();
+            player.stop();
+        }
+        File musicFile = new File(musicPath);
+        try {
+            AudioInputStream audioInput = AudioSystem.getAudioInputStream(musicFile);
+            player = AudioSystem.getClip();
+            player.open(audioInput);
+            player.start();
+            isPlaying = true;
+            if (option == LOOP_OPTION) {
+                player.loop(Clip.LOOP_CONTINUOUSLY);
+            }
+        }catch (Exception e){
+            System.out.println(e);
+        }
+    }
+
+    public void stop() {
+        if (isPlaying) {
+            player.stop();
+            player.close();
+            isPlaying = false;
+        }
+    }
+}
diff --git a/src/Music/MusicPlayerManager.java b/src/Music/MusicPlayerManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..bd7a8def2cc860de586fb5995a67508c99346a65
--- /dev/null
+++ b/src/Music/MusicPlayerManager.java
@@ -0,0 +1,53 @@
+package Music;
+
+import myUtil.MyMath;
+
+import java.util.ArrayList;
+
+public class MusicPlayerManager {
+    private static MusicPlayerManager musicPlayerManager = null;
+    private ArrayList<MusicPlayer> musicPlayers = new ArrayList<>();;
+
+    private static final int NONE = -1;
+    private static int currentPlayingSingleTrack = NONE;
+
+    private MusicPlayerManager() {
+
+    }
+
+    public static MusicPlayerManager getInstance() {
+        if (musicPlayerManager == null) {
+            musicPlayerManager = new MusicPlayerManager();
+        }
+        return musicPlayerManager;
+    }
+
+    public void playMixed(int musicIndex, int option) {
+        if (MyMath.between(0, musicPlayers.size() - 1, musicIndex)) {
+            musicPlayers.get(musicIndex).play(option);
+        }
+    }
+
+    public void playSingleTrack(int musicIndex, int option) {
+        if (currentPlayingSingleTrack != NONE) {
+            musicPlayers.get(currentPlayingSingleTrack).stop();
+        }
+        if (MyMath.between(0, musicPlayers.size() - 1, musicIndex)) {
+            currentPlayingSingleTrack = musicIndex;
+            musicPlayers.get(musicIndex).play(option);
+        }
+    }
+
+    public int addMusic(MusicPlayer music) {
+        int currentIndex = musicPlayers.size();
+        musicPlayers.add(music);
+        return currentIndex;
+    }
+
+    public void stopAll() {
+        currentPlayingSingleTrack = NONE;
+        for (MusicPlayer musicPlayer : musicPlayers) {
+            musicPlayer.stop();
+        }
+    }
+}
diff --git a/src/Page/GameStage.java b/src/Page/GameStage.java
new file mode 100644
index 0000000000000000000000000000000000000000..d3ba89fe9b129716917fbc2741a6c4de02c7a43d
--- /dev/null
+++ b/src/Page/GameStage.java
@@ -0,0 +1,62 @@
+package Page;
+
+import Music.MusicPlayer;
+import Music.MusicPlayerManager;
+
+import java.util.ArrayList;
+
+public class GameStage {
+    private static GameStage gameStage = null;
+    private ArrayList<MusicPlayer> musicPlayers = new ArrayList<>();;
+
+    //stage
+    public static final int START_PAGE = 0;
+    public static final int LEVEL_SELECT_PAGE = 1;
+    public static final int GAME_PAGE = 2;
+    public static final int MAKE_PAGE = 3;
+    public static final int MY_LEVEL_PAGE = 5;
+    public static final int LOADING = 100;
+
+    private static int currentStage;
+
+    private GameStage() {
+        currentStage = 0;
+    }
+
+    public static GameStage getInstance() {
+        if (gameStage == null) {
+            gameStage = new GameStage();
+            setMusic();
+        }
+        return gameStage;
+    }
+
+    public int getCurrentStage() {
+        return currentStage;
+    }
+
+    public void goTo(int stage) {
+        if (stage == START_PAGE) {
+            MusicPlayerManager.getInstance().playSingleTrack(startMusic, MusicPlayer.LOOP_OPTION);
+        } else if (stage == GAME_PAGE) {
+            MusicPlayerManager.getInstance().playSingleTrack(playMusic, MusicPlayer.LOOP_OPTION);
+        } else if (stage == MAKE_PAGE) {
+            MusicPlayerManager.getInstance().playSingleTrack(makeMusic, MusicPlayer.LOOP_OPTION);
+        }
+        currentStage = stage;
+    }
+
+    public static int startMusic;
+    public static int playMusic;
+    public static int makeMusic;
+    public static int wining;
+    public static int lose;
+
+    private static void setMusic() {
+        startMusic = MusicPlayerManager.getInstance().addMusic(new MusicPlayer("res/ActorExtensionPack/Sound/wav/startScheme.wav"));
+        playMusic = MusicPlayerManager.getInstance().addMusic(new MusicPlayer("res/ActorExtensionPack/Sound/wav/StartMenuBGM.wav"));
+        makeMusic = MusicPlayerManager.getInstance().addMusic(new MusicPlayer("res/ActorExtensionPack/Sound/wav/makeScheme.wav"));
+        wining = MusicPlayerManager.getInstance().addMusic(new MusicPlayer("res/ActorExtensionPack/Sound/wav/win.wav"));
+        lose = MusicPlayerManager.getInstance().addMusic(new MusicPlayer("res/ActorExtensionPack/Sound/wav/lose.wav"));
+    }
+}
diff --git a/src/Page/LevelButton.java b/src/Page/LevelButton.java
new file mode 100644
index 0000000000000000000000000000000000000000..dbfd5024e8850ecff7218bb2ce3bb6f4a493c6e9
--- /dev/null
+++ b/src/Page/LevelButton.java
@@ -0,0 +1,41 @@
+package Page;
+
+import Level.Level;
+import UI.Button;
+import UI.TextBox;
+import bagel.Image;
+import bagel.util.Colour;
+import myUtil.Vec2D;
+
+public class LevelButton extends Button {
+    private int num;
+    private LevelPage castToLevelPage;
+    TextBox textBox;
+
+    public LevelButton(Image button, Vec2D position, int num, LevelPage castToLevelPage) {
+        super(button, position);
+        this.num = num;
+        this.castToLevelPage = castToLevelPage;
+
+        textBox = new TextBox("", (float) button.getWidth(), position.out_add(new Vec2D(30,100)), Colour.WHITE);
+    }
+
+    @Override
+    public void event() {
+        castToLevelPage.setLevelChosen(num);
+    }
+
+    @Override
+    public void display() {
+        super.display();
+        textBox.setFontSize(100);
+        textBox.setStr("" + num);
+        textBox.display();
+    }
+
+    public void setNum(int num) {
+        this.num = num;
+    }
+
+
+}
diff --git a/src/Page/LevelPage.java b/src/Page/LevelPage.java
new file mode 100644
index 0000000000000000000000000000000000000000..ac030d877ce511d6b1e7e6af889d5a0d29b1bbce
--- /dev/null
+++ b/src/Page/LevelPage.java
@@ -0,0 +1,169 @@
+package Page;
+
+import Level.MyLevelManager;
+import UI.Button;
+import UI.Pane;
+import UI.TextBox;
+import bagel.Image;
+import bagel.util.Colour;
+import myUtil.MyMath;
+import myUtil.Vec2D;
+
+import java.util.ArrayList;
+
+public class LevelPage extends Pane {
+    //level type
+    public static final int DEFAULT_LEVEL = 0;
+    public static final int MY_LEVEL = 1;
+    public static final int INVALID = -1;
+
+    public int DEFAULT_LEVEL_COUNT = 15;
+
+    private int upPart;
+    private int middlePart;
+    private int bottomPart;
+
+    private static final Vec2D UP_POSITION = new Vec2D(220, 200);
+    private static final Vec2D MIDDLE_POSITION1 = new Vec2D(220, 300);
+    private static final Vec2D MIDDLE_POSITION2 = new Vec2D(220, 400);
+    private static final Vec2D MIDDLE_POSITION3 = new Vec2D(220, 500);
+    private static final Vec2D BOTTOM_POSITION = new Vec2D(220, 600);
+
+    Button nextButton = new Button(new Image("res/ActorExtensionPack/UI/next.png"), new Vec2D(780, 450)) {
+        @Override
+        public void event() {
+            nextPage();
+        }
+    };
+    Button prevButton = new Button(new Image("res/ActorExtensionPack/UI/prev.png"), new Vec2D(220, 450)) {
+        @Override
+        public void event() {
+            prevPage();
+        }
+    };
+
+    Button homeButton = new Button(new Image("res/ActorExtensionPack/UI/home.png"), new Vec2D(955, 0)) {
+        @Override
+        public void event() {
+            start = 0;
+            GameStage.getInstance().goTo(GameStage.START_PAGE + GameStage.LOADING);
+        }
+    };
+
+    TextBox title;
+
+    private final static int TITLE_SIZE = 100;
+
+    private String path;
+    private int currentType;
+
+    private int start = 0;
+
+    private int totalLevel;
+
+    private int levelChosen = INVALID;
+
+    ArrayList<LevelButton> levelButtons;
+    private static final int MAX_LEVEL_BUTTON_ROW = 3;
+    private static final int MAX_LEVEL_BUTTON_COL = 3;
+
+    public LevelPage(String path, int type) {
+        super();
+        this.path = path;
+        currentType = type;
+
+        levelButtons = new ArrayList<>();
+
+
+        if (currentType == DEFAULT_LEVEL) {
+            totalLevel = DEFAULT_LEVEL_COUNT;
+            title = new TextBox("Challenge", 1000, UP_POSITION.clone().out_add(new Vec2D(-30,0)), Colour.WHITE);
+        } else if (currentType == MY_LEVEL) {
+            load();
+            title = new TextBox("My Map", 1000, UP_POSITION.clone().out_add(new Vec2D(-30,0)), Colour.WHITE);
+        }
+
+        generateButton(totalLevel);
+
+        upPart = add(new Image("res/ActorExtensionPack/UI/levelBackUp.png"));
+        middlePart = add(new Image("res/ActorExtensionPack/UI/levelBackMiddle.png"));
+        bottomPart = add(new Image("res/ActorExtensionPack/UI/levelBackBottom.png"));
+
+    }
+
+    public void load() {
+        totalLevel = MyLevelManager.getInstance().getSize();
+    }
+
+    @Override
+    public void display() {
+        title.setFontSize(TITLE_SIZE);
+
+        getSource().get(upPart).drawFromTopLeft(UP_POSITION.x, UP_POSITION.y);
+        getSource().get(middlePart).drawFromTopLeft(MIDDLE_POSITION1.x, MIDDLE_POSITION1.y);
+        getSource().get(middlePart).drawFromTopLeft(MIDDLE_POSITION2.x, MIDDLE_POSITION2.y);
+        getSource().get(middlePart).drawFromTopLeft(MIDDLE_POSITION3.x, MIDDLE_POSITION3.y);
+        getSource().get(bottomPart).drawFromTopLeft(BOTTOM_POSITION.x, BOTTOM_POSITION.y);
+
+        for (int i = 0; i < MyMath.min(totalLevel - start, MAX_LEVEL_BUTTON_COL * MAX_LEVEL_BUTTON_ROW); i++) {
+            levelButtons.get(i).setNum(start + i + 1);
+            levelButtons.get(i).display();
+        }
+
+        homeButton.display();
+
+        nextButton.display();
+        prevButton.display();
+
+        title.display();
+
+        for (int i = 0; i < MyMath.min(totalLevel - start, MAX_LEVEL_BUTTON_COL * MAX_LEVEL_BUTTON_ROW); i++) {
+            levelButtons.get(i).onClick();
+        }
+
+        homeButton.onClick();
+
+        nextButton.onClick();
+        prevButton.onClick();
+    }
+
+    public void setLevelChosen(int levelChosen) {
+        this.levelChosen = levelChosen;
+    }
+
+    public void generateButton(int num) {
+        //generate buttons
+        int count = 0;
+
+        for (int i = 0; i < MAX_LEVEL_BUTTON_COL; i++) {
+            if (count == MyMath.min(MAX_LEVEL_BUTTON_COL * MAX_LEVEL_BUTTON_ROW, num)) {
+                break;
+            }
+            for (int j = 0; j < MAX_LEVEL_BUTTON_ROW; j++) {
+                count++;
+                levelButtons.add(new LevelButton(new Image("res/ActorExtensionPack/UI/levelButton.png"), new Vec2D(270 + j * 170,240 + i * 170), count, this));
+
+                if (count == MyMath.min(MAX_LEVEL_BUTTON_COL * MAX_LEVEL_BUTTON_ROW, num)) {
+                    break;
+                }
+            }
+        }
+    }
+
+    protected void nextPage() {
+        if (start + 9 > totalLevel) return;
+
+        start += 9;
+    }
+
+
+    protected void prevPage() {
+        if (start - MAX_LEVEL_BUTTON_ROW * MAX_LEVEL_BUTTON_COL < 0) return;
+
+        start -= MAX_LEVEL_BUTTON_ROW * MAX_LEVEL_BUTTON_COL;
+    }
+
+    public int getLevelChosen() {
+        return levelChosen;
+    }
+}
diff --git a/src/Page/StartPage.java b/src/Page/StartPage.java
new file mode 100644
index 0000000000000000000000000000000000000000..0eddbfbde8fe28b21201a5baa45a94c82e62dd45
--- /dev/null
+++ b/src/Page/StartPage.java
@@ -0,0 +1,122 @@
+package Page;
+
+import Music.MusicPlayerManager;
+import UI.Button;
+import UI.Pane;
+import UI.TextBox;
+import bagel.Image;
+import bagel.util.Colour;
+import myUtil.Vec2D;
+
+public class StartPage extends Pane {
+
+    Button start = new Button(new Image("res/ActorExtensionPack/UI/redButton.png"), new Vec2D(400,250)) {
+        TextBox textBox = new TextBox("START", (float) new Image("res/ActorExtensionPack/UI/redButton.png").getWidth(), new Vec2D(400,250).out_add(new Vec2D(40,50)), Colour.WHITE);
+        @Override
+        public void event() {
+            MusicPlayerManager.getInstance().stopAll();
+            GameStage.getInstance().goTo(GameStage.LEVEL_SELECT_PAGE + GameStage.LOADING);
+        }
+
+        @Override
+        public void display() {
+            super.display();
+            textBox.setFontSize(50);
+            textBox.display();
+        }
+    };
+
+    Button create = new Button(new Image("res/ActorExtensionPack/UI/bblueButton.png"), new Vec2D(400,350)) {
+        TextBox textBox = new TextBox("MAKE", (float) new Image("res/ActorExtensionPack/UI/redButton.png").getWidth(), new Vec2D(400,350).out_add(new Vec2D(40,50)), Colour.WHITE);
+        @Override
+        public void event() {
+            MusicPlayerManager.getInstance().stopAll();
+            GameStage.getInstance().goTo(GameStage.MAKE_PAGE + GameStage.LOADING);
+        }
+
+        @Override
+        public void display() {
+            super.display();
+            textBox.setFontSize(50);
+            textBox.display();
+        }
+    };
+
+    Button myMap = new Button(new Image("res/ActorExtensionPack/UI/clayButton.png"), new Vec2D(400,450)) {
+        TextBox textBox = new TextBox("MY MAP", (float) new Image("res/ActorExtensionPack/UI/redButton.png").getWidth(), new Vec2D(400,450).out_add(new Vec2D(40,50)), Colour.WHITE);
+        @Override
+        public void event() {
+            MusicPlayerManager.getInstance().stopAll();
+            GameStage.getInstance().goTo(GameStage.MY_LEVEL_PAGE + GameStage.LOADING);
+        }
+
+        @Override
+        public void display() {
+            super.display();
+            textBox.setFontSize(50);
+            textBox.display();
+        }
+    };
+
+    Button exit = new Button(new Image("res/ActorExtensionPack/UI/blueButton.png"), new Vec2D(400,550)) {
+        TextBox textBox = new TextBox("EXIT", (float) new Image("res/ActorExtensionPack/UI/redButton.png").getWidth(), new Vec2D(400,550).out_add(new Vec2D(40,50)), Colour.WHITE);
+        @Override
+        public void event() {
+            System.exit(0);
+        }
+
+        @Override
+        public void display() {
+            super.display();
+            textBox.setFontSize(50);
+            textBox.display();
+        }
+    };
+
+    private int upPart;
+    private int middlePart;
+    private int bottomPart;
+
+    private static final Vec2D UP_POSITION = new Vec2D(220, 200);
+    private static final Vec2D MIDDLE_POSITION1 = new Vec2D(220, 300);
+    private static final Vec2D MIDDLE_POSITION2 = new Vec2D(220, 400);
+    private static final Vec2D BOTTOM_POSITION = new Vec2D(220, 500);
+
+    private final static int TITLE_SIZE = 100;
+
+    TextBox title = new TextBox("SHADOW LIFE", 1000, UP_POSITION.clone().out_add(new Vec2D(-30,0)), Colour.WHITE);
+
+    public StartPage() {
+        super();
+        load();
+    }
+
+    public void load() {
+        upPart = add(new Image("res/ActorExtensionPack/UI/levelBackUp.png"));
+        middlePart = add(new Image("res/ActorExtensionPack/UI/levelBackMiddle.png"));
+        bottomPart = add(new Image("res/ActorExtensionPack/UI/levelBackBottom.png"));
+    }
+
+    @Override
+    public void display() {
+        title.setFontSize(TITLE_SIZE);
+
+        getSource().get(upPart).drawFromTopLeft(UP_POSITION.x, UP_POSITION.y);
+        getSource().get(middlePart).drawFromTopLeft(MIDDLE_POSITION1.x, MIDDLE_POSITION1.y);
+        getSource().get(middlePart).drawFromTopLeft(MIDDLE_POSITION2.x, MIDDLE_POSITION2.y);
+        getSource().get(bottomPart).drawFromTopLeft(BOTTOM_POSITION.x, BOTTOM_POSITION.y);
+
+        title.display();
+
+        start.display();
+        create.display();
+        myMap.display();
+        exit.display();
+
+
+        start.onClick();
+        create.onClick();
+        myMap.onClick();
+        exit.onClick();
+    }
+}
diff --git a/src/ShadowLifeGame.java b/src/ShadowLifeGame.java
new file mode 100644
index 0000000000000000000000000000000000000000..02e94e016107548f5385da69c9a5b015154f51f1
--- /dev/null
+++ b/src/ShadowLifeGame.java
@@ -0,0 +1,219 @@
+import Animation.Animation;
+import Animation.AnimationStateManager;
+import Level.*;
+import Listener.MouseListener;
+import Music.MusicPlayer;
+import Music.MusicPlayerManager;
+import Page.LevelPage;
+import UI.Button;
+import UI.FontManager;
+import UI.TextBox;
+import actor.*;
+import bagel.*;
+import bagel.util.Colour;
+import bagel.util.Point;
+import myUtil.Vec2D;
+import Page.GameStage;
+import Page.StartPage;
+
+import java.util.ArrayList;
+
+import static Page.LevelPage.INVALID;
+
+public class ShadowLifeGame extends AbstractGame {
+    public static final int WIDTH = 1024;
+    public static final int HEIGHT = 768;
+
+    //time control
+    private static float dt = 1;
+    private static float framePassed = 0;
+
+    //int init
+    private static final int RESET = 0;
+
+    Vec2D progressPosition = new Vec2D(192,384);
+
+    private Level level = LevelManager.getInstance().getLevel(3);
+    private StartPage startPage = new StartPage();
+    private LevelPage levelPage = new LevelPage("res/ActorExtensionPack/Level", LevelPage.DEFAULT_LEVEL);
+    private LevelPage myLevelPage = new LevelPage("res/ActorExtensionPack/Level/MyLevel", LevelPage.MY_LEVEL);
+    private MakeLevel sampleLevel = new MakeLevel(Level.DUNGEON, "res/ActorExtensionPack/Level/EmptyMap.csv", LevelManager.MAKING_INVENTORY);
+    private MakeLevel makeLevel = sampleLevel.clone();
+
+    private int loadCount = 0;
+
+    private boolean fromMyLevel = false;
+
+    Animation progress = new Animation();
+
+    TextBox loading = new TextBox("FAKE LOADING...", 1000, progressPosition, Colour.WHITE);
+
+    Image background = new Image("res/ActorExtensionPack/UI/startpage.png");
+
+    Button generateButton = new Button(new Image("res/ActorExtensionPack/UI/yes.png"), new Vec2D(955, 500)) {
+        @Override
+        public void event() {
+            MusicPlayerManager.getInstance().stopAll();
+            GameStage.getInstance().goTo(GameStage.MY_LEVEL_PAGE);
+            makeLevel.generate();
+            makeLevel = null;
+            MyLevelManager.refresh();
+            myLevelPage = new LevelPage("res/ActorExtensionPack/Level", LevelPage.MY_LEVEL);
+        }
+    };
+
+    Button levelButton = new Button(new Image("res/ActorExtensionPack/UI/LevelMenu.png"), new Vec2D(749, 0)) {
+        @Override
+        public void event() {
+            if (GameStage.getInstance().getCurrentStage() == GameStage.GAME_PAGE) {
+                GameStage.getInstance().goTo(GameStage.LEVEL_SELECT_PAGE);
+            }
+            if (fromMyLevel) {
+                GameStage.getInstance().goTo(GameStage.MY_LEVEL_PAGE);
+            }
+            if (GameStage.getInstance().getCurrentStage() == GameStage.MAKE_PAGE) {
+                GameStage.getInstance().goTo(GameStage.MY_LEVEL_PAGE);
+            }
+        }
+    };
+
+    public ShadowLifeGame() {
+        super(WIDTH, HEIGHT, "Shadow Life");
+
+        //create new world
+        startPage.load();
+        GameStage.getInstance().goTo(GameStage.START_PAGE);
+        createProgressBar();
+    }
+
+    public static void main(String[] args) {
+        //generate world
+        ShadowLifeGame game = new ShadowLifeGame();
+        game.run();
+    }
+
+
+    @Override
+    public void update(Input input) {
+        //listen input
+        MouseListener.getInstance().listen(input);
+        background.drawFromTopLeft(0,0);
+
+        //level.update(framePassed % Level.TILED_LENGTH);
+        if (GameStage.getInstance().getCurrentStage() == GameStage.START_PAGE) {
+            if (makeLevel != null) {
+                makeLevel = null;
+            }
+            startPage.display();
+        } else if (GameStage.getInstance().getCurrentStage() == GameStage.LEVEL_SELECT_PAGE) {
+            levelPage.display();
+            if (levelPage.getLevelChosen() != INVALID) {
+                GameStage.getInstance().goTo(GameStage.GAME_PAGE + GameStage.LOADING);
+                level = LevelManager.getInstance().getLevel(levelPage.getLevelChosen());
+                levelPage.setLevelChosen(INVALID);
+            }
+        } else if (GameStage.getInstance().getCurrentStage() == GameStage.GAME_PAGE) {
+            level.update(framePassed % Level.TILED_LENGTH);
+            if (level.getState() == Level.LOSE) {
+                levelButton.display();
+                levelButton.onClick();
+            }
+            if (level.getState() == Level.WIN) {
+                levelButton.display();
+                levelButton.onClick();
+            }
+        } else if (GameStage.getInstance().getCurrentStage() == GameStage.MAKE_PAGE) {
+            if (makeLevel == null) {
+                makeLevel = sampleLevel.clone();
+            }
+            makeLevel.update(framePassed % Level.TILED_LENGTH);
+            if (makeLevel.getState() == Level.WIN) {
+                generateButton.display();
+                generateButton.onClick();
+            }
+            if (level.getState() == Level.LOSE) {
+                levelButton.display();
+                levelButton.onClick();
+            }
+        } else if (GameStage.getInstance().getCurrentStage() == GameStage.MY_LEVEL_PAGE) {
+            if (makeLevel != null) {
+                makeLevel = null;
+            }
+            myLevelPage.display();
+            fromMyLevel = true;
+            if (myLevelPage.getLevelChosen() != INVALID) {
+                GameStage.getInstance().goTo(GameStage.GAME_PAGE + GameStage.LOADING);
+                level = MyLevelManager.getInstance().getLevel(myLevelPage.getLevelChosen());
+                myLevelPage.setLevelChosen(INVALID);
+            }
+        } else if (GameStage.getInstance().getCurrentStage() >= GameStage.LOADING) {
+            loading.setFontSize(80);
+            loading.display();
+            loadCount++;
+            progress.playAt(progressPosition);
+            if (loadCount > 3 * 64) {
+                progress.replay();
+                loadCount = 0;
+                GameStage.getInstance().goTo(GameStage.getInstance().getCurrentStage() - GameStage.LOADING);
+            }
+        }
+
+        //update time
+        framePassed += dt;
+
+        //test only
+        //drawGridView(framePassed % Level.TILED_LENGTH);
+
+    }
+
+    private void drawGridView(float framePassedInUnit) {
+        Colour c = Colour.BLACK;
+        int thickness = 2;
+        if (framePassedInUnit == 31) {
+            c = Colour.GREEN;
+            thickness = 4;
+        }
+        if (framePassedInUnit == 63) {
+            c = Colour.RED;
+            thickness = 4;
+        }
+        for (int i = 0; i <= 1024; i += 64) {
+            Drawing.drawLine(new Point(i, 0), new Point(i, 768), 2, c);
+        }
+        for (int j = 0; j <= 768; j += 64) {
+            Drawing.drawLine(new Point(0, j), new Point(1024, j), 2, c);
+        }
+    }
+
+    public void createProgressBar() {
+        Image f0 = new Image("res/ActorExtensionPack/UI/progressBar/0.png");
+        Image f1 = new Image("res/ActorExtensionPack/UI/progressBar/1.png");
+        Image f2 = new Image("res/ActorExtensionPack/UI/progressBar/2.png");
+        Image f3 = new Image("res/ActorExtensionPack/UI/progressBar/3.png");
+        Image f4 = new Image("res/ActorExtensionPack/UI/progressBar/4.png");
+        Image f5 = new Image("res/ActorExtensionPack/UI/progressBar/5.png");
+        Image f6 = new Image("res/ActorExtensionPack/UI/progressBar/6.png");
+        Image f7 = new Image("res/ActorExtensionPack/UI/progressBar/7.png");
+        Image f8 = new Image("res/ActorExtensionPack/UI/progressBar/8.png");
+        Image f9 = new Image("res/ActorExtensionPack/UI/progressBar/9.png");
+
+        progress.addFrame(f0);
+        progress.addFrame(f1);
+        progress.addFrame(f2);
+        progress.addFrame(f3);
+        progress.addFrame(f4);
+        progress.addFrame(f5);
+        progress.addFrame(f6);
+        progress.addFrame(f7);
+        progress.addFrame(f8);
+        progress.addFrame(f9);
+        progress.addFrame(f9);
+        progress.addFrame(f9);
+        progress.addFrame(f9);
+        progress.addFrame(f9);
+        progress.addFrame(f9);
+        progress.addFrame(f9);
+    }
+
+
+}
diff --git a/src/UI/AABB.java b/src/UI/AABB.java
new file mode 100644
index 0000000000000000000000000000000000000000..4c826bf4fe22b143d31fb8d202c2b7fee0e8b2ef
--- /dev/null
+++ b/src/UI/AABB.java
@@ -0,0 +1,20 @@
+package UI;
+
+import myUtil.MyMath;
+import myUtil.Vec2D;
+import bagel.Input;
+import bagel.MouseButtons;
+
+public class AABB {
+    Vec2D min;
+    Vec2D max;
+
+    public AABB(Vec2D min, Vec2D max) {
+        this.min = min;
+        this.max = max;
+    }
+
+    public boolean contains(Vec2D position) {
+        return MyMath.between(max.x, min.x, position.x) && MyMath.between(max.y, min.y, position.y);
+    }
+}
diff --git a/src/UI/Button.java b/src/UI/Button.java
new file mode 100644
index 0000000000000000000000000000000000000000..80d0863a4b576a13d607b76fbbccf58c401a4485
--- /dev/null
+++ b/src/UI/Button.java
@@ -0,0 +1,57 @@
+package UI;
+
+import Listener.MouseListener;
+import Music.MusicPlayer;
+import Music.MusicPlayerManager;
+import bagel.Drawing;
+import bagel.util.Colour;
+import bagel.util.Point;
+import myUtil.MyMath;
+import myUtil.Vec2D;
+import bagel.Image;
+import bagel.Input;
+import bagel.MouseButtons;
+import bagel.util.Vector2;
+
+public abstract class Button {
+    //private AABB volume;
+    private AABB boundingBox;
+    private Image button;
+    private final int buttonPressedSound = MusicPlayerManager.getInstance().addMusic(new MusicPlayer("res/ActorExtensionPack/Sound/wav/ButtonPressed.wav"));
+
+    public Button(Image button, Vec2D position) {
+        this.button = button;
+        Vec2D adding = new Vec2D((float)button.getWidth(), (float)button.getHeight());
+        this.boundingBox = new AABB(position, position.out_add(adding));
+        //this.volume = new AABB(boundingBox.min.out_sub(frameSize), boundingBox.max.out_add(frameSize));
+    }
+
+    public void onClick() {
+        if (boundingBox.contains(MouseListener.getInstance().position()))
+        {
+            Point a = boundingBox.min.toPoint();
+            Point b = new Point(boundingBox.max.x, boundingBox.min.y);
+            Point c = boundingBox.max.toPoint();
+            Point d = new Point(boundingBox.min.x, boundingBox.max.y);
+            Drawing.drawLine(a,b,2,Colour.WHITE);
+            Drawing.drawLine(c,b,2,Colour.WHITE);
+            Drawing.drawLine(c,d,2,Colour.WHITE);
+            Drawing.drawLine(a,d,2,Colour.WHITE);
+            if (MouseListener.getInstance().leftClick())
+            {
+                MusicPlayerManager.getInstance().playMixed(buttonPressedSound, MusicPlayer.NONE);
+                event();
+            }
+        }
+    }
+
+    public abstract void event();
+
+    public void display() {
+        button.drawFromTopLeft(boundingBox.min.x, boundingBox.min.y);
+    }
+
+    public void setButton(Image button) {
+        this.button = button;
+    }
+}
\ No newline at end of file
diff --git a/src/UI/FontManager.java b/src/UI/FontManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..2ff9d1bf7d10c272cd0968cc54f46dad7d06353d
--- /dev/null
+++ b/src/UI/FontManager.java
@@ -0,0 +1,11 @@
+package UI;
+
+import bagel.Font;
+
+public class FontManager {
+    private static final String FONT_PATH = "res/ActorExtensionPack/Font/8-bit-pusab.ttf";
+
+    public static Font sizeFont(int size) {
+        return new Font(FONT_PATH, size);
+    }
+}
diff --git a/src/UI/Pane.java b/src/UI/Pane.java
new file mode 100644
index 0000000000000000000000000000000000000000..90b9c6788b06c8d77ed8b05f33afc1737ca5bff3
--- /dev/null
+++ b/src/UI/Pane.java
@@ -0,0 +1,26 @@
+package UI;
+
+import myUtil.Vec2D;
+import bagel.Image;
+
+import java.util.ArrayList;
+
+public abstract class Pane {
+    private ArrayList<Image> source;
+
+    public Pane() {
+        source = new ArrayList<>();
+    }
+
+    public int add(Image image) {
+        int index = source.size();
+        source.add(image);
+        return index;
+    }
+
+    public abstract void display();
+
+    public ArrayList<Image> getSource() {
+        return source;
+    }
+}
diff --git a/src/UI/TestButton.java b/src/UI/TestButton.java
new file mode 100644
index 0000000000000000000000000000000000000000..1ed8e4b713cbde03daeee715c09e54739351d544
--- /dev/null
+++ b/src/UI/TestButton.java
@@ -0,0 +1,15 @@
+package UI;
+
+import myUtil.Vec2D;
+import bagel.Image;
+
+public class TestButton extends Button {
+    public TestButton(Image button, Vec2D position) {
+        super(button, position);
+    }
+
+    @Override
+    public void event() {
+        System.out.println("u clicked me!!!!");
+    }
+}
diff --git a/src/UI/TestPane.java b/src/UI/TestPane.java
new file mode 100644
index 0000000000000000000000000000000000000000..5222d2e1fb7927dbf338d59cf3e35259a5be050f
--- /dev/null
+++ b/src/UI/TestPane.java
@@ -0,0 +1,26 @@
+package UI;
+
+import myUtil.Vec2D;
+import bagel.Image;
+
+public class TestPane extends Pane {
+
+    private int upPart;
+    private int middlePart;
+    private int bottomPart;
+
+    public TestPane(Vec2D position) {
+        super();
+    }
+
+    public void load() {
+        upPart = add(new Image("res/ActorExtensionPack/UI/levelBackUp.png"));
+        middlePart = add(new Image("res/ActorExtensionPack/UI/levelBackMiddle.png"));
+        bottomPart = add(new Image("res/ActorExtensionPack/UI/levelBackBottom.png"));
+    }
+
+    @Override
+    public void display() {
+
+    }
+}
diff --git a/src/UI/TextBox.java b/src/UI/TextBox.java
new file mode 100644
index 0000000000000000000000000000000000000000..d3a7378f7a21d46a9f3af97bcc60057c87e81811
--- /dev/null
+++ b/src/UI/TextBox.java
@@ -0,0 +1,58 @@
+package UI;
+
+import myUtil.Vec2D;
+import bagel.DrawOptions;
+import bagel.Drawing;
+import bagel.Font;
+import bagel.util.Colour;
+import bagel.util.Point;
+
+public class TextBox {
+    private int fontSize = 20;
+
+    private String str;
+    private float width;
+    private Vec2D position;
+    private Colour colour;
+
+    public TextBox(String str, float width, Vec2D position, Colour colour) {
+        this.str = str;
+        this.width = width;
+        this.position = position;
+        this.colour = colour;
+    }
+
+    public void display() {
+        showLine(str, position);
+    }
+
+    public void setFontSize(int fontSize) {
+        this.fontSize = fontSize;
+    }
+
+    private void showLine(String str, Vec2D position) {
+        Font font = FontManager.sizeFont(fontSize);
+        if (font.getWidth(str) <= width) {
+            DrawOptions drawOptions = new DrawOptions();
+            font.drawString(str, position.x, position.y, drawOptions.setBlendColour(colour));
+            return;
+        }
+        for (int i = 1; i < str.length(); i++) {
+            if (font.getWidth(str.substring(0, i)) > width) {
+                if (i != 1) {
+                    DrawOptions drawOptions = new DrawOptions();
+                    font.drawString(str.substring(0, i - 1), position.x, position.y, drawOptions.setBlendColour(colour));
+                    showLine(str.substring(i - 1), position.out_add(new Vec2D(0, 2 * fontSize / 3)));
+                    return;
+                } else {
+                    throw new ArrayIndexOutOfBoundsException("Width is too short");
+                }
+            }
+        }
+
+    }
+
+    public void setStr(String str) {
+        this.str = str;
+    }
+}
diff --git a/src/actor/Actor.java b/src/actor/Actor.java
new file mode 100644
index 0000000000000000000000000000000000000000..fd27d6fe2152fb0347aa13be9c56b4207c31497c
--- /dev/null
+++ b/src/actor/Actor.java
@@ -0,0 +1,249 @@
+package actor;
+
+import Animation.AnimationStateManager;
+import Level.Level;
+import bagel.Image;
+import myUtil.Vec2D;
+
+public abstract class Actor implements Comparable<Actor> {
+    //Moving properties
+    private Vec2D position;
+
+    //Basic properties
+    private boolean active; //can the actor move
+    private boolean destroyed;
+    private boolean isMoving;
+    private boolean remove;
+
+    //Direction
+    private int direction;
+    private int face;
+
+    //Direction constant
+    private static final Vec2D UP_VEC = new Vec2D(0, -1);
+    private static final Vec2D DOWN_VEC = new Vec2D(0, 1);
+    private static final Vec2D LEFT_VEC = new Vec2D(-1, 0);
+    private static final Vec2D RIGHT_VEC = new Vec2D(1, 0);
+
+    //Direction constant
+    protected static final int UP = 0;
+    protected static final int RIGHT = 1;
+    protected static final int DOWN = 2;
+    protected static final int LEFT = 3;
+
+    protected static final int NUM_DIRECTION = 4;
+
+    private int layer = 0;
+
+    //portal
+    private boolean transfer;
+
+    //Animation
+    private int animationState;
+    private AnimationStateManager getAnimationManager;
+
+    //type
+    private String type = "Actor";
+
+    public Actor(Vec2D spawnPoint) {
+        //Moving information
+        position = new Vec2D();
+        position.set(spawnPoint);
+        destroyed = false;
+        face = LEFT;
+        remove = false;
+
+        transfer = false;
+    }
+
+    public void move() {
+        setMoving(true);
+        if (active) {
+            if (direction == UP) {
+                position.addN(Level.TILED_LENGTH, UP_VEC);
+            } else if (direction == DOWN) {
+                position.addN(Level.TILED_LENGTH, DOWN_VEC);
+            } else if (direction == LEFT) {
+                position.addN(Level.TILED_LENGTH, LEFT_VEC);
+            } else if (direction == RIGHT) {
+                position.addN(Level.TILED_LENGTH, RIGHT_VEC);
+            } else {
+                //do nothing
+                return;
+            }
+            if (position.x < 64) {
+                position.addN(-Level.TILED_LENGTH, LEFT_VEC);
+                turnAround();
+                if (this instanceof Projectile) {
+                    destroy();
+                }
+            } else if (position.x > (1024 - 64 - 64)) {
+                position.addN(-Level.TILED_LENGTH, RIGHT_VEC);
+                turnAround();
+                if (this instanceof Projectile) {
+                    destroy();
+                }
+            }
+            if (position.y < 64) {
+                position.addN(-Level.TILED_LENGTH, UP_VEC);
+                turnAround();
+                if (this instanceof Projectile) {
+                    destroy();
+                }
+            } else if (position.y > (768 - 64 - 64)) {
+                position.addN(-Level.TILED_LENGTH, DOWN_VEC);
+                turnAround();
+                if (this instanceof Projectile) {
+                    destroy();
+                }
+            }
+        }
+    }
+
+    public void display() {
+        getAnimationManager().playAt(getPosition());
+    }
+
+    public abstract Actor clone();
+
+    public abstract void behavior();
+
+    public abstract void onInteract(Actor actor);
+
+    public abstract void animationUpdate();
+
+    //Getter and Setter
+    public void setActive(boolean active) {
+        this.active = active;
+    }
+
+    public void setDirection(int direction) {
+        if (direction == LEFT) {
+            face = LEFT;
+        }
+        if (direction == RIGHT) {
+            face = RIGHT;
+        }
+        this.direction = direction;
+    }
+
+    public boolean isTransfer() {
+        return transfer;
+    }
+
+    public void transfer() {
+        transfer = true;
+    }
+
+    public void resetTransfer() {
+        transfer = false;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String type() {
+        return type;
+    }
+
+    public Vec2D getPosition() {
+        return position;
+    }
+
+    public int getDirection() {
+        return direction;
+    }
+
+    public boolean isDestroyed() {
+        return destroyed;
+    }
+
+    public boolean isActive() {
+        return active;
+    }
+
+    public int getAnimationState() {
+        return animationState;
+    }
+
+    public void setAnimationState(int animationState) {
+        this.animationState = animationState;
+    }
+
+    public AnimationStateManager getAnimationManager() {
+        return getAnimationManager;
+    }
+
+    public void setGetAnimationManager(AnimationStateManager getAnimationManager) {
+        this.getAnimationManager = getAnimationManager;
+    }
+
+    public boolean isMoving() {
+        return isMoving;
+    }
+
+    public void setMoving(boolean moving) {
+        isMoving = moving;
+    }
+
+    public void setPosition(Vec2D position) {
+        this.position = position;
+    }
+
+    public int getFace() {
+        return face;
+    }
+
+    public boolean isRemove() {
+        return remove;
+    }
+
+    public void setRemove(boolean remove) {
+        this.remove = remove;
+    }
+
+    //useful action
+    public void rotate90Clockwise() {
+        direction = Math.floorMod(++direction, NUM_DIRECTION);
+        if (direction == LEFT) {
+            face = LEFT;
+        }
+        if (direction == RIGHT) {
+            face = RIGHT;
+        }
+    }
+
+    public void rotate90CounterClockwise() {
+        direction = Math.floorMod(--direction, NUM_DIRECTION);
+        if (direction == LEFT) {
+            face = LEFT;
+        }
+        if (direction == RIGHT) {
+            face = RIGHT;
+        }
+    }
+
+    public void destroy() {
+        active = false;
+        destroyed = true;
+    }
+
+    public void turnAround() {
+        rotate90Clockwise();
+        rotate90Clockwise();
+    }
+
+    @Override
+    public int compareTo(Actor o) {
+        return this.layer - o.getLayer();
+    }
+
+    public int getLayer() {
+        return layer;
+    }
+
+    public void setLayer(int layer) {
+        this.layer = layer;
+    }
+}
diff --git a/src/actor/Chest.java b/src/actor/Chest.java
new file mode 100644
index 0000000000000000000000000000000000000000..b2f2039cdbc2614e673b70d263c2e8765c270f7d
--- /dev/null
+++ b/src/actor/Chest.java
@@ -0,0 +1,76 @@
+package actor;
+
+import Animation.Animation;
+import Animation.AnimationStateManager;
+import bagel.Image;
+import myUtil.Vec2D;
+
+public class Chest extends Actor {
+    //state
+    private static final int OPEN = 0;
+    private static final int CLOSED = 1;
+
+    private static final int LAYER = 1;
+
+    private boolean opened;
+
+    public Chest(Vec2D spawnPoint) {
+        super(spawnPoint);
+        if (getAnimationManager() == null) {
+            setGetAnimationManager(newAnimationManager());
+        }
+
+        setMoving(false);
+        setActive(false);
+        opened = false;
+
+        setLayer(LAYER);
+
+        getAnimationManager().toState(CLOSED);
+    }
+
+    @Override
+    public void behavior() {
+    }
+
+    @Override
+    public void animationUpdate() {
+        if (opened) {
+            getAnimationManager().toState(OPEN);
+        }
+    }
+
+    @Override
+    public void onInteract(Actor actor) {
+        if (actor instanceof Knight && !opened) {
+            opened = true;
+            ((Knight) actor).setCarrying(true);
+        }
+        actor.turnAround();
+    }
+
+    private static AnimationStateManager newAnimationManager() {
+        AnimationStateManager animationStateManager = new AnimationStateManager();
+
+        Animation open = new Animation();
+        Animation close = new Animation();
+        Image frame0 = new Image("res/ActorExtensionPack/Actor/Chest/chest_1.png");
+        Image frame2 = new Image("res/ActorExtensionPack/Actor/Chest/chest_0.png");
+        open.addFrame(frame0);
+        close.addFrame(frame2);
+
+        animationStateManager.add(open);
+        animationStateManager.add(close);
+
+        return animationStateManager;
+    }
+
+    @Override
+    public Actor clone() {
+        return new Chest(getPosition());
+    }
+
+    public int getLAYER() {
+        return LAYER;
+    }
+}
diff --git a/src/actor/Knight.java b/src/actor/Knight.java
new file mode 100644
index 0000000000000000000000000000000000000000..c3f43080e7d06008b0f6b51c19b5ea55ce0494d7
--- /dev/null
+++ b/src/actor/Knight.java
@@ -0,0 +1,118 @@
+package actor;
+
+import Animation.Animation;
+import Animation.AnimationStateManager;
+import bagel.Image;
+import myUtil.Vec2D;
+
+public class Knight extends Actor{
+    //state
+    private static final int IDLE_R = 0;
+    private static final int WALK_R = 1;
+    private static final int IDLE_L = 2;
+    private static final int WALK_L = 3;
+
+    private static final int LAYER = 2;
+
+    private boolean carrying = false;
+
+    public Knight(Vec2D spawnPoint) {
+        super(spawnPoint);
+
+        if (getAnimationManager() == null) {
+            setGetAnimationManager(newAnimationManager());
+        }
+
+        setLayer(LAYER);
+
+        setMoving(false);
+        setDirection(LEFT);
+        setActive(true);
+
+    }
+
+    @Override
+    public void onInteract(Actor actor) {
+
+    }
+
+    @Override
+    public void behavior() {
+        resetTransfer();
+        move();
+    }
+
+    @Override
+    public void animationUpdate() {
+        if (isMoving()) {
+            if (getFace() == LEFT) {
+                getAnimationManager().toState(WALK_L);
+            } else if (getFace() == RIGHT) {
+                getAnimationManager().toState(WALK_R);
+            }
+        } else {
+            if (getFace() == LEFT) {
+                getAnimationManager().toState(IDLE_L);
+            } else if (getFace() == RIGHT) {
+                getAnimationManager().toState(IDLE_R);
+            }
+        }
+    }
+
+    private static AnimationStateManager newAnimationManager() {
+        AnimationStateManager animationStateManager = new AnimationStateManager();
+
+        Animation idleR = new Animation();
+        Image idleRFrame0 = new Image("res/ActorExtensionPack/Actor/Knight/knight_right_idle_0.png");
+        Image idleRFrame1 = new Image("res/ActorExtensionPack/Actor/Knight/knight_right_idle_1.png");
+        idleR.addFrame(idleRFrame0);
+        idleR.addFrame(idleRFrame1);
+
+        Animation walkR = new Animation();
+        Image walkRFrame0 = new Image("res/ActorExtensionPack/Actor/Knight/knight_right_walk_0.png");
+        Image walkRFrame1 = new Image("res/ActorExtensionPack/Actor/Knight/knight_right_walk_1.png");
+        walkR.addFrame(walkRFrame0);
+        walkR.addFrame(walkRFrame1);
+
+        Animation idleL = new Animation();
+        Image idleLFrame0 = new Image("res/ActorExtensionPack/Actor/Knight/knight_left_idle_0.png");
+        Image idleLFrame1 = new Image("res/ActorExtensionPack/Actor/Knight/knight_left_idle_1.png");
+        idleL.addFrame(idleLFrame0);
+        idleL.addFrame(idleLFrame1);
+
+        Animation walkL = new Animation();
+        Image walkLFrame0 = new Image("res/ActorExtensionPack/Actor/Knight/knight_left_walk_0.png");
+        Image walkLFrame1 = new Image("res/ActorExtensionPack/Actor/Knight/knight_left_walk_1.png");
+        walkL.addFrame(walkLFrame0);
+        walkL.addFrame(walkLFrame1);
+
+        animationStateManager.add(idleR);
+        animationStateManager.add(walkR);
+
+        animationStateManager.add(idleL);
+        animationStateManager.add(walkL);
+        return animationStateManager;
+    }
+
+    @Override
+    public Actor clone() {
+        return new Knight(getPosition());
+    }
+
+    @Override
+    public void destroy() {
+        super.destroy();
+    }
+
+    public void setCarrying(boolean carrying) {
+        this.carrying = carrying;
+    }
+
+    public boolean isCarrying() {
+        return carrying;
+    }
+
+    public int getLAYER() {
+        return LAYER;
+    }
+}
diff --git a/src/actor/Lightning.java b/src/actor/Lightning.java
new file mode 100644
index 0000000000000000000000000000000000000000..d32860a9585bec4c47dd4db5ce62c4e93937486a
--- /dev/null
+++ b/src/actor/Lightning.java
@@ -0,0 +1,84 @@
+package actor;
+
+import Animation.Animation;
+import Animation.AnimationStateManager;
+import bagel.Image;
+import myUtil.Vec2D;
+
+public class Lightning extends Actor {
+    //state
+    public static final int HORIZON = 0;
+    public static final int VERTICAL = 1;
+
+    private static final int LAYER = 3;
+
+    private int relateID;
+
+    //type
+    private int currentType;
+
+    public Lightning(Vec2D spawnPoint, int currentType, int relateID) {
+        super(spawnPoint);
+        if (getAnimationManager() == null) {
+            setGetAnimationManager(newAnimationManager());
+        }
+
+        setLayer(LAYER);
+
+        this.relateID = relateID;
+        setMoving(false);
+        setActive(false);
+        this.currentType = currentType;
+        getAnimationManager().toState(this.currentType);
+    }
+
+    @Override
+    public void behavior() {
+
+    }
+
+    @Override
+    public void animationUpdate() {
+    }
+
+    @Override
+    public void onInteract(Actor actor) {
+        if (actor instanceof Knight) {
+            actor.destroy();
+        }
+    }
+
+    private static AnimationStateManager newAnimationManager() {
+        AnimationStateManager animationStateManager = new AnimationStateManager();
+
+        Animation horizon = new Animation();
+        Image frame00 = new Image("res/ActorExtensionPack/Actor/WallMaker/wall_horizontal_0.png");
+        Image frame01 = new Image("res/ActorExtensionPack/Actor/WallMaker/wall_horizontal_1.png");
+        horizon.addFrame(frame00);
+        horizon.addFrame(frame01);
+
+        Animation vertical = new Animation();
+        Image frame10 = new Image("res/ActorExtensionPack/Actor/WallMaker/wall_vertical_0.png");
+        Image frame11 = new Image("res/ActorExtensionPack/Actor/WallMaker/wall_vertical_1.png");
+        vertical.addFrame(frame10);
+        vertical.addFrame(frame11);
+
+        animationStateManager.add(horizon);
+        animationStateManager.add(vertical);
+
+        return animationStateManager;
+    }
+
+    public int getRelateID() {
+        return relateID;
+    }
+
+    @Override
+    public Actor clone() {
+        return new Lightning(getPosition(), currentType, relateID);
+    }
+
+    public int getLAYER() {
+        return LAYER;
+    }
+}
diff --git a/src/actor/Portal.java b/src/actor/Portal.java
new file mode 100644
index 0000000000000000000000000000000000000000..efe87353b07f754b19f82fcd7c83f851a801cb42
--- /dev/null
+++ b/src/actor/Portal.java
@@ -0,0 +1,147 @@
+package actor;
+
+import Animation.Animation;
+import Animation.AnimationStateManager;
+import Level.Level;
+import bagel.Image;
+import myUtil.Vec2D;
+
+import java.util.ArrayList;
+
+public class Portal extends Actor{
+
+    //state
+    private static final int PORTAL_REST = 0;
+
+    private static final int LAYER = 1;
+
+    private int pairID;
+    private static int pair = 0;
+    private ArrayList<Actor> temp;
+
+    Level castToLevel;
+
+    public Portal(Vec2D spawnPoint, Vec2D pairSpawnPoint, Level castToLevel) {
+        super(spawnPoint);
+        if (getAnimationManager() == null) {
+            setGetAnimationManager(newAnimationManager());
+        }
+
+        setLayer(LAYER);
+
+        setMoving(false);
+        setActive(false);
+        this.pairID = getPair();
+        setCastToLevel(castToLevel);
+
+        addPair(pairSpawnPoint, castToLevel);
+
+        getAnimationManager().toState(PORTAL_REST);
+    }
+
+    public Portal(Vec2D spawnPoint, Vec2D pairSpawnPoint, ArrayList<Actor> temp, Level castToLevel) {
+        super(spawnPoint);
+        if (getAnimationManager() == null) {
+            setGetAnimationManager(newAnimationManager());
+        }
+
+        setLayer(LAYER);
+
+        setMoving(false);
+        setActive(false);
+        this.pairID = getPair();
+        setCastToLevel(castToLevel);
+        this.temp = temp;
+        addPair(pairSpawnPoint);
+
+        getAnimationManager().toState(PORTAL_REST);
+    }
+
+    public Portal(Vec2D spawnPoint, int pairID, Level castToLevel) {
+        super(spawnPoint);
+        if (getAnimationManager() == null) {
+            setGetAnimationManager(newAnimationManager());
+        }
+
+        setLayer(LAYER);
+
+        setMoving(false);
+        setActive(false);
+        this.pairID = pairID;
+
+        setCastToLevel(castToLevel);
+
+        getAnimationManager().toState(PORTAL_REST);
+    }
+
+    @Override
+    public void behavior() {
+    }
+
+    @Override
+    public void animationUpdate() {
+    }
+
+    @Override
+    public void onInteract(Actor actor) {
+        if (!actor.isActive()) {
+            return;
+        }
+        for (Actor pair : castToLevel.getActors()) {
+            if (pair != this && pair instanceof Portal) {
+                if (((Portal) pair).getPairID() == this.pairID) {
+                    if (!actor.isTransfer()) {
+                        actor.setPosition(pair.getPosition().clone());
+                        actor.transfer();
+                    }
+                }
+            }
+        }
+    }
+
+    private static AnimationStateManager newAnimationManager() {
+        AnimationStateManager animationStateManager = new AnimationStateManager();
+
+        Animation portalRest = new Animation();
+        Image frame0 = new Image("res/ActorExtensionPack/Actor/Portal/portal_0.png");
+        Image frame1 = new Image("res/ActorExtensionPack/Actor/Portal/portal_1.png");
+        Image frame2 = new Image("res/ActorExtensionPack/Actor/Portal/portal_2.png");
+        portalRest.addFrame(frame0);
+        portalRest.addFrame(frame1);
+        portalRest.addFrame(frame2);
+
+        animationStateManager.add(portalRest);
+
+        return animationStateManager;
+    }
+
+    public void setCastToLevel(Level castToLevel) {
+        this.castToLevel = castToLevel;
+    }
+
+    public void addPair(Vec2D spawnPoint, Level castToLevel) {
+        castToLevel.add(new Portal(spawnPoint, this.getPairID(), castToLevel));
+    }
+
+    public void addPair(Vec2D spawnPoint) {
+        temp.add(new Portal(spawnPoint, this.getPairID(), castToLevel));
+    }
+
+    public static int getPair() {
+        pair++;
+        return pair;
+    }
+
+    public int getPairID() {
+        return pairID;
+    }
+
+    @Override
+    public Actor clone() {
+        return new Portal(getPosition(), getPairID(), castToLevel);
+    }
+
+    public int getLAYER() {
+        return LAYER;
+    }
+}
diff --git a/src/actor/Projectile.java b/src/actor/Projectile.java
new file mode 100644
index 0000000000000000000000000000000000000000..64a14938433481f191e9a87b521dd60da91da218
--- /dev/null
+++ b/src/actor/Projectile.java
@@ -0,0 +1,88 @@
+package actor;
+
+import Animation.Animation;
+import Animation.AnimationStateManager;
+import bagel.Image;
+import myUtil.Vec2D;
+
+public class Projectile extends Actor {
+    //state
+    public static final int MAGIC = 0;
+    public static final int FIRE = 1;
+
+    private static final int LAYER = 3;
+
+    //Direction constant
+    private static final Vec2D UP_VEC = new Vec2D(0, -1);
+    private static final Vec2D DOWN_VEC = new Vec2D(0, 1);
+    private static final Vec2D LEFT_VEC = new Vec2D(-1, 0);
+    private static final Vec2D RIGHT_VEC = new Vec2D(1, 0);
+
+    private static final int PROJECTILE_SPEED = 2;
+
+    public Projectile(Vec2D spawnPoint, int type) {
+        super(spawnPoint);
+        if (getAnimationManager() == null) {
+            setGetAnimationManager(newAnimationManager());
+        }
+
+        setLayer(LAYER);
+
+        setMoving(false);
+        setDirection(RIGHT);
+        setActive(true);
+
+        getAnimationManager().toState(type);
+    }
+
+    @Override
+    public void behavior() {
+        resetTransfer();
+        move();
+    }
+
+    @Override
+    public void animationUpdate() {}
+
+    @Override
+    public void onInteract(Actor actor) {
+        if (actor instanceof Knight) {
+            actor.destroy();
+        }
+    }
+
+    private static AnimationStateManager newAnimationManager() {
+        AnimationStateManager animationStateManager = new AnimationStateManager();
+
+        Animation magic = new Animation();
+        Image frame00 = new Image("res/ActorExtensionPack/Actor/Witch/magicBall_0.png");
+        Image frame01 = new Image("res/ActorExtensionPack/Actor/Witch/magicBall_1.png");
+        Image frame02 = new Image("res/ActorExtensionPack/Actor/Witch/magicBall_2.png");
+        magic.addFrame(frame00);
+        magic.addFrame(frame01);
+        magic.addFrame(frame02);
+
+
+        Animation fire = new Animation();
+        Image frame10 = new Image("res/ActorExtensionPack/Actor/FireSkull/fireBall_0.png");
+        Image frame11 = new Image("res/ActorExtensionPack/Actor/FireSkull/fireBall_1.png");
+        Image frame12 = new Image("res/ActorExtensionPack/Actor/FireSkull/fireBall_2.png");
+        fire.addFrame(frame10);
+        fire.addFrame(frame11);
+        fire.addFrame(frame12);
+
+        animationStateManager.add(magic);
+        animationStateManager.add(fire);
+
+        return animationStateManager;
+    }
+
+    @Override
+    public Actor clone() {
+        return null;
+    }
+
+    public int getLAYER() {
+        return LAYER;
+    }
+}
diff --git a/src/actor/Sign.java b/src/actor/Sign.java
new file mode 100644
index 0000000000000000000000000000000000000000..57a1d9ebdea4ce049a0070301239682ec0827b76
--- /dev/null
+++ b/src/actor/Sign.java
@@ -0,0 +1,86 @@
+package actor;
+
+import Animation.Animation;
+import Animation.AnimationStateManager;
+import bagel.Image;
+import myUtil.Vec2D;
+
+public class Sign extends Actor{
+    //type
+    private static final String TYPE = "Sign";
+
+    private static final int LAYER = 0;
+
+    //image path
+    private static final String PATH_SIGN_UP = "res/images/up.png";
+    private static final String PATH_SIGN_DOWN = "res/images/down.png";
+    private static final String PATH_SIGN_LEFT = "res/images/left.png";
+    private static final String PATH_SIGN_RIGHT = "res/images/right.png";
+
+    public Sign(Vec2D spawnPoint, int direction) {
+        super(spawnPoint);
+
+        //Set Properties
+        setMoving(false);
+        setActive(false);
+        setDirection(direction);
+
+        setLayer(LAYER);
+
+        if (getAnimationManager() == null) {
+            setGetAnimationManager(newAnimationManager());
+        }
+
+        //set appearance
+        getAnimationManager().toState(direction);
+    }
+
+    @Override
+    public void behavior() {
+    }
+
+    @Override
+    public void animationUpdate() {}
+
+    @Override
+    public void onInteract(Actor actor) {
+        if (actor instanceof Knight) {
+            actor.setDirection(this.getDirection());
+        }
+    }
+
+    private static AnimationStateManager newAnimationManager() {
+        AnimationStateManager animationStateManager = new AnimationStateManager();
+
+        Animation sign0 = new Animation();
+        Animation sign1 = new Animation();
+        Animation sign2 = new Animation();
+        Animation sign3 = new Animation();
+        Image frame0 = new Image(PATH_SIGN_UP);
+        Image frame1 = new Image(PATH_SIGN_RIGHT);
+        Image frame2 = new Image(PATH_SIGN_DOWN);
+        Image frame3 = new Image(PATH_SIGN_LEFT);
+        sign0.addFrame(frame0);
+        sign1.addFrame(frame1);
+        sign2.addFrame(frame2);
+        sign3.addFrame(frame3);
+
+        animationStateManager.add(sign0);
+        animationStateManager.add(sign1);
+        animationStateManager.add(sign2);
+        animationStateManager.add(sign3);
+
+        return animationStateManager;
+    }
+
+    @Override
+    public Actor clone() {
+        return new Sign(getPosition(), getDirection());
+    }
+
+    public int getLAYER() {
+        return LAYER;
+    }
+
+
+}
diff --git a/src/actor/Skeleton.java b/src/actor/Skeleton.java
new file mode 100644
index 0000000000000000000000000000000000000000..54a31dcc5857b35e33782cff9fe29469b55105ed
--- /dev/null
+++ b/src/actor/Skeleton.java
@@ -0,0 +1,152 @@
+package actor;
+
+import Animation.Animation;
+import Animation.AnimationStateManager;
+import bagel.Image;
+import myUtil.Vec2D;
+import Level.*;
+
+public class Skeleton extends Actor {
+    //state
+    private static final int IDLE_VERTICAL = 0;
+    private static final int WALK_VERTICAL = 2;
+    private static final int IDLE_HORIZON = 1;
+    private static final int WALK_HORIZON = 3;
+
+    private static final int LAYER = 2;
+
+    //type
+    public static final int TYPE_VERTICAL = 0;
+    public static final int TYPE_HORIZON = 1;
+
+    //wander loop
+    private int wanderLoop;
+    private int currentWander;
+
+    private int currentType;
+
+
+    public Skeleton(Vec2D spawnPoint, int direction, int wanderLoop) {
+        super(spawnPoint);
+        if (getAnimationManager() == null) {
+            setGetAnimationManager(newAnimationManager());
+        }
+
+        setMoving(false);
+        setActive(true);
+
+        setDirection(direction);
+
+        setLayer(LAYER);
+
+        //initialize type
+        if (direction == RIGHT || direction == LEFT) {
+            this.currentType = TYPE_HORIZON;
+        } else if (direction == UP || direction == DOWN) {
+            this.currentType = TYPE_VERTICAL;
+        }
+
+        currentWander = 0;
+        this.wanderLoop = --wanderLoop;
+    }
+
+    @Override
+    public void behavior() {
+        resetTransfer();
+        move();
+        if (currentWander == wanderLoop - 1) {
+            turnAround();
+        }
+        currentWander++;
+        currentWander = currentWander % wanderLoop;
+
+    }
+
+    @Override
+    public void animationUpdate() {
+        if (isMoving()) {
+            if (currentType == TYPE_VERTICAL) {
+                getAnimationManager().toState(WALK_VERTICAL);
+            } else if (currentType == TYPE_HORIZON) {
+                getAnimationManager().toState(WALK_HORIZON);
+            }
+        } else {
+            if (currentType == TYPE_VERTICAL) {
+                getAnimationManager().toState(IDLE_VERTICAL);
+            } else if (currentType == TYPE_HORIZON) {
+                getAnimationManager().toState(IDLE_HORIZON);
+            }
+        }
+    }
+
+    @Override
+    public void onInteract(Actor actor) {
+        if (actor instanceof Knight) {
+            actor.destroy();
+        }
+    }
+
+    private static AnimationStateManager newAnimationManager() {
+        AnimationStateManager animationStateManager = new AnimationStateManager();
+
+        Animation idleVertical = new Animation();
+        Image frame00 = new Image("res/ActorExtensionPack/Actor/Skeleton/skeleton_up_idle_0.png");
+        Image frame01 = new Image("res/ActorExtensionPack/Actor/Skeleton/skeleton_up_idle_1.png");
+        Image frame02 = new Image("res/ActorExtensionPack/Actor/Skeleton/skeleton_up_idle_2.png");
+        idleVertical.addFrame(frame00);
+        idleVertical.addFrame(frame01);
+        idleVertical.addFrame(frame02);
+
+        Animation idleHorizon = new Animation();
+        Image frame10 = new Image("res/ActorExtensionPack/Actor/Skeleton/skeleton_down_idle_0.png");
+        Image frame11 = new Image("res/ActorExtensionPack/Actor/Skeleton/skeleton_down_idle_1.png");
+        Image frame12 = new Image("res/ActorExtensionPack/Actor/Skeleton/skeleton_down_idle_2.png");
+        idleHorizon.addFrame(frame10);
+        idleHorizon.addFrame(frame11);
+        idleHorizon.addFrame(frame12);
+
+        Animation walkVertical = new Animation();
+        Image frame20 = new Image("res/ActorExtensionPack/Actor/Skeleton/skeleton_up_walk_0.png");
+        Image frame21 = new Image("res/ActorExtensionPack/Actor/Skeleton/skeleton_up_walk_1.png");
+        walkVertical.addFrame(frame20);
+        walkVertical.addFrame(frame21);
+
+        Animation walkHorizon = new Animation();
+        Image frame30 = new Image("res/ActorExtensionPack/Actor/Skeleton/skeleton_down_walk_0.png");
+        Image frame31 = new Image("res/ActorExtensionPack/Actor/Skeleton/skeleton_down_walk_1.png");
+        walkHorizon.addFrame(frame30);
+        walkHorizon.addFrame(frame31);
+
+        animationStateManager.add(idleVertical);
+        animationStateManager.add(idleHorizon);
+        animationStateManager.add(walkVertical);
+        animationStateManager.add(walkHorizon);
+
+        return animationStateManager;
+    }
+
+    public int getWanderLoop() {
+        return wanderLoop;
+    }
+
+    public int getCurrentType() {
+        return currentType;
+    }
+
+    public void setCurrentType(int currentType) {
+        this.currentType = currentType;
+    }
+
+    public void setWanderLoop(int wanderLoop) {
+        this.wanderLoop = wanderLoop;
+    }
+
+    @Override
+    public Actor clone() {
+        return new Skeleton(getPosition(),getDirection(), wanderLoop);
+    }
+
+    public int getLAYER() {
+        return LAYER;
+    }
+}
diff --git a/src/actor/Skull.java b/src/actor/Skull.java
new file mode 100644
index 0000000000000000000000000000000000000000..3d9f1b39b96003dfb6d9f615d5812f693f95fa4c
--- /dev/null
+++ b/src/actor/Skull.java
@@ -0,0 +1,120 @@
+package actor;
+
+import Animation.Animation;
+import Animation.AnimationStateManager;
+import Level.Level;
+import bagel.Image;
+import myUtil.MyMath;
+import myUtil.Vec2D;
+
+public class Skull extends Actor {
+    //state
+    private static final int IDLE = 0;
+    private static final int ATTACK = 1;
+
+    private static final int LAYER = 2;
+
+    //wander loop
+    private int wanderLoop;
+    private int currentWander;
+
+    Level castToLevel;
+
+    public Skull(Vec2D spawnPoint, int direction, int wanderLoop) {
+        super(spawnPoint);
+
+        if (getAnimationManager() == null) {
+            setGetAnimationManager(newAnimationManager());
+        }
+
+        setMoving(false);
+        setActive(true);
+
+        setLayer(LAYER);
+
+        setDirection(direction);
+
+        currentWander = 0;
+        this.wanderLoop = --wanderLoop;
+    }
+
+    @Override
+    public void behavior() {
+        resetTransfer();
+        if (currentWander == 0) {
+            turnAround();
+        }
+
+        if (MyMath.isEven(currentWander) && currentWander != 0) {
+            castToLevel.pend(new Projectile(getPosition().clone(), Projectile.FIRE));
+        }
+        move();
+        currentWander++;
+        currentWander = currentWander % wanderLoop;
+    }
+
+    @Override
+    public void animationUpdate() {
+        getAnimationManager().toState(IDLE);
+        if (MyMath.isEven(currentWander) && currentWander != 0) {
+            getAnimationManager().toState(ATTACK);
+        } else {
+            getAnimationManager().toState(IDLE);
+        }
+    }
+
+    @Override
+    public void onInteract(Actor actor) {
+        if (actor instanceof Knight) {
+            actor.destroy();
+        }
+    }
+
+    private static AnimationStateManager newAnimationManager() {
+        AnimationStateManager animationStateManager = new AnimationStateManager();
+
+        Animation idle = new Animation();
+        Image frame00 = new Image("res/ActorExtensionPack/Actor/FireSkull/skull_normal_idle_0.png");
+        Image frame01 = new Image("res/ActorExtensionPack/Actor/FireSkull/skull_normal_idle_1.png");
+        Image frame02 = new Image("res/ActorExtensionPack/Actor/FireSkull/skull_normal_idle_2.png");
+        Image frame03 = new Image("res/ActorExtensionPack/Actor/FireSkull/skull_normal_idle_3.png");
+        idle.addFrame(frame00);
+        idle.addFrame(frame01);
+        idle.addFrame(frame02);
+        idle.addFrame(frame03);
+
+        Animation attack = new Animation();
+        Image frame10 = new Image("res/ActorExtensionPack/Actor/FireSkull/skull_attack_idle_0.png");
+        Image frame11 = new Image("res/ActorExtensionPack/Actor/FireSkull/skull_attack_idle_1.png");
+        Image frame12 = new Image("res/ActorExtensionPack/Actor/FireSkull/skull_attack_idle_2.png");
+        Image frame13 = new Image("res/ActorExtensionPack/Actor/FireSkull/skull_attack_idle_3.png");
+        attack.addFrame(frame10);
+        attack.addFrame(frame11);
+        attack.addFrame(frame12);
+        attack.addFrame(frame13);
+
+        animationStateManager.add(idle);
+        animationStateManager.add(attack);
+
+        return animationStateManager;
+    }
+
+    public void setCastToLevel(Level castToLevel) {
+        this.castToLevel = castToLevel;
+    }
+
+    @Override
+    public Actor clone() {
+        Actor skull = new Skull(getPosition(), getDirection(), wanderLoop);
+        ((Skull) skull).setCastToLevel(castToLevel);
+        return skull;
+    }
+
+    public int getWanderLoop() {
+        return wanderLoop;
+    }
+
+    public int getLAYER() {
+        return LAYER;
+    }
+}
diff --git a/src/actor/Spider.java b/src/actor/Spider.java
new file mode 100644
index 0000000000000000000000000000000000000000..4cacec1a15397edb0d3a3cc52e9ccad0bce66f25
--- /dev/null
+++ b/src/actor/Spider.java
@@ -0,0 +1,134 @@
+package actor;
+
+import Animation.Animation;
+import Animation.AnimationStateManager;
+import bagel.Image;
+import myUtil.Vec2D;
+
+public class Spider extends Actor {
+    //state
+    private static final int IDLE = 0;
+    private static final int WALK = 1;
+
+    //direction choice
+    private static final int FIRST = 0;
+    private static final int SECOND = 1;
+
+    private static final int LAYER = 2;
+
+    //wander loop
+    private int wanderLoop;
+    private int currentWander;
+
+    private int direction0;
+    private int direction1;
+
+    public Spider(Vec2D spawnPoint, int direction0, int direction1, int wanderLoop) {
+        super(spawnPoint);
+        if (getAnimationManager() == null) {
+            setGetAnimationManager(newAnimationManager());
+        }
+
+        setMoving(false);
+        setActive(true);
+
+        setLayer(LAYER);
+
+        setDirection(direction0);
+
+        this.direction0 = direction0;
+        this.direction1 = direction1;
+
+        currentWander = 0;
+        this.wanderLoop = wanderLoop;
+    }
+
+    @Override
+    public void behavior() {
+        resetTransfer();
+
+        setDirection(direction0);
+        move();
+        setDirection(direction1);
+        move();
+
+        if (currentWander == wanderLoop - 1) {
+            if (direction0 == RIGHT) {
+                direction0 = LEFT;
+            } else if (direction0 == LEFT) {
+                direction0 = RIGHT;
+            }
+
+            if (direction1 == UP) {
+                direction1 = DOWN;
+            } else if (direction1 == DOWN) {
+                direction1 = UP;
+            }
+        }
+        currentWander++;
+        currentWander = currentWander % wanderLoop;
+
+    }
+
+    @Override
+    public void animationUpdate() {
+        if (isMoving()) {
+            getAnimationManager().toState(WALK);
+        } else {
+            getAnimationManager().toState(IDLE);
+        }
+    }
+
+    @Override
+    public void onInteract(Actor actor) {
+        if (actor instanceof Knight) {
+            actor.destroy();
+        }
+    }
+
+    private static AnimationStateManager newAnimationManager() {
+        AnimationStateManager animationStateManager = new AnimationStateManager();
+
+        Animation idle = new Animation();
+        Image frame00 = new Image("res/ActorExtensionPack/Actor/Spider/spider_idle_0.png");
+        Image frame01 = new Image("res/ActorExtensionPack/Actor/Spider/spider_idle_1.png");
+        idle.addFrame(frame00);
+        idle.addFrame(frame01);
+
+        Animation walk = new Animation();
+        Image frame10 = new Image("res/ActorExtensionPack/Actor/Spider/spider_move_0.png");
+        Image frame11 = new Image("res/ActorExtensionPack/Actor/Spider/spider_move_1.png");
+        Image frame12 = new Image("res/ActorExtensionPack/Actor/Spider/spider_move_2.png");
+        Image frame13 = new Image("res/ActorExtensionPack/Actor/Spider/spider_move_3.png");
+        walk.addFrame(frame10);
+        walk.addFrame(frame11);
+        walk.addFrame(frame12);
+        walk.addFrame(frame13);
+
+        animationStateManager.add(idle);
+        animationStateManager.add(walk);
+
+        return animationStateManager;
+    }
+
+    @Override
+    public Actor clone() {
+        return new Spider(getPosition(), direction0, direction1, wanderLoop);
+    }
+
+    public int getWanderLoop() {
+        return wanderLoop;
+    }
+
+    public int getLAYER() {
+        return LAYER;
+    }
+
+    public int getDirection0() {
+        return direction0;
+    }
+
+    public int getDirection1() {
+        return direction1;
+    }
+}
diff --git a/src/actor/Trap.java b/src/actor/Trap.java
new file mode 100644
index 0000000000000000000000000000000000000000..e06722625c3bdb8a5d0e3c6c450bdf6cc82efd96
--- /dev/null
+++ b/src/actor/Trap.java
@@ -0,0 +1,106 @@
+package actor;
+
+import Animation.Animation;
+import Animation.AnimationStateManager;
+import Level.Level;
+import bagel.Image;
+import myUtil.Vec2D;
+
+public class Trap extends Actor {
+    //state
+    private static final int TRAP_REST = 0;
+    private static final int TRAP_ATTACK = 1;
+
+    public static final int ON = 1;
+    public static final int OFF = 0;
+
+    private static final int LAYER = 0;
+
+    private boolean attack;
+
+    private int on;
+
+    public Trap(Vec2D spawnPoint, int on) {
+        super(spawnPoint);
+        if (getAnimationManager() == null) {
+            setGetAnimationManager(newAnimationManager());
+        }
+
+        setLayer(LAYER);
+
+        setMoving(false);
+        setActive(false);
+
+        this.on = on;
+        if (on == ON) {
+            attack = true;
+        } else if (on == OFF) {
+            attack = false;
+        }
+    }
+
+    @Override
+    public void behavior() {
+        if (!attack) {
+            attack = true;
+        } else {
+            attack = false;
+        }
+    }
+
+    @Override
+    public void animationUpdate() {
+        if (!attack) {
+            getAnimationManager().toState(TRAP_REST);
+        } else {
+            getAnimationManager().toState(TRAP_ATTACK);
+        }
+
+    }
+
+    @Override
+    public void onInteract(Actor actor) {
+        if (actor instanceof Knight && attack) {
+            actor.destroy();
+        }
+    }
+
+    private static AnimationStateManager newAnimationManager() {
+        AnimationStateManager animationStateManager = new AnimationStateManager();
+
+        Animation trapRest = new Animation();
+        Animation trapAttack = new Animation();
+        Image frame0 = new Image("res/ActorExtensionPack/Actor/Trap/trap_0.png");
+        Image frame2 = new Image("res/ActorExtensionPack/Actor/Trap/trap_2.png");
+        trapRest.addFrame(frame0);
+        trapAttack.addFrame(frame2);
+
+        animationStateManager.add(trapRest);
+        animationStateManager.add(trapAttack);
+
+        return animationStateManager;
+    }
+
+    @Override
+    public Actor clone() {
+        return new Trap(getPosition(), on);
+    }
+
+    public int getLAYER() {
+        return LAYER;
+    }
+
+    public void trigger() {
+        if (on == ON) {
+            on = OFF;
+            attack = false;
+        } else if (on == OFF) {
+            on = ON;
+            attack = true;
+        }
+    }
+
+    public int getOn() {
+        return on;
+    }
+}
diff --git a/src/actor/WallMaker.java b/src/actor/WallMaker.java
new file mode 100644
index 0000000000000000000000000000000000000000..c39dab543e9e6ef62fb2a1ade1b4c1bf1d9aaa4b
--- /dev/null
+++ b/src/actor/WallMaker.java
@@ -0,0 +1,88 @@
+package actor;
+
+import Animation.Animation;
+import Animation.AnimationStateManager;
+import bagel.Image;
+import myUtil.Vec2D;
+
+public class WallMaker extends Actor{
+    //state
+    private static final int STAND = 0;
+
+    private int relateID;
+    private static int wID = 0;
+
+    private static final int LAYER = 2;
+
+    public WallMaker(Vec2D spawnPoint) {
+        super(spawnPoint);
+        if (getAnimationManager() == null) {
+            setGetAnimationManager(newAnimationManager());
+        }
+
+        relateID = wID;
+        wID++;
+
+        setLayer(LAYER);
+
+        setMoving(false);
+        setActive(false);
+        getAnimationManager().toState(STAND);
+    }
+
+    public WallMaker(Vec2D spawnPoint, int relateID) {
+        super(spawnPoint);
+        if (getAnimationManager() == null) {
+            setGetAnimationManager(newAnimationManager());
+        }
+
+        setLayer(LAYER);
+
+        this.relateID = relateID;
+
+        setMoving(false);
+        setActive(false);
+        getAnimationManager().toState(STAND);
+    }
+
+    @Override
+    public void behavior() {
+
+    }
+
+    @Override
+    public void animationUpdate() {
+    }
+
+    @Override
+    public void onInteract(Actor actor) {
+        if (actor instanceof Knight) {
+            actor.destroy();
+        }
+    }
+
+    private static AnimationStateManager newAnimationManager() {
+        AnimationStateManager animationStateManager = new AnimationStateManager();
+
+        Animation stand = new Animation();
+        Image frame0 = new Image("res/ActorExtensionPack/Actor/WallMaker/wallMaker.png");
+        stand.addFrame(frame0);
+
+        animationStateManager.add(stand);
+
+        return animationStateManager;
+    }
+
+    public int getRelateID() {
+        return relateID;
+    }
+
+    @Override
+    public Actor clone() {
+        return new WallMaker(getPosition(), relateID);
+    }
+
+    public int getLAYER() {
+        return LAYER;
+    }
+}
diff --git a/src/actor/Witch.java b/src/actor/Witch.java
new file mode 100644
index 0000000000000000000000000000000000000000..5eea34c625c1c395a6b2a40f82939a1fc8ab9e9a
--- /dev/null
+++ b/src/actor/Witch.java
@@ -0,0 +1,110 @@
+package actor;
+
+import Animation.Animation;
+import Animation.AnimationStateManager;
+import Level.Level;
+import bagel.Image;
+import myUtil.MyMath;
+import myUtil.Vec2D;
+
+public class Witch extends Actor {
+    //state
+    private static final int IDLE = 1;
+    private static final int WALK = 0;
+
+    private static final int LAYER = 2;
+
+    //wander loop
+    private int wanderLoop;
+    private int currentWander;
+
+    Level castToLevel;
+
+    public Witch(Vec2D spawnPoint, int direction, int wanderLoop) {
+        super(spawnPoint);
+
+        if (getAnimationManager() == null) {
+            setGetAnimationManager(newAnimationManager());
+        }
+
+        setLayer(LAYER);
+
+        setMoving(false);
+        setActive(true);
+
+        setDirection(direction);
+
+        currentWander = 0;
+        this.wanderLoop = --wanderLoop;
+    }
+
+    @Override
+    public void behavior() {
+        resetTransfer();
+        if (currentWander == 0) {
+            turnAround();
+        }
+        move();
+        if (MyMath.isOdd(currentWander) && currentWander != 0) {
+            castToLevel.pend(new Projectile(getPosition().out_add(Level.TILED_LENGTH), Projectile.MAGIC));
+            castToLevel.pend(new Projectile(getPosition().out_sub(Level.TILED_LENGTH), Projectile.MAGIC));
+        }
+        currentWander++;
+        currentWander = currentWander % wanderLoop;
+    }
+
+    @Override
+    public void animationUpdate() {
+        if (isMoving()) {
+            getAnimationManager().toState(WALK);
+        }
+        getAnimationManager().toState(IDLE);
+    }
+
+    @Override
+    public void onInteract(Actor actor) {
+        if (actor instanceof Knight) {
+            actor.destroy();
+        }
+    }
+
+    private static AnimationStateManager newAnimationManager() {
+        AnimationStateManager animationStateManager = new AnimationStateManager();
+
+        Animation walk = new Animation();
+        Image frame00 = new Image("res/ActorExtensionPack/Actor/Witch/witch_walk_0.png");
+        Image frame01 = new Image("res/ActorExtensionPack/Actor/Witch/witch_walk_1.png");
+        walk.addFrame(frame00);
+        walk.addFrame(frame01);
+
+        Animation idle = new Animation();
+        Image frame10 = new Image("res/ActorExtensionPack/Actor/Witch/witch_idle_0.png");
+        Image frame11 = new Image("res/ActorExtensionPack/Actor/Witch/witch_idle_1.png");
+        idle.addFrame(frame10);
+        idle.addFrame(frame11);
+
+        animationStateManager.add(idle);
+        animationStateManager.add(walk);
+
+        return animationStateManager;
+    }
+
+    public void setCastToLevel(Level castToLevel) {
+        this.castToLevel = castToLevel;
+    }
+
+    @Override
+    public Actor clone() {
+        Actor witch = new Witch(getPosition(), getDirection(), wanderLoop);
+        ((Witch) witch).setCastToLevel(castToLevel);
+        return witch;
+    }
+
+    public int getWanderLoop() {
+        return wanderLoop;
+    }
+
+    public int getLAYER() {
+        return LAYER;
+    }
+}
diff --git a/src/myUtil/MyMath.java b/src/myUtil/MyMath.java
new file mode 100644
index 0000000000000000000000000000000000000000..04b2ec1137a591f86b8c258a4d6dfd2ce32b8ff0
--- /dev/null
+++ b/src/myUtil/MyMath.java
@@ -0,0 +1,268 @@
+package myUtil;
+
+public class MyMath {
+    /**
+     * This class is created for float calculation.
+     */
+    /**
+     * Commonly used value
+     */
+    public static final float HALF = 0.5f;
+    public static final float DOUBLE = 2.0f;
+
+    /**
+     * Commonly used radian value
+     */
+    public static final float PI = 3.14159f;
+    public static final float RAD0 = 0.0f;
+    public static final float RAD30 = 0.52360f;
+    public static final float RAD45 = 0.78540f;
+    public static final float RAD60 = 1.04720f;
+    public static final float RAD90 = HALF * PI;
+    public static final float RAD120 = 4.0f * RAD30;
+    public static final float RAD135 = 3.0f * RAD45;
+    public static final float RAD150 = 5.0f * RAD30;
+    public static final float RAD180 = PI;
+    public static final float RAD270 = 3.0f * RAD90;
+    public static final float RAD360 = 2.0f * PI;
+
+    /**
+     * return the square of the float
+     * @param a a float
+     * @return The square of value a
+     */
+    public static float sqr(float a) {
+        return a * a;
+    }
+
+    /**
+     * return the square root of the float
+     * @param a a float
+     * @return The square root of value a
+     */
+    public static float sqrt(float a) {
+        return (float)StrictMath.sqrt(a);
+    }
+
+    /**
+     * return the sin of the float
+     * @param a a float
+     * @return The sin of value a
+     */
+    public static float sin(float a) {
+        return (float)StrictMath.sin(a);
+    }
+
+    /**
+     * return the cos of the float
+     * @param a a float
+     * @return The cos of value a
+     */
+    public static float cos(float a) {
+        return (float)StrictMath.cos(a);
+    }
+
+    /**
+     * return the tan of the float
+     * @param a a float
+     * @return The tan of value a
+     */
+    public static float tan(float a) {
+        return (float)StrictMath.tan(a);
+    }
+
+    /**
+     * return the arcsin of the float
+     * @param a a float
+     * @return The arcsin of value a
+     */
+    public static float asin(float a) {
+        return (float)StrictMath.asin(a);
+    }
+
+    /**
+     * return the arccos of the float
+     * @param a a float
+     * @return The arccos of value a
+     */
+    public static float acos(float a) {
+        return (float)StrictMath.acos(a);
+    }
+
+    /**
+     * return the arctan of the float
+     * @param a a float
+     * @return The arctan of value a
+     */
+    public static float atan(float a) {
+        return (float)StrictMath.atan(a);
+    }
+
+    /**
+     * return the sinh of the float
+     * @param a a float
+     * @return The sinh of value a
+     */
+    public static float sinh(float a) {
+        return (float)StrictMath.sinh(a);
+    }
+
+    /**
+     * return the cosh of the float
+     * @param a a float
+     * @return The cosh of value a
+     */
+    public static float cosh(float a) {
+        return (float)StrictMath.cosh(a);
+    }
+
+    /**
+     * return the tanh of the float
+     * @param a a float
+     * @return The tanh of value a
+     */
+    public static float tanh(float a) {
+        return (float)StrictMath.tanh(a);
+    }
+
+    /**
+     * return the absolute value of the float
+     * @param a a float
+     * @return The absolute value of value a
+     */
+    public static float abs(float a) {
+        return StrictMath.abs(a);
+    }
+
+    /**
+     * return the max value of two float number
+     * @param a a float
+     * @param b a float
+     * @return The max value
+     */
+    public static float max(float a, float b) {
+        return StrictMath.max(a, b);
+    }
+
+    /**
+     * return the min value of two float number
+     * @param a a float
+     * @param b a float
+     * @return The min value
+     */
+    public static float min(float a, float b) {
+        return StrictMath.min(a, b);
+    }
+
+    /**
+     * return the max value among multiple float number
+     * @param a multiple float
+     * @return The max value among a
+     */
+    public static float maxs(float ... a) {
+        float max = a[0];
+        for (int i = 1; i < a.length; i++) {
+            if (max < a[i]) {
+                max = a[i];
+            }
+        }
+        return max;
+    }
+
+    /**
+     * return the min value among multiple float number
+     * @param a multiple float
+     * @return The min value among a
+     */
+    public static float mins(float ... a) {
+        float min = a[0];
+        for (int i = 1; i < a.length; i++) {
+            if (min > a[i]) {
+                min = a[i];
+            }
+        }
+        return min;
+    }
+
+    /**
+     * return a random number between a and b
+     * @param a a float
+     * @param b a float
+     * @return a random number between a and b
+     */
+    public static float random(float a, float b) {
+        return (float)StrictMath.random() * (max(a, b) - min(a, b)) + min(a, b);
+    }
+
+    /**
+     * return rotated radian value
+     * @param start the start radians
+     * @param delta the change in delta
+     * @param counterClockwise the direction of rotating
+     * @return rotated radians value
+     */
+    public static float rotateRadians(float start, float delta, boolean counterClockwise) {
+        if (counterClockwise) {
+            start += delta;
+        } else {
+            start -= delta;
+        }
+        return start;
+    }
+
+    /**
+     * check is a an even number
+     * @param a an integer
+     * @return the check result
+     */
+    public static boolean isEven(int a) {
+        return a % 2 == 0;
+    }
+
+    /**
+     * check is a an odd number
+     * @param a an integer
+     * @return the check result
+     */
+    public static boolean isOdd(int a) {
+        return a % 2 == 1;
+    }
+
+    /**
+     * return the clamp of a var between boundary 1 and boundary 2
+     * @param b1 boundary 1
+     * @param b2 boundary 2
+     * @param var a float
+     * @return the clamp value
+     */
+    public static float clamp(float b1, float b2, float var) {
+        float max = max(b1, b2);
+        float min = min(b1, b2);
+        if (var > max) return max;
+        if (var < min) return min;
+        return var;
+    }
+
+    /**
+     * check whether var between boundary 1 and boundary 2
+     * @param b1 boundary 1
+     * @param b2 boundary 2
+     * @param var a float
+     * @return the check result
+     */
+    public static boolean between(float b1, float b2, float var) {
+        float max = max(b1, b2);
+        float min = min(b1, b2);
+        return var >= min && var <= max;
+    }
+
+    /**
+     * get difference
+     * @param var1 v 1
+     * @param var2 v 2
+     * @return the difference
+     */
+    public static float diff(float var1, float var2) {
+        return abs(var1 - var2);
+    }
+}
diff --git a/src/myUtil/Vec2D.java b/src/myUtil/Vec2D.java
new file mode 100644
index 0000000000000000000000000000000000000000..e3e768937e02211e31d18292ba4c1fe42e748e7d
--- /dev/null
+++ b/src/myUtil/Vec2D.java
@@ -0,0 +1,509 @@
+package myUtil;
+
+import bagel.util.Point;
+import bagel.util.Vector2;
+
+
+/**
+ * This class is created to replace the job for Point and Vector, where it increase the running speed by using float.
+ */
+
+public class Vec2D {
+    public float x;
+    public float y;
+
+    /**
+     * default constructor for vec2D, initialize vec2D to 0 vector
+     */
+    public Vec2D() {
+        this.x = 0.0f;
+        this.y = 0.0f;
+    }
+
+    /**
+     * constructor for vec2D, initialize vec2d with two values
+     * @param var1 a float
+     * @param var2 a float
+     */
+    public Vec2D(float var1, float var2) {
+        this.x = var1;
+        this.y = var2;
+    }
+
+    /**
+     * constructor for vec2D, initialize vec2d with two values
+     * @param var1 a double
+     * @param var2 a double
+     */
+    public Vec2D(double var1, double var2) {
+        this.x = (float) var1;
+        this.y = (float) var2;
+    }
+
+    /**
+     * set vector with var1 and var2
+     * @param var1 a float
+     * @param var2 a float
+     */
+    public void set(float var1,float var2) {
+        this.x = var1;
+        this.y = var2;
+    }
+
+    /**
+     * set vector with var1 and var2
+     * @param var1 a double
+     * @param var2 a double
+     */
+    public void set(double var1,double var2) {
+        this.x = (float)var1;
+        this.y = (float)var2;
+    }
+
+    /**
+     * copy vec value to itself
+     * @param vec a float
+     */
+    public void set(Vec2D vec) {
+        this.x = vec.x;
+        this.y = vec.y;
+    }
+
+    /**
+     * copy itself
+     * @return the clone
+     */
+    public Vec2D clone() {
+        Vec2D out = new Vec2D();
+        out.set(this);
+        return out;
+    }
+
+    /**
+     * from vector2D to point
+     * @return point
+     */
+    public Point toPoint() {
+        return new Point(this.x,this.y);
+    }
+
+    /**
+     * from vector2D to Vector2
+     * @return Vector2
+     */
+    public Vector2 toVector2() {
+        return new Vector2(this.x,this.y);
+    }
+
+    /**
+     * from point to vector2D
+     * @param point
+     * @return vector2D
+     */
+    public static Vec2D toVec2D(Point point) {
+        return new Vec2D((float)point.x, (float)point.y);
+    }
+
+    /**
+     * from vector2 to vector2D
+     * @param vec
+     * @return vector2D
+     */
+    public static Vec2D toVec2D(Vector2 vec) {
+        return new Vec2D((float)vec.x, (float)vec.y);
+    }
+
+    /**
+     * return the length of a vector
+     * @return the length of a vector
+     */
+    public float length() {
+        return MyMath.sqrt(this.sqrLength());
+    }
+
+    /**
+     * return the square length of a vector for comparing
+     * @return the square length of a vector
+     */
+    public float sqrLength() {
+        return MyMath.sqr(this.x) + MyMath.sqr(this.y);
+    }
+
+    /**
+     * return the distance between two vec
+     * @return the distance between two vec
+     */
+    public static float distance(Vec2D vec1, Vec2D vec2) {
+        return MyMath.sqrt(sqrDistance(vec1, vec2));
+    }
+
+    /**
+     * return the square distance between two vec for comparing
+     * @return the square distance between two vec
+     */
+    public static float sqrDistance(Vec2D vec1, Vec2D vec2) {
+        return MyMath.sqr(vec1.x - vec2.x) + MyMath.sqr(vec1.y - vec2.y);
+    }
+
+    /**
+     * return the vector of two points
+     * @return the vector of two points
+     */
+    public static Vec2D makeVec(Vec2D vec1, Vec2D vec2) {
+        return vec2.out_sub(vec1);
+    }
+
+    /**
+     * return the dot product
+     * @param vec1 a vector
+     * @param vec2 a vector
+     * @return return the dot product
+     */
+    public static float dotProduct(Vec2D vec1, Vec2D vec2) {
+        return vec1.x * vec2.x + vec1.y * vec2.y;
+    }
+
+    /**
+     * toString method with tag
+     */
+    public String toString(String tag) {
+        return tag + ": " + this.toString();
+    }
+
+    /**
+     * toString method
+     */
+    public String toString() {
+        return "(" + this.x + ", " + this.y + ")";
+    }
+
+    /**
+     * print the String with tag
+     */
+    public void print(String tag) {
+        System.out.println(tag + ": (" + this.x + ", " + this.y + ")\n");
+    }
+
+    /**
+     * print the String
+     */
+    public void print() {
+        System.out.println("(" + this.x + ", " + this.y + ")\n");
+    }
+
+    /**
+     * return the normal
+     * @param vec1 a vector
+     * @param vec2 a vector
+     * @return return the normal
+     */
+    public static Vec2D normal(Vec2D vec1, Vec2D vec2) {
+        return new Vec2D(-(vec2.y - vec1.y), (vec2.x - vec1.x));
+    }
+
+    /**
+     * return the radian value of the vector
+     */
+    public float radian() {
+        float radians = (float)StrictMath.atan(this.y / this.x);
+        if (this.x >= 0 && this.y >= 0) return radians;
+        if (this.x <= 0 && this.y <= 0) return radians + 3.14159f;
+        if (this.x >= 0 && this.y <= 0) return 2.0f * 3.14159f + radians;
+        if (this.x <= 0 && this.y >= 0) return radians + 3.14159f;
+        return 0.0f;
+    }
+
+    /**
+     * return the final point point by the original point
+     * @param radians the angle
+     * @param length the moving distance
+     * @return the final point point by the original point
+     */
+    public Vec2D pointer(float radians, float length) {
+        return this.out_add(new Vec2D(length * MyMath.cos(radians),  length * MyMath.sin(radians)));
+    }
+
+    /**
+     * check for equality
+     * @param x float
+     * @param y float
+     * @return result of check
+     */
+    public boolean equals(float x, float y) {
+        return this.x == x && this.y == y;
+    }
+
+    /**
+     * check for equality
+     * @param vec
+     * @return result of check
+     */
+    public boolean equals(Vec2D vec) {
+        return this.x == vec.x && this.y == vec.y;
+    }
+
+    /**
+     * clamp for vector
+     * @param b1 boundary 1
+     * @param b2 boundary 2
+     * @param var
+     * @return the clamp result
+     */
+    public static Vec2D clamp(Vec2D b1, Vec2D b2, Vec2D var) {
+        float fMaxX = MyMath.max(b1.x, b2.x);
+        float fMinX = MyMath.min(b1.x, b2.x);
+        float fMaxY = MyMath.max(b1.y, b2.y);
+        float fMinY = MyMath.min(b1.y, b2.y);
+        return new Vec2D(MyMath.clamp(fMaxX, fMinX, var.x), MyMath.clamp(fMaxY, fMinY, var.y));
+    }
+
+    //basic operation
+    //without return a new vec
+
+    /**
+     * vector add a variable
+     * @param var
+     */
+    public void add(float var) {
+        this.x += var;
+        this.y += var;
+    }
+
+    /**
+     * vector add a vector
+     * @param vec
+     */
+    public void add(Vec2D vec) {
+        this.x += vec.x;
+        this.y += vec.y;
+    }
+
+    /**
+     * vector minus a variable
+     * @param var
+     */
+    public void sub(float var) {
+        this.x -= var;
+        this.y -= var;
+    }
+
+    /**
+     * vector minus a vector
+     * @param vec
+     */
+    public void sub(Vec2D vec) {
+        this.x -= vec.x;
+        this.y -= vec.y;
+    }
+
+    /**
+     * vector divide by a variable
+     * @param var
+     */
+    public void div(float var) {
+        this.x /= var;
+        this.y /= var;
+    }
+
+    /**
+     * vector divide by a vector
+     * @param vec
+     */
+    public void div(Vec2D vec) {
+        this.x /= vec.x;
+        this.y /= vec.y;
+    }
+
+    /**
+     *vector times a variable
+     * @param var
+     */
+    public void mul(float var) {
+        this.x *= var;
+        this.y *= var;
+    }
+
+    /**
+     * vector times a vector
+     * @param vec
+     */
+    public void mul(Vec2D vec) {
+        this.x *= vec.x;
+        this.y *= vec.y;
+    }
+
+    /**
+     * vector add vector n times
+     * @param n
+     * @param vec
+     */
+    public void addN(float n, Vec2D vec) {
+        this.add(vec.out_mul(n));
+    }
+
+    /**
+     * vector minus vector n times
+     * @param n
+     * @param vec
+     */
+    public void subN(float n, Vec2D vec) {
+        this.sub(vec.out_mul(n));
+    }
+
+    /**
+     *vector divide by vector n times
+     * @param n
+     * @param vec
+     */
+    public void divN(float n, Vec2D vec) {
+        this.div(vec.out_mul(n));
+    }
+
+    /**
+     *vector multiply vector n times
+     * @param n
+     * @param vec
+     */
+    public void mulN(float n, Vec2D vec) {
+        this.mul(vec.out_mul(n));
+    }
+
+    //return a new vec
+
+    /**
+     * return a new vector using add(float var)
+     * @param var
+     * @return a new vector using add(float var)
+     */
+    public Vec2D out_add(float var) {
+        Vec2D out = this.clone();
+        out.add(var);
+        return out;
+    }
+
+    /**
+     * return a new vector using add(Vec2D vec)
+     * @param vec
+     * @return a new vector using add(Vec2D vec)
+     */
+    public Vec2D out_add(Vec2D vec) {
+        Vec2D out = this.clone();
+        out.add(vec);
+        return out;
+    }
+
+    /**
+     * return a new vector using sub(float var)
+     * @param var
+     * @return a new vector using sub(float var)
+     */
+    public Vec2D out_sub(float var) {
+        Vec2D out = this.clone();
+        out.sub(var);
+        return out;
+    }
+
+    /**
+     * return a new vector using sub(Vec2D vec)
+     * @param vec
+     * @return a new vector using sub(Vec2D vec)
+     */
+    public Vec2D out_sub(Vec2D vec) {
+        Vec2D out = this.clone();
+        out.sub(vec);
+        return out;
+    }
+
+    /**
+     * return a new vector using div(float var)
+     * @param var
+     * @return a new vector using div(float var)
+     */
+    public Vec2D out_div(float var) {
+        Vec2D out = this.clone();
+        out.div(var);
+        return out;
+    }
+
+    /**
+     * return a new vector using div(Vec2D vec)
+     * @param vec
+     * @return a new vector using div(Vec2D vec)
+     */
+    public Vec2D out_div(Vec2D vec) {
+        Vec2D out = this.clone();
+        out.div(vec);
+        return out;
+    }
+
+    /**
+     * return a new vector using mul(float var)
+     * @param var
+     * @return a new vector using mul(float var)
+     */
+    public Vec2D out_mul(float var) {
+        Vec2D out = this.clone();
+        out.mul(var);
+        return out;
+    }
+
+    /**
+     * return a new vector using mul(Vec2D vec)
+     * @param vec
+     * @return a new vector using mul(Vec2D vec)
+     */
+    public Vec2D out_mul(Vec2D vec) {
+        Vec2D out = this.clone();
+        out.mul(vec);
+        return out;
+    }
+
+    /**
+     * return a new vector using addN(float n, Vec2D vec)
+     * @param n
+     * @param vec
+     * @return a new vector using addN(float n, Vec2D vec)
+     */
+    public Vec2D out_addN(float n, Vec2D vec) {
+        Vec2D out = this.clone();
+        out.addN(n,vec);
+        return out;
+    }
+
+    /**
+     * return a new vector using subN(float n, Vec2D vec)
+     * @param n
+     * @param vec
+     * @return a new vector using subN(float n, Vec2D vec)
+     */
+    public Vec2D out_subN(float n, Vec2D vec) {
+        Vec2D out = this.clone();
+        out.subN(n,vec);
+        return out;
+    }
+
+    /**
+     * return a new vector using divN(float n, Vec2D vec)
+     * @param n float
+     * @param vec vector
+     * @return a new vector using divN(float n, Vec2D vec)
+     */
+    public Vec2D out_divN(float n, Vec2D vec) {
+        Vec2D out = this.clone();
+        out.divN(n,vec);
+        return out;
+    }
+
+    /**
+     * return a new vector using mulN(float n, float vec)
+     * @param n float
+     * @param vec vector
+     * @return a new vector using mulN(float n, float vec)
+     */
+    public Vec2D out_mulN(float n, Vec2D vec) {
+        Vec2D out = this.clone();
+        out.mulN(n,vec);
+        return out;
+    }
+
+}