[nano-assault] 01/18: New upstream version 1.0

Dominik George natureshadow-guest at moszumanska.debian.org
Mon Apr 24 16:49:57 UTC 2017


This is an automated email from the git hooks/post-receive script.

natureshadow-guest pushed a commit to branch master
in repository nano-assault.

commit 7f8388f068f096efe79106cc897cfe248a65db45
Author: Dominik George <nik at naturalnet.de>
Date:   Mon Apr 24 17:13:24 2017 +0200

    New upstream version 1.0
---
 LICENSE.txt                                       | 339 ++++++++++++++++++++++
 MANIFEST.in                                       |   1 +
 Nano_Assault.egg-info/PKG-INFO                    |  16 +
 Nano_Assault.egg-info/SOURCES.txt                 |  77 +++++
 Nano_Assault.egg-info/dependency_links.txt        |   1 +
 Nano_Assault.egg-info/entry_points.txt            |   3 +
 Nano_Assault.egg-info/not-zip-safe                |   1 +
 Nano_Assault.egg-info/requires.txt                |   1 +
 Nano_Assault.egg-info/top_level.txt               |   1 +
 PKG-INFO                                          |  16 +
 nanoassault/__init__.py                           |  52 ++++
 nanoassault/__main__.py                           |  20 ++
 nanoassault/actor.py                              |  67 +++++
 nanoassault/animation.py                          |  39 +++
 nanoassault/animations.py                         |  29 ++
 nanoassault/bullet.py                             |  38 +++
 nanoassault/bullets.py                            |  33 +++
 nanoassault/collectible.py                        |  26 ++
 nanoassault/collectibles.py                       |  31 ++
 nanoassault/constants.py                          |  32 ++
 nanoassault/dungeon.py                            | 101 +++++++
 nanoassault/enemies.py                            | 146 ++++++++++
 nanoassault/enemy.py                              |  34 +++
 nanoassault/gameobject.py                         |  39 +++
 nanoassault/img/boss_coccusimmanis_walking0.png   | Bin 0 -> 596 bytes
 nanoassault/img/boss_coccusimmanis_walking1.png   | Bin 0 -> 551 bytes
 nanoassault/img/bullet_enemy0.png                 | Bin 0 -> 186 bytes
 nanoassault/img/bullet_player0.png                | Bin 0 -> 186 bytes
 nanoassault/img/collectible_energy.png            | Bin 0 -> 454 bytes
 nanoassault/img/collectible_spasmolytic.png       | Bin 0 -> 394 bytes
 nanoassault/img/enemy_bacillusceler_walking0.png  | Bin 0 -> 239 bytes
 nanoassault/img/enemy_bacillusceler_walking1.png  | Bin 0 -> 252 bytes
 nanoassault/img/enemy_coccusdesertus_walking0.png | Bin 0 -> 316 bytes
 nanoassault/img/enemy_coccusdesertus_walking1.png | Bin 0 -> 323 bytes
 nanoassault/img/enemy_coccusiactans.png           | Bin 0 -> 316 bytes
 nanoassault/img/enemy_coccusiactans_standing0.png | Bin 0 -> 316 bytes
 nanoassault/img/enemy_coccusiactans_walking0.png  | Bin 0 -> 300 bytes
 nanoassault/img/intro.png                         | Bin 0 -> 3350 bytes
 nanoassault/img/level_fleshy_bottom.png           | Bin 0 -> 317 bytes
 nanoassault/img/level_fleshy_bottomclosed0.png    | Bin 0 -> 233 bytes
 nanoassault/img/level_fleshy_bottomdoor0.png      | Bin 0 -> 384 bytes
 nanoassault/img/level_fleshy_bottomleft.png       | Bin 0 -> 372 bytes
 nanoassault/img/level_fleshy_bottomlocked0.png    | Bin 0 -> 283 bytes
 nanoassault/img/level_fleshy_bottomright.png      | Bin 0 -> 392 bytes
 nanoassault/img/level_fleshy_ground.png           | Bin 0 -> 159 bytes
 nanoassault/img/level_fleshy_left.png             | Bin 0 -> 281 bytes
 nanoassault/img/level_fleshy_leftclosed0.png      | Bin 0 -> 219 bytes
 nanoassault/img/level_fleshy_leftdoor0.png        | Bin 0 -> 350 bytes
 nanoassault/img/level_fleshy_leftlocked0.png      | Bin 0 -> 270 bytes
 nanoassault/img/level_fleshy_right.png            | Bin 0 -> 274 bytes
 nanoassault/img/level_fleshy_rightclosed0.png     | Bin 0 -> 231 bytes
 nanoassault/img/level_fleshy_rightdoor0.png       | Bin 0 -> 362 bytes
 nanoassault/img/level_fleshy_rightlocked0.png     | Bin 0 -> 285 bytes
 nanoassault/img/level_fleshy_top.png              | Bin 0 -> 293 bytes
 nanoassault/img/level_fleshy_topclosed0.png       | Bin 0 -> 231 bytes
 nanoassault/img/level_fleshy_topdoor0.png         | Bin 0 -> 366 bytes
 nanoassault/img/level_fleshy_topleft.png          | Bin 0 -> 381 bytes
 nanoassault/img/level_fleshy_toplocked0.png       | Bin 0 -> 280 bytes
 nanoassault/img/level_fleshy_topright.png         | Bin 0 -> 357 bytes
 nanoassault/img/player_walking0.png               | Bin 0 -> 349 bytes
 nanoassault/img/player_walking1.png               | Bin 0 -> 350 bytes
 nanoassault/img/player_walking2.png               | Bin 0 -> 351 bytes
 nanoassault/img/player_walking3.png               | Bin 0 -> 352 bytes
 nanoassault/img/titlescreen.png                   | Bin 0 -> 7776 bytes
 nanoassault/img/ui_heart.png                      | Bin 0 -> 277 bytes
 nanoassault/level.py                              | 132 +++++++++
 nanoassault/levels.py                             |  63 ++++
 nanoassault/player.py                             |  44 +++
 nanoassault/run_dungeon.py                        |  35 +++
 nanoassault/run_level.py                          | 194 +++++++++++++
 nanoassault/sound/gameover.wav                    | Bin 0 -> 103796 bytes
 nanoassault/sound/hit0.wav                        | Bin 0 -> 13280 bytes
 nanoassault/sound/open.wav                        | Bin 0 -> 22888 bytes
 nanoassault/sound/pickup.wav                      | Bin 0 -> 14752 bytes
 nanoassault/sound/theme0.wav                      | Bin 0 -> 2411140 bytes
 nanoassault/sound/theme1.wav                      | Bin 0 -> 1121324 bytes
 nanoassault/wall.py                               |  23 ++
 setup.cfg                                         |   5 +
 setup.py                                          |  55 ++++
 79 files changed, 1694 insertions(+)

diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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 2 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, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..42eb410
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1 @@
+include LICENSE.txt
diff --git a/Nano_Assault.egg-info/PKG-INFO b/Nano_Assault.egg-info/PKG-INFO
new file mode 100644
index 0000000..7816bb4
--- /dev/null
+++ b/Nano_Assault.egg-info/PKG-INFO
@@ -0,0 +1,16 @@
+Metadata-Version: 1.1
+Name: Nano-Assault
+Version: 1.0
+Summary: UNKNOWN
+Home-page: https://edugit.org/eike/nanoassault
+Author: Eike Jesinghaus
+Author-email: eike at naturalnet.de
+License: UNKNOWN
+Description: UNKNOWN
+Platform: UNKNOWN
+Classifier: Development Status :: 6 - Mature
+Classifier: License :: OSI Approved :: GNU General Public License (GPL)
+Classifier: Natural Language :: English
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Topic :: Games/Entertainment :: Arcade
diff --git a/Nano_Assault.egg-info/SOURCES.txt b/Nano_Assault.egg-info/SOURCES.txt
new file mode 100644
index 0000000..a7a571e
--- /dev/null
+++ b/Nano_Assault.egg-info/SOURCES.txt
@@ -0,0 +1,77 @@
+LICENSE.txt
+MANIFEST.in
+setup.py
+Nano_Assault.egg-info/PKG-INFO
+Nano_Assault.egg-info/SOURCES.txt
+Nano_Assault.egg-info/dependency_links.txt
+Nano_Assault.egg-info/entry_points.txt
+Nano_Assault.egg-info/not-zip-safe
+Nano_Assault.egg-info/requires.txt
+Nano_Assault.egg-info/top_level.txt
+nanoassault/__init__.py
+nanoassault/__main__.py
+nanoassault/actor.py
+nanoassault/animation.py
+nanoassault/animations.py
+nanoassault/bullet.py
+nanoassault/bullets.py
+nanoassault/collectible.py
+nanoassault/collectibles.py
+nanoassault/constants.py
+nanoassault/dungeon.py
+nanoassault/enemies.py
+nanoassault/enemy.py
+nanoassault/gameobject.py
+nanoassault/level.py
+nanoassault/levels.py
+nanoassault/player.py
+nanoassault/run_dungeon.py
+nanoassault/run_level.py
+nanoassault/wall.py
+nanoassault/img/boss_coccusimmanis_walking0.png
+nanoassault/img/boss_coccusimmanis_walking1.png
+nanoassault/img/bullet_enemy0.png
+nanoassault/img/bullet_player0.png
+nanoassault/img/collectible_energy.png
+nanoassault/img/collectible_spasmolytic.png
+nanoassault/img/enemy_bacillusceler_walking0.png
+nanoassault/img/enemy_bacillusceler_walking1.png
+nanoassault/img/enemy_coccusdesertus_walking0.png
+nanoassault/img/enemy_coccusdesertus_walking1.png
+nanoassault/img/enemy_coccusiactans.png
+nanoassault/img/enemy_coccusiactans_standing0.png
+nanoassault/img/enemy_coccusiactans_walking0.png
+nanoassault/img/intro.png
+nanoassault/img/level_fleshy_bottom.png
+nanoassault/img/level_fleshy_bottomclosed0.png
+nanoassault/img/level_fleshy_bottomdoor0.png
+nanoassault/img/level_fleshy_bottomleft.png
+nanoassault/img/level_fleshy_bottomlocked0.png
+nanoassault/img/level_fleshy_bottomright.png
+nanoassault/img/level_fleshy_ground.png
+nanoassault/img/level_fleshy_left.png
+nanoassault/img/level_fleshy_leftclosed0.png
+nanoassault/img/level_fleshy_leftdoor0.png
+nanoassault/img/level_fleshy_leftlocked0.png
+nanoassault/img/level_fleshy_right.png
+nanoassault/img/level_fleshy_rightclosed0.png
+nanoassault/img/level_fleshy_rightdoor0.png
+nanoassault/img/level_fleshy_rightlocked0.png
+nanoassault/img/level_fleshy_top.png
+nanoassault/img/level_fleshy_topclosed0.png
+nanoassault/img/level_fleshy_topdoor0.png
+nanoassault/img/level_fleshy_topleft.png
+nanoassault/img/level_fleshy_toplocked0.png
+nanoassault/img/level_fleshy_topright.png
+nanoassault/img/player_walking0.png
+nanoassault/img/player_walking1.png
+nanoassault/img/player_walking2.png
+nanoassault/img/player_walking3.png
+nanoassault/img/titlescreen.png
+nanoassault/img/ui_heart.png
+nanoassault/sound/gameover.wav
+nanoassault/sound/hit0.wav
+nanoassault/sound/open.wav
+nanoassault/sound/pickup.wav
+nanoassault/sound/theme0.wav
+nanoassault/sound/theme1.wav
\ No newline at end of file
diff --git a/Nano_Assault.egg-info/dependency_links.txt b/Nano_Assault.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/Nano_Assault.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/Nano_Assault.egg-info/entry_points.txt b/Nano_Assault.egg-info/entry_points.txt
new file mode 100644
index 0000000..e988fff
--- /dev/null
+++ b/Nano_Assault.egg-info/entry_points.txt
@@ -0,0 +1,3 @@
+[gui_scripts]
+nanoassault = nanoassault:main
+
diff --git a/Nano_Assault.egg-info/not-zip-safe b/Nano_Assault.egg-info/not-zip-safe
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/Nano_Assault.egg-info/not-zip-safe
@@ -0,0 +1 @@
+
diff --git a/Nano_Assault.egg-info/requires.txt b/Nano_Assault.egg-info/requires.txt
new file mode 100644
index 0000000..0d5e0c8
--- /dev/null
+++ b/Nano_Assault.egg-info/requires.txt
@@ -0,0 +1 @@
+Pygame
diff --git a/Nano_Assault.egg-info/top_level.txt b/Nano_Assault.egg-info/top_level.txt
new file mode 100644
index 0000000..c86f363
--- /dev/null
+++ b/Nano_Assault.egg-info/top_level.txt
@@ -0,0 +1 @@
+nanoassault
diff --git a/PKG-INFO b/PKG-INFO
new file mode 100644
index 0000000..7816bb4
--- /dev/null
+++ b/PKG-INFO
@@ -0,0 +1,16 @@
+Metadata-Version: 1.1
+Name: Nano-Assault
+Version: 1.0
+Summary: UNKNOWN
+Home-page: https://edugit.org/eike/nanoassault
+Author: Eike Jesinghaus
+Author-email: eike at naturalnet.de
+License: UNKNOWN
+Description: UNKNOWN
+Platform: UNKNOWN
+Classifier: Development Status :: 6 - Mature
+Classifier: License :: OSI Approved :: GNU General Public License (GPL)
+Classifier: Natural Language :: English
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Topic :: Games/Entertainment :: Arcade
diff --git a/nanoassault/__init__.py b/nanoassault/__init__.py
new file mode 100644
index 0000000..9750196
--- /dev/null
+++ b/nanoassault/__init__.py
@@ -0,0 +1,52 @@
+# ~*~ coding: utf-8 ~*~
+
+# (C) 2017, Eike Jesinghaus
+# 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/>.
+
+import os
+
+from .constants import SCALEFAC, TILEX, TILEY
+from .player import Player
+from .dungeon import Dungeon
+from .run_dungeon import run_dungeon
+from .levels import ALL_LEVELS, BOSS_LEVELS
+
+import pygame
+
+def main():
+    screen = pygame.display.set_mode((TILEX*16*SCALEFAC, TILEY*16*SCALEFAC+8*SCALEFAC), pygame.FULLSCREEN)
+    pygame.display.set_caption("Nano Assault")
+
+    for i in ("titlescreen", "intro"):
+        titlescreen = pygame.image.load(os.path.join(os.path.dirname(__file__), "img", "%s.png" % i))
+        titlescreen = pygame.transform.scale(titlescreen, screen.get_size())
+        screen.blit(titlescreen, (0, 0))
+        pygame.display.update()
+
+        while True:
+            event = pygame.event.wait()
+            if event.type == pygame.KEYDOWN:
+                if event.key == pygame.K_ESCAPE:
+                    exit(0)
+                else:
+                    break
+
+    player = Player((screen.get_width()/2-SCALEFAC*8, screen.get_height()/2-SCALEFAC*12))
+
+    dungeon = Dungeon("fleshy", 12)
+    dungeon.generate(ALL_LEVELS, BOSS_LEVELS)
+
+    run_dungeon(screen, dungeon, player)
+
+    return 0
diff --git a/nanoassault/__main__.py b/nanoassault/__main__.py
new file mode 100644
index 0000000..cbfdfb2
--- /dev/null
+++ b/nanoassault/__main__.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+# ~*~ coding: utf-8 ~*~
+
+# (C) 2017, Eike Jesinghaus
+# 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/>.
+
+from nanoassault import main
+
+exit(main())
diff --git a/nanoassault/actor.py b/nanoassault/actor.py
new file mode 100644
index 0000000..dcde31f
--- /dev/null
+++ b/nanoassault/actor.py
@@ -0,0 +1,67 @@
+# ~*~ coding: utf-8 ~*~
+
+# (C) 2017, Eike Jesinghaus
+# 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/>.
+
+from .constants import SPEED_SLOW, SPEED_NORM, SPEED_FAST, SPEED_MEGAFAST
+from .gameobject import GameObject
+
+class Actor(GameObject):
+    def __init__(self, p_animations, pos):
+        GameObject.__init__(self, p_animations, pos)
+
+        self.motion = [0, 0]
+        self.knockback = [0, 0]
+        self.oldpos = self.rect.topleft
+
+        self.speed_slow = SPEED_SLOW
+        self.speed_norm = SPEED_NORM
+        self.speed_fast = SPEED_FAST
+        self.speed_megafast = SPEED_MEGAFAST
+
+        self.speed = self.speed_norm
+
+        self.knockback_timer = 0
+        self.invincibility_frames = 0
+
+    def hit(self, target):
+        if target.invincibility_frames > 0:
+            return
+        target.get_damage(self.damage)
+        if not (self.motion[0] == 0 and self.motion[1] == 0):
+            kb = self.motion
+        else:
+            kb = [-1*i for i in target.motion]
+        target.get_knockback(kb)
+
+    def get_damage(self, damage):
+        self.hp -= damage
+
+    def get_knockback(self, motion):
+        self.knockback = motion
+        self.knockback_timer = 8
+
+    def move(self):
+        self.oldpos = self.rect.topleft
+        if self.knockback_timer > 0:
+            self.knockback_timer -= 1
+            self.rect.move_ip(self.knockback[0]*self.speed_megafast, self.knockback[1]*self.speed_megafast)
+        else:
+            self.rect.move_ip(self.motion[0]*self.speed, self.motion[1]*self.speed)
+
+    def coll_obstacle(self, obstacle):
+        self.rect.topleft = self.oldpos
+
+    def update(self):
+        self.invincibility_frames -= 1 if self.invincibility_frames > 0 else 0
diff --git a/nanoassault/animation.py b/nanoassault/animation.py
new file mode 100644
index 0000000..ffe6c03
--- /dev/null
+++ b/nanoassault/animation.py
@@ -0,0 +1,39 @@
+# ~*~ coding: utf-8 ~*~
+
+# (C) 2017, Eike Jesinghaus
+# 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/>.
+
+import os
+
+from .constants import SCALEFAC
+
+import pygame
+
+class Animation(object):
+    def __init__(self, frame_names, speed):
+        self.frame_names = frame_names
+        self.frames = [pygame.image.load(os.path.join(os.path.dirname(__file__), "img", "%s.png" % f)) for f in self.frame_names]
+        self.frames = [pygame.transform.scale(f, (f.get_width()*SCALEFAC, f.get_height()*SCALEFAC)) for f in self.frames]
+        self.frame = 0
+        self.frame_timer = 0
+        self.speed = speed
+
+    def tick(self, factor=1):
+        self.frame_timer += factor
+        if self.frame_timer >= self.speed:
+            self.frame_timer = 0
+            self.frame += 1
+            if self.frame == len(self.frames):
+                self.frame = 0
+        return self.frames[self.frame]
diff --git a/nanoassault/animations.py b/nanoassault/animations.py
new file mode 100644
index 0000000..186d4a8
--- /dev/null
+++ b/nanoassault/animations.py
@@ -0,0 +1,29 @@
+# ~*~ coding: utf-8 ~*~
+
+# (C) 2017, Eike Jesinghaus
+# 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/>.
+
+from .animation import Animation
+
+anim_player_walking = Animation(("player_walking0", "player_walking1", "player_walking2", "player_walking3", "player_walking2", "player_walking1"), 10)
+animations_player = (anim_player_walking,)
+
+def animations_enemy_coccusdesertus(): return (Animation(("enemy_coccusdesertus_walking0", "enemy_coccusdesertus_walking1"), 6),
+                                               Animation(("enemy_coccusdesertus_walking0",), 0),)
+def animations_enemy_coccusiactans(): return (Animation(("enemy_coccusiactans_walking0",), 0),
+                                              Animation(("enemy_coccusiactans_standing0",), 0),)
+def animations_boss_coccusimmanis(): return (Animation(("boss_coccusimmanis_walking0",), 0),
+                                             Animation(("boss_coccusimmanis_walking1",), 0),)
+def animations_enemy_bacillusceler(): return (Animation(("enemy_bacillusceler_walking0",), 0),
+                                             Animation(("enemy_bacillusceler_walking1",), 0),)
diff --git a/nanoassault/bullet.py b/nanoassault/bullet.py
new file mode 100644
index 0000000..e2f8757
--- /dev/null
+++ b/nanoassault/bullet.py
@@ -0,0 +1,38 @@
+# ~*~ coding: utf-8 ~*~
+
+# (C) 2017, Eike Jesinghaus
+# 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/>.
+
+from .actor import Actor
+from .animation import Animation
+
+class Bullet(Actor):
+    def __init__(self, image, pos, motion, timer, damage):
+        Actor.__init__(self, (Animation((image,), 0),), pos)
+        self.rect.center = pos
+
+        self.motion = motion
+        self.speed = self.speed_fast
+        self.timer = timer
+        self.damage = damage
+
+        self.byplayer = False
+
+    def update(self):
+        self.timer -= 1
+        if self.timer == 0:
+            self.kill()
+            return
+        self.move()
+        self.update_image()
diff --git a/nanoassault/bullets.py b/nanoassault/bullets.py
new file mode 100644
index 0000000..db4826c
--- /dev/null
+++ b/nanoassault/bullets.py
@@ -0,0 +1,33 @@
+# ~*~ coding: utf-8 ~*~
+
+# (C) 2017, Eike Jesinghaus
+# 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/>.
+
+from .bullet import Bullet
+
+class BulletPlayer(Bullet):
+    def __init__(self, pos, motion):
+        Bullet.__init__(self, "bullet_player0", pos, motion, 60, 3)
+        self.speed = self.speed_fast
+        self.byplayer = True
+
+class BulletEnemy0(Bullet):
+    def __init__(self, pos, motion):
+        Bullet.__init__(self, "bullet_enemy0", pos, motion, 60, 1)
+        self.speed = self.speed_norm
+
+class BulletEnemy1(BulletEnemy0):
+    def __init__(self, pos, motion):
+        BulletEnemy0.__init__(self, pos, motion)
+        self.speed = self.speed_fast
\ No newline at end of file
diff --git a/nanoassault/collectible.py b/nanoassault/collectible.py
new file mode 100644
index 0000000..0eacb60
--- /dev/null
+++ b/nanoassault/collectible.py
@@ -0,0 +1,26 @@
+# ~*~ coding: utf-8 ~*~
+
+# (C) 2017, Eike Jesinghaus
+# 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/>.
+
+from .animation import Animation
+from .constants import SCALEFAC
+from .gameobject import GameObject
+
+class Collectible(GameObject):
+    def __init__(self, image, pos):
+        GameObject.__init__(self, (Animation((image,), 0),), (pos[0]*16*SCALEFAC, pos[1]*16*SCALEFAC))
+
+    def on_collect(self, player):
+        pass
diff --git a/nanoassault/collectibles.py b/nanoassault/collectibles.py
new file mode 100644
index 0000000..38d4321
--- /dev/null
+++ b/nanoassault/collectibles.py
@@ -0,0 +1,31 @@
+# ~*~ coding: utf-8 ~*~
+
+# (C) 2017, Eike Jesinghaus
+# 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/>.
+
+from .collectible import Collectible
+
+class Energy(Collectible):
+    def __init__(self, pos):
+        Collectible.__init__(self, "collectible_energy", pos)
+
+    def on_collect(self, player):
+        player.hp += 1
+
+class Spasmolytic(Collectible):
+    def __init__(self, pos):
+        Collectible.__init__(self, "collectible_spasmolytic", pos)
+
+    def on_collect(self, player):
+        player.keys += 1
diff --git a/nanoassault/constants.py b/nanoassault/constants.py
new file mode 100644
index 0000000..0fd5c71
--- /dev/null
+++ b/nanoassault/constants.py
@@ -0,0 +1,32 @@
+# ~*~ coding: utf-8 ~*~
+
+# (C) 2017, Eike Jesinghaus
+# 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/>.
+
+import pygame
+
+pygame.init()
+
+FPS = 60
+
+TILEX = 16
+TILEY = 12
+
+_max_mode = pygame.display.list_modes()[0]
+SCALEFAC = min((int(_max_mode[0]/(TILEX*16)), int(_max_mode[1]/(TILEY*16+8))))
+
+SPEED_SLOW = SCALEFAC / 2
+SPEED_NORM = SCALEFAC
+SPEED_FAST = SCALEFAC * 2
+SPEED_MEGAFAST = SCALEFAC * 4
diff --git a/nanoassault/dungeon.py b/nanoassault/dungeon.py
new file mode 100644
index 0000000..4bbeff7
--- /dev/null
+++ b/nanoassault/dungeon.py
@@ -0,0 +1,101 @@
+# ~*~ coding: utf-8 ~*~
+
+# (C) 2017, Eike Jesinghaus
+# 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/>.
+
+import random
+
+from .collectibles import Spasmolytic
+from .levels import LevelStart
+
+class Dungeon(object):
+    def __init__(self, theme, room_count, keylevel_increment_counter=5):
+        self.theme = theme
+        self.room_count = room_count
+        self.rooms = []
+        self.keylevel_increment_counter = keylevel_increment_counter
+
+        for i in range(0, 11):
+            self.rooms.append([None, None, None, None, None, None, None, None, None, None, None])
+
+    def generate(self, levels, bosslevels):
+        count = 0
+        keylevel = 0
+
+        self.rooms[5][5] = LevelStart(self.theme, keylevel)
+        self.rooms[5][5].label = "S"
+
+        while count < self.room_count:
+
+            parentroom = None
+            while parentroom is None:
+                y = random.randint(0, 10)
+                x = random.randint(0, 10)
+                parentroom = self.rooms[y][x]
+
+            if parentroom.keylevel != keylevel:
+                continue
+
+            adjacent = [(x, y-1, "up", "down"), (x, y+1, "down", "up"), (x-1, y, "left", "right"), (x+1, y, "right", "left")]
+            for i in adjacent:
+                if -1 in i or 11 in i:
+                    adjacent.remove(i)
+
+            adjacent_empty = []
+            for i in adjacent:
+                if self.rooms[i[1]][i[0]] is None:
+                    adjacent_empty.append(i)
+
+            if len(adjacent_empty) == 0:
+                continue
+
+            if (count > 0 and count % self.keylevel_increment_counter == 0) or count == self.room_count - 1:
+                keylevel += 1
+
+            coords = random.choice(adjacent_empty)
+            level_group = levels
+            if count == self.room_count - 1:
+                level_group = bosslevels
+            self.rooms[coords[1]][coords[0]] = random.choice(level_group)(self.theme, keylevel)
+            childroom = self.rooms[coords[1]][coords[0]]
+
+            setattr(parentroom, coords[2], (childroom, (childroom.keylevel > parentroom.keylevel)))
+            setattr(childroom, coords[3], (parentroom, False))
+
+            parentroom.children.append(childroom)
+            childroom.parent = parentroom
+
+            count = 0
+            for i in self.rooms:
+                for j in i:
+                    if j is not None:
+                        count += 1
+
+        childroom.label = "B"
+
+        keys = 0
+        while keys < keylevel:
+
+            room = None
+            while room is None:
+                y = random.randint(0, 10)
+                x = random.randint(0, 10)
+                room = self.rooms[y][x]
+
+            if room.keylevel != keys or room.label in "SB":
+                continue
+
+            room.contains = Spasmolytic(room.keypos)
+            room.label = "K"
+            keys += 1
diff --git a/nanoassault/enemies.py b/nanoassault/enemies.py
new file mode 100644
index 0000000..d6077ed
--- /dev/null
+++ b/nanoassault/enemies.py
@@ -0,0 +1,146 @@
+# ~*~ coding: utf-8 ~*~
+
+# (C) 2017, Eike Jesinghaus
+# 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/>.
+
+from random import randint
+
+from .animations import animations_enemy_coccusdesertus, animations_enemy_coccusiactans, animations_boss_coccusimmanis, animations_enemy_bacillusceler
+from .bullets import BulletEnemy0, BulletEnemy1
+from .enemy import Enemy
+
+class CoccusDesertus(Enemy):
+    def __init__(self, pos):
+        Enemy.__init__(self, "Coccus desertus", animations_enemy_coccusdesertus, pos, 5, 1)
+        self.still_counter = 60
+        self.speed = self.speed_norm
+
+    def coll_obstacle(self, obstacle):
+        Enemy.coll_obstacle(self, obstacle)
+        self.still_counter = 1
+
+    def update(self, player, bullets):
+        if self.isdead():
+            self.kill()
+            return
+
+        self.still_counter -= 1
+        if self.still_counter == 0:
+            self.motion = ((0, -1), (0, 1), (-1, 0), (1, 0))[randint(0, 3)]
+            self.change_anim(0)
+        elif self.still_counter == -80:
+            self.motion = (0, 0)
+            self.still_counter = 30
+            self.change_anim(1)
+
+        self.move()
+        self.update_image()
+
+class CoccusIactans(Enemy):
+    def __init__(self, pos):
+        Enemy.__init__(self, "Coccus iactans", animations_enemy_coccusiactans, pos, 8, 1)
+        self.still_counter = 60
+
+    def coll_obstacle(self, obstacle):
+        Enemy.coll_obstacle(self, obstacle)
+        self.still_counter = 1
+
+    def update(self, player, bullets):
+        if self.isdead():
+            self.kill()
+            return
+
+        self.still_counter -= 1
+        if self.still_counter == 0:
+            self.motion = ((-1, -1), (1, 1), (-1, 1), (1, -1))[randint(0, 3)]
+            self.change_anim(0)
+        elif self.still_counter == -80:
+            self.motion = (0, 0)
+            self.still_counter = 60
+            self.change_anim(1)
+            bullets.add(BulletEnemy1(self.rect.center, (0, 1)))
+            bullets.add(BulletEnemy1(self.rect.center, (0, -1)))
+            bullets.add(BulletEnemy1(self.rect.center, (1, 0)))
+            bullets.add(BulletEnemy1(self.rect.center, (-1, 0)))
+
+
+        self.move()
+        self.update_image()
+
+class CoccusImmanis(Enemy):
+    def __init__(self, pos):
+        Enemy.__init__(self, "Coccus immanis", animations_boss_coccusimmanis, pos, 26, 1)
+        self.speed = self.speed_fast
+        self.rotation_timer = 40
+        self.rot = 0
+        self.shot_timer = 0
+
+    def coll_obtacle(self, obstacle):
+        Enemy.coll_obstacle(self, obstacle)
+        self.motion = ((-1, 0), (1, 0), (0, -1), (0, 1))[randint(0, 1)+2*self.rot]
+
+    def update(self, player, bullets):
+        if self.isdead():
+            self.kill()
+            return
+
+        self.rotation_timer -= 1
+        if self.rotation_timer == 0:
+            self.rot = (self.rot+1)%2
+            self.change_anim(self.rot)
+            self.rotation_timer = 40
+            self.shot_timer = 15
+            self.motion = ((-1, 0), (1, 0), (0, -1), (0, 1))[randint(0, 1)+2*self.rot]
+
+        if self.shot_timer:
+            self.shot_timer -= 1
+            if self.shot_timer % 5 == 0:
+                if self.rot == 0:
+                    bullets.add(BulletEnemy1(self.rect.center, (0, 1)))
+                    bullets.add(BulletEnemy1(self.rect.center, (0, -1)))
+                elif self.rot == 1:
+                    bullets.add(BulletEnemy1(self.rect.center, (1, 0)))
+                    bullets.add(BulletEnemy1(self.rect.center, (-1, 0)))
+                
+
+        self.move()
+        self.update_image()
+
+class BacillusCeler(Enemy):
+    def __init__(self, pos):
+        Enemy.__init__(self, "Bacillus celer", animations_enemy_bacillusceler, pos, 3, 1)
+        self.speed = self.speed_megafast
+        self.dtimer = 40
+
+    def coll_obstacle(self, obstacle):
+        Enemy.coll_obstacle(self, obstacle)
+        self.motion = ((0, 1), (0, -1), (1, 0), (-1, 0))[randint(0, 3)]
+
+    def update(self, player, bullets):
+        if self.isdead():
+            self.kill()
+            return
+
+        self.dtimer -= 1
+        if self.dtimer == 0:
+            self.dtimer = 40
+            self.motion = ((0, 1), (0, -1), (1, 0), (-1, 0))[randint(0, 3)]
+
+        if self.motion[1] == 0:
+            self.change_anim(1)
+        else:
+            self.change_anim(0)
+
+        self.move()
+        self.update_image()
diff --git a/nanoassault/enemy.py b/nanoassault/enemy.py
new file mode 100644
index 0000000..31157c5
--- /dev/null
+++ b/nanoassault/enemy.py
@@ -0,0 +1,34 @@
+# ~*~ coding: utf-8 ~*~
+
+# (C) 2017, Eike Jesinghaus
+# 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/>.
+
+from .actor import Actor
+
+class Enemy(Actor):
+    def __init__(self, name, animations, pos, hp, contact_damage):
+        Actor.__init__(self, animations(), pos)
+        self.name = name
+
+        self.hp = hp
+        self.damage = contact_damage
+
+    def isdead(self):
+        return self.hp <= 0
+
+    def contact(self, player):
+        self.hit(player)
+
+    def update(self, player, bullets):
+        pass
diff --git a/nanoassault/gameobject.py b/nanoassault/gameobject.py
new file mode 100644
index 0000000..75bab4e
--- /dev/null
+++ b/nanoassault/gameobject.py
@@ -0,0 +1,39 @@
+# ~*~ coding: utf-8 ~*~
+
+# (C) 2017, Eike Jesinghaus
+# 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/>.
+
+import pygame
+
+class GameObject(pygame.sprite.Sprite):
+    def __init__(self, p_animations, pos):
+        pygame.sprite.Sprite.__init__(self)
+        self.animations = p_animations
+        self.anim_index = 0
+        self.animation = self.animations[self.anim_index]
+        self.image = self.animation.tick(0)
+        self.rect = self.image.get_rect()
+        self.rect.topleft = pos
+
+    def update(self):
+        pass
+
+    def change_anim(self, anim_index):
+        if self.anim_index == anim_index:
+            return
+        self.anim_index = anim_index
+        self.animation = self.animations[self.anim_index]
+
+    def update_image(self):
+        self.image = self.animation.tick()
diff --git a/nanoassault/img/boss_coccusimmanis_walking0.png b/nanoassault/img/boss_coccusimmanis_walking0.png
new file mode 100644
index 0000000..c840335
Binary files /dev/null and b/nanoassault/img/boss_coccusimmanis_walking0.png differ
diff --git a/nanoassault/img/boss_coccusimmanis_walking1.png b/nanoassault/img/boss_coccusimmanis_walking1.png
new file mode 100644
index 0000000..0affe45
Binary files /dev/null and b/nanoassault/img/boss_coccusimmanis_walking1.png differ
diff --git a/nanoassault/img/bullet_enemy0.png b/nanoassault/img/bullet_enemy0.png
new file mode 100644
index 0000000..033a99c
Binary files /dev/null and b/nanoassault/img/bullet_enemy0.png differ
diff --git a/nanoassault/img/bullet_player0.png b/nanoassault/img/bullet_player0.png
new file mode 100644
index 0000000..fbc3f00
Binary files /dev/null and b/nanoassault/img/bullet_player0.png differ
diff --git a/nanoassault/img/collectible_energy.png b/nanoassault/img/collectible_energy.png
new file mode 100644
index 0000000..884bf99
Binary files /dev/null and b/nanoassault/img/collectible_energy.png differ
diff --git a/nanoassault/img/collectible_spasmolytic.png b/nanoassault/img/collectible_spasmolytic.png
new file mode 100644
index 0000000..bb5d8c9
Binary files /dev/null and b/nanoassault/img/collectible_spasmolytic.png differ
diff --git a/nanoassault/img/enemy_bacillusceler_walking0.png b/nanoassault/img/enemy_bacillusceler_walking0.png
new file mode 100644
index 0000000..108b323
Binary files /dev/null and b/nanoassault/img/enemy_bacillusceler_walking0.png differ
diff --git a/nanoassault/img/enemy_bacillusceler_walking1.png b/nanoassault/img/enemy_bacillusceler_walking1.png
new file mode 100644
index 0000000..a9c08ba
Binary files /dev/null and b/nanoassault/img/enemy_bacillusceler_walking1.png differ
diff --git a/nanoassault/img/enemy_coccusdesertus_walking0.png b/nanoassault/img/enemy_coccusdesertus_walking0.png
new file mode 100644
index 0000000..825d2e5
Binary files /dev/null and b/nanoassault/img/enemy_coccusdesertus_walking0.png differ
diff --git a/nanoassault/img/enemy_coccusdesertus_walking1.png b/nanoassault/img/enemy_coccusdesertus_walking1.png
new file mode 100644
index 0000000..63014be
Binary files /dev/null and b/nanoassault/img/enemy_coccusdesertus_walking1.png differ
diff --git a/nanoassault/img/enemy_coccusiactans.png b/nanoassault/img/enemy_coccusiactans.png
new file mode 100644
index 0000000..788eef1
Binary files /dev/null and b/nanoassault/img/enemy_coccusiactans.png differ
diff --git a/nanoassault/img/enemy_coccusiactans_standing0.png b/nanoassault/img/enemy_coccusiactans_standing0.png
new file mode 100644
index 0000000..60fe53c
Binary files /dev/null and b/nanoassault/img/enemy_coccusiactans_standing0.png differ
diff --git a/nanoassault/img/enemy_coccusiactans_walking0.png b/nanoassault/img/enemy_coccusiactans_walking0.png
new file mode 100644
index 0000000..18990c4
Binary files /dev/null and b/nanoassault/img/enemy_coccusiactans_walking0.png differ
diff --git a/nanoassault/img/intro.png b/nanoassault/img/intro.png
new file mode 100644
index 0000000..9778936
Binary files /dev/null and b/nanoassault/img/intro.png differ
diff --git a/nanoassault/img/level_fleshy_bottom.png b/nanoassault/img/level_fleshy_bottom.png
new file mode 100644
index 0000000..08f7bbc
Binary files /dev/null and b/nanoassault/img/level_fleshy_bottom.png differ
diff --git a/nanoassault/img/level_fleshy_bottomclosed0.png b/nanoassault/img/level_fleshy_bottomclosed0.png
new file mode 100644
index 0000000..466be2a
Binary files /dev/null and b/nanoassault/img/level_fleshy_bottomclosed0.png differ
diff --git a/nanoassault/img/level_fleshy_bottomdoor0.png b/nanoassault/img/level_fleshy_bottomdoor0.png
new file mode 100644
index 0000000..9192700
Binary files /dev/null and b/nanoassault/img/level_fleshy_bottomdoor0.png differ
diff --git a/nanoassault/img/level_fleshy_bottomleft.png b/nanoassault/img/level_fleshy_bottomleft.png
new file mode 100644
index 0000000..4bb365b
Binary files /dev/null and b/nanoassault/img/level_fleshy_bottomleft.png differ
diff --git a/nanoassault/img/level_fleshy_bottomlocked0.png b/nanoassault/img/level_fleshy_bottomlocked0.png
new file mode 100644
index 0000000..e25bff0
Binary files /dev/null and b/nanoassault/img/level_fleshy_bottomlocked0.png differ
diff --git a/nanoassault/img/level_fleshy_bottomright.png b/nanoassault/img/level_fleshy_bottomright.png
new file mode 100644
index 0000000..3563db0
Binary files /dev/null and b/nanoassault/img/level_fleshy_bottomright.png differ
diff --git a/nanoassault/img/level_fleshy_ground.png b/nanoassault/img/level_fleshy_ground.png
new file mode 100644
index 0000000..e759f22
Binary files /dev/null and b/nanoassault/img/level_fleshy_ground.png differ
diff --git a/nanoassault/img/level_fleshy_left.png b/nanoassault/img/level_fleshy_left.png
new file mode 100644
index 0000000..14bbfc2
Binary files /dev/null and b/nanoassault/img/level_fleshy_left.png differ
diff --git a/nanoassault/img/level_fleshy_leftclosed0.png b/nanoassault/img/level_fleshy_leftclosed0.png
new file mode 100644
index 0000000..b2bd8c7
Binary files /dev/null and b/nanoassault/img/level_fleshy_leftclosed0.png differ
diff --git a/nanoassault/img/level_fleshy_leftdoor0.png b/nanoassault/img/level_fleshy_leftdoor0.png
new file mode 100644
index 0000000..c9e3f49
Binary files /dev/null and b/nanoassault/img/level_fleshy_leftdoor0.png differ
diff --git a/nanoassault/img/level_fleshy_leftlocked0.png b/nanoassault/img/level_fleshy_leftlocked0.png
new file mode 100644
index 0000000..58009c8
Binary files /dev/null and b/nanoassault/img/level_fleshy_leftlocked0.png differ
diff --git a/nanoassault/img/level_fleshy_right.png b/nanoassault/img/level_fleshy_right.png
new file mode 100644
index 0000000..c2de2d3
Binary files /dev/null and b/nanoassault/img/level_fleshy_right.png differ
diff --git a/nanoassault/img/level_fleshy_rightclosed0.png b/nanoassault/img/level_fleshy_rightclosed0.png
new file mode 100644
index 0000000..f5ac283
Binary files /dev/null and b/nanoassault/img/level_fleshy_rightclosed0.png differ
diff --git a/nanoassault/img/level_fleshy_rightdoor0.png b/nanoassault/img/level_fleshy_rightdoor0.png
new file mode 100644
index 0000000..c06a75e
Binary files /dev/null and b/nanoassault/img/level_fleshy_rightdoor0.png differ
diff --git a/nanoassault/img/level_fleshy_rightlocked0.png b/nanoassault/img/level_fleshy_rightlocked0.png
new file mode 100644
index 0000000..b7cc41a
Binary files /dev/null and b/nanoassault/img/level_fleshy_rightlocked0.png differ
diff --git a/nanoassault/img/level_fleshy_top.png b/nanoassault/img/level_fleshy_top.png
new file mode 100644
index 0000000..7288322
Binary files /dev/null and b/nanoassault/img/level_fleshy_top.png differ
diff --git a/nanoassault/img/level_fleshy_topclosed0.png b/nanoassault/img/level_fleshy_topclosed0.png
new file mode 100644
index 0000000..2326f35
Binary files /dev/null and b/nanoassault/img/level_fleshy_topclosed0.png differ
diff --git a/nanoassault/img/level_fleshy_topdoor0.png b/nanoassault/img/level_fleshy_topdoor0.png
new file mode 100644
index 0000000..810ca79
Binary files /dev/null and b/nanoassault/img/level_fleshy_topdoor0.png differ
diff --git a/nanoassault/img/level_fleshy_topleft.png b/nanoassault/img/level_fleshy_topleft.png
new file mode 100644
index 0000000..768bce4
Binary files /dev/null and b/nanoassault/img/level_fleshy_topleft.png differ
diff --git a/nanoassault/img/level_fleshy_toplocked0.png b/nanoassault/img/level_fleshy_toplocked0.png
new file mode 100644
index 0000000..3164603
Binary files /dev/null and b/nanoassault/img/level_fleshy_toplocked0.png differ
diff --git a/nanoassault/img/level_fleshy_topright.png b/nanoassault/img/level_fleshy_topright.png
new file mode 100644
index 0000000..bc352c8
Binary files /dev/null and b/nanoassault/img/level_fleshy_topright.png differ
diff --git a/nanoassault/img/player_walking0.png b/nanoassault/img/player_walking0.png
new file mode 100644
index 0000000..5e32bbe
Binary files /dev/null and b/nanoassault/img/player_walking0.png differ
diff --git a/nanoassault/img/player_walking1.png b/nanoassault/img/player_walking1.png
new file mode 100644
index 0000000..a3b01d2
Binary files /dev/null and b/nanoassault/img/player_walking1.png differ
diff --git a/nanoassault/img/player_walking2.png b/nanoassault/img/player_walking2.png
new file mode 100644
index 0000000..ad0af70
Binary files /dev/null and b/nanoassault/img/player_walking2.png differ
diff --git a/nanoassault/img/player_walking3.png b/nanoassault/img/player_walking3.png
new file mode 100644
index 0000000..a080824
Binary files /dev/null and b/nanoassault/img/player_walking3.png differ
diff --git a/nanoassault/img/titlescreen.png b/nanoassault/img/titlescreen.png
new file mode 100644
index 0000000..76d0876
Binary files /dev/null and b/nanoassault/img/titlescreen.png differ
diff --git a/nanoassault/img/ui_heart.png b/nanoassault/img/ui_heart.png
new file mode 100644
index 0000000..8d8d189
Binary files /dev/null and b/nanoassault/img/ui_heart.png differ
diff --git a/nanoassault/level.py b/nanoassault/level.py
new file mode 100644
index 0000000..825ff24
--- /dev/null
+++ b/nanoassault/level.py
@@ -0,0 +1,132 @@
+# ~*~ coding: utf-8 ~*~
+
+# (C) 2017, Eike Jesinghaus
+# 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/>.
+
+from .constants import SCALEFAC, TILEX, TILEY
+from .wall import Wall
+
+import os
+
+import pygame
+
+class Level(object):
+    def __init__(self, theme, walls, enemies, keylevel, contains=None):
+        self.theme = theme
+        self.walls = list(walls)
+        self.enemies = enemies
+
+        self.keylevel = keylevel
+        self.parent = None
+        self.children = []
+
+        self.up = None
+        self.down = None
+        self.left = None
+        self.right = None
+
+        self.cleared = False
+        self.unlocked = False
+
+        self.contains = contains
+
+        self.label = "O"
+
+        self.keypos = (7.5, 5.5)
+
+    def generate_walls(self):
+        walls = [("topleft", (0, 0)), ("topright", (16*(TILEX-1)*SCALEFAC, 0)), ("bottomleft", (0, 16*(TILEY-1)*SCALEFAC)), ("bottomright", (16*(TILEX-1)*SCALEFAC, 16*(TILEY-1)*SCALEFAC))] + self.walls
+
+        for i in range(1, TILEX-1):
+            if not (i in (TILEX/2, TILEX/2-1) and self.up):
+                walls += [("top", (16*i*SCALEFAC, 0))]
+            if not (i in (TILEX/2, TILEX/2-1) and self.down):
+                walls += [("bottom", (16*i*SCALEFAC, 16*(TILEY-1)*SCALEFAC))]
+
+        for i in range(1, TILEY-1):
+            if not (i in (TILEY/2, TILEY/2-1) and self.left):
+                walls += [("left", (0, 16*i*SCALEFAC))]
+            if not (i in (TILEY/2, TILEY/2-1) and self.right):
+                walls += [("right", (16*(TILEX-1)*SCALEFAC, 16*i*SCALEFAC))]
+
+        walls = [Wall("level_%s_%s" % (self.theme, w[0]), w[1]) for w in walls]
+
+        return walls
+
+    def generate_enemies(self):
+        return [e[0]((e[1][0]*16*SCALEFAC, e[1][1]*16*SCALEFAC), *e[2:]) for e in self.enemies] if not self.cleared else []
+
+    def generate_bg(self):
+        bg = pygame.Surface((16*TILEX*SCALEFAC, 16*TILEY*SCALEFAC))
+
+        bgimg = pygame.image.load(os.path.join(os.path.dirname(__file__), "img", "level_%s_ground.png" % self.theme))
+        bgimg = pygame.transform.scale(bgimg, (bgimg.get_width()*SCALEFAC, bgimg.get_height()*SCALEFAC))
+
+        upimg = pygame.image.load(os.path.join(os.path.dirname(__file__), "img", "level_%s_topdoor0.png" % self.theme))
+        downimg = pygame.image.load(os.path.join(os.path.dirname(__file__), "img", "level_%s_bottomdoor0.png" % self.theme))
+        leftimg = pygame.image.load(os.path.join(os.path.dirname(__file__), "img", "level_%s_leftdoor0.png" % self.theme))
+        rightimg = pygame.image.load(os.path.join(os.path.dirname(__file__), "img", "level_%s_rightdoor0.png" % self.theme))
+
+        upimg = pygame.transform.scale(upimg, (upimg.get_width()*SCALEFAC, upimg.get_height()*SCALEFAC))
+        downimg = pygame.transform.scale(downimg, (downimg.get_width()*SCALEFAC, downimg.get_height()*SCALEFAC))
+        leftimg = pygame.transform.scale(leftimg, (leftimg.get_width()*SCALEFAC, leftimg.get_height()*SCALEFAC))
+        rightimg = pygame.transform.scale(rightimg, (rightimg.get_width()*SCALEFAC, rightimg.get_height()*SCALEFAC))
+
+        for y in range(0, TILEY):
+            for x in range(0, TILEX):
+                bg.blit(bgimg, (16*x*SCALEFAC, 16*y*SCALEFAC))
+
+        if self.up:
+            bg.blit(upimg, (16*SCALEFAC*(TILEX/2-1), 0))
+        if self.down:
+            bg.blit(downimg, (16*SCALEFAC*(TILEX/2-1), 16*SCALEFAC*(TILEY-1)))
+        if self.left:
+            bg.blit(leftimg, (0, 16*SCALEFAC*(TILEY/2-1)))
+        if self.right:
+            bg.blit(rightimg, (16*SCALEFAC*(TILEX-1), 16*SCALEFAC*(TILEY/2-1)))
+
+        return bg
+
+    def generate_doors(self):
+        doors = []
+        if self.up:
+            if self.up[1] and not self.unlocked:
+                doors.append(Wall("level_%s_toplocked0" % self.theme, (16*SCALEFAC*(TILEX/2-1), 0), 1))
+            elif not self.cleared:
+                doors.append(Wall("level_%s_topclosed0" % self.theme, (16*SCALEFAC*(TILEX/2-1), 0), 2))
+        if self.down:
+            if self.down[1] and not self.unlocked:
+                doors.append(Wall("level_%s_bottomlocked0" % self.theme, (16*SCALEFAC*(TILEX/2-1), 16*SCALEFAC*(TILEY-1)), 1))
+            elif not self.cleared:
+                doors.append(Wall("level_%s_bottomclosed0" % self.theme, (16*SCALEFAC*(TILEX/2-1), 16*SCALEFAC*(TILEY-1)), 2))
+        if self.left:
+            if self.left[1] and not self.unlocked:
+                doors.append(Wall("level_%s_leftlocked0" % self.theme, (0, 16*SCALEFAC*(TILEY/2-1)), 1))
+            elif not self.cleared:
+                doors.append(Wall("level_%s_leftclosed0" % self.theme, (0, 16*SCALEFAC*(TILEY/2-1)), 2))
+        if self.right:
+            if self.right[1] and not self.unlocked:
+                doors.append(Wall("level_%s_rightlocked0" % self.theme, (16*SCALEFAC*(TILEX-1), 16*SCALEFAC*(TILEY/2-1)), 1))
+            elif not self.cleared:
+                doors.append(Wall("level_%s_rightclosed0" % self.theme, (16*SCALEFAC*(TILEX-1), 16*SCALEFAC*(TILEY/2-1)), 2))
+        return doors
+
+
+    def clear(self, collectibles, doors):
+        self.cleared = True
+        if self.contains:
+            collectibles.add(self.contains)
+        for d in doors:
+            if d.door == 2:
+                d.kill()
diff --git a/nanoassault/levels.py b/nanoassault/levels.py
new file mode 100644
index 0000000..1938a8d
--- /dev/null
+++ b/nanoassault/levels.py
@@ -0,0 +1,63 @@
+# ~*~ coding: utf-8 ~*~
+
+# (C) 2017, Eike Jesinghaus
+# 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/>.
+
+from .collectibles import Energy
+from .enemies import CoccusDesertus, CoccusIactans, CoccusImmanis, BacillusCeler
+from .level import Level
+
+class LevelStart(Level):
+    def __init__(self, theme, keylevel):
+        Level.__init__(self, theme, (), (), keylevel)
+
+class LevelCDCorner(Level):
+    def __init__(self, theme, keylevel):
+        Level.__init__(self, theme, (), ((CoccusDesertus, (2, 2)), (CoccusDesertus, (13, 2)), (CoccusDesertus, (2, 9)), (CoccusDesertus, (13, 9))), keylevel)
+
+class LevelCIMid(Level):
+    def __init__(self, theme, keylevel):
+        Level.__init__(self, theme, (), ((CoccusIactans, (7.5, 5.5)),), keylevel)
+
+class LevelCITwo(Level):
+    def __init__(self, theme, keylevel):
+        Level.__init__(self, theme, (), ((CoccusIactans, (6, 5)), (CoccusIactans, (9, 5))), keylevel)
+
+class LevelCICD(Level):
+    def __init__(self, theme, keylevel):
+        Level.__init__(self, theme, (), ((CoccusDesertus, (4, 4)), (CoccusDesertus, (11, 4)), (CoccusDesertus, (4, 7)), (CoccusDesertus, (11, 7)), (CoccusIactans, (7.5, 5.5))), keylevel, Energy((7.5, 5.5)))
+
+class LevelBossCI(Level):
+    def __init__(self, theme, keylevel):
+        Level.__init__(self, theme, (), ((CoccusImmanis, (7, 5)),), keylevel)
+
+class LevelBC(Level):
+    def __init__(self, theme, keylevel):
+        Level.__init__(self, theme, (), ((BacillusCeler, (7, 5)),), keylevel)
+
+class LevelBCCD(Level):
+    def __init__(self, theme, keylevel):
+        Level.__init__(self, theme, (), ((BacillusCeler, (7, 5)), (CoccusDesertus, (8, 5))), keylevel)
+
+class LevelBCThree(Level):
+    def __init__(self, theme, keylevel):
+        Level.__init__(self, theme, (), ((BacillusCeler, (5, 5)), (BacillusCeler, (7, 5)), (BacillusCeler, (9, 5))), keylevel)
+
+ALL_LEVELS = []
+BOSS_LEVELS = []
+for i in Level.__subclasses__():
+    if i.__name__.startswith("LevelBoss"):
+        BOSS_LEVELS.append(i)
+    else:
+        ALL_LEVELS.append(i)
diff --git a/nanoassault/player.py b/nanoassault/player.py
new file mode 100644
index 0000000..dda4574
--- /dev/null
+++ b/nanoassault/player.py
@@ -0,0 +1,44 @@
+# ~*~ coding: utf-8 ~*~
+
+# 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/>.
+
+from .actor import Actor
+from .animations import animations_player
+
+class Player(Actor):
+    def __init__(self, pos):
+        Actor.__init__(self, animations_player, pos)
+
+        self.hp = 5
+
+        self.keys = 0
+
+        self.bullet_cooldown = 0
+
+    def isdead(self):
+        return self.hp <= 0
+
+    def get_damage(self, damage):
+        self.invincibility_frames = 60
+        Actor.get_damage(self, damage)
+
+    def update(self):
+        if self.isdead():
+            return False
+        if self.bullet_cooldown:
+            self.bullet_cooldown -= 1
+        self.move()
+        self.update_image()
+        Actor.update(self)
+        return True
diff --git a/nanoassault/run_dungeon.py b/nanoassault/run_dungeon.py
new file mode 100644
index 0000000..961f89e
--- /dev/null
+++ b/nanoassault/run_dungeon.py
@@ -0,0 +1,35 @@
+# ~*~ coding: utf-8 ~*~
+
+# (C) 2017, Eike Jesinghaus
+# 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/>.
+
+from .run_level import run_level
+
+import os
+
+import pygame
+pygame.mixer.pre_init(44100, -16, 2, 2048)
+pygame.init()
+
+def run_dungeon(screen, dungeon, player):
+    next_level = dungeon.rooms[5][5]
+
+    pygame.mixer.music.load(os.path.join(os.path.dirname(__file__), "sound", "theme0.wav"))
+    pygame.mixer.music.play(-1)
+
+    while True:
+        next_level = run_level(screen, next_level, player)
+        if next_level.label == "B":
+            pygame.mixer.music.load(os.path.join(os.path.dirname(__file__), "sound", "theme1.wav"))
+            pygame.mixer.music.play(-1)
diff --git a/nanoassault/run_level.py b/nanoassault/run_level.py
new file mode 100644
index 0000000..2b88185
--- /dev/null
+++ b/nanoassault/run_level.py
@@ -0,0 +1,194 @@
+# ~*~ coding: utf-8 ~*~
+
+# (C) 2017, Eike Jesinghaus
+# 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/>.
+
+import os
+
+from .bullets import BulletPlayer
+from .collectibles import Energy
+from .constants import SCALEFAC, FPS, TILEX, TILEY
+
+import pygame
+
+
+pygame.init()
+
+def quit_():
+    exit(0)
+
+def gameover():
+    quit_()
+
+def run_level(screen, level, player):
+
+    ui_heart = pygame.image.load(os.path.join(os.path.dirname(__file__), "img", "ui_heart.png"))
+    ui_heart = pygame.transform.scale(ui_heart, (ui_heart.get_width()*SCALEFAC, ui_heart.get_height()*SCALEFAC))
+
+    sound_pickup = pygame.mixer.Sound(os.path.join(os.path.dirname(__file__), "sound", "pickup.wav"))
+    sound_open = pygame.mixer.Sound(os.path.join(os.path.dirname(__file__), "sound", "open.wav"))
+    sound_hit = pygame.mixer.Sound(os.path.join(os.path.dirname(__file__), "sound", "hit0.wav"))
+
+    clock = pygame.time.Clock()
+
+    bg = level.generate_bg()
+
+    collectibles = pygame.sprite.RenderClear()
+    doors = pygame.sprite.RenderClear()
+    players = pygame.sprite.RenderClear()
+    bullets = pygame.sprite.RenderClear()
+    enemies = pygame.sprite.RenderClear()
+    walls = pygame.sprite.RenderClear()
+
+    players.add(player)
+
+    walls.add(*level.generate_walls())
+    walls.draw(bg)
+
+    enemies.add(*level.generate_enemies())
+    doors.add(*level.generate_doors())
+
+    screen.blit(bg, (0, 0))
+
+    doors.draw(screen)
+
+    while True:
+        for event in pygame.event.get():
+            if event.type == pygame.QUIT:
+                quit_()
+            elif event.type == pygame.KEYDOWN:
+                if event.key == pygame.K_ESCAPE:
+                    quit_()
+                elif event.key == pygame.K_w:
+                    player.motion[1] = -1
+                elif event.key == pygame.K_s:
+                    player.motion[1] = 1
+                elif event.key == pygame.K_a:
+                    player.motion[0] = -1
+                elif event.key == pygame.K_d:
+                    player.motion[0] = 1
+                elif event.key == pygame.K_UP and not player.bullet_cooldown:
+                    bullets.add(BulletPlayer(player.rect.center, (0, -1)))
+                    player.bullet_cooldown = 30
+                elif event.key == pygame.K_DOWN and not player.bullet_cooldown:
+                    bullets.add(BulletPlayer(player.rect.center, (0, 1)))
+                    player.bullet_cooldown = 30
+                elif event.key == pygame.K_LEFT and not player.bullet_cooldown:
+                    bullets.add(BulletPlayer(player.rect.center, (-1, 0)))
+                    player.bullet_cooldown = 30
+                elif event.key == pygame.K_RIGHT and not player.bullet_cooldown:
+                    bullets.add(BulletPlayer(player.rect.center, (1, 0)))
+                    player.bullet_cooldown = 30
+
+            elif event.type == pygame.KEYUP:
+                if event.key == pygame.K_w:
+                    player.motion[1] = 0
+                    if pygame.key.get_pressed()[pygame.K_s]:
+                        player.motion[1] = 1
+                elif event.key == pygame.K_s:
+                    player.motion[1] = 0
+                    if pygame.key.get_pressed()[pygame.K_w]:
+                        player.motion[1] = -1
+                elif event.key == pygame.K_a:
+                    player.motion[0] = 0
+                    if pygame.key.get_pressed()[pygame.K_d]:
+                        player.motion[0] = 1
+                elif event.key == pygame.K_d:
+                    player.motion[0] = 0
+                    if pygame.key.get_pressed()[pygame.K_a]:
+                        player.motion[0] = -1
+
+        doors.clear(screen, bg)
+        collectibles.clear(screen, bg)
+        enemies.clear(screen, bg)
+        players.clear(screen, bg)
+        bullets.clear(screen, bg)
+
+        if not player.update():
+            gameover()
+
+        for w in pygame.sprite.spritecollide(player, walls, False):
+            player.coll_obstacle(w)
+
+        for d in pygame.sprite.spritecollide(player, doors, False):
+            player.coll_obstacle(d)
+            if level.cleared and player.keys > 0:
+                sound_open.play()
+                player.keys -= 1
+                d.kill()
+                level.unlocked = True
+
+        for c in pygame.sprite.spritecollide(player, collectibles, True):
+            c.on_collect(player)
+            sound_pickup.play()
+
+        if player.rect.top < 16*SCALEFAC:
+            player.rect.bottom = screen.get_height()-24*SCALEFAC
+            return level.up[0]
+        elif player.rect.left < 16*SCALEFAC:
+            player.rect.right = screen.get_width()-16*SCALEFAC
+            return level.left[0]
+        elif player.rect.bottom > screen.get_height()-24*SCALEFAC:
+            player.rect.top = 16*SCALEFAC
+            return level.down[0]
+        elif player.rect.right > screen.get_width()-16*SCALEFAC:
+            player.rect.left = 16*SCALEFAC
+            return level.right[0]
+
+        enemies.update(player, bullets)
+
+        if len(enemies) == 0 and len(collectibles) == 0:
+            if not level.cleared:
+                if len(level.enemies):
+                    sound_open.play()
+                level.clear(collectibles, doors)
+
+        for e in pygame.sprite.spritecollide(player, enemies, False):
+            sound_hit.play()
+            e.contact(player)
+
+        c = pygame.sprite.groupcollide(enemies, walls, False, False)
+        for i in c:
+            i.coll_obstacle(c[i])
+
+        c = pygame.sprite.groupcollide(enemies, doors, False, False)
+        for i in c:
+            i.coll_obstacle(c[i])
+
+        bullets.update()
+
+        c = pygame.sprite.groupcollide(bullets, enemies, False, False)
+        for i in c:
+            if i.byplayer:
+                sound_hit.play()
+                i.hit(c[i][0])
+                i.kill()
+
+        for b in pygame.sprite.spritecollide(player, bullets, False):
+            if not b.byplayer:
+                b.hit(player)
+                b.kill()
+
+        doors.draw(screen)
+        collectibles.draw(screen)
+        enemies.draw(screen)
+        players.draw(screen)
+        bullets.draw(screen)
+
+        pygame.draw.rect(screen, (10, 10, 10), (0, TILEY*16*SCALEFAC, TILEX*16*SCALEFAC, 8*SCALEFAC), 0)
+        for i in range(0, player.hp+1):
+            screen.blit(ui_heart, (i*SCALEFAC*8, TILEY*16*SCALEFAC))
+
+        pygame.display.update()
+        clock.tick_busy_loop(FPS)
diff --git a/nanoassault/sound/gameover.wav b/nanoassault/sound/gameover.wav
new file mode 100644
index 0000000..f1baf5c
Binary files /dev/null and b/nanoassault/sound/gameover.wav differ
diff --git a/nanoassault/sound/hit0.wav b/nanoassault/sound/hit0.wav
new file mode 100644
index 0000000..686e9ea
Binary files /dev/null and b/nanoassault/sound/hit0.wav differ
diff --git a/nanoassault/sound/open.wav b/nanoassault/sound/open.wav
new file mode 100644
index 0000000..9fe2f8f
Binary files /dev/null and b/nanoassault/sound/open.wav differ
diff --git a/nanoassault/sound/pickup.wav b/nanoassault/sound/pickup.wav
new file mode 100644
index 0000000..51ec2c5
Binary files /dev/null and b/nanoassault/sound/pickup.wav differ
diff --git a/nanoassault/sound/theme0.wav b/nanoassault/sound/theme0.wav
new file mode 100644
index 0000000..c37c1fa
Binary files /dev/null and b/nanoassault/sound/theme0.wav differ
diff --git a/nanoassault/sound/theme1.wav b/nanoassault/sound/theme1.wav
new file mode 100644
index 0000000..139dcd6
Binary files /dev/null and b/nanoassault/sound/theme1.wav differ
diff --git a/nanoassault/wall.py b/nanoassault/wall.py
new file mode 100644
index 0000000..20551b0
--- /dev/null
+++ b/nanoassault/wall.py
@@ -0,0 +1,23 @@
+# ~*~ coding: utf-8 ~*~
+
+# (C) 2017, Eike Jesinghaus
+# 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/>.
+
+from .animation import Animation
+from .gameobject import GameObject
+
+class Wall(GameObject):
+    def __init__(self, image, pos, door=0):
+        GameObject.__init__(self, (Animation((image,), 0),), pos)
+        self.door = door
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..6bc2ff3
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,5 @@
+[egg_info]
+tag_date = 0
+tag_build = 
+tag_svn_revision = 0
+
diff --git a/setup.py b/setup.py
new file mode 100755
index 0000000..03858cc
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+# ~*~ coding: utf-8 ~*~
+
+# (C) 2017, Eike Jesinghaus
+# 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/>.
+
+import os
+
+from setuptools import setup
+
+try:
+    from bdist_nsi import bdist_nsi
+except:
+    pass
+
+setup(
+    name='Nano-Assault',
+    version='1.0',
+    url="https://edugit.org/eike/nanoassault",
+    author="Eike Jesinghaus",
+    author_email="eike at naturalnet.de",
+    packages=['nanoassault'],
+    package_data={
+                  'nanoassault': ["img/*.png", "sound/*.wav"],
+                 },
+    zip_safe=False,
+    install_requires=[
+                      'Pygame',
+                     ],
+    entry_points={
+                  'gui_scripts': [
+                                  'nanoassault = nanoassault:main',
+                                 ],
+                 },
+    classifiers=[
+                 "Development Status :: 6 - Mature",
+                 "License :: OSI Approved :: GNU General Public License (GPL)",
+                 "Natural Language :: English",
+                 "Operating System :: OS Independent",
+                 "Programming Language :: Python",
+                 "Topic :: Games/Entertainment :: Arcade"
+                ],
+    options={"bdist_nsi": {}}
+)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/nano-assault.git



More information about the Pkg-games-commits mailing list