lauraF
3 years ago
128 changed files with 4873 additions and 0 deletions
-
10.classpath
-
17.project
-
15.settings/org.eclipse.jdt.core.prefs
-
0Textdokument.txt
-
BINaudio/laser.wav
-
BINaudio/shot.wav
-
BINaudio/smash.wav
-
BINbin/base/GameLoop.class
-
BINbin/base/MultiLevelGame.class
-
BINbin/collider/CircleCollider.class
-
BINbin/collider/Collider.class
-
BINbin/collider/RectCollider.class
-
BINbin/controller/CollisionAwareEgoController.class
-
BINbin/controller/EgoController.class
-
BINbin/controller/EnemyController.class
-
BINbin/controller/FallingStarController.class
-
BINbin/controller/LimitedTimeController.class
-
BINbin/controller/MineController.class
-
BINbin/controller/ObjectController.class
-
BINbin/controller/SimpleShotController.class
-
BINbin/controller/ZickZackController.class
-
BINbin/controller/package-info.class
-
BINbin/gameobjects/AnimatedGameobject.class
-
BINbin/gameobjects/EgoObject.class
-
BINbin/gameobjects/FallingStar.class
-
BINbin/gameobjects/GameObject.class
-
BINbin/gameobjects/RectObject.class
-
BINbin/gameobjects/TextObject.class
-
30bin/log4j2.xml
-
BINbin/playground/Animation.class
-
BINbin/playground/HighscoreManager.class
-
BINbin/playground/Level1.class
-
BINbin/playground/Level2.class
-
BINbin/playground/Level3.class
-
BINbin/playground/Level4.class
-
BINbin/playground/LevelBoss.class
-
BINbin/playground/LevelHitTwice.class
-
BINbin/playground/Music$1.class
-
BINbin/playground/Music.class
-
BINbin/playground/Playground.class
-
BINbin/playground/SaveGame.class
-
BINbin/playground/SpaceInvadersLevel.class
-
BINbin/playground/SpaceInvadersLevelTest.class
-
BINbin/rendering/AnimationArtist.class
-
BINbin/rendering/Artist.class
-
BINbin/rendering/CircleArtist.class
-
BINbin/rendering/RectArtist.class
-
BINbin/rendering/TextArtist.class
-
BINbin/ui/AboutFrame$1.class
-
BINbin/ui/AboutFrame.class
-
BINbin/ui/GamePanel.class
-
BINbin/ui/GameUI.class
-
1highscore.txt
-
202lib/apache-log4j-2.13.3-bin/LICENSE.txt
-
17lib/apache-log4j-2.13.3-bin/NOTICE.txt
-
60lib/apache-log4j-2.13.3-bin/RELEASE-NOTES.md
-
BINlib/apache-log4j-2.13.3-bin/log4j-1.2-api-2.13.3.jar
-
BINlib/apache-log4j-2.13.3-bin/log4j-api-2.13.3.jar
-
BINlib/apache-log4j-2.13.3-bin/log4j-core-2.13.3.jar
-
185log/log4j.log
-
231src/base/GameLoop.java
-
30src/base/MultiLevelGame.java
-
88src/collider/CircleCollider.java
-
127src/collider/Collider.java
-
127src/collider/RectCollider.java
-
84src/controller/CollisionAwareEgoController.java
-
216src/controller/EgoController.java
-
36src/controller/EnemyController.java
-
24src/controller/FallingStarController.java
-
36src/controller/LimitedTimeController.java
-
47src/controller/MineController.java
-
110src/controller/ObjectController.java
-
16src/controller/SimpleShotController.java
-
32src/controller/ZickZackController.java
-
11src/controller/package-info.java
-
42src/gameobjects/AnimatedGameobject.java
-
34src/gameobjects/EgoObject.java
-
28src/gameobjects/FallingStar.java
-
377src/gameobjects/GameObject.java
-
76src/gameobjects/RectObject.java
-
70src/gameobjects/TextObject.java
-
30src/log4j2.xml
-
84src/playground/Animation.java
-
55src/playground/HighscoreManager.java
-
15src/playground/Level1.java
-
17src/playground/Level2.java
-
40src/playground/Level3.java
-
63src/playground/Level4.java
-
112src/playground/LevelBoss.java
-
65src/playground/LevelHitTwice.java
-
48src/playground/Music.java
-
374src/playground/Playground.java
-
62src/playground/SaveGame.java
-
678src/playground/SpaceInvadersLevel.java
-
81src/playground/SpaceInvadersLevelTest.java
-
93src/rendering/AnimationArtist.java
-
40src/rendering/Artist.java
-
34src/rendering/CircleArtist.java
-
33src/rendering/RectArtist.java
-
81src/rendering/TextArtist.java
@ -0,0 +1,10 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<classpath> |
||||
|
<classpathentry kind="src" path="src"/> |
||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> |
||||
|
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5"/> |
||||
|
<classpathentry kind="lib" path="lib/apache-log4j-2.13.3-bin/log4j-1.2-api-2.13.3.jar"/> |
||||
|
<classpathentry kind="lib" path="lib/apache-log4j-2.13.3-bin/log4j-api-2.13.3.jar"/> |
||||
|
<classpathentry kind="lib" path="lib/apache-log4j-2.13.3-bin/log4j-core-2.13.3.jar"/> |
||||
|
<classpathentry kind="output" path="bin"/> |
||||
|
</classpath> |
@ -0,0 +1,17 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<projectDescription> |
||||
|
<name>GameProject</name> |
||||
|
<comment></comment> |
||||
|
<projects> |
||||
|
</projects> |
||||
|
<buildSpec> |
||||
|
<buildCommand> |
||||
|
<name>org.eclipse.jdt.core.javabuilder</name> |
||||
|
<arguments> |
||||
|
</arguments> |
||||
|
</buildCommand> |
||||
|
</buildSpec> |
||||
|
<natures> |
||||
|
<nature>org.eclipse.jdt.core.javanature</nature> |
||||
|
</natures> |
||||
|
</projectDescription> |
@ -0,0 +1,15 @@ |
|||||
|
eclipse.preferences.version=1 |
||||
|
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled |
||||
|
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate |
||||
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=12 |
||||
|
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve |
||||
|
org.eclipse.jdt.core.compiler.compliance=12 |
||||
|
org.eclipse.jdt.core.compiler.debug.lineNumber=generate |
||||
|
org.eclipse.jdt.core.compiler.debug.localVariable=generate |
||||
|
org.eclipse.jdt.core.compiler.debug.sourceFile=generate |
||||
|
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error |
||||
|
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled |
||||
|
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error |
||||
|
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning |
||||
|
org.eclipse.jdt.core.compiler.release=enabled |
||||
|
org.eclipse.jdt.core.compiler.source=12 |
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
|
||||
|
<configuration status="OFF"> |
||||
|
<appenders> |
||||
|
|
||||
|
<Console name="Console" target="SYSTEM_OUT"> |
||||
|
<PatternLayout pattern="%d %-5level %logger{36} - %msg%n" /> |
||||
|
</Console> |
||||
|
|
||||
|
<File name="File" fileName="log\log4j.log"> |
||||
|
<PatternLayout pattern="%d %-5level %logger{36} - %msg%n" /> |
||||
|
</File> |
||||
|
|
||||
|
</appenders> |
||||
|
|
||||
|
<loggers> |
||||
|
|
||||
|
<root level="warn"> |
||||
|
<appender-ref ref="Console" /> |
||||
|
<appender-ref ref="File" /> |
||||
|
</root> |
||||
|
|
||||
|
<Logger name="base.GameLoop" level="info"> |
||||
|
</Logger> |
||||
|
|
||||
|
<Logger name="playground" level="info"> |
||||
|
</Logger> |
||||
|
|
||||
|
</loggers> |
||||
|
</configuration> |
@ -0,0 +1 @@ |
|||||
|
22500 |
@ -0,0 +1,202 @@ |
|||||
|
|
||||
|
Apache License |
||||
|
Version 2.0, January 2004 |
||||
|
http://www.apache.org/licenses/ |
||||
|
|
||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
||||
|
|
||||
|
1. Definitions. |
||||
|
|
||||
|
"License" shall mean the terms and conditions for use, reproduction, |
||||
|
and distribution as defined by Sections 1 through 9 of this document. |
||||
|
|
||||
|
"Licensor" shall mean the copyright owner or entity authorized by |
||||
|
the copyright owner that is granting the License. |
||||
|
|
||||
|
"Legal Entity" shall mean the union of the acting entity and all |
||||
|
other entities that control, are controlled by, or are under common |
||||
|
control with that entity. For the purposes of this definition, |
||||
|
"control" means (i) the power, direct or indirect, to cause the |
||||
|
direction or management of such entity, whether by contract or |
||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the |
||||
|
outstanding shares, or (iii) beneficial ownership of such entity. |
||||
|
|
||||
|
"You" (or "Your") shall mean an individual or Legal Entity |
||||
|
exercising permissions granted by this License. |
||||
|
|
||||
|
"Source" form shall mean the preferred form for making modifications, |
||||
|
including but not limited to software source code, documentation |
||||
|
source, and configuration files. |
||||
|
|
||||
|
"Object" form shall mean any form resulting from mechanical |
||||
|
transformation or translation of a Source form, including but |
||||
|
not limited to compiled object code, generated documentation, |
||||
|
and conversions to other media types. |
||||
|
|
||||
|
"Work" shall mean the work of authorship, whether in Source or |
||||
|
Object form, made available under the License, as indicated by a |
||||
|
copyright notice that is included in or attached to the work |
||||
|
(an example is provided in the Appendix below). |
||||
|
|
||||
|
"Derivative Works" shall mean any work, whether in Source or Object |
||||
|
form, that is based on (or derived from) the Work and for which the |
||||
|
editorial revisions, annotations, elaborations, or other modifications |
||||
|
represent, as a whole, an original work of authorship. For the purposes |
||||
|
of this License, Derivative Works shall not include works that remain |
||||
|
separable from, or merely link (or bind by name) to the interfaces of, |
||||
|
the Work and Derivative Works thereof. |
||||
|
|
||||
|
"Contribution" shall mean any work of authorship, including |
||||
|
the original version of the Work and any modifications or additions |
||||
|
to that Work or Derivative Works thereof, that is intentionally |
||||
|
submitted to Licensor for inclusion in the Work by the copyright owner |
||||
|
or by an individual or Legal Entity authorized to submit on behalf of |
||||
|
the copyright owner. For the purposes of this definition, "submitted" |
||||
|
means any form of electronic, verbal, or written communication sent |
||||
|
to the Licensor or its representatives, including but not limited to |
||||
|
communication on electronic mailing lists, source code control systems, |
||||
|
and issue tracking systems that are managed by, or on behalf of, the |
||||
|
Licensor for the purpose of discussing and improving the Work, but |
||||
|
excluding communication that is conspicuously marked or otherwise |
||||
|
designated in writing by the copyright owner as "Not a Contribution." |
||||
|
|
||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity |
||||
|
on behalf of whom a Contribution has been received by Licensor and |
||||
|
subsequently incorporated within the Work. |
||||
|
|
||||
|
2. Grant of Copyright License. Subject to the terms and conditions of |
||||
|
this License, each Contributor hereby grants to You a perpetual, |
||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||
|
copyright license to reproduce, prepare Derivative Works of, |
||||
|
publicly display, publicly perform, sublicense, and distribute the |
||||
|
Work and such Derivative Works in Source or Object form. |
||||
|
|
||||
|
3. Grant of Patent License. Subject to the terms and conditions of |
||||
|
this License, each Contributor hereby grants to You a perpetual, |
||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||
|
(except as stated in this section) patent license to make, have made, |
||||
|
use, offer to sell, sell, import, and otherwise transfer the Work, |
||||
|
where such license applies only to those patent claims licensable |
||||
|
by such Contributor that are necessarily infringed by their |
||||
|
Contribution(s) alone or by combination of their Contribution(s) |
||||
|
with the Work to which such Contribution(s) was submitted. If You |
||||
|
institute patent litigation against any entity (including a |
||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work |
||||
|
or a Contribution incorporated within the Work constitutes direct |
||||
|
or contributory patent infringement, then any patent licenses |
||||
|
granted to You under this License for that Work shall terminate |
||||
|
as of the date such litigation is filed. |
||||
|
|
||||
|
4. Redistribution. You may reproduce and distribute copies of the |
||||
|
Work or Derivative Works thereof in any medium, with or without |
||||
|
modifications, and in Source or Object form, provided that You |
||||
|
meet the following conditions: |
||||
|
|
||||
|
(a) You must give any other recipients of the Work or |
||||
|
Derivative Works a copy of this License; and |
||||
|
|
||||
|
(b) You must cause any modified files to carry prominent notices |
||||
|
stating that You changed the files; and |
||||
|
|
||||
|
(c) You must retain, in the Source form of any Derivative Works |
||||
|
that You distribute, all copyright, patent, trademark, and |
||||
|
attribution notices from the Source form of the Work, |
||||
|
excluding those notices that do not pertain to any part of |
||||
|
the Derivative Works; and |
||||
|
|
||||
|
(d) If the Work includes a "NOTICE" text file as part of its |
||||
|
distribution, then any Derivative Works that You distribute must |
||||
|
include a readable copy of the attribution notices contained |
||||
|
within such NOTICE file, excluding those notices that do not |
||||
|
pertain to any part of the Derivative Works, in at least one |
||||
|
of the following places: within a NOTICE text file distributed |
||||
|
as part of the Derivative Works; within the Source form or |
||||
|
documentation, if provided along with the Derivative Works; or, |
||||
|
within a display generated by the Derivative Works, if and |
||||
|
wherever such third-party notices normally appear. The contents |
||||
|
of the NOTICE file are for informational purposes only and |
||||
|
do not modify the License. You may add Your own attribution |
||||
|
notices within Derivative Works that You distribute, alongside |
||||
|
or as an addendum to the NOTICE text from the Work, provided |
||||
|
that such additional attribution notices cannot be construed |
||||
|
as modifying the License. |
||||
|
|
||||
|
You may add Your own copyright statement to Your modifications and |
||||
|
may provide additional or different license terms and conditions |
||||
|
for use, reproduction, or distribution of Your modifications, or |
||||
|
for any such Derivative Works as a whole, provided Your use, |
||||
|
reproduction, and distribution of the Work otherwise complies with |
||||
|
the conditions stated in this License. |
||||
|
|
||||
|
5. Submission of Contributions. Unless You explicitly state otherwise, |
||||
|
any Contribution intentionally submitted for inclusion in the Work |
||||
|
by You to the Licensor shall be under the terms and conditions of |
||||
|
this License, without any additional terms or conditions. |
||||
|
Notwithstanding the above, nothing herein shall supersede or modify |
||||
|
the terms of any separate license agreement you may have executed |
||||
|
with Licensor regarding such Contributions. |
||||
|
|
||||
|
6. Trademarks. This License does not grant permission to use the trade |
||||
|
names, trademarks, service marks, or product names of the Licensor, |
||||
|
except as required for reasonable and customary use in describing the |
||||
|
origin of the Work and reproducing the content of the NOTICE file. |
||||
|
|
||||
|
7. Disclaimer of Warranty. Unless required by applicable law or |
||||
|
agreed to in writing, Licensor provides the Work (and each |
||||
|
Contributor provides its Contributions) on an "AS IS" BASIS, |
||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
||||
|
implied, including, without limitation, any warranties or conditions |
||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |
||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the |
||||
|
appropriateness of using or redistributing the Work and assume any |
||||
|
risks associated with Your exercise of permissions under this License. |
||||
|
|
||||
|
8. Limitation of Liability. In no event and under no legal theory, |
||||
|
whether in tort (including negligence), contract, or otherwise, |
||||
|
unless required by applicable law (such as deliberate and grossly |
||||
|
negligent acts) or agreed to in writing, shall any Contributor be |
||||
|
liable to You for damages, including any direct, indirect, special, |
||||
|
incidental, or consequential damages of any character arising as a |
||||
|
result of this License or out of the use or inability to use the |
||||
|
Work (including but not limited to damages for loss of goodwill, |
||||
|
work stoppage, computer failure or malfunction, or any and all |
||||
|
other commercial damages or losses), even if such Contributor |
||||
|
has been advised of the possibility of such damages. |
||||
|
|
||||
|
9. Accepting Warranty or Additional Liability. While redistributing |
||||
|
the Work or Derivative Works thereof, You may choose to offer, |
||||
|
and charge a fee for, acceptance of support, warranty, indemnity, |
||||
|
or other liability obligations and/or rights consistent with this |
||||
|
License. However, in accepting such obligations, You may act only |
||||
|
on Your own behalf and on Your sole responsibility, not on behalf |
||||
|
of any other Contributor, and only if You agree to indemnify, |
||||
|
defend, and hold each Contributor harmless for any liability |
||||
|
incurred by, or claims asserted against, such Contributor by reason |
||||
|
of your accepting any such warranty or additional liability. |
||||
|
|
||||
|
END OF TERMS AND CONDITIONS |
||||
|
|
||||
|
APPENDIX: How to apply the Apache License to your work. |
||||
|
|
||||
|
To apply the Apache License to your work, attach the following |
||||
|
boilerplate notice, with the fields enclosed by brackets "[]" |
||||
|
replaced with your own identifying information. (Don't include |
||||
|
the brackets!) The text should be enclosed in the appropriate |
||||
|
comment syntax for the file format. We also recommend that a |
||||
|
file or class name and description of purpose be included on the |
||||
|
same "printed page" as the copyright notice for easier |
||||
|
identification within third-party archives. |
||||
|
|
||||
|
Copyright 1999-2005 The Apache Software Foundation |
||||
|
|
||||
|
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
you may not use this file except in compliance with the License. |
||||
|
You may obtain a copy of the License at |
||||
|
|
||||
|
http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
|
||||
|
Unless required by applicable law or agreed to in writing, software |
||||
|
distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
See the License for the specific language governing permissions and |
||||
|
limitations under the License. |
@ -0,0 +1,17 @@ |
|||||
|
Apache Log4j |
||||
|
Copyright 1999-2017 Apache Software Foundation |
||||
|
|
||||
|
This product includes software developed at |
||||
|
The Apache Software Foundation (http://www.apache.org/). |
||||
|
|
||||
|
ResolverUtil.java |
||||
|
Copyright 2005-2006 Tim Fennell |
||||
|
|
||||
|
Dumbster SMTP test server |
||||
|
Copyright 2004 Jason Paul Kitchen |
||||
|
|
||||
|
TypeUtil.java |
||||
|
Copyright 2002-2012 Ramnivas Laddad, Juergen Hoeller, Chris Beams |
||||
|
|
||||
|
picocli (http://picocli.info) |
||||
|
Copyright 2017 Remko Popma |
@ -0,0 +1,60 @@ |
|||||
|
<!--- |
||||
|
Licensed to the Apache Software Foundation (ASF) under one or more |
||||
|
contributor license agreements. See the NOTICE file distributed with |
||||
|
this work for additional information regarding copyright ownership. |
||||
|
The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
|
(the "License"); you may not use this file except in compliance with |
||||
|
the License. You may obtain a copy of the License at |
||||
|
|
||||
|
http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
|
||||
|
Unless required by applicable law or agreed to in writing, software |
||||
|
distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
See the License for the specific language governing permissions and |
||||
|
limitations under the License. |
||||
|
--> |
||||
|
# Apache Log4j 2.13.3 Release Notes |
||||
|
|
||||
|
The Apache Log4j 2 team is pleased to announce the Log4j 2.13.3 release! |
||||
|
|
||||
|
Apache Log4j is a well known framework for logging application behavior. Log4j 2 is an upgrade |
||||
|
to Log4j that provides significant improvements over its predecessor, Log4j 1.x, and provides |
||||
|
many other modern features such as support for Markers, lambda expressions for lazy logging, |
||||
|
property substitution using Lookups, multiple patterns on a PatternLayout and asynchronous |
||||
|
Loggers. Another notable Log4j 2 feature is the ability to be "garbage-free" (avoid allocating |
||||
|
temporary objects) while logging. In addition, Log4j 2 will not lose events while reconfiguring. |
||||
|
|
||||
|
The artifacts may be downloaded from https://logging.apache.org/log4j/2.x/download.html. |
||||
|
|
||||
|
This release contains a fix for bug LOG4J2-2838. |
||||
|
|
||||
|
Due to a break in compatibility in the SLF4J binding, Log4j now ships with two versions of the SLF4J to Log4j adapters. |
||||
|
log4j-slf4j-impl should be used with SLF4J 1.7.x and earlier and log4j-slf4j18-impl should be used with SLF4J 1.8.x and |
||||
|
later. |
||||
|
|
||||
|
Note that the default XML, JSON and YAML formats changed in the 2.11.0 release: they no longer have the "timeMillis" |
||||
|
attribute and instead have an "Instant" element with "epochSecond" and "nanoOfSecond" attributes. If the previous |
||||
|
behavior is desired the "includeTimeMillis" attribute may be set to true on each of the respective Layouts. |
||||
|
|
||||
|
The Log4j 2.13.3 API, as well as many core components, maintains binary compatibility with previous releases. |
||||
|
|
||||
|
## GA Release 2.13.3 |
||||
|
|
||||
|
Changes in this version include: |
||||
|
|
||||
|
|
||||
|
### Fixed Bugs |
||||
|
* [LOG4J2-2838](https://issues.apache.org/jira/browse/LOG4J2-2838): |
||||
|
Fix NullPointerException in ThreadContextDataInjector. |
||||
|
|
||||
|
|
||||
|
--- |
||||
|
|
||||
|
Apache Log4j 2.13.3 requires a minimum of Java 8 to build and run. Log4j 2.3 was the |
||||
|
last release that supported Java 6 and Log4j 2.12.1 is the last release to support Java 7. |
||||
|
|
||||
|
For complete information on Apache Log4j 2, including instructions on how to submit bug |
||||
|
reports, patches, or suggestions for improvement, see the Apache Apache Log4j 2 website: |
||||
|
|
||||
|
https://logging.apache.org/log4j/2.x/ |
@ -0,0 +1,185 @@ |
|||||
|
2022-04-24 15:15:37,957 INFO base.GameLoop - GUI starts |
||||
|
2022-04-24 15:15:43,111 INFO base.GameLoop - GUI NEW |
||||
|
2022-04-24 15:15:43,111 INFO playground.SpaceInvadersLevel - PREPARE |
||||
|
2022-04-24 15:15:43,144 INFO playground.Animation - img added .\video/sweetAlien0.png |
||||
|
2022-04-24 15:15:43,147 INFO playground.Animation - img added .\video/sweetAlien1.png |
||||
|
2022-04-24 15:15:43,148 INFO playground.Animation - img added .\video/sweetAlien2.png |
||||
|
2022-04-24 15:15:43,150 INFO playground.Animation - img added .\video/sweetAlien3.png |
||||
|
2022-04-24 15:15:43,151 INFO playground.Animation - img added .\video/sweetAlien4.png |
||||
|
2022-04-24 15:15:43,153 INFO playground.Animation - img added .\video/sweetAlien5.png |
||||
|
2022-04-24 15:15:43,154 INFO playground.Animation - img added .\video/sweetAlien6.png |
||||
|
2022-04-24 15:15:43,156 INFO playground.Animation - img added .\video/sweetAlien7.png |
||||
|
2022-04-24 15:15:43,159 INFO playground.Animation - img added .\video/heart0.png |
||||
|
2022-04-24 15:15:43,160 INFO playground.Animation - img added .\video/heart1.png |
||||
|
2022-04-24 15:15:43,161 WARN playground.HighscoreManager - WARNING: Highscore file was not found and reset |
||||
|
2022-04-24 15:15:43,162 INFO playground.HighscoreManager - Highscore file was opened and saved score: 0 |
||||
|
2022-04-24 15:15:43,164 INFO playground.SpaceInvadersLevel - HIGHSCORE0 |
||||
|
2022-04-24 15:16:28,157 INFO base.GameLoop - GUI NEW |
||||
|
2022-04-24 15:16:28,158 INFO playground.SpaceInvadersLevel - PREPARE |
||||
|
2022-04-24 15:16:28,159 INFO playground.SpaceInvadersLevel - HIGHSCORE0 |
||||
|
2022-04-24 15:16:47,660 INFO base.GameLoop - GUI NEW |
||||
|
2022-04-24 15:16:47,660 INFO playground.SpaceInvadersLevel - PREPARE |
||||
|
2022-04-24 15:16:47,661 INFO playground.SpaceInvadersLevel - HIGHSCORE0 |
||||
|
2022-04-24 15:16:48,868 INFO base.GameLoop - GUI NEW |
||||
|
2022-04-24 15:16:48,869 INFO playground.SpaceInvadersLevel - PREPARE |
||||
|
2022-04-24 15:16:48,869 INFO playground.SpaceInvadersLevel - HIGHSCORE0 |
||||
|
2022-04-24 15:16:50,412 INFO base.GameLoop - GUI PAUSE |
||||
|
2022-04-24 15:16:52,109 INFO base.GameLoop - GUI NEW |
||||
|
2022-04-24 15:16:52,109 INFO playground.SpaceInvadersLevel - PREPARE |
||||
|
2022-04-24 15:16:52,110 INFO playground.SpaceInvadersLevel - HIGHSCORE0 |
||||
|
2022-04-24 15:16:53,652 INFO base.GameLoop - GUI NEW |
||||
|
2022-04-24 15:16:53,652 INFO playground.SpaceInvadersLevel - PREPARE |
||||
|
2022-04-24 15:16:53,653 INFO playground.SpaceInvadersLevel - HIGHSCORE0 |
||||
|
2022-04-24 15:16:54,315 INFO base.GameLoop - GUI NEW |
||||
|
2022-04-24 15:16:54,315 INFO playground.SpaceInvadersLevel - PREPARE |
||||
|
2022-04-24 15:16:54,316 INFO playground.SpaceInvadersLevel - HIGHSCORE0 |
||||
|
2022-04-24 15:16:58,388 INFO base.GameLoop - GUI starts |
||||
|
2022-04-24 15:17:00,103 INFO base.GameLoop - GUI NEW |
||||
|
2022-04-24 15:17:00,104 INFO playground.SpaceInvadersLevel - PREPARE |
||||
|
2022-04-24 15:17:00,130 INFO playground.Animation - img added .\video/sweetAlien0.png |
||||
|
2022-04-24 15:17:00,133 INFO playground.Animation - img added .\video/sweetAlien1.png |
||||
|
2022-04-24 15:17:00,135 INFO playground.Animation - img added .\video/sweetAlien2.png |
||||
|
2022-04-24 15:17:00,136 INFO playground.Animation - img added .\video/sweetAlien3.png |
||||
|
2022-04-24 15:17:00,138 INFO playground.Animation - img added .\video/sweetAlien4.png |
||||
|
2022-04-24 15:17:00,139 INFO playground.Animation - img added .\video/sweetAlien5.png |
||||
|
2022-04-24 15:17:00,140 INFO playground.Animation - img added .\video/sweetAlien6.png |
||||
|
2022-04-24 15:17:00,141 INFO playground.Animation - img added .\video/sweetAlien7.png |
||||
|
2022-04-24 15:17:00,144 INFO playground.Animation - img added .\video/heart0.png |
||||
|
2022-04-24 15:17:00,146 INFO playground.Animation - img added .\video/heart1.png |
||||
|
2022-04-24 15:17:00,149 INFO playground.SpaceInvadersLevel - HIGHSCORE0 |
||||
|
2022-04-24 15:17:26,519 INFO playground.HighscoreManager - Highscore file was opened and saved score: 6000 |
||||
|
2022-04-24 15:17:26,519 INFO playground.SpaceInvadersLevel - no enemies left, level done. |
||||
|
2022-04-24 15:17:26,520 INFO base.GameLoop - reached end of levels |
||||
|
2022-04-24 15:17:26,520 INFO base.GameLoop - Game ends. Bye. |
||||
|
2022-04-24 15:20:47,899 INFO base.GameLoop - GUI starts |
||||
|
2022-04-24 15:20:54,103 INFO base.GameLoop - GUI NEW |
||||
|
2022-04-24 15:20:54,104 INFO playground.SpaceInvadersLevel - PREPARE |
||||
|
2022-04-24 15:20:54,135 INFO playground.Animation - img added .\video/sweetAlien0.png |
||||
|
2022-04-24 15:20:54,138 INFO playground.Animation - img added .\video/sweetAlien1.png |
||||
|
2022-04-24 15:20:54,140 INFO playground.Animation - img added .\video/sweetAlien2.png |
||||
|
2022-04-24 15:20:54,142 INFO playground.Animation - img added .\video/sweetAlien3.png |
||||
|
2022-04-24 15:20:54,144 INFO playground.Animation - img added .\video/sweetAlien4.png |
||||
|
2022-04-24 15:20:54,145 INFO playground.Animation - img added .\video/sweetAlien5.png |
||||
|
2022-04-24 15:20:54,147 INFO playground.Animation - img added .\video/sweetAlien6.png |
||||
|
2022-04-24 15:20:54,148 INFO playground.Animation - img added .\video/sweetAlien7.png |
||||
|
2022-04-24 15:20:54,151 INFO playground.Animation - img added .\video/heart0.png |
||||
|
2022-04-24 15:20:54,153 INFO playground.Animation - img added .\video/heart1.png |
||||
|
2022-04-24 15:20:54,155 INFO playground.SpaceInvadersLevel - HIGHSCORE6000 |
||||
|
2022-04-24 15:21:22,977 INFO playground.SpaceInvadersLevel - no enemies left, level done. |
||||
|
2022-04-24 15:21:22,977 INFO base.GameLoop - reached end of levels |
||||
|
2022-04-24 15:21:22,977 INFO base.GameLoop - Game ends. Bye. |
||||
|
2022-04-24 15:28:41,348 INFO base.GameLoop - GUI starts |
||||
|
2022-04-24 15:28:43,030 INFO base.GameLoop - GUI NEW |
||||
|
2022-04-24 15:28:43,030 INFO playground.SpaceInvadersLevel - PREPARE |
||||
|
2022-04-24 15:28:43,058 INFO playground.Animation - img added .\video/sweetAlien0.png |
||||
|
2022-04-24 15:28:43,062 INFO playground.Animation - img added .\video/sweetAlien1.png |
||||
|
2022-04-24 15:28:43,063 INFO playground.Animation - img added .\video/sweetAlien2.png |
||||
|
2022-04-24 15:28:43,064 INFO playground.Animation - img added .\video/sweetAlien3.png |
||||
|
2022-04-24 15:28:43,065 INFO playground.Animation - img added .\video/sweetAlien4.png |
||||
|
2022-04-24 15:28:43,067 INFO playground.Animation - img added .\video/sweetAlien5.png |
||||
|
2022-04-24 15:28:43,068 INFO playground.Animation - img added .\video/sweetAlien6.png |
||||
|
2022-04-24 15:28:43,069 INFO playground.Animation - img added .\video/sweetAlien7.png |
||||
|
2022-04-24 15:28:43,071 INFO playground.Animation - img added .\video/heart0.png |
||||
|
2022-04-24 15:28:43,073 INFO playground.Animation - img added .\video/heart1.png |
||||
|
2022-04-24 15:28:43,076 INFO playground.SpaceInvadersLevel - HIGHSCORE6000 |
||||
|
2022-04-24 15:28:56,264 INFO playground.SpaceInvadersLevel - no enemies left, level done. |
||||
|
2022-04-24 15:28:56,265 INFO playground.SpaceInvadersLevel - PREPARE |
||||
|
2022-04-24 15:28:56,267 INFO playground.Animation - img added .\video/sweetAlien0.png |
||||
|
2022-04-24 15:28:56,268 INFO playground.Animation - img added .\video/sweetAlien1.png |
||||
|
2022-04-24 15:28:56,269 INFO playground.Animation - img added .\video/sweetAlien2.png |
||||
|
2022-04-24 15:28:56,270 INFO playground.Animation - img added .\video/sweetAlien3.png |
||||
|
2022-04-24 15:28:56,272 INFO playground.Animation - img added .\video/sweetAlien4.png |
||||
|
2022-04-24 15:28:56,273 INFO playground.Animation - img added .\video/sweetAlien5.png |
||||
|
2022-04-24 15:28:56,274 INFO playground.Animation - img added .\video/sweetAlien6.png |
||||
|
2022-04-24 15:28:56,275 INFO playground.Animation - img added .\video/sweetAlien7.png |
||||
|
2022-04-24 15:28:56,277 INFO playground.Animation - img added .\video/heart0.png |
||||
|
2022-04-24 15:28:56,278 INFO playground.Animation - img added .\video/heart1.png |
||||
|
2022-04-24 15:28:56,279 INFO playground.SpaceInvadersLevel - HIGHSCORE6000 |
||||
|
2022-04-24 15:29:17,828 INFO playground.HighscoreManager - Highscore file was opened and saved score: 12000 |
||||
|
2022-04-24 15:29:17,828 INFO playground.SpaceInvadersLevel - no enemies left, level done. |
||||
|
2022-04-24 15:29:17,828 INFO playground.SpaceInvadersLevel - PREPARE |
||||
|
2022-04-24 15:29:17,830 INFO playground.Animation - img added .\video/sweetAlien0.png |
||||
|
2022-04-24 15:29:17,831 INFO playground.Animation - img added .\video/sweetAlien1.png |
||||
|
2022-04-24 15:29:17,832 INFO playground.Animation - img added .\video/sweetAlien2.png |
||||
|
2022-04-24 15:29:17,833 INFO playground.Animation - img added .\video/sweetAlien3.png |
||||
|
2022-04-24 15:29:17,834 INFO playground.Animation - img added .\video/sweetAlien4.png |
||||
|
2022-04-24 15:29:17,835 INFO playground.Animation - img added .\video/sweetAlien5.png |
||||
|
2022-04-24 15:29:17,835 INFO playground.Animation - img added .\video/sweetAlien6.png |
||||
|
2022-04-24 15:29:17,836 INFO playground.Animation - img added .\video/sweetAlien7.png |
||||
|
2022-04-24 15:29:17,838 INFO playground.Animation - img added .\video/heart0.png |
||||
|
2022-04-24 15:29:17,839 INFO playground.Animation - img added .\video/heart1.png |
||||
|
2022-04-24 15:29:17,840 INFO playground.SpaceInvadersLevel - HIGHSCORE12000 |
||||
|
2022-04-24 15:29:52,038 INFO playground.HighscoreManager - Highscore file was opened and saved score: 17500 |
||||
|
2022-04-24 15:29:52,038 INFO playground.SpaceInvadersLevel - no enemies left, level done. |
||||
|
2022-04-24 15:29:52,038 INFO playground.SpaceInvadersLevel - PREPARE |
||||
|
2022-04-24 15:29:52,040 INFO playground.Animation - img added .\video/sweetAlien0.png |
||||
|
2022-04-24 15:29:52,041 INFO playground.Animation - img added .\video/sweetAlien1.png |
||||
|
2022-04-24 15:29:52,042 INFO playground.Animation - img added .\video/sweetAlien2.png |
||||
|
2022-04-24 15:29:52,043 INFO playground.Animation - img added .\video/sweetAlien3.png |
||||
|
2022-04-24 15:29:52,043 INFO playground.Animation - img added .\video/sweetAlien4.png |
||||
|
2022-04-24 15:29:52,044 INFO playground.Animation - img added .\video/sweetAlien5.png |
||||
|
2022-04-24 15:29:52,045 INFO playground.Animation - img added .\video/sweetAlien6.png |
||||
|
2022-04-24 15:29:52,046 INFO playground.Animation - img added .\video/sweetAlien7.png |
||||
|
2022-04-24 15:29:52,048 INFO playground.Animation - img added .\video/heart0.png |
||||
|
2022-04-24 15:29:52,049 INFO playground.Animation - img added .\video/heart1.png |
||||
|
2022-04-24 15:29:52,049 INFO playground.SpaceInvadersLevel - HIGHSCORE17500 |
||||
|
2022-04-24 15:30:16,985 INFO playground.HighscoreManager - Highscore file was opened and saved score: 22500 |
||||
|
2022-04-24 15:30:16,985 INFO playground.SpaceInvadersLevel - no enemies left, level done. |
||||
|
2022-04-24 15:30:16,985 INFO base.GameLoop - reached end of levels |
||||
|
2022-04-24 15:30:16,985 INFO base.GameLoop - Game ends. Bye. |
||||
|
2022-04-24 15:32:41,524 INFO base.GameLoop - GUI starts |
||||
|
2022-04-24 15:32:42,806 INFO base.GameLoop - GUI NEW |
||||
|
2022-04-24 15:32:42,807 INFO playground.SpaceInvadersLevel - PREPARE |
||||
|
2022-04-24 15:32:42,835 INFO playground.Animation - img added .\video/sweetAlien0.png |
||||
|
2022-04-24 15:32:42,838 INFO playground.Animation - img added .\video/sweetAlien1.png |
||||
|
2022-04-24 15:32:42,839 INFO playground.Animation - img added .\video/sweetAlien2.png |
||||
|
2022-04-24 15:32:42,841 INFO playground.Animation - img added .\video/sweetAlien3.png |
||||
|
2022-04-24 15:32:42,842 INFO playground.Animation - img added .\video/sweetAlien4.png |
||||
|
2022-04-24 15:32:42,844 INFO playground.Animation - img added .\video/sweetAlien5.png |
||||
|
2022-04-24 15:32:42,845 INFO playground.Animation - img added .\video/sweetAlien6.png |
||||
|
2022-04-24 15:32:42,846 INFO playground.Animation - img added .\video/sweetAlien7.png |
||||
|
2022-04-24 15:32:42,849 INFO playground.Animation - img added .\video/heart0.png |
||||
|
2022-04-24 15:32:42,850 INFO playground.Animation - img added .\video/heart1.png |
||||
|
2022-04-24 15:32:42,852 INFO playground.SpaceInvadersLevel - HIGHSCORE22500 |
||||
|
2022-04-24 15:32:57,951 INFO playground.SpaceInvadersLevel - no enemies left, level done. |
||||
|
2022-04-24 15:32:57,952 INFO playground.SpaceInvadersLevel - PREPARE |
||||
|
2022-04-24 15:32:57,954 INFO playground.Animation - img added .\video/sweetAlien0.png |
||||
|
2022-04-24 15:32:57,956 INFO playground.Animation - img added .\video/sweetAlien1.png |
||||
|
2022-04-24 15:32:57,957 INFO playground.Animation - img added .\video/sweetAlien2.png |
||||
|
2022-04-24 15:32:57,958 INFO playground.Animation - img added .\video/sweetAlien3.png |
||||
|
2022-04-24 15:32:57,959 INFO playground.Animation - img added .\video/sweetAlien4.png |
||||
|
2022-04-24 15:32:57,960 INFO playground.Animation - img added .\video/sweetAlien5.png |
||||
|
2022-04-24 15:32:57,961 INFO playground.Animation - img added .\video/sweetAlien6.png |
||||
|
2022-04-24 15:32:57,962 INFO playground.Animation - img added .\video/sweetAlien7.png |
||||
|
2022-04-24 15:32:57,964 INFO playground.Animation - img added .\video/heart0.png |
||||
|
2022-04-24 15:32:57,965 INFO playground.Animation - img added .\video/heart1.png |
||||
|
2022-04-24 15:32:57,966 INFO playground.SpaceInvadersLevel - HIGHSCORE22500 |
||||
|
2022-04-24 15:33:11,120 INFO playground.SpaceInvadersLevel - no enemies left, level done. |
||||
|
2022-04-24 15:33:11,120 INFO playground.SpaceInvadersLevel - PREPARE |
||||
|
2022-04-24 15:33:11,123 INFO playground.Animation - img added .\video/sweetAlien0.png |
||||
|
2022-04-24 15:33:11,124 INFO playground.Animation - img added .\video/sweetAlien1.png |
||||
|
2022-04-24 15:33:11,124 INFO playground.Animation - img added .\video/sweetAlien2.png |
||||
|
2022-04-24 15:33:11,125 INFO playground.Animation - img added .\video/sweetAlien3.png |
||||
|
2022-04-24 15:33:11,126 INFO playground.Animation - img added .\video/sweetAlien4.png |
||||
|
2022-04-24 15:33:11,127 INFO playground.Animation - img added .\video/sweetAlien5.png |
||||
|
2022-04-24 15:33:11,128 INFO playground.Animation - img added .\video/sweetAlien6.png |
||||
|
2022-04-24 15:33:11,129 INFO playground.Animation - img added .\video/sweetAlien7.png |
||||
|
2022-04-24 15:33:11,131 INFO playground.Animation - img added .\video/heart0.png |
||||
|
2022-04-24 15:33:11,132 INFO playground.Animation - img added .\video/heart1.png |
||||
|
2022-04-24 15:33:11,133 INFO playground.SpaceInvadersLevel - HIGHSCORE22500 |
||||
|
2022-04-24 15:33:28,392 INFO playground.SpaceInvadersLevel - no enemies left, level done. |
||||
|
2022-04-24 15:33:28,392 INFO playground.SpaceInvadersLevel - PREPARE |
||||
|
2022-04-24 15:33:28,394 INFO playground.Animation - img added .\video/sweetAlien0.png |
||||
|
2022-04-24 15:33:28,395 INFO playground.Animation - img added .\video/sweetAlien1.png |
||||
|
2022-04-24 15:33:28,396 INFO playground.Animation - img added .\video/sweetAlien2.png |
||||
|
2022-04-24 15:33:28,397 INFO playground.Animation - img added .\video/sweetAlien3.png |
||||
|
2022-04-24 15:33:28,398 INFO playground.Animation - img added .\video/sweetAlien4.png |
||||
|
2022-04-24 15:33:28,399 INFO playground.Animation - img added .\video/sweetAlien5.png |
||||
|
2022-04-24 15:33:28,399 INFO playground.Animation - img added .\video/sweetAlien6.png |
||||
|
2022-04-24 15:33:28,400 INFO playground.Animation - img added .\video/sweetAlien7.png |
||||
|
2022-04-24 15:33:28,402 INFO playground.Animation - img added .\video/heart0.png |
||||
|
2022-04-24 15:33:28,403 INFO playground.Animation - img added .\video/heart1.png |
||||
|
2022-04-24 15:33:28,404 INFO playground.SpaceInvadersLevel - HIGHSCORE22500 |
||||
|
2022-04-24 15:33:34,404 INFO playground.SpaceInvadersLevel - no enemies left, level done. |
||||
|
2022-04-24 15:33:34,404 INFO base.GameLoop - reached end of levels |
||||
|
2022-04-24 15:33:34,404 INFO base.GameLoop - Game ends. Bye. |
@ -0,0 +1,231 @@ |
|||||
|
package base; |
||||
|
|
||||
|
import java.io.IOException; |
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
import java.util.ListIterator; |
||||
|
import org.apache.logging.log4j.LogManager; |
||||
|
import org.apache.logging.log4j.Logger; |
||||
|
import gameobjects.GameObject; |
||||
|
import playground.Level1; |
||||
|
import playground.Playground; |
||||
|
import ui.GameUI; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Main class starting any game, contains main(). Apart from that, this class manages all |
||||
|
* non-logical functionalities which should be hidden from a game designer like: |
||||
|
* <ul> |
||||
|
* <li>Setting up windows, panels, buttons, action callbacks, ... |
||||
|
* <li>Reading keyboard inputs |
||||
|
* <li>Redrawing game window if necessary |
||||
|
* <li>managing the game time and calling the appropriate {@link GameObject} or {@link Playground} |
||||
|
* methods periodically, at every time step of the game. |
||||
|
* </ul> |
||||
|
* There will normally never be a need to modify this file, a designer/game programmer should always |
||||
|
* redefine the {@link GameObject} and {@link Playground} classes and implement new functionality |
||||
|
* there. To make a long story short<br> |
||||
|
*/ |
||||
|
public class GameLoop { |
||||
|
|
||||
|
/** Pixel width of Game GUI ( above 0) */ |
||||
|
public static int SIZEX = 300; |
||||
|
/** Pixel height of Game GUI (above 0) */ |
||||
|
public static int SIZEY = 200; |
||||
|
|
||||
|
/** |
||||
|
* before call to {@link #runGame(String[])} this List should be initialized (in constructor). |
||||
|
*/ |
||||
|
private List<Playground> levels = new ArrayList<Playground>(0); |
||||
|
|
||||
|
private static Logger logger = LogManager.getLogger(GameLoop.class); |
||||
|
|
||||
|
/** constructor which calls {@link #defineLevels()}, which adds all levels of this game. |
||||
|
*/ |
||||
|
public GameLoop() { |
||||
|
this.defineLevels(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* First resets (clears) the already existing level instances of this game's list of levels ({@link #resetLevels()}), |
||||
|
* then adds one instance of {@link Level1} by calling {@link #addLevel()}. |
||||
|
* Should be called only before playing starts (e.g. in constructor or before {@link #runGame(String[]) } is called. |
||||
|
* |
||||
|
* <br><strong>Note:</strong> Subclasses of {@link GameLoop} should override this method to define own levels for their game. |
||||
|
*/ |
||||
|
void defineLevels() { |
||||
|
this.resetLevels(); |
||||
|
this.addLevel(new Level1()); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Adds the given level instance to the end of the currently already stored list of levels to play. |
||||
|
* Should be called only before playing starts (e.g. in constructor or before {@link #runGame(String[]) } is called. |
||||
|
* |
||||
|
* @param level instance of Playground (a level) to add. |
||||
|
*/ |
||||
|
void addLevel(Playground level) { |
||||
|
this.levels.add(level); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Removes all levels from the list of levels to play! Do not call this method while {@link #runGame(String[]) } is running! |
||||
|
*/ |
||||
|
void resetLevels() { |
||||
|
this.levels.clear(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* loops over all {@link #levels} and implements the game loop to update continuously the level |
||||
|
* during play time |
||||
|
* |
||||
|
* @param args command line arguments forwarded (currently ignored) |
||||
|
* @throws IOException if hitghscore.txt cannot be written. |
||||
|
*/ |
||||
|
public void runGame(String[] args) throws IOException { |
||||
|
|
||||
|
logger.info("GUI starts"); |
||||
|
GameUI gameUI = new GameUI(SIZEX, SIZEY); // probably change to your new GUI class |
||||
|
|
||||
|
double gameTime = -1; |
||||
|
Playground currentPlayground = null; |
||||
|
|
||||
|
// loop over different levels |
||||
|
ListIterator<Playground> levelIterator = levels.listIterator(); |
||||
|
while (true) { |
||||
|
logger.debug("LevelIndex is " + (levelIterator.nextIndex()) + " (of " + levels.size() + " levels)"); |
||||
|
gameTime = 0; |
||||
|
long start = System.nanoTime(); |
||||
|
|
||||
|
// loop over single level |
||||
|
while (true) { |
||||
|
|
||||
|
int act = GameUI.getNewAction(); |
||||
|
|
||||
|
// Query GameUI for high-level user commands; new game/reset/etc... |
||||
|
if (act == GameUI.ACTION_RESET) { |
||||
|
// ReStart Game in same Level |
||||
|
logger.info("GUI RESET"); |
||||
|
currentPlayground.prepareLevel("level" + (levelIterator.nextIndex()-1)); |
||||
|
GameUI.resetAction(); |
||||
|
} |
||||
|
|
||||
|
if (act == GameUI.ACTION_NEW) { |
||||
|
// new game |
||||
|
logger.info("GUI NEW"); |
||||
|
start = System.nanoTime(); |
||||
|
levelIterator = levels.listIterator(); // reset |
||||
|
currentPlayground = levelIterator.next(); // again level |
||||
|
currentPlayground.prepareLevel("level" + (levelIterator.nextIndex()-1)); |
||||
|
gameUI.setPlayground(currentPlayground); |
||||
|
GameUI.resetAction(); |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
if (act == GameUI.ACTION_BUTTON) { |
||||
|
// Event of Button pressed --> PAUSE! |
||||
|
logger.info("GUI PAUSE"); |
||||
|
if (currentPlayground != null) { |
||||
|
boolean p = currentPlayground.isPaused(); |
||||
|
p = !p; |
||||
|
currentPlayground.setPaused(p); |
||||
|
} |
||||
|
GameUI.resetAction(); |
||||
|
} |
||||
|
|
||||
|
if (act == GameUI.ACTION_SAVE) { |
||||
|
logger.info("GUI SAVE"); |
||||
|
// UNDONE save current state (not yet working/implemented) |
||||
|
GameUI.resetAction(); |
||||
|
} |
||||
|
|
||||
|
if (act == GameUI.ACTION_LOAD) { |
||||
|
logger.info("GUI LOAD"); |
||||
|
// load game state (currently simply resets) |
||||
|
GameUI.resetAction(); |
||||
|
} |
||||
|
|
||||
|
// if game has been created: execute a single iteration of the game loop |
||||
|
if (currentPlayground != null) { |
||||
|
// calc time that was used for painting the game, in seconds since last loop |
||||
|
long end = System.nanoTime(); |
||||
|
double realTS = ((double) (end - start) / 1000000000.); |
||||
|
|
||||
|
// time calc for one loop of the while |
||||
|
start = System.nanoTime(); |
||||
|
|
||||
|
|
||||
|
|
||||
|
if (currentPlayground.levelFinished() || currentPlayground.gameOver() == true) { |
||||
|
break; // leave level; breaks WHILE |
||||
|
} |
||||
|
|
||||
|
// paint current state of level and start time measurement |
||||
|
gameUI.waitWhilePainting(); |
||||
|
|
||||
|
|
||||
|
gameUI.grabFocus(); // needed to grab input events in next step |
||||
|
|
||||
|
// communicate inputs to level |
||||
|
currentPlayground.processKeyEvents(gameUI.getKeyEvents()); |
||||
|
currentPlayground.processMouseEvents(gameUI.getMouseEvents()); |
||||
|
|
||||
|
if (currentPlayground.isPaused() == false) { |
||||
|
|
||||
|
// update objects and level |
||||
|
currentPlayground.updateObjects(); |
||||
|
currentPlayground.applyGameLogic(); |
||||
|
|
||||
|
|
||||
|
// update game time |
||||
|
gameTime += realTS; |
||||
|
// communicate gameTime and timestep to level |
||||
|
currentPlayground.setTimestep(realTS); |
||||
|
currentPlayground.setGameTime(gameTime); |
||||
|
Playground.setGlobalFlag("gameTime", Double.valueOf(realTS)); |
||||
|
logger.trace("gameTime is now "+gameTime); |
||||
|
|
||||
|
} // if |
||||
|
} // if |
||||
|
|
||||
|
} // inner while loop within level |
||||
|
|
||||
|
// after level is done: leave outer loop if game over |
||||
|
if (currentPlayground.gameOver() == true) { |
||||
|
break; // outer while ends game |
||||
|
} |
||||
|
|
||||
|
// after level is done: reset level and go to next, if there is one |
||||
|
if (currentPlayground.levelFinished() == true) { |
||||
|
currentPlayground.reset(); |
||||
|
|
||||
|
// increase level counter, go on to next one |
||||
|
logger.debug("level finished. now new LevelIndex is " + levelIterator.nextIndex()); |
||||
|
if (levelIterator.nextIndex() >= levels.size()) { |
||||
|
logger.info("reached end of levels"); |
||||
|
break; // outer while ends game; |
||||
|
} |
||||
|
currentPlayground = levelIterator.next(); |
||||
|
currentPlayground.prepareLevel("level" + (levelIterator.nextIndex()-1)); |
||||
|
} |
||||
|
|
||||
|
} // outer loop over levels |
||||
|
logger.info("Game ends. Bye."); |
||||
|
System.exit(0); |
||||
|
} // main() |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* main to start the whole application. |
||||
|
* initializes the {@link #levels} ArrayList of Playground instances (levels) to be played with one level {@link SpaceInvadersLevel} in constructor of {@link #GameLoop}. |
||||
|
* |
||||
|
* @param args Java default command line args, forwarded to {@link #runGame(String[])} |
||||
|
* @throws IOException in case highscore.txt cannot be written. |
||||
|
*/ |
||||
|
public static void main(String[] args) throws IOException { |
||||
|
GameLoop gl = new GameLoop(); |
||||
|
gl.runGame(args); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,30 @@ |
|||||
|
//Coding Team 66 |
||||
|
package base; |
||||
|
|
||||
|
import java.io.IOException; |
||||
|
|
||||
|
//importieren der neuen Level aus dem Package Playground |
||||
|
import playground.Level1; |
||||
|
import playground.Level3; |
||||
|
import playground.LevelBoss; |
||||
|
import playground.LevelHitTwice; |
||||
|
|
||||
|
|
||||
|
public class MultiLevelGame extends GameLoop{ |
||||
|
|
||||
|
//main wie bei GameLoop, nur das stattdessen Instanz von MulitLevelGame erstellt wird |
||||
|
public static void main(String[] args) throws IOException { |
||||
|
MultiLevelGame gl = new MultiLevelGame(); |
||||
|
gl.runGame(args); |
||||
|
} |
||||
|
|
||||
|
@Override //Überschreiben der Methode defineLevels |
||||
|
void defineLevels() { |
||||
|
this.resetLevels(); |
||||
|
this.addLevel(new Level1()); |
||||
|
this.addLevel(new LevelHitTwice()); |
||||
|
this.addLevel(new Level3()); |
||||
|
this.addLevel(new LevelBoss()); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,88 @@ |
|||||
|
package collider; |
||||
|
|
||||
|
import java.awt.Color; |
||||
|
import gameobjects.*; |
||||
|
import org.apache.logging.log4j.Logger; |
||||
|
import org.apache.logging.log4j.LogManager; |
||||
|
|
||||
|
|
||||
|
/** Collider for round objects */ |
||||
|
public class CircleCollider extends Collider { |
||||
|
|
||||
|
double x; |
||||
|
double y; |
||||
|
double vx; |
||||
|
double vy; |
||||
|
|
||||
|
double r; |
||||
|
|
||||
|
private static Logger logger = LogManager.getLogger(Collider.class); |
||||
|
|
||||
|
/** |
||||
|
* Constructor which sets the radius to be respected for collisions. |
||||
|
* |
||||
|
* @param id String unique name for the collider instance |
||||
|
* @param o GameObject it belongs to |
||||
|
* @param radius radius in pixels to use as a size |
||||
|
*/ |
||||
|
public CircleCollider(String id, GameObject o, double radius) { |
||||
|
|
||||
|
super(id, o); |
||||
|
this.r = radius; |
||||
|
} |
||||
|
|
||||
|
/** simple concatenation of all attributes (x,y,r) */ |
||||
|
public String toString() { |
||||
|
return "circ:" + x + " " + y + "/" + r + " "; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* calculates the collission of this with other collider |
||||
|
* |
||||
|
* @param _c2 the other collider |
||||
|
* @return true if a collision was detected |
||||
|
* @throws Exception in case the math operations are invalid (due to illegal values of x y or |
||||
|
* radius) |
||||
|
*/ |
||||
|
public boolean checkCollisionCircCirc(Collider _c2) throws Exception { |
||||
|
CircleCollider c2 = (CircleCollider) _c2; |
||||
|
CircleCollider c1 = this; |
||||
|
logger.trace(c1.x + " " + c1.y + " " + c1.r + " " + c2.x + " " + c2.y+ " " + c2.r); |
||||
|
int kathete1 = (int) (Math.abs(c2.gameobject.getX() - c1.gameobject.getX())); |
||||
|
int kathete2 = (int) (Math.abs(c2.gameobject.getX() - c1.gameobject.getY())); |
||||
|
int hypothenuse = (int) (c1.r + c2.r); |
||||
|
|
||||
|
logger.trace(kathete1 + " " + kathete2 + " " + hypothenuse + " "); |
||||
|
|
||||
|
if (((kathete1 ^ 2) + (kathete2 ^ 2)) <= (hypothenuse ^ 2)) { |
||||
|
logger.trace("Collision"); |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
@Override |
||||
|
public boolean collidesWith(Collider other) { |
||||
|
|
||||
|
// circ circ |
||||
|
try { |
||||
|
return checkCollisionCircCirc(other); |
||||
|
} catch (Exception e) { |
||||
|
} |
||||
|
|
||||
|
try { |
||||
|
return other.collidesWith(this); |
||||
|
} catch (Exception e) { |
||||
|
} |
||||
|
|
||||
|
throw new RuntimeException("Collider type not implemented!"); |
||||
|
} |
||||
|
|
||||
|
private Color color = Color.WHITE; |
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,127 @@ |
|||||
|
package collider; |
||||
|
|
||||
|
import java.awt.Graphics2D; |
||||
|
import java.util.LinkedList; |
||||
|
import gameobjects.GameObject; |
||||
|
import playground.Playground; |
||||
|
import controller.ObjectController; |
||||
|
|
||||
|
/** |
||||
|
* abstract base class for all Colliders to detect collisions between GameObjects |
||||
|
* |
||||
|
* |
||||
|
*/ |
||||
|
public abstract class Collider { |
||||
|
|
||||
|
/** unique internal name for Collider */ |
||||
|
public String id = null; |
||||
|
/** GameObject it belongs to */ |
||||
|
protected GameObject gameobject = null; |
||||
|
/** PlayGround instance it belongs to */ |
||||
|
protected Playground playground = null; |
||||
|
/** the ObjectController to the corresponding GameObject (can be null) */ |
||||
|
protected ObjectController controller = null; |
||||
|
|
||||
|
protected double dx = 0.; |
||||
|
double dy = 0.; |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param id unique name for Collider (internally) |
||||
|
* @param o GameObject instance it belongs to |
||||
|
*/ |
||||
|
public Collider(String id, GameObject o) { |
||||
|
this.gameobject = o; |
||||
|
|
||||
|
this.id = id; |
||||
|
this.controller = o.getObjectController(); |
||||
|
this.playground = o.getPlayground(); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* setter for offset values to be used relative to GameObject center. default is zero. |
||||
|
* |
||||
|
* @param dx offset in X direction (default 0) |
||||
|
* @param dy offset in Y direction (default 0) |
||||
|
* @return this instance of Collider |
||||
|
*/ |
||||
|
public Collider setOffsets(double dx, double dy) { |
||||
|
this.dx = dx; |
||||
|
this.dy = dy; |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
public String toString() { |
||||
|
return "baseColl"; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* returns the corresponding game objects X coordinate (center) plus this colliders offset in X |
||||
|
* (probably zero). |
||||
|
* |
||||
|
* @return X value |
||||
|
*/ |
||||
|
public double getX() { |
||||
|
return this.gameobject.getX() + this.dx; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* returns the corresponding game objects Y coordinate (center) plus this colliders offset in Y |
||||
|
* (probably zero). |
||||
|
* |
||||
|
* @return Y value |
||||
|
*/ |
||||
|
public double getY() { |
||||
|
return this.gameobject.getY() + this.dy; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* returns the internal unique name |
||||
|
* |
||||
|
* @return the String with the name |
||||
|
*/ |
||||
|
public String getId() { |
||||
|
return id; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* setter for corresponding GameObject |
||||
|
* |
||||
|
* @param gameObject to be saved in attribute |
||||
|
*/ |
||||
|
public void setObject(GameObject gameObject) { |
||||
|
this.gameobject = gameObject; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* setter for GameController |
||||
|
* |
||||
|
* @param controller to be saved in attribute |
||||
|
*/ |
||||
|
public void setController(ObjectController controller) { |
||||
|
this.controller = controller; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* setter for Playground instance this collider belongs to |
||||
|
* |
||||
|
* @param playground instance to be stored in attribute |
||||
|
*/ |
||||
|
public void setPlayground(Playground playground) { |
||||
|
this.playground = playground; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* checks the collission with another collider instance. |
||||
|
* |
||||
|
* @param other the instance to compare to |
||||
|
* @return true if the colliders collide (touch or overlap) |
||||
|
*/ |
||||
|
abstract public boolean collidesWith(Collider other); |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,127 @@ |
|||||
|
package collider; |
||||
|
|
||||
|
import java.awt.Color; |
||||
|
|
||||
|
import gameobjects.*; |
||||
|
import org.apache.logging.log4j.Logger; |
||||
|
import org.apache.logging.log4j.LogManager; |
||||
|
|
||||
|
/** a {@link Collider} for Rectangles, usually used for {@link RectObject} instances. |
||||
|
* @see gameobjects.RectObject#generateColliders() |
||||
|
*/ |
||||
|
public class RectCollider extends Collider { |
||||
|
|
||||
|
//double x; |
||||
|
//double y; |
||||
|
//double vx; |
||||
|
//double vy; |
||||
|
double w, h; |
||||
|
|
||||
|
private Color color = Color.WHITE; |
||||
|
|
||||
|
private static Logger logger = LogManager.getLogger(RectCollider.class); |
||||
|
|
||||
|
/** |
||||
|
* initializes this RectCollider. |
||||
|
* calls superclass constructor of {@link Collider#Collider(String, GameObject)} with params String id and GameObject o. |
||||
|
* |
||||
|
* @param id String unique name for this RectCollider |
||||
|
* @param o GameObject instance this RectCollider belongs to (cannot be null) |
||||
|
* @param w width in pixels for the collider dimensions (> 0) |
||||
|
* @param h height in pixels for the collider dimensions (>0) |
||||
|
*/ |
||||
|
public RectCollider(String id, GameObject o, double w, double h) { |
||||
|
super(id, o); |
||||
|
this.w = w; |
||||
|
this.h = h; |
||||
|
} |
||||
|
|
||||
|
public String toString() { |
||||
|
return " " + w + " " + h + " "; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* checks collision with other Collider, which needs to be a RectCollider, too. |
||||
|
* @param other RectCollider (is casted) to calculate collision with |
||||
|
* @return true if collission is detected |
||||
|
*/ |
||||
|
public boolean checkCollisionRectRect(Collider other) { |
||||
|
RectCollider r1 = this; |
||||
|
RectCollider r2 = (RectCollider) other; |
||||
|
|
||||
|
if ((((r1.getX() + r1.w / 2.) >= (r2.getX() - r2.w / 2.)) && ((r1.getX() + r1.w / 2.) <= (r2 |
||||
|
.getX() + r2.w / 2.))) |
||||
|
|| (((r2.getX() + r2.w / 2.) >= (r1.getX() - r1.w / 2.)) && ((r2.getX() + r2.w / 2.) <= (r1 |
||||
|
.getX() + r1.w / 2.)))) { |
||||
|
if ((((r1.getY() + r1.h / 2.) >= (r2.getY() - r2.h / 2.)) && ((r1.getY() + r1.h / 2.) <= (r2 |
||||
|
.getY() + r2.h / 2.))) |
||||
|
|| (((r2.getY() + r2.h / 2.) >= (r1.getY() - r1.h / 2.)) && ((r2.getY() + r2.h / 2.) <= (r1 |
||||
|
.getY() + r1.h / 2.)))) { |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* checks collision with other Collider, which needs to be a CircleCollider |
||||
|
* @param other CircleCollider (is casted) to calculate collision with |
||||
|
* @return true if collission is detected |
||||
|
*/ |
||||
|
public boolean checkCollisionRectCirc(Collider other) { |
||||
|
RectCollider r = this; |
||||
|
CircleCollider c = (CircleCollider) (other); |
||||
|
double circleDistX = Math.abs(c.getX() - (r.getX() )); |
||||
|
double circleDistY = Math.abs(c.getY() - (r.getY() ) ); |
||||
|
|
||||
|
logger.trace("c.x:"+c.x+" "+"c.y:"+c.y+" "+"c.r:"+c.r+" "+"r.x:"+r.getX()+" "+"r.y:"+r.getY()+" "+"r.w:"+r.w+" "+"r.h:"+r.h+" "+"circleDistX:"+circleDistX+" "+"circleDistY:"+circleDistY); |
||||
|
|
||||
|
if (circleDistX > (r.w / 2 + c.r)) |
||||
|
return false; |
||||
|
if (circleDistY > (r.h / 2 + c.r)) |
||||
|
return false; |
||||
|
|
||||
|
if (circleDistX <= (r.w / 2)) { |
||||
|
logger.trace("Collision Rect with circle"); |
||||
|
return true; |
||||
|
} |
||||
|
if (circleDistY <= (r.h / 2)) { |
||||
|
logger.trace("Collision Rect with circle (second)"); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
double cornerDistSqr = Math.pow(circleDistX - r.w / 2, 2) + Math.pow(circleDistY - r.h / 2, 2); // Satz |
||||
|
// des |
||||
|
// Pythagoras |
||||
|
return (cornerDistSqr <= c.r * c.r); // falls true zurueckgegeben: Kollision |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
@Override |
||||
|
public boolean collidesWith(Collider other) { |
||||
|
|
||||
|
// rect circ |
||||
|
try { |
||||
|
return checkCollisionRectCirc(other); |
||||
|
} catch (Exception e) { |
||||
|
// do nothing |
||||
|
} |
||||
|
|
||||
|
// rect rect |
||||
|
try { |
||||
|
return checkCollisionRectRect(other); |
||||
|
} catch (Exception e) { |
||||
|
// do nothing |
||||
|
} |
||||
|
|
||||
|
try { |
||||
|
return other.collidesWith(this); |
||||
|
} catch (Exception e) { |
||||
|
// do nothing |
||||
|
} |
||||
|
|
||||
|
throw new RuntimeException("Collider type not implemented!"); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,84 @@ |
|||||
|
package controller; |
||||
|
|
||||
|
import playground.*; |
||||
|
import gameobjects.*; |
||||
|
import java.util.*; |
||||
|
import java.awt.event.*; |
||||
|
import java.io.File; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* An EgoController which cannot move through obstacle objects (is collission aware). Only respects |
||||
|
* GameObjects that have the String 'obstacle' in their name. |
||||
|
* |
||||
|
*/ |
||||
|
public class CollisionAwareEgoController extends EgoController { |
||||
|
|
||||
|
double savex, savey, savevx, savevy; |
||||
|
double lastSpaceAt = -1; |
||||
|
private File shot = null; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param egoRad radius of ego object to be used. |
||||
|
*/ |
||||
|
public CollisionAwareEgoController(double egoRad) { |
||||
|
super(egoRad); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param egoRad radius of ego object to be used. |
||||
|
* @param soundOnShot WAV file to be played on shot |
||||
|
*/ |
||||
|
public CollisionAwareEgoController(double egoRad, File soundOnShot) { |
||||
|
super(egoRad); |
||||
|
this.shot = soundOnShot; |
||||
|
} |
||||
|
|
||||
|
public void saveDynamicState() { |
||||
|
this.savex = this.getX(); |
||||
|
this.savey = this.getY(); |
||||
|
this.savevx = this.getVX(); |
||||
|
this.savevy = this.getVY(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public void restoreDynamicState() { |
||||
|
this.setX(savex); |
||||
|
this.setY(savey); |
||||
|
this.setVX(savevx); |
||||
|
this.setVY(savevy); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public boolean stopObject() { |
||||
|
boolean s = super.stopObject(); |
||||
|
|
||||
|
Playground pg = this.getPlayground(); |
||||
|
|
||||
|
LinkedList<GameObject> obstacles = pg.collectObjects("obstacle", false); |
||||
|
|
||||
|
this.saveDynamicState(); |
||||
|
this.applySpeedVector(); |
||||
|
|
||||
|
for (GameObject ob : obstacles) { |
||||
|
if (ob.collisionDetection(this.gameObject)) { |
||||
|
this.restoreDynamicState(); |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
this.restoreDynamicState(); |
||||
|
return s; |
||||
|
} |
||||
|
|
||||
|
public void onSpace(KeyEvent e, GameObject ego) { |
||||
|
double cgt = ego.getGameTime(); |
||||
|
if ((cgt - this.lastSpaceAt) > 0.1) { |
||||
|
super.onSpace(e, ego); |
||||
|
Music.music(this.shot); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,216 @@ |
|||||
|
package controller; |
||||
|
|
||||
|
import java.awt.Color; |
||||
|
import java.awt.event.KeyEvent; |
||||
|
import playground.*; |
||||
|
import gameobjects.*; |
||||
|
import java.util.*; |
||||
|
import org.apache.logging.log4j.Logger; |
||||
|
import org.apache.logging.log4j.LogManager; |
||||
|
|
||||
|
/** |
||||
|
* Controller using key events for up, down, left, right and space (shooting) to control the ego |
||||
|
* object behavior. |
||||
|
*/ |
||||
|
public class EgoController extends ObjectController { |
||||
|
// either rad is zero or width/height is zero (guaranteed by constructors) |
||||
|
private double rad = 0; |
||||
|
private double width = 0; |
||||
|
private double height = 0; |
||||
|
|
||||
|
private Integer pressedKey = null; |
||||
|
private Integer lastPressedKey = null; |
||||
|
private static Logger logger = LogManager.getLogger(EgoController.class); |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* constructor that gives the ego controller a radius to stop the ego object when it reaches the level boundaries. |
||||
|
* @param egoRad radius to use as a boundary stop for level borders (usually use the same dimensions as your ego object) |
||||
|
*/ |
||||
|
public EgoController(double egoRad) { |
||||
|
this.rad = egoRad; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* constructor that gives the ego controller a width and height to stop the ego object when it reaches the level boundaries. |
||||
|
* @param width width to use as a boundary stop for level borders (usually use the same dimensions as your ego object) |
||||
|
* @param height height to use as a boundary stop for level borders (usually use the same dimensions as your ego object) |
||||
|
*/ |
||||
|
public EgoController(double width, double height) { |
||||
|
this.width = width; |
||||
|
this.height = height; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public void onUp(KeyEvent kc, GameObject ego) { |
||||
|
ego.setVX(0.0); |
||||
|
ego.setVY(-SpaceInvadersLevel.EGOSPEED); |
||||
|
} |
||||
|
|
||||
|
public void onDown(KeyEvent kc, GameObject ego) { |
||||
|
ego.setVX(0.0); |
||||
|
ego.setVY(SpaceInvadersLevel.EGOSPEED); |
||||
|
} |
||||
|
|
||||
|
public void onLeft(KeyEvent kc, GameObject ego) { |
||||
|
ego.setVY(0.0); |
||||
|
ego.setVX(-SpaceInvadersLevel.EGOSPEED); |
||||
|
} |
||||
|
|
||||
|
public void onRight(KeyEvent kc, GameObject ego) { |
||||
|
ego.setVY(0.0); |
||||
|
ego.setVX(SpaceInvadersLevel.EGOSPEED); |
||||
|
} |
||||
|
|
||||
|
public void onStop(KeyEvent kc, GameObject ego) { |
||||
|
ego.setVY(0.0); |
||||
|
ego.setVX(0.0); |
||||
|
ego.setComponentProperty("controller", "setDummy", "NEW"); |
||||
|
ego.setComponentProperty("controller", "setDummy2", "XXX"); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** checks the position and respects level boundaries and own radius or width/height set on constructor. |
||||
|
* |
||||
|
* @return true if the object reached the boundaries of the level, false otherwise |
||||
|
*/ |
||||
|
public boolean stopObject() { |
||||
|
// check whether ego object is at level boundaries |
||||
|
// can use radius (rad) and width or height in one check as either rad or width/height is zero. |
||||
|
int pgSizeX = this.getPlayground().getSizeX(); |
||||
|
int pgSizeY = this.getPlayground().getSizeY(); |
||||
|
double ts = this.getTimestep(); |
||||
|
if (this.getX() + rad + (width/2d) + this.getVX() * ts >= pgSizeX |
||||
|
|| this.getX() - rad - (width/2d) + this.getVX() * ts < 0) { |
||||
|
return true; |
||||
|
} |
||||
|
if (this.getY() + rad + (height/2d) + this.getVY() * ts >= pgSizeY |
||||
|
|| this.getY() - rad - (height/2d) + this.getVY() * ts < 0) { |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** behavior for shooting on key space |
||||
|
* |
||||
|
* @param e KeyEvent of the space key |
||||
|
* @param ego EgoObject instance (used to determine position of shot object's start) |
||||
|
*/ |
||||
|
public void onSpace(KeyEvent e, GameObject ego) { |
||||
|
pressedKey = lastPressedKey; |
||||
|
lastPressedKey = null; |
||||
|
|
||||
|
// create unique name for object |
||||
|
// read Flag nextShot read (if not existing already it will be set) |
||||
|
// it will be updated by 1 and saved |
||||
|
Integer nextShot = |
||||
|
(Integer) this.getPlayground().getOrCreateLevelFlag("nextShot", Integer.valueOf(0)); |
||||
|
String shotName = "simpleShot" + nextShot++; |
||||
|
this.getPlayground().setLevelFlag("nextShot", nextShot); |
||||
|
|
||||
|
SimpleShotController simpleshot = new SimpleShotController(); |
||||
|
GameObject ss = new RectObject(shotName, this.getPlayground(), ego.getX(), ego.getY(), 0, |
||||
|
-1. * SpaceInvadersLevel.SHOTSPEED, 4, 12, Color.CYAN).addController(simpleshot); |
||||
|
ss.generateColliders(); |
||||
|
this.getPlayground().addObject(ss); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* updates position based on key events (mouse currently ignored) |
||||
|
*/ |
||||
|
public void updateObject() { |
||||
|
|
||||
|
logger.trace("Playground inst is"+this.getPlayground()) ; |
||||
|
Stack<KeyEvent> keyEvents = this.getPlayground().getKeyEvents(); |
||||
|
|
||||
|
GameObject ego = this.gameObject; |
||||
|
|
||||
|
while (!keyEvents.isEmpty()) { |
||||
|
|
||||
|
KeyEvent e = keyEvents.pop(); |
||||
|
boolean pressed = false; |
||||
|
boolean released = true; |
||||
|
int kc = e.getKeyCode(); |
||||
|
|
||||
|
if (e.paramString().indexOf("PRESSED") >= 0) { |
||||
|
pressed = true; |
||||
|
released = false; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Generelle Idee: Wenn eine Taste gedrückt wird wird sie gespeichert. wenn die zuvor |
||||
|
* gespeicherte Taste wieder losgelassen wird stoppt das Ego-Objekt. Falls vor dem Loslassen |
||||
|
* eine andere Taste gedrückt wird, wird diese gespeichert und die alte vergessen. Dh das |
||||
|
* loslassen der alten Taste stoppt das Objekt nicht. Spezialfall: space, das loslassen von |
||||
|
* space stoppt das Objekt nicht! |
||||
|
*/ |
||||
|
|
||||
|
if (pressed == true) { |
||||
|
lastPressedKey = pressedKey; |
||||
|
pressedKey = kc; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Nur eine losgelassene Taste die auch vorher gedrückt wurde stoppt das Objekt. Eine |
||||
|
* losgelassene Taste die nicht vorher gedrückt wurde bzw vergessen wurde stoppt das Objekt |
||||
|
* nicht |
||||
|
*/ |
||||
|
if (released == true) { |
||||
|
if (pressedKey != null) { |
||||
|
if (pressedKey.equals(kc)) { |
||||
|
ego.setVX(0); |
||||
|
ego.setVY(0); |
||||
|
pressedKey = null; |
||||
|
} |
||||
|
} |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
if (kc == KeyEvent.VK_LEFT) { |
||||
|
this.onLeft(e, ego); |
||||
|
} |
||||
|
|
||||
|
if (kc == KeyEvent.VK_RIGHT) { |
||||
|
this.onRight(e, ego); |
||||
|
} |
||||
|
|
||||
|
if (kc == KeyEvent.VK_UP) { |
||||
|
this.onUp(e, ego); |
||||
|
} |
||||
|
|
||||
|
if (kc == KeyEvent.VK_DOWN) { |
||||
|
this.onDown(e, ego); |
||||
|
} |
||||
|
|
||||
|
// stop |
||||
|
if (kc == KeyEvent.VK_Z) { |
||||
|
this.onStop(e, ego); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
// shot |
||||
|
if (kc == KeyEvent.VK_SPACE) { |
||||
|
// space is not registered! Releasing space does not stop the egoobject |
||||
|
this.onSpace(e, ego); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
boolean stop = this.stopObject(); |
||||
|
|
||||
|
if (stop) { |
||||
|
this.setVX(0); |
||||
|
this.setVY(0); |
||||
|
} |
||||
|
|
||||
|
// updateSpeed and position |
||||
|
applySpeedVector(); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,36 @@ |
|||||
|
package controller; |
||||
|
|
||||
|
|
||||
|
import org.apache.logging.log4j.Logger; |
||||
|
import org.apache.logging.log4j.LogManager; |
||||
|
|
||||
|
/** |
||||
|
* This class controls the space invaders. |
||||
|
*/ |
||||
|
public class EnemyController extends ObjectController { |
||||
|
|
||||
|
private static Logger logger = LogManager.getLogger(EnemyController.class); |
||||
|
|
||||
|
@Override |
||||
|
public void updateObject() { |
||||
|
logger.trace("updatre" + gameObject.getId()); |
||||
|
if ((gameObject.getX() > this.getPlayground().getSizeX() * 0.9) && (gameObject.getVX() > 0)) { |
||||
|
logger.trace("toleft!" + gameObject.getX()); |
||||
|
gameObject.setVX(-this.getVX()); |
||||
|
} |
||||
|
if ((gameObject.getX() < this.getPlayground().getSizeX() * 0.1) && (gameObject.getVX() < 0)) { |
||||
|
logger.trace("toright!" + gameObject.getX()); |
||||
|
gameObject.setVX(-this.getVX()); |
||||
|
} |
||||
|
|
||||
|
// if it reaches the bottom, delete it and deduct points |
||||
|
if (gameObject.getY() >= this.getPlayground().getSizeY()) { |
||||
|
this.getPlayground().deleteObject(gameObject.getId()); |
||||
|
// add to points counter |
||||
|
Integer pts = (Integer) this.getPlayground().getGlobalFlag("points"); |
||||
|
this.getPlayground().setGlobalFlag("points", pts - 200); |
||||
|
} |
||||
|
|
||||
|
applySpeedVector(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,24 @@ |
|||||
|
package controller; |
||||
|
|
||||
|
import org.apache.logging.log4j.Logger; |
||||
|
import org.apache.logging.log4j.LogManager; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Controls background stars. When they touch the bottom of the display they reappear on top. |
||||
|
*/ |
||||
|
public class FallingStarController extends ObjectController { |
||||
|
int rad = 3; |
||||
|
private static Logger logger = LogManager.getLogger(FallingStarController.class); |
||||
|
|
||||
|
|
||||
|
@Override |
||||
|
public void updateObject() { |
||||
|
logger.trace( |
||||
|
"+" + this.gameObject.getId() + " HO " + this.gameObject + "/" + this.getPlayground()); |
||||
|
if (this.getY() + rad >= this.getPlayground().getSizeY()) { |
||||
|
this.setY(10); |
||||
|
} |
||||
|
applySpeedVector(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,36 @@ |
|||||
|
package controller; |
||||
|
|
||||
|
/** |
||||
|
* Controls and abject that is deleted after a lifetime specified in the constructor, and when it |
||||
|
* leaves the display. |
||||
|
*/ |
||||
|
public class LimitedTimeController extends ObjectController { |
||||
|
int rad = 3; |
||||
|
double g0 = -1; |
||||
|
double duration = 0; |
||||
|
|
||||
|
/** |
||||
|
* Constructor. |
||||
|
* |
||||
|
* @param g0 int initial game time at creation |
||||
|
* @param duration int duration in seconds |
||||
|
*/ |
||||
|
public LimitedTimeController(double g0, double duration) { |
||||
|
this.g0 = g0; |
||||
|
this.duration = duration; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void updateObject() { |
||||
|
double gameTime = this.getPlayground().getGameTime(); |
||||
|
applySpeedVector(); |
||||
|
|
||||
|
if (gameObject.getY() >= getPlayground().getSizeY() || gameObject.getY() < 0 |
||||
|
|| gameObject.getX() >= getPlayground().getSizeX() || gameObject.getX() < 0 |
||||
|
|| (gameTime - g0) > duration) { |
||||
|
|
||||
|
this.getPlayground().deleteObject(this.gameObject.getId()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,47 @@ |
|||||
|
package controller; |
||||
|
|
||||
|
import controller.ObjectController; |
||||
|
import gameobjects.GameObject; |
||||
|
|
||||
|
import org.apache.logging.log4j.Logger; |
||||
|
import org.apache.logging.log4j.LogManager; |
||||
|
|
||||
|
public class MineController extends ObjectController { |
||||
|
int rad = 3; |
||||
|
|
||||
|
double xSpeed = 0.; |
||||
|
double lineSpeed = 0; |
||||
|
private static Logger logger = LogManager.getLogger(MineController.class); |
||||
|
|
||||
|
|
||||
|
public MineController(double lineSpeed) { |
||||
|
this.lineSpeed = lineSpeed; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void updateObject() { |
||||
|
|
||||
|
if (gameObject.getY() >= this.getPlayground().getSizeY() - 10) { |
||||
|
this.gameObject.setVY(0); |
||||
|
if (xSpeed == 0.) { |
||||
|
GameObject ego = getPlayground().getObject("ego"); |
||||
|
double egoXPos = ego.getX(); |
||||
|
if (egoXPos > this.gameObject.getX()) { |
||||
|
xSpeed = 50; |
||||
|
} else { |
||||
|
xSpeed = -50; |
||||
|
} |
||||
|
this.gameObject.setVX(xSpeed); |
||||
|
|
||||
|
} |
||||
|
this.gameObject.setVX(xSpeed); |
||||
|
|
||||
|
} |
||||
|
if (this.gameObject.getX() < 0 || (this.gameObject.getX() > this.getPlayground().getSizeX())) { |
||||
|
logger.debug("deleting" + this.gameObject.getId()); |
||||
|
getPlayground().deleteObject(this.gameObject.getId()); |
||||
|
} |
||||
|
|
||||
|
applySpeedVector(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,110 @@ |
|||||
|
package controller; |
||||
|
|
||||
|
import gameobjects.GameObject; |
||||
|
import playground.Playground; |
||||
|
import org.apache.logging.log4j.Logger; |
||||
|
import org.apache.logging.log4j.LogManager; |
||||
|
|
||||
|
/** |
||||
|
* Class that controls the LOGICAL behavior of an object independently of how it is displayed or |
||||
|
* drawn. The most important method here is {@link #updateObject}: this method is, by various |
||||
|
* indirections, called exactly once per game time step for every object that is on the playground. |
||||
|
* It has, by virtue of the member variables {@link #gameObject} full access to |
||||
|
* <ul> |
||||
|
* <li>the object it is controlling |
||||
|
* <li>the playground this object belongs to |
||||
|
* </ul> |
||||
|
* Typically, updateObject would check whether an object leaves the screen to react appropriately. |
||||
|
* In that case the object can be marked for deletion (by adding it to the flag "deleted" that is |
||||
|
* always defined for any playground), but of course other reactions are possible like rebounding, |
||||
|
* emerging on the other side, ... |
||||
|
*/ |
||||
|
|
||||
|
public abstract class ObjectController { |
||||
|
protected GameObject gameObject = null; |
||||
|
protected String dummy = ""; |
||||
|
|
||||
|
private static Logger logger = LogManager.getLogger(ObjectController.class); |
||||
|
|
||||
|
public void setObject(GameObject gameObject) { |
||||
|
this.gameObject = gameObject; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public void setDummy(String x) { |
||||
|
logger.debug("DUMMY called!!"); |
||||
|
this.dummy = x; |
||||
|
logger.debug("DUMMY is now:" + dummy); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Is called once every game time step by the game itself. NEVER call this directly, not |
||||
|
* necessary!<br> |
||||
|
* The method can do whatever it likes, including nothing. The attribute {@link #gameObject} |
||||
|
* contains a reference to the controlled object, which allows access to the Playground the object |
||||
|
* belongs to (useful for getting the pixel size in x and y of the playing field.<br> |
||||
|
* <strong>Recommended:</strong> when implementing this method, call at the end |
||||
|
* {@link #applySpeedVector() } method. This is a helper method that sets the new x,y coordinates |
||||
|
* for the {@link #gameObject} correctly. |
||||
|
*/ |
||||
|
public abstract void updateObject(); |
||||
|
|
||||
|
/** |
||||
|
* Convenience method: simply moves the object forward one step from its present position, using |
||||
|
* its present speed. |
||||
|
*/ |
||||
|
public void applySpeedVector() { |
||||
|
double ts = this.getPlayground().getTimestep(); |
||||
|
this.setX(this.getX() + this.getVX() * ts); |
||||
|
gameObject.setY(this.getY() + this.getVY() * ts); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public double getTimestep() { |
||||
|
return this.gameObject.getPlayground().getTimestep(); |
||||
|
} |
||||
|
|
||||
|
public double getX() { |
||||
|
return this.gameObject.getX(); |
||||
|
} |
||||
|
|
||||
|
public double getY() { |
||||
|
return this.gameObject.getY(); |
||||
|
} |
||||
|
|
||||
|
public double getVX() { |
||||
|
return this.gameObject.getVX(); |
||||
|
} |
||||
|
|
||||
|
public double getVY() { |
||||
|
return this.gameObject.getVY(); |
||||
|
} |
||||
|
|
||||
|
public void setX(double x) { |
||||
|
this.gameObject.setX(x); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public void setY(double y) { |
||||
|
this.gameObject.setY(y); |
||||
|
} |
||||
|
|
||||
|
public void setVX(double vx) { |
||||
|
this.gameObject.setVX(vx); |
||||
|
} |
||||
|
|
||||
|
public void setVY(double vy) { |
||||
|
this.gameObject.setVY(vy); |
||||
|
} |
||||
|
|
||||
|
public Playground getPlayground() { |
||||
|
return this.gameObject.getPlayground(); |
||||
|
} |
||||
|
|
||||
|
public void setPlayground(Playground playground) { |
||||
|
this.gameObject.setPlayground(playground); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,16 @@ |
|||||
|
package controller; |
||||
|
|
||||
|
public class SimpleShotController extends ObjectController { |
||||
|
int rad = 3; |
||||
|
|
||||
|
@Override |
||||
|
public void updateObject() { |
||||
|
if (gameObject.getY() < 0) { |
||||
|
// LinkedList<String> deleteList = (LinkedList<String>) playground.getFlag("delete"); |
||||
|
// deleteList.add(gameObject.getId()); |
||||
|
getPlayground().deleteObject(this.gameObject.getId()); |
||||
|
} else { |
||||
|
applySpeedVector(); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,32 @@ |
|||||
|
package controller; |
||||
|
|
||||
|
import org.apache.logging.log4j.Logger; |
||||
|
import org.apache.logging.log4j.LogManager; |
||||
|
|
||||
|
public class ZickZackController extends EnemyController { |
||||
|
protected double g0; |
||||
|
protected double dt; |
||||
|
protected double lastMod = -1; |
||||
|
|
||||
|
private static Logger logger = LogManager.getLogger(ZickZackController.class); |
||||
|
|
||||
|
public ZickZackController(double gameTime, double dt) { |
||||
|
super(); |
||||
|
this.dt = dt; |
||||
|
this.g0 = gameTime; |
||||
|
} |
||||
|
|
||||
|
public void updateObject() { |
||||
|
double gameTime = this.getPlayground().getGameTime(); |
||||
|
logger.trace("current Object x: "+gameObject.getX()); |
||||
|
double mod = (gameTime - this.g0) % this.dt; |
||||
|
if (mod < lastMod) { |
||||
|
gameObject.setVX(-1.0 * gameObject.getVX()); |
||||
|
logger.trace("inverting VX"); |
||||
|
} |
||||
|
lastMod = mod; |
||||
|
|
||||
|
super.updateObject(); |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
/** |
||||
|
* The controller package contains Object controllers that govern an objects behavior, without being |
||||
|
* involved in its collision or drawing properties. Object controllers react to user actions/inputs |
||||
|
* and govern for example the movement of {@link gameobjects.GameObject} instances. They can access |
||||
|
* their parent objects' properties and, by indirection, the properties and methods of the |
||||
|
* associated level. <br> |
||||
|
* Controllers should be designed in such a way that they implement behavior that is |
||||
|
* level-independent. All level-dependent behavior should be implemented in |
||||
|
* {@link playground.Playground#applyGameLogic}. |
||||
|
*/ |
||||
|
package controller; |
@ -0,0 +1,42 @@ |
|||||
|
package gameobjects; |
||||
|
|
||||
|
import java.util.LinkedList; |
||||
|
import playground.Playground; |
||||
|
import playground.Animation; |
||||
|
import collider.Collider; |
||||
|
import collider.RectCollider; |
||||
|
import rendering.*; |
||||
|
import org.apache.logging.log4j.Logger; |
||||
|
import org.apache.logging.log4j.LogManager; |
||||
|
|
||||
|
|
||||
|
public class AnimatedGameobject extends GameObject { |
||||
|
|
||||
|
protected AnimationArtist animArtist; |
||||
|
private static Logger logger = LogManager.getLogger(AnimationArtist.class); |
||||
|
|
||||
|
|
||||
|
// auto-generates collider according to box width/height |
||||
|
public GameObject generateColliders() { |
||||
|
logger.debug("Created animated Obj "+ this.animArtist.getW()+" "+this.animArtist.getH()) ; |
||||
|
double w = this.animArtist.getW() ; |
||||
|
double h = this.animArtist.getH() ; |
||||
|
this.addCollider(new RectCollider("RectColl_" + this.id, this, w, |
||||
|
h)) ; |
||||
|
|
||||
|
logger.info("ANIMGO-COLL ID="+this.getId()+" WH= "+w+"/"+h) ; |
||||
|
return this ; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public AnimatedGameobject(String id, Playground pg, double x, double y, double vx, double vy, |
||||
|
double scale, Animation anim, double t0, String abspielmodus) { |
||||
|
super(id, pg, x, y, vx, vy); // Konstruktor-Aufruf GameObject |
||||
|
|
||||
|
this.artist = new AnimationArtist(this, anim, t0, abspielmodus, scale); |
||||
|
this.animArtist = (AnimationArtist) (this.artist); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,34 @@ |
|||||
|
package gameobjects; |
||||
|
|
||||
|
|
||||
|
import java.awt.Color; |
||||
|
import collider.*; |
||||
|
import java.awt.Graphics2D; |
||||
|
import java.awt.image.BufferedImage; |
||||
|
import java.io.File; |
||||
|
import java.io.IOException; |
||||
|
import java.util.LinkedList; |
||||
|
import javax.imageio.ImageIO; |
||||
|
import collider.Collider; |
||||
|
import controller.ObjectController; |
||||
|
import playground.Playground; |
||||
|
import rendering.*; |
||||
|
|
||||
|
public class EgoObject extends GameObject { |
||||
|
|
||||
|
double egoRad = 0; |
||||
|
|
||||
|
public EgoObject(String id, Playground pg, double x, double y, double vx, double vy, |
||||
|
double egoRad) { |
||||
|
super(id, pg, x, y, vx, vy); |
||||
|
this.egoRad = egoRad; |
||||
|
this.artist = new CircleArtist(this, egoRad, Color.WHITE); |
||||
|
} |
||||
|
|
||||
|
public GameObject generateColliders() { |
||||
|
CircleCollider coll = new CircleCollider("coll", this, this.egoRad); |
||||
|
this.addCollider(coll); |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,28 @@ |
|||||
|
package gameobjects; |
||||
|
|
||||
|
import java.awt.Color; |
||||
|
import java.util.LinkedList; |
||||
|
import collider.*; |
||||
|
import playground.Playground; |
||||
|
import rendering.*; |
||||
|
|
||||
|
public class FallingStar extends GameObject { |
||||
|
|
||||
|
private Color color = Color.WHITE; |
||||
|
|
||||
|
protected double rad = -1; |
||||
|
|
||||
|
|
||||
|
public FallingStar(String id, Playground playground, double x, double y, double vx, double vy, |
||||
|
Color color, double rad) { |
||||
|
super(id, playground, x, y, vx, vy); |
||||
|
this.rad = rad; |
||||
|
this.color = color; |
||||
|
LinkedList<Collider> cols = new LinkedList<Collider>(); |
||||
|
CircleCollider cc = new CircleCollider("cc", this, rad); |
||||
|
cols.add(cc); |
||||
|
setColliders(cols); |
||||
|
this.artist = new CircleArtist(this, rad, color); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,377 @@ |
|||||
|
package gameobjects; |
||||
|
|
||||
|
import java.awt.Graphics2D; |
||||
|
import java.awt.image.BufferedImage; |
||||
|
import java.util.LinkedList; |
||||
|
import java.lang.reflect.*; |
||||
|
import rendering.*; |
||||
|
import collider.Collider; |
||||
|
import controller.ObjectController; |
||||
|
import playground.Playground; |
||||
|
import org.apache.logging.log4j.Logger; |
||||
|
import org.apache.logging.log4j.LogManager; |
||||
|
|
||||
|
/** |
||||
|
* The class {@link GameObject} represents a (possibly animated) object appearing in a level of the |
||||
|
* game. It is therefore attached to an instance of the class {@link Playground}. A GameObject has |
||||
|
* at least the following properties: |
||||
|
* <ul> |
||||
|
* <li>2D screen position |
||||
|
* <li>2D speed |
||||
|
* <li>a name that is unique within a certain {@link Playground}<br> |
||||
|
* <li>a reference to the {@link Playground} object it belongs to<br> |
||||
|
* <li>a reference to an instance of {@link controller.ObjectController} that handles the movement |
||||
|
* logic of the object<br> |
||||
|
* <li>a (circular) radius for simple collision checking. This may be handled differently in |
||||
|
* subclasses<br> |
||||
|
* </ul> |
||||
|
* The main task of GameObject, or its subclasses, is to draw the object on the screen, which is |
||||
|
* handles by the {@link #draw(Graphics2D)} method. It is this method that must be redefined if a |
||||
|
* new appearance should be realized. For introducing new behavior, it is sufficient to supply a |
||||
|
* different {@link controller.ObjectController} instance when constructing a GameObject. |
||||
|
*/ |
||||
|
public abstract class GameObject { |
||||
|
|
||||
|
public static final int RADIUS = 0; |
||||
|
public static final int RECTANGLE = 1; |
||||
|
public static final int MASK = 2; |
||||
|
|
||||
|
protected Artist artist = null; |
||||
|
|
||||
|
public String id = null; |
||||
|
protected double x = 0; |
||||
|
protected double vx = 0; |
||||
|
protected double y = 0; |
||||
|
protected double vy = 0; |
||||
|
protected BufferedImage mask = null; // UNDONE implement usage of mask |
||||
|
protected boolean active = true; |
||||
|
// public int collisionMode = GameObject.RADIUS; |
||||
|
protected Playground playground = null; |
||||
|
|
||||
|
private ObjectController controller = null; |
||||
|
public LinkedList<Collider> scol; |
||||
|
|
||||
|
private static Logger logger = LogManager.getLogger(GameObject.class); |
||||
|
|
||||
|
/** |
||||
|
* Constructor to initialize a GameObject, respectively set the current {@link Playground} |
||||
|
* instance this GameObject belongs to. |
||||
|
* |
||||
|
* @param id unique ID for this GameObject (should not be null or empty String) |
||||
|
* @param playground the Playground the GameObject belongs to (should not be null) |
||||
|
* @param x initial screen position in direction horizontal (positive value including zero) |
||||
|
* @param y initial screen position in direction vertical (positive value including zero) |
||||
|
* @param vx initial speed (velocity) in direction horizontal (can be negative, zero, positive) |
||||
|
* @param vy initial speed (velocity) in direction horizontal (can be negative, zero, positive) |
||||
|
*/ |
||||
|
public GameObject(String id, Playground playground, double x, double y, double vx, double vy) { |
||||
|
setX(x); |
||||
|
setY(y); |
||||
|
setVX(vx); |
||||
|
setVY(vy); |
||||
|
this.id = id; |
||||
|
this.controller = null; |
||||
|
this.scol = new LinkedList<Collider>(); |
||||
|
this.setPlayground(playground); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Constructor to initialize a GameObject, respectively set the current Playground instance this |
||||
|
* GameObject belongs to. |
||||
|
* |
||||
|
* @param id unique ID for this GameObject (should not be null or empty String) |
||||
|
* @param playground the Playground the GameObject belongs to (should not be null) |
||||
|
* @param controller controller instance to be used for this GameObject (can be null) |
||||
|
* @param x initial screen position in direction horizontal (positive value including zero) |
||||
|
* @param y initial screen position in direction vertical (positive value including zero) |
||||
|
* @param vx initial speed (velocity) in direction horizontal (can be negative, zero, positive) |
||||
|
* @param vy initial speed (velocity) in direction horizontal (can be negative, zero, positive) |
||||
|
*/ |
||||
|
public GameObject(String id, Playground playground, ObjectController controller, double x, |
||||
|
double y, double vx, double vy) { |
||||
|
this(id, playground, x, y, vx, vy); |
||||
|
this.controller = controller; |
||||
|
if (this.controller != null) { |
||||
|
this.controller.setObject(this); |
||||
|
this.controller.setPlayground(playground); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* sets colliders. |
||||
|
* |
||||
|
* @param l LinkedList of Colliders. |
||||
|
*/ |
||||
|
public void setColliders(LinkedList<Collider> l) { |
||||
|
this.scol = l; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* generates and sets collider(s) for this GameObject. This implementation does nothing. Intended |
||||
|
* to be overridden by subclasses. |
||||
|
* |
||||
|
* @return instance of this GameObject (this). |
||||
|
*/ |
||||
|
public GameObject generateColliders() { |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sets the controller to use for this GameObject's logical behavior. |
||||
|
* |
||||
|
* @param c instance to be used. |
||||
|
* @return the current instance (this). |
||||
|
*/ |
||||
|
public GameObject addController(ObjectController c) { |
||||
|
this.controller = c; |
||||
|
this.controller.setObject(this); |
||||
|
this.controller.setPlayground(playground); |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sets the artist to be used for drawing the object onto visible canvas area. |
||||
|
* |
||||
|
* @param a instance to be used for calling {@link rendering.Artist#draw(Graphics2D)}. |
||||
|
* @return the current instance (this). |
||||
|
*/ |
||||
|
public GameObject addArtist(Artist a) { |
||||
|
this.artist = a; |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* saves the collider in the internal list of Colliders to be used for this GameObject. |
||||
|
* |
||||
|
* @param c instance to be added to internal list |
||||
|
*/ |
||||
|
public void addCollider(Collider c) { |
||||
|
if (this.scol == null) { |
||||
|
this.scol = new LinkedList<Collider>(); |
||||
|
} |
||||
|
this.scol.add(c); |
||||
|
} |
||||
|
|
||||
|
public Playground getPlayground() { |
||||
|
return playground; |
||||
|
} |
||||
|
|
||||
|
public void setPlayground(Playground playground) { |
||||
|
this.playground = playground; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* calls via reflection a method of a component if this GameObjects instance and provides the |
||||
|
* given value as String parameter. |
||||
|
* |
||||
|
* @param comp class name of GameObject component. Currently only "controller" is supported, |
||||
|
* otherwise nothing happens. |
||||
|
* @param property method name of the component to call. |
||||
|
* @param value argument to pass to the method as String parameter. |
||||
|
*/ |
||||
|
public void setComponentProperty(String comp, String property, Object value) { |
||||
|
if (comp.equals("controller")) { |
||||
|
Class<? extends Object> clO = this.controller.getClass(); |
||||
|
for (Method m : clO.getMethods()) { |
||||
|
if (m.getName().indexOf(property) != -1) { |
||||
|
logger.debug("Method " + property + " found!!"); |
||||
|
try { |
||||
|
m.invoke(this.getObjectController(), value); |
||||
|
} catch (Exception e) { |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void setObjectFlag(String flag, Object value) { |
||||
|
this.playground.setLevelFlag(this.id + "/" + flag, value); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public Object getObjectFlag(String flag) { |
||||
|
return this.playground.getLevelFlag(this.id + "/" + flag); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public Object getOrCreateObjectFlag(String flag, Object createValue) { |
||||
|
return this.playground.getOrCreateLevelFlag(this.id + "/" + flag, createValue); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
public boolean isActive() { |
||||
|
return active; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public GameObject setActive(boolean flag) { |
||||
|
this.active = flag; |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* return the unique object ID. |
||||
|
* |
||||
|
* @return unique object ID |
||||
|
*/ |
||||
|
public String getId() { |
||||
|
return id; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* gets the screen X position. |
||||
|
* |
||||
|
* @return screen x position |
||||
|
*/ |
||||
|
public double getX() { |
||||
|
return x; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* gets the screen Y position. |
||||
|
* |
||||
|
* @return screen Y position |
||||
|
*/ |
||||
|
public double getY() { |
||||
|
return y; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* gets the screen X speed in pixels per frame. |
||||
|
* |
||||
|
* @return screen x speed |
||||
|
*/ |
||||
|
public double getVX() { |
||||
|
return vx; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* gets the screen Y speed in pixels per frame. |
||||
|
* |
||||
|
* @return screen y speed |
||||
|
*/ |
||||
|
public double getVY() { |
||||
|
return vy; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* set screen x position. |
||||
|
* |
||||
|
* @param x new position |
||||
|
*/ |
||||
|
public void setX(double x) { |
||||
|
if (this.active == true) { |
||||
|
this.x = x; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* set screen y position. |
||||
|
* |
||||
|
* @param y new position |
||||
|
*/ |
||||
|
public void setY(double y) { |
||||
|
if (this.active == true) { |
||||
|
this.y = y; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* set screen x speed in pixel per frame |
||||
|
* |
||||
|
* @param vx new x speed |
||||
|
*/ |
||||
|
public void setVX(double vx) { |
||||
|
if (this.active == true) { |
||||
|
this.vx = vx; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* set screen y speed in pixel per frame. |
||||
|
* |
||||
|
* @param vy new y speed. |
||||
|
*/ |
||||
|
public void setVY(double vy) { |
||||
|
if (this.active == true) { |
||||
|
this.vy = vy; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sets a new object controller (replaces any former one). |
||||
|
* |
||||
|
* @param controller An instance of {@link controller.ObjectController} or one of its subclasses. |
||||
|
*/ |
||||
|
public void setObjectController(ObjectController controller) { |
||||
|
this.controller = controller; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Access to object controller. |
||||
|
* |
||||
|
* @return the controller for this object. |
||||
|
*/ |
||||
|
public ObjectController getObjectController() { |
||||
|
return this.controller; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public double getGameTime() { |
||||
|
return this.playground.getGameTime(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Collision detection implemented by iteration through the own list of {@link collider.Collider} |
||||
|
* and calling their {@link collider.Collider#collidesWith(Collider)} method to check collision |
||||
|
* with the given parameter instance of other {@link GameObject}. |
||||
|
* |
||||
|
* @param other instance of the other GameObject to check collision with |
||||
|
* @return true if collision is detected, false otherwise |
||||
|
*/ |
||||
|
public boolean collisionDetection(GameObject other) { |
||||
|
if (this.scol == null) { |
||||
|
return false; |
||||
|
} |
||||
|
for (Collider c : this.scol) { |
||||
|
logger.trace(other.id); |
||||
|
for (Collider o : other.scol) { |
||||
|
if (c.collidesWith(o)) { |
||||
|
logger.trace(c.id + " " + o.id); |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return false; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* triggers this GameObjects own controller (if set) to update the object. |
||||
|
* |
||||
|
* @see GameObject#controller |
||||
|
*/ |
||||
|
public void updateObject() { |
||||
|
if (this.controller != null) { |
||||
|
controller.updateObject(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Draws the object in its current state. Is called by the game engine, should NOT be called |
||||
|
* otherwise. |
||||
|
* |
||||
|
* @param g object that has all the necessary drawing functionalities |
||||
|
*/ |
||||
|
public void draw(Graphics2D g) { |
||||
|
if (this.artist != null) { |
||||
|
this.artist.draw(g); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,76 @@ |
|||||
|
package gameobjects; |
||||
|
|
||||
|
import java.awt.Color; |
||||
|
import java.io.File; |
||||
|
import collider.RectCollider; |
||||
|
import playground.Playground; |
||||
|
import playground.SpaceInvadersLevel; |
||||
|
import rendering.RectArtist; |
||||
|
|
||||
|
/** |
||||
|
* A rectangle object. <br> |
||||
|
* If {@link #generateColliders()} is called, it generates a RectCollider with id-prefix |
||||
|
* "shotcollider_" and registers it for this RectObject. |
||||
|
* |
||||
|
*/ |
||||
|
public class RectObject extends GameObject { |
||||
|
|
||||
|
/** width in pixels of the RectObject (> 0) */ |
||||
|
protected double width; |
||||
|
/** height in pixels of the RectObject (> 0) */ |
||||
|
protected double height; |
||||
|
|
||||
|
/** |
||||
|
* Initializes the RectObject with a suitable RectArtist for drawing the RectObject. |
||||
|
* |
||||
|
* @param id String unique name to be used. |
||||
|
* @param pg {@link Playground} instance this RectObject belongs to (the level it belongs to). |
||||
|
* @param x position in horizontal direction in pixels (zero or positive number). |
||||
|
* @param y position in vertical direction in pixels (zero or positive number). |
||||
|
* @param vx speed/velocity in horizontal direction in pixels (negative, zero or positive number). |
||||
|
* @param vy speed/velocity in vertical direction in pixels (negative, zero or positive number). |
||||
|
* @param width in pixels |
||||
|
* @param height in pixels |
||||
|
* @param color solid color for the whole object, used to initialize an instance of |
||||
|
* {@link rendering.RectArtist} used for this RectObject. |
||||
|
*/ |
||||
|
public RectObject(String id, Playground pg, double x, double y, double vx, double vy, |
||||
|
double width, double height, Color color) { |
||||
|
super(id, pg, x, y, vx, vy); |
||||
|
|
||||
|
this.width = width; |
||||
|
this.height = height; |
||||
|
|
||||
|
this.artist = new RectArtist(this, width, height, color); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* generates a new {@link RectCollider} with id-prefix "shotcollider_" and registers it for 'this' |
||||
|
* [@link RectObject}. The {@link RectCollider} uses the same dimensions ({@link #width} and {@link #height}) as this RectObject. |
||||
|
* |
||||
|
* @return this RectObject itself |
||||
|
*/ |
||||
|
public RectObject generateColliders() { |
||||
|
this.scol.add(new RectCollider("shotcollider_" + id, this, this.width, this.height)); |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** Getter for the width |
||||
|
* |
||||
|
* @return double width value as set by constructor |
||||
|
*/ |
||||
|
public double getWidth() { |
||||
|
return this.width; |
||||
|
} |
||||
|
|
||||
|
/** Getter for the height |
||||
|
* |
||||
|
* @return double height value as set by constructor |
||||
|
*/ |
||||
|
public double getHeight() { |
||||
|
return this.height; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,70 @@ |
|||||
|
package gameobjects; |
||||
|
|
||||
|
import java.awt.Color; |
||||
|
import java.awt.Font; |
||||
|
import java.awt.Graphics2D; |
||||
|
import java.awt.font.FontRenderContext; |
||||
|
import java.awt.font.TextAttribute; |
||||
|
import java.text.AttributedString; |
||||
|
import java.util.LinkedList; |
||||
|
import collider.*; |
||||
|
import controller.ObjectController; |
||||
|
import playground.Playground; |
||||
|
import rendering.*; |
||||
|
|
||||
|
/** |
||||
|
* Convenience Class subclassing {@link GameObject}, directly instanciating {@link TextArtist} a |
||||
|
* subclass of {@link Artist} that draws a text. The controller is left undefined, the collider as |
||||
|
* well. However, a single call to the overwritten method {@link #generateColliders} will in fact |
||||
|
* generate a {@link RectCollider} of just the right size for the text. |
||||
|
* |
||||
|
*/ |
||||
|
public class TextObject extends GameObject { |
||||
|
|
||||
|
private String text = null; |
||||
|
protected double rx, ry; |
||||
|
|
||||
|
public String getText() { |
||||
|
return this.text; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Constructor. |
||||
|
* |
||||
|
* @param id object name |
||||
|
* @param playground containing {@link Playground} instance |
||||
|
* @param x positionx |
||||
|
* @param y positiony |
||||
|
* @param vx speedx |
||||
|
* @param vy speedy |
||||
|
* @param size font size in Pixel |
||||
|
* @param text String to be displayed |
||||
|
* @param textColor text color, see java.awt.Color |
||||
|
*/ |
||||
|
public TextObject(String id, Playground playground, double x, double y, double vx, double vy, |
||||
|
String text, int size, Color textColor) { |
||||
|
super(id, playground, x, y, vx, vy); |
||||
|
|
||||
|
this.artist = new TextArtist(this, text, size, textColor); |
||||
|
|
||||
|
this.setColliders(new LinkedList<Collider>()); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
public void setText(String s) { |
||||
|
this.text = s; |
||||
|
((TextArtist) this.artist).setText(s); |
||||
|
} |
||||
|
|
||||
|
public TextObject generateColliders() { |
||||
|
// we need to Cast to TextArtist as we want to access Width and Height of text |
||||
|
TextArtist kruecke = (TextArtist) (this.artist); |
||||
|
|
||||
|
this.scol.clear(); |
||||
|
this.scol.add(new RectCollider("rect", this, kruecke.getTextWidth(), kruecke.getTextHeight())); |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
|
||||
|
<configuration status="OFF"> |
||||
|
<appenders> |
||||
|
|
||||
|
<Console name="Console" target="SYSTEM_OUT"> |
||||
|
<PatternLayout pattern="%d %-5level %logger{36} - %msg%n" /> |
||||
|
</Console> |
||||
|
|
||||
|
<File name="File" fileName="log\log4j.log"> |
||||
|
<PatternLayout pattern="%d %-5level %logger{36} - %msg%n" /> |
||||
|
</File> |
||||
|
|
||||
|
</appenders> |
||||
|
|
||||
|
<loggers> |
||||
|
|
||||
|
<root level="warn"> |
||||
|
<appender-ref ref="Console" /> |
||||
|
<appender-ref ref="File" /> |
||||
|
</root> |
||||
|
|
||||
|
<Logger name="base.GameLoop" level="info"> |
||||
|
</Logger> |
||||
|
|
||||
|
<Logger name="playground" level="info"> |
||||
|
</Logger> |
||||
|
|
||||
|
</loggers> |
||||
|
</configuration> |
@ -0,0 +1,84 @@ |
|||||
|
package playground; |
||||
|
|
||||
|
|
||||
|
import java.awt.image.BufferedImage; |
||||
|
|
||||
|
import javax.imageio.ImageIO; |
||||
|
import java.io.File; |
||||
|
import java.io.*; |
||||
|
import java.io.FileNotFoundException; |
||||
|
import java.util.LinkedList; |
||||
|
import java.util.Locale; |
||||
|
import java.util.Scanner; |
||||
|
import java.nio.file.Path; |
||||
|
import java.nio.file.Paths; |
||||
|
|
||||
|
import org.apache.logging.log4j.Logger; |
||||
|
import org.apache.logging.log4j.LogManager; |
||||
|
|
||||
|
public class Animation { |
||||
|
|
||||
|
public LinkedList<String> fileList = null; |
||||
|
public LinkedList<Double> showtimeList = null; |
||||
|
public LinkedList<BufferedImage> imageList = null; |
||||
|
|
||||
|
private static Logger logger = LogManager.getLogger(Animation.class); |
||||
|
|
||||
|
public Animation(String datName) { |
||||
|
|
||||
|
Scanner scanner; |
||||
|
this.fileList = new LinkedList<String>(); |
||||
|
this.showtimeList = new LinkedList<Double>(); |
||||
|
this.imageList = new LinkedList<BufferedImage>(); |
||||
|
|
||||
|
try { |
||||
|
scanner = new Scanner(new File(datName), "UTF-8"); |
||||
|
|
||||
|
scanner.useLocale(Locale.GERMANY); |
||||
|
|
||||
|
String zeile; |
||||
|
double zeit; |
||||
|
int it = 0; |
||||
|
|
||||
|
while (scanner.hasNext()) { |
||||
|
if (scanner.hasNextDouble()) { |
||||
|
zeit = scanner.nextDouble(); |
||||
|
showtimeList.add(zeit); |
||||
|
} else { |
||||
|
zeile = scanner.next(); |
||||
|
Path basePath = Paths.get(datName); |
||||
|
String file = basePath.getParent().toString() + "/" + zeile; |
||||
|
fileList.add(file); |
||||
|
try { |
||||
|
this.imageList.add(ImageIO.read(new File(file))); |
||||
|
logger.info("img added " + file); |
||||
|
|
||||
|
} catch (IOException e) { |
||||
|
logger.warn(file + " not found!!"); |
||||
|
} |
||||
|
|
||||
|
it++; |
||||
|
logger.trace(basePath.getParent().toString() + "/" + zeile); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
scanner.close(); |
||||
|
|
||||
|
} catch (FileNotFoundException e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public LinkedList<String> getFileList() { |
||||
|
return this.fileList; |
||||
|
} |
||||
|
|
||||
|
public LinkedList<Double> getShowtimeList() { |
||||
|
return this.showtimeList; |
||||
|
} |
||||
|
|
||||
|
public LinkedList<BufferedImage> getImageList() { |
||||
|
return this.imageList; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,55 @@ |
|||||
|
package playground; |
||||
|
|
||||
|
import java.io.*; |
||||
|
import java.util.Scanner; |
||||
|
|
||||
|
import org.apache.logging.log4j.Logger; |
||||
|
import org.apache.logging.log4j.LogManager; |
||||
|
|
||||
|
|
||||
|
// Klasse um Highscore umzusetzen |
||||
|
public class HighscoreManager { |
||||
|
Scanner s; |
||||
|
private static Logger logger = LogManager.getLogger(HighscoreManager.class); |
||||
|
|
||||
|
public HighscoreManager() { |
||||
|
try { |
||||
|
File f = new File("./highscore.txt"); |
||||
|
if (!f.exists()) { |
||||
|
logger.warn("WARNING: Highscore file was not found and reset"); |
||||
|
writeHSToFile(0, -1); |
||||
|
} |
||||
|
s = new Scanner(f); |
||||
|
} catch (FileNotFoundException e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public int readHSFromFile() { |
||||
|
if (s.hasNext()) { |
||||
|
int highscore = s.nextInt(); |
||||
|
return highscore; |
||||
|
} |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
public static void writeHSToFile(Integer pts, Integer highscore) { |
||||
|
String highscore2 = String.valueOf(pts); |
||||
|
BufferedWriter bw; |
||||
|
try { |
||||
|
if (pts > highscore) { |
||||
|
FileWriter fw = new FileWriter("./highscore.txt"); |
||||
|
bw = new BufferedWriter(fw); |
||||
|
bw.write(highscore2); |
||||
|
bw.close(); |
||||
|
logger.info("Highscore file was opened and saved score: " + highscore2); |
||||
|
} |
||||
|
} catch (IOException e) { |
||||
|
logger.error("File for Highscore not writeable! Score lost."); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void closeFile() { |
||||
|
s.close(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,15 @@ |
|||||
|
package playground; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* extends {@link SpaceInvadersLevel} with a boring start message |
||||
|
*/ |
||||
|
public class Level1 extends SpaceInvadersLevel { |
||||
|
|
||||
|
@Override |
||||
|
protected String getStartupMessage() { |
||||
|
return "Get ready for boring level 1!"; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,17 @@ |
|||||
|
package playground; |
||||
|
|
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* extends extends {@link SpaceInvadersLevel} with a different startup message. |
||||
|
*/ |
||||
|
public class Level2 extends SpaceInvadersLevel { |
||||
|
|
||||
|
@Override |
||||
|
protected String getStartupMessage() { |
||||
|
return "Get ready for level 2!"; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,40 @@ |
|||||
|
package playground; |
||||
|
|
||||
|
import org.apache.logging.log4j.LogManager; |
||||
|
import org.apache.logging.log4j.Logger; |
||||
|
import controller.ObjectController; |
||||
|
import controller.ZickZackController; |
||||
|
import gameobjects.AnimatedGameobject; |
||||
|
import gameobjects.GameObject; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* extends {@link SpaceInvadersLevel} with a ZigZack move of the enemies in |
||||
|
* {@link #createSingleEnemy(String, double, double, double, double, ObjectController, double)} and |
||||
|
* sets a different {@link #getStartupMessage()}. |
||||
|
*/ |
||||
|
public class Level3 extends SpaceInvadersLevel { |
||||
|
|
||||
|
private static Logger logger = LogManager.getLogger(Level3.class); |
||||
|
|
||||
|
@Override |
||||
|
protected String getStartupMessage() { |
||||
|
return "Get ready for level 3!!!"; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@Override |
||||
|
protected GameObject createSingleEnemy(String name, double x_enemy, double y_enemy, |
||||
|
double vx_enemy, double vy_enemy, ObjectController enemyController, double gameTime) { |
||||
|
logger.trace("creating enemy [" + name + "] with ZickZackController "); |
||||
|
ObjectController zzController = new ZickZackController(gameTime, 0.5); |
||||
|
GameObject go = new AnimatedGameobject(name, this, x_enemy, y_enemy, vx_enemy, vy_enemy, |
||||
|
ENEMYSCALE, this.enemyAnim, this.getGameTime(), "loop").addController(zzController) |
||||
|
.generateColliders(); |
||||
|
|
||||
|
return go.generateColliders(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,63 @@ |
|||||
|
package playground; |
||||
|
|
||||
|
import gameobjects.GameObject; |
||||
|
import controller.LimitedTimeController; |
||||
|
import gameobjects.TextObject; |
||||
|
import java.awt.Color; |
||||
|
import org.apache.logging.log4j.LogManager; |
||||
|
import org.apache.logging.log4j.Logger; |
||||
|
|
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* extends extends {@link SpaceInvadersLevel} |
||||
|
* <ul> |
||||
|
* <li>Hit aliens twice to kill them |
||||
|
* <li>they say AUA when not destroyed |
||||
|
* </ul> |
||||
|
*/ |
||||
|
public class Level4 extends SpaceInvadersLevel { |
||||
|
|
||||
|
/** constant defining the number of shots needed to destroy an enemy */ |
||||
|
public static final int MAX_HITS = 2; |
||||
|
|
||||
|
private static Logger logger = LogManager.getLogger(Level4.class); |
||||
|
|
||||
|
@Override |
||||
|
protected String getStartupMessage() { |
||||
|
return "Jetzt gibts Saures!"; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
void actionIfEnemyIsHit(GameObject e, GameObject shot) { |
||||
|
double gameTime = this.getGameTime(); |
||||
|
|
||||
|
Object counterFlag = e.getOrCreateObjectFlag("counter", Integer.valueOf(1)); |
||||
|
|
||||
|
int counter = (Integer) counterFlag; |
||||
|
|
||||
|
if (counter >= MAX_HITS) { |
||||
|
logger.trace("enemy was hit before for " + counter + " times, which is above " |
||||
|
+ LevelHitTwice.MAX_HITS); |
||||
|
super.actionIfEnemyIsHit(e, shot); |
||||
|
} else { |
||||
|
logger.trace("enemy was hit before for "+counter+" times, which is below "+LevelHitTwice.MAX_HITS); |
||||
|
e.setObjectFlag("counter", Integer.valueOf(counter + 1)); |
||||
|
// spawn a bonus points object |
||||
|
double vx = 2 * (Math.random() - 0.5) * SHARDSPEED + e.getVX(); |
||||
|
double vy = 2 * (Math.random() - 0.5) * SHARDSPEED + e.getVY(); |
||||
|
logger.trace("creating new TextObject bonus" + e.getId()); |
||||
|
LimitedTimeController bonusTextController = |
||||
|
new LimitedTimeController(gameTime, SpaceInvadersLevel.EXPL_DURATION); |
||||
|
GameObject bonusText = new TextObject("bonus" + e.getId(), this, e.getX(), e.getY(), vx, vy, |
||||
|
"Aua", 20, Color.YELLOW).addController(bonusTextController); |
||||
|
|
||||
|
this.addObject(bonusText); |
||||
|
} |
||||
|
deleteObject(shot.getId()); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,112 @@ |
|||||
|
package playground; |
||||
|
|
||||
|
import java.awt.Color; |
||||
|
import org.apache.logging.log4j.LogManager; |
||||
|
import org.apache.logging.log4j.Logger; |
||||
|
import controller.EgoController; |
||||
|
import controller.FallingStarController; |
||||
|
import controller.ObjectController; |
||||
|
import gameobjects.AnimatedGameobject; |
||||
|
import gameobjects.EgoObject; |
||||
|
import gameobjects.FallingStar; |
||||
|
import gameobjects.GameObject; |
||||
|
import gameobjects.TextObject; |
||||
|
|
||||
|
/** |
||||
|
* Class that realizes all the game logic of a very simple game level. The level contains for now |
||||
|
* only two objects that are {@link GameObject} subclasses: {@link FallingStar} and |
||||
|
* {@link EgoObject}. Functions performed by this class are: |
||||
|
* <ul> |
||||
|
* <li>initially set up the level, spawn all object etc., in method {@link #prepareLevel} |
||||
|
* <li>React to keyboard commands in method {@link #processKeyEvents(java.util.Stack)} |
||||
|
* <li>define basic object movement rules for all objects in the level in the various |
||||
|
* ObjectController subclasses: {@link EgoController} and {@link FallingStarController}. |
||||
|
* </ul> |
||||
|
*/ |
||||
|
public class LevelBoss extends SpaceInvadersLevel { |
||||
|
|
||||
|
private static int MAX_SHOTS = 10; |
||||
|
private static Logger logger = LogManager.getLogger(LevelBoss.class); |
||||
|
|
||||
|
@Override |
||||
|
void actionIfEnemyIsHit(GameObject e, GameObject shot) { |
||||
|
|
||||
|
Object counterFlag = e.getOrCreateObjectFlag("counter", Integer.valueOf(1)); |
||||
|
|
||||
|
int counter = (Integer) counterFlag; |
||||
|
|
||||
|
if (counter >= LevelBoss.MAX_SHOTS) { |
||||
|
logger.trace("enemy was hit before for " + counter + " times, which is equal or above " |
||||
|
+ LevelHitTwice.MAX_HITS); |
||||
|
super.actionIfEnemyIsHit(e, shot); |
||||
|
} else { |
||||
|
logger.trace("enemy was hit before for " + counter + " times, which is below " |
||||
|
+ LevelHitTwice.MAX_HITS); |
||||
|
e.setObjectFlag("counter", Integer.valueOf(counter + 1)); |
||||
|
} |
||||
|
deleteObject(shot.getId()); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
@Override |
||||
|
double calcEnemyShotProb() { |
||||
|
return 1.5 * this.getTimestep(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected double calcEnemySpeedX() { |
||||
|
return ENEMYSPEEDX * 2; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected double calcEnemySpeedY() { |
||||
|
return ENEMYSPEEDY * 2; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected int calcNrEnemies() { |
||||
|
return (int) 1; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected GameObject createEnemyShotObject(GameObject parentObject, String name, |
||||
|
ObjectController limitedTimeController) { |
||||
|
GameObject ego = this.getObject("ego"); |
||||
|
|
||||
|
double deltax = parentObject.getX() - ego.getX(); |
||||
|
double deltay = parentObject.getY() - ego.getY(); |
||||
|
|
||||
|
double norm = Math.sqrt(deltax * deltax + deltay * deltay); |
||||
|
deltax *= -ENEMYSHOTSPEED / norm; |
||||
|
deltay *= -ENEMYSHOTSPEED / norm; |
||||
|
|
||||
|
logger.trace("Creating EnemyShot as TextObject [" + name + "] in direction " + deltax + "/" |
||||
|
+ deltay + " towards ego"); |
||||
|
GameObject to = new TextObject(name, this, parentObject.getX(), parentObject.getY(), deltax, |
||||
|
deltay, "*", 20, Color.GREEN).generateColliders().addController(limitedTimeController); |
||||
|
return to; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
@Override |
||||
|
protected GameObject createSingleEnemy(String name, double x_enemy, double y_enemy, |
||||
|
double vx_enemy, double vy_enemy, ObjectController enemyController, double gameTime) { |
||||
|
|
||||
|
GameObject go = new AnimatedGameobject(name, this, this.canvasX / 2, 10, vx_enemy, 50, |
||||
|
ENEMYSCALE * 3, this.enemyAnim, this.getGameTime(), "loop").generateColliders() |
||||
|
.addController(enemyController); |
||||
|
|
||||
|
return go; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@Override |
||||
|
protected String getStartupMessage() { |
||||
|
return "BOSS LEVEL!"; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,65 @@ |
|||||
|
package playground; |
||||
|
|
||||
|
import controller.FallingStarController; |
||||
|
import gameobjects.EgoObject; |
||||
|
import gameobjects.FallingStar; |
||||
|
import gameobjects.GameObject; |
||||
|
import gameobjects.RectObject; |
||||
|
import java.awt.Color; |
||||
|
import org.apache.logging.log4j.LogManager; |
||||
|
import org.apache.logging.log4j.Logger; |
||||
|
|
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* extends {@link SpaceInvadersLevel} with 10 enemies that need two shots each to be destroyed. |
||||
|
* |
||||
|
*/ |
||||
|
|
||||
|
|
||||
|
public class LevelHitTwice extends SpaceInvadersLevel { |
||||
|
|
||||
|
/** constant defining the number of shots needed to destroy an enemy */ |
||||
|
public static final int MAX_HITS = 2; |
||||
|
|
||||
|
private static Logger logger = LogManager.getLogger(LevelHitTwice.class); |
||||
|
|
||||
|
/** constructor setting internal name to 'hitTwice' */ |
||||
|
public LevelHitTwice() { |
||||
|
super(); |
||||
|
this.level = "hitTwice"; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@Override |
||||
|
protected String getStartupMessage() { |
||||
|
return "2 shots at alien required!!!"; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected int calcNrEnemies() { |
||||
|
return 10; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
@Override |
||||
|
void actionIfEnemyIsHit(GameObject e, GameObject shot) { |
||||
|
Object counterFlag = e.getOrCreateObjectFlag("counter", Integer.valueOf(1)); |
||||
|
|
||||
|
int counter = (Integer) counterFlag; |
||||
|
|
||||
|
if (counter >= MAX_HITS) { |
||||
|
logger.trace("enemy was hit before for " + counter + " times, which is above " |
||||
|
+ LevelHitTwice.MAX_HITS); |
||||
|
super.actionIfEnemyIsHit(e, shot); |
||||
|
} else { |
||||
|
logger.trace("enemy was hit before for "+counter+" times, which is below "+LevelHitTwice.MAX_HITS); |
||||
|
e.setObjectFlag("counter", Integer.valueOf(counter + 1)); |
||||
|
} |
||||
|
deleteObject(shot.getId()); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,48 @@ |
|||||
|
package playground; |
||||
|
|
||||
|
import java.io.File; |
||||
|
import javax.sound.sampled.AudioInputStream; |
||||
|
import javax.sound.sampled.AudioSystem; |
||||
|
import javax.sound.sampled.Clip; |
||||
|
import javax.sound.sampled.FloatControl; |
||||
|
|
||||
|
public class Music { |
||||
|
private static final float volume = 0.02f; // scale 0 silence, 1 no change, 2 double. (linear). |
||||
|
|
||||
|
public static synchronized void music(File track) { |
||||
|
|
||||
|
final File trackname = track; |
||||
|
|
||||
|
new Thread(new Runnable() { |
||||
|
|
||||
|
@Override |
||||
|
public void run() { |
||||
|
while (true) { |
||||
|
|
||||
|
try { |
||||
|
|
||||
|
Clip clip = AudioSystem.getClip(); |
||||
|
AudioInputStream inputstream = AudioSystem.getAudioInputStream(trackname); |
||||
|
clip.open(inputstream); |
||||
|
FloatControl volumeControl = |
||||
|
(FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN); |
||||
|
if (volumeControl != null) { |
||||
|
volumeControl.setValue(20f * (float) Math.log10(volume)); |
||||
|
} |
||||
|
clip.start(); |
||||
|
|
||||
|
Thread.sleep(clip.getMicrosecondLength() / 1); |
||||
|
|
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
}).start(); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,374 @@ |
|||||
|
package playground; |
||||
|
|
||||
|
import java.awt.Graphics2D; |
||||
|
import java.util.HashMap; |
||||
|
import java.util.LinkedList; |
||||
|
import java.util.Map; |
||||
|
import java.util.Stack; |
||||
|
import java.awt.event.*; |
||||
|
import gameobjects.GameObject; |
||||
|
import org.apache.logging.log4j.Logger; |
||||
|
import org.apache.logging.log4j.LogManager; |
||||
|
|
||||
|
/** |
||||
|
* Playground represents a level of the game, focusing on the game LOGIC, i.e., not so much on the |
||||
|
* graphical representation. In particular, an instance of Playground |
||||
|
* <ul> |
||||
|
* <li>manages the different moving or static objects in a level (e.g., collisions, adding objects, |
||||
|
* removing objects). This is mainly done by the methods {@link #addObject}, {@link #deleteObject}. |
||||
|
* <li>processes keyboard inputs provided by GameLoop in {@link #processKeyEvents(Stack)} and |
||||
|
* {@link #processMouseEvents(Stack)} |
||||
|
* <li>represents the state of a level represented by <b>flags</b>. Each flag has a name (a String) |
||||
|
* and an arbitrary value of any type. Methods: {@link #setLevelFlag(String, Object)}, |
||||
|
* {@link #getLevelFlag(String)}. As an example, the current score is a flag usually named "points", |
||||
|
* with an Integer as a value. This value can be retrieved and manipulated using the above mentioned |
||||
|
* methods. |
||||
|
* </ul> |
||||
|
*/ |
||||
|
public abstract class Playground { |
||||
|
|
||||
|
public static final int FLAGS_GLOBAL = 1; |
||||
|
public static final int FLAGS_LEVEL = 2; |
||||
|
public static final int FLAGS_ALL = 3; |
||||
|
protected int canvasX = -1; |
||||
|
protected int canvasY = -1; |
||||
|
|
||||
|
/** only one set of objects exists concurrently so this can be static */ |
||||
|
protected static HashMap<String, GameObject> gameObjects = new HashMap<String, GameObject>(); |
||||
|
|
||||
|
/** only one set of objects exists concurrently so this can be static */ |
||||
|
protected static HashMap<String, Object> flags = new HashMap<String, Object>(); |
||||
|
|
||||
|
protected String level = ""; |
||||
|
protected double timeStep = 0; |
||||
|
protected double gameTime = 0; |
||||
|
LinkedList<GameObject> addables = new LinkedList<GameObject>(); |
||||
|
LinkedList<String> removables = new LinkedList<String>(); |
||||
|
// HashMap<Integer,Integer> keys ; |
||||
|
Stack<KeyEvent> keyEvents; |
||||
|
Stack<MouseEvent> mouseEvents; |
||||
|
|
||||
|
protected boolean pausedFlag = false; |
||||
|
|
||||
|
private static Logger logger = LogManager.getLogger(Playground.class); |
||||
|
|
||||
|
public Playground() { |
||||
|
this.canvasX = -1; |
||||
|
this.canvasY = -1; |
||||
|
} |
||||
|
|
||||
|
// here, the level communicates its size preference to the GameUI |
||||
|
// called automatically |
||||
|
public abstract int preferredSizeX(); |
||||
|
|
||||
|
public abstract int preferredSizeY(); |
||||
|
|
||||
|
/** |
||||
|
* Adds a graphics object to a level. |
||||
|
* |
||||
|
* @param o GameObject The object to be added |
||||
|
*/ |
||||
|
public void addObject(GameObject o) { |
||||
|
// gameObjects.put(o.getId(), o); |
||||
|
addables.addLast(o); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Adds a graphics object to a level. |
||||
|
* |
||||
|
* @param o GameObject The object to be added |
||||
|
*/ |
||||
|
public void addObjectNow(GameObject o) { |
||||
|
gameObjects.put(o.getId(), o); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Puts objects with a certain substring in their name into a LinkedLisrt and returns them. |
||||
|
* |
||||
|
* @param substr The string that must be part of the object name if object is to be considered |
||||
|
* found. |
||||
|
* @param filterInactive if set true only active objects are considered. |
||||
|
* @return a reference to a LinkedList filled with all objects that have <b>substr</b> in their |
||||
|
* name |
||||
|
*/ |
||||
|
public LinkedList<GameObject> collectObjects(String substr, boolean filterInactive) { |
||||
|
LinkedList<GameObject> l = new LinkedList<GameObject>(); |
||||
|
for (Map.Entry<String, GameObject> entry : Playground.gameObjects.entrySet()) { // Iterator |
||||
|
// usage |
||||
|
GameObject obj = entry.getValue(); |
||||
|
if (obj.getId().contains(substr)) { |
||||
|
if (filterInactive == true) { |
||||
|
if (obj.isActive()) { |
||||
|
l.add(obj); |
||||
|
} |
||||
|
} else { |
||||
|
l.add(obj); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return l; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Removes a graphics object from a level. |
||||
|
* |
||||
|
* @param id String The unique identifier of the object |
||||
|
*/ |
||||
|
public void deleteObject(String id) { |
||||
|
// gameObjects.remove(id); |
||||
|
removables.addLast(id); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Removes a graphics object from a level immediately, CAUTION. |
||||
|
* |
||||
|
* @param id String The unique identifier of the object |
||||
|
*/ |
||||
|
public void deleteObjectNow(String id) { |
||||
|
gameObjects.remove(id); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Retrieves a graphics object by name. |
||||
|
* |
||||
|
* @param id String Unique id of the object |
||||
|
* @return reference to the requested game object, or null if not found |
||||
|
*/ |
||||
|
public GameObject getObject(String id) { |
||||
|
return gameObjects.get(id); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sets a level-wide permanent flag. |
||||
|
* |
||||
|
* @param flag String Q unique name in this level. If it exists value is overwritten. |
||||
|
* @param value Object Any Object can be the value of a flag! |
||||
|
*/ |
||||
|
|
||||
|
public static void setGlobalFlag(String flag, Object value) { |
||||
|
flags.put("/global/" + flag, value); |
||||
|
} |
||||
|
|
||||
|
public Object setLevelFlag(String flag, Object value) { |
||||
|
flags.put("/" + this.level + "/" + flag, value); |
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* mode can be: FLAGS_ALL (all), FLAGS_GLOBAL(global), FLAGs_LEVEL(level) |
||||
|
* |
||||
|
* @param mode can be only one of {@link #FLAGS_GLOBAL} {@link #FLAGS_ALL} or |
||||
|
* {@link #FLAGS_LEVEL } |
||||
|
*/ |
||||
|
public void resetFlags(int mode) { |
||||
|
LinkedList<String> delKeys = new LinkedList<String>(); |
||||
|
for (Map.Entry<String, Object> entry : Playground.flags.entrySet()) { |
||||
|
logger.trace(entry.getKey() + " IndexofGlobal = " + entry.getKey().indexOf("/global/")); |
||||
|
if ((mode == FLAGS_GLOBAL) && (entry.getKey().indexOf("/global/") != -1)) { |
||||
|
logger.debug("GLOBAL: scheduling for removal: " + entry.getKey()); |
||||
|
delKeys.add(entry.getKey()); |
||||
|
} else if ((mode == FLAGS_LEVEL) && (entry.getKey().indexOf("/global/") == -1)) { |
||||
|
logger.debug("LEVEL: scheduling for removal: " + entry.getKey()); |
||||
|
delKeys.add(entry.getKey()); |
||||
|
} else if (mode == FLAGS_ALL) { |
||||
|
logger.debug("ALL: scheduling for removal: " + entry.getKey()); |
||||
|
delKeys.add(entry.getKey()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
for (String str : delKeys) { |
||||
|
logger.trace("removing key " + str); |
||||
|
flags.remove(str); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Retrieves a level-wide flag by name. |
||||
|
* |
||||
|
* @param flag String Unique flag id |
||||
|
* @return the value associated with <b>flag</b>, or <b>null</b> if the flag does not exist. |
||||
|
*/ |
||||
|
public static Object getGlobalFlag(String flag) { |
||||
|
return flags.get("/global/" + flag); |
||||
|
} |
||||
|
|
||||
|
/** checks for existence and if not creates the new global flag with the given initial value. Returns the value. |
||||
|
* afterwards it is guaranteed that no priorly existing value is overridden and that it definitely exists (created if not present before). |
||||
|
* |
||||
|
* @param flag String name for the global flag (created if not present) |
||||
|
* @param value Object value to be stored (used only if flag was not present) |
||||
|
* @return the current value of the flag (maybe the initial one in case flag was not there before) |
||||
|
*/ |
||||
|
public static Object getOrCreateGlobalFlag(String flag, Object value) { |
||||
|
Object tmp = getGlobalFlag(flag); |
||||
|
if (tmp == null) { |
||||
|
setGlobalFlag(flag, value); |
||||
|
return value; |
||||
|
} else { |
||||
|
return tmp; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public Object getLevelFlag(String flag) { |
||||
|
return flags.get("/" + this.level + "/" + flag); |
||||
|
} |
||||
|
|
||||
|
public Object getOrCreateLevelFlag(String flag, Object createValue) { |
||||
|
Object tmp = getLevelFlag(flag); |
||||
|
if (tmp == null) { |
||||
|
return setLevelFlag(flag, createValue); |
||||
|
} else { |
||||
|
return tmp; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Reinitializes the level. |
||||
|
*/ |
||||
|
public void reset() { |
||||
|
gameObjects.clear(); |
||||
|
} |
||||
|
|
||||
|
public boolean isPaused() { |
||||
|
return this.pausedFlag; |
||||
|
} |
||||
|
|
||||
|
public void setPaused(boolean p) { |
||||
|
this.pausedFlag = p; |
||||
|
} |
||||
|
|
||||
|
public void togglePause() { |
||||
|
pausedFlag = !pausedFlag; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Method meant to be filled with own code, processes Keyboard inputs. |
||||
|
* |
||||
|
* @param keyEvents all collected {@link KeyEvent}s collected since last game loop. |
||||
|
*/ |
||||
|
|
||||
|
public void processKeyEvents(Stack<KeyEvent> keyEvents) { |
||||
|
this.keyEvents = keyEvents; |
||||
|
Playground.setGlobalFlag("inputs", keyEvents); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public void processMouseEvents(Stack<MouseEvent> mouseEvents) { |
||||
|
this.mouseEvents = mouseEvents; |
||||
|
Playground.setGlobalFlag("inputs", mouseEvents); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public Stack<KeyEvent> getKeyEvents() { |
||||
|
return this.keyEvents; |
||||
|
} |
||||
|
|
||||
|
public Stack<MouseEvent> getMouseEvents() { |
||||
|
return this.mouseEvents; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Method meant to be filled with own code, handles the entore game logic (collision checks, timed |
||||
|
* events, ...). |
||||
|
* |
||||
|
*/ |
||||
|
public abstract void applyGameLogic(); |
||||
|
|
||||
|
/** |
||||
|
* Sets up a single level. Prepares all objects etc. |
||||
|
* |
||||
|
* @param level String a string identifying the level number etc |
||||
|
*/ |
||||
|
public abstract void prepareLevel(String level); |
||||
|
|
||||
|
public abstract boolean gameOver(); |
||||
|
|
||||
|
public abstract boolean levelFinished(); |
||||
|
|
||||
|
public int getSizeX() { |
||||
|
return canvasX; |
||||
|
} |
||||
|
|
||||
|
public int getSizeY() { |
||||
|
return canvasY; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Calls all object update methods in level. Internal, never call directly. |
||||
|
* |
||||
|
*/ |
||||
|
public void updateObjects() { |
||||
|
for (GameObject gameObject : gameObjects.values()) { // Iterator usage |
||||
|
if (gameObject.isActive() == true) { |
||||
|
gameObject.updateObject(); |
||||
|
logger.trace("updated object " + gameObject.scol); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
for (GameObject o : addables) { // Iterator usage |
||||
|
addObjectNow(o); |
||||
|
} |
||||
|
|
||||
|
for (String s : removables) { // Iterator usage |
||||
|
deleteObjectNow(s); |
||||
|
} |
||||
|
removables.clear(); |
||||
|
addables.clear(); |
||||
|
} |
||||
|
|
||||
|
public void setTimestep(double s) { |
||||
|
timeStep = s; |
||||
|
} |
||||
|
|
||||
|
public double getTimestep() { |
||||
|
return timeStep; |
||||
|
} |
||||
|
|
||||
|
/** set the game time value (in seconds) |
||||
|
* |
||||
|
* @param s seconds the game is running |
||||
|
*/ |
||||
|
public void setGameTime(double s) { |
||||
|
this.gameTime = s; |
||||
|
} |
||||
|
|
||||
|
/** returns time in seconds since level start */ |
||||
|
public double getGameTime() { |
||||
|
return this.gameTime; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* To be redefined!! Draws mainly h level background and global information like points etc. |
||||
|
* |
||||
|
* @param g2 Graphics2D abstract drawing object of java Swing, used to carry out all drawing |
||||
|
* operations. |
||||
|
*/ |
||||
|
public abstract void redrawLevel(Graphics2D g2); |
||||
|
|
||||
|
/** |
||||
|
* Internal, do not call directly. |
||||
|
* |
||||
|
* @param g2 Graphics2D abstract drawing object of java Swing, used to carry out all drawing |
||||
|
* operations. |
||||
|
*/ |
||||
|
public void redraw(Graphics2D g2) { |
||||
|
redrawLevel(g2); |
||||
|
for (GameObject gameObject : gameObjects.values()) { |
||||
|
if (gameObject.isActive()) { |
||||
|
gameObject.draw(g2); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,62 @@ |
|||||
|
package playground; |
||||
|
|
||||
|
import java.io.FileInputStream; |
||||
|
import java.io.FileNotFoundException; |
||||
|
import java.io.FileOutputStream; |
||||
|
import java.io.IOException; |
||||
|
import java.io.ObjectInputStream; |
||||
|
import java.io.ObjectOutputStream; |
||||
|
import java.util.ArrayList; |
||||
|
import org.apache.logging.log4j.Logger; |
||||
|
import org.apache.logging.log4j.LogManager; |
||||
|
|
||||
|
public class SaveGame { |
||||
|
|
||||
|
private static String datnam = "aktuellerSpielzustand.ser"; |
||||
|
private static Logger logger = LogManager.getLogger(SaveGame.class); |
||||
|
|
||||
|
|
||||
|
@SuppressWarnings("unchecked") |
||||
|
public static void save() { |
||||
|
|
||||
|
// gameobjects.AnimatedGameobject |
||||
|
ArrayList<String> objArrList = null; |
||||
|
ObjectInputStream in = null; |
||||
|
try { |
||||
|
in = new ObjectInputStream(new FileInputStream(datnam)); |
||||
|
objArrList = (ArrayList<String>) in.readObject(); |
||||
|
} catch (FileNotFoundException ex) { |
||||
|
logger.warn("Savegame file not (yet) existing!"); |
||||
|
} catch (Exception ex) { |
||||
|
logger.error(ex); |
||||
|
} finally { |
||||
|
try { |
||||
|
if (in != null) |
||||
|
in.close(); |
||||
|
} catch (IOException e) { |
||||
|
} |
||||
|
} |
||||
|
if (objArrList == null) |
||||
|
objArrList = new ArrayList<String>(); |
||||
|
|
||||
|
objArrList.add(new String("ArrayListgroesse: " + objArrList.size())); |
||||
|
logger.debug(objArrList); |
||||
|
|
||||
|
ObjectOutputStream aus = null; |
||||
|
try { |
||||
|
aus = new ObjectOutputStream(new FileOutputStream(datnam)); |
||||
|
aus.writeObject(objArrList); |
||||
|
} catch (IOException ex) { |
||||
|
logger.error(ex); |
||||
|
} finally { |
||||
|
try { |
||||
|
if (aus != null) { |
||||
|
aus.flush(); |
||||
|
aus.close(); |
||||
|
} |
||||
|
} catch (IOException e) { |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,678 @@ |
|||||
|
package playground; |
||||
|
|
||||
|
// import utilities.* ; |
||||
|
import java.awt.Color; |
||||
|
import java.awt.Font; |
||||
|
import java.awt.Graphics2D; |
||||
|
import java.awt.Polygon; |
||||
|
import java.awt.RenderingHints; |
||||
|
import java.awt.font.TextAttribute; |
||||
|
import java.awt.image.BufferedImage; |
||||
|
import java.io.*; |
||||
|
import java.text.AttributedString; |
||||
|
import java.util.LinkedList; |
||||
|
import controller.EnemyController; |
||||
|
import controller.FallingStarController; |
||||
|
import controller.LimitedTimeController; |
||||
|
import controller.ObjectController; |
||||
|
import controller.EgoController; |
||||
|
import controller.CollisionAwareEgoController; |
||||
|
import gameobjects.AnimatedGameobject; |
||||
|
import gameobjects.FallingStar; |
||||
|
import gameobjects.GameObject; |
||||
|
import gameobjects.EgoObject; |
||||
|
import gameobjects.TextObject; |
||||
|
import org.apache.logging.log4j.Logger; |
||||
|
import org.apache.logging.log4j.LogManager; |
||||
|
|
||||
|
/** |
||||
|
* Class that realizes all the game logic of a very simple game level. The level contains for now |
||||
|
* only two objects that are {@link GameObject} subclasses: {@link FallingStar} and |
||||
|
* {@link EgoObject}. Functions performed by this class are: |
||||
|
* <ul> |
||||
|
* <li>initially set up the level, spawn all object etc., in method {@link #prepareLevel} |
||||
|
* <li>React to game events in {@link #actionIfEgoCollidesWithCollect(GameObject, GameObject)} , |
||||
|
* {@link #actionIfEgoCollidesWithEnemy(GameObject, GameObject)}, etc. |
||||
|
* <li>define basic object movement rules for all objects in the level in the various |
||||
|
* ObjectController subclasses: {@link EgoController} and {@link FallingStarController}. |
||||
|
* </ul> |
||||
|
*/ |
||||
|
public class SpaceInvadersLevel extends Playground { |
||||
|
|
||||
|
public static final double SHOTSPEED = 175; |
||||
|
public static final double EGOSPEED = 220; |
||||
|
protected static final int LEVEL2STARS = 80; |
||||
|
protected static final double BONUS_DURATION = 1.; |
||||
|
protected static final double ENEMYSPEEDX = 60; |
||||
|
protected static final double ENEMYSPEEDY = 40; |
||||
|
protected static final double ENEMYSCALE = 1.0; |
||||
|
protected static final double ENEMYSHOTSPEED = 75; |
||||
|
protected static final int NRSHARDS = 50; |
||||
|
protected static final double EXPL_DURATION = 1.; |
||||
|
protected static final int NR_ENEMIES = 30; |
||||
|
protected static final int NR_COLLECT = 5; |
||||
|
protected static final Color EXPL_COLOR = Color.RED; |
||||
|
protected static final double SHARDSPEED = 200; |
||||
|
protected static final double STARSPEED = 100; |
||||
|
protected static final double STARTTEXTSPEED = 75; |
||||
|
protected static final double STARTPERIOD = 5.; |
||||
|
protected static final double DYING_INTERVAL = 2.0; |
||||
|
protected static final int CANVASX = 700; |
||||
|
protected static final int CANVASY = 700; |
||||
|
protected static final double EGORAD = 15; |
||||
|
protected static final double LEVEL_INIT_TIME = 1.0; |
||||
|
|
||||
|
protected int nextShot = 0; |
||||
|
|
||||
|
protected boolean lost = false; |
||||
|
protected boolean doneLevel = false; |
||||
|
protected double starttime = 0; |
||||
|
protected File smash = null; |
||||
|
protected File laser = null; |
||||
|
|
||||
|
protected BufferedImage[] alienImage = null; |
||||
|
protected double[] alienshowTime = null; |
||||
|
|
||||
|
protected BufferedImage[] heartImage = null; |
||||
|
protected double[] heartshowTime = null; |
||||
|
|
||||
|
protected Animation enemyAnim = null; |
||||
|
protected Animation heartAnim = null; |
||||
|
|
||||
|
private static Logger logger = LogManager.getLogger(SpaceInvadersLevel.class); |
||||
|
|
||||
|
public SpaceInvadersLevel() { |
||||
|
super(); |
||||
|
this.canvasX = this.preferredSizeX(); |
||||
|
this.canvasY = this.preferredSizeY(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* initially sets up the level. Not called by user interaction, but called every time a layer is |
||||
|
* restarted from scratch. So make sure that this is possible. Here, resources are loaded only |
||||
|
* once even if method is called several times. |
||||
|
* |
||||
|
* @param id String identifies level. |
||||
|
*/ |
||||
|
@Override |
||||
|
public void prepareLevel(String id) { |
||||
|
logger.info("PREPARE"); |
||||
|
reset(); |
||||
|
this.doneLevel = false; |
||||
|
this.lost = false; |
||||
|
resetFlags(FLAGS_LEVEL); |
||||
|
|
||||
|
// set up flags that some objects rely on |
||||
|
setLevelFlag("delete", new LinkedList<String>()); |
||||
|
setLevelFlag("replace", new LinkedList<String>()); |
||||
|
getOrCreateGlobalFlag("points", Integer.valueOf(0)); |
||||
|
setLevelFlag("enemyShotCounter", Integer.valueOf(0)); |
||||
|
setLevelFlag("gameStatus", "start"); |
||||
|
setLevelFlag("detailedStatus", "std"); |
||||
|
getOrCreateGlobalFlag("egoLives", Integer.valueOf(5)); |
||||
|
setLevelFlag("dying", Double.valueOf(-1)); |
||||
|
|
||||
|
// start time measure |
||||
|
this.starttime = this.getGameTime(); |
||||
|
|
||||
|
// music load |
||||
|
if (this.smash == null) { |
||||
|
this.smash = new File("./audio/smash.wav"); |
||||
|
} |
||||
|
if (this.laser == null) { |
||||
|
this.laser = new File("./audio/laser.wav"); |
||||
|
} |
||||
|
|
||||
|
// ----- Alien |
||||
|
if (this.enemyAnim == null) { |
||||
|
String dateiName = "./video/sweetAlien.txt"; |
||||
|
this.enemyAnim = new Animation(dateiName); |
||||
|
} |
||||
|
|
||||
|
// -----Heart |
||||
|
if (this.heartAnim == null) { |
||||
|
String heartName = "./video/heart.txt"; |
||||
|
this.heartAnim = new Animation(heartName); |
||||
|
} |
||||
|
|
||||
|
// load highscore and update |
||||
|
HighscoreManager dh = new HighscoreManager(); |
||||
|
int alltimeHighscore = dh.readHSFromFile(); |
||||
|
setGlobalFlag("highscore", alltimeHighscore); |
||||
|
logger.info("HIGHSCORE" + alltimeHighscore); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* (re)draws the level but NOT the objects, they draw themselves. Called by the main game loop. |
||||
|
* This method mainly draws the background and the scoreboard. |
||||
|
* |
||||
|
* @param g2 Graphics2D object that can, and should be, draw on. |
||||
|
*/ |
||||
|
@Override |
||||
|
public void redrawLevel(Graphics2D g2) { |
||||
|
// Set anti-alias! |
||||
|
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); |
||||
|
// Set anti-alias for text |
||||
|
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, |
||||
|
RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); |
||||
|
|
||||
|
// fill background with black |
||||
|
int[] x = {0, canvasX, canvasX, 0}; |
||||
|
int[] y = {0, 0, canvasY, canvasY}; |
||||
|
Polygon bg = new Polygon(x, y, 4); |
||||
|
g2.setColor(Color.BLACK); |
||||
|
g2.fill(bg); |
||||
|
|
||||
|
// draw score in upper left part of playground |
||||
|
Integer pts = (Integer) getGlobalFlag("points"); |
||||
|
Font drawFont = new Font("SansSerif", Font.PLAIN, 20); |
||||
|
AttributedString as = new AttributedString("Points: " + pts); |
||||
|
as.addAttribute(TextAttribute.FONT, drawFont); |
||||
|
as.addAttribute(TextAttribute.FOREGROUND, Color.yellow); |
||||
|
g2.drawString(as.getIterator(), 10, 20); |
||||
|
|
||||
|
// draw lives counter in upper left part of playground |
||||
|
Integer lives = (Integer) getGlobalFlag("egoLives"); |
||||
|
Font drawFont2 = new Font("SansSerif", Font.PLAIN, 20); |
||||
|
AttributedString as2 = new AttributedString("Lives: " + lives); |
||||
|
as2.addAttribute(TextAttribute.FONT, drawFont2); |
||||
|
as2.addAttribute(TextAttribute.FOREGROUND, Color.yellow); |
||||
|
g2.drawString(as2.getIterator(), canvasX - 100, 20); |
||||
|
|
||||
|
// draw highscore in left part of playground under score |
||||
|
Integer highscore = (Integer) getGlobalFlag("highscore"); |
||||
|
Font drawFont3 = new Font("SansSerif", Font.PLAIN, 20); |
||||
|
AttributedString as3 = new AttributedString("Highscore: " + highscore); |
||||
|
as3.addAttribute(TextAttribute.FONT, drawFont3); |
||||
|
as3.addAttribute(TextAttribute.FOREGROUND, Color.yellow); |
||||
|
g2.drawString(as3.getIterator(), 10, 40); |
||||
|
|
||||
|
if (isPaused()) { |
||||
|
Font drawFont4 = new Font("SansSerif", Font.PLAIN, 50); |
||||
|
AttributedString as4 = new AttributedString("Das Spiel wurde pausiert."); |
||||
|
as4.addAttribute(TextAttribute.FONT, drawFont4); |
||||
|
as4.addAttribute(TextAttribute.FOREGROUND, Color.red); |
||||
|
g2.drawString(as4.getIterator(), 30, 400); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* applies the logic of the level: For now, this is just about deleting shots that are leaving the |
||||
|
* screen and calling methods 'actionIf..' in case objects collide. |
||||
|
* |
||||
|
*/ |
||||
|
@Override |
||||
|
public void applyGameLogic() { |
||||
|
double gameTime = this.getGameTime(); |
||||
|
String gameStatus = (String) getLevelFlag("gameStatus"); |
||||
|
String subStatus = (String) getLevelFlag("detailedStatus"); |
||||
|
|
||||
|
if (gameStatus.equals("start") == true) { |
||||
|
setupInitialState(); |
||||
|
|
||||
|
} else if (gameStatus.equals("starting") == true) { |
||||
|
|
||||
|
if ((gameTime - starttime) > LEVEL_INIT_TIME) { |
||||
|
setLevelFlag("gameStatus", "init"); |
||||
|
} |
||||
|
|
||||
|
} else if (gameStatus.equals("init") == true) { |
||||
|
|
||||
|
this.createEnemies(); |
||||
|
this.createCollectables(); |
||||
|
|
||||
|
setLevelFlag("gameStatus", "playing"); |
||||
|
|
||||
|
} else if (gameStatus.equals("playing") == true) { |
||||
|
GameObject s = this.getObject("ego"); |
||||
|
|
||||
|
if (subStatus.equals("std")) { |
||||
|
|
||||
|
// check for collisions of enemy and shots, reuse shots list from before.. |
||||
|
LinkedList<GameObject> enemies = collectObjects("enemy", false); |
||||
|
|
||||
|
// check whether all enemies have been destroyed or escaped |
||||
|
if (enemies.size() == 0) { |
||||
|
HighscoreManager hsm = new HighscoreManager(); |
||||
|
HighscoreManager.writeHSToFile((Integer) Playground.getGlobalFlag("points"), |
||||
|
(Integer) Playground.getGlobalFlag("highscore")); |
||||
|
this.doneLevel = true; |
||||
|
logger.info("no enemies left, level done."); |
||||
|
} |
||||
|
|
||||
|
// loop over enemies to check for collisions or suchlike ... |
||||
|
LinkedList<GameObject> shots = collectObjects("simpleShot", true); |
||||
|
for (GameObject e : enemies) { |
||||
|
// if ego collides with enemy.. |
||||
|
if (s.collisionDetection(e)) { |
||||
|
actionIfEgoCollidesWithEnemy(e, s); |
||||
|
} |
||||
|
|
||||
|
// if shot collides with enemy |
||||
|
for (GameObject shot : shots) { |
||||
|
if (e.collisionDetection(shot)) { |
||||
|
actionIfEnemyIsHit(e, shot); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// collecting hearts |
||||
|
LinkedList<GameObject> collects = collectObjects("collect", false); |
||||
|
for (GameObject c : collects) { |
||||
|
if (s.collisionDetection(c)) { |
||||
|
actionIfEgoCollidesWithCollect(c, s); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// loop over enemies and, with a certain probability, launch an enemy shot for each one |
||||
|
for (GameObject e : enemies) { |
||||
|
createEnemyShot(e); |
||||
|
} |
||||
|
|
||||
|
// check for collisions between ego object and enemy shots |
||||
|
LinkedList<GameObject> eshots = collectObjects("enmyShot", true); |
||||
|
for (GameObject eshot : eshots) { |
||||
|
|
||||
|
if (s.collisionDetection(eshot)) { |
||||
|
logger.trace("COLLISION" + eshot.scol.get(0) + "/" + s.scol.get(0)); |
||||
|
actionIfEgoObjectIsHit(eshot, s); |
||||
|
} |
||||
|
} |
||||
|
} // if substatus.. |
||||
|
else if (subStatus.equals("dying")) { |
||||
|
Double t0 = (Double) getLevelFlag("t0"); |
||||
|
if (gameTime - t0 > DYING_INTERVAL) { |
||||
|
LinkedList<GameObject> enemies = collectObjects("enemy", false); |
||||
|
setLevelFlag("detailedStatus", "std"); |
||||
|
s.setActive(true); |
||||
|
|
||||
|
for (GameObject e : enemies) { |
||||
|
logger.trace("activating" + e.getId()); |
||||
|
e.setActive(true); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} // if (gameStatus == "playing") |
||||
|
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
public boolean gameOver() { |
||||
|
return lost; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public boolean levelFinished() { |
||||
|
return doneLevel; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* calculates and returns the preferred size of the level (in pixel) for X-direction |
||||
|
*/ |
||||
|
public int preferredSizeX() { |
||||
|
return CANVASX; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* calculates and returns the preferred size of the level (in pixel) for Y-direction |
||||
|
*/ |
||||
|
public int preferredSizeY() { |
||||
|
return CANVASY; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** Adds ego object and stars and displays startup message. Is called from applyGameLogic */ |
||||
|
protected void setupInitialState() { |
||||
|
double gameTime = this.getGameTime(); |
||||
|
setLevelFlag("gameStatus", "starting"); |
||||
|
|
||||
|
this.createStars(); |
||||
|
|
||||
|
// set up ego object |
||||
|
this.createEgoObject(); |
||||
|
|
||||
|
// add text object to playground |
||||
|
ObjectController ctrl = new LimitedTimeController(gameTime, 3.); |
||||
|
GameObject readyText = new TextObject("ready?", this, getSizeX() / 2, 0, 0, 100, |
||||
|
this.getStartupMessage(), 50, Color.RED).addController(ctrl); |
||||
|
addObject(readyText); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* simply returns the text that should be displayed at level start |
||||
|
* |
||||
|
* @return a string that is displayed at start. Should be not longer than 30 characters. |
||||
|
*/ |
||||
|
protected String getStartupMessage() { |
||||
|
return "Get ready for level X!"; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* returns a number representing the speed of an enemy object in X direction (pixels/second) |
||||
|
* |
||||
|
* @return a positive value |
||||
|
*/ |
||||
|
protected double calcEnemySpeedX() { |
||||
|
return SpaceInvadersLevel.ENEMYSPEEDX; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* returns a number representing the speed of an enemy object in Y direction (pixels/second) |
||||
|
* |
||||
|
* @return a positive value |
||||
|
*/ |
||||
|
protected double calcEnemySpeedY() { |
||||
|
return SpaceInvadersLevel.ENEMYSPEEDY; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* returns the maximum number of enemy instances (which are created at level start) |
||||
|
* |
||||
|
* @return a positive value |
||||
|
*/ |
||||
|
protected int calcNrEnemies() { |
||||
|
return SpaceInvadersLevel.NR_ENEMIES; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* returns the maximum number of collectables' instances (which are created at level start) |
||||
|
* |
||||
|
* @return a positive value |
||||
|
*/ |
||||
|
protected int calcNrCollect() { |
||||
|
return SpaceInvadersLevel.NR_COLLECT; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
protected GameObject createEnemyShotObject(GameObject parentObject, String name, |
||||
|
ObjectController limitedTimeController) { |
||||
|
GameObject to = |
||||
|
new TextObject(name, this, parentObject.getX(), parentObject.getY(), 0, ENEMYSHOTSPEED, "I", |
||||
|
20, Color.YELLOW).generateColliders().addController(limitedTimeController); |
||||
|
/* |
||||
|
* // also possible: GameObject to = new RectObject(name, this, parentObject.getX(), |
||||
|
* parentObject.getY(), 0, ENEMYSHOTSPEED, 4, 20, |
||||
|
* Color.YELLOW).addController(limitedTimeController) ; to.generateColliders(); |
||||
|
*/ |
||||
|
return to; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
protected void createEnemyShot(GameObject e) { |
||||
|
double gameTime = this.getGameTime(); |
||||
|
|
||||
|
double PROB = calcEnemyShotProb(); |
||||
|
double diceThrow = Math.random(); |
||||
|
Integer nrEnemyShots = (Integer) (getLevelFlag("enemyShotCounter")); |
||||
|
if (diceThrow < PROB) { |
||||
|
setLevelFlag("enemyShotCounter", Integer.valueOf(++nrEnemyShots)); |
||||
|
|
||||
|
LimitedTimeController limitedTimeController = new LimitedTimeController(gameTime, 10.); |
||||
|
|
||||
|
GameObject textObject = |
||||
|
createEnemyShotObject(e, "enmyShot" + nrEnemyShots, limitedTimeController); |
||||
|
|
||||
|
addObject(textObject); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* calculates and returns the probability that an enemy shots. Used by |
||||
|
* {@link SpaceInvadersLevel#createEnemyShot(GameObject)}. |
||||
|
* |
||||
|
* @return a positive value between 0 (no chance) to 1 (for sure). |
||||
|
*/ |
||||
|
double calcEnemyShotProb() { |
||||
|
return 0.1 * this.getTimestep(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
ObjectController createEnemyController() { |
||||
|
return new EnemyController(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
GameObject createSingleEnemy(String name, double x_enemy, double y_enemy, double vx_enemy, |
||||
|
double vy_enemy, ObjectController enemyController, double gameTime) { |
||||
|
|
||||
|
GameObject tmp = |
||||
|
new AnimatedGameobject(name, this, x_enemy, y_enemy, vx_enemy, vy_enemy, ENEMYSCALE, |
||||
|
this.enemyAnim, gameTime, "loop").addController(enemyController).generateColliders(); |
||||
|
return tmp; |
||||
|
} |
||||
|
|
||||
|
GameObject createSingleCollect(String name) { |
||||
|
double gameTime = this.getGameTime(); |
||||
|
double cspeedy = 20.; |
||||
|
double x_collect = Math.random() * this.canvasX; |
||||
|
double y_collect = Math.random() * this.canvasY / 3; |
||||
|
double vx_collect = 2 * (Math.random() - 0.5) * 0; |
||||
|
double vy_collect = Math.random() * cspeedy; |
||||
|
|
||||
|
GameObject tmp = new AnimatedGameobject(name, this, x_collect, y_collect, vx_collect, |
||||
|
vy_collect, 0.3, this.heartAnim, gameTime, "loop").generateColliders() |
||||
|
.addController(new EnemyController()); |
||||
|
return tmp; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void createEnemies() { |
||||
|
// create enemies |
||||
|
double gameTime = this.getGameTime(); |
||||
|
double speedx = this.calcEnemySpeedX(); |
||||
|
double speedy = this.calcEnemySpeedY(); |
||||
|
for (int i = 0; i < this.calcNrEnemies(); i++) { |
||||
|
double x_enemy = Math.random() * this.canvasX; |
||||
|
double y_enemy = Math.random() * this.canvasY / 3; |
||||
|
double vx_enemy = 2 * (Math.random() - 0.5) * speedx; |
||||
|
double vy_enemy = Math.random() * speedy; |
||||
|
|
||||
|
ObjectController enemyController = createEnemyController(); |
||||
|
GameObject enemy = createSingleEnemy("enemy" + i, x_enemy, y_enemy, vx_enemy, vy_enemy, |
||||
|
enemyController, gameTime); |
||||
|
addObject(enemy); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void createCollectables() { |
||||
|
double gameTime = this.getGameTime(); |
||||
|
// create collectables |
||||
|
for (int i = 0; i < this.calcNrCollect(); i++) { |
||||
|
|
||||
|
|
||||
|
GameObject collect = createSingleCollect("collect" + i); |
||||
|
|
||||
|
addObject(collect); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void createEgoObject() { |
||||
|
// add ego to playground at lower bottom |
||||
|
EgoController egoController = |
||||
|
new CollisionAwareEgoController(SpaceInvadersLevel.EGORAD, this.laser); |
||||
|
|
||||
|
GameObject ego = new EgoObject("ego", this, canvasX / 2, canvasY - (EGORAD * 2), 0, 0, EGORAD) |
||||
|
.addController(egoController).generateColliders(); |
||||
|
|
||||
|
addObject(ego); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void createStars() { |
||||
|
// add stars to playground |
||||
|
for (int i = 1; i <= LEVEL2STARS; i++) { |
||||
|
FallingStarController fsc = new FallingStarController(); |
||||
|
|
||||
|
GameObject star = new FallingStar("star" + i, this, Math.random() * canvasX, |
||||
|
Math.random() * 15, 0.0, Math.random() * STARSPEED, Color.WHITE, 1.).addController(fsc); |
||||
|
|
||||
|
addObject(star); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void createExplosion(double gameTime, GameObject e, String basename, double interval, |
||||
|
Color color) { |
||||
|
// spawn a cloud of exploded shards |
||||
|
for (int i = 0; i < NRSHARDS; i++) { |
||||
|
double vx = 2 * (Math.random() - 0.5) * SHARDSPEED + e.getVX(); |
||||
|
double vy = 2 * (Math.random() - 0.5) * SHARDSPEED + e.getVY(); |
||||
|
addObject( |
||||
|
new FallingStar("shard" + gameTime + "/" + i, this, e.getX(), e.getY(), vx, vy, color, 2) |
||||
|
.addController(new LimitedTimeController(gameTime, interval))); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* implements game behavior if an enemy object is hit by a players' shot. It creates an explosion |
||||
|
* effect, plays a sound and adds 200 points to the current score (and it removes the enemy object |
||||
|
* and the shot object). |
||||
|
* |
||||
|
* @param e enemy which was hit |
||||
|
* @param shot the shot object that hit the enemy |
||||
|
*/ |
||||
|
void actionIfEnemyIsHit(GameObject e, GameObject shot) { |
||||
|
|
||||
|
double gameTime = this.getGameTime(); |
||||
|
createExplosion(gameTime, e, "shard", DYING_INTERVAL, Color.RED); |
||||
|
|
||||
|
Music.music(smash); |
||||
|
|
||||
|
// delete enemy |
||||
|
deleteObject(e.getId()); |
||||
|
|
||||
|
// delete shot |
||||
|
deleteObject(shot.getId()); |
||||
|
|
||||
|
// add to points counter |
||||
|
Integer pts = (Integer) getGlobalFlag("points"); |
||||
|
setGlobalFlag("points", pts + 200); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* implements game behavior if ego object of player touches a collectable |
||||
|
* {@link gameobjects.GameObject }. Here it adds one extra life and displays a text for a limited |
||||
|
* time on screen "Extra life!!". The duration is set in constant |
||||
|
* {@link SpaceInvadersLevel#EXPL_DURATION}. |
||||
|
* |
||||
|
* |
||||
|
* @param collect item touched by ego |
||||
|
* @param ego the players ego object |
||||
|
*/ |
||||
|
void actionIfEgoCollidesWithCollect(GameObject collect, GameObject ego) { |
||||
|
double gameTime = this.getGameTime(); |
||||
|
|
||||
|
if (this.getObject("bonustext") == null) { |
||||
|
|
||||
|
// spawn a bonus points object |
||||
|
double vx = 2 * (Math.random() - 0.5) * SHARDSPEED + collect.getVX(); |
||||
|
double vy = 2 * (Math.random() - 0.5) * SHARDSPEED + collect.getVY(); |
||||
|
|
||||
|
|
||||
|
LimitedTimeController bonusTextController = |
||||
|
new LimitedTimeController(gameTime, SpaceInvadersLevel.EXPL_DURATION); |
||||
|
GameObject bonusText = new TextObject("bonustext", this, collect.getX(), collect.getY(), vx, |
||||
|
vy, "Extra life!!", 20, Color.YELLOW).addController(bonusTextController); |
||||
|
|
||||
|
addObject(bonusText); |
||||
|
|
||||
|
// delete collect |
||||
|
deleteObject(collect.getId()); |
||||
|
|
||||
|
// add to points counter |
||||
|
Integer lives = (Integer) getGlobalFlag("egoLives"); |
||||
|
lives++; |
||||
|
setGlobalFlag("egoLives", lives); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* implements behaviour of game when ego object is touching an enemy. It displays a text "AUAA!!" |
||||
|
* for a certain time on the game screen. Time span is defined as constant in |
||||
|
* {@link SpaceInvadersLevel#BONUS_DURATION } . |
||||
|
* |
||||
|
* @param enemy the enemy that was hit |
||||
|
* @param ego the ego object of the player |
||||
|
*/ |
||||
|
void actionIfEgoCollidesWithEnemy(GameObject enemy, GameObject ego) { |
||||
|
|
||||
|
/** |
||||
|
* set temporary text over ego. This object lives only for a short time. While it lives, further |
||||
|
* collisions are ignored. Otherwise a single collision would result in a lot of deducted |
||||
|
* points... |
||||
|
*/ |
||||
|
|
||||
|
double gameTime = this.getGameTime(); |
||||
|
GameObject auaObj = this.getObject("AUA-EGO"); |
||||
|
|
||||
|
if (auaObj == null) { |
||||
|
addObject(new TextObject("AUA-EGO", this, ego.getX(), ego.getY() - 20, ego.getVX(), |
||||
|
ego.getVY(), "AUAA!!", 10, Color.RED) |
||||
|
.addController(new LimitedTimeController(gameTime, BONUS_DURATION))); |
||||
|
// deduct points |
||||
|
Integer pts = (Integer) getGlobalFlag("points"); |
||||
|
setGlobalFlag("points", pts - 500); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* implements what happens if the eog object of player is hit by a shot. It removes the shot from |
||||
|
* screen, reduces lives by 1, removes the ego and end current playing. |
||||
|
* |
||||
|
* @param eshot the shot object that hits the ego |
||||
|
* @param ego the ego object of the player |
||||
|
*/ |
||||
|
void actionIfEgoObjectIsHit(GameObject eshot, GameObject ego) { |
||||
|
logger.debug("collision of " + eshot.getId() + " and " + ego.getId()); |
||||
|
|
||||
|
double gameTime = this.getGameTime(); |
||||
|
this.deleteObject(eshot.getId()); |
||||
|
|
||||
|
Integer oldLives = (Integer) getGlobalFlag("egoLives"); |
||||
|
int newLives = oldLives - 1; |
||||
|
setGlobalFlag("egoLives", newLives); |
||||
|
logger.debug("set egoLives to " + newLives + " (was " + oldLives + ")"); |
||||
|
|
||||
|
if (newLives <= 0) { |
||||
|
lost = true; |
||||
|
HighscoreManager.writeHSToFile((Integer) Playground.getGlobalFlag("points"), |
||||
|
(Integer) Playground.getGlobalFlag("highscore")); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
LinkedList<GameObject> eshots = collectObjects("enmyShot", true); |
||||
|
for (GameObject _eshot : eshots) { |
||||
|
deleteObject(_eshot.getId()); |
||||
|
} |
||||
|
setLevelFlag("detailedStatus", "dying"); |
||||
|
setLevelFlag("t0", gameTime); |
||||
|
ego.setActive(false); |
||||
|
createExplosion(gameTime, ego, "egoexp", DYING_INTERVAL, Color.WHITE); |
||||
|
LinkedList<GameObject> enemies = collectObjects("enemy", false); |
||||
|
for (GameObject enemy : enemies) { |
||||
|
enemy.setY(0); |
||||
|
enemy.setActive(false); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,81 @@ |
|||||
|
package playground; |
||||
|
|
||||
|
import static org.junit.Assert.assertTrue; |
||||
|
import java.awt.Color; |
||||
|
import org.junit.jupiter.api.AfterAll; |
||||
|
import org.junit.jupiter.api.BeforeAll; |
||||
|
import org.junit.jupiter.api.Test; |
||||
|
import gameobjects.EgoObject; |
||||
|
import gameobjects.GameObject; |
||||
|
import gameobjects.RectObject; |
||||
|
|
||||
|
/** |
||||
|
* Tests {@link SpaceInvadersLevel} for |
||||
|
* <ol> |
||||
|
* <li>calcEnemySpeedX() returns the same value as constant SpaceInvadersLevel.ENEMYSPEEDX |
||||
|
* <li>calcEnemySpeedY() returns the same value as constant SpaceInvadersLevel.ENEMYSPEEDY |
||||
|
* <li>calcNrEnemies() returns the same value as constant SpaceInvadersLevel.NR_ENEMIES |
||||
|
* <li>actionIfEnemyIsHit() adds 200 points to score |
||||
|
* <li>actionIfEgoObjectIsHit() reduces number of lives (egoLives) |
||||
|
* </ol> |
||||
|
* @author jkonert |
||||
|
* |
||||
|
*/ |
||||
|
class SpaceInvadersLevelTest { |
||||
|
|
||||
|
private static SpaceInvadersLevel myLevel; |
||||
|
|
||||
|
@BeforeAll |
||||
|
static void setUpBeforeClass() throws Exception { |
||||
|
myLevel = new SpaceInvadersLevel(); |
||||
|
SpaceInvadersLevel.setGlobalFlag("egoLives", 5); |
||||
|
SpaceInvadersLevel.setGlobalFlag("points", 500); |
||||
|
SpaceInvadersLevel.setGlobalFlag("highscore", 5000); |
||||
|
} |
||||
|
|
||||
|
@AfterAll |
||||
|
static void tearDownAfterClass() throws Exception { |
||||
|
// nothing |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
void testCalcEnemySpeedX() { |
||||
|
assertTrue("EnemySpeedX is as in SpaceInvadersLevel defined", myLevel.calcEnemySpeedX() == SpaceInvadersLevel.ENEMYSPEEDX); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
void testCalcEnemySpeedY() { |
||||
|
assertTrue("EnemySpeedY is as in SpaceInvadersLevel defined", myLevel.calcEnemySpeedY() == SpaceInvadersLevel.ENEMYSPEEDY); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
void testCalcNrEnemies() { |
||||
|
assertTrue("NrOfEnemies is as in SpaceInvadersLevel defined", myLevel.calcNrEnemies() == SpaceInvadersLevel.NR_ENEMIES); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@Test |
||||
|
void testActionIfEnemyIsHitPointsUp() { |
||||
|
Integer numPointsBefore = (Integer)myLevel.getGlobalFlag("points"); |
||||
|
GameObject dummyShot = new RectObject("shot1", myLevel, 0,0,0,0, 12, 12, Color.WHITE); |
||||
|
GameObject dummyEnemy = new RectObject("ego1", myLevel, 0,0,0,0, 12, 12, Color.BLACK); |
||||
|
myLevel.addObject(dummyShot); |
||||
|
myLevel.addObject(dummyEnemy); |
||||
|
myLevel.actionIfEnemyIsHit(dummyEnemy, dummyShot);; // this is the call under test |
||||
|
Integer numPointsAfter = (Integer)myLevel.getGlobalFlag("points"); // changed? |
||||
|
assertTrue("numPoints is up +200 after EnemyIsHit", numPointsAfter == numPointsBefore + 200); // points are set +200 , check. |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
void testActionIfEgoObjectIsHitLivesDown() { |
||||
|
Integer numLivesBefore = (Integer)myLevel.getGlobalFlag("egoLives"); |
||||
|
GameObject dummyShot = new RectObject("shot1", myLevel, 0,0,0,0, 12, 12, Color.RED); |
||||
|
GameObject dummyEgo = new EgoObject("ego1", myLevel, 0,0,0,0, 5); |
||||
|
myLevel.addObject(dummyShot); |
||||
|
myLevel.actionIfEgoObjectIsHit(dummyShot, dummyEgo); // this is the call under test |
||||
|
Integer numLivesAfter = (Integer)myLevel.getGlobalFlag("egoLives"); // changed? |
||||
|
assertTrue("numLives is reduced by one ifEgoIsHit", numLivesAfter == numLivesBefore - 1); // lives is reduced by one |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,93 @@ |
|||||
|
package rendering; |
||||
|
|
||||
|
import gameobjects.GameObject; |
||||
|
import playground.Animation; |
||||
|
import java.awt.Graphics2D; |
||||
|
import java.awt.image.BufferedImage; |
||||
|
import java.util.LinkedList; |
||||
|
import org.apache.logging.log4j.Logger; |
||||
|
import org.apache.logging.log4j.LogManager; |
||||
|
|
||||
|
public class AnimationArtist extends Artist { |
||||
|
|
||||
|
protected LinkedList<BufferedImage> imageArray; |
||||
|
protected LinkedList<Double> showtime; |
||||
|
protected double t0; |
||||
|
|
||||
|
protected int loopFrame = 0; |
||||
|
|
||||
|
protected double w = 0, h = 0, scale = 0; |
||||
|
protected String playmode = ""; // can be loop, forward, backward |
||||
|
private static Logger logger = LogManager.getLogger(AnimationArtist.class); |
||||
|
|
||||
|
|
||||
|
public AnimationArtist(GameObject go, Animation anim, double t0, String playmode, double scale) { |
||||
|
super(go); |
||||
|
|
||||
|
this.imageArray = anim.getImageList(); |
||||
|
this.showtime = anim.getShowtimeList(); |
||||
|
this.t0 = t0; |
||||
|
logger.debug("AnimationArtist start = ") ; |
||||
|
this.loopFrame = 0; |
||||
|
|
||||
|
for (int i = 0; i < imageArray.size(); i++) { |
||||
|
logger.trace("ANIMRAWWH="+imageArray.get(i).getWidth()) ; |
||||
|
this.w = Math.max(this.w, imageArray.get(i).getWidth()); |
||||
|
this.h = Math.max(imageArray.get(i).getHeight(), this.h); |
||||
|
} |
||||
|
|
||||
|
logger.debug("AnimationArtist RAW WH = "+this.w+"/"+this.h) ; |
||||
|
|
||||
|
this.playmode = playmode; |
||||
|
this.w *= scale; |
||||
|
this.h *= scale; |
||||
|
} |
||||
|
|
||||
|
public double getW() { |
||||
|
return w; |
||||
|
} |
||||
|
|
||||
|
public double getH() { |
||||
|
return h; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@Override |
||||
|
public void draw(Graphics2D g) { |
||||
|
double i2 = this.getGameTime(); |
||||
|
|
||||
|
double elapsedTime = i2 - t0; |
||||
|
|
||||
|
// Diff chance from sec to millis |
||||
|
double mseconds = (double) elapsedTime; |
||||
|
logger.debug("showtime= "+showtime.get(loopFrame)+" elapsed= "+elapsedTime+" i2= "+i2); |
||||
|
|
||||
|
if (playmode.equals("loop")) { |
||||
|
if (mseconds >= showtime.get(loopFrame)) { |
||||
|
loopFrame++; |
||||
|
if (loopFrame >= imageArray.size()) |
||||
|
loopFrame = 0; |
||||
|
t0 = i2; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (playmode.equals("forward")) { |
||||
|
if (mseconds >= showtime.get(loopFrame) && loopFrame < imageArray.size() - 1) { |
||||
|
loopFrame++; |
||||
|
t0 = i2; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (playmode.equals("backward")) { |
||||
|
if (mseconds >= showtime.get(loopFrame) && loopFrame > 1) { |
||||
|
loopFrame--; |
||||
|
t0 = i2; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
g.drawImage(imageArray.get(loopFrame), (int) Math.round(this.getX() - w / 2.), |
||||
|
(int) Math.round(this.getY() - h / 2.), (int) w, (int) h, null); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,40 @@ |
|||||
|
package rendering; |
||||
|
|
||||
|
import gameobjects.GameObject; |
||||
|
import java.awt.Graphics2D; |
||||
|
|
||||
|
public abstract class Artist { |
||||
|
protected GameObject gameObject; |
||||
|
|
||||
|
Artist(GameObject go) { |
||||
|
this.gameObject = go; |
||||
|
} |
||||
|
|
||||
|
public double getX() { |
||||
|
return this.gameObject.getX(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public double getY() { |
||||
|
return this.gameObject.getY(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public double getVX() { |
||||
|
return this.gameObject.getX(); |
||||
|
} |
||||
|
|
||||
|
public double getVY() { |
||||
|
return this.gameObject.getX(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public double getGameTime() { |
||||
|
return this.gameObject.getGameTime(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
public abstract void draw(Graphics2D g); |
||||
|
|
||||
|
} |
@ -0,0 +1,34 @@ |
|||||
|
package rendering; |
||||
|
|
||||
|
import gameobjects.GameObject; |
||||
|
import java.awt.Color; |
||||
|
import java.awt.Graphics2D; |
||||
|
|
||||
|
public class CircleArtist extends Artist { |
||||
|
|
||||
|
protected double egoRad; |
||||
|
protected Color color; |
||||
|
|
||||
|
public CircleArtist(GameObject go) { |
||||
|
super(go); |
||||
|
this.egoRad = 15.0; |
||||
|
} |
||||
|
|
||||
|
public CircleArtist(GameObject go, double egoRad, Color color) { |
||||
|
super(go); |
||||
|
this.egoRad = egoRad; |
||||
|
this.color = color; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void draw(Graphics2D g) { |
||||
|
g.setColor(this.color); |
||||
|
double x = this.getX(); |
||||
|
double y = this.getY(); |
||||
|
int posX = (int) (x - egoRad); |
||||
|
int posY = (int) (y - egoRad); |
||||
|
int rad = (int) (2 * egoRad); |
||||
|
g.fillOval(posX, posY, rad, rad); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,33 @@ |
|||||
|
package rendering; |
||||
|
|
||||
|
import gameobjects.GameObject; |
||||
|
import java.awt.Color; |
||||
|
import java.awt.Graphics2D; |
||||
|
|
||||
|
public class RectArtist extends Artist { |
||||
|
|
||||
|
protected Color color; |
||||
|
protected double width, height; |
||||
|
|
||||
|
public RectArtist(GameObject go, double width, double height, Color color) { |
||||
|
super(go); |
||||
|
this.color = color; |
||||
|
this.width = width; |
||||
|
this.height = height; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void draw(Graphics2D g) { |
||||
|
g.setColor(this.color); |
||||
|
|
||||
|
// g.drawLine((int) (Math.round(this.getX())), (int) (Math.round(this.getY()-this.height/2.)), |
||||
|
// (int) Math.round(this.getX()), |
||||
|
// (int) Math.round(this.getY() + this.height/2.)); |
||||
|
int x = (int) this.getX(); |
||||
|
int y = (int) this.getY(); |
||||
|
g.fillRect((int) (this.getX() - this.width / 2.), (int) (this.getY() - this.height / 2.), |
||||
|
(int) this.width, (int) this.height); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,81 @@ |
|||||
|
package rendering; |
||||
|
|
||||
|
import gameobjects.GameObject; |
||||
|
import java.awt.Color; |
||||
|
import java.awt.Font; |
||||
|
import java.awt.Graphics2D; |
||||
|
import java.awt.font.FontRenderContext; |
||||
|
import java.awt.font.TextAttribute; |
||||
|
import java.text.AttributedString; |
||||
|
|
||||
|
/** |
||||
|
* Rendering an object as a text of a specified color, size and font. |
||||
|
*/ |
||||
|
public class TextArtist extends Artist { |
||||
|
|
||||
|
private String text = null; |
||||
|
private int size = 1; |
||||
|
private Color textColor = null; |
||||
|
protected double textWidth, textHeight; |
||||
|
Font serifFont = null; |
||||
|
|
||||
|
public TextArtist(GameObject go, String text, int size, Color textColor) { |
||||
|
super(go); |
||||
|
this.size = size; |
||||
|
this.text = text; |
||||
|
|
||||
|
this.serifFont = new Font("Serif", Font.PLAIN, size); |
||||
|
FontRenderContext frc = new FontRenderContext(null, false, false); |
||||
|
this.textWidth = (int) (serifFont.getStringBounds(text, frc).getWidth()); |
||||
|
this.textHeight = (int) (serifFont.getStringBounds(text, frc).getHeight()); |
||||
|
|
||||
|
this.textColor = textColor; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public String getText() { |
||||
|
return this.text; |
||||
|
} |
||||
|
|
||||
|
public void setText(String s) { |
||||
|
this.text = s; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
public double getTextWidth() { |
||||
|
return textWidth; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public void setTextWidth(double textWidth) { |
||||
|
this.textWidth = textWidth; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
public double getTextHeight() { |
||||
|
return textHeight; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public void setTextHeight(double textHeight) { |
||||
|
this.textHeight = textHeight; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Draw the text. |
||||
|
* |
||||
|
* @param g The Swing graphics context. |
||||
|
*/ |
||||
|
@Override |
||||
|
public void draw(Graphics2D g) { |
||||
|
AttributedString as = new AttributedString(this.text); |
||||
|
as.addAttribute(TextAttribute.FONT, this.serifFont); |
||||
|
as.addAttribute(TextAttribute.FOREGROUND, this.textColor); |
||||
|
|
||||
|
g.drawString(as.getIterator(), (int) Math.round(this.getX() - this.textWidth / 2.), |
||||
|
(int) Math.round(this.getY() + this.textHeight / 2.)); |
||||
|
} |
||||
|
|
||||
|
} |
Some files were not shown because too many files changed in this diff
Write
Preview
Loading…
Cancel
Save
Reference in new issue