This commit is contained in:
Andreas Greiner 2021-06-28 21:45:53 +02:00
parent b0d8b5806f
commit 572fc7b439
54 changed files with 340 additions and 266 deletions

View File

@ -2,7 +2,9 @@ package de.thdeg.greiner.superpangworld.game.managers;
import de.thdeg.greiner.superpangworld.gameview.GameView; import de.thdeg.greiner.superpangworld.gameview.GameView;
/** This class manages the main game loop of the game. */ /**
* This class manages the main game loop of the game.
*/
public class GameLoopManager { public class GameLoopManager {
private final GameView gameView; private final GameView gameView;
private final InputManager inputManager; private final InputManager inputManager;

View File

@ -2,12 +2,16 @@ package de.thdeg.greiner.superpangworld.game.managers;
import de.thdeg.greiner.superpangworld.gameview.GameView; import de.thdeg.greiner.superpangworld.gameview.GameView;
import de.thdeg.greiner.superpangworld.graphics.base.Bubble; import de.thdeg.greiner.superpangworld.graphics.base.Bubble;
import de.thdeg.greiner.superpangworld.graphics.base.CollidableGameObject;
import de.thdeg.greiner.superpangworld.graphics.base.GameObject; import de.thdeg.greiner.superpangworld.graphics.base.GameObject;
import de.thdeg.greiner.superpangworld.graphics.immovable.*; import de.thdeg.greiner.superpangworld.graphics.immovable.*;
import de.thdeg.greiner.superpangworld.graphics.moveable.*; import de.thdeg.greiner.superpangworld.graphics.moveable.*;
import java.awt.*; import java.awt.Color;
import java.util.ArrayList;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List;
import java.util.Random;
/** /**
* The manager handling the display and passive movement of the game objects. * The manager handling the display and passive movement of the game objects.
@ -23,17 +27,22 @@ class GameObjectManager {
private final LivesLabel livesLabel; private final LivesLabel livesLabel;
private final Background background; private final Background background;
private final GameFrame frame; private final GameFrame frame;
private final GameOverlay gameOverlay; private final Overlay overlay;
private final PlayerObject playerObject; private final PlayerObject playerObject;
private final LinkedList<GameObject> gameObjects; private final LinkedList<GameObject> gameObjects;
private final Random random;
/** /**
* Create a manager handling the display and passive movement of the game objects. * Create a manager handling the game objects.
*
* @param gameView the GameView * @param gameView the GameView
*/ */
public GameObjectManager(GameView gameView){ public GameObjectManager(GameView gameView){
random = new Random();
gameView.setColorForBlockImage('k', Color.LIGHT_GRAY); gameView.setColorForBlockImage('k', Color.LIGHT_GRAY);
bubbles = new LinkedList<>(); bubbles = new LinkedList<>();
@ -47,18 +56,72 @@ class GameObjectManager {
background = new Background(gameView); background = new Background(gameView);
frame = new GameFrame(gameView); frame = new GameFrame(gameView);
playerObject = new PlayerObject(gameView); playerObject = new PlayerObject(gameView);
gameOverlay = new GameOverlay(gameView); overlay = new Overlay(gameView);
} }
/** /**
* Clear all game object lists. * Clear all game object lists and stops any sounds.
*/ */
public void clearAll(){ public void clearAll(){
gameObjects.clear(); gameObjects.clear();
bubbles.clear(); bubbles.clear();
harpoons.forEach(Harpoon::stopSound);
harpoons.clear(); harpoons.clear();
} }
/**
* Get all collideable game objects a bubble can collide with.
*
* @return the game objects
*/
public List<CollidableGameObject> getBubblesCollideables(){
List<CollidableGameObject> collidableGameObjects = new ArrayList<>();
collidableGameObjects.add(playerObject);
collidableGameObjects.addAll(harpoons);
return collidableGameObjects;
}
/**
* Add bubbles to the game.
*
* @param newBubbles the list of new bubbles
* @param gamePlayManager the associated game play manager
*/
public void addBubbles(List<Bubble> newBubbles,GamePlayManager gamePlayManager){
List<CollidableGameObject> collidableGameObjects = getBubblesCollideables();
newBubbles.forEach(bubble->{
bubble.setGamePlayManager(gamePlayManager);
bubble.addCollidableGameObject(collidableGameObjects);
bubbles.add(bubble);
});
}
/**
* Add a random bubble to the game.
*
* @param specialBubblePresent flag, if a special bubble is already present in the game
* @param gameView the game view for the bubble
* @param gamePlayManager the game play manager for the bubble
* @return <code>true</code> if a special bubble was added, otherwise <code>false</code>
*/
public boolean addRandomBubble(boolean specialBubblePresent, GameView gameView, GamePlayManager gamePlayManager){
boolean specialBubbleAdded = false;
int randomNumber = specialBubblePresent ? random.nextInt(90) : random.nextInt(100);
List<CollidableGameObject> collidableGameObjects = getBubblesCollideables();
Bubble newBubble;
if(randomNumber<60){
newBubble = new RoundBubble(gameView, collidableGameObjects);
}else if(randomNumber<90){
newBubble = new HexagonalBubble(gameView, collidableGameObjects);
}else{
newBubble = new SpecialBubble(gameView, collidableGameObjects);
specialBubbleAdded = true;
}
newBubble.setGamePlayManager(gamePlayManager);
bubbles.add(newBubble);
return specialBubbleAdded;
}
/** /**
* Add the objects to the canvas and handle update their positions. * Add the objects to the canvas and handle update their positions.
*/ */
@ -73,7 +136,7 @@ class GameObjectManager {
gameObjects.add(livesLabel); gameObjects.add(livesLabel);
gameObjects.add(playerObject); gameObjects.add(playerObject);
gameObjects.addAll(bubbles); gameObjects.addAll(bubbles);
gameObjects.add(gameOverlay); gameObjects.add(overlay);
gameObjects.forEach(gameObject ->{ gameObjects.forEach(gameObject ->{
gameObject.update(); gameObject.update();
@ -149,8 +212,8 @@ class GameObjectManager {
* *
* @return the game overlay * @return the game overlay
*/ */
public GameOverlay getGameOverlay(){ public Overlay getGameOverlay(){
return gameOverlay; return overlay;
} }
/** /**
@ -161,4 +224,4 @@ class GameObjectManager {
public Background getBackground() { public Background getBackground() {
return background; return background;
} }
} }

View File

@ -2,45 +2,28 @@ package de.thdeg.greiner.superpangworld.game.managers;
import de.thdeg.greiner.superpangworld.gameview.GameView; import de.thdeg.greiner.superpangworld.gameview.GameView;
import de.thdeg.greiner.superpangworld.graphics.base.Bubble; import de.thdeg.greiner.superpangworld.graphics.base.Bubble;
import de.thdeg.greiner.superpangworld.graphics.base.CollidableGameObject;
import de.thdeg.greiner.superpangworld.graphics.base.Position; import de.thdeg.greiner.superpangworld.graphics.base.Position;
import de.thdeg.greiner.superpangworld.graphics.helper.Level; import de.thdeg.greiner.superpangworld.graphics.helper.*;
import de.thdeg.greiner.superpangworld.graphics.helper.Player;
import de.thdeg.greiner.superpangworld.graphics.moveable.Harpoon; import de.thdeg.greiner.superpangworld.graphics.moveable.Harpoon;
import de.thdeg.greiner.superpangworld.graphics.moveable.HexagonalBubble;
import de.thdeg.greiner.superpangworld.graphics.moveable.RoundBubble;
import de.thdeg.greiner.superpangworld.graphics.moveable.SpecialBubble;
import java.awt.*; import java.awt.Color;
import java.util.*; import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;
/** /**
* The manager which handles the gameplay. * The manager which handles the gameplay.
*/ */
public class GamePlayManager { public class GamePlayManager {
/** Flag, if a special bubble is present */
/** The GameView on which the game is displayed */
private final GameView gameView;
/** The manager, which handles the game objects */
private final GameObjectManager gameObjectManager;
/** Generator for random values */
private final Random random;
/** The current level */
private Level level;
/** The player */
private Player player;
/** The level manager */
private LevelManager levelManager;
/** Flag, if bubbles should be spawned */
private boolean spawnBubbles;
/** Flag, if all bubbles should be destroyed */
private boolean destroyAllBubbles;
/** Flag, is a special bubble is currently present */
public boolean specialBubblePresent; public boolean specialBubblePresent;
/** Flag, if the bubble movement is froze */ /** Flag, if the bubble movement is frozen */
public boolean movementFroze; public boolean movementFroze;
private final GameView gameView;
private final GameObjectManager gameObjectManager;
private Level level;
private Player player;
private LevelManager levelManager;
private boolean spawnBubbles;
private boolean destroyAllBubbles;
/** /**
* Create the manager handling the gameplay. * Create the manager handling the gameplay.
@ -49,39 +32,47 @@ public class GamePlayManager {
* @param gameObjectManager the manager handling the game objects * @param gameObjectManager the manager handling the game objects
*/ */
public GamePlayManager(GameView gameView, GameObjectManager gameObjectManager) { public GamePlayManager(GameView gameView, GameObjectManager gameObjectManager) {
random = new Random();
this.gameView = gameView; this.gameView = gameView;
this.gameObjectManager = gameObjectManager; this.gameObjectManager = gameObjectManager;
boolean easyDifficulty = gameView.showSimpleStartScreen("Super Pang World","Start the game"); initializeGame();
initializeGame(easyDifficulty);
initializeLevel();
} }
/** /**
* Initialize the game. * Initialize the game.
*
* @param easyDifficulty the game difficulty
*/ */
private void initializeGame(boolean easyDifficulty){ private void initializeGame(){
StartScreen startScreen = new StartScreen(gameView);
startScreen.showStartScreen();
boolean difficultySetToEasy = startScreen.isDifficultySetToEasy();
gameView.playSound("backgroundMusic.wav", true); gameView.playSound("backgroundMusic.wav", true);
gameObjectManager.clearAll(); levelManager = new LevelManager(difficultySetToEasy);
levelManager = new LevelManager(easyDifficulty);
try { try {
level = levelManager.getNextLevel(); level = levelManager.getNextLevel();
} catch (LevelManager.NoMoreLevelsAvailableException e) { } catch (LevelManager.NoMoreLevelsAvailableException e) {
System.out.println("No levels were generated, exiting program");
System.exit(-1); System.exit(-1);
} }
player = new Player(level); player = new Player(level);
gameObjectManager.getPlayerObject().setGamePlayManager(this); gameObjectManager.getPlayerObject().setGamePlayManager(this);
gameObjectManager.getPlayerObject().setPosition(GameView.WIDTH/2.0, 360);
initializeLevel();
}
/**
* Start the next game or quit the game entirely.
*/
private void nextGame(){
gameView.stopAllSounds();
gameObjectManager.clearAll();
EndScreen endScreen = new EndScreen(gameView);
String message = player.lives<0 ? "You lost the game.\n Your score: "+player.score : "You won the game.\n Your score: "+player.score;
endScreen.showEndScreen(message);
initializeGame();
} }
/** /**
* Initialize the level. * Initialize the level.
*/ */
private void initializeLevel(){ private void initializeLevel(){
// Set Gameplay variables
spawnBubbles = true; spawnBubbles = true;
destroyAllBubbles = false; destroyAllBubbles = false;
specialBubblePresent = false; specialBubblePresent = false;
@ -90,24 +81,6 @@ public class GamePlayManager {
gameObjectManager.getBackground().setBackgroundImage(level.backgroundImage); gameObjectManager.getBackground().setBackgroundImage(level.backgroundImage);
} }
/**
* Loose a life and remove all bubbles
*/
public void looseLife(){
if(player.lives==0){
handleGameEnded("You lost the game.\nYour score: "+player.score);
}else {
player.lives--;
gameObjectManager.getLivesLabel().setLifeCount(player.lives);
gameObjectManager.getBubbles().clear();
gameObjectManager.getHarpoons().forEach(h -> h.stopSound());
gameObjectManager.getHarpoons().clear();
specialBubblePresent = false;
spawnBubbles = true;
gameObjectManager.getGameOverlay().flashScreen(Color.red, 100);
}
}
/** /**
* Switch to the next level or end the game if every level was played. * Switch to the next level or end the game if every level was played.
*/ */
@ -116,25 +89,27 @@ public class GamePlayManager {
level = levelManager.getNextLevel(); level = levelManager.getNextLevel();
initializeLevel(); initializeLevel();
} catch (LevelManager.NoMoreLevelsAvailableException e) { } catch (LevelManager.NoMoreLevelsAvailableException e) {
handleGameEnded("You won the game.\nYour score: "+player.score); nextGame();
} }
} }
/** /**
* End the game and show exit/restart screen. * Loose a life and remove all bubbles.
*
* @param text text to display
*/ */
private void handleGameEnded(String text){ public void looseLife(){
gameView.stopAllSounds(); player.lives--;
gameView.showEndScreen(text); if(player.lives<0){
boolean easyDifficulty = gameView.showSimpleStartScreen("Super Pang World","Start the game"); nextGame();
initializeGame(easyDifficulty); }else {
initializeLevel(); gameObjectManager.clearAll();
specialBubblePresent = false;
spawnBubbles = true;
gameObjectManager.getGameOverlay().flashScreen(Color.red, 100);
}
} }
/** /**
* Update all HUD elements * Update all HUD elements.
*/ */
private void updateHUD(){ private void updateHUD(){
gameObjectManager.getLevelLabel().setLevel(level.number); gameObjectManager.getLevelLabel().setLevel(level.number);
@ -149,26 +124,20 @@ public class GamePlayManager {
*/ */
public void updateGamePlay(){ public void updateGamePlay(){
updateHUD(); updateHUD();
if(!destroyAllBubbles && player.score>=level.neededOverallScore){ if(!destroyAllBubbles && player.score>=level.neededOverallScore){
nextLevel(); nextLevel();
} }
if(spawnBubbles && !movementFroze && gameView.timerExpired("SpawnBubble","GamePlayManager" )){
if(gameView.timerExpired("SpawnBubble","GamePlayManager" ) && spawnBubbles && !movementFroze){
addRandomBubble(); addRandomBubble();
gameView.setTimer("SpawnBubble","GamePlayManager",3000); gameView.setTimer("SpawnBubble","GamePlayManager",3000);
} }
if(movementFroze && gameView.timerExpired("MovementFroze","GamePlayManager")){ if(movementFroze && gameView.timerExpired("MovementFroze","GamePlayManager")){
movementFroze = false; movementFroze = false;
} }
if(destroyAllBubbles && gameView.timerExpired("DestroyAllBubbles","GamePlayManager")){ if(destroyAllBubbles && gameView.timerExpired("DestroyAllBubbles","GamePlayManager")){
List<Bubble> bubblesCopy = new ArrayList<>(gameObjectManager.getBubbles()); List<Bubble> bubblesCopy = new ArrayList<>(gameObjectManager.getBubbles());
if(bubblesCopy.size()>0) { if(bubblesCopy.size()>0) {
for (Bubble bubble : bubblesCopy) { bubblesCopy.forEach(this::destroy);
destroy(bubble);
}
gameView.setTimer("DestroyAllBubbles", "GamePlayManager", 300); gameView.setTimer("DestroyAllBubbles", "GamePlayManager", 300);
}else{ }else{
destroyAllBubbles = false; destroyAllBubbles = false;
@ -195,7 +164,7 @@ public class GamePlayManager {
movementFroze = true; movementFroze = true;
gameView.playSound("freeze.wav",false); gameView.playSound("freeze.wav",false);
gameView.setTimer("MovementFroze","GamePlayManager",freezeTime); gameView.setTimer("MovementFroze","GamePlayManager",freezeTime);
gameObjectManager.getGameOverlay().showMessage("Freeze "+ TimeUnit.MILLISECONDS.toSeconds(freezeTime)+" sec",freezeTime); gameObjectManager.getGameOverlay().showMessage("Freeze "+ (freezeTime/1000)+" sec",freezeTime);
} }
/** /**
@ -233,31 +202,11 @@ public class GamePlayManager {
} }
/** /**
* Add a random bubble with given values to the game. Percentages: * Spawn a random bubble into the game.
* - 60% normal bubble
* - 30% hexagonal bubble
* - 10% special bubble
*/ */
private void addRandomBubble(){ private void addRandomBubble(){
int randomNumber = specialBubblePresent ? random.nextInt(90) : random.nextInt(10000); boolean specialBubbleAdded = gameObjectManager.addRandomBubble(specialBubblePresent, gameView, this);
ArrayList<CollidableGameObject> collidableGameObjects = new ArrayList<>(); specialBubblePresent = specialBubblePresent || specialBubbleAdded;
collidableGameObjects.add(gameObjectManager.getPlayerObject());
collidableGameObjects.addAll(gameObjectManager.getHarpoons());
if(randomNumber<10){
RoundBubble roundBubble = new RoundBubble(gameView, collidableGameObjects);
roundBubble.setGamePlayManager(this);
gameObjectManager.getBubbles().add(roundBubble);
}else if(randomNumber<90){
HexagonalBubble hexagonalBubble = new HexagonalBubble(gameView, collidableGameObjects);
hexagonalBubble.setGamePlayManager(this);
gameObjectManager.getBubbles().add(hexagonalBubble);
}else{
SpecialBubble specialBubble = new SpecialBubble(gameView, collidableGameObjects);
specialBubble.setGamePlayManager(this);
gameObjectManager.getBubbles().add(specialBubble);
specialBubblePresent = true;
}
} }
/** /**
@ -265,27 +214,19 @@ public class GamePlayManager {
* *
* @param bubbles the bubbles * @param bubbles the bubbles
*/ */
public void addBubbles(Bubble... bubbles){ public void addBubbles(List<Bubble> bubbles){
ArrayList<CollidableGameObject> collidableGameObjects = new ArrayList<>(); gameObjectManager.addBubbles(bubbles, this);
collidableGameObjects.add(gameObjectManager.getPlayerObject());
collidableGameObjects.addAll(gameObjectManager.getHarpoons());
for(Bubble bubble: bubbles){
bubble.setGamePlayManager(this);
bubble.addCollidableGameObject(collidableGameObjects);
gameObjectManager.getBubbles().add(bubble);
}
} }
/** /**
* Shoot a harpoon starting at a given position. * Shoot a harpoon starting at a given position.
* *
* @param startPosition the start position * @param playerPosition the player position
* @return if a harpoon was shot or not * @return if a harpoon was shot or not
*/ */
public boolean shootHarpoon(Position startPosition){ public boolean shootHarpoon(Position playerPosition){
if(gameView.timerExpired("ShootHarpoon","GamePlayManager") && gameObjectManager.getHarpoons().size()<2){ if(gameView.timerExpired("ShootHarpoon","GamePlayManager") && gameObjectManager.getHarpoons().size()<2){
Harpoon harpoon = new Harpoon(gameView,new ArrayList<>()); Harpoon harpoon = new Harpoon(gameView,new ArrayList<>(), new Position(playerPosition.x+6, playerPosition.y-15));
harpoon.getPosition().setTo(startPosition.x+6, startPosition.y-15);
harpoon.setGamePlayManager(this); harpoon.setGamePlayManager(this);
gameObjectManager.getHarpoons().add(harpoon); gameObjectManager.getHarpoons().add(harpoon);
gameObjectManager.getBubbles().forEach(b -> b.addCollidableGameObject(Collections.singletonList(harpoon))); gameObjectManager.getBubbles().forEach(b -> b.addCollidableGameObject(Collections.singletonList(harpoon)));
@ -294,4 +235,4 @@ public class GamePlayManager {
} }
return false; return false;
} }
} }

View File

@ -15,8 +15,6 @@ class InputManager {
private final GameView gameView; private final GameView gameView;
/** The player object */ /** The player object */
private final PlayerObject playerObject; private final PlayerObject playerObject;
/** Flag, if diagonal movement is allowed */
private static final boolean DIAGONAL_MOVEMENT_ALLOWED = false;
/** /**
* Create a manager handling the user input. * Create a manager handling the user input.
@ -48,12 +46,6 @@ class InputManager {
default: default:
continue; continue;
} }
if(!DIAGONAL_MOVEMENT_ALLOWED){
return;
}
} }
} }
} }

View File

@ -2,7 +2,6 @@ package de.thdeg.greiner.superpangworld.game.managers;
import de.thdeg.greiner.superpangworld.graphics.helper.Level; import de.thdeg.greiner.superpangworld.graphics.helper.Level;
import java.sql.Array;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -13,22 +12,22 @@ import java.util.Queue;
*/ */
public class LevelManager { public class LevelManager {
/** The amount of background images */
private static final int BACKGROUND_IMAGE_COUNT = 9; private static final int BACKGROUND_IMAGE_COUNT = 9;
/** The queue to store the generated levels */ /** The queue to store the generated levels */
private final Queue<Level> levels; private final Queue<Level> levels;
/** The list with all the background image names */
private List<String> backgroundImages; private final List<String> backgroundImages;
/** /**
* Create a level manager. * Create a level manager.
* *
* @param easyDifficulty the difficulty * @param difficultyIsSetToEasy flag if easy difficulty is set
*/ */
public LevelManager(boolean easyDifficulty){ public LevelManager(boolean difficultyIsSetToEasy){
levels = new ArrayDeque<>(); levels = new ArrayDeque<>();
backgroundImages = loadBackgroundImages(); backgroundImages = loadBackgroundImages();
generateLevels(easyDifficulty); generateLevels(difficultyIsSetToEasy);
} }
/** /**
@ -48,7 +47,7 @@ public class LevelManager {
/** /**
* Generate the levels according to the difficulty. * Generate the levels according to the difficulty.
* *
* @param easyDifficulty the difficulty * @param easyDifficulty flag if easy difficulty is set
*/ */
private void generateLevels(boolean easyDifficulty){ private void generateLevels(boolean easyDifficulty){
int overallScoreNeeded = 0; int overallScoreNeeded = 0;
@ -66,6 +65,11 @@ public class LevelManager {
} }
} }
/**
* Create the background image name list.
*
* @return the list with the background image names
*/
private List<String> loadBackgroundImages(){ private List<String> loadBackgroundImages(){
List<String> images = new ArrayList<>(); List<String> images = new ArrayList<>();
for(int i=1;i<=BACKGROUND_IMAGE_COUNT;i++){ for(int i=1;i<=BACKGROUND_IMAGE_COUNT;i++){

View File

@ -14,10 +14,6 @@ import java.util.*;
*/ */
public abstract class Bubble extends CollidingGameObject implements MovingGameObject{ public abstract class Bubble extends CollidingGameObject implements MovingGameObject{
/** The velocity of a normal right movement */
public static final Point2D VELOCITY_RIGHT = new Point2D.Double(3,1);
/** The velocity of a normal left movement */
public static final Point2D VELOCITY_LEFT = new Point2D.Double(-3,1);
/** The random generator */ /** The random generator */
protected final Random random; protected final Random random;
/** Flag, if the bubble is in the spawning phase */ /** Flag, if the bubble is in the spawning phase */
@ -35,7 +31,7 @@ public abstract class Bubble extends CollidingGameObject implements MovingGameOb
* @param gameView the {@link GameView} to display the bubble * @param gameView the {@link GameView} to display the bubble
* @param objectsToCollideWith the list of {@link CollidableGameObject} the bubble can collide with * @param objectsToCollideWith the list of {@link CollidableGameObject} the bubble can collide with
*/ */
public Bubble(GameView gameView, ArrayList<CollidableGameObject> objectsToCollideWith){ public Bubble(GameView gameView, List<CollidableGameObject> objectsToCollideWith){
super(gameView,objectsToCollideWith); super(gameView,objectsToCollideWith);
random = new Random(); random = new Random();
rotation = 90; rotation = 90;
@ -45,13 +41,17 @@ public abstract class Bubble extends CollidingGameObject implements MovingGameOb
speedInPixel = 1; speedInPixel = 1;
spawnID = UUID.randomUUID().getLeastSignificantBits(); spawnID = UUID.randomUUID().getLeastSignificantBits();
position.setTo(HelperValues.FRAME_BORDER_WIDTH + random.nextInt((int)(GameView.WIDTH-width - (2*HelperValues.FRAME_BORDER_WIDTH))), -width); position.x = 2*HelperValues.FRAME_BORDER_WIDTH + random.nextInt((int)(GameView.WIDTH-width - (2*HelperValues.FRAME_BORDER_WIDTH))-(int)(2*HelperValues.FRAME_BORDER_WIDTH));
position.y = -width;
spawning = true; spawning = true;
spawnSpeed = 500; spawnSpeed = 500;
gameView.setTimer("spawn"+spawnID,"bubble"+spawnID,spawnSpeed); gameView.setTimer("spawn"+spawnID,"bubble"+spawnID,spawnSpeed);
velocity = random.nextBoolean() ? VELOCITY_LEFT : VELOCITY_RIGHT; if(random.nextBoolean()){
velocity = new Point2D.Double(1 + random.nextInt(501)/100.0, 1 + random.nextInt(10));
}else{
velocity = new Point2D.Double((1 + random.nextInt(501)/100.0) * -1.0, 1+ random.nextInt(10));
}
} }
/** /**
@ -60,18 +60,16 @@ public abstract class Bubble extends CollidingGameObject implements MovingGameOb
* @param gameView the {@link GameView} to display the bubble * @param gameView the {@link GameView} to display the bubble
* @param objectsToCollideWith the list of {@link CollidableGameObject} the bubble can collide with * @param objectsToCollideWith the list of {@link CollidableGameObject} the bubble can collide with
* @param size the object size * @param size the object size
* @param speedInPixel the speed in pixel per tick
* @param position the position * @param position the position
* @param spawning flag, if the bubble is in the spawning phase * @param spawning flag, if the bubble is in the spawning phase
* @param velocity the initial velocity of the bubble * @param velocity the initial velocity of the bubble
*/ */
public Bubble(GameView gameView, ArrayList<CollidableGameObject> objectsToCollideWith, double size, double speedInPixel, Position position, boolean spawning, Point2D velocity){ public Bubble(GameView gameView, List<CollidableGameObject> objectsToCollideWith, double size, Position position, boolean spawning, Point2D velocity){
super(gameView,objectsToCollideWith); super(gameView,objectsToCollideWith);
random = new Random(); random = new Random();
rotation = 90; rotation = 90;
this.size = size; this.size = size;
this.speedInPixel = speedInPixel; setPosition(position.x, position.y);
this.position.setTo(position.x,position.y);
this.spawning = spawning; this.spawning = spawning;
this.velocity = velocity; this.velocity = velocity;
spawnID = UUID.randomUUID().getLeastSignificantBits(); spawnID = UUID.randomUUID().getLeastSignificantBits();
@ -87,9 +85,6 @@ public abstract class Bubble extends CollidingGameObject implements MovingGameOb
} }
/**
* Moves the bubble a tick further.
*/
@Override @Override
public void updatePosition(){ public void updatePosition(){
if(spawning){ if(spawning){
@ -100,19 +95,19 @@ public abstract class Bubble extends CollidingGameObject implements MovingGameOb
gameView.setTimer("spawn"+spawnID,"bubble"+spawnID,spawnSpeed); gameView.setTimer("spawn"+spawnID,"bubble"+spawnID,spawnSpeed);
} }
}else{ }else{
Point2D newLocation = new Point2D.Double(position.x,position.y); Point2D newLocation = new Point2D.Double(position.x,position.y);
double speedFactor = 0.2; double speedFactor = 0.2;
Point2D bubbleGravity = new Point2D.Double(0,0.1);
newLocation = new Point2D.Double(newLocation.getX() + (velocity.getX() * speedFactor), newLocation.getY() + (velocity.getY() * speedFactor)); newLocation = new Point2D.Double(newLocation.getX() + (velocity.getX() * speedFactor), newLocation.getY() + (velocity.getY() * speedFactor));
velocity = new Point2D.Double(velocity.getX() + HelperValues.BUBBLE_GRAVITY.getX(), velocity.getY() + HelperValues.BUBBLE_GRAVITY.getY()); velocity = new Point2D.Double(velocity.getX() + bubbleGravity.getX(), velocity.getY() + bubbleGravity.getY());
// Wall bounce // Wall bounce
if((newLocation.getX() >= GameView.WIDTH - width - HelperValues.FRAME_BORDER_WIDTH) || newLocation.getX() <= HelperValues.FRAME_BORDER_WIDTH){ if((newLocation.getX() >= GameView.WIDTH - width - HelperValues.FRAME_BORDER_WIDTH) || newLocation.getX() <= HelperValues.FRAME_BORDER_WIDTH){
velocity = new Point2D.Double(velocity.getX() * -1.0, velocity.getY()); velocity = new Point2D.Double(velocity.getX() * -1.0, velocity.getY());
} }
// Floor bounce // Floor/roof bounce
if(newLocation.getY() >= HelperValues.FRAME_WINDOW_HEIGHT + HelperValues.FRAME_BORDER_WIDTH - width){ if(newLocation.getY() >= HelperValues.FRAME_WINDOW_HEIGHT + HelperValues.FRAME_BORDER_WIDTH - width){
velocity = new Point2D.Double(velocity.getX(), velocity.getY() * -0.95); velocity = new Point2D.Double(velocity.getX(), velocity.getY() * -0.95);
newLocation = new Point2D.Double(newLocation.getX(), HelperValues.FRAME_WINDOW_HEIGHT + HelperValues.FRAME_BORDER_WIDTH - width); newLocation = new Point2D.Double(newLocation.getX(), HelperValues.FRAME_WINDOW_HEIGHT + HelperValues.FRAME_BORDER_WIDTH - width);
@ -121,9 +116,12 @@ public abstract class Bubble extends CollidingGameObject implements MovingGameOb
specialBubble.freezeState = !specialBubble.freezeState; specialBubble.freezeState = !specialBubble.freezeState;
gameView.playSound("specialBounce.wav",false); gameView.playSound("specialBounce.wav",false);
} }
}else if(newLocation.getY() <= HelperValues.FRAME_BORDER_WIDTH){
velocity = new Point2D.Double(velocity.getX(), velocity.getY() * -0.95);
newLocation = new Point2D.Double(newLocation.getX(), HelperValues.FRAME_BORDER_WIDTH);
} }
position.setTo(newLocation.getX(), newLocation.getY()); setPosition(newLocation.getX(),newLocation.getY());
} }
} }
@ -146,9 +144,9 @@ public abstract class Bubble extends CollidingGameObject implements MovingGameOb
@Override @Override
public void reactToCollision(CollidableGameObject otherObject) { public void reactToCollision(CollidableGameObject otherObject) {
if (otherObject instanceof PlayerObject && !gamePlayManager.movementFroze) { if (otherObject instanceof PlayerObject && !gamePlayManager.movementFroze) {
//gamePlayManager.looseLife(); gamePlayManager.looseLife();
} else if (otherObject instanceof Harpoon && !spawning) { } else if (otherObject instanceof Harpoon && !spawning) {
gamePlayManager.destroy((Harpoon) otherObject, this); gamePlayManager.destroy((Harpoon) otherObject,this);
} }
} }

View File

@ -10,8 +10,14 @@ import java.util.Objects;
*/ */
public abstract class CollidableGameObject extends GameObject { public abstract class CollidableGameObject extends GameObject {
/** The hitbox of the game object */
protected Rectangle hitBox; protected Rectangle hitBox;
/**
* Create a collidable game object.
*
* @param gameView the game view
*/
protected CollidableGameObject(GameView gameView) { protected CollidableGameObject(GameView gameView) {
super(gameView); super(gameView);
this.hitBox = new Rectangle(-100_000, -100_000, 0, 0); this.hitBox = new Rectangle(-100_000, -100_000, 0, 0);

View File

@ -2,7 +2,6 @@ package de.thdeg.greiner.superpangworld.graphics.base;
import de.thdeg.greiner.superpangworld.gameview.GameView; import de.thdeg.greiner.superpangworld.gameview.GameView;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@ -10,9 +9,16 @@ import java.util.List;
*/ */
public abstract class CollidingGameObject extends CollidableGameObject { public abstract class CollidingGameObject extends CollidableGameObject {
protected final ArrayList<CollidableGameObject> objectsToCollideWith; /** The list of game objects that this object may collide with */
protected final List<CollidableGameObject> objectsToCollideWith;
protected CollidingGameObject(GameView gameView, ArrayList<CollidableGameObject> objectsToCollideWith) { /**
* Create a colliding game object.
*
* @param gameView the game view
* @param objectsToCollideWith the objects that this object can collide with
*/
protected CollidingGameObject(GameView gameView, List<CollidableGameObject> objectsToCollideWith) {
super(gameView); super(gameView);
this.objectsToCollideWith = objectsToCollideWith; this.objectsToCollideWith = objectsToCollideWith;
} }
@ -46,6 +52,11 @@ public abstract class CollidingGameObject extends CollidableGameObject {
return this.hitBox.intersects(other.hitBox); return this.hitBox.intersects(other.hitBox);
} }
/**
* Add collideable game objects to the list.
*
* @param objects the collideable game objects
*/
public void addCollidableGameObject(List<CollidableGameObject> objects){ public void addCollidableGameObject(List<CollidableGameObject> objects){
objectsToCollideWith.addAll(objects); objectsToCollideWith.addAll(objects);
} }

View File

@ -77,6 +77,17 @@ public abstract class GameObject implements Cloneable{
return position; return position;
} }
/**
* Set the position with x and y coordinates.
*
* @param x the new x coordinate
* @param y the new y coordinate
*/
public void setPosition(double x, double y){
position.x = x;
position.y = y;
}
/** /**
* Adapts the position of this game object, in case the whole game world is moved. * Adapts the position of this game object, in case the whole game world is moved.
* *

View File

@ -3,20 +3,20 @@ package de.thdeg.greiner.superpangworld.graphics.base;
import java.util.Objects; import java.util.Objects;
/** /**
* Die Position eines Objekts auf einem Fenster anhand zweidimensionaler Koordinaten. * The position of an object on the game window represented by 2 dimensional coordinates.
*/ */
public class Position implements Cloneable, Comparable<Position>{ public class Position implements Cloneable, Comparable<Position>{
/** Die x-Koordinate */ /** The x-coordinate */
public double x; public double x;
/** Die y-Koordinate */ /** The y-coordinate */
public double y; public double y;
/** /**
* Erzeugt eine Position mit den übergebenen Koordinaten. * Create a position.
* *
* @param x die x-Koordinate des Objekts * @param x the x-coordinate of the position
* @param y die y-Koordinate des Objekts * @param y the y-coordinate of the position
*/ */
public Position(double x, double y) { public Position(double x, double y) {
this.x = x; this.x = x;
@ -24,80 +24,41 @@ public class Position implements Cloneable, Comparable<Position>{
} }
/** /**
* Veränderung der Position um einen Pixel nach links. * Move the position to the left.
*/
public void left() {
x--;
}
/**
* Veränderung der Position nach links.
* *
* @param pixel die Anzahl der Pixel * @param pixel the amount of pixels to move
*/ */
public void left(double pixel){ public void left(double pixel){
x -= pixel; x -= pixel;
} }
/** /**
* Veränderung der Position um einen Pixel nach rechts. * Move the position to the right.
*/
public void right() {
x++;
}
/**
* Veränderung der Position nach rechts.
* *
* @param pixel die Anzahl der Pixel * @param pixel the amount of pixels to move
*/ */
public void right(double pixel){ public void right(double pixel){
x += pixel; x += pixel;
} }
/** /**
* Veränderung der Position um einen Pixel nach oben. * Move the position upwards.
*/
public void up() {
y--;
}
/**
* Veränderung der Position nach oben.
* *
* @param pixel die Anzahl der Pixel * @param pixel the amount of pixels to move
*/ */
public void up(double pixel){ public void up(double pixel){
y -= pixel; y -= pixel;
} }
/** /**
* Veränderung der Position um einen Pixel nach unten. * Move the position downwards.
*/
public void down() {
y++;
}
/**
* Veränderung der Position nach unten.
* *
* @param pixel die Anzahl der Pixel * @param pixel the amount of pixels to move
*/ */
public void down(double pixel){ public void down(double pixel){
y += pixel; y += pixel;
} }
/**
* Set the position to given x and y coordinates.
*
* @param x the x coordinate
* @param y the y coordinate
*/
public void setTo(double x, double y){
this.x = x;
this.y = y;
}
/** /**
* Calculates the distance to any other position. * Calculates the distance to any other position.
* *

View File

@ -0,0 +1,31 @@
package de.thdeg.greiner.superpangworld.graphics.helper;
import de.thdeg.greiner.superpangworld.gameview.GameView;
/**
* The class handling the end screen of the game.
*/
public class EndScreen {
/**
* The game view to display the end screen on
*/
private GameView gameView;
/**
* Create an end screen which can be displayed onto the game view.
*
* @param gameView the game view
*/
public EndScreen(GameView gameView){
this.gameView = gameView;
}
/**
* Show the game end screen.
*/
public void showEndScreen(String message){
gameView.showEndScreen(message);
}
}

View File

@ -11,7 +11,5 @@ public class HelperValues {
public static final double FRAME_BORDER_WIDTH = 8; public static final double FRAME_BORDER_WIDTH = 8;
/** The height of the main game window */ /** The height of the main game window */
public static final double FRAME_WINDOW_HEIGHT = 432; public static final double FRAME_WINDOW_HEIGHT = 432;
/** The games gravity */
public static Point2D BUBBLE_GRAVITY = new Point2D.Double(0,0.2);
} }

View File

@ -11,7 +11,7 @@ public class Level {
public int neededLevelScore; public int neededLevelScore;
/** The overall needed score to surpass this level */ /** The overall needed score to surpass this level */
public int neededOverallScore; public int neededOverallScore;
/** The background image name */
public String backgroundImage; public String backgroundImage;
/** /**
@ -20,6 +20,7 @@ public class Level {
* @param number the level number * @param number the level number
* @param neededLevelScore the needed score to surpass this level * @param neededLevelScore the needed score to surpass this level
* @param neededOverallScore the overall needed score to surpass this level * @param neededOverallScore the overall needed score to surpass this level
* @param backgroundImage the background image
*/ */
public Level(int number, int neededLevelScore, int neededOverallScore, String backgroundImage){ public Level(int number, int neededLevelScore, int neededOverallScore, String backgroundImage){
this.number = number; this.number = number;

View File

@ -0,0 +1,40 @@
package de.thdeg.greiner.superpangworld.graphics.helper;
import de.thdeg.greiner.superpangworld.gameview.GameView;
/**
* The class handling the start screen of the game.
*/
public class StartScreen {
/** The game view to display the start screen on */
private GameView gameView;
/** The flag, if the user chose the easy difficulty */
private boolean difficultySetToEasy;
/**
* Create a start screen which can be displayed onto the game view.
*
* @param gameView the game view
*/
public StartScreen(GameView gameView){
this.gameView = gameView;
}
/**
* Show the game start screen.
*/
public void showStartScreen(){
difficultySetToEasy = gameView.showSimpleStartScreen("Super Pang World","Start the game");
}
/**
* Check if the user chose the easy difficulty.
*
* @return <code>true</code> if the easy difficulty was chosen, else <code>false</code>
*/
public boolean isDifficultySetToEasy(){
return difficultySetToEasy;
}
}

View File

@ -17,7 +17,7 @@ public class Background extends GameObject {
*/ */
public Background(GameView gameView) { public Background(GameView gameView) {
super(gameView); super(gameView);
this.position.setTo(0,0); setPosition(0,0);
size = 1; size = 1;
rotation = 0; rotation = 0;
backgroundImage = "background_1.png"; backgroundImage = "background_1.png";

View File

@ -15,7 +15,7 @@ public class GameFrame extends GameObject {
*/ */
public GameFrame(GameView gameView) { public GameFrame(GameView gameView) {
super(gameView); super(gameView);
this.position.setTo(0,0); setPosition(0,0);
size = 1; size = 1;
rotation = 0; rotation = 0;
} }

View File

@ -24,7 +24,7 @@ public class LevelLabel extends GameObject {
width = 109; width = 109;
height = 8; height = 8;
level = 1; level = 1;
getPosition().setTo(GameView.WIDTH/2.0 - width,GameView.HEIGHT-height-60); setPosition(GameView.WIDTH/2.0 - width,GameView.HEIGHT-height-60);
} }
/** /**

View File

@ -24,7 +24,7 @@ public class LevelProgressBar extends GameObject {
width = 101; width = 101;
height = 8; height = 8;
levelProgress = 0; levelProgress = 0;
getPosition().setTo(GameView.WIDTH/2.0 - width,GameView.HEIGHT-(height*size)); setPosition(GameView.WIDTH/2.0 - width,GameView.HEIGHT-(height*size));
} }
/** /**

View File

@ -25,7 +25,7 @@ public class LivesLabel extends GameObject {
this.lifeCount = 0; this.lifeCount = 0;
position.setTo(10,GameView.HEIGHT - height - 5); setPosition(10,GameView.HEIGHT - height - 5);
} }
@Override @Override

View File

@ -9,7 +9,7 @@ import java.awt.*;
/** /**
* The game overlay for display text or color on the screen. * The game overlay for display text or color on the screen.
*/ */
public class GameOverlay extends GameObject { public class Overlay extends GameObject {
/** The message to display */ /** The message to display */
private String message; private String message;
@ -21,7 +21,7 @@ public class GameOverlay extends GameObject {
* *
* @param gameView the game view to display the elements on * @param gameView the game view to display the elements on
*/ */
public GameOverlay(GameView gameView){ public Overlay(GameView gameView){
super(gameView); super(gameView);
} }
@ -29,6 +29,7 @@ public class GameOverlay extends GameObject {
* Show a message on the screen. * Show a message on the screen.
* *
* @param message the message to display * @param message the message to display
* @param duration the display duration
*/ */
public void showMessage(String message, long duration){ public void showMessage(String message, long duration){
gameView.setTimer("DisplayMessage","Overlay",duration); gameView.setTimer("DisplayMessage","Overlay",duration);

View File

@ -25,7 +25,7 @@ public class ScoreLabel extends GameObject {
width = (int) size * 100; width = (int) size * 100;
height = (int) size * 8; height = (int) size * 8;
position.setTo(0,GameView.HEIGHT-height-60); setPosition(0,GameView.HEIGHT-height-60);
} }
@Override @Override

View File

@ -4,7 +4,6 @@ import de.thdeg.greiner.superpangworld.gameview.GameView;
import de.thdeg.greiner.superpangworld.graphics.base.*; import de.thdeg.greiner.superpangworld.graphics.base.*;
import de.thdeg.greiner.superpangworld.graphics.helper.HelperValues; import de.thdeg.greiner.superpangworld.graphics.helper.HelperValues;
import java.awt.*;
import java.util.ArrayList; import java.util.ArrayList;
/** /**
@ -19,9 +18,9 @@ public class Harpoon extends CollidingGameObject implements MovingGameObject {
" kkkkk \n"+ " kkkkk \n"+
"k kkk k\n"+ "k kkk k\n"+
"k kkk k\n"; "k kkk k\n";
/** The pixel string representing the harpoon rope */
private final String harpoonRope; private final String harpoonRope;
/** The identifier for the sound timer */
private int sound; private int sound;
/** /**
@ -29,15 +28,16 @@ public class Harpoon extends CollidingGameObject implements MovingGameObject {
* *
* @param gameView the {@link GameView} to display the bubble * @param gameView the {@link GameView} to display the bubble
* @param objectsToCollideWith the list of {@link CollidableGameObject} the harpoon can collide with * @param objectsToCollideWith the list of {@link CollidableGameObject} the harpoon can collide with
* @param position the position
*/ */
public Harpoon(GameView gameView, ArrayList<CollidableGameObject> objectsToCollideWith){ public Harpoon(GameView gameView, ArrayList<CollidableGameObject> objectsToCollideWith, Position position){
super(gameView, objectsToCollideWith); super(gameView, objectsToCollideWith);
this.position = position;
speedInPixel = 2; speedInPixel = 2;
size = 3; size = 3;
width = (int) (7 * size); width = (int) (7 * size);
height = (int) (5 * size); height = (int) (5 * size);
rotation = 0; rotation = 0;
getPosition().setTo(300,300);
this.hitBox.width = width - 2; this.hitBox.width = width - 2;
this.hitBox.height = (int) (440 - position.y); this.hitBox.height = (int) (440 - position.y);
sound = gameView.playSound("harpoon.wav",true); sound = gameView.playSound("harpoon.wav",true);
@ -45,15 +45,19 @@ public class Harpoon extends CollidingGameObject implements MovingGameObject {
harpoonRope = generateRope(); harpoonRope = generateRope();
} }
/**
* Generate the rope's pixel string.
*
* @return the pixel representation of the harpoon rope
*/
private String generateRope(){ private String generateRope(){
int pre = 3; int pre = 3;
int post = 3; int post = 3;
boolean right = true; boolean right = true;
String rope = ""; StringBuilder stringBuilder = new StringBuilder();
for(int i = 0; i< HelperValues.FRAME_WINDOW_HEIGHT; i++){ for(int i = 0; i< HelperValues.FRAME_WINDOW_HEIGHT; i++){
rope += " ".repeat(pre) + "k" + " ".repeat(post)+"\n"; stringBuilder.append(" ".repeat(pre) + "k" + " ".repeat(post)+"\n");
if(right){ if(right){
pre++; pre++;
post--; post--;
@ -65,7 +69,7 @@ public class Harpoon extends CollidingGameObject implements MovingGameObject {
right = !right; right = !right;
} }
} }
return rope; return stringBuilder.toString();
} }
@Override @Override
@ -76,9 +80,7 @@ public class Harpoon extends CollidingGameObject implements MovingGameObject {
} }
@Override @Override
public void reactToCollision(CollidableGameObject otherObject) { public void reactToCollision(CollidableGameObject otherObject) {}
}
/** /**
* Draws the harpoon onto the {@link GameView}. * Draws the harpoon onto the {@link GameView}.
@ -108,6 +110,9 @@ public class Harpoon extends CollidingGameObject implements MovingGameObject {
public void updateStatus() { public void updateStatus() {
} }
/**
* Stop the sound.
*/
public void stopSound(){ public void stopSound(){
gameView.stopSound(sound); gameView.stopSound(sound);
} }

View File

@ -5,9 +5,10 @@ import de.thdeg.greiner.superpangworld.graphics.base.Bubble;
import de.thdeg.greiner.superpangworld.graphics.base.CollidableGameObject; import de.thdeg.greiner.superpangworld.graphics.base.CollidableGameObject;
import de.thdeg.greiner.superpangworld.graphics.base.Position; import de.thdeg.greiner.superpangworld.graphics.base.Position;
import java.awt.*;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/** /**
* The rare hexagonal bubble. * The rare hexagonal bubble.
@ -20,7 +21,7 @@ public class HexagonalBubble extends Bubble {
* @param gameView the {@link GameView} to display the bubble * @param gameView the {@link GameView} to display the bubble
* @param objectsToCollideWith the list of {@link CollidableGameObject} the bubble can collide with * @param objectsToCollideWith the list of {@link CollidableGameObject} the bubble can collide with
*/ */
public HexagonalBubble(GameView gameView, ArrayList<CollidableGameObject> objectsToCollideWith) { public HexagonalBubble(GameView gameView, List<CollidableGameObject> objectsToCollideWith) {
super(gameView,objectsToCollideWith); super(gameView,objectsToCollideWith);
size=1; size=1;
@ -33,8 +34,18 @@ public class HexagonalBubble extends Bubble {
this.hitBox.height = (int)(width - (width*0.1) ); this.hitBox.height = (int)(width - (width*0.1) );
} }
public HexagonalBubble(GameView gameView, ArrayList<CollidableGameObject> objectsToCollideWith, double size, double speedInPixel, Position position, boolean spawning, Point2D velocity){ /**
super(gameView, objectsToCollideWith, size, speedInPixel, position, spawning, velocity); * Create a hexagonal bubble.
*
* @param gameView the game view
* @param objectsToCollideWith the objects this bubble may collide with
* @param size the size
* @param position the position
* @param spawning if the bubble is in the spawning state
* @param velocity the velocity of the bubble
*/
public HexagonalBubble(GameView gameView, List<CollidableGameObject> objectsToCollideWith, double size, Position position, boolean spawning, Point2D velocity){
super(gameView, objectsToCollideWith, size, position, spawning, velocity);
width = (int) (128 * size); width = (int) (128 * size);
height = (int) (128 * size); height = (int) (128 * size);
@ -89,10 +100,10 @@ public class HexagonalBubble extends Bubble {
Point2D.Double velocityLeft = new Point2D.Double(Math.min(this.velocity.getX(),this.velocity.getX() * -1.0),Math.min(this.velocity.getY(),this.velocity.getY() * -1.0)); Point2D.Double velocityLeft = new Point2D.Double(Math.min(this.velocity.getX(),this.velocity.getX() * -1.0),Math.min(this.velocity.getY(),this.velocity.getY() * -1.0));
Point2D.Double velocityRight = new Point2D.Double(Math.max(this.velocity.getX(),this.velocity.getX() * -1.0),Math.min(this.velocity.getY(),this.velocity.getY() * -1.0)); Point2D.Double velocityRight = new Point2D.Double(Math.max(this.velocity.getX(),this.velocity.getX() * -1.0),Math.min(this.velocity.getY(),this.velocity.getY() * -1.0));
Bubble bubbleLeft = new HexagonalBubble(gameView, new ArrayList<>(), size/2, speedInPixel, positionLeft, false, velocityLeft); Bubble bubbleLeft = new HexagonalBubble(gameView, new ArrayList<>(), size/2, positionLeft, false, velocityLeft);
Bubble bubbleRight = new HexagonalBubble(gameView, new ArrayList<>(), size/2, speedInPixel, positionRight, false, velocityRight); Bubble bubbleRight = new HexagonalBubble(gameView, new ArrayList<>(), size/2, positionRight, false, velocityRight);
gamePlayManager.addBubbles(bubbleLeft, bubbleRight); gamePlayManager.addBubbles(Arrays.asList(bubbleLeft, bubbleRight));
} }
} }
} }

View File

@ -3,7 +3,6 @@ package de.thdeg.greiner.superpangworld.graphics.moveable;
import de.thdeg.greiner.superpangworld.gameview.GameView; import de.thdeg.greiner.superpangworld.gameview.GameView;
import de.thdeg.greiner.superpangworld.graphics.base.CollidableGameObject; import de.thdeg.greiner.superpangworld.graphics.base.CollidableGameObject;
import java.awt.*;
import java.util.Objects; import java.util.Objects;
/** /**
@ -27,7 +26,7 @@ public class PlayerObject extends CollidableGameObject implements Cloneable {
*/ */
public PlayerObject(GameView gameView){ public PlayerObject(GameView gameView){
super(gameView); super(gameView);
position.setTo(GameView.WIDTH/2.0, 360); setPosition(GameView.WIDTH/2.0, 360);
shooting = false; shooting = false;
size = 2; size = 2;
width = (int) (26 * size); width = (int) (26 * size);

View File

@ -4,10 +4,12 @@ import de.thdeg.greiner.superpangworld.gameview.GameView;
import de.thdeg.greiner.superpangworld.graphics.base.Bubble; import de.thdeg.greiner.superpangworld.graphics.base.Bubble;
import de.thdeg.greiner.superpangworld.graphics.base.CollidableGameObject; import de.thdeg.greiner.superpangworld.graphics.base.CollidableGameObject;
import de.thdeg.greiner.superpangworld.graphics.base.Position; import de.thdeg.greiner.superpangworld.graphics.base.Position;
import de.thdeg.greiner.superpangworld.graphics.helper.HelperValues;
import java.awt.*;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/** /**
@ -56,7 +58,7 @@ public class RoundBubble extends Bubble {
* @param gameView the {@link GameView} to display the bubble * @param gameView the {@link GameView} to display the bubble
* @param objectsToCollideWith the list of {@link CollidableGameObject} the bubble can collide with * @param objectsToCollideWith the list of {@link CollidableGameObject} the bubble can collide with
*/ */
public RoundBubble(GameView gameView, ArrayList<CollidableGameObject> objectsToCollideWith) { public RoundBubble(GameView gameView, List<CollidableGameObject> objectsToCollideWith) {
super(gameView,objectsToCollideWith); super(gameView,objectsToCollideWith);
this.hitBox.width = width-20; this.hitBox.width = width-20;
this.hitBox.height = height-20; this.hitBox.height = height-20;
@ -69,13 +71,12 @@ public class RoundBubble extends Bubble {
* @param gameView the {@link GameView} to display the bubble * @param gameView the {@link GameView} to display the bubble
* @param objectsToCollideWith the list of {@link CollidableGameObject} the bubble can collide with * @param objectsToCollideWith the list of {@link CollidableGameObject} the bubble can collide with
* @param size the object size * @param size the object size
* @param speedInPixel the speed in Pixel per tick
* @param position the Position * @param position the Position
* @param spawning flag, if the bubble is spawning or not * @param spawning flag, if the bubble is spawning or not
* @param velocity the initial velocity of the bubble * @param velocity the initial velocity of the bubble
*/ */
public RoundBubble(GameView gameView, ArrayList<CollidableGameObject> objectsToCollideWith, double size, double speedInPixel, Position position, boolean spawning, Point2D velocity){ public RoundBubble(GameView gameView, ArrayList<CollidableGameObject> objectsToCollideWith, double size, Position position, boolean spawning, Point2D velocity){
super(gameView, objectsToCollideWith, size, speedInPixel, position, spawning, velocity); super(gameView, objectsToCollideWith, size, position, spawning, velocity);
this.hitBox.width = (int) (width*0.8); this.hitBox.width = (int) (width*0.8);
this.hitBox.height = (int) (height*0.8); this.hitBox.height = (int) (height*0.8);
redBubble = true; redBubble = true;
@ -90,16 +91,16 @@ public class RoundBubble extends Bubble {
public void destroy() { public void destroy() {
gameView.playSound("burst.wav",false); gameView.playSound("burst.wav",false);
if (size > 1.25) { if (size > 1.25) {
Position positionLeft = new Position(position.x - (width/2.0/2.0), position.y); Position positionLeft = new Position(Math.max(position.x - (width/2.0/2.0), HelperValues.FRAME_BORDER_WIDTH + 2), position.y);
Position positionRight = new Position(position.x + width - (width/2.0/2.0), position.y); Position positionRight = new Position(Math.min(position.x + width - (width/2.0/2.0), GameView.WIDTH - (2*HelperValues.FRAME_BORDER_WIDTH) -width - 2), position.y);
Point2D.Double velocityLeft = new Point2D.Double(Math.min(this.velocity.getX(),this.velocity.getX() * -1.0),Math.min(this.velocity.getY(),this.velocity.getY() * -1.0)); Point2D.Double velocityLeft = new Point2D.Double(Math.min(this.velocity.getX(),this.velocity.getX() * -1.0),Math.min(this.velocity.getY(),this.velocity.getY() * -1.0));
Point2D.Double velocityRight = new Point2D.Double(Math.max(this.velocity.getX(),this.velocity.getX() * -1.0),Math.min(this.velocity.getY(),this.velocity.getY() * -1.0)); Point2D.Double velocityRight = new Point2D.Double(Math.max(this.velocity.getX(),this.velocity.getX() * -1.0),Math.min(this.velocity.getY(),this.velocity.getY() * -1.0));
Bubble bubbleLeft = new RoundBubble(gameView, new ArrayList<>(), size/2, speedInPixel, positionLeft, false, velocityLeft); Bubble bubbleLeft = new RoundBubble(gameView, new ArrayList<>(), size/2, positionLeft, false, velocityLeft);
Bubble bubbleRight = new RoundBubble(gameView, new ArrayList<>(), size/2, speedInPixel, positionRight, false, velocityRight); Bubble bubbleRight = new RoundBubble(gameView, new ArrayList<>(), size/2, positionRight, false, velocityRight);
gamePlayManager.addBubbles(bubbleLeft, bubbleRight); gamePlayManager.addBubbles(Arrays.asList(bubbleLeft, bubbleRight));
}else if(timeFreeze){ }else if(timeFreeze){
gamePlayManager.freezeMovement(1000); gamePlayManager.freezeMovement(1000);
} }
@ -148,7 +149,5 @@ public class RoundBubble extends Bubble {
} }
@Override @Override
public void updateStatus() { public void updateStatus() {}
}
} }

View File

@ -5,8 +5,8 @@ import de.thdeg.greiner.superpangworld.graphics.base.Bubble;
import de.thdeg.greiner.superpangworld.graphics.base.CollidableGameObject; import de.thdeg.greiner.superpangworld.graphics.base.CollidableGameObject;
import de.thdeg.greiner.superpangworld.graphics.base.Position; import de.thdeg.greiner.superpangworld.graphics.base.Position;
import java.awt.*; import java.util.List;
import java.util.ArrayList;
/** /**
* The green bubble with special abilities. * The green bubble with special abilities.
@ -79,7 +79,7 @@ public class SpecialBubble extends Bubble {
* @param gameView the {@link GameView} to display the bubble * @param gameView the {@link GameView} to display the bubble
* @param objectsToCollideWith the list of {@link CollidableGameObject} the bubble can collide with * @param objectsToCollideWith the list of {@link CollidableGameObject} the bubble can collide with
*/ */
public SpecialBubble(GameView gameView, ArrayList<CollidableGameObject> objectsToCollideWith) { public SpecialBubble(GameView gameView, List<CollidableGameObject> objectsToCollideWith) {
super(gameView,objectsToCollideWith); super(gameView,objectsToCollideWith);
this.freezeState = true; this.freezeState = true;
this.hitBox.width = width-20; this.hitBox.width = width-20;