Polygon Wars is a simple shooter video game. Inspired by 80's arcade games, the game world looks simple and is easy to read. In this game you control a simple circle shape, that can shoot, move and even dash. Your goal is to survive until all enemies are dead and no more enemies are spawned. Killing enemies grants points and pickups, collect them all to reach the highest score of anyone you know!
Below you can find a quick video description of the Project. It gives you an overview on how to download, build and run the project. (Click on the Image to open the video.)
- Movement
W
A
S
D
or↑
←
↓
→
to move on the MapRight-Mouse
or
- Combat
Left-Mouse
to shoot
- Gameplay
Esc
to pause/resumeTab
to restart (this is for Debugging only)
This project was created by:
- David Pittracher
- Fabio Vitalba
Unfortunately LibGDX only has unofficial maven support. So in order to run the game you will have to execute the steps below.
In order to run this Project you will need to have both java
(At least JAVA 17) and maven installed on your machine.
Once you've installed both, you'll need to first build then execute the project through command line.
To build the project, run:
mvn package
You can also compile
mvn compile
or test the project
mvn test
To play the game, run:
mvn exec:exec
Alternatively you can also run the jar-directly, in this case run the following:
java -jar ./target/polygonwars-1.0.0-jar-with-dependencies.jar
java -jar -XstartOnFirstThread ./target/polygonwars-1.0.0-jar-with-dependencies.jar
Note: The flag
-XstartOnFirstThread
is only required for MacOS, if you're on any other Operating system, you should omit this flag.
In order to generate the documentation for the project use the following command:
mvn javadoc:javadoc
You will find the generated documentation under ./target/site/apidocs/index.html
.
Our Project is divided into three main Java Packages:
- org.davidfabio.game
- Contains anything that represents the Game-World and Game-Flow.
- org.davidfabio.game.enemies
- Contains all the enemy logics. Since these became very specific, we opted to move them to a seperate package.
- org.davidfabio.input
- Contains anything that is required to handle User Inputs (Key-presses, Mouse movement, ...)
- org.davidfabio.ui
- Contains anything that creates User Interfaces (Main Menu, In-game UI, ...)
- org.davidfabio.utils
- Contains anything that is useful for all packages or is not strictly Game-World-specific.
We have some diagrams showing the relationship between our implemented classes. Please have a look at these diagrams before delving into our codebase.
- UI Flowchart
- This flowchart explains very well how the Programm is started and which classes are called to reach the actual Game.
- UI Flowchart
- Game Class-Diagram
- This Class Diagram illustrates how the Game-World is composed. It does not contain all specific classes and subclasses, but it's a good start to understand what is present in a Game-World and how it's connected.
- Game Class Diagram
- World Class-Diagram
- This Class Diagram shows all the main classes like
player
,enemy
,entity
,bullet
and all their derivatives. - World Class Diagram
- This Class Diagram shows all the main classes like
These are the Third-Party Libraries we've used:
- LibGDX: This library provides us with some basic functionalities needed to create a game. We were able to use features like: Shape-Renderers, Cameras, Sound-players and more.
- Shade UI: (This is no library, but a preexisting Resource we're using.) Skin for UI (Buttons, Progress Bars, and so on). It is freely available under czyzby's GDX Skins GitHub Repository.
- Jackson: This library allows us to easily serialize and deserialize objects into JSON format for storage in a file.
List and explain how you used the 10 programming techniques required for this project.
- Graphical User Interface: We used the built-in Libraries of LibGDX in order to create various User Interfaces for Game Menus, Settings, Highscores and User Interface in Game.
- Method Overriding: Since we're using inheritance and interfaces we predefine a few methods at a high level (Example
Entity
providesinit()
,update()
,render()
methods.). However, some Entities require special behaviour and therefore need to override the original implementation of the method. For example thePlayer
class requires a differentupdate()
method than theEnemyChaser
class. - Interfaces:
Movable
,Attackable
,Attacker
Interfaces. These are used to unify the combat behaviour for Players, Enemies and other Entities. - Method Overloading: Various methods use the overloading technique to provide easy-to-use methods. For example:
- In the
UIBuilder
class we use method overloading to provide various functions to create UI-controls in default settings, or by overloading, with specific settings.
- In the
- Collections: In order to store various data we use collections. For example:
- When storing past
Score
s in order to list the highscores. - When storing enemies in the
World
-class to periodically update their behaviour and spawn new ones.
- When storing past
- Try-Catch-Blocks: In order to safely load the sounds and music we rely on Try-Catch blocks to avoid any errors on missing files. We also use these Try-Catch blocks to avoid RunTimeErrors while writing or reading from files.
- File I/O: In order to store settings and scores we use files and therefore we need to write and read from files.
- Serialization: In order to store Settings and Scores in a sensible way, we serialize them into a JSON. We use Jackson for this.
- Deserialization: In order to read our serialized Settings and Scores we need to deserialize them from JSON. We use Jackson for this.
- Test Hooks: For our Test Suite we use
@BeforeAll
and@AfterAll
in order to clean our Test environment. For example theJSONFileManagementTest
uses these hooks to clean the Files created. - Streams: In the High Scores screen we use streams to show the best 5 scores present in the Scores List.
Testing a LibGDX application has proven to be very tricky. This is because of two reasons mainly:
- Testing UI is always difficult.
- Many LibGDX-methods, which we use throughout our game, can only be run in the main thread and require some kind of initialization. Both requirements that we cannot satisfy through jUnit Tests. Therefore Classes like the
Camera
cannot be tested as they would require Gdx.graphics to be set up, which again requires an Application to run on the main thread.
Because of these constraints we tried to test as much of our non-LibGDX-related classes as possible. Obviously this still leaves a lot of room for potential errors.
Overall, we had fun iterating over the various features and ideas of the Project. Both David and I learned a lot in the process. We also learned from eachother since we both have different backgrounds in programming and are used to different styles of programming. We were very quick at building a working prototype and this helped us get a lot of the groundwork done early.
We had no clear division of responsibilities, but we ended up with the following responsibilities:
- David Pittracher: Game Design
- Fabio Vitalba: UI Design, Documentation, Project structure
We both used GitHub Issues in order to track the outstanding tasks and features.
Elaborate on the main challenges each group member faced throughout the project and how they were surpassed.
- David Pittracher: The most difficult things for me were how to structure the project (i.e. the class hierarchies) and which system to use to spawn enemies (time-based or something else?, completely fixed/static or with some amount of randomness?). Both things were overcome with thinking about it for a bit, trying out the most sensible idea and then simply adjusting it if needed. It was also a challenge to work with someone else on a bigger project like this and coordinate it.
- Fabio Vitalba: Migrating from gradle (LibGDX's preferred Bundler) to Maven was quite painful. Coordinating the work was difficult at first, but once we figured out how to use the GitHub Issues it was a lot better.
Describe what you learned with this project.
- David Pittracher: The main thing was working on a project with someone else. I also learned to use some features of GitHub I never/barely used before (branches, issues).
- Fabio Vitalba: I learned a new library called
LibGDX
and David helped me learn something more regarding Game Development.