diff --git a/android/assets/text/game/shootingrange/shootingrange_cs.properties b/android/assets/text/game/shootingrange/shootingrange_cs.properties
new file mode 100644
index 0000000000000000000000000000000000000000..2d6d455253c5bcc49c30839a47deb8fc745d4cca
--- /dev/null
+++ b/android/assets/text/game/shootingrange/shootingrange_cs.properties
@@ -0,0 +1,10 @@
+game_shootingrange_rulemessage_understand=RozumĂ­m
+game_shootingrange_result_0=Vedle jak ta jedle. Tohle bude chtít hodně tréninku.
+game_shootingrange_result_1=Ještě\u00A0že ty\u00A0náboje nemusíš platit! Ale neboj, žádný pistolník z\u00A0nebe nespadl.
+game_shootingrange_result_2=Pěkná série zásahů, ale chce to ještě trochu víc se soustředit.
+game_shootingrange_result_3=Na divokém západě by\u00A0se před tebou všem klepala kolena.
+
+game_shootingrange_loadingtext_1=Pozorně sleduj kytku v\u00A0pravém horním rohu. Na\u00A0střelnici trefuj kytky stejného tvaru a\u00A0barvy.
+game_shootingrange_loadingtext_2=Kliknutí na bednu s\u00A0hvězdičkou ti\u00A0strefování kytek ulehčí, kliknutí na\u00A0bednu s\u00A0lebkou naopak ztíží.
+game_shootingrange_plus=+5
+game_shootingrange_minus=-5
diff --git a/android/assets/text/game/shootingrange/shootingrange_sk.properties b/android/assets/text/game/shootingrange/shootingrange_sk.properties
new file mode 100644
index 0000000000000000000000000000000000000000..a575a2f2aadaf18843c9d19ea03c4392824abe8a
--- /dev/null
+++ b/android/assets/text/game/shootingrange/shootingrange_sk.properties
@@ -0,0 +1,12 @@
+game_shootingrange_rulemessage_understand=Rozumiem
+game_kidnapping_result_0=Vedľa ako tá jedľa. Toto bude chcieť trochu tréningu.
+game_kidnapping_result_1=Ešte že tie náboje nemusíš platiť! Ale neboj, žiadny pištolník z neba nespadol.
+game_kidnapping_result_2=Pekná séria zásahov, ale chce to ešte trochu viac sa sústrediť.
+game_kidnapping_result_3=Na divokom západe by sa pred tebou všetkým klepali kolená.
+
+game_shootingrange_loadingtext_1=Pozorne sleduj kvet v pravom hornom rohu. Na strelnici triafaj kvety rovnakého tvaru a farby.
+game_shootingrange_loadingtext_2=Kliknutie na bedňu s hviezdičkou ti triafanie kvetov uľahčí, kliknutie na bedňu s lebkou naopak sťaží.
+game_shootingrange_plus=+5
+game_shootingrange_minus=-5
+
+
diff --git a/core/assets/common/game/kidnapping/mfx/error.mp3 b/core/assets/common/game/kidnapping/sfx/error.mp3
similarity index 100%
rename from core/assets/common/game/kidnapping/mfx/error.mp3
rename to core/assets/common/game/kidnapping/sfx/error.mp3
diff --git a/core/assets/common/game/shootingrange/gfx/background.png b/core/assets/common/game/shootingrange/gfx/background.png
new file mode 100644
index 0000000000000000000000000000000000000000..dc40b155a65be61c7ade375882d370e263cbd071
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/background.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/box_bad.png b/core/assets/common/game/shootingrange/gfx/box_bad.png
new file mode 100644
index 0000000000000000000000000000000000000000..880a3c8fa37a1abcc873af3083515ce1b71687f6
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/box_bad.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/box_good.png b/core/assets/common/game/shootingrange/gfx/box_good.png
new file mode 100644
index 0000000000000000000000000000000000000000..bba8410b930e40a7f77d789dc6e297b7ff106938
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/box_good.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/carousel.png b/core/assets/common/game/shootingrange/gfx/carousel.png
new file mode 100644
index 0000000000000000000000000000000000000000..99e1f8bdf468eddd528617f499fee0fe513d6936
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/carousel.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/effects/1smoke.png b/core/assets/common/game/shootingrange/gfx/effects/1smoke.png
new file mode 100644
index 0000000000000000000000000000000000000000..c77b2a07e2c4941f46079a3f78b6733bded8bd3d
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/effects/1smoke.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/effects/2smoke.png b/core/assets/common/game/shootingrange/gfx/effects/2smoke.png
new file mode 100644
index 0000000000000000000000000000000000000000..aa71a99c67b34d01d7086d0e54b8188fd0381c07
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/effects/2smoke.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/effects/3smoke.png b/core/assets/common/game/shootingrange/gfx/effects/3smoke.png
new file mode 100644
index 0000000000000000000000000000000000000000..6dfe7037df34caba5a7d18a20f29bf82abb43c84
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/effects/3smoke.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/effects/4smoke.png b/core/assets/common/game/shootingrange/gfx/effects/4smoke.png
new file mode 100644
index 0000000000000000000000000000000000000000..d5d93f5b687ea4bae4a6bb586a77fdf4ab7b7531
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/effects/4smoke.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/effects/5smoke.png b/core/assets/common/game/shootingrange/gfx/effects/5smoke.png
new file mode 100644
index 0000000000000000000000000000000000000000..c1149bd393b57823397727d4823617e902a0ce1b
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/effects/5smoke.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/effects/bad_fast.png b/core/assets/common/game/shootingrange/gfx/effects/bad_fast.png
new file mode 100644
index 0000000000000000000000000000000000000000..9f2f557ed1aa46f184b7e3238cc0691e5f72a3ec
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/effects/bad_fast.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/effects/bad_minus5.png b/core/assets/common/game/shootingrange/gfx/effects/bad_minus5.png
new file mode 100644
index 0000000000000000000000000000000000000000..abd6bbf6e026f38d65adf32bba7af1045ae6080b
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/effects/bad_minus5.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/effects/bad_minus7.png b/core/assets/common/game/shootingrange/gfx/effects/bad_minus7.png
new file mode 100644
index 0000000000000000000000000000000000000000..b407a3177d53a0c5451aebdc068757e6df408a43
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/effects/bad_minus7.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/effects/good_plus1.png b/core/assets/common/game/shootingrange/gfx/effects/good_plus1.png
new file mode 100644
index 0000000000000000000000000000000000000000..d7be57ab4dea4dad0fa2b2082beba3dc57de8184
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/effects/good_plus1.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/effects/good_plus5.png b/core/assets/common/game/shootingrange/gfx/effects/good_plus5.png
new file mode 100644
index 0000000000000000000000000000000000000000..7d6c907356402391c9996ae2851cb5fb45761ca4
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/effects/good_plus5.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/effects/good_plus7.png b/core/assets/common/game/shootingrange/gfx/effects/good_plus7.png
new file mode 100644
index 0000000000000000000000000000000000000000..29a4cb3b2719d754fc87e313d8001757a887ba84
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/effects/good_plus7.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/effects/good_slow.png b/core/assets/common/game/shootingrange/gfx/effects/good_slow.png
new file mode 100644
index 0000000000000000000000000000000000000000..2ca26e0cb1291e8d49ef892a8753baaa7a9f3995
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/effects/good_slow.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._1.png b/core/assets/common/game/shootingrange/gfx/flowers/._1.png
new file mode 100644
index 0000000000000000000000000000000000000000..d376f42b0f5b93584d00554fef53c146e365f14c
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._1.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._10.png b/core/assets/common/game/shootingrange/gfx/flowers/._10.png
new file mode 100644
index 0000000000000000000000000000000000000000..929226701b13f6b9a034348d00287b887d7ed480
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._10.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._11.png b/core/assets/common/game/shootingrange/gfx/flowers/._11.png
new file mode 100644
index 0000000000000000000000000000000000000000..5dacb8433708c9451e1f3d3f74b409c14fae9478
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._11.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._12.png b/core/assets/common/game/shootingrange/gfx/flowers/._12.png
new file mode 100644
index 0000000000000000000000000000000000000000..93f024149d28425ddc852f6732870ace00fdc89b
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._12.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._13.png b/core/assets/common/game/shootingrange/gfx/flowers/._13.png
new file mode 100644
index 0000000000000000000000000000000000000000..e748f10a7c999e49e60bf7f09186ff3266f4f79e
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._13.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._14.png b/core/assets/common/game/shootingrange/gfx/flowers/._14.png
new file mode 100644
index 0000000000000000000000000000000000000000..8f96d8c6152d25260ff3ba57d4910e460015ecc1
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._14.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._15.png b/core/assets/common/game/shootingrange/gfx/flowers/._15.png
new file mode 100644
index 0000000000000000000000000000000000000000..fd1908b1660bc228f07ebb32720c1019b02726be
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._15.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._16.png b/core/assets/common/game/shootingrange/gfx/flowers/._16.png
new file mode 100644
index 0000000000000000000000000000000000000000..a32e7c8012d11f8fb0d86911490be3ae3e32b547
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._16.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._17.png b/core/assets/common/game/shootingrange/gfx/flowers/._17.png
new file mode 100644
index 0000000000000000000000000000000000000000..f690ff0a7b968aeaafdf547bdff3f6b18f378a24
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._17.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._18.png b/core/assets/common/game/shootingrange/gfx/flowers/._18.png
new file mode 100644
index 0000000000000000000000000000000000000000..dc64c038fce17e9e62fc2b3cb40dace628ee8eb8
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._18.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._19.png b/core/assets/common/game/shootingrange/gfx/flowers/._19.png
new file mode 100644
index 0000000000000000000000000000000000000000..b9e85173a828e6ac06beb02bcb281833ec7aa504
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._19.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._2.png b/core/assets/common/game/shootingrange/gfx/flowers/._2.png
new file mode 100644
index 0000000000000000000000000000000000000000..232152005bbca707bf0f13b6a722c4fe3c1aa7fe
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._2.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._20.png b/core/assets/common/game/shootingrange/gfx/flowers/._20.png
new file mode 100644
index 0000000000000000000000000000000000000000..08196c7af24161f4e01501424d41d0bd35581d66
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._20.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._21.png b/core/assets/common/game/shootingrange/gfx/flowers/._21.png
new file mode 100644
index 0000000000000000000000000000000000000000..57b0f0cdc64a1d0ce63809a2875bc41300a7b44b
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._21.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._22.png b/core/assets/common/game/shootingrange/gfx/flowers/._22.png
new file mode 100644
index 0000000000000000000000000000000000000000..226ffb3e6f9a29a546e685aa604a8b1d4dd039b9
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._22.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._23.png b/core/assets/common/game/shootingrange/gfx/flowers/._23.png
new file mode 100644
index 0000000000000000000000000000000000000000..fb88e0cbfc5762e2dcba2b5f997b68d87b4bc898
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._23.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._24.png b/core/assets/common/game/shootingrange/gfx/flowers/._24.png
new file mode 100644
index 0000000000000000000000000000000000000000..c1ada061a1820927c15494da17297c40b8a7dd44
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._24.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._3.png b/core/assets/common/game/shootingrange/gfx/flowers/._3.png
new file mode 100644
index 0000000000000000000000000000000000000000..3e695b26d4f2c9aa8e622a33682c23d804f72c50
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._3.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._4.png b/core/assets/common/game/shootingrange/gfx/flowers/._4.png
new file mode 100644
index 0000000000000000000000000000000000000000..bdf7d88bd5e4993528394a7599b0b8592e1318fc
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._4.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._5.png b/core/assets/common/game/shootingrange/gfx/flowers/._5.png
new file mode 100644
index 0000000000000000000000000000000000000000..7668f1610803424c94905c3f7d54dcad251f1f5b
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._5.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._6.png b/core/assets/common/game/shootingrange/gfx/flowers/._6.png
new file mode 100644
index 0000000000000000000000000000000000000000..2b4858912adb3e47c78ea9eb1339a29c436d9879
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._6.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._7.png b/core/assets/common/game/shootingrange/gfx/flowers/._7.png
new file mode 100644
index 0000000000000000000000000000000000000000..1bdd39c66fc0ea761ad31617def6bbece923a5a6
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._7.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._8.png b/core/assets/common/game/shootingrange/gfx/flowers/._8.png
new file mode 100644
index 0000000000000000000000000000000000000000..6bef76b018db356b18efa4f42719c864d0e50640
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._8.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/._9.png b/core/assets/common/game/shootingrange/gfx/flowers/._9.png
new file mode 100644
index 0000000000000000000000000000000000000000..24bca9292548d71f80d828fa94f4fade0bba55d3
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/._9.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/1.png b/core/assets/common/game/shootingrange/gfx/flowers/1.png
new file mode 100644
index 0000000000000000000000000000000000000000..def0b1afe28f73c3cb3ed75c13bab69e7aee9b60
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/1.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/10.png b/core/assets/common/game/shootingrange/gfx/flowers/10.png
new file mode 100644
index 0000000000000000000000000000000000000000..ed96dab5610f829176ede8cc6737236edc20cba5
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/10.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/11.png b/core/assets/common/game/shootingrange/gfx/flowers/11.png
new file mode 100644
index 0000000000000000000000000000000000000000..4b795617b54f44f9dfabd29a7857690d49d9ddba
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/11.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/12.png b/core/assets/common/game/shootingrange/gfx/flowers/12.png
new file mode 100644
index 0000000000000000000000000000000000000000..8b7a1657670de7f7119128e4039ca4cdc376b7ed
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/12.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/13.png b/core/assets/common/game/shootingrange/gfx/flowers/13.png
new file mode 100644
index 0000000000000000000000000000000000000000..a8fe0405415b502eca1060f2c8ffe02181fe5409
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/13.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/14.png b/core/assets/common/game/shootingrange/gfx/flowers/14.png
new file mode 100644
index 0000000000000000000000000000000000000000..806438fd0de311ebd5e42a1a0056aa4c9ef62843
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/14.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/15.png b/core/assets/common/game/shootingrange/gfx/flowers/15.png
new file mode 100644
index 0000000000000000000000000000000000000000..091141023b5c2e0762d76807853d5ec5763c091f
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/15.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/16.png b/core/assets/common/game/shootingrange/gfx/flowers/16.png
new file mode 100644
index 0000000000000000000000000000000000000000..416bf8fa6fe22db1ee3f45fdc4d0aedb7bcc9cd0
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/16.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/17.png b/core/assets/common/game/shootingrange/gfx/flowers/17.png
new file mode 100644
index 0000000000000000000000000000000000000000..d1086798cd8e39008eae0332444548a1116acf3a
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/17.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/18.png b/core/assets/common/game/shootingrange/gfx/flowers/18.png
new file mode 100644
index 0000000000000000000000000000000000000000..7c4a4ed3a09c1911868b0cf879c770aa88829724
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/18.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/19.png b/core/assets/common/game/shootingrange/gfx/flowers/19.png
new file mode 100644
index 0000000000000000000000000000000000000000..21690116ea9637e9a320536069022257c57f0840
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/19.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/2.png b/core/assets/common/game/shootingrange/gfx/flowers/2.png
new file mode 100644
index 0000000000000000000000000000000000000000..017f65f3071c46ce150b38d462fe33b3b37885a3
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/2.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/20.png b/core/assets/common/game/shootingrange/gfx/flowers/20.png
new file mode 100644
index 0000000000000000000000000000000000000000..b3fccac4a47c17efed77ce580486dbdae971b011
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/20.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/21.png b/core/assets/common/game/shootingrange/gfx/flowers/21.png
new file mode 100644
index 0000000000000000000000000000000000000000..f46c35ff43fe0ae8ff9525e8809c6e3311cc40cc
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/21.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/22.png b/core/assets/common/game/shootingrange/gfx/flowers/22.png
new file mode 100644
index 0000000000000000000000000000000000000000..19235fbe4479c1dafc69d31ee74f734bff6009cc
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/22.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/23.png b/core/assets/common/game/shootingrange/gfx/flowers/23.png
new file mode 100644
index 0000000000000000000000000000000000000000..214703524d57b918653413d78930ee122c96830e
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/23.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/24.png b/core/assets/common/game/shootingrange/gfx/flowers/24.png
new file mode 100644
index 0000000000000000000000000000000000000000..53d4bbeb3cc271c3f8ba2faa14e49713a2aea16a
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/24.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/3.png b/core/assets/common/game/shootingrange/gfx/flowers/3.png
new file mode 100644
index 0000000000000000000000000000000000000000..68e94c9da3117cdde40ca65aaaa0a5623d62f501
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/3.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/4.png b/core/assets/common/game/shootingrange/gfx/flowers/4.png
new file mode 100644
index 0000000000000000000000000000000000000000..1d799822d92f9d886a3639a06deeb68b01a10c50
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/4.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/5.png b/core/assets/common/game/shootingrange/gfx/flowers/5.png
new file mode 100644
index 0000000000000000000000000000000000000000..73560f824f217698e588e9eae04c35c6703fc117
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/5.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/6.png b/core/assets/common/game/shootingrange/gfx/flowers/6.png
new file mode 100644
index 0000000000000000000000000000000000000000..3b5088e2b07f6a1ab4ccf4d998641b62df87e7b2
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/6.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/7.png b/core/assets/common/game/shootingrange/gfx/flowers/7.png
new file mode 100644
index 0000000000000000000000000000000000000000..412b8bbc6d2e0748d23115bd8aa4c23ffeadeda9
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/7.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/8.png b/core/assets/common/game/shootingrange/gfx/flowers/8.png
new file mode 100644
index 0000000000000000000000000000000000000000..eb52a05ece14c6197513c1257b5263170c1c29b6
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/8.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/flowers/9.png b/core/assets/common/game/shootingrange/gfx/flowers/9.png
new file mode 100644
index 0000000000000000000000000000000000000000..41992a6fc24e0bc445c96748fb5512ab11b3df79
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/flowers/9.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/frame.png b/core/assets/common/game/shootingrange/gfx/frame.png
new file mode 100644
index 0000000000000000000000000000000000000000..5f7d6742432750b0ee8440cab88536540b1cf957
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/frame.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/plan1.png b/core/assets/common/game/shootingrange/gfx/plan1.png
new file mode 100644
index 0000000000000000000000000000000000000000..30cd286f25947226f69b9235e1b369c206e5e9e4
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/plan1.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/plan2.png b/core/assets/common/game/shootingrange/gfx/plan2.png
new file mode 100644
index 0000000000000000000000000000000000000000..a68a835d3950969e1aa001b01e9c9156d6ef426d
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/plan2.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/plan3.png b/core/assets/common/game/shootingrange/gfx/plan3.png
new file mode 100644
index 0000000000000000000000000000000000000000..c77f31e3ef5d2b4952e5dd0216dbb49af119b5c1
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/plan3.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/watch.png b/core/assets/common/game/shootingrange/gfx/watch.png
new file mode 100644
index 0000000000000000000000000000000000000000..88dcdbe4e6a9438e67e1b4c1575e15ec53f1d5ad
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/watch.png differ
diff --git a/core/assets/common/game/shootingrange/gfx/watch_hand.png b/core/assets/common/game/shootingrange/gfx/watch_hand.png
new file mode 100644
index 0000000000000000000000000000000000000000..3bcea73300b041ba62480438a6e5c3fa023e810a
Binary files /dev/null and b/core/assets/common/game/shootingrange/gfx/watch_hand.png differ
diff --git a/core/assets/common/game/shootingrange/sfx/bell.mp3 b/core/assets/common/game/shootingrange/sfx/bell.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..278b7b7bb9dc5b1578a7099402d8692deaf13185
Binary files /dev/null and b/core/assets/common/game/shootingrange/sfx/bell.mp3 differ
diff --git a/core/assets/common/game/shootingrange/sfx/box_fast.mp3 b/core/assets/common/game/shootingrange/sfx/box_fast.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..1d72e1d1039b252f35bbe67001438e4928ef45d4
Binary files /dev/null and b/core/assets/common/game/shootingrange/sfx/box_fast.mp3 differ
diff --git a/core/assets/common/game/shootingrange/sfx/box_slow.mp3 b/core/assets/common/game/shootingrange/sfx/box_slow.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..8879b8b8ff318f91b2249af841dc90fc20048239
Binary files /dev/null and b/core/assets/common/game/shootingrange/sfx/box_slow.mp3 differ
diff --git a/core/assets/common/game/shootingrange/sfx/box_smoke.mp3 b/core/assets/common/game/shootingrange/sfx/box_smoke.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..0188de19b4d0cda3f9dcac2c4a149def0752b5e9
Binary files /dev/null and b/core/assets/common/game/shootingrange/sfx/box_smoke.mp3 differ
diff --git a/core/assets/common/game/shootingrange/sfx/carousel_1.mp3 b/core/assets/common/game/shootingrange/sfx/carousel_1.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..a8b603c865f05ee75f8447b4c7fab603dfdce944
Binary files /dev/null and b/core/assets/common/game/shootingrange/sfx/carousel_1.mp3 differ
diff --git a/core/assets/common/game/shootingrange/sfx/carousel_2.mp3 b/core/assets/common/game/shootingrange/sfx/carousel_2.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..cb6718570944bb0f9932f296f0ac28f1ce2978d3
Binary files /dev/null and b/core/assets/common/game/shootingrange/sfx/carousel_2.mp3 differ
diff --git a/core/assets/common/game/shootingrange/sfx/hit_1.mp3 b/core/assets/common/game/shootingrange/sfx/hit_1.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..a60bf3dba90c0669ca551d0d9f60ba8c2cdd7be7
Binary files /dev/null and b/core/assets/common/game/shootingrange/sfx/hit_1.mp3 differ
diff --git a/core/assets/common/game/shootingrange/sfx/hit_2.mp3 b/core/assets/common/game/shootingrange/sfx/hit_2.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..292aa244b7cad4ebf5b9206f9a412c3583bf9ed4
Binary files /dev/null and b/core/assets/common/game/shootingrange/sfx/hit_2.mp3 differ
diff --git a/core/assets/common/game/shootingrange/sfx/hit_3.mp3 b/core/assets/common/game/shootingrange/sfx/hit_3.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..d655143c3cea361a72a0c95e69633f1a1809c838
Binary files /dev/null and b/core/assets/common/game/shootingrange/sfx/hit_3.mp3 differ
diff --git a/core/assets/common/game/shootingrange/sfx/hit_4.mp3 b/core/assets/common/game/shootingrange/sfx/hit_4.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..7a35c6dfec8f330844979ad548c7d16ea20417f9
Binary files /dev/null and b/core/assets/common/game/shootingrange/sfx/hit_4.mp3 differ
diff --git a/core/assets/common/game/shootingrange/sfx/miss.mp3 b/core/assets/common/game/shootingrange/sfx/miss.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..c9493bcb75193be9e3b502f726d6eb6715747e69
Binary files /dev/null and b/core/assets/common/game/shootingrange/sfx/miss.mp3 differ
diff --git a/core/assets/common/game/shootingrange/sfx/swoosh_in.mp3 b/core/assets/common/game/shootingrange/sfx/swoosh_in.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..ddb7602e104c75346d2fefdeeb216b4cb9b224e8
Binary files /dev/null and b/core/assets/common/game/shootingrange/sfx/swoosh_in.mp3 differ
diff --git a/core/assets/common/game/shootingrange/sfx/wrong.mp3 b/core/assets/common/game/shootingrange/sfx/wrong.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..b17c0f4719a52432c8e2932f9c5151cfd9252e15
Binary files /dev/null and b/core/assets/common/game/shootingrange/sfx/wrong.mp3 differ
diff --git a/core/assets/cs/game/shootingrange/mfx/loading.mp3 b/core/assets/cs/game/shootingrange/mfx/loading.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..c43d106861437e19e4098ed0db82437c18248f56
Binary files /dev/null and b/core/assets/cs/game/shootingrange/mfx/loading.mp3 differ
diff --git a/core/assets/cs/game/shootingrange/mfx/result0.mp3 b/core/assets/cs/game/shootingrange/mfx/result0.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..11eacb7172ae0038cf93644ddf54bdb1b8ab394e
Binary files /dev/null and b/core/assets/cs/game/shootingrange/mfx/result0.mp3 differ
diff --git a/core/assets/cs/game/shootingrange/mfx/result1.mp3 b/core/assets/cs/game/shootingrange/mfx/result1.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..3032e486dc903f1d6c034a0f9f88ec2f1c2936bf
Binary files /dev/null and b/core/assets/cs/game/shootingrange/mfx/result1.mp3 differ
diff --git a/core/assets/cs/game/shootingrange/mfx/result2.mp3 b/core/assets/cs/game/shootingrange/mfx/result2.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..27d85c60f731a4aec32262d7679b2f60a2910bb5
Binary files /dev/null and b/core/assets/cs/game/shootingrange/mfx/result2.mp3 differ
diff --git a/core/assets/cs/game/shootingrange/mfx/result3.mp3 b/core/assets/cs/game/shootingrange/mfx/result3.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..92c79af273898feca6c0555c69ed7f805ed6c800
Binary files /dev/null and b/core/assets/cs/game/shootingrange/mfx/result3.mp3 differ
diff --git a/core/assets/sk/game/shootingrange/mfx/loading.mp3 b/core/assets/sk/game/shootingrange/mfx/loading.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..1654e79749f8e1ba8f8fc45d4f339600abbd0be2
Binary files /dev/null and b/core/assets/sk/game/shootingrange/mfx/loading.mp3 differ
diff --git a/core/assets/sk/game/shootingrange/mfx/result0.mp3 b/core/assets/sk/game/shootingrange/mfx/result0.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..6c2c1767dc5a7b3fde5db45c5fb1478442125c13
Binary files /dev/null and b/core/assets/sk/game/shootingrange/mfx/result0.mp3 differ
diff --git a/core/assets/sk/game/shootingrange/mfx/result1.mp3 b/core/assets/sk/game/shootingrange/mfx/result1.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..9bf5b9804593248a7399849bdfd060d69c3fc489
Binary files /dev/null and b/core/assets/sk/game/shootingrange/mfx/result1.mp3 differ
diff --git a/core/assets/sk/game/shootingrange/mfx/result2.mp3 b/core/assets/sk/game/shootingrange/mfx/result2.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..deb32fa60c2eaa115f44c4ca67c59502b9e70434
Binary files /dev/null and b/core/assets/sk/game/shootingrange/mfx/result2.mp3 differ
diff --git a/core/assets/sk/game/shootingrange/mfx/result3.mp3 b/core/assets/sk/game/shootingrange/mfx/result3.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..71fa7a264a9c7ec836cdad71d03428ac7519e4d6
Binary files /dev/null and b/core/assets/sk/game/shootingrange/mfx/result3.mp3 differ
diff --git a/core/src/cz/nic/tablexia/TablexiaSettings.java b/core/src/cz/nic/tablexia/TablexiaSettings.java
index c9ac4c10eba207cbf50ed35cef562c4ff7d78589..1fd0e5349368409fb4aed9fb1e836a2cc7175087 100644
--- a/core/src/cz/nic/tablexia/TablexiaSettings.java
+++ b/core/src/cz/nic/tablexia/TablexiaSettings.java
@@ -9,6 +9,8 @@ import cz.nic.tablexia.bus.ApplicationBus;
 import cz.nic.tablexia.bus.event.LocaleChangedEvent;
 import cz.nic.tablexia.game.GameDefinition;
 import cz.nic.tablexia.game.difficulty.GameDifficulty;
+import cz.nic.tablexia.game.games.kidnapping.KidnappingGame;
+import cz.nic.tablexia.game.games.shooting_range.ShootingRangeGame;
 import cz.nic.tablexia.loader.application.ApplicationTextManager;
 import cz.nic.tablexia.screen.AbstractTablexiaScreen;
 import cz.nic.tablexia.screen.gamemenu.GameMenuScreen;
diff --git a/core/src/cz/nic/tablexia/game/AbstractTablexiaGame.java b/core/src/cz/nic/tablexia/game/AbstractTablexiaGame.java
index 3972215f072721fc51d976a8463dd651a124da48..d49329242d7be75c4c81acbc21a338978ed8ce14 100644
--- a/core/src/cz/nic/tablexia/game/AbstractTablexiaGame.java
+++ b/core/src/cz/nic/tablexia/game/AbstractTablexiaGame.java
@@ -48,7 +48,7 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T>
     public static final String VICTORYSCREEN_RATINGSTAR_DISABLED = "ratingstar_disabled";
     public static final String VICTORYSCREEN_RATINGSTAR_ENABLED  = "ratingstar_enabled";
 
-    public static final String GAME_STATE_RANDOM_SEED            = "randomSeed";
+    public static final String GAME_STATE_RANDOM_SEED = "randomSeed";
 
     private TablexiaRandom random;
     private GameDifficulty gameDifficulty;
@@ -189,33 +189,33 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T>
 
 //////////////////////////// ABSTRACT TABLEXIA GAME
 
-    private final float DIALOG_HEIGHT     = AbstractTablexiaGame.this.getStage().getHeight() * (3f/4);
+    private final float DIALOG_HEIGHT     = AbstractTablexiaGame.this.getStage().getHeight() * (3f / 4);
     private final float DIALOG_WIDTH      = DIALOG_HEIGHT * 1.2f;
     private final float DIALOG_POSITION_X = (AbstractTablexiaGame.this.getStage().getWidth() / 2) - (DIALOG_WIDTH / 2);
-    private final float DIALOG_POSITION_Y = (TablexiaSettings.getMinWorldHeight() / 2) - (DIALOG_HEIGHT / 2);
+    private final float DIALOG_POSITION_Y = (TablexiaSettings.getMinWorldHeight() / 2) - (DIALOG_HEIGHT / 2); // TODO fix for floating screen
 
     private class VictoryDialog extends TwoButtonDialog {
 
         public static final int   RATINGSTARS_COUNT = 3;
         public static final float RATINGSTAR_DELAY  = 0.75f;
 
-        public static final float RESULTSBANNER_WIDTH_RATIO = 2f / 3;
+        public static final float RESULTSBANNER_WIDTH_RATIO      = 2f / 3;
         public static final float RESULTSBANNER_TOPPADDING_RATIO = 1f / 30;
-        public static final float RATINGSTAR_HEIGHT_RATIO = 1f / 8;
+        public static final float RATINGSTAR_HEIGHT_RATIO        = 1f / 8;
 
         Image[] ratingStarsEnabled;
 
         public VictoryDialog() {
             super(DIALOG_POSITION_X,
-                  DIALOG_POSITION_Y,
-                  DIALOG_WIDTH,
-                  DIALOG_HEIGHT,
-                  BackGroundType.DIALOG_SQUARE_BORDERLINES,
-                  new DialogTextContent("TEXT"),
-                  TablexiaButton.ButtonType.BLUE,
-                  TablexiaButton.ButtonType.GREEN,
-                  ApplicationTextManager.getInstance().getText(ApplicationTextManager.ApplicationTextsAssets.VICTORYSCREEN_BUTTON_CHANGEGAME),
-                  ApplicationTextManager.getInstance().getText(ApplicationTextManager.ApplicationTextsAssets.VICTORYSCREEN_BUTTON_REPLAY));
+                    DIALOG_POSITION_Y,
+                    DIALOG_WIDTH,
+                    DIALOG_HEIGHT,
+                    BackGroundType.DIALOG_SQUARE_BORDERLINES,
+                    new DialogTextContent("TEXT"),
+                    TablexiaButton.ButtonType.BLUE,
+                    TablexiaButton.ButtonType.GREEN,
+                    ApplicationTextManager.getInstance().getText(ApplicationTextManager.ApplicationTextsAssets.VICTORYSCREEN_BUTTON_CHANGEGAME),
+                    ApplicationTextManager.getInstance().getText(ApplicationTextManager.ApplicationTextsAssets.VICTORYSCREEN_BUTTON_REPLAY));
             //dialog does not hide on click outside the BG area
             setHideOnOutsideClick(false);
         }
