Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Project developed as part of a LDTS (Software Design and Testing Laboratory) course @ FEUP

Notifications You must be signed in to change notification settings

jmisidro/LDTS-Space-Shooter-Ultimate

Repository files navigation

Space Shooter Ultimate

An arcade like game built on Java, through TDD

The space shooter ultimate is a space invaders type game in which the goal is to kill the maximum amount of enemies without losing all your lives. The longer you stay alive the more enemies will spawn and the stronger they will be.

This project was developed by Filipe Cardoso (up202006409@edu.fe.up.pt), José Isidro (up202006485@edu.fe.up.pt) and Miguel Nogueira (up202005488@edu.fe.up.pt) for LDTS 2021-22.

IMPLEMENTED FEATURES

  • Single shooting - Shoots one bullet at once.

GIF 1. Single Shot



  • Double shooting - Shoots two bullets at once. However it deals less damage.

GIF 2. Double Shot



  • Burst shooting - Shoots bullets in burst. However it deals less damage.

GIF 3. Bust Shot



  • Asteroids - asteroids will spawn randomly. Try to dodge them.

GIF 4. Asteroids



  • Spaceships - spaceships will spawn and move randomly whilst shooting you. Try to dodge their bullets.

GIF 5. Spaceships



  • Items - items will spawn randomly after you gain some score points. Try to catch them so you can get more lives. If you happen to have reached the maximum lives, which is 3, you can increase your score.

GIF 6. Items




DESIGN

Architectural Pattern

Problem in Context

The architecture of the project is one of the most important parts of a project like this. At first, we weren't able to implement this pattern as we struggled to do so. Later on the project, we succeeded in its implementation.

The Pattern

We have applied the Model-View-Controller pattern. This pattern allows you to implement user interfaces, data, and controlling logic separately. This separation between the display and the logic provides for a better division of labor and improved maintenance and better organized code overall.

Our game currently has an MVC module for each one of the three states:

  • Main Menu
  • Space
  • Game Over

Implementation

Image 1. MVC Diagram



Consequences

The use of the Model View Controller Pattern in the current design allows the following benefits:

  • Easily Modifiable
  • Faster Development Process
  • Easy planning and maintenance

GameState

Problem in Context

In order to keep playing without having to restart the game, we created a game menu. We then needed a way to efficiently jump between the Game Menu and the Playing Space. Moreover, we also needed a GameOver Menu where the player could either close the game or continue to play. For that purpose, we needed a way to manage which was the current state of the game and a way change it.

The Pattern

We have applied the State pattern. This pattern allows you to represent different states with different subclasses. We can switch to a different state of the application by switching to another implementation (i.e., another subclass). This pattern allowed to address the identified problems because now the player can jump between states depending on what he needs to do. There is now a MenuState, where the game is started so the player can start playing or quit the game. There is a Playing State for when the game is being played and there is a Game Over State for when the player dies.

Implementation

The following figure shows how the pattern’s roles were mapped to the application classes.

Image 2. State UML Diagram



These classes can be found in the following files:

Consequences

The use of the State Pattern in the current design allows the following benefits:

  • Each state has its own MVC module.
  • We don't have to rely on flags.
  • There are now more classes and instances to manage, but still in a reasonable number.

Space Builder

Problem in Context:

A space consists in an agglomeration of elements such as borders, asteroids, spaceships, a player, items, etc. This implementation makes it possible to only create specific elements and also generate spaces in different ways, in case we need to add different levels in the future, for instance.

The Pattern:

The Builder is a creational design pattern, which allows a step-by-step creation of complex objects, improving the code. The construction is controlled by a director object that only needs to know the type of object it is to create. In our case, the director is the PlayState.

Implementation:

As for the implementation, the SpaceBuilder is a class which knows how to construct a space, however only its methods can supply the necessary components of the spaces. The builder pattern is implemented in all the above classes by dividing the construction in smaller steps.

Image 3. Space Builder UML

These classes can be found in the following files:

Consequences:

Benefits of applying the above pattern:

  • You avoid tight coupling between the creator and the concrete products.
  • Open/Closed Principle. You can introduce new types of products into the program without breaking existing client code.
  • You can construct objects step-by-step, defer construction steps or run steps recursively.

Code Smells AND Possible Refactoring

Switch Statements and Code Duplicate

We have spotted was the high use of complex Switch Statements to perform tasks like moving through the menus or moving the player. This will result in Duplicate Code. In order to solve this we could use the Observer Design Pattern which will be useful since a few objects in the app must observe others in certain cases. For instance, we should create a Keyboard Observer and Listener which would solve the duplicate code showed in the image below.

Image 4. Code Duplicate



Lazy Class

The class SingleShot, DoubleShot and BurstShot are an examples of Lazy Classes in our code. These classes extend the Bullet class, but they only use its constructor to set their position and damage. Removing these classes would make the code a little simpler since they could be implemented as be a method of their parent class.

Image 5. Lazy Class - DoubleShot




TESTING

  • Screenshot of coverage report.

Image 6. test.png



SELF-EVALUATION

  • Filipe Cardoso: 33.3%
  • José Isidro: 33.3%
  • Miguel Nogueira: 33.3%

About

Project developed as part of a LDTS (Software Design and Testing Laboratory) course @ FEUP

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages