diff --git a/Clunk.sln b/Clunk.sln
new file mode 100644
index 0000000..e0ab2ef
--- /dev/null
+++ b/Clunk.sln
@@ -0,0 +1,46 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Clunk", "Clunk\Clunk.csproj", "{2944A07B-BB91-4475-9334-DB9B1C3953E2}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Otter", "..\..\..\Privat\Otter Sources\kylepulver-otter-578e5a9b3f38\kylepulver-otter-578e5a9b3f38\Otter\Otter.csproj", "{236485C2-A7BA-4DCD-808A-B3A634764402}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x86 = Debug|x86
+ NuGet|Any CPU = NuGet|Any CPU
+ NuGet|x86 = NuGet|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2944A07B-BB91-4475-9334-DB9B1C3953E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2944A07B-BB91-4475-9334-DB9B1C3953E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2944A07B-BB91-4475-9334-DB9B1C3953E2}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {2944A07B-BB91-4475-9334-DB9B1C3953E2}.Debug|x86.Build.0 = Debug|Any CPU
+ {2944A07B-BB91-4475-9334-DB9B1C3953E2}.NuGet|Any CPU.ActiveCfg = Release|Any CPU
+ {2944A07B-BB91-4475-9334-DB9B1C3953E2}.NuGet|Any CPU.Build.0 = Release|Any CPU
+ {2944A07B-BB91-4475-9334-DB9B1C3953E2}.NuGet|x86.ActiveCfg = Release|Any CPU
+ {2944A07B-BB91-4475-9334-DB9B1C3953E2}.NuGet|x86.Build.0 = Release|Any CPU
+ {2944A07B-BB91-4475-9334-DB9B1C3953E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2944A07B-BB91-4475-9334-DB9B1C3953E2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2944A07B-BB91-4475-9334-DB9B1C3953E2}.Release|x86.ActiveCfg = Release|Any CPU
+ {2944A07B-BB91-4475-9334-DB9B1C3953E2}.Release|x86.Build.0 = Release|Any CPU
+ {236485C2-A7BA-4DCD-808A-B3A634764402}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {236485C2-A7BA-4DCD-808A-B3A634764402}.Debug|Any CPU.Build.0 = Debug|x86
+ {236485C2-A7BA-4DCD-808A-B3A634764402}.Debug|x86.ActiveCfg = Debug|x86
+ {236485C2-A7BA-4DCD-808A-B3A634764402}.Debug|x86.Build.0 = Debug|x86
+ {236485C2-A7BA-4DCD-808A-B3A634764402}.NuGet|Any CPU.ActiveCfg = NuGet|x86
+ {236485C2-A7BA-4DCD-808A-B3A634764402}.NuGet|x86.ActiveCfg = NuGet|x86
+ {236485C2-A7BA-4DCD-808A-B3A634764402}.NuGet|x86.Build.0 = NuGet|x86
+ {236485C2-A7BA-4DCD-808A-B3A634764402}.Release|Any CPU.ActiveCfg = Release|x86
+ {236485C2-A7BA-4DCD-808A-B3A634764402}.Release|x86.ActiveCfg = Release|x86
+ {236485C2-A7BA-4DCD-808A-B3A634764402}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Clunk/App.config b/Clunk/App.config
new file mode 100644
index 0000000..d740e88
--- /dev/null
+++ b/Clunk/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Clunk/Assets.cs b/Clunk/Assets.cs
new file mode 100644
index 0000000..e3909e5
--- /dev/null
+++ b/Clunk/Assets.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Otter;
+
+namespace Clunk
+{
+ public class Assets
+ {
+ public const string TITLE_IMG = "../../Assets/Graphics/randomOtter.jpg";
+ public const string FONT_PANIC = "../../Assets/Fonts/PanicStricken.ttf";
+ public const string MUSIC_TITLE = "../../Assets/Music/menu.ogg";
+ public const string PLAYER = "../../Assets/Graphics/alien.png";
+ public const string PLAYER_EXPLOSION = "../../Assets/Graphics/explosion.png";
+ public const string PLAYER_PARTICLE = "../../Assets/Graphics/particle.png";
+ public const string BULLET = "../../Assets/Graphics/bullet.png";
+ public const string MUSIC_GAME = "../../Assets/Music/game.ogg";
+ public const string SND_BULLET_SHOOT = "../../Assets/Sounds/bulletShoot.ogg";
+ public const string SND_BULLET_EXPLODE = "../../Assets/Sounds/bulletExplode.ogg";
+ public const string BULLET_EXPLOSION = "../../Assets/Graphics/explosion.png";
+ public const string BULLET_PARTICLE = "../../Assets/Graphics/particle.png";
+ public const string ENEMY_SPRITE = "../../Assets/Graphics/enemyAlien.png";
+ public const string SND_ENEMY_HURT = "../../Assets/Sounds/enemyHurt.ogg";
+ public const string TILESET = "../../Assets/Graphics/Tilemap_testingGround.png";
+ public const string MAP_WORLD = "../../Assets/Levels/tiles.csv";
+ public const string MAP_SOLID = "../../Assets/Levels/solids.csv";
+ public const string MAP_TESTINGGROUND = "../../Assets/Levels/TestingGroundTileMap.csv";//keine Kollisionsmap vorhanden
+ public const string HAGURUMAINCOCKWEEL = "../../Assets/Graphics/ZahnrahdFassung4.png";
+ public const string HAGURUSIDECOCKWEEL = "../../Assets/Graphics/NebenZahnrahdFassung5.png";
+ }
+}
diff --git a/Clunk/Assets/Fonts/PanicStricken.ttf b/Clunk/Assets/Fonts/PanicStricken.ttf
new file mode 100644
index 0000000..4754d52
Binary files /dev/null and b/Clunk/Assets/Fonts/PanicStricken.ttf differ
diff --git a/Clunk/Assets/Graphics/NebenZahnrahdFassung4.png b/Clunk/Assets/Graphics/NebenZahnrahdFassung4.png
new file mode 100644
index 0000000..24f2ea8
Binary files /dev/null and b/Clunk/Assets/Graphics/NebenZahnrahdFassung4.png differ
diff --git a/Clunk/Assets/Graphics/NebenZahnrahdFassung5.png b/Clunk/Assets/Graphics/NebenZahnrahdFassung5.png
new file mode 100644
index 0000000..4e569c8
Binary files /dev/null and b/Clunk/Assets/Graphics/NebenZahnrahdFassung5.png differ
diff --git a/Clunk/Assets/Graphics/TestingGroundTileSet.tsx b/Clunk/Assets/Graphics/TestingGroundTileSet.tsx
new file mode 100644
index 0000000..bb2a959
--- /dev/null
+++ b/Clunk/Assets/Graphics/TestingGroundTileSet.tsx
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/Clunk/Assets/Graphics/Tilemap_testingGround.png b/Clunk/Assets/Graphics/Tilemap_testingGround.png
new file mode 100644
index 0000000..fd62fcb
Binary files /dev/null and b/Clunk/Assets/Graphics/Tilemap_testingGround.png differ
diff --git a/Clunk/Assets/Graphics/ZahnrahdFassung4.png b/Clunk/Assets/Graphics/ZahnrahdFassung4.png
new file mode 100644
index 0000000..bef5b53
Binary files /dev/null and b/Clunk/Assets/Graphics/ZahnrahdFassung4.png differ
diff --git a/Clunk/Assets/Graphics/alien.png b/Clunk/Assets/Graphics/alien.png
new file mode 100644
index 0000000..316b796
Binary files /dev/null and b/Clunk/Assets/Graphics/alien.png differ
diff --git a/Clunk/Assets/Graphics/bullet.png b/Clunk/Assets/Graphics/bullet.png
new file mode 100644
index 0000000..03a3be7
Binary files /dev/null and b/Clunk/Assets/Graphics/bullet.png differ
diff --git a/Clunk/Assets/Graphics/enemyAlien.png b/Clunk/Assets/Graphics/enemyAlien.png
new file mode 100644
index 0000000..7c9bdc8
Binary files /dev/null and b/Clunk/Assets/Graphics/enemyAlien.png differ
diff --git a/Clunk/Assets/Graphics/explosion.png b/Clunk/Assets/Graphics/explosion.png
new file mode 100644
index 0000000..6546eba
Binary files /dev/null and b/Clunk/Assets/Graphics/explosion.png differ
diff --git a/Clunk/Assets/Graphics/particle.png b/Clunk/Assets/Graphics/particle.png
new file mode 100644
index 0000000..38555d8
Binary files /dev/null and b/Clunk/Assets/Graphics/particle.png differ
diff --git a/Clunk/Assets/Graphics/randomOtter.jpg b/Clunk/Assets/Graphics/randomOtter.jpg
new file mode 100644
index 0000000..850083d
Binary files /dev/null and b/Clunk/Assets/Graphics/randomOtter.jpg differ
diff --git a/Clunk/Assets/Levels/TestingGroundTileMap.csv b/Clunk/Assets/Levels/TestingGroundTileMap.csv
new file mode 100644
index 0000000..6da6385
--- /dev/null
+++ b/Clunk/Assets/Levels/TestingGroundTileMap.csv
@@ -0,0 +1,15 @@
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+0,2,2,2,2,2,0,0,0,0,0,0,0,0,2,2,2,2,2,0
+0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0
+0,0,0,2,0,2,2,2,2,0,0,0,2,2,0,0,2,0,0,0
+0,0,0,2,0,2,0,0,0,0,0,2,0,0,2,0,2,0,0,0
+0,0,0,2,0,2,0,0,0,0,0,2,0,0,0,0,2,0,0,0
+0,0,0,0,0,2,2,2,2,0,0,0,2,0,0,0,0,0,0,0
+0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0
+0,0,0,0,0,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0
+0,0,0,0,0,2,2,2,2,0,0,2,0,0,2,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+0,0,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
diff --git a/Clunk/Assets/Levels/solids.csv b/Clunk/Assets/Levels/solids.csv
new file mode 100644
index 0000000..72e9f20
--- /dev/null
+++ b/Clunk/Assets/Levels/solids.csv
@@ -0,0 +1,30 @@
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0
+0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0
+0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0
+0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0
+0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
diff --git a/Clunk/Assets/Levels/tiles.csv b/Clunk/Assets/Levels/tiles.csv
new file mode 100644
index 0000000..a74090a
--- /dev/null
+++ b/Clunk/Assets/Levels/tiles.csv
@@ -0,0 +1,30 @@
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,3,3,3,3,3,3,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,3,3,3,3,3,3,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,2,2,2,2,2,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,3,3,3,3,3,3,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
+1,1,1,1,1,1,3,1,1,1,1,3,1,1,1,1,1,1,1,1,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,3,3,3,3,3,3,1,1,1,1,1,1,1
+1,1,1,1,1,1,3,1,1,1,1,3,1,1,1,1,1,1,1,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1
+1,1,1,1,1,1,3,1,1,1,1,3,1,1,1,1,1,1,1,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1
+1,1,1,1,1,1,3,1,1,1,1,3,1,1,1,1,1,1,1,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1
+1,1,1,1,1,1,3,3,3,3,3,3,1,1,1,1,1,1,1,1,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,3,3,3,3,3,3,1,1,1,1,1,1,1
+1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,3,1,1,1,1,3,1,1,1,1,1,1,1
+1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,3,1,1,1,1,3,1,1,1,1,1,1,1
+1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,3,1,1,1,1,3,1,1,1,1,1,1,1
+1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,3,3,3,3,3,3,1,1,1,1,1,1,1
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
diff --git a/Clunk/Assets/Music/game.ogg b/Clunk/Assets/Music/game.ogg
new file mode 100644
index 0000000..37f2c5e
Binary files /dev/null and b/Clunk/Assets/Music/game.ogg differ
diff --git a/Clunk/Assets/Music/menu.ogg b/Clunk/Assets/Music/menu.ogg
new file mode 100644
index 0000000..13dcdb3
Binary files /dev/null and b/Clunk/Assets/Music/menu.ogg differ
diff --git a/Clunk/Assets/Sounds/bulletExplode.ogg b/Clunk/Assets/Sounds/bulletExplode.ogg
new file mode 100644
index 0000000..ad9ff9e
Binary files /dev/null and b/Clunk/Assets/Sounds/bulletExplode.ogg differ
diff --git a/Clunk/Assets/Sounds/bulletShoot.ogg b/Clunk/Assets/Sounds/bulletShoot.ogg
new file mode 100644
index 0000000..fbec5f1
Binary files /dev/null and b/Clunk/Assets/Sounds/bulletShoot.ogg differ
diff --git a/Clunk/Assets/Sounds/enemyHurt.ogg b/Clunk/Assets/Sounds/enemyHurt.ogg
new file mode 100644
index 0000000..1e3b2cb
Binary files /dev/null and b/Clunk/Assets/Sounds/enemyHurt.ogg differ
diff --git a/Clunk/Clunk.csproj b/Clunk/Clunk.csproj
new file mode 100644
index 0000000..05b15c9
--- /dev/null
+++ b/Clunk/Clunk.csproj
@@ -0,0 +1,147 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {2944A07B-BB91-4475-9334-DB9B1C3953E2}
+ Exe
+ Properties
+ Clunk
+ Clunk
+ v4.5.2
+ 512
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+
+
+ {236485c2-a7ba-4dcd-808a-b3a634764402}
+ Otter
+
+
+
+
+ PreserveNewest
+
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+
+
+ PreserveNewest
+
+
+
+
+
\ No newline at end of file
diff --git a/Clunk/Effects/BulletExplosion.cs b/Clunk/Effects/BulletExplosion.cs
new file mode 100644
index 0000000..00da9e4
--- /dev/null
+++ b/Clunk/Effects/BulletExplosion.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Otter;
+using Clunk;
+using Clunk.Effects;
+
+namespace Clunk.Effects
+{
+ public class BulletExplosion : BulletParticle
+ {
+ // Used to keep track of when to remove explosion from the scene
+ public const int DESTROY_FRAME = 3;
+
+ // Sound that is played when to remove explosion from the scene
+ private Sound bulletExplodeSnd = new Sound(Assets.SND_BULLET_EXPLODE);
+
+ public BulletExplosion(float x, float y) : base(x, y)
+ {
+ destroyFrame = DESTROY_FRAME;
+
+ // Set up our explosion animation, and play it. Lastly, set our graphic.
+ sprite = new Spritemap(Assets.BULLET_EXPLOSION, 32, 40);
+ sprite.Add("Emit", new int[] { 0, 1, 2, 3 }, new float[] { 10f, 10f, 10f, 10f });
+ sprite.Play("Emit");
+ Graphic = sprite;
+
+ bulletExplodeSnd.Play();
+
+ // Shake the camera each time we explode
+ Global.camShaker.ShakeCamera();
+ }
+ }
+}
diff --git a/Clunk/Effects/BulletParticle.cs b/Clunk/Effects/BulletParticle.cs
new file mode 100644
index 0000000..ffdd10d
--- /dev/null
+++ b/Clunk/Effects/BulletParticle.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Otter;
+using Clunk;
+
+namespace Clunk.Effects
+{
+ public class BulletParticle : Entity
+ {
+ // Our bullet particle graphics contain multiple frames. Spritemap makes sense here.
+ public Spritemap sprite;
+
+ // Once the animation hits this frame, remove ourself from the Scene
+ public int destroyFrame = 1;
+
+ public BulletParticle(float x, float y) : base(x, y)
+ {
+
+ }
+
+ public override void Update()
+ {
+ base.Update();
+
+ // Have our particle drift up a bit as it dissolves
+ Y -= (float)(1.5 / Otter.Rand.Float(1, 3));
+
+ // Check if we have finished playing. If so, remove self
+ if (sprite.CurrentFrame == destroyFrame)
+ {
+ RemoveSelf();
+ }
+ }
+ }
+}
diff --git a/Clunk/Effects/BulletTrail.cs b/Clunk/Effects/BulletTrail.cs
new file mode 100644
index 0000000..56f8c20
--- /dev/null
+++ b/Clunk/Effects/BulletTrail.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Otter;
+using Clunk;
+using Clunk.Effects;
+
+namespace Clunk.Effects
+{
+ public class BulletTrail : BulletParticle
+ {
+ public const int DESTROY_FRAME = 3;
+
+ public BulletTrail(float x, float y) : base(x, y)
+ {
+ destroyFrame = DESTROY_FRAME;
+
+ sprite = new Spritemap(Assets.BULLET_PARTICLE, 32, 40);
+ sprite.Add("Emit", new int[] { 0, 1, 2, 3 }, new float[] { 10f, 10f, 10f, 10f });
+ sprite.Play("Emit");
+ Graphic = sprite;
+ }
+ }
+}
diff --git a/Clunk/Effects/DamageText.cs b/Clunk/Effects/DamageText.cs
new file mode 100644
index 0000000..00ba19b
--- /dev/null
+++ b/Clunk/Effects/DamageText.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Otter;
+using Clunk;
+
+namespace Clunk.Effects
+{
+ class DamageText : Entity
+ {
+ // Random jitter so that each DamageText object
+ // doesn't appear in the exact same spot
+ private const int MIN_X_JITTER = 0;
+ private const int MAX_X_JITTER = 30;
+
+ // Our Text object that displays on screen
+ private Text text;
+
+ public DamageText(float x, float y, string dmgText, int fontSize = 16)
+ {
+ text = new Text(dmgText, fontSize);
+ text.Color = Color.Red;
+
+ // Move the X value a bit for each new DamageText so they
+ // all don't appear in the same spot if the Enemy is idle
+ X = x + Otter.Rand.Int(MIN_X_JITTER, MAX_X_JITTER);
+ Y = y - 20;
+
+ Graphic = text;
+ }
+
+ public override void Update()
+ {
+ base.Update();
+
+ // Slowly subtract from our alpha value
+ text.Alpha -= 0.02f;
+ Y -= 1.25f; // Drift upwards
+
+ // Remove once invisible
+ if (text.Alpha <= 0)
+ {
+ RemoveSelf();
+ }
+ }
+ }
+}
diff --git a/Clunk/Effects/Explosion.cs b/Clunk/Effects/Explosion.cs
new file mode 100644
index 0000000..747dca4
--- /dev/null
+++ b/Clunk/Effects/Explosion.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Otter;
+using Clunk;
+
+namespace Clunk.Effects
+{
+ public class Explosion : Entity
+ {
+ public Image img;
+
+ // Default color is white
+ public Color color = new Color("FFFFFF");
+
+ public Sound explode = new Sound(Assets.SND_BULLET_EXPLODE);
+
+ public Explosion(float x, float y, int width = 32, int height = 40, Color expColor = null, int radius = 20)
+ {
+ X = x + width / 2;
+ Y = y;
+
+ // You can pass in a custom color, if desired
+ if (expColor != null)
+ {
+ color = expColor;
+ }
+
+ // Center ourselves and set the graphic
+ img = Image.CreateCircle(radius, color);
+ img.CenterOrigin();
+ Graphic = img;
+
+ Global.camShaker.ShakeCamera(40f);
+ explode.Play();
+ }
+
+ public override void Update()
+ {
+ base.Update();
+
+ // Gradually grow, in the fashion of an explosion
+ // If you want to get fancy, perhaps you could make this
+ // a decaying growth, or even Tween it so it grows faster
+ // at the beginning
+ img.ScaleX += 0.10f;
+ img.ScaleY += 0.10f;
+
+ img.CenterOrigin();
+
+ // Gradually phase to invisible
+ img.Alpha -= 0.04f;
+ if (img.Alpha <= 0)
+ {
+ RemoveSelf();
+ }
+ }
+ }
+}
diff --git a/Clunk/Effects/WalkParticle.cs b/Clunk/Effects/WalkParticle.cs
new file mode 100644
index 0000000..d32e544
--- /dev/null
+++ b/Clunk/Effects/WalkParticle.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Otter;
+using Clunk;
+using Clunk.Effects;
+
+namespace Clunk.Effects
+{
+ public class WalkParticle : Entity
+ {
+ // Number of frames to remain on screen for
+ public const int PARTICLE_FRAMES = 5;
+
+ // Our graphic will be a simple image
+ public Image image;
+
+ public int direction = 0;
+ public int particleTimer = 0;
+
+ public WalkParticle(float x, float y) : base(x, y)
+ {
+ // Our graphic will be a purple circle, with a 4 pixel radius
+ Color col = new Color("9612C2");
+ image = Image.CreateCircle(4, col);
+ Graphic = image;
+ }
+
+ public override void Update()
+ {
+ // Float upward
+ Y -= (float)(1.5 / Otter.Rand.Float(1, 3));
+
+ // Gradually become transparent before disappearing
+ image.Alpha -= 0.10f;
+
+ particleTimer++;
+ if (particleTimer >= PARTICLE_FRAMES)
+ {
+ RemoveSelf();
+ }
+ }
+ }
+}
diff --git a/Clunk/Entities/Bullet.cs b/Clunk/Entities/Bullet.cs
new file mode 100644
index 0000000..251a8e4
--- /dev/null
+++ b/Clunk/Entities/Bullet.cs
@@ -0,0 +1,101 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Otter;
+using Clunk;
+using Clunk.Effects;
+
+namespace Clunk.Entities
+{
+ public class Bullet : Entity
+ {
+ // Default bullet speed
+ public float bulletSpeed = 10.0f;
+
+ // Direction the bullet is going to travel in
+ public int direction = 0;
+
+ // Distance the bullet has traveled
+ public float distanceTraveled = 0f;
+
+ // Max distance a bullet can travel
+ public float maxDistance = 350f;
+
+ // The image object that is our bullet's graphic
+ public Image image;
+
+ public Sound shootSnd = new Sound(Assets.SND_BULLET_SHOOT);
+
+ public Bullet(float x, float y, int dir)
+ {
+ // Set the Bullet's X,Y coordinates, and its direction
+ X = x;
+ Y = y;
+ direction = dir;
+
+ // Set the graphic to our bullet image
+ image = new Image(Assets.BULLET);
+ Graphic = image;
+
+ shootSnd.Play();
+
+ // Add a BulletTrail particle as soon as the Bullet enters the Scene
+ Global.CLUNK.Scene.Add(new BulletTrail(X, Y));
+
+ SetHitbox(16, 14, (int)Global.Type.BULLET);
+ }
+
+ public override void Update()
+ {
+ base.Update();
+
+ // Move in the correct direction that the bullet was fired in
+ switch (direction)
+ {
+ case Global.DIR_UP:
+ {
+ Y -= bulletSpeed;
+ break;
+ }
+ case Global.DIR_DOWN:
+ {
+ Y += bulletSpeed;
+ break;
+ }
+ case Global.DIR_LEFT:
+ {
+ X -= bulletSpeed;
+ break;
+ }
+ case Global.DIR_RIGHT:
+ {
+ X += bulletSpeed;
+ break;
+ }
+ }
+
+ // Add a new BulletTrail particle every 60 pixels traveled
+ if (distanceTraveled % 60 == 0)
+ {
+ Global.CLUNK.Scene.Add(new BulletTrail(X, Y));
+ }
+
+ // If we have traveled the max distance or more, then
+ // the bullet will remove itself from the current Scene
+ distanceTraveled += bulletSpeed;
+ if (distanceTraveled >= maxDistance)
+ {
+ Global.CLUNK.Scene.Add(new BulletExplosion(X, Y));
+ RemoveSelf();
+ }
+ }
+
+ public void Destroy()
+ {
+ RemoveSelf();
+ }
+ }
+
+}
diff --git a/Clunk/Entities/Enemy.cs b/Clunk/Entities/Enemy.cs
new file mode 100644
index 0000000..9ef681d
--- /dev/null
+++ b/Clunk/Entities/Enemy.cs
@@ -0,0 +1,113 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Otter;
+using Clunk;
+using Clunk.Effects;
+
+namespace Clunk.Entities
+{
+ public class Enemy : Entity
+ {
+ // Default speed an enemy will move in
+ public const float DEFAULT_SPEED = 3.4f;
+
+ // Default health points our enemy starts with
+ public const int DEFAULT_HEALTH = 4;
+
+ public const float MOVE_DISTANCE = 300;
+
+ // left = true, right = false
+ public bool direction = true;
+
+ // Used to keep track of the enemy distance moved
+ public float distMoved = 0f;
+
+ public Sound hurt = new Sound(Assets.SND_ENEMY_HURT);
+
+ public int health = 1;
+ public float speed = 1f;
+
+ public Spritemap sprite;
+
+ public Enemy(float x, float y) : base(x, y)
+ {
+ health = DEFAULT_HEALTH;
+ speed = DEFAULT_SPEED;
+
+ // Set up the Spritemap in the same manner we did for the player
+ sprite = new Spritemap(Assets.ENEMY_SPRITE, 32, 40);
+ sprite.Add("standLeft", new int[] { 0, 1 }, new float[] { 10f, 10f });
+ sprite.Add("standRight", new int[] { 0, 1 }, new float[] { 10f, 10f });
+ sprite.Add("standDown", new int[] { 3, 4 }, new float[] { 10f, 10f });
+ sprite.Add("standUp", new int[] { 6, 7 }, new float[] { 10f, 10f });
+ sprite.Add("walkLeft", new int[] { 0, 1 }, new float[] { 10f, 10f });
+ sprite.Add("walkRight", new int[] { 0, 1 }, new float[] { 10f, 10f });
+ sprite.Add("walkDown", new int[] { 3, 4 }, new float[] { 10f, 10f });
+ sprite.Add("walkUp", new int[] { 6, 7 }, new float[] { 10f, 10f });
+ sprite.Play("standLeft");
+
+ Graphic = sprite;
+
+ // Set our Enemy hitbox to be 32 x 40. This goes in our Enemy class
+ SetHitbox(32, 40, (int)Global.Type.ENEMY);
+
+ }
+
+ public override void Update()
+ {
+ base.Update();
+
+ // Access the Enemy's Collider to check collision
+ var collb = Collider.Collide(X, Y, (int)Global.Type.BULLET);
+
+ if (collb != null)
+ {
+ Bullet b = (Bullet)collb.Entity;
+ b.Destroy();
+ // Shake the camera when a Bullet hits an Enemy
+ // and then add a new DamageText object with the
+ // abritary string "1234". Lastly add it to our Scene
+ Global.camShaker.ShakeCamera();
+ DamageText dt = new DamageText(X, Y, "9999");
+ Global.CLUNK.Scene.Add(dt);
+
+ hurt.Play();
+ health--; // Decrement the health by 1 for each Bullet that hits
+ if (health <= 0)
+ {
+ // Add a new Explosion and remove self from the Scene if out of health
+ Global.CLUNK.Scene.Add(new Explosion(X, Y));
+ Global.CLUNK.Scene.Add(new Enemy(Otter.Rand.Float(50,590),Otter.Rand.Float(50,430)));
+
+
+ RemoveSelf();
+ }
+ }
+
+ // If going left, flip the spritesheet
+ sprite.FlippedX = direction;
+
+ // if moving left then go left, otherwise go right
+ if (direction)
+ {
+ X -= speed;
+ }
+ else
+ {
+ X += speed;
+ }
+
+ // Update distance moved, and check if we should flip directions
+ distMoved += speed;
+ if (distMoved >= MOVE_DISTANCE)
+ {
+ direction = !direction;
+ distMoved = 0f;
+ }
+ }
+
+ }
+}
diff --git a/Clunk/Entities/HaguruClock.cs b/Clunk/Entities/HaguruClock.cs
new file mode 100644
index 0000000..be00991
--- /dev/null
+++ b/Clunk/Entities/HaguruClock.cs
@@ -0,0 +1,126 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Otter;
+using Clunk;
+using Clunk.Effects;
+
+namespace Clunk.Entities
+{
+ public class HaguruClock : Entity
+ {
+ private Image mainWheel;
+ private Image sideWheel;
+
+ private GraphicList graphics = new GraphicList();
+
+ //Timer for showing time again
+ float timer;
+
+ // Our Text object that displays on screen to show time
+ private Text text;
+
+ private bool isFreezed;
+
+ private int currentHour;
+ private int currentMinute;
+
+
+ // referenced gameTime
+ private int summedHours;
+ private int summedMinutes;
+
+
+
+ //Initial Konstrukter - Is only called ones the game runs the first time
+ public HaguruClock()
+ {
+ //Clock Position (Entity Position)
+ X = 200;
+ Y = 200;
+
+ //Mainwheel Graphics
+ mainWheel = new Image(Assets.HAGURUMAINCOCKWEEL);
+ mainWheel.CenterOrigin();
+
+ //Darf nicht relativ zur Uhr gerendered werden weil drehen der Uhr sonst mainwheel mitdreht!!!
+ mainWheel.Relative = false;
+
+ mainWheel.ScaleX = 0.25f;
+ mainWheel.ScaleY = 0.25f;
+
+ mainWheel.X = 0;
+ mainWheel.Y = 0;
+
+ //add it to the rendered Graphiclist
+ graphics.Add(mainWheel);
+
+ //SideWheel Graphics
+ sideWheel = new Image(Assets.HAGURUSIDECOCKWEEL);
+ sideWheel.CenterOrigin();
+
+ //Muss relativ zur Uhr gerendered werden weil drehen der Uhr sonst sidewheels position nicht mitdreht!!!
+ sideWheel.Relative = true;
+ sideWheel.ScaleX = 0.25f;
+ sideWheel.ScaleY = 0.25f;
+
+ sideWheel.X = 0;
+ //Relative Position zur Uhr
+ sideWheel.Y = 0 - ((mainWheel.ScaledHeight/2) + (sideWheel.ScaledHeight/2)-20);
+
+ //add it to the rendered Graphiclist
+ graphics.Add(sideWheel);
+
+ //Set overall Graphic to the list so all graphics are rendered properly
+ Graphic = graphics;
+
+
+ }
+
+ public override void Update()
+ {
+ base.Update();
+
+ currentHour = 1;
+ currentMinute = 1;
+
+ //Rotation of the main weel to match 1 hour ingame time by rotation when both hour and minute pointer meet
+ //therefor 1minute ingame = aprox. 1,09 minutes in real time
+
+ mainWheel.Transform.Rotation += 32.7272f/3600f;
+ sideWheel.Transform.Rotation -= 32.7272f /50f;
+
+ timer += Game.Instance.DeltaTime; ;
+
+ if (timer < 0f)
+ {
+
+ summedHours += 1;
+ summedMinutes += 1;
+
+ text = new Text(howLongPlayed(), 16);
+ text.Color = Color.Red;
+ X = 20f;
+ Y = 20f;
+ timer = 0f;
+ Graphic = mainWheel;
+
+ }
+
+ }
+
+ public string howLongPlayed()
+ {
+ string time = "Time played: " + summedHours + " hours and " + summedMinutes + " minutes!";
+ return time;
+ }
+
+ public void whatTimeIsIt(out int hours, out int minutes)
+ {
+ hours = currentHour;
+ minutes = currentMinute;
+ }
+ }
+}
diff --git a/Clunk/Entities/Player.cs b/Clunk/Entities/Player.cs
new file mode 100644
index 0000000..20931e8
--- /dev/null
+++ b/Clunk/Entities/Player.cs
@@ -0,0 +1,205 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Otter;
+using Clunk.Effects;
+using Clunk.Scenes;
+
+namespace Clunk.Entities
+{
+ public class Player : Entity
+ {
+ // Our entity's graphic will be a Spritemap
+ private Spritemap sprite;
+
+ public float moveSpeed = 4.0f;
+
+ public int direction = 0;
+
+ public const int WIDTH = 32;
+ public const int HEIGHT = 40;
+ public const float DIAGONAL_SPEED = 1.4f;
+
+ public Player(float x = 0, float y = 0)
+ {
+ // When creating a new player, the desired X,Y coordinates are passed in. If excluded, we start at 0,0
+ X = x;
+ Y = y;
+ // Create a new spritemap, with the player.png image as our source, 32 pixels wide, and 40 pixels tall
+ sprite = new Spritemap(Assets.PLAYER, 32, 40);
+
+ // We must define each animation for our spritemap.
+ // An animation is made up of a group of frames, ranging from 1 frame to many frames.
+ // Each 32x40 box is a single frame in our particular sprite map.
+ // The frames start counting from 0, and count from left-to-right, top-to-bottom
+ sprite.Add("standLeft", new int[] { 0, 1 }, new float[] { 10f, 10f });
+ sprite.Add("standRight", new int[] { 0, 1 }, new float[] { 10f, 10f });
+ sprite.Add("standDown", new int[] { 3, 4 }, new float[] { 10f, 10f });
+ sprite.Add("standUp", new int[] { 6, 7 }, new float[] { 10f, 10f });
+ sprite.Add("walkLeft", new int[] { 0, 1 }, new float[] { 10f, 10f });
+ sprite.Add("walkRight", new int[] { 0, 1 }, new float[] { 10f, 10f });
+ sprite.Add("walkDown", new int[] { 3, 4 }, new float[] { 10f, 10f });
+ sprite.Add("walkUp", new int[] { 6, 7 }, new float[] { 10f, 10f });
+
+ // Tell the spritemap which animation to play when the scene starts
+ sprite.Play("standDown");
+
+ // Lastly, we must set our Entity's graphic, otherwise it will not display
+ Graphic = sprite;
+ }
+
+ public override void Update()
+ {
+ base.Update();
+
+ // Used to determine which directions we are moving in
+ bool horizontalMovement = true;
+ bool verticalMovement = true;
+
+ float xSpeed = 0;
+ float ySpeed = 0;
+ float newX;
+ float newY;
+ GameScene checkScene = (GameScene)Scene;
+
+ // Check horizontal movement
+ if (Global.PlayerSession.Controller.Button("Left").Down)
+ {
+ newX = X - moveSpeed;
+
+ // Check if we are colliding with a solid rectangle or not.
+ // Ensure the GridCollider snaps our values to a grid, by passing
+ // in a false boolean for the usingGrid parameter
+ if (!checkScene.grid.GetRect(newX, Y, newX + WIDTH, Y + HEIGHT, false))
+ {
+ xSpeed = -moveSpeed;
+ }
+
+ direction = Global.DIR_LEFT;
+ sprite.FlippedX = true;
+ }
+ else if (Global.PlayerSession.Controller.Button("Right").Down)
+ {
+ newX = X + moveSpeed;
+ if (!checkScene.grid.GetRect(newX, Y, newX + WIDTH, Y + HEIGHT, false))
+ {
+ xSpeed = moveSpeed;
+ }
+
+ direction = Global.DIR_RIGHT;
+ sprite.FlippedX = false;
+ }
+ else
+ {
+ horizontalMovement = false;
+ }
+
+ // Check vertical movement
+ if (Global.PlayerSession.Controller.Button("Up").Down)
+ {
+ newY = Y - moveSpeed;
+ if (!checkScene.grid.GetRect(X, newY, X + WIDTH, newY + HEIGHT, false))
+ {
+ ySpeed = -moveSpeed;
+ }
+
+ direction = Global.DIR_UP;
+ sprite.FlippedX = false;
+ }
+ else if (Global.PlayerSession.Controller.Button("Down").Down)
+ {
+ newY = Y + moveSpeed;
+ if (!checkScene.grid.GetRect(X, newY, X + WIDTH, newY + HEIGHT, false))
+ {
+ ySpeed = moveSpeed;
+ }
+
+ direction = Global.DIR_DOWN;
+ sprite.FlippedX = false;
+ }
+ else
+ {
+ verticalMovement = false;
+ }
+
+ if (Global.PlayerSession.Controller.Button("X").Pressed)
+ {
+ Global.CLUNK.Scene.Add(new Bullet(X, Y, direction));
+ }
+
+ // If we are not moving play our idle animations
+ // Currently our spritesheet lacks true idle
+ // animations, but this helps get the idea across
+ if (!horizontalMovement && !verticalMovement)
+ {
+ if (sprite.CurrentAnim.Equals("walkLeft"))
+ {
+ sprite.Play("standLeft");
+ }
+ else if (sprite.CurrentAnim.Equals("walkRight"))
+ {
+ sprite.Play("standRight");
+ }
+ else if (sprite.CurrentAnim.Equals("walkDown"))
+ {
+ sprite.Play("standDown");
+ }
+ else if (sprite.CurrentAnim.Equals("walkUp"))
+ {
+ sprite.Play("standUp");
+ }
+ }
+
+ // Add particles if the player is moving in any direction
+ if (verticalMovement || horizontalMovement)
+ {
+ // Add walking particles
+ float particleXBuffer = 0;
+ float particleYBuffer = 0;
+ switch (direction)
+ {
+ case Global.DIR_UP:
+ {
+ particleXBuffer = Otter.Rand.Float(8, 24);
+ particleYBuffer = Otter.Rand.Float(0, 5);
+ Global.CLUNK.Scene.Add(new WalkParticle(X + particleXBuffer, Y + 40));
+ break;
+ }
+ case Global.DIR_DOWN:
+ {
+ particleXBuffer = Otter.Rand.Float(8, 24);
+ Global.CLUNK.Scene.Add(new WalkParticle(X + particleXBuffer, Y));
+ break;
+ }
+ case Global.DIR_LEFT:
+ {
+ particleYBuffer = Otter.Rand.Float(-2, 2);
+ Global.CLUNK.Scene.Add(new WalkParticle(X + 32 - 3, Y + 40 + particleYBuffer));
+ break;
+ }
+ case Global.DIR_RIGHT:
+ {
+ particleYBuffer = Otter.Rand.Float(-2, 2);
+ Global.CLUNK.Scene.Add(new WalkParticle(X + 3, Y + 40 + particleYBuffer));
+ break;
+ }
+ }
+ }
+
+ if (verticalMovement && horizontalMovement)
+ {
+ X += xSpeed / DIAGONAL_SPEED;
+ Y += ySpeed / DIAGONAL_SPEED;
+ }
+ else
+ {
+ X += xSpeed;
+ Y += ySpeed;
+ }
+ }
+ }
+
+}
diff --git a/Clunk/Global.cs b/Clunk/Global.cs
new file mode 100644
index 0000000..058943f
--- /dev/null
+++ b/Clunk/Global.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Otter;
+using Clunk.Entities;
+using Clunk.Util;
+
+
+namespace Clunk
+{
+ public class Global
+ {
+ public static Game CLUNK = null;
+ public static Session PlayerSession;
+ public static Player player = null;
+ public static CameraShaker camShaker = new CameraShaker();
+ public static bool paused = false;
+ public static Music gameMusic = null;
+ public static HaguruClock clock = null;
+ public const int DIR_UP = 0;
+ public const int DIR_DOWN = 1;
+ public const int DIR_LEFT = 2;
+ public const int DIR_RIGHT = 3;
+ // These variables will be used when creating our Tilemap related objects
+ public const int GAME_WIDTH = 640;
+ public const int GAME_HEIGHT = 480;
+ public const int GRID_WIDTH = 32;
+ public const int GRID_HEIGHT = 32;
+ public enum Type
+ {
+ BULLET,
+ ENEMY
+ }
+
+
+ }
+}
diff --git a/Clunk/PlayerEntity.cs b/Clunk/PlayerEntity.cs
new file mode 100644
index 0000000..1281805
--- /dev/null
+++ b/Clunk/PlayerEntity.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Otter;
+
+namespace Clunk
+{
+ class PlayerEntity : Entity
+ {
+ // Create a rectangle image.
+ Image image = Image.CreateRectangle(32, 32, Color.White);
+
+
+ public PlayerEntity(float x, float y ) : base(x, y)
+ {
+
+ var axisMove = Axis.CreateWASD();
+
+ // Add the rectangle graphic to the Entity.
+ AddGraphic(image);
+
+ // Center the image's origin.
+ image.CenterOrigin();
+
+ AddComponents(
+ axisMove,
+ new TopDownMovement(axisMove, 4)
+
+ );
+
+ }
+
+ public override void Update()
+ {
+ base.Update();
+
+
+ }
+
+ }
+}
diff --git a/Clunk/Program.cs b/Clunk/Program.cs
new file mode 100644
index 0000000..fcc0e83
--- /dev/null
+++ b/Clunk/Program.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Otter;
+using Clunk;
+using Clunk.Scenes;
+
+namespace Clunk
+{
+ public class Program
+ {
+ static void Main(string[] args)
+ {
+ //To Do Gravity einbauen (oder plattformermovement einbauen[in otter vorhanden])
+
+
+ Global.CLUNK = new Game("Playground", 640, 480);
+ Global.CLUNK.SetWindow(640, 480);
+
+ Global.CLUNK.FirstScene = new TitleScene();
+ Global.PlayerSession = Global.CLUNK.AddSession("Player");
+ Global.PlayerSession.Controller.AddButton("Enter");
+ Global.PlayerSession.Controller.Button("Enter").AddKey(Key.Return);
+ Global.PlayerSession.Controller.AddButton("Up");
+ Global.PlayerSession.Controller.Button("Up").AddKey(Key.Up);
+ Global.PlayerSession.Controller.AddButton("Left");
+ Global.PlayerSession.Controller.Button("Left").AddKey(Key.Left);
+ Global.PlayerSession.Controller.AddButton("Down");
+ Global.PlayerSession.Controller.Button("Down").AddKey(Key.Down);
+ Global.PlayerSession.Controller.AddButton("Right");
+ Global.PlayerSession.Controller.Button("Right").AddKey(Key.Right);
+ Global.PlayerSession.Controller.AddButton("X");
+ Global.PlayerSession.Controller.Button("X").AddKey(Key.X);
+
+ //Code für positionen des players
+ //Console.WriteLine(Global.player.ScreenX);
+ //Console.WriteLine(Global.player.ScreenY);
+ //To do snap to grid logik implementieren um abhängig von player position gridladen zu können
+
+ // Start the game \:D/
+ Global.CLUNK.Start();
+
+
+
+ /*
+ float playerPosX = Game.Instance.HalfWidth;
+ float playerPosY = Game.Instance.HalfHeight;
+
+ // Create a Scene.
+ var scene = new Scene();
+
+ //Funktioniert noch nicht: Components angugen und checken
+ //ob und wie beide entities player und tileMap
+ //player positionen sharen können damit tileMap auf playerbewegung
+ //reagieren kann!!!
+
+ //-> Otter forum checken nach wie komponenten/variablen global bekannt sein können
+
+
+ //Set and add Player
+ PlayerEntity player = new PlayerEntity(playerPosX,playerPosY);
+ scene.Add(player);
+
+ //Set and add TileMap
+ Tiles tileMap = new Tiles(playerPosX, playerPosY);
+ scene.Add(tileMap);
+
+ // Set the mouse visibility to true for this example.
+ game.MouseVisible = true;
+ */
+ // Start the Game.
+ //game.Start(scene);
+ }
+ }
+}
diff --git a/Clunk/Properties/AssemblyInfo.cs b/Clunk/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..a08d9df
--- /dev/null
+++ b/Clunk/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Allgemeine Informationen über eine Assembly werden über die folgenden
+// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
+// die einer Assembly zugeordnet sind.
+[assembly: AssemblyTitle("Clunk")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Orgname")]
+[assembly: AssemblyProduct("Clunk")]
+[assembly: AssemblyCopyright("Copyright © Orgname 2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
+// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
+// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
+[assembly: ComVisible(false)]
+
+// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
+[assembly: Guid("2944a07b-bb91-4475-9334-db9b1c3953e2")]
+
+// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
+//
+// Hauptversion
+// Nebenversion
+// Buildnummer
+// Revision
+//
+// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
+// übernehmen, indem Sie "*" eingeben:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Clunk/Scenes/GameScene.cs b/Clunk/Scenes/GameScene.cs
new file mode 100644
index 0000000..ab1af4e
--- /dev/null
+++ b/Clunk/Scenes/GameScene.cs
@@ -0,0 +1,269 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Otter;
+using Clunk.Entities;
+
+namespace Clunk.Scenes
+{
+
+
+ public class GameScene : Scene
+ {
+ public Music gameMusic = new Music(Assets.MUSIC_GAME);
+ // Scene object that will hold the next scene that we transition to
+ public Scene nextScene;
+
+ // Use a J,I coordinate system for our map's screens to avoid
+ // confusion with our already existing X,Y coordinate systems
+ public int screenJ;
+ public int screenI;
+
+ // Our Tilemap's calculated width and height
+ public const int WIDTH = Global.GAME_WIDTH * 3;
+ public const int HEIGHT = Global.GAME_HEIGHT * 2;
+
+ public Tilemap tilemap = null;
+ public GridCollider grid = null;
+
+ //Players TileGridPositions
+ public int GridXPosOld = 0;
+ public int GridYPosOld = 0;
+ public int GridXPos = 0;
+ public int GridYPos = 0;
+
+
+ // Our new constructor takes in the new J,I coordinates, and a Player object
+ public GameScene(int nextJ = 0, int nextI = 0, Player player = null) : base()
+ {
+ screenJ = nextJ;
+ screenI = nextI;
+
+ // If a Player object isn't passed in, start at the default x,y position of 100,100
+ if (player == null)
+ {
+ Global.player = new Player(100, 100);
+ }
+ else
+ {
+ Global.player = player;
+ }
+
+ // Create and load our Tilemap and GridCollider
+ tilemap = new Tilemap(Assets.TILESET, WIDTH, HEIGHT, Global.GRID_WIDTH, Global.GRID_HEIGHT);
+ grid = new GridCollider(WIDTH, HEIGHT, Global.GRID_WIDTH, Global.GRID_HEIGHT);
+ string mapToLoad = Assets.MAP_WORLD;
+ string solidsToLoad = Assets.MAP_SOLID;
+ LoadWorld(mapToLoad, solidsToLoad);
+
+ // Since we are constantly switching Scenes we need to do some checking,
+ // ensuring that the music doesn't get restarted.
+ // We should probably add an isPlaying boolean to the Music class. I will do this soon.
+ if (Global.gameMusic == null)
+ {
+ Global.gameMusic = new Music(Assets.MUSIC_GAME);
+ Global.gameMusic.Play();
+ Global.gameMusic.Volume = 0.40f;
+ }
+
+ }
+
+ // We now add our Entities and Graphics once the Scene has been switched to
+ public override void Begin()
+ {
+ Entity gridEntity = new Entity(0, 0, null, grid);
+ Add(gridEntity);
+ AddGraphic(tilemap);
+
+ // Ensure that the player is not null
+ if (Global.player != null)
+ {
+ Add(Global.player);
+
+ // Never should be paused once transitioning is complete
+ Global.paused = false;
+ }
+
+ //Set PlayerGridposition (plus sprite margin)
+ GridXPosOld = (int)(Global.player.X + 16f) / tilemap.TileWidth;
+ GridXPos = GridXPosOld;
+ GridYPosOld = (int)(Global.player.Y + 20f)/ tilemap.TileHeight;
+ GridYPos = GridYPosOld;
+
+ Add(Global.camShaker);
+
+ // This is rather crude, as we re-add the Enemy every time we switch screens
+ // A good task beyond these tutorials would be ensuring that non-player
+ // Entities retain their state upon switching screens
+ Add(new Enemy(500, 400));
+ }
+
+ public override void Update()
+ {
+ if (Global.paused)
+ {
+ return;
+ }
+
+ /* Zeichnen der Map je nach Player Position
+ GridXPos = (int)(Global.player.X + 16f) / tilemap.TileWidth ;
+ GridYPos = (int)(Global.player.Y + 20f) / tilemap.TileHeight ;
+
+ if (GridXPos != GridXPosOld || GridYPos != GridYPosOld)
+ {
+ //clear old markings
+ tilemap.SetTile(GridXPosOld + 2, GridYPosOld, 0);
+ tilemap.SetTile(GridXPosOld + 1, GridYPosOld - 1, 0);
+ tilemap.SetTile(GridXPosOld + 1, GridYPosOld + 1, 0);
+ tilemap.SetTile(GridXPosOld, GridYPosOld + 2, 0);
+ tilemap.SetTile(GridXPosOld, GridYPosOld - 2, 0);
+ tilemap.SetTile(GridXPosOld - 1, GridYPosOld - 1, 0);
+ tilemap.SetTile(GridXPosOld - 1, GridYPosOld + 1, 0);
+ tilemap.SetTile(GridXPosOld - 2, GridYPosOld, 0);
+
+ //write new markings
+ tilemap.SetTile(GridXPos + 2, GridYPos, 2);
+ tilemap.SetTile(GridXPos + 1, GridYPos - 1, 2);
+ tilemap.SetTile(GridXPos + 1, GridYPos + 1, 2);
+ tilemap.SetTile(GridXPos , GridYPos + 2, 2);
+ tilemap.SetTile(GridXPos, GridYPos - 2, 2);
+ tilemap.SetTile(GridXPos - 1, GridYPos - 1, 2);
+ tilemap.SetTile(GridXPos - 1, GridYPos + 1, 2);
+ tilemap.SetTile(GridXPos - 2, GridYPos, 2);
+ GridXPosOld = GridXPos;
+ GridYPosOld = GridYPos;
+ } */
+
+ // Check the Player's X,Y position, and determine if we need to move a
+ // Scene up, down, left, or right. We also check the current J and I values,
+ // ensuring that we don't move past our actual tileset, into a plain grey screen
+ const float HALF_TILE = Global.GRID_WIDTH / 2;
+ if (Global.player.X - CameraX < HALF_TILE)
+ {
+ if (screenJ > 0)
+ {
+ if (Global.player.X > 50)
+ {
+ screenJ--;
+ this.Scroll(-1, 0);
+ }
+ }
+ }
+
+ if (Global.player.Y - CameraY < HALF_TILE)
+ {
+ if (screenI > 0)
+ {
+ if (Global.player.Y > 32)
+ {
+ screenI--;
+ this.Scroll(0, -1);
+ }
+ }
+ }
+
+ if (Global.player.X - CameraX - Global.GAME_WIDTH > -HALF_TILE)
+ {
+ if (screenJ < 2)
+ {
+ screenJ++;
+ this.Scroll(1, 0);
+ }
+ }
+
+ if (Global.player.Y - CameraY - Global.GAME_HEIGHT > -HALF_TILE)
+ {
+ if (screenI < 1)
+ {
+ screenI++;
+ this.Scroll(0, 1);
+ }
+ }
+
+ //Write Tiles around the player
+
+ }
+
+ // Scroll method that moves the CameraX, CameraY
+ // coordinates by the multiple dx, dy values
+ public void Scroll(int dx, int dy)
+ {
+ // Pause the game when we start scrolling
+ Global.paused = true;
+
+ // Set the nextScene and call UpdateLists to
+ // ensure all Entities are cleaned up properly
+ nextScene = new GameScene(screenJ, screenI, Global.player);
+ nextScene.UpdateLists();
+
+ // Push the player over with the screen via a Tween
+ float pushPlayerX = dx * 30;
+ float pushPlayerY = dy * 30;
+
+ Tweener.Tween(Global.player, new
+ {
+ X = Global.player.X + pushPlayerX,
+ Y = Global.player.Y + pushPlayerY
+ }, 30f, 0);
+
+ // Finally, push the Camera over by a multiple of the
+ // Game's width and height, and set the call back method
+ // to our new ScrollDone method
+ Tweener.Tween(this, new
+ {
+ CameraX = CameraX + Global.GAME_WIDTH * dx,
+ CameraY = CameraY + Global.GAME_HEIGHT * dy
+ }, 30f, 0).OnComplete(ScrollDone);
+ }
+
+ // Method called once the screen scrolling is all done
+ public void ScrollDone()
+ {
+ // Once the scroll is done remove all added graphics
+ // and call UpdateLists to clean everything up and
+ // then switch to the nextScene
+ RemoveAll();
+ UpdateLists();
+
+ // Set the nextScene's Camera values to the current Scene's
+ // freshly tweened camera values, otherwise we snap back to screen 0,0
+ nextScene.CameraX = CameraX;
+ nextScene.CameraY = CameraY;
+ Global.CLUNK.SwitchScene(nextScene);
+ }
+
+ private void LoadWorld(string map, string solids)
+ {
+ // Get our CSV map in string format and load it via our tilemap
+ string newMap = CSVToString(map);
+ tilemap.LoadCSV(newMap);
+
+ // Get our csv solid map and load it into our GridCollider
+ string newSolids = CSVToString(solids);
+ grid.LoadCSV(newSolids);
+ }
+
+ // Add this method to your GameScene.cs class
+ private static string CSVToString(string csvMap)
+ {
+ string ourMap = "";
+
+ using (var reader = new StreamReader(csvMap))
+ {
+ // Read each line, adding a line-break to the end of each
+ string line;
+ while ((line = reader.ReadLine()) != null)
+ {
+ ourMap += line;
+ ourMap += "\n";
+ }
+ }
+
+ return ourMap;
+ }
+
+ }
+}
diff --git a/Clunk/Scenes/TitleScreen.cs b/Clunk/Scenes/TitleScreen.cs
new file mode 100644
index 0000000..d3227ad
--- /dev/null
+++ b/Clunk/Scenes/TitleScreen.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Otter;
+using Clunk;
+
+namespace Clunk.Scenes
+{
+ public class TitleScene : Scene
+ {
+ // Create a new Image object, referencing the Otter image in our Assets folder
+ public Image titleImage = new Image(Assets.TITLE_IMG);
+ public Text titleText = new Text("Clunk", Assets.FONT_PANIC, 84);
+ public Text enterText = new Text("Press Enter", Assets.FONT_PANIC, 40);
+ public const float TIMER_BLINK = 25f;
+ public float blinkTimer = 0;
+ // Create a new, looping sound object, with our MUSIC_TITLE as its source
+ public Music titleSong = new Music(Assets.MUSIC_TITLE, true);
+
+ public TitleScene()
+ {
+ // Center the title picture
+ titleImage.CenterOrigin();
+ titleImage.X = Global.CLUNK.HalfWidth;
+ titleImage.Y = 1000; // When tweening something in, make sure it is actually off the screen first
+ this.AddGraphic(titleImage);
+
+ // Otter utilizes the C# Tweening library called Glide
+ // More info can be found here: http://www.reddit.com/r/gamedev/comments/1fabdh/
+ Tweener.Tween(titleImage, new { Y = 250 }, 30f, 0f).Ease(Ease.BackOut);
+
+ // Set the text's outline color to the
+ // hex color #7FA8D2 (Otter2d.com Blue)
+ titleText.OutlineColor = new Otter.Color("7FA8D2");
+ titleText.OutlineThickness = 3; // Set the outline thickness to 3 pixels
+ titleText.CenterOrigin();
+ titleText.X = Global.CLUNK.HalfWidth;
+ titleText.Y = 25;
+ this.AddGraphic(titleText);
+
+ enterText.OutlineColor = new Otter.Color("7FA8D2");
+ enterText.OutlineThickness = 2;
+ enterText.CenterOrigin();
+ enterText.X = Global.CLUNK.HalfWidth;
+ enterText.Y = 450;
+ this.AddGraphic(enterText);
+
+ titleSong.Play();
+ }
+
+ public override void Update()
+ {
+ base.Update();
+
+ blinkTimer++;
+ if (blinkTimer >= TIMER_BLINK)
+ {
+ enterText.Visible = !enterText.Visible;
+ blinkTimer = 0;
+ }
+
+ if (Global.PlayerSession.Controller.Button("Enter").Pressed)
+ {
+ titleSong.Stop();
+
+ Global.CLUNK.RemoveScene();
+ Global.CLUNK.AddScene(new GameScene());
+ }
+ }
+ }
+}
diff --git a/Clunk/TopDownMovement.cs b/Clunk/TopDownMovement.cs
new file mode 100644
index 0000000..1c5b8c1
--- /dev/null
+++ b/Clunk/TopDownMovement.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Otter;
+
+namespace Clunk
+{
+ class TopDownMovement : Component
+ {
+ Axis axis;
+
+ float moveSpeed;
+
+ public TopDownMovement(Axis movementAxis,float speed)
+ {
+ axis = movementAxis;
+ moveSpeed = speed;
+ }
+
+ public override void Update()
+ {
+ base.Update();
+
+ Entity.AddPosition(axis, moveSpeed);
+ }
+
+ }
+}
diff --git a/Clunk/Util/CameraShaker.cs b/Clunk/Util/CameraShaker.cs
new file mode 100644
index 0000000..335abab
--- /dev/null
+++ b/Clunk/Util/CameraShaker.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Otter;
+using Clunk;
+
+namespace Clunk.Util
+{
+ public class CameraShaker : Entity
+ {
+ // Variables that will store our camera X,Y coordinates before shaking
+ private float priorCameraX = 0f;
+ private float priorCameraY = 0f;
+
+ // Variable used to keep track of how long we have been shaking for
+ private float shakeTimer = 0f;
+ // Number of frames to shake the camera for. Gets set in constructor
+ private float shakeFrames = 0f;
+ // Bool used to determine if the camera needs shaking or not
+ private bool shakeCamera = false;
+
+ // Default constructor
+ public CameraShaker()
+ {
+ }
+
+ public void ShakeCamera(float shakeDur = 20f)
+ {
+ // If camera isn't already shaking
+ if (!shakeCamera)
+ {
+ // Save our original X,Y values
+ priorCameraX = this.Scene.CameraX;
+ priorCameraY = this.Scene.CameraY;
+
+ // Set shakeCamera to true, and our shake duration
+ shakeCamera = true;
+ shakeFrames = shakeDur;
+ }
+ }
+
+ public override void Update()
+ {
+ if (shakeCamera)
+ {
+ // Move the Camera X,Y values a random, but controlled amount
+ this.Scene.CameraX = priorCameraX + (10 - 6 * 2 * Rand.Float(0, 1));
+ this.Scene.CameraY = priorCameraY + (10 - 6 * 2 * Rand.Float(0, 1));
+
+ // Increase the shake timer by one frame
+ // and check if we have been shaking long enough
+ shakeTimer++;
+ if (shakeTimer >= shakeFrames)
+ {
+ shakeCamera = false;
+ shakeTimer = 0;
+ shakeFrames = 0;
+
+ this.Scene.CameraX = priorCameraX;
+ this.Scene.CameraY = priorCameraY;
+ }
+ }
+ }
+ }
+}
diff --git a/Clunk/Util/Gravity.cs b/Clunk/Util/Gravity.cs
new file mode 100644
index 0000000..64bce2a
--- /dev/null
+++ b/Clunk/Util/Gravity.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Otter;
+using Clunk;
+
+namespace Clunk.Util
+{
+ class Gravity : Entity
+ {
+
+ //Fallspeed every Linked Entity is accelerated
+ private float fallSpeed;
+
+ private enum direction
+ {
+ UP,
+ DOWN,
+ LEFT,
+ RIGHT
+
+ }
+
+ List entityList = new List();
+ public Gravity(float acceleration)
+ {
+ //Acceleration² for increasing speed
+ fallSpeed = acceleration * acceleration / 1000;
+
+ }
+
+ public void linkToGravity(ref Entity entity)
+ {
+ entityList.Add(entity);
+ }
+ public override void Update()
+ {
+
+ }
+ }
+}
diff --git a/Clunk/tiles.png b/Clunk/tiles.png
new file mode 100644
index 0000000..5fb32b7
Binary files /dev/null and b/Clunk/tiles.png differ