@@ -258,14 +258,14 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T>
             cell.height(ratingStarHeight).width(ratingStarDisabled.getWidth() * ratingStarSizeRatio);
         }
 
-        public Dialog show(int score, Stage stage) {
-            if (score < 0 || score > RATINGSTARS_COUNT) {
-                throw new IllegalArgumentException("Invalid score value: " + score);
+        public Dialog show(int cupsCount, Stage stage) {
+            if (cupsCount < 0 || cupsCount > RATINGSTARS_COUNT) {
+                throw new IllegalArgumentException("Invalid cupsCount value: " + cupsCount);
             }
 
             super.show(stage);
 
-            for (int i = 0; i < score; i++) {
+            for (int i = 0; i < cupsCount; i++) {
                 final Image ratingStarEnabled = ratingStarsEnabled[i];
 
                 addAction(sequence(delay((i + 1) * RATINGSTAR_DELAY), run(new Runnable() {
@@ -324,13 +324,13 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T>
             screenDimmer.addAction(alpha(0));
             screenDimmer.setVisible(true);
             screenDimmer.addAction(sequence(fadeIn(SCREEN_TRANSACTION_FADE_DELAY, Interpolation.pow4Out),
-                                            run(new Runnable() {
-                                                @Override
-                                                public void run() {
-                                                    gameVisible = false;
-                                                }
-                                            }),
-                                            run(onHide)));
+                    run(new Runnable() {
+                        @Override
+                        public void run() {
+                            gameVisible = false;
+                        }
+                    }),
+                    run(onHide)));
         }
     }
 
diff --git a/core/src/cz/nic/tablexia/game/common/media/AssetDescription.java b/core/src/cz/nic/tablexia/game/common/media/AssetDescription.java
new file mode 100644
index 0000000000000000000000000000000000000000..007f40f988045d96331be6cec8e0adc190d3eff1
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/common/media/AssetDescription.java
@@ -0,0 +1,8 @@
+package cz.nic.tablexia.game.common.media;
+
+/**
+ * Created by lhoracek on 6/23/15.
+ */
+public interface AssetDescription {
+    public String getResource();
+}
diff --git a/core/src/cz/nic/tablexia/game/common/media/GfxLibrary.java b/core/src/cz/nic/tablexia/game/common/media/GfxLibrary.java
new file mode 100644
index 0000000000000000000000000000000000000000..341c0251c9cad958b0120cdfccbbab10acd2d531
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/common/media/GfxLibrary.java
@@ -0,0 +1,60 @@
+/**
+ * ****************************************************************************
+ * Tablexia
+ * <p/>
+ * Copyright (C) 2013  CZ NIC z.s.p.o. <podpora at nic dot cz>
+ * <p/>
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * <p/>
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * <p/>
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * ****************************************************************************
+ */
+
+package cz.nic.tablexia.game.common.media;
+
+import com.badlogic.gdx.graphics.g2d.TextureRegion;
+
+import java.util.HashMap;
+
+import cz.nic.tablexia.game.AbstractTablexiaGame;
+
+
+/**
+ * Library of all kidnapping assets except tiles
+ *
+ * @author lhoracek
+ */
+public class GfxLibrary extends HashMap<AssetDescription, String> {
+
+    private static final long   serialVersionUID   = -4016629019721509061L;
+    private static final String DEFAULT_TEXTURE_DIR = "gfx/";
+    private final        String TEXTURE_DIR;
+
+    AbstractTablexiaGame abstractTablexiaGame;
+
+    public GfxLibrary(AbstractTablexiaGame abstractTablexiaGame, AssetDescription[] textures, String dir) {
+        this.abstractTablexiaGame = abstractTablexiaGame;
+        this.TEXTURE_DIR = dir == null ? DEFAULT_TEXTURE_DIR : dir;
+        for (AssetDescription assetDescription : textures) {
+            String path = TEXTURE_DIR + assetDescription.getResource();
+            put(assetDescription, path);
+        }
+    }
+
+    public GfxLibrary(AbstractTablexiaGame abstractTablexiaGame, AssetDescription[] textures) {
+        this(abstractTablexiaGame, textures, null);
+    }
+
+    public TextureRegion getTextureRegion(AssetDescription assetDescription) {
+        return abstractTablexiaGame.getScreenTextureRegion(get(assetDescription));
+    }
+}
diff --git a/core/src/cz/nic/tablexia/game/games/kidnapping/media/MfxLibrary.java b/core/src/cz/nic/tablexia/game/common/media/SfxLibrary.java
similarity index 54%
rename from core/src/cz/nic/tablexia/game/games/kidnapping/media/MfxLibrary.java
rename to core/src/cz/nic/tablexia/game/common/media/SfxLibrary.java
index 536eff45e5a7a5204db32327e2c8dc3f6d916b8b..a6afdaded4171e879654d14aabe0fda0a2773923 100644
--- a/core/src/cz/nic/tablexia/game/games/kidnapping/media/MfxLibrary.java
+++ b/core/src/cz/nic/tablexia/game/common/media/SfxLibrary.java
@@ -19,31 +19,37 @@
  * ****************************************************************************
  */
 
-package cz.nic.tablexia.game.games.kidnapping.media;
+package cz.nic.tablexia.game.common.media;
 
 
+import com.badlogic.gdx.audio.Sound;
+
 import java.util.HashMap;
 
-import cz.nic.tablexia.game.games.kidnapping.media.assets.SoundType;
+import cz.nic.tablexia.game.AbstractTablexiaGame;
+import cz.nic.tablexia.util.Log;
+
 
 /**
  * @author lhoracek
  */
-public class MfxLibrary extends HashMap<SoundType, String> {
+public class SfxLibrary extends HashMap<AssetDescription, String> {
 
-    private static final String SOUNDS_DIR       = "mfx/";
+    private static final String SOUNDS_DIR       = "sfx/";
     public static final  String SOUNDS_EXTENSION = ".mp3";
 
+    private AbstractTablexiaGame abstractTablexiaGame;
 
-    public MfxLibrary() {
-        super();
-        loadSounds();
+    public SfxLibrary(AbstractTablexiaGame abstractTablexiaGame, AssetDescription[] assetDescriptions) {
+        this.abstractTablexiaGame = abstractTablexiaGame;
+        for (AssetDescription assetDescription : assetDescriptions) {
+            String path = SOUNDS_DIR + assetDescription.getResource() + SOUNDS_EXTENSION;
+            Log.info(getClass(), "Adding sound " + path);
+            put(assetDescription, path);
+        }
     }
 
-    private void loadSounds() {
-        for (SoundType sound : SoundType.values()) {
-            String path = SOUNDS_DIR + sound.getResource() + SOUNDS_EXTENSION;
-            put(sound, path);
-        }
+    public Sound getSound(AssetDescription assetDescription) {
+        return abstractTablexiaGame.getSound(get(assetDescription));
     }
 }
diff --git a/core/src/cz/nic/tablexia/game/games/kidnapping/KidnappingGame.java b/core/src/cz/nic/tablexia/game/games/kidnapping/KidnappingGame.java
index fb9751c4d7e1e2815c9d24bdde567130c434f4c3..f965ef79cc14e8f8f0ec0fb8d5ee5bac6d4a8d2d 100644
--- a/core/src/cz/nic/tablexia/game/games/kidnapping/KidnappingGame.java
+++ b/core/src/cz/nic/tablexia/game/games/kidnapping/KidnappingGame.java
@@ -5,12 +5,16 @@ import com.badlogic.gdx.scenes.scene2d.EventListener;
 import com.badlogic.gdx.scenes.scene2d.InputEvent;
 import com.badlogic.gdx.scenes.scene2d.actions.Actions;
 import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
+import com.google.common.collect.ObjectArrays;
 
 import java.util.Arrays;
 import java.util.List;
 
 import cz.nic.tablexia.TablexiaSettings;
 import cz.nic.tablexia.game.AbstractTablexiaGame;
+import cz.nic.tablexia.game.common.media.AssetDescription;
+import cz.nic.tablexia.game.common.media.GfxLibrary;
+import cz.nic.tablexia.game.common.media.SfxLibrary;
 import cz.nic.tablexia.game.games.kidnapping.actions.ArrowMusicAction;
 import cz.nic.tablexia.game.games.kidnapping.actions.CenterTileAction;
 import cz.nic.tablexia.game.games.kidnapping.actions.fades.CorrectAlphaAction;
@@ -23,9 +27,9 @@ import cz.nic.tablexia.game.games.kidnapping.actions.fades.WrongAlphaAction;
 import cz.nic.tablexia.game.games.kidnapping.actors.Arrow;
 import cz.nic.tablexia.game.games.kidnapping.actors.Map;
 import cz.nic.tablexia.game.games.kidnapping.media.DirectionSounds;
-import cz.nic.tablexia.game.games.kidnapping.media.GfxLibrary;
-import cz.nic.tablexia.game.games.kidnapping.media.MfxLibrary;
 import cz.nic.tablexia.game.games.kidnapping.media.assets.SoundType;
+import cz.nic.tablexia.game.games.kidnapping.media.assets.TextureTypes;
+import cz.nic.tablexia.game.games.kidnapping.media.assets.TileType;
 import cz.nic.tablexia.game.games.kidnapping.model.Direction;
 import cz.nic.tablexia.game.games.kidnapping.model.GameState;
 import cz.nic.tablexia.game.games.kidnapping.model.Position;
@@ -37,14 +41,14 @@ import cz.nic.tablexia.util.Log;
  */
 public class KidnappingGame extends AbstractTablexiaGame<GameState> {
 
-    private GfxLibrary gfxLibrary = new GfxLibrary();
-    private MfxLibrary mfxLibrary = new MfxLibrary();
-    private Map        map;
+    private GfxLibrary gfxLibrary = new GfxLibrary(this, ObjectArrays.concat(TextureTypes.values(), TileType.values(), AssetDescription.class));
+    private SfxLibrary sfxLibrary = new SfxLibrary(this, SoundType.values());
+    private Map map;
 
     @Override
     protected void prepareScreenSoundAssetNames(List<String> soundsFileNames) {
         super.prepareScreenSoundAssetNames(soundsFileNames);
-        soundsFileNames.addAll(mfxLibrary.values());
+        soundsFileNames.addAll(sfxLibrary.values());
     }
 
     @Override
@@ -58,8 +62,7 @@ public class KidnappingGame extends AbstractTablexiaGame<GameState> {
     protected void gameLoaded(java.util.Map<String, String> gameState) {
         // TODO show rule screen
         // TODO show sub-rule screen
-        getStage().setDebugAll(TablexiaSettings.getInstance().isShowBoundingBoxes());
-        getStage().addActor(map = Map.MapFactory.createInstance(this, getData()));
+        getStage().addActor(map = Map.MapFactory.createInstance(this, gfxLibrary, getData()));
         map.setBounds(0, getStage().getCamera().position.y - getStage().getHeight() / 2, getStage().getWidth(), getStage().getHeight()); // scaling viewport camera y-position adjustment
         map.setMapScale(0.5f);
         // center first tile and start game
@@ -131,7 +134,7 @@ public class KidnappingGame extends AbstractTablexiaGame<GameState> {
                                             }
                                         })));
                                     } else {
-                                        getSound(mfxLibrary.get(SoundType.SOUND_ERROR)).play();
+                                        sfxLibrary.getSound(SoundType.SOUND_ERROR).play();
                                         map.addAction(Actions.sequence(WrongAlphaAction.fadeIn(), WrongAlphaAction.fadeOut()));
                                         wrong();
                                     }
@@ -163,8 +166,8 @@ public class KidnappingGame extends AbstractTablexiaGame<GameState> {
         return gfxLibrary;
     }
 
-    public MfxLibrary getMfxLibrary() {
-        return mfxLibrary;
+    public SfxLibrary getSfxLibrary() {
+        return sfxLibrary;
     }
 
     public String getVictoryText(int progress) {
diff --git a/core/src/cz/nic/tablexia/game/games/kidnapping/actors/Map.java b/core/src/cz/nic/tablexia/game/games/kidnapping/actors/Map.java
index 9c9924a1b01605651016285e7536fcfba005c437..29c1f40f5e19c71d8c3fbc915ec597eb3e7f879d 100644
--- a/core/src/cz/nic/tablexia/game/games/kidnapping/actors/Map.java
+++ b/core/src/cz/nic/tablexia/game/games/kidnapping/actors/Map.java
@@ -7,9 +7,10 @@ import com.badlogic.gdx.scenes.scene2d.ui.Image;
 
 import java.util.HashMap;
 
+import cz.nic.tablexia.game.common.media.GfxLibrary;
 import cz.nic.tablexia.game.games.kidnapping.KidnappingGame;
 import cz.nic.tablexia.game.games.kidnapping.Properties;
-import cz.nic.tablexia.game.games.kidnapping.media.assets.TextureType;
+import cz.nic.tablexia.game.games.kidnapping.media.assets.TextureTypes;
 import cz.nic.tablexia.game.games.kidnapping.model.Direction;
 import cz.nic.tablexia.game.games.kidnapping.model.GameState;
 import cz.nic.tablexia.game.games.kidnapping.model.Position;
@@ -29,13 +30,14 @@ public class Map extends Group {
     private Image        correct, wrong;
     private DragActorListener debugListener = new DragActorListener(tiles);
 
-    public Map(KidnappingGame screen) {
+    public Map(KidnappingGame screen, GfxLibrary library) {
         addActor(tiles);
         addActor(replayButton = new ReplayButton(screen));
         replayButton.setVisible(false);
-        addActor(overlay = new EarOverlay(screen.getText("game_kidnapping_instructions_pay_attention"),ApplicationAtlasManager.getInstance().getColorTexture(Color.BLACK), screen.getScreenTextureRegion(screen.getGfxLibrary().get(TextureType.EAR))));
-        addActor(correct = new Image(screen.getScreenTextureRegion(screen.getGfxLibrary().get(TextureType.CORRECT))));
-        addActor(wrong = new Image(screen.getScreenTextureRegion(screen.getGfxLibrary().get(TextureType.WRONG))));
+        // TODO fix getting text through screen
+        addActor(overlay = new EarOverlay(screen.getText("game_kidnapping_instructions_pay_attention"),ApplicationAtlasManager.getInstance().getColorTexture(Color.BLACK), screen.getScreenTextureRegion(screen.getGfxLibrary().get(TextureTypes.EAR))));
+        addActor(correct = new Image(library.getTextureRegion(TextureTypes.CORRECT)));
+        addActor(wrong = new Image(library.getTextureRegion(TextureTypes.WRONG)));
         wrong.setVisible(false);
         correct.setVisible(false);
     }
@@ -111,10 +113,10 @@ public class Map extends Group {
     }
 
     public static class MapFactory {
-        public static Map createInstance(KidnappingGame screen, GameState gameState) {
-            Map map = new Map(screen);
+        public static Map createInstance(KidnappingGame game, GfxLibrary gfxLibrary, GameState gameState) {
+            Map map = new Map(game, gfxLibrary);
             for (Position position : gameState.getMap().keySet()) {
-                map.addTile(position, Tile.TileFactory.createInstance(screen, gameState.getMap().get(position)));
+                map.addTile(position, Tile.TileFactory.createInstance(gfxLibrary, gameState.getMap().get(position)));
             }
             map.getOverlay().setVisible(false);
             return map;
diff --git a/core/src/cz/nic/tablexia/game/games/kidnapping/actors/ReplayButton.java b/core/src/cz/nic/tablexia/game/games/kidnapping/actors/ReplayButton.java
index 5fc0b3d48caa4f3be57ab3ddda96b09f265a034d..e87b3ef8a7dc2733c6acbdff2ab89ad31c3c15c7 100644
--- a/core/src/cz/nic/tablexia/game/games/kidnapping/actors/ReplayButton.java
+++ b/core/src/cz/nic/tablexia/game/games/kidnapping/actors/ReplayButton.java
@@ -10,6 +10,7 @@ import cz.nic.tablexia.util.ui.TablexiaButton;
 public class ReplayButton extends TablexiaButton {
 
     public ReplayButton(KidnappingGame screen) {
+        // TODO fix getting text through screen
         super(screen.getText("game_kidnapping_replay"), ButtonType.GREEN);
         setSize(150, 80);
     }
diff --git a/core/src/cz/nic/tablexia/game/games/kidnapping/actors/Tile.java b/core/src/cz/nic/tablexia/game/games/kidnapping/actors/Tile.java
index ac4951ffb62399a741c3789cb13a476a741807ef..7eef4028929792950ef80c46aa6151bbc0b66b33 100644
--- a/core/src/cz/nic/tablexia/game/games/kidnapping/actors/Tile.java
+++ b/core/src/cz/nic/tablexia/game/games/kidnapping/actors/Tile.java
@@ -29,8 +29,8 @@ import com.badlogic.gdx.scenes.scene2d.Touchable;
 import com.badlogic.gdx.scenes.scene2d.ui.Image;
 import com.badlogic.gdx.scenes.scene2d.ui.Label;
 
-import cz.nic.tablexia.game.games.kidnapping.KidnappingGame;
-import cz.nic.tablexia.game.games.kidnapping.media.assets.TextureType;
+import cz.nic.tablexia.game.common.media.GfxLibrary;
+import cz.nic.tablexia.game.games.kidnapping.media.assets.TextureTypes;
 import cz.nic.tablexia.game.games.kidnapping.media.assets.TileType;
 import cz.nic.tablexia.game.games.kidnapping.model.Position;
 
@@ -119,59 +119,59 @@ public class Tile extends Group {
     }
 
     public static class TileFactory {
-        public static Tile createInstance(KidnappingGame screen, TileType tileType) {
+        public static Tile createInstance(GfxLibrary gfxLibrary, TileType tileType) {
             Tile tile = new Tile();
             tile.tileType = tileType;
 
-            TextureRegion tileTexture = screen.getScreenTextureRegion(screen.getGfxLibrary().getTileLibrary().get(tileType));
+            TextureRegion tileTexture = gfxLibrary.getTextureRegion(tileType);
             tile.street = new Image(tileTexture);
             tile.addActor(tile.street);
             tile.street.setTouchable(Touchable.disabled);
 
-            addPath(screen, tile);
-            addArrows(screen, tile);
+            addPath(gfxLibrary, tile);
+            addArrows(gfxLibrary, tile);
 
             return tile;
         }
 
-        private static void addPath(KidnappingGame screen, Tile tile) {
-            TextureRegion flagTexture = screen.getScreenTextureRegion(screen.getGfxLibrary().get(TextureType.POSITION_CURRENT));
+        private static void addPath(GfxLibrary gfxLibrary, Tile tile) {
+            TextureRegion flagTexture = gfxLibrary.getTextureRegion(TextureTypes.POSITION_CURRENT);
             tile.addActor(tile.flag = new Image(flagTexture));
             tile.flag.setPosition(351, -29);
             tile.flag.setVisible(false);
 
-            TextureRegion lineNE = screen.getScreenTextureRegion(screen.getGfxLibrary().get(TextureType.POSITION_LINE_NESW));
+            TextureRegion lineNE = gfxLibrary.getTextureRegion(TextureTypes.POSITION_LINE_NESW);
             tile.addActor(tile.pathNorthEast = new Image(lineNE));
             tile.pathNorthEast.setPosition(464, 86);
             tile.pathNorthEast.setVisible(false);
 
-            TextureRegion lineNW = screen.getScreenTextureRegion(screen.getGfxLibrary().get(TextureType.POSITION_LINE_NWSE));
+            TextureRegion lineNW = gfxLibrary.getTextureRegion(TextureTypes.POSITION_LINE_NWSE);
             tile.addActor(tile.pathNorthWest = new Image(lineNW));
             tile.pathNorthWest.setPosition(59, 88);
             tile.pathNorthWest.setVisible(false);
         }
 
-        private static void addArrows(KidnappingGame screen, Tile tile) {
-            TextureRegion arrowNE = screen.getScreenTextureRegion(screen.getGfxLibrary().get(TextureType.POSITION_NEXT_NE));
-            TextureRegion arrowNEPressed = screen.getScreenTextureRegion(screen.getGfxLibrary().get(TextureType.POSITION_NEXT_NE_PRESSED));
+        private static void addArrows(GfxLibrary gfxLibrary, Tile tile) {
+            TextureRegion arrowNE = gfxLibrary.getTextureRegion(TextureTypes.POSITION_NEXT_NE);
+            TextureRegion arrowNEPressed = gfxLibrary.getTextureRegion(TextureTypes.POSITION_NEXT_NE_PRESSED);
             tile.addActor(tile.northEastOut = new Arrow(arrowNE, arrowNEPressed));
             tile.northEastOut.setPosition(531, 110);
             tile.northEastOut.setVisible(false);
 
-            TextureRegion arrowNW = screen.getScreenTextureRegion(screen.getGfxLibrary().get(TextureType.POSITION_NEXT_NW));
-            TextureRegion arrowNWPressed = screen.getScreenTextureRegion(screen.getGfxLibrary().get(TextureType.POSITION_NEXT_NW_PRESSED));
+            TextureRegion arrowNW = gfxLibrary.getTextureRegion(TextureTypes.POSITION_NEXT_NW);
+            TextureRegion arrowNWPressed = gfxLibrary.getTextureRegion(TextureTypes.POSITION_NEXT_NW_PRESSED);
             tile.addActor(tile.northWestOut = new Arrow(arrowNW, arrowNWPressed));
             tile.northWestOut.setPosition(127, 112);
             tile.northWestOut.setVisible(false);
 
-            TextureRegion arrowSE = screen.getScreenTextureRegion(screen.getGfxLibrary().get(TextureType.POSITION_NEXT_SE));
-            TextureRegion arrowSEPressed = screen.getScreenTextureRegion(screen.getGfxLibrary().get(TextureType.POSITION_NEXT_SE_PRESSED));
+            TextureRegion arrowSE = gfxLibrary.getTextureRegion(TextureTypes.POSITION_NEXT_SE);
+            TextureRegion arrowSEPressed = gfxLibrary.getTextureRegion(TextureTypes.POSITION_NEXT_SE_PRESSED);
             tile.addActor(tile.northWestIn = new Arrow(arrowSE, arrowSEPressed));
             tile.northWestIn.setPosition(137, 112);
             tile.northWestIn.setVisible(false);
 
-            TextureRegion arrowSW = screen.getScreenTextureRegion(screen.getGfxLibrary().get(TextureType.POSITION_NEXT_SW));
-            TextureRegion arrowSWPressed = screen.getScreenTextureRegion(screen.getGfxLibrary().get(TextureType.POSITION_NEXT_SW_PRESSED));
+            TextureRegion arrowSW = gfxLibrary.getTextureRegion(TextureTypes.POSITION_NEXT_SW);
+            TextureRegion arrowSWPressed = gfxLibrary.getTextureRegion(TextureTypes.POSITION_NEXT_SW_PRESSED);
             tile.addActor(tile.northEastIn = new Arrow(arrowSW, arrowSWPressed));
             tile.northEastIn.setPosition(515, 106);
             tile.northEastIn.setVisible(false);
diff --git a/core/src/cz/nic/tablexia/game/games/kidnapping/media/TileLibrary.java b/core/src/cz/nic/tablexia/game/games/kidnapping/media/TileLibrary.java
deleted file mode 100644
index d1a269cc3916b84248817a8af132838802a70805..0000000000000000000000000000000000000000
--- a/core/src/cz/nic/tablexia/game/games/kidnapping/media/TileLibrary.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * ****************************************************************************
- * Tablexia
- * <p/>
- * Copyright (C) 2013  CZ NIC z.s.p.o. <podpora at nic dot cz>
- * <p/>
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * <p/>
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * <p/>
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- * ****************************************************************************
- */
-
-package cz.nic.tablexia.game.games.kidnapping.media;
-
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Set;
-
-import cz.nic.tablexia.game.games.kidnapping.media.assets.TileType;
-
-/**
- * Library of tile image paths
- *
- * @author lhoracek
- */
-public class TileLibrary extends HashMap<TileType, String> {
-
-    private static final long   serialVersionUID = 7306787996311196671L;
-    private static final String TILES_DIR       = "gfx/tiles/";
-
-
-    public TileLibrary() {
-        for (TileType tile : TileType.values()) {
-            if (!containsKey(tile)) {
-                String path = TILES_DIR + tile.getName();
-                put(tile, path);
-            }
-        }
-    }
-
-    /**
-     * Metrod prepared for future. Supposed to filter only tiles used in map to speed up loading times
-     *
-     * @param tiles
-     * @return
-     */
-    public Collection<String> getTileRecords(Collection<TileType> tiles) {
-        Set<String> paths = new HashSet<String>();
-        for (TileType tile : tiles) {
-            paths.add(get(tiles));
-        }
-        return paths;
-    }
-}
diff --git a/core/src/cz/nic/tablexia/game/games/kidnapping/media/assets/SoundType.java b/core/src/cz/nic/tablexia/game/games/kidnapping/media/assets/SoundType.java
index d4c69cb8d9c93c498bce54d9a47f5ad54c4255e3..9d486341ecd00fcb5f86a2b5796d15674665805d 100644
--- a/core/src/cz/nic/tablexia/game/games/kidnapping/media/assets/SoundType.java
+++ b/core/src/cz/nic/tablexia/game/games/kidnapping/media/assets/SoundType.java
@@ -1,28 +1,32 @@
-/*******************************************************************************
- *     Tablexia	
- * 
- *     Copyright (C) 2013  CZ NIC z.s.p.o. <podpora at nic dot cz>
- * 
- *     This program is free software: you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation, either version 3 of the License, or
- *     (at your option) any later version.
- * 
- *     This program is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- * 
- *     You should have received a copy of the GNU General Public License
- *     along with this program.  If not, see <http://www.gnu.org/licenses/>.
- ******************************************************************************/
+/**
+ * ****************************************************************************
+ * Tablexia
+ * <p/>
+ * Copyright (C) 2013  CZ NIC z.s.p.o. <podpora at nic dot cz>
+ * <p/>
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * <p/>
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * <p/>
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * ****************************************************************************
+ */
 
 package cz.nic.tablexia.game.games.kidnapping.media.assets;
 
+import cz.nic.tablexia.game.common.media.AssetDescription;
+
 /**
  * @author lhoracek
  */
-public enum SoundType {
+public enum SoundType implements AssetDescription {
 
     SOUND_ERROR("error", SoundClass.SOUND, true); //
 
@@ -32,23 +36,11 @@ public enum SoundType {
 
     private SoundType(String resource, SoundClass soundClass, boolean eager) {
         this.resource = resource;
-        this.eager = eager;
-        this.soundClass = soundClass;
     }
 
-    private final String     resource;
-    private final boolean    eager;
-    private final SoundClass soundClass;
+    private final String resource;
 
     public String getResource() {
         return resource;
     }
-
-    public boolean isEager() {
-        return eager;
-    }
-
-    public SoundClass getSoundClass() {
-        return soundClass;
-    }
 }
diff --git a/core/src/cz/nic/tablexia/game/games/kidnapping/media/assets/TextureType.java b/core/src/cz/nic/tablexia/game/games/kidnapping/media/assets/TextureTypes.java
similarity index 91%
rename from core/src/cz/nic/tablexia/game/games/kidnapping/media/assets/TextureType.java
rename to core/src/cz/nic/tablexia/game/games/kidnapping/media/assets/TextureTypes.java
index 6b8c025c196cdcb096fd3227b9f5350648337215..0b2cb62779be9a900ec2679298f7ced077ad66f7 100644
--- a/core/src/cz/nic/tablexia/game/games/kidnapping/media/assets/TextureType.java
+++ b/core/src/cz/nic/tablexia/game/games/kidnapping/media/assets/TextureTypes.java
@@ -21,10 +21,12 @@
 
 package cz.nic.tablexia.game.games.kidnapping.media.assets;
 
+import cz.nic.tablexia.game.common.media.AssetDescription;
+
 /**
  * @author lhoracek
  */
-public enum TextureType {
+public enum TextureTypes implements AssetDescription {
 
     POSITION_CURRENT("zde-jsi"), //
     OVERLAY("overlay"), //
@@ -48,7 +50,7 @@ public enum TextureType {
     private final String resource;
 
 
-    private TextureType(String resource) {
+    private TextureTypes(String resource) {
         this.resource = resource;
     }
 
diff --git a/core/src/cz/nic/tablexia/game/games/kidnapping/media/assets/TileType.java b/core/src/cz/nic/tablexia/game/games/kidnapping/media/assets/TileType.java
index 9be071f28d1fed59d495364eccd635c78c24663d..5cdda73521032bd2f400edf8a7504ace3fe552ff 100644
--- a/core/src/cz/nic/tablexia/game/games/kidnapping/media/assets/TileType.java
+++ b/core/src/cz/nic/tablexia/game/games/kidnapping/media/assets/TileType.java
@@ -2,10 +2,14 @@ package cz.nic.tablexia.game.games.kidnapping.media.assets;
 
 import java.util.Random;
 
+import cz.nic.tablexia.game.common.media.AssetDescription;
+
 /**
  * Created by lhoracek on 5/15/15.
  */
-public enum TileType {
+public enum TileType implements AssetDescription {
+
+
     DOME1(1, 1, "domek1", 78), //
     DOME2(1, 1, "domek2", 78), //
     DOME3(1, 1, "domek3", 78), //
@@ -23,7 +27,7 @@ public enum TileType {
     VILA3(1, 1, "vila3", 78), //
     VILA4(1, 1, "vila4", 78); //
 
-
+    public static final String BASE_DIR = "tiles/";
     private final int swSize, seSize;
     private final String name;
     private final int    yOffset;
@@ -43,8 +47,8 @@ public enum TileType {
         return seSize;
     }
 
-    public String getName() {
-        return name;
+    public String getResource() {
+        return BASE_DIR + name;
     }
 
     public int getyOffset() {
diff --git a/core/src/cz/nic/tablexia/game/games/shooting_range/Properties.java b/core/src/cz/nic/tablexia/game/games/shooting_range/Properties.java
new file mode 100644
index 0000000000000000000000000000000000000000..97dcb85b1a38365faff32bf8807d5a13e6918eec
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/games/shooting_range/Properties.java
@@ -0,0 +1,28 @@
+package cz.nic.tablexia.game.games.shooting_range;
+
+/**
+ * Created by lhoracek on 6/22/15.
+ */
+public class Properties {
+    public static final String BASE_DIR = "strelnice/";
+
+    // GAME SPEED AND TIME
+    public static final float ADD_TIME = 5f;
+    public static final float SUB_TIME = -5f;
+
+    public static final float GAME_SPEED_FAST    = 2.0f;
+    public static final float GAME_SPEED_NORMAL  = 1f;
+    public static final float GAME_SPEED_SLOW    = 0.5f;
+    public static final float GAME_SPEED_TIMEOUT = 5f;
+
+    public static final int GAME_TIME    = 60;
+    public static final int WARNING_TIME = 5;
+
+    // RESULTS
+    public static final int[] CUPS_EASY   = {25, 45, 75};
+    public static final int[] CUPS_MEDIUM = {20, 40, 70};
+    public static final int[] CUPS_HARD   = {20, 35, 60};
+
+    static final String[] RESULT_SOUNDS = new String[]{"result0", "result1", "result2", "result3"};
+    static final String[] RESULT_TEXT   = new String[]{"game_shootingrange_result_0", "game_shootingrange_result_1", "game_shootingrange_result_2", "game_shootingrange_result_3"};
+}
diff --git a/core/src/cz/nic/tablexia/game/games/shooting_range/ShootingRangeGame.java b/core/src/cz/nic/tablexia/game/games/shooting_range/ShootingRangeGame.java
index efd52c6ed7a1a2244fb13b22c16879742b451108..d08b9b0f0d1fd56aeb7f59b4bf1e2770ac8ae1db 100644
--- a/core/src/cz/nic/tablexia/game/games/shooting_range/ShootingRangeGame.java
+++ b/core/src/cz/nic/tablexia/game/games/shooting_range/ShootingRangeGame.java
@@ -1,9 +1,273 @@
 package cz.nic.tablexia.game.games.shooting_range;
 
+import com.badlogic.gdx.graphics.Color;
+import com.badlogic.gdx.scenes.scene2d.InputEvent;
+import com.badlogic.gdx.scenes.scene2d.InputListener;
+import com.badlogic.gdx.scenes.scene2d.actions.Actions;
+import com.badlogic.gdx.scenes.scene2d.ui.Label;
+
+import java.util.List;
+import java.util.Map;
+
+import cz.nic.tablexia.TablexiaSettings;
 import cz.nic.tablexia.game.AbstractTablexiaGame;
+import cz.nic.tablexia.game.common.media.GfxLibrary;
+import cz.nic.tablexia.game.common.media.SfxLibrary;
+import cz.nic.tablexia.game.games.shooting_range.actors.Carousel;
+import cz.nic.tablexia.game.games.shooting_range.actors.Row;
+import cz.nic.tablexia.game.games.shooting_range.actors.Scene;
+import cz.nic.tablexia.game.games.shooting_range.actors.Target;
+import cz.nic.tablexia.game.games.shooting_range.actors.Watch;
+import cz.nic.tablexia.game.games.shooting_range.media.BoxType;
+import cz.nic.tablexia.game.games.shooting_range.media.SoundType;
+import cz.nic.tablexia.game.games.shooting_range.media.TextureType;
+import cz.nic.tablexia.game.games.shooting_range.model.GameState;
+import cz.nic.tablexia.game.games.shooting_range.model.Wave;
+import cz.nic.tablexia.game.games.shooting_range.tools.HitEvaluator;
+import cz.nic.tablexia.game.games.shooting_range.tools.PixelPerfectHitEvaluator;
+import cz.nic.tablexia.game.games.shooting_range.tools.TargetGenerator;
+import cz.nic.tablexia.game.games.shooting_range.tools.TargetPositionController;
 
 /**
- * Created by Václav Tarantík on 6.3.15.
+ * Created by lhoracek
  */
-public class ShootingRangeGame extends AbstractTablexiaGame<Void> {
+public class ShootingRangeGame extends AbstractTablexiaGame<GameState> {
+
+    private GfxLibrary gfxLibrary = new GfxLibrary(this, TextureType.values());
+    private SfxLibrary sfxLibrary = new SfxLibrary(this, SoundType.values());
+
+    private Scene                    scene;
+    private Carousel                 carousel;
+    private Watch                    watch;
+    private Label                    score;
+    private TargetGenerator          targetGenerator;
+    private TargetPositionController targetPositionController;
+    private HitEvaluator             hitEvaluator;
+
+    /**
+     * Most important listener deciding every hit on target
+     */
+    private InputListener clickListener = new InputListener() {
+        /**
+         * Decide on touchDown for fast response
+         */
+        @Override
+        public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
+            Target target = (Target) event.getTarget();
+            if (!target.isShot()) { // skip if target already hit and let miss listener to catch
+                if (target.getTextureType().equals(getData().getCurrentTarget())) {
+                    sfxLibrary.getSound(SoundType.HITS[getRandom().nextInt(SoundType.HITS.length)]).play();
+                    target.setShot(true);
+                    target.addAction(Actions.scaleTo(1, 0, 0.1f));
+                    getData().addHit();
+                    if (getData().getHitLimit() == 0) {
+                        newTarget();
+                    }
+                } else if (target.getTextureType().equals(TextureType.BOX_BAD)) {
+                    target.setShot(true);
+                    getData().addBoxBad();
+                    target.addAction(Actions.scaleTo(1, 0, 0.1f));
+                    switch (BoxType.BAD_BOXES[getRandom().nextInt(BoxType.BAD_BOXES.length)]) {
+                        case SPEED_UP:
+                            getData().setGameSpeed(Properties.GAME_SPEED_FAST);
+                            sfxLibrary.getSound(SoundType.BOX_FAST).play();
+                            // showEffect(target, TextureType.BOX_SPEED_UP); TODO
+                            break;
+                        case TIME_ADD:
+                            getData().addTime(Properties.ADD_TIME);
+                            sfxLibrary.getSound(SoundType.BELL).play();
+                            // showEffect(target, TextureType.BOX_TIME_MINUS_5); TODO
+                            break;
+                        case CLOUD:
+                            // showCloud(target.getX(), target.getY() + 100, 0); // mraky lehce zvedneme TODO
+                            sfxLibrary.getSound(SoundType.BOX_SMOKE);
+                            break;
+                        default:
+                    }
+                } else if (target.getTextureType().equals(TextureType.BOX_GOOD)) {
+                    target.setShot(true);
+                    getData().addBoxGood();
+                    target.addAction(Actions.scaleTo(1, 0, 0.1f));
+                    switch (BoxType.GOOD_BOXES[getRandom().nextInt(BoxType.GOOD_BOXES.length)]) {
+                        case SLOW_DOWN:
+                            getData().setGameSpeed(Properties.GAME_SPEED_SLOW);
+                            //showEffect(target, TextureType.BOX_SPEED_DOWN); TODO
+                            sfxLibrary.getSound(SoundType.BOX_SLOW).play();
+                            break;
+                        case TIME_SUB:
+                            getData().addTime(Properties.SUB_TIME);
+                            sfxLibrary.getSound(SoundType.BELL).play();
+                            //showEffect(target, TextureType.BOX_TIME_PLUS_5); TODO
+                            break;
+                        case HIT:
+                            // showEffect(target, TextureType.BOX_HIT); TODO
+                            sfxLibrary.getSound(SoundType.HITS[getRandom().nextInt(SoundType.HITS.length)]).play();
+                            getData().addScore(2);
+                            break;
+                        default:
+                            throw new IllegalStateException("Unknown state");
+                    }
+                } else {
+                    sfxLibrary.getSound(SoundType.WRONG).play();
+                    getData().addWrongTarget();
+                }
+            }
+            return super.touchDown(event, x, y, pointer, button);
+        }
+    };
+
+    private InputListener missInputListener = new InputListener() {
+        @Override
+        public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
+            sfxLibrary.getSound(SoundType.MISS).play();
+            getData().addMiss();
+            return super.touchDown(event, x, y, pointer, button);
+        }
+    };
+
+    @Override
+    protected void prepareScreenSoundAssetNames(List<String> soundsFileNames) {
+        super.prepareScreenSoundAssetNames(soundsFileNames);
+        soundsFileNames.addAll(sfxLibrary.values());
+    }
+
+    @Override
+    protected GameState prepareGameData(Map<String, String> gameState) {
+        GameState gameData = new GameState();
+        return gameData;
+    }
+
+    @Override
+    protected void gameLoaded(Map<String, String> gameState) {
+        getStage().setDebugAll(TablexiaSettings.getInstance().isShowBoundingBoxes());
+        super.gameLoaded(gameState);
+        initScene();
+
+        // Create new hit evaluator
+        hitEvaluator = new PixelPerfectHitEvaluator(gfxLibrary, TextureType.getTargetPack(getGameDifficulty())); // need to be done here - getGameDifficulty returns null anywhere before
+        // TODO add boxes - hit evaluator is initialized with flowers, but not boxes and could case glitch when evaluating box hit
+        addDisposable(hitEvaluator);
+
+
+        targetGenerator = new TargetGenerator(getGameDifficulty(), getRandom(), gfxLibrary, clickListener, hitEvaluator);
+        targetPositionController = new TargetPositionController(scene, targetGenerator, getRandom(), getGameDifficulty(), getStage().getWidth());
+        for (Row row : scene.getRows()) {         // init each row with starting flowers
+            row.setWave(Wave.getWave(getGameDifficulty(), row.getRowIndex()));
+            row.addTargets(targetGenerator.generateTargetRow(row));
+        }
+        scene.getBackground().addListener(missInputListener);
+        scene.addAction(Actions.sequence(Actions.delay(3), Actions.run(new Runnable() {
+            // TODO animate flowers in
+            // TODO animate hand in
+            // TODO animate carousel in
+            @Override
+            public void run() {
+                newTarget();
+                getData().setRunning(true);
+            }
+        })));
+    }
+
+    /**
+     * Based on game difficulty create randome hit limit for current target
+     * Current it 1-4 hit for all difficulties
+     *
+     * @return hitLimit
+     */
+    private int getNewHitLimit() {
+        return getRandom().nextInt(4) + 1;
+    }
+
+    /**
+     * Generate new target and hit limit a show it in carousel
+     */
+    private void newTarget() {
+        getData().setHitLimit(getNewHitLimit());
+        getData().setCurrentTarget(getRandomFlower());
+        carousel.showNextFlower(getData().getCurrentTarget());
+        targetPositionController.setTargetType(getData().getCurrentTarget());
+    }
+
+    /**
+     * Get random flower from target bag.
+     *
+     * @return
+     */
+    private TextureType getRandomFlower() {
+        if (targetPositionController.getAvailableTypes().size() > 0) {
+            TextureType[] types = targetPositionController.getAvailableTypes().toArray(new TextureType[0]);
+            return types[getRandom().nextInt(types.length)];
+        }
+        TextureType flowerType = targetGenerator.getRandomFlowerType(getGameDifficulty());
+        return flowerType;
+    }
+
+    /**
+     * Called in each tick of rendering engine. Updates position of targets and passed game time
+     *
+     * @param delta
+     */
+    @Override
+    protected void screenRender(float delta) {
+        super.screenRender(delta);
+        if (!isPaused()) {
+            if (getData().isRunning()) {
+                if (getData().getTime() > 60) {
+                    finishGame();
+                }
+                getData().addTime(delta);
+                targetPositionController.onUpdate(delta * getData().getGameSpeed());
+            }
+            watch.setTime((int) getData().getTime());
+            score.setText(String.valueOf(getData().getScore()));
+        }
+    }
+
+    private void finishGame() {
+        getData().setRunning(false);
+        sfxLibrary.getSound(SoundType.BELL).play();
+        // TODO hide flowers
+        // TODO play finish sound
+        gameComplete(getData().countProgress(getGameDifficulty()));
+    }
+
+    /**
+     * Create scene with watch, carousel and background
+     */
+    private void initScene() {
+        getStage().addActor(scene = new Scene(gfxLibrary));
+        scene.setBounds(0, getStage().getCamera().position.y - getStage().getHeight() / 2, getStage().getWidth(), getStage().getHeight()); // scaling viewport camera y-position adjustment
+        getStage().addActor(watch = new Watch(gfxLibrary));
+        watch.setScale(0.4f);
+        getStage().addActor(carousel = new Carousel(gfxLibrary));
+        carousel.setScale(0.6f);
+        Label.LabelStyle labelStyle = new Label.LabelStyle(getDefaultBoldFont(), Color.WHITE);
+        getStage().addActor(score = new Label("0", labelStyle));
+
+        screenResized((int) getStage().getWidth(), (int) getStage().getHeight());
+    }
+
+    /**
+     * Recompute carousel and watch position on screen resize
+     *
+     * @param width
+     * @param height
+     */
+    @Override
+    protected void screenResized(int width, int height) {
+        super.screenResized(width, height);
+        watch.setPosition(0, getStage().getCamera().position.y - getStage().getHeight() / 2);
+        carousel.setPosition(getStage().getWidth() - (carousel.getWidth() / 2), getStage().getCamera().position.y + (getStage().getHeight() / 2) - (carousel.getHeight() / 2));
+        score.setPosition(getStage().getWidth() - score.getWidth() - 50, 25);
+    }
+
+    public String getVictoryText(int progress) {
+        return Properties.RESULT_TEXT[progress];
+    }
+
+    public String getVictorySound(int progress) {
+        return Properties.RESULT_SOUNDS[progress];
+    }
+
+
 }
diff --git a/core/src/cz/nic/tablexia/game/games/shooting_range/actions/HitAction.java b/core/src/cz/nic/tablexia/game/games/shooting_range/actions/HitAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..3c02ac6c30b1131622ace3779bd266a8bc727b58
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/games/shooting_range/actions/HitAction.java
@@ -0,0 +1,16 @@
+package cz.nic.tablexia.game.games.shooting_range.actions;
+
+import com.badlogic.gdx.scenes.scene2d.actions.ScaleToAction;
+
+import cz.nic.tablexia.game.games.shooting_range.actors.Target;
+
+/**
+ * Created by lhoracek on 6/26/15.
+ */
+public class HitAction extends ScaleToAction {
+    public HitAction(Target target) {
+        setTarget(target);
+        setX(1f);
+        setY(0.1f);
+    }
+}
diff --git a/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Carousel.java b/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Carousel.java
new file mode 100644
index 0000000000000000000000000000000000000000..77f47c93b34d163af21a024e26835bcde78c520f
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Carousel.java
@@ -0,0 +1,39 @@
+package cz.nic.tablexia.game.games.shooting_range.actors;
+
+import com.badlogic.gdx.math.Interpolation;
+import com.badlogic.gdx.scenes.scene2d.Group;
+import com.badlogic.gdx.scenes.scene2d.Touchable;
+import com.badlogic.gdx.scenes.scene2d.actions.Actions;
+import com.badlogic.gdx.scenes.scene2d.ui.Image;
+
+import cz.nic.tablexia.game.common.media.GfxLibrary;
+import cz.nic.tablexia.game.games.shooting_range.media.TextureType;
+
+/**
+ * Created by lhoracek on 6/23/15.
+ */
+public class Carousel extends Group {
+    private Image      carouselBase;
+    private Image      flower;// TODO change type to Flower
+    private GfxLibrary gfxLibrary;
+
+    public Carousel(GfxLibrary gfxLibrary) {
+        addActor(carouselBase = new Image(gfxLibrary.getTextureRegion(TextureType.CAROUSEL)));
+        setSize(carouselBase.getWidth(), carouselBase.getHeight());
+        setTouchable(Touchable.disabled);
+        setSize(carouselBase.getWidth(), carouselBase.getHeight());
+        setOrigin(getWidth() / 2, getHeight() / 2);
+        this.gfxLibrary = gfxLibrary;
+    }
+
+    public void showNextFlower(final TextureType textureType) { // TODO change type to Flower
+        final Image oldFlower = this.flower;
+        this.flower = new Image(gfxLibrary.getTextureRegion(textureType));
+        addActor(flower);
+        flower.setOrigin(getWidth() / 10 * 3, getHeight() / 10 * 4);
+        flower.setX(getWidth() / 10 * 2);
+        flower.setY(getHeight() / 10);
+        flower.setRotation(-getRotation() + 90);
+        addAction(Actions.sequence(Actions.rotateBy(-90, 0.5f, Interpolation.elasticOut), (oldFlower == null ? Actions.delay(0) : Actions.removeActor(oldFlower))));
+    }
+}
diff --git a/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Effect.java b/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Effect.java
new file mode 100644
index 0000000000000000000000000000000000000000..5dae279d189451075c3b06ef945e41667531af40
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Effect.java
@@ -0,0 +1,9 @@
+package cz.nic.tablexia.game.games.shooting_range.actors;
+
+import com.badlogic.gdx.scenes.scene2d.Group;
+
+/**
+ * Created by lhoracek on 6/23/15.
+ */
+public class Effect extends Group {
+}
diff --git a/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Flower.java b/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Flower.java
new file mode 100644
index 0000000000000000000000000000000000000000..2db8b56cb5f0de0fd30282f599c26e8022d00c54
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Flower.java
@@ -0,0 +1,16 @@
+package cz.nic.tablexia.game.games.shooting_range.actors;
+
+import com.badlogic.gdx.graphics.g2d.TextureRegion;
+import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
+
+import cz.nic.tablexia.game.games.shooting_range.media.TextureType;
+import cz.nic.tablexia.game.games.shooting_range.tools.HitEvaluator;
+
+/**
+ * Created by lhoracek on 6/26/15.
+ */
+public class Flower extends Target {
+    public Flower(TextureRegion texture, Float startTime, Row row, TextureType textureType, ClickListener listener, HitEvaluator hitEvaluator) {
+        super(texture, startTime, row, textureType, listener, hitEvaluator);
+    }
+}
diff --git a/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Row.java b/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Row.java
new file mode 100644
index 0000000000000000000000000000000000000000..3030507e2318c181f7c0ddc1b15bf42b3888ff21
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Row.java
@@ -0,0 +1,73 @@
+package cz.nic.tablexia.game.games.shooting_range.actors;
+
+import com.badlogic.gdx.scenes.scene2d.Group;
+import com.badlogic.gdx.scenes.scene2d.Touchable;
+import com.badlogic.gdx.scenes.scene2d.ui.Image;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import cz.nic.tablexia.game.common.media.GfxLibrary;
+import cz.nic.tablexia.game.games.shooting_range.media.TextureType;
+import cz.nic.tablexia.game.games.shooting_range.model.Wave;
+
+/**
+ * Created by lhoracek on 6/23/15.
+ */
+public class Row extends Group {
+    private Image waveImage;
+    private Group targetGroup;
+    private List<Target> targets = new CopyOnWriteArrayList<Target>();
+    private Wave wave;
+    private int  rowIndex;
+
+    public Row(GfxLibrary gfxLibrary, int index, TextureType texture) {
+        addActor(targetGroup = new Group());
+        addActor(waveImage = new Image(gfxLibrary.getTextureRegion(texture)));
+        rowIndex = index;
+        setTouchable(Touchable.childrenOnly);
+        targetGroup.setTouchable(Touchable.childrenOnly);
+        waveImage.setTouchable(Touchable.disabled);
+    }
+
+    public void setWave(Wave wave) {
+        this.wave = wave;
+    }
+
+    public Wave getWave() {
+        return wave;
+    }
+
+    public int getRowIndex() {
+        return rowIndex;
+    }
+
+    public void addTargets(Collection<Target> targets) {
+        for (Target target : targets) {
+            targetGroup.addActor(target);
+            this.targets.add(target);
+        }
+    }
+
+    public void addTarget(Target target) {
+        targetGroup.addActor(target);
+        targets.add(target);
+    }
+
+    public void removeTarget(Target target) {
+        targets.remove(target);
+        targetGroup.removeActor(target);
+    }
+
+    public List<Target> getTargets() {
+        return targets;
+    }
+
+    @Override
+    protected void sizeChanged() {
+        super.sizeChanged();
+        waveImage.setSize(getWidth(), getHeight());
+        targetGroup.setSize(getWidth(), getHeight());
+    }
+}
diff --git a/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Scene.java b/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Scene.java
new file mode 100644
index 0000000000000000000000000000000000000000..051ee862ffed7c35ce6f4fe45503d57a48b6c040
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Scene.java
@@ -0,0 +1,50 @@
+package cz.nic.tablexia.game.games.shooting_range.actors;
+
+import com.badlogic.gdx.scenes.scene2d.Group;
+import com.badlogic.gdx.scenes.scene2d.Touchable;
+import com.badlogic.gdx.scenes.scene2d.ui.Image;
+
+import cz.nic.tablexia.game.common.media.GfxLibrary;
+import cz.nic.tablexia.game.games.shooting_range.media.TextureType;
+
+/**
+ * Created by lhoracek on 6/23/15.
+ */
+public class Scene extends Group {
+    private final Image frame;
+    private final Image background;
+    private       Row   row1, row2, row3;
+    private Row[]            rows;
+
+
+    public Scene(GfxLibrary gfxLibrary) {
+        addActor(background = new Image(gfxLibrary.getTextureRegion(TextureType.BACKGROUND)));
+
+        addActor(row1 = new Row(gfxLibrary, 0, TextureType.WAVE_1));
+        addActor(row2 = new Row(gfxLibrary, 1, TextureType.WAVE_2));
+        addActor(row3 = new Row(gfxLibrary, 2, TextureType.WAVE_3));
+        rows = new Row[]{row1, row2, row3};
+
+        addActor(frame = new Image(gfxLibrary.getTextureRegion(TextureType.FRAME)));
+        frame.setTouchable(Touchable.disabled);
+    }
+
+    @Override
+    protected void sizeChanged() {
+        super.sizeChanged();
+        background.setSize(getWidth(), getHeight());
+        frame.setSize(getWidth(), getHeight());
+
+        row1.setSize(getWidth(), getHeight() / 10 * 7);
+        row2.setSize(getWidth(), getHeight() / 10 * 5);
+        row3.setSize(getWidth(), getHeight() / 10 * 3);
+    }
+
+    public Row[] getRows() {
+        return rows;
+    }
+
+    public Image getBackground() {
+        return background;
+    }
+}
diff --git a/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Smoke.java b/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Smoke.java
new file mode 100644
index 0000000000000000000000000000000000000000..d7ea4999eb56a2d6f04c4da82aa32700bb83f3fd
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Smoke.java
@@ -0,0 +1,7 @@
+package cz.nic.tablexia.game.games.shooting_range.actors;
+
+/**
+ * Created by lhoracek on 6/23/15.
+ */
+public class Smoke extends Effect {
+}
diff --git a/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Target.java b/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Target.java
new file mode 100644
index 0000000000000000000000000000000000000000..43f538aa4ccbfc979f7e43239d66ccc83d51a773
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Target.java
@@ -0,0 +1,125 @@
+package cz.nic.tablexia.game.games.shooting_range.actors;
+
+import com.badlogic.gdx.graphics.g2d.Sprite;
+import com.badlogic.gdx.graphics.g2d.TextureRegion;
+import com.badlogic.gdx.scenes.scene2d.Actor;
+import com.badlogic.gdx.scenes.scene2d.InputListener;
+import com.badlogic.gdx.scenes.scene2d.ui.Image;
+
+import cz.nic.tablexia.game.games.shooting_range.media.TextureType;
+import cz.nic.tablexia.game.games.shooting_range.tools.HitEvaluator;
+
+/**
+ * Created by lhoracek on 6/22/15.
+ */
+public class Target extends Image {
+    private final float       startTime;
+    private       TextureType textureType;
+    private boolean shot = false;
+    private Sprite       effect;
+    private Row          row;
+    private HitEvaluator hitEvaluator;
+
+
+    public static interface PositionProvider {
+        public float getY(float elapseTime, float maxHeight);
+
+        public static final PositionProvider PROVIDER_FLAT = new PositionProvider() {
+            @Override
+            public float getY(float elapsedTime, float maxHeight) {
+                return 0;
+            }
+        };
+    }
+
+    public Target(TextureRegion texture, Float startTime, Row row, TextureType textureType, InputListener listener, HitEvaluator hitEvaluator) {
+        super(texture);
+        this.startTime = startTime;
+        this.textureType = textureType;
+        this.row = row;
+        addListener(listener);
+        this.hitEvaluator = hitEvaluator;
+    }
+
+    public float getStartTime() {
+        return startTime;
+    }
+
+    public void setTextureType(TextureType textureType) {
+        this.textureType = textureType;
+    }
+
+    public TextureType getTextureType() {
+        return textureType;
+    }
+
+    public Row getRow() {
+        return row;
+    }
+
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = (prime * result) + Float.floatToIntBits(startTime);
+        result = (prime * result) + ((textureType == null) ? 0 : textureType.hashCode());
+        result = (prime * result) + ((row == null) ? 0 : row.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        Target other = (Target) obj;
+        if (Float.floatToIntBits(startTime) != Float.floatToIntBits(other.startTime)) {
+            return false;
+        }
+        if (textureType != other.textureType) {
+            return false;
+        }
+        if (row != other.row) {
+            return false;
+        }
+        return true;
+    }
+
+    public boolean isShot() {
+        return shot;
+    }
+
+    public void setShot(boolean shot) {
+        this.shot = shot;
+    }
+
+    public Sprite getEffect() {
+        return effect;
+    }
+
+    public void setEffect(Sprite effect) {
+        this.effect = effect;
+    }
+
+
+    @Override
+    public String toString() {
+        return "Target{" +
+                "textureType=" + textureType +
+                ", shot=" + shot +
+                '}';
+    }
+
+    @Override
+    public Actor hit(float x, float y, boolean touchable) {
+        Actor superValue = super.hit(x, y, touchable);
+        return hitEvaluator.hit(this, x, y) ? superValue : null;
+    }
+}
diff --git a/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Watch.java b/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Watch.java
new file mode 100644
index 0000000000000000000000000000000000000000..ad08cb4c5b4a53a6fb90ddf76a8787074594a216
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/games/shooting_range/actors/Watch.java
@@ -0,0 +1,30 @@
+package cz.nic.tablexia.game.games.shooting_range.actors;
+
+import com.badlogic.gdx.math.Interpolation;
+import com.badlogic.gdx.scenes.scene2d.Group;
+import com.badlogic.gdx.scenes.scene2d.Touchable;
+import com.badlogic.gdx.scenes.scene2d.actions.Actions;
+import com.badlogic.gdx.scenes.scene2d.ui.Image;
+
+import cz.nic.tablexia.game.common.media.GfxLibrary;
+import cz.nic.tablexia.game.games.shooting_range.media.TextureType;
+
+/**
+ * Created by lhoracek on 6/23/15.
+ */
+public class Watch extends Group {
+    private Image watch, watchHand;
+
+    public Watch(GfxLibrary gfxLibrary) {
+        addActor(watch = new Image(gfxLibrary.getTextureRegion(TextureType.WATCH)));
+        addActor(watchHand = new Image(gfxLibrary.getTextureRegion(TextureType.WATCH_HAND)));
+        watchHand.setPosition(254, 166);
+        watchHand.setOrigin(watchHand.getWidth() / 2, 15);
+        setTouchable(Touchable.disabled);
+    }
+
+    public void setTime(int time) {
+        int newRotation = (time%60) * -6;
+        watchHand.addAction(Actions.rotateTo(newRotation, Math.abs(watch.getRotation() - newRotation) * 0.002f, Interpolation.elasticOut));
+    }
+}
diff --git a/core/src/cz/nic/tablexia/game/games/shooting_range/media/BoxType.java b/core/src/cz/nic/tablexia/game/games/shooting_range/media/BoxType.java
new file mode 100644
index 0000000000000000000000000000000000000000..1e46ad40224465957a6c794499fb0d1c5a47562a
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/games/shooting_range/media/BoxType.java
@@ -0,0 +1,28 @@
+package cz.nic.tablexia.game.games.shooting_range.media;
+
+/**
+ * @author lhoracek
+ */
+public enum BoxType {
+
+    TIME_ADD(TextureType.BOX_BAD), //
+    TIME_SUB(TextureType.BOX_GOOD), //
+    SLOW_DOWN(TextureType.BOX_GOOD), //
+    SPEED_UP(TextureType.BOX_BAD), //
+    HIT(TextureType.BOX_GOOD), //
+    CLOUD(TextureType.BOX_BAD);
+
+    public static final BoxType[] GOOD_BOXES = new BoxType[]{HIT, TIME_SUB, SLOW_DOWN};
+    public static final BoxType[] BAD_BOXES  = new BoxType[]{TIME_ADD, SPEED_UP, CLOUD};
+
+    private final TextureType textureType;
+
+    private BoxType(TextureType textureType) {
+        this.textureType = textureType;
+    }
+
+    public TextureType getTextures() {
+        return textureType;
+    }
+
+}
diff --git a/core/src/cz/nic/tablexia/game/games/kidnapping/media/GfxLibrary.java b/core/src/cz/nic/tablexia/game/games/shooting_range/media/SoundType.java
similarity index 53%
rename from core/src/cz/nic/tablexia/game/games/kidnapping/media/GfxLibrary.java
rename to core/src/cz/nic/tablexia/game/games/shooting_range/media/SoundType.java
index f50f4d3f6d12dc2e96bfd5145318d399fe422614..e0414951abb338dd28efba687fea48043c5ab9cc 100644
--- a/core/src/cz/nic/tablexia/game/games/kidnapping/media/GfxLibrary.java
+++ b/core/src/cz/nic/tablexia/game/games/shooting_range/media/SoundType.java
@@ -19,35 +19,39 @@
  * ****************************************************************************
  */
 
-package cz.nic.tablexia.game.games.kidnapping.media;
+package cz.nic.tablexia.game.games.shooting_range.media;
 
-import java.util.HashMap;
-
-import cz.nic.tablexia.game.games.kidnapping.Properties;
-import cz.nic.tablexia.game.games.kidnapping.media.assets.TextureType;
+import cz.nic.tablexia.game.common.media.AssetDescription;
 
 /**
- * Library of all kidnapping assets except tiles
- *
  * @author lhoracek
  */
-public class GfxLibrary extends HashMap<TextureType, String> {
-
-    private static final long   serialVersionUID = -4016629019721509061L;
-    private static final String TEXTURE_DIR      = "gfx/";
-
-    private final TileLibrary tileLibrary;
-
-    public GfxLibrary() {
-        super();
-        tileLibrary = new TileLibrary();
-        for (TextureType textureType : TextureType.values()) {
-            String path = TEXTURE_DIR + textureType.getResource();
-            put(textureType, path);
-        }
+public enum SoundType implements AssetDescription {
+
+    BELL("bell"), //
+    CAROUSEL_1("carousel_1"), //
+    CAROUSEL_2("carousel_2"), //
+    SWOOSH("swoosh"), //
+    BOX_FAST("box_fast"),//
+    BOX_SLOW("box_slow"), //
+    BOX_SMOKE("box_smoke"), //
+    HIT_1("hit_1"), //
+    HIT_2("hit_2"), //
+    HIT_3("hit_3"), //
+    HIT_4("hit_4"), //
+    MISS("miss"), //
+    WRONG("wrong"); //
+
+    public static final SoundType[] CAROUSELS = {CAROUSEL_1, CAROUSEL_2};
+    public static final SoundType[] HITS      = {HIT_1, HIT_2, HIT_3, HIT_4};
+
+    private SoundType(String resource) {
+        this.resource = resource;
     }
 
-    public TileLibrary getTileLibrary() {
-        return tileLibrary;
+    private final String resource;
+
+    public String getResource() {
+        return resource;
     }
 }
diff --git a/core/src/cz/nic/tablexia/game/games/shooting_range/media/TextureType.java b/core/src/cz/nic/tablexia/game/games/shooting_range/media/TextureType.java
new file mode 100644
index 0000000000000000000000000000000000000000..14afe1f55a6e2124a5219a8b55a16ca5df775e34
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/games/shooting_range/media/TextureType.java
@@ -0,0 +1,97 @@
+package cz.nic.tablexia.game.games.shooting_range.media;
+
+import java.util.Arrays;
+import java.util.List;
+
+import cz.nic.tablexia.game.common.media.AssetDescription;
+import cz.nic.tablexia.game.difficulty.GameDifficulty;
+
+/**
+ * Created by lhoracek on 6/22/15.
+ */
+public enum TextureType implements AssetDescription {
+
+    WATCH("watch"), //
+    WATCH_HAND("watch_hand"), //
+
+    CAROUSEL("carousel"), //
+
+    BACKGROUND("background"), //
+    FRAME("frame"), //
+
+    BOX_BAD("box_bad"), //
+    BOX_GOOD("box_good"), //
+
+    WAVE_1("plan2"), //
+    WAVE_2("plan1"), //
+    WAVE_3("plan3"), //
+
+    FLOWER_1("flowers/1"), //
+    FLOWER_2("flowers/2"), //
+    FLOWER_3("flowers/3"), //
+    FLOWER_4("flowers/4"), //
+    FLOWER_5("flowers/5"), //
+    FLOWER_6("flowers/6"), //
+    FLOWER_7("flowers/7"), //
+    FLOWER_8("flowers/8"), //
+    FLOWER_9("flowers/9"), //
+    FLOWER_10("flowers/10"), //
+    FLOWER_11("flowers/11"), //
+    FLOWER_12("flowers/12"), //
+    FLOWER_13("flowers/13"), //
+    FLOWER_14("flowers/14"), //
+    FLOWER_15("flowers/15"), //
+    FLOWER_16("flowers/16"), //
+    FLOWER_17("flowers/17"), //
+    FLOWER_18("flowers/18"), //
+    FLOWER_19("flowers/19"), //
+    FLOWER_20("flowers/20"), //
+    FLOWER_21("flowers/21"), //
+    FLOWER_22("flowers/22"), //
+    FLOWER_23("flowers/23"), //
+    FLOWER_24("flowers/24"), //
+
+    BOX_SMOKE_1("effects/1smoke"), //
+    BOX_SMOKE_2("effects/2smoke"), //
+    BOX_SMOKE_3("effects/3smoke"), //
+    BOX_SMOKE_4("effects/4smoke"), //
+    BOX_SMOKE_5("effects/5smoke"), //
+    BOX_HIT("effects/good_plus1"), //
+    BOX_TIME_MINUS_7("effects/bad_minus7"), //
+    BOX_TIME_MINUS_5("effects/bad_minus5"), //
+    BOX_TIME_PLUS_5("effects/good_plus5"), //
+    BOX_TIME_PLUS_7("effects/good_plus7"), //
+    BOX_SPEED_UP("effects/bad_fast"), //
+    BOX_SPEED_DOWN("effects/good_slow"), //
+
+    ; //
+
+    public static final TextureType[] BOXES                = {BOX_BAD, BOX_GOOD};
+    public static final TextureType[] EFFECTS              = {BOX_SMOKE_1, BOX_SMOKE_2, BOX_SMOKE_3, BOX_SMOKE_4, BOX_SMOKE_5, BOX_TIME_MINUS_5, BOX_TIME_MINUS_7, BOX_TIME_PLUS_5, BOX_TIME_PLUS_7, BOX_SPEED_UP, BOX_SPEED_DOWN};
+    public static final TextureType[] FLOWERS_LEVEL_EASY   = {FLOWER_1, FLOWER_6, FLOWER_9, FLOWER_13, FLOWER_17, FLOWER_21};
+    public static final TextureType[] FLOWERS_LEVEL_MEDIUM = {FLOWER_2, FLOWER_4, FLOWER_5, FLOWER_7, FLOWER_11, FLOWER_12, FLOWER_14, FLOWER_15, FLOWER_17, FLOWER_19, FLOWER_21, FLOWER_22};
+    public static final TextureType[] FLOWERS_LEVEL_HARD   = {FLOWER_1, FLOWER_2, FLOWER_3, FLOWER_4, FLOWER_5, FLOWER_6, FLOWER_7, FLOWER_8, FLOWER_9, FLOWER_10, FLOWER_11, FLOWER_12, FLOWER_13, FLOWER_14, FLOWER_15, FLOWER_16, FLOWER_17, FLOWER_18, FLOWER_19, FLOWER_20, FLOWER_21, FLOWER_22, FLOWER_23, FLOWER_24};
+
+    private final String resource;
+
+    private TextureType(String resource) {
+        this.resource = resource;
+    }
+
+    public String getResource() {
+        return resource;
+    }
+
+    public static List<TextureType> getTargetPack(GameDifficulty gameDifficulty) {
+        switch (gameDifficulty) {
+            case EASY:
+                return Arrays.asList(TextureType.FLOWERS_LEVEL_EASY);
+            case MEDIUM:
+                return Arrays.asList(TextureType.FLOWERS_LEVEL_MEDIUM);
+            case HARD:
+                return Arrays.asList(TextureType.FLOWERS_LEVEL_HARD);
+            default:
+                throw new IllegalStateException("Unknown difficulty");
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/src/cz/nic/tablexia/game/games/shooting_range/model/Direction.java b/core/src/cz/nic/tablexia/game/games/shooting_range/model/Direction.java
new file mode 100644
index 0000000000000000000000000000000000000000..cd9513ea0b7b9b3deaf785f19fddd0ed5dc1fd78
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/games/shooting_range/model/Direction.java
@@ -0,0 +1,8 @@
+package cz.nic.tablexia.game.games.shooting_range.model;
+
+/**
+ * Created by lhoracek on 6/22/15.
+ */
+public enum Direction {
+    LEFT, RIGHT;
+}
\ No newline at end of file
diff --git a/core/src/cz/nic/tablexia/game/games/shooting_range/model/GameState.java b/core/src/cz/nic/tablexia/game/games/shooting_range/model/GameState.java
new file mode 100644
index 0000000000000000000000000000000000000000..b8b97e2bc4de92a147fea00c1955525ad5e6a7e4
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/games/shooting_range/model/GameState.java
@@ -0,0 +1,135 @@
+package cz.nic.tablexia.game.games.shooting_range.model;
+
+import cz.nic.tablexia.game.difficulty.GameDifficulty;
+import cz.nic.tablexia.game.games.shooting_range.Properties;
+import cz.nic.tablexia.game.games.shooting_range.media.TextureType;
+
+/**
+ * Created by lhoracek on 6/22/15.
+ */
+public class GameState {
+
+    private boolean running = false;
+
+    private int   score        = 0;
+    private int   hits         = 0;
+    private int   misses       = 0;
+    private int   wrongTargets = 0;
+    private int   boxesBadHit  = 0;
+    private int   boxesGoodHit = 0;
+    private float time         = 0f;
+    private TextureType currentTarget;
+    private int   hitLimit  = 0;
+    private float gameSpeed = Properties.GAME_SPEED_NORMAL;
+
+    public int getHitLimit() {
+        return hitLimit;
+    }
+
+    public void setGameSpeed(float gameSpeed) {
+        this.gameSpeed = gameSpeed;
+    }
+
+    public void setHitLimit(int limit) {
+        this.hitLimit = limit;
+    }
+
+    public int getScore() {
+        return score;
+    }
+
+    public void addScore(int diff) {
+        score += diff;
+    }
+
+    public void addMiss() {
+        misses++;
+        addScore(-1);
+    }
+
+    public void addWrongTarget() {
+        wrongTargets++;
+        addScore(-1);
+    }
+
+    public void addBoxGood() {
+        boxesGoodHit++;
+    }
+
+    public void addBoxBad() {
+        boxesBadHit++;
+    }
+
+
+    public int getHits() {
+        return hits;
+    }
+
+    public void addHit() {
+        this.hits++;
+        addScore(2);
+        hitLimit--;
+    }
+
+    public int getMisses() {
+        return misses;
+
+    }
+
+    public int getWrongTargets() {
+        return wrongTargets;
+    }
+
+    public int getBoxesBadHit() {
+        return boxesBadHit;
+    }
+
+    public int getBoxesGoodHit() {
+        return boxesGoodHit;
+    }
+
+    public float getTime() {
+        return time;
+    }
+
+    public void setTime(float time) {
+        this.time = time;
+    }
+
+    public float getGameSpeed() {
+        return gameSpeed;
+    }
+
+    public void addTime(float delta) {
+        time += delta * gameSpeed;
+    }
+
+    public boolean isRunning() {
+        return running;
+    }
+
+    public void setRunning(boolean running) {
+        this.running = running;
+    }
+
+    public TextureType getCurrentTarget() {
+        return currentTarget;
+    }
+
+    public void setCurrentTarget(TextureType currentTarget) {
+        this.currentTarget = currentTarget;
+    }
+
+    public int countProgress(GameDifficulty gameDifficulty) {
+        int[][] CUPS = {Properties.CUPS_EASY, Properties.CUPS_MEDIUM, Properties.CUPS_HARD};
+
+        if (getScore() > CUPS[gameDifficulty.ordinal()][2]) {
+            return 3;
+        } else if (getScore() > CUPS[gameDifficulty.ordinal()][1]) {
+            return 2;
+        } else if (getScore() > CUPS[gameDifficulty.ordinal()][0]) {
+            return 1;
+        }
+        return 0;
+    }
+}
diff --git a/core/src/cz/nic/tablexia/game/games/shooting_range/model/Wave.java b/core/src/cz/nic/tablexia/game/games/shooting_range/model/Wave.java
new file mode 100644
index 0000000000000000000000000000000000000000..f7f2656fb195f76094e1340a2d80a5a0c02e7eea
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/games/shooting_range/model/Wave.java
@@ -0,0 +1,127 @@
+package cz.nic.tablexia.game.games.shooting_range.model;
+
+import cz.nic.tablexia.game.difficulty.GameDifficulty;
+import cz.nic.tablexia.game.games.shooting_range.actors.Target;
+
+/**
+ * Created by lhoracek on 6/22/15.
+ */
+public enum Wave {
+    /* --------------- LEVEL EASY --------------------- */
+    WAVE_1_1(GameDifficulty.EASY, 0, 7, 5, Direction.LEFT, new Target.PositionProvider() {
+        @Override
+        public float getY(float elapsedTime, float maxHeight) {
+            return (float) ((Math.sin((((elapsedTime / WAVE_1_1.getRunningTime()) * Math.PI * 2) * 1.5f) - 0.5) * maxHeight) / 30);
+        }
+    }), //
+    WAVE_1_2(GameDifficulty.EASY, 1, 5, 7, Direction.LEFT, new Target.PositionProvider() {
+        @Override
+        public float getY(float elapsedTime, float maxHeight) {
+            return (float) ((Math.sin((((elapsedTime / WAVE_1_2.getRunningTime()) * Math.PI * 2) * 2.3f) + 0.5) * maxHeight) / 30);
+        }
+    }), //
+    WAVE_1_3(GameDifficulty.EASY, 2, 6, 7, Direction.LEFT, new Target.PositionProvider() {
+        @Override
+        public float getY(float elapsedTime, float maxHeight) {
+            return (float) ((Math.sin((((elapsedTime / WAVE_3_3.getRunningTime()) * Math.PI * 2) * 1.5f) - 0.5) * maxHeight) / 20);
+        }
+    }), //
+
+    /* --------------- LEVEL MEDIUM --------------------- */
+    WAVE_2_1(GameDifficulty.MEDIUM, 0, 6, 5, Direction.LEFT, new Target.PositionProvider() {
+        @Override
+        public float getY(float elapsedTime, float maxHeight) {
+            return (float) ((Math.sin((((elapsedTime / WAVE_2_1.getRunningTime()) * Math.PI * 2) * 1.5f) - 0.5) * maxHeight) / 30);
+        }
+    }), //
+    WAVE_2_2(GameDifficulty.MEDIUM, 1, 4, 7, Direction.RIGHT, new Target.PositionProvider() {
+        @Override
+        public float getY(float elapsedTime, float maxHeight) {
+            return (float) ((Math.sin((((elapsedTime / WAVE_2_2.getRunningTime()) * Math.PI * 2) * 2.3f) - 0.5) * maxHeight) / 30);
+        }
+    }), //
+    WAVE_2_3(GameDifficulty.MEDIUM, 2, 5, 7, Direction.RIGHT, new Target.PositionProvider() {
+        @Override
+        public float getY(float elapsedTime, float maxHeight) {
+            return (float) ((Math.sin((((elapsedTime / WAVE_3_3.getRunningTime()) * Math.PI * 2) * 1.5f) - 0.5) * maxHeight) / 20);
+        }
+    }), //
+
+    /* --------------- LEVEL MEDIUM --------------------- */
+    WAVE_3_1(GameDifficulty.HARD, 0, 4, 10, Direction.LEFT, new Target.PositionProvider() {
+        @Override
+        public float getY(float elapsedTime, float maxHeight) {
+            return (float) ((Math.sin((((elapsedTime / WAVE_3_1.getRunningTime()) * Math.PI * 2) * 1.5f) - 0.5) * maxHeight) / 30);
+        }
+    }), //
+    WAVE_3_2(GameDifficulty.HARD, 1, 3, 7, Direction.RIGHT, new Target.PositionProvider() {
+        @Override
+        public float getY(float elapsedTime, float maxHeight) {
+            return (float) ((Math.sin((((elapsedTime / WAVE_3_2.getRunningTime()) * Math.PI * 2) * 2.3f) - 0.5) * maxHeight) / 20);
+        }
+    }), //
+    WAVE_3_3(GameDifficulty.HARD, 2, 5, 5, Direction.LEFT, new Target.PositionProvider() {
+        @Override
+        public float getY(float elapsedTime, float maxHeight) {
+            return (float) ((Math.sin((((elapsedTime / WAVE_3_3.getRunningTime()) * Math.PI * 2) * 1.5f) - 0.5) * maxHeight) / 20);
+        }
+    }); //
+
+    public static final  int    WAVE_ROWS    = 3;
+    private static final Wave[] EASY_WAVES   = new Wave[]{WAVE_1_1, WAVE_1_2, WAVE_1_3};
+    private static final Wave[] MEDIUM_WAVES = new Wave[]{WAVE_2_1, WAVE_2_2, WAVE_2_3};
+    private static final Wave[] HARD_WAVES   = new Wave[]{WAVE_3_1, WAVE_3_2, WAVE_3_3};
+
+    public static Wave getWave(GameDifficulty difficulty, int wavePosition) {
+        switch (difficulty) {
+            case EASY:
+                return EASY_WAVES[wavePosition];
+            case MEDIUM:
+                return MEDIUM_WAVES[wavePosition];
+            case HARD:
+                return HARD_WAVES[wavePosition];
+            default:
+                throw new IllegalStateException("Unknow difficulty");
+        }
+    }
+
+    private final int                     verticalOrder;
+    private final float                   runningTime;
+    private final Direction               direction;
+    private final Target.PositionProvider positionProvider;
+    private final int                     flowerOnScreen;
+    private final GameDifficulty          difficulty;
+
+    private Wave(GameDifficulty difficulty, int verticalOrder, float runningTime, int flowersOnScreen, Direction direction, Target.PositionProvider positionProvider) {
+        this.verticalOrder = verticalOrder;
+        this.runningTime = runningTime;
+        this.direction = direction;
+        this.positionProvider = positionProvider;
+        flowerOnScreen = flowersOnScreen;
+        this.difficulty = difficulty;
+    }
+
+    public float getRunningTime() {
+        return runningTime;
+    }
+
+    public float getY(float elapsedTime, float maxHeight) {
+        return positionProvider.getY(elapsedTime, maxHeight);
+    }
+
+    public float getX(float elapsedTime, float maxWidth) {
+        return ((Direction.LEFT == direction ? -1 : 1) * (maxWidth * (elapsedTime / getRunningTime()))) + (Direction.LEFT == direction ? maxWidth : 0);
+    }
+
+    public int getFlowersOnScreen() {
+        return flowerOnScreen;
+    }
+
+    public Direction getDirection() {
+        return direction;
+    }
+
+    public GameDifficulty getDifficulty() {
+        return difficulty;
+    }
+}
diff --git a/core/src/cz/nic/tablexia/game/games/shooting_range/tools/HitEvaluator.java b/core/src/cz/nic/tablexia/game/games/shooting_range/tools/HitEvaluator.java
new file mode 100644
index 0000000000000000000000000000000000000000..368eff6cbcd81ee60c7065c8aabda847609cdcf6
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/games/shooting_range/tools/HitEvaluator.java
@@ -0,0 +1,12 @@
+package cz.nic.tablexia.game.games.shooting_range.tools;
+
+import com.badlogic.gdx.utils.Disposable;
+
+import cz.nic.tablexia.game.games.shooting_range.actors.Target;
+
+/**
+ * Created by lhoracek on 7/14/15.
+ */
+public interface HitEvaluator extends Disposable {
+    public boolean hit(Target target, float x, float y);
+}
diff --git a/core/src/cz/nic/tablexia/game/games/shooting_range/tools/PixelPerfectHitEvaluator.java b/core/src/cz/nic/tablexia/game/games/shooting_range/tools/PixelPerfectHitEvaluator.java
new file mode 100644
index 0000000000000000000000000000000000000000..fbf029939747233a16038cc36d6dce6c627c3482
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/games/shooting_range/tools/PixelPerfectHitEvaluator.java
@@ -0,0 +1,63 @@
+package cz.nic.tablexia.game.games.shooting_range.tools;
+
+import com.badlogic.gdx.graphics.Color;
+import com.badlogic.gdx.graphics.Pixmap;
+import com.badlogic.gdx.graphics.Texture;
+import com.badlogic.gdx.graphics.g2d.TextureRegion;
+import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import cz.nic.tablexia.game.common.media.GfxLibrary;
+import cz.nic.tablexia.game.games.shooting_range.actors.Target;
+import cz.nic.tablexia.game.games.shooting_range.media.TextureType;
+
+/**
+ * Created by lhoracek on 7/14/15.
+ */
+public class PixelPerfectHitEvaluator implements HitEvaluator {
+    private Map<Texture, Pixmap> pixmapCache = new HashMap<Texture, Pixmap>();
+
+    @Override
+    public void dispose() {
+        for (Pixmap pixmap : pixmapCache.values()) {
+            pixmap.dispose();
+        }
+    }
+
+    public PixelPerfectHitEvaluator(GfxLibrary gfxLibrary, List<TextureType> targetTypes) {
+        init(gfxLibrary, targetTypes);
+    }
+
+    private void init(GfxLibrary gfxLibrary, List<TextureType> targetTypes) {
+        for (TextureType targetType : targetTypes) {
+            getPixmap(gfxLibrary.getTextureRegion(targetType).getTexture());
+        }
+    }
+
+    private Pixmap getPixmap(Texture texture) {
+        if (pixmapCache.get(texture) == null) {
+            texture.getTextureData().prepare();
+            Pixmap pixmap = texture.getTextureData().consumePixmap();
+            pixmapCache.put(texture, pixmap);
+        }
+        return pixmapCache.get(texture);
+    }
+
+    @Override
+    public boolean hit(Target target, float x, float y) {
+        // Pixel perfect hit decision
+        if (!target.isShot()) {
+            TextureRegion textureRegion = ((TextureRegionDrawable) target.getDrawable()).getRegion();
+            Texture texture = textureRegion.getTexture();
+            Pixmap pixmap = getPixmap(texture);
+            int pixel = pixmap.getPixel(textureRegion.getRegionX() + (int) x, textureRegion.getRegionY() + textureRegion.getRegionHeight() - (int) y);
+            if (new Color(pixel).a != 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/core/src/cz/nic/tablexia/game/games/shooting_range/tools/TargetGenerator.java b/core/src/cz/nic/tablexia/game/games/shooting_range/tools/TargetGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..c769ac2e901b28790fb7038896f05d111721faa9
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/games/shooting_range/tools/TargetGenerator.java
@@ -0,0 +1,137 @@
+package cz.nic.tablexia.game.games.shooting_range.tools;
+
+import com.badlogic.gdx.scenes.scene2d.InputListener;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import cz.nic.tablexia.game.common.media.GfxLibrary;
+import cz.nic.tablexia.game.difficulty.GameDifficulty;
+import cz.nic.tablexia.game.games.shooting_range.actors.Row;
+import cz.nic.tablexia.game.games.shooting_range.actors.Target;
+import cz.nic.tablexia.game.games.shooting_range.media.TextureType;
+
+/**
+ * Created by lhoracek on 6/22/15.
+ */
+public class TargetGenerator {
+    private static final String TAG = TargetGenerator.class.getSimpleName();
+
+    private static final float EASY_BOX_PROBABILITY   = 0.05f;                                // 5% krabic
+    private static final float MEDIUM_BOX_PROBABILITY = 0.05f;                                // 5% krabic
+    private static final float HARD_BOX_PROBABILITY   = 0.1f;                                 // 10% krabic
+
+    public static final float EASY_GOOD_PROBABILITY   = 0.7f;
+    public static final float MEDIUM_GOOD_PROBABILITY = 0.5f;
+    public static final float HARD_GOOD_PROBABILITY   = 0.3f;
+
+    private final GameDifficulty gameDifficulty;
+    private final Random         random;
+    private final GfxLibrary     gfxLibrary;
+    private final InputListener  clickListener;
+    private final HitEvaluator   hitEvaluator;
+
+    public TargetGenerator(GameDifficulty gameDifficulty, Random random, GfxLibrary gfxLibrary, InputListener clickListener, HitEvaluator hitEvaluator) {
+        super();
+        this.random = random;
+        this.gameDifficulty = gameDifficulty;
+        this.gfxLibrary = gfxLibrary;
+        this.clickListener = clickListener;
+        this.hitEvaluator = hitEvaluator;
+    }
+
+    public TextureType getRandomFlowerType(GameDifficulty gameDifficulty) {
+        List<TextureType> textureTypeBag = getTextureTypeBag();
+        return textureTypeBag.get(random.nextInt(textureTypeBag.size()));
+    }
+
+    private Map<Row, Target> lastTargetsForRow = new HashMap<Row, Target>();
+
+    public Target getLastTargetInRow(Row row) {
+        return lastTargetsForRow.get(row);
+    }
+
+    public Target addNewTargetToRow(Row row, TextureType requiredTextureType) {
+        Target prevLastTarget = getLastTargetInRow(row);
+        float targetPeriod = row.getWave().getRunningTime() / row.getWave().getFlowersOnScreen();
+        return addNewTargetToRow(row, requiredTextureType, prevLastTarget.getStartTime() + targetPeriod);
+    }
+
+    public Target addNewTargetToRow(Row row, TextureType requiredTextureType, float startTime) {
+        return addNewTargetToRow(row, requiredTextureType, startTime, true);
+    }
+
+    public Target addNewTargetToRow(Row row, TextureType requiredTextureType, float startTime, boolean asLast) {
+        List<TextureType> textureTypeBag = new ArrayList<TextureType>(requiredTextureType == null ? getTextureTypeBag() : Arrays.asList((new TextureType[]{requiredTextureType})));
+        Target target = getRandomTarget(textureTypeBag, startTime, row);
+        if (asLast) {
+            lastTargetsForRow.put(row, target);
+        }
+        return target;
+    }
+
+    /*
+     * Init row on start
+     */
+    public List<Target> generateTargetRow(Row row) {
+        List<Target> flowers = new ArrayList<Target>();
+        List<TextureType> textureTypeBag = new ArrayList<TextureType>(getTextureTypeBag());
+
+        int flowerNumber = row.getWave().getFlowersOnScreen();
+        float targetPeriod = row.getWave().getRunningTime() / row.getWave().getFlowersOnScreen();
+
+        // add one more target off the screen
+        for (int i = -flowerNumber; i <= 0; i++) {
+            Target target = getRandomTarget(textureTypeBag, targetPeriod * i, row);
+            flowers.add(target);
+            if (i == 0) {
+                lastTargetsForRow.put(row, target);
+            }
+        }
+        return flowers;
+    }
+
+    private TextureType getRandomBoxType() {
+        float boxTypeIndex = random.nextFloat();
+        if ((gameDifficulty == GameDifficulty.EASY) && (boxTypeIndex > EASY_GOOD_PROBABILITY)) {
+            return TextureType.BOX_BAD;
+        } else if ((gameDifficulty == GameDifficulty.MEDIUM) && (boxTypeIndex > HARD_GOOD_PROBABILITY)) {
+            return TextureType.BOX_BAD;
+        } else if ((gameDifficulty == GameDifficulty.HARD) && (boxTypeIndex > HARD_GOOD_PROBABILITY)) {
+            return TextureType.BOX_BAD;
+        }
+
+        return TextureType.BOX_GOOD;
+    }
+
+    private Target getRandomTarget(List<TextureType> textureTypeBag, float startTime, Row row) {
+        float boxIndex = random.nextFloat();
+        TextureType textureType = getRandomBoxType();
+        if (boxIndex > getBoxProbability()) {
+            int random = (int) (Math.random() * textureTypeBag.size());
+            textureType = textureTypeBag.get(random);
+        }
+        return new Target(gfxLibrary.getTextureRegion(textureType), startTime, row, textureType, clickListener, hitEvaluator);
+    }
+
+    private float getBoxProbability() {
+        switch (gameDifficulty) {
+            case EASY:
+                return EASY_BOX_PROBABILITY;
+            case MEDIUM:
+                return MEDIUM_BOX_PROBABILITY;
+            case HARD:
+                return HARD_BOX_PROBABILITY;
+            default:
+                throw new IllegalStateException("Unknown difficulty");
+        }
+    }
+
+    private List<TextureType> getTextureTypeBag() {
+        return TextureType.getTargetPack(gameDifficulty);
+    }
+}
\ No newline at end of file
diff --git a/core/src/cz/nic/tablexia/game/games/shooting_range/tools/TargetPositionController.java b/core/src/cz/nic/tablexia/game/games/shooting_range/tools/TargetPositionController.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed818644cd5a28b7b2b01b579151677ecf1f59cf
--- /dev/null
+++ b/core/src/cz/nic/tablexia/game/games/shooting_range/tools/TargetPositionController.java
@@ -0,0 +1,107 @@
+package cz.nic.tablexia.game.games.shooting_range.tools;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+
+import cz.nic.tablexia.game.difficulty.GameDifficulty;
+import cz.nic.tablexia.game.games.shooting_range.actors.Row;
+import cz.nic.tablexia.game.games.shooting_range.actors.Scene;
+import cz.nic.tablexia.game.games.shooting_range.actors.Target;
+import cz.nic.tablexia.game.games.shooting_range.media.TextureType;
+import cz.nic.tablexia.game.games.shooting_range.model.Direction;
+
+/**
+ * Created by lhoracek on 7/2/15.
+ */
+public class TargetPositionController {
+
+    private float elapsedTime = 0;
+    private final TargetGenerator targetGenerator;
+    private final Random          random;
+    private final float           width;
+    private final Scene           scene;
+    private       TextureType     targetType;
+    private       GameDifficulty  gameDifficulty;
+    Set<TextureType> availableTypes = new HashSet<TextureType>();
+
+    public TargetPositionController(Scene scene, TargetGenerator targetGenerator, Random random, GameDifficulty gameDifficulty, float width) {
+        super();
+        this.scene = scene;
+        this.targetGenerator = targetGenerator;
+        this.random = random;
+        this.width = width;
+        this.gameDifficulty = gameDifficulty;
+    }
+
+
+    public void setTargetType(TextureType targetType) {
+        this.targetType = targetType;
+    }
+
+    public Set<TextureType> getAvailableTypes() {
+        return availableTypes;
+    }
+
+    /*
+             * (non-Javadoc)
+             * @see org.andengine.engine.handler.IUpdateHandler#onUpdate(float)
+             */
+    public void onUpdate(float pSecondsElapsed) {
+        elapsedTime += pSecondsElapsed;
+        Set<TextureType> availableTypes = new HashSet<TextureType>();
+        List<Target> invisibles = new ArrayList<Target>();
+
+        for (Row row : scene.getRows()) {
+            for (Target target : row.getTargets()) {
+                float x = row.getWave().getX(elapsedTime - target.getStartTime(), width);
+                // is target in scene?
+                if (((x + target.getWidth()) > 0) && (x < width)) {
+                    // is last target in row
+                    if (targetGenerator.getLastTargetInRow(row).equals(target)) {
+                        // last invisible target is on scene - add new one
+                        List<TextureType> textures = TextureType.getTargetPack(gameDifficulty);
+                        row.addTarget(targetGenerator.addNewTargetToRow(row, textures.get(random.nextInt(textures.size()))));
+                    }
+                    target.setX(x);
+                    target.setY(row.getHeight() - 50 + row.getWave().getY(elapsedTime - target.getStartTime(), row.getHeight()));
+
+                    // is target in first half of its way? to get available target types not immediately leaving screen
+                    if ((x > (Direction.RIGHT == row.getWave().getDirection() ? 0 : width / 2)) && (x < (Direction.RIGHT == row.getWave().getDirection() ? width / 2 : width))) {
+                        // only not hit
+                        if (!target.isShot()) {
+                            availableTypes.add(target.getTextureType());
+                        }
+                    }
+                    // target is not on scene
+                } else {
+                    if (((row.getWave().getDirection() == Direction.LEFT) && (x < 0)) || ((row.getWave().getDirection() == Direction.RIGHT) && (x > width))) {
+                        // gone out of screen
+                        row.removeTarget(target);
+                    } else {
+                        // comming to the screen
+                        invisibles.add(target);
+                        availableTypes.add(target.getTextureType()); // TODO count available to make them more available or select tartgetType, tha has multiple occurences
+                    }
+                }
+            }
+        }
+
+        if ((targetType != null) && !availableTypes.contains(targetType)) {
+            if (invisibles.size() > 0) {
+                int index = random.nextInt(invisibles.size());
+                Target swap = invisibles.get(index);
+                Target swapTo = targetGenerator.addNewTargetToRow(swap.getRow(), targetType, swap.getStartTime(), targetGenerator.getLastTargetInRow(swap.getRow()).equals(swap));
+
+                swap.getRow().addTarget(swapTo);
+                swap.getRow().removeTarget(swap);
+            } else {
+                Row row = scene.getRows()[random.nextInt(scene.getRows().length)];
+                row.addTarget(targetGenerator.addNewTargetToRow(row, targetType));
+            }
+        }
+        this.availableTypes = availableTypes;
+    }
+}
diff --git a/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java b/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java
index dce03602b58874cb4e003c849d0b015666520b36..56caf63c31a403313492eed80b0cd3b34a3779cf 100644
--- a/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java
+++ b/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java
@@ -272,6 +272,10 @@ public abstract class AbstractTablexiaScreen<T> extends ScreenAdapter {
         return false;
     }
 
+    public boolean isPaused() {
+        return paused;
+    }
+
 //////////////////////////// LOADING LISTENER
 
     private void notifyLoadingCompleteListeners() {
diff --git a/core/src/cz/nic/tablexia/screen/createuser/FormScreen.java b/core/src/cz/nic/tablexia/screen/createuser/FormScreen.java
index 436eeec3eb0ca1ed4082ef613f6c7fb2e5f30c8c..6ad0d71006bc4927b5c5b6718912db69aaa2afa2 100644
--- a/core/src/cz/nic/tablexia/screen/createuser/FormScreen.java
+++ b/core/src/cz/nic/tablexia/screen/createuser/FormScreen.java
@@ -148,7 +148,7 @@ public class FormScreen extends AbstractTablexiaScreen<Void> {
         sl.switchToStep(1);
         sl.setDisabledPoint(middle);
 
-        // TODO pencil and stamp layers
+        // pencil and stamp layers
         group.addActor(pen = ScaleUtil.createImageWidthPosition(getScreenTextureRegion(GFX_PATH + "pencil_dropped"), getStage().getWidth() * 0.2f, getStage().getWidth() * 0.85f, getStage().getWidth() * -0.13f));
         group.addActor(stamp = ScaleUtil.createImageWidthPosition(getScreenTextureRegion(GFX_PATH + "stamp_left_dropped"), getStage().getWidth() * 0.2f, getStage().getWidth() * -0.01f, getStage().getWidth() * -0.05f));
         pen.addListener(new DragActorListener(pen, true, new DragActorListener.DragDropListener() {
@@ -278,9 +278,7 @@ public class FormScreen extends AbstractTablexiaScreen<Void> {
                 return false;
             }
         });
-        // TODO show sign dialog
-
-
+        // show sign dialog
         getStage().addActor(signature);
         Dialog dialog = new SignatureDialog(getStage().getWidth() * 0.1f, getStage().getWidth() * 0.1f - (getStage().getCamera().position.y - getStage().getHeight() / 2) / 2, getStage().getWidth() * 0.8f, getStage().getHeight() * 0.8f).show(getStage());
     }
diff --git a/core/src/cz/nic/tablexia/util/listener/DragActorListener.java b/core/src/cz/nic/tablexia/util/listener/DragActorListener.java
index 08797a897755a1ddbddc79373f9f6bf73b9db462..2a22ac17bbdd81bc6c06bebfce353fcd87cd85a4 100644
--- a/core/src/cz/nic/tablexia/util/listener/DragActorListener.java
+++ b/core/src/cz/nic/tablexia/util/listener/DragActorListener.java
@@ -62,7 +62,7 @@ public class DragActorListener extends InputListener {
             float bx = actor.getX() + (x - grabX) * actor.getScaleX();
             float by = actor.getY() + (y - grabY) * actor.getScaleY();
             actor.setPosition(bx, by);
-            if (actor.getDebug() && logging) {
+            if (actor.getDebug()) { // TODO enable logging switch
                 Log.info(((Object) this).getClass().getName(), "Position " + bx + "x" + by);
             }
             event.stop();