Aufgaben 12

This commit is contained in:
Andreas Greiner 2021-06-22 22:33:44 +02:00
parent 2f00876eec
commit fd910162a2
67 changed files with 221 additions and 445 deletions

View File

@ -16,7 +16,7 @@ public class GameLoopManager {
this.gameView = new GameView(); this.gameView = new GameView();
this.gameView.setWindowTitle("Super Pang World"); this.gameView.setWindowTitle("Super Pang World");
this.gameView.setStatusText("Andreas Greiner - Java Programmierung SS 2021"); this.gameView.setStatusText("Andreas Greiner - Java Programmierung SS 2021");
this.gameView.setWindowIcon("Target.png"); this.gameView.setWindowIcon("icon.png");
this.gameObjectManager = new GameObjectManager(gameView); this.gameObjectManager = new GameObjectManager(gameView);
this.inputManager = new InputManager(gameView, gameObjectManager.getPlayerObject()); this.inputManager = new InputManager(gameView, gameObjectManager.getPlayerObject());
this.gamePlayManager = new GamePlayManager(gameView, gameObjectManager); this.gamePlayManager = new GamePlayManager(gameView, gameObjectManager);
@ -26,7 +26,7 @@ public class GameLoopManager {
* Starts the main loop of the game. * Starts the main loop of the game.
*/ */
public void startGame() { public void startGame() {
while (true) { // The "Game-Loop" while (true) {
gamePlayManager.updateGamePlay(); gamePlayManager.updateGamePlay();
inputManager.updateUserInputs(); inputManager.updateUserInputs();
gameObjectManager.updateGameObjects(); gameObjectManager.updateGameObjects();

View File

@ -14,45 +14,38 @@ import java.util.LinkedList;
*/ */
class GameObjectManager { class GameObjectManager {
private GameView gameView; private final LinkedList<Bubble> bubbles;
private final LinkedList<Harpoon> harpoons;
private LinkedList<Bubble> bubbles; private final LevelProgressBar levelProgressBar;
private LinkedList<Harpoon> harpoons; private final LevelLabel levelLabel;
private final ScoreLabel scoreLabel;
private final LivesLabel livesLabel;
private final Background background;
private final GameFrame frame;
private LevelProgressBar levelProgressBar; private final PlayerObject playerObject;
private LevelLabel levelLabel;
private ScoreLabel scoreLabel;
private LivesLabel livesLabel;
private Background background;
private PlayerObject playerObject;
private RandomBall randomBall; private final LinkedList<GameObject> gameObjects;
private FollowerBall followerBall;
private LinkedList<GameObject> gameObjects;
/** /**
* Create a manager handling the display and passive movement of the game objects. * Create a manager handling the display and passive movement of the game objects.
* @param gameView the GameView * @param gameView the GameView
*/ */
public GameObjectManager(GameView gameView){ public GameObjectManager(GameView gameView){
this.gameView = gameView;
gameView.setColorForBlockImage('k', Color.LIGHT_GRAY); gameView.setColorForBlockImage('k', Color.LIGHT_GRAY);
bubbles = new LinkedList<>(); bubbles = new LinkedList<>();
harpoons = new LinkedList<>(); harpoons = new LinkedList<>();
gameObjects = new LinkedList<>(); gameObjects = new LinkedList<>();
this.levelProgressBar = new LevelProgressBar(gameView); levelProgressBar = new LevelProgressBar(gameView);
this.levelLabel = new LevelLabel(gameView); levelLabel = new LevelLabel(gameView);
this.scoreLabel = new ScoreLabel(gameView); scoreLabel = new ScoreLabel(gameView);
this.livesLabel = new LivesLabel(gameView); livesLabel = new LivesLabel(gameView);
this.background = new Background(gameView); background = new Background(gameView);
frame = new GameFrame(gameView);
this.playerObject = new PlayerObject(gameView); playerObject = new PlayerObject(gameView);
this.randomBall = new RandomBall(gameView);
this.followerBall = new FollowerBall(gameView, randomBall);
} }
/** /**
@ -61,15 +54,14 @@ class GameObjectManager {
public void updateGameObjects(){ public void updateGameObjects(){
gameObjects.clear(); gameObjects.clear();
gameObjects.add(background); gameObjects.add(background);
gameObjects.addAll(bubbles);
gameObjects.addAll(harpoons); gameObjects.addAll(harpoons);
gameObjects.add(frame);
gameObjects.add(levelProgressBar); gameObjects.add(levelProgressBar);
gameObjects.add(levelLabel); gameObjects.add(levelLabel);
gameObjects.add(scoreLabel); gameObjects.add(scoreLabel);
gameObjects.add(livesLabel); gameObjects.add(livesLabel);
gameObjects.add(playerObject); gameObjects.add(playerObject);
gameObjects.add(randomBall); gameObjects.addAll(bubbles);
//gameObjects.add(followerBall);
gameObjects.forEach(gameObject ->{ gameObjects.forEach(gameObject ->{
gameObject.update(); gameObject.update();
@ -133,20 +125,4 @@ class GameObjectManager {
return harpoons; return harpoons;
} }
/**
* Adapts the position of all game objects.
*
* @param adaptX Adaption to the right.
* @param adaptY Adaption downwards.
*/
public void moveWorld(double adaptX, double adaptY) {
for (GameObject gameObject : gameObjects) {
if (gameObject.getClass() != LevelLabel.class
&& gameObject.getClass() != LevelProgressBar.class
&& gameObject.getClass() != LivesLabel.class
&& gameObject.getClass() != ScoreLabel.class){
gameObject.adaptPosition(adaptX, adaptY);
}
}
}
} }

View File

@ -12,7 +12,7 @@ import de.thdeg.greiner.superpangworld.graphics.moveable.RoundBubble;
import de.thdeg.greiner.superpangworld.graphics.moveable.SpecialBubble; import de.thdeg.greiner.superpangworld.graphics.moveable.SpecialBubble;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Collections;
import java.util.Random; import java.util.Random;
/** /**
@ -21,30 +21,29 @@ import java.util.Random;
public class GamePlayManager { public class GamePlayManager {
/** The GameView on which the game is displayed */ /** The GameView on which the game is displayed */
private GameView gameView; private final GameView gameView;
/** The manager, which handles the game objects */ /** The manager, which handles the game objects */
private GameObjectManager gameObjectManager; private final GameObjectManager gameObjectManager;
/** Flag, if the game objects were already deleted once */
private boolean listHasBeenDeleted;
/** Generator for random values */ /** Generator for random values */
private Random random; private final Random random;
/** Das erste Level */ /** Das erste Level */
private Level level; private Level level;
/** Der Spieler */ /** Der Spieler */
private Player player; private final Player player;
/** /**
* Create the manager handling the gameplay. * Create the manager handling the gameplay.
* @param gameView *
* @param gameObjectManager * @param gameView the GameView for visualization
* @param gameObjectManager the manager handling the game objects
*/ */
public GamePlayManager(GameView gameView, GameObjectManager gameObjectManager) { public GamePlayManager(GameView gameView, GameObjectManager gameObjectManager) {
listHasBeenDeleted = false;
this.gameView = gameView; this.gameView = gameView;
this.gameObjectManager = gameObjectManager; this.gameObjectManager = gameObjectManager;
this.level = new Level(1,10000,10000); level = new Level(1,10000,10000);
player = new Player(this.level); player = new Player(this.level);
this.random = new Random(); random = new Random();
// Set HUD elements
gameObjectManager.getPlayerObject().setGamePlayManager(this); gameObjectManager.getPlayerObject().setGamePlayManager(this);
gameObjectManager.getLevelLabel().setLevel(level.number); gameObjectManager.getLevelLabel().setLevel(level.number);
gameObjectManager.getLivesLabel().setLifeCount(player.lives); gameObjectManager.getLivesLabel().setLifeCount(player.lives);
@ -56,39 +55,44 @@ public class GamePlayManager {
*/ */
public void updateGamePlay(){ public void updateGamePlay(){
if(gameView.timerExpired("SpawnBubble","GamePlayManager")){ if(gameView.timerExpired("SpawnBubble","GamePlayManager")){
RoundBubble roundBubble = new RoundBubble(gameView, new ArrayList<>(Arrays.asList(gameObjectManager.getPlayerObject()))); RoundBubble roundBubble = new RoundBubble(gameView, new ArrayList<>(Collections.singletonList(gameObjectManager.getPlayerObject())));
roundBubble.setGamePlayManager(this); roundBubble.setGamePlayManager(this);
gameObjectManager.getBubbles().add(roundBubble); gameObjectManager.getBubbles().add(roundBubble);
gameView.setTimer("SpawnBubble","GamePlayManager",3000); gameView.setTimer("SpawnBubble","GamePlayManager",3000);
} }
} }
/** /**
* Shoot a harpoon starting at a given position. * Shoot a harpoon starting at a given position.
*
* @param startPosition the start position * @param startPosition the start position
* @return if a harpoon was shot or not
*/ */
public void shootHarpoon(Position startPosition){ public boolean shootHarpoon(Position startPosition){
if(gameView.timerExpired("ShootHarpoon","GamePlayManager")){ if(gameView.timerExpired("ShootHarpoon","GamePlayManager") && gameObjectManager.getHarpoons().size()<2){
ArrayList<CollidableGameObject> collidableGameObjects = new ArrayList<>(); ArrayList<CollidableGameObject> collidableGameObjects = new ArrayList<>(gameObjectManager.getBubbles());
collidableGameObjects.addAll(gameObjectManager.getBubbles());
Harpoon harpoon = new Harpoon(gameView,collidableGameObjects); Harpoon harpoon = new Harpoon(gameView,collidableGameObjects);
harpoon.getPosition().setTo(startPosition.x, startPosition.y); harpoon.getPosition().setTo(startPosition.x+16, startPosition.y-15);
harpoon.setGamePlayManager(this); harpoon.setGamePlayManager(this);
gameObjectManager.getHarpoons().add(harpoon); gameObjectManager.getHarpoons().add(harpoon);
gameView.setTimer("ShootHarpoon","GamePlayManager",300); gameView.setTimer("ShootHarpoon","GamePlayManager",300);
return true;
} }
return false;
} }
/** /**
* Remove a harpoon from the game. * Remove a harpoon from the game.
*
* @param harpoon the harpoon to remove * @param harpoon the harpoon to remove
*/ */
public void destroy(Harpoon harpoon){ public void destroy(Harpoon harpoon){
gameObjectManager.getHarpoons().remove(harpoon); gameObjectManager.getHarpoons().remove(harpoon);
} }
/** /**
* Remove a bubble from the game. * Remove a bubble from the game.
*
* @param bubble the bubble to remove * @param bubble the bubble to remove
*/ */
public void destroy(Bubble bubble){ public void destroy(Bubble bubble){
@ -107,20 +111,24 @@ public class GamePlayManager {
} }
} }
/**
* Update all HUD elements
*/
private void updateHud(){ private void updateHud(){
gameObjectManager.getScoreLabel().setScore(player.score); gameObjectManager.getScoreLabel().setScore(player.score);
double progress = (player.score- level.neededOverallScore+ level.neededLevelScore * 1.0) / level.neededLevelScore; double progress = (player.score- level.neededOverallScore+ level.neededLevelScore * 1.0) / level.neededLevelScore;
System.out.println(progress);
gameObjectManager.getLevelProgressBar().setLevelProgress(Math.min((int)(progress*100),100)); gameObjectManager.getLevelProgressBar().setLevelProgress(Math.min((int)(progress*100),100));
gameObjectManager.getLevelLabel().setLevel(level.number); gameObjectManager.getLevelLabel().setLevel(level.number);
} }
/**
* Switch the current level.
*/
private void switchLevel(){ private void switchLevel(){
if(level.number==99){ if(level.number==99){
System.out.println("You won!"); System.out.println("You won!");
}else{ }else{
Level newLevel = new Level(level.number+1,10000,(level.number+1)*10000); level = new Level(level.number+1,10000,(level.number+1)*10000);
level = newLevel;
updateHud(); updateHud();
} }
} }
@ -130,6 +138,13 @@ public class GamePlayManager {
* - 60% normal bubble * - 60% normal bubble
* - 30% hexagonal bubble * - 30% hexagonal bubble
* - 10% special bubble * - 10% special bubble
*
* TODO: Integrate all different bubbles, not only the normal red bubble
*
* @param size the size of the bubble
* @param speedInPixel the speed of the bubble
* @param position the position of the bubble
* @param spawning the flag if the bubble gets created in spawning mode
*/ */
private void addRandomBubble(double size, double speedInPixel, Position position, boolean spawning){ private void addRandomBubble(double size, double speedInPixel, Position position, boolean spawning){
int randomNumber = random.nextInt(59); int randomNumber = random.nextInt(59);

View File

@ -12,14 +12,15 @@ import java.util.Arrays;
class InputManager { class InputManager {
/** The gameView, which displays the player object */ /** The gameView, which displays the player object */
private GameView gameView; private final GameView gameView;
/** The player object */ /** The player object */
private PlayerObject playerObject; private final PlayerObject playerObject;
/** Flag, if diagonal movement is allowed */ /** Flag, if diagonal movement is allowed */
private static final boolean DIAGONAL_MOVEMENT_ALLOWED = false; private static final boolean DIAGONAL_MOVEMENT_ALLOWED = false;
/** /**
* Create a manager handling the user input * Create a manager handling the user input.
*
* @param gameView the GameView * @param gameView the GameView
* @param playerObject the player object * @param playerObject the player object
*/ */
@ -29,14 +30,14 @@ class InputManager {
} }
/** /**
* Read the user inputs and perform actions accordingly * Read the user inputs and perform actions accordingly.
*/ */
public void updateUserInputs() { public void updateUserInputs() {
Integer[] gedruekteTasten = gameView.getKeyCodesOfCurrentlyPressedKeys(); Integer[] pressedButtons = gameView.getKeyCodesOfCurrentlyPressedKeys();
if(Arrays.stream(gedruekteTasten).anyMatch(k -> k == KeyEvent.VK_SPACE)){ if(Arrays.stream(pressedButtons).anyMatch(k -> k == KeyEvent.VK_SPACE)){
playerObject.shoot(); playerObject.shoot();
} }
for (int keyCode : gedruekteTasten) { for (int keyCode : pressedButtons) {
switch(keyCode) { switch(keyCode) {
case KeyEvent.VK_LEFT: case KeyEvent.VK_LEFT:
playerObject.left(); playerObject.left();

View File

@ -11,16 +11,14 @@ import java.util.*;
*/ */
public abstract class Bubble extends CollidingGameObject implements MovingGameObject{ public abstract class Bubble extends CollidingGameObject implements MovingGameObject{
/** Flag, if the bubble flies from left to right */
private boolean flyFromLeftToRight;
/** Random generator */ /** Random generator */
private Random random; private final Random random;
/** Flag, if the bubble is in the spawning phase */ /** Flag, if the bubble is in the spawning phase */
private boolean spawning; private boolean spawning;
/** Spawning speed */ /** Spawning speed */
private int spawnSpeed; private int spawnSpeed;
/** Unique id for the spawn event timer */ /** Unique id for the spawn event timer */
private long spawnID; private final long spawnID;
/** Temporary movement action */ /** Temporary movement action */
private Position nextPosition; private Position nextPosition;
@ -37,7 +35,6 @@ public abstract class Bubble extends CollidingGameObject implements MovingGameOb
width = (int) (12 * size); width = (int) (12 * size);
height = (int) (12 * size); height = (int) (12 * size);
speedInPixel = 1; speedInPixel = 1;
flyFromLeftToRight = true;
spawnID = UUID.randomUUID().getLeastSignificantBits(); spawnID = UUID.randomUUID().getLeastSignificantBits();
random = new Random(); random = new Random();
@ -51,6 +48,7 @@ public abstract class Bubble extends CollidingGameObject implements MovingGameOb
/** /**
* Create a bubble. * Create a 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
@ -65,7 +63,6 @@ public abstract class Bubble extends CollidingGameObject implements MovingGameOb
width = (int) (12 * size); width = (int) (12 * size);
height = (int) (12 * size); height = (int) (12 * size);
this.speedInPixel = speedInPixel; this.speedInPixel = speedInPixel;
flyFromLeftToRight = true;
this.position.setTo(position.x,position.y); this.position.setTo(position.x,position.y);
spawnID = UUID.randomUUID().getLeastSignificantBits(); spawnID = UUID.randomUUID().getLeastSignificantBits();
random = new Random(); random = new Random();
@ -87,7 +84,7 @@ public abstract class Bubble extends CollidingGameObject implements MovingGameOb
if(position.y >= 0){ if(position.y >= 0){
spawning = false; spawning = false;
} else if(gameView.timerExpired("spawn"+spawnID,"bubble"+spawnID)){ } else if(gameView.timerExpired("spawn"+spawnID,"bubble"+spawnID)){
position.down(width/4); position.down(width/4.0);
gameView.setTimer("spawn"+spawnID,"bubble"+spawnID,spawnSpeed); gameView.setTimer("spawn"+spawnID,"bubble"+spawnID,spawnSpeed);
} }
}else{ }else{
@ -122,7 +119,8 @@ public abstract class Bubble extends CollidingGameObject implements MovingGameOb
} }
/** /**
* Get the speed in pixel per tick * Get the speed in pixel per tick.
*
* @return the speed in pixel per tick * @return the speed in pixel per tick
*/ */
public double getSpeedInPixel(){ public double getSpeedInPixel(){

View File

@ -35,7 +35,7 @@ public abstract class CollidableGameObject extends GameObject {
} }
/** /**
* If a GameObject has collided with something, it is able to react to the collision * If a GameObject has collided with something, it is able to react to the collision.
* *
* @param otherObject The other GameObject that is involved in the collision. * @param otherObject The other GameObject that is involved in the collision.
*/ */

View File

@ -30,6 +30,7 @@ public abstract class GameObject implements Cloneable{
/** /**
* Create a game object with default values. * Create a game object with default values.
*
* @param gameView the gameView * @param gameView the gameView
*/ */
protected GameObject(GameView gameView){ protected GameObject(GameView gameView){
@ -59,6 +60,7 @@ public abstract class GameObject implements Cloneable{
/** /**
* Set the responsible GamePlayManager. * Set the responsible GamePlayManager.
*
* @param gamePlayManager the responsible GamePlayManager * @param gamePlayManager the responsible GamePlayManager
*/ */
public void setGamePlayManager(GamePlayManager gamePlayManager){ public void setGamePlayManager(GamePlayManager gamePlayManager){
@ -67,6 +69,7 @@ public abstract class GameObject implements Cloneable{
/** /**
* Get the position of the game object. * Get the position of the game object.
*
* @return the position * @return the position
*/ */
public Position getPosition(){ public Position getPosition(){

View File

@ -1,77 +0,0 @@
package de.thdeg.greiner.superpangworld.graphics.base;
import de.thdeg.greiner.superpangworld.gameview.GameView;
import de.thdeg.greiner.superpangworld.graphics.helper.XAxisComparator;
import java.util.*;
/**
* Offers different movement patterns for moveable game objects.
*/
public class MovementPatterns {
private HashMap<String, ArrayList<Position>> patterns;
private Random random;
/**
* Create the MovementPatterns object providing access to different movement patterns.
*/
public MovementPatterns(){
patterns = new HashMap<>();
random = new Random();
ArrayList<Position> square = new ArrayList<>((Arrays.asList(new Position(30,30),new Position(930,30),
new Position(930,510),new Position(30,510))));
ArrayList<Position> zigZag = new ArrayList<>((Arrays.asList( new Position(300,200),new Position(400,340),new Position(500,200),
new Position(600,340),new Position(700,200),new Position(800,340))));
ArrayList<Position> zero = new ArrayList<>();
zero.addAll(square);
zero.addAll(zigZag);
zero.sort(Comparator.naturalOrder());
ArrayList<Position> xFirst = new ArrayList<>(zero);
xFirst.sort(new XAxisComparator());
Comparator<Position> yAxisComparator = new Comparator<Position>() {
@Override
public int compare(Position o1, Position o2) {
return Double.compare(o1.y,o2.y);
}
};
ArrayList<Position> yFirst = new ArrayList<>(zero);
yFirst.sort(yAxisComparator);
ArrayList<Position> centered = new ArrayList<>(zero);
centered.sort((p1,p2)->{
Position pMid = new Position(GameView.WIDTH/2,GameView.HEIGHT/2);
return Double.compare(p1.distance(pMid),p2.distance(pMid));
});
patterns.put("square",square);
patterns.put("zigzag",zigZag);
patterns.put("zero",zero);
patterns.put("XFirst",xFirst);
patterns.put("YFirst",yFirst);
patterns.put("Centered",centered);
}
/**
* Get a movement pattern by its name.
* @param pattern the pattern name
* @return the movement pattern
*/
public ArrayList<Position> getPattern(String pattern){
return patterns.get(pattern);
}
/**
* get a random movement pattern.
* @return the movement pattern
*/
public ArrayList<Position> getRandomPattern(){
int index = random.nextInt(patterns.values().size());
return new ArrayList<ArrayList<Position>>(patterns.values()).get(index);
}
}

View File

@ -8,6 +8,6 @@ public interface MovingGameObject {
/** /**
* Update the position of a game object. * Update the position of a game object.
*/ */
public void updatePosition(); void updatePosition();
} }

View File

@ -23,13 +23,6 @@ public class Position implements Cloneable, Comparable<Position>{
this.y = y; this.y = y;
} }
/**
* Erzeugt eine Standardposition für die Koordinaten (0, 0).
*/
public Position(){
this(0,0);
}
/** /**
* Veränderung der Position um einen Pixel nach links. * Veränderung der Position um einen Pixel nach links.
*/ */
@ -39,6 +32,7 @@ public class Position implements Cloneable, Comparable<Position>{
/** /**
* Veränderung der Position nach links. * Veränderung der Position nach links.
*
* @param pixel die Anzahl der Pixel * @param pixel die Anzahl der Pixel
*/ */
public void left(double pixel){ public void left(double pixel){
@ -54,6 +48,7 @@ public class Position implements Cloneable, Comparable<Position>{
/** /**
* Veränderung der Position nach rechts. * Veränderung der Position nach rechts.
*
* @param pixel die Anzahl der Pixel * @param pixel die Anzahl der Pixel
*/ */
public void right(double pixel){ public void right(double pixel){
@ -69,6 +64,7 @@ public class Position implements Cloneable, Comparable<Position>{
/** /**
* Veränderung der Position nach oben. * Veränderung der Position nach oben.
*
* @param pixel die Anzahl der Pixel * @param pixel die Anzahl der Pixel
*/ */
public void up(double pixel){ public void up(double pixel){
@ -84,6 +80,7 @@ public class Position implements Cloneable, Comparable<Position>{
/** /**
* Veränderung der Position nach unten. * Veränderung der Position nach unten.
*
* @param pixel die Anzahl der Pixel * @param pixel die Anzahl der Pixel
*/ */
public void down(double pixel){ public void down(double pixel){
@ -92,6 +89,7 @@ public class Position implements Cloneable, Comparable<Position>{
/** /**
* Set the position to given x and y coordinates. * Set the position to given x and y coordinates.
*
* @param x the x coordinate * @param x the x coordinate
* @param y the y coordinate * @param y the y coordinate
*/ */

View File

@ -16,11 +16,13 @@ public class Player {
/** /**
* Create a player. * Create a player.
*
* @param level the level the player is on * @param level the level the player is on
*/ */
public Player(Level level){ public Player(Level level){
lives = MAX_LIVES; lives = MAX_LIVES;
score = 0; score = 0;
this.level = level;
} }
} }

View File

@ -1,17 +0,0 @@
package de.thdeg.greiner.superpangworld.graphics.helper;
import de.thdeg.greiner.superpangworld.graphics.base.Position;
import java.util.Comparator;
/**
* Compare two Positions regarding their x values
*/
public class XAxisComparator implements Comparator<Position> {
@Override
public int compare(Position o1, Position o2) {
return (int)Math.signum(o1.x-o2.x);
}
}

View File

@ -3,8 +3,6 @@ package de.thdeg.greiner.superpangworld.graphics.immovable;
import de.thdeg.greiner.superpangworld.gameview.GameView; import de.thdeg.greiner.superpangworld.gameview.GameView;
import de.thdeg.greiner.superpangworld.graphics.base.GameObject; import de.thdeg.greiner.superpangworld.graphics.base.GameObject;
import java.util.Random;
/** /**
* The background for the game. * The background for the game.
*/ */
@ -20,8 +18,6 @@ public class Background extends GameObject {
this.position.setTo(0,0); this.position.setTo(0,0);
size = 1; size = 1;
rotation = 0; rotation = 0;
} }
@Override @Override
@ -30,7 +26,5 @@ public class Background extends GameObject {
} }
@Override @Override
public void updateStatus() { public void updateStatus() { }
}
} }

View File

@ -0,0 +1,32 @@
package de.thdeg.greiner.superpangworld.graphics.immovable;
import de.thdeg.greiner.superpangworld.gameview.GameView;
import de.thdeg.greiner.superpangworld.graphics.base.GameObject;
/**
* The frame around the game.
*/
public class GameFrame extends GameObject {
/**
* Create a frame object.
*
* @param gameView the gameView
*/
public GameFrame(GameView gameView) {
super(gameView);
this.position.setTo(0,0);
size = 1;
rotation = 0;
}
@Override
public void addToCanvas() {
gameView.addImageToCanvas("frame.png",position.x,position.y,size,rotation);
}
@Override
public void updateStatus() {
}
}

View File

@ -15,6 +15,7 @@ public class LevelLabel extends GameObject {
/** /**
* Create a label for the level with default values. * Create a label for the level with default values.
*
* @param gameView the {@link GameView} to display the level label * @param gameView the {@link GameView} to display the level label
*/ */
public LevelLabel(GameView gameView){ public LevelLabel(GameView gameView){
@ -23,7 +24,7 @@ public class LevelLabel extends GameObject {
width = 101; width = 101;
height = 8; height = 8;
level = 1; level = 1;
getPosition().setTo(GameView.WIDTH/2 - (width/2),GameView.HEIGHT-height-60); getPosition().setTo(GameView.WIDTH/2.0 - (width/2.0),GameView.HEIGHT-height-60);
} }
/** /**
@ -35,7 +36,8 @@ public class LevelLabel extends GameObject {
} }
/** /**
* Set the current level number * Set the current level number.
*
* @param level the level number * @param level the level number
*/ */
public void setLevel(int level) { public void setLevel(int level) {

View File

@ -15,6 +15,7 @@ public class LevelProgressBar extends GameObject {
/** /**
* Create a progress bar with default values. * Create a progress bar with default values.
*
* @param gameView the {@link GameView} to display the progress bar * @param gameView the {@link GameView} to display the progress bar
*/ */
public LevelProgressBar(GameView gameView){ public LevelProgressBar(GameView gameView){
@ -23,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 - (width/2),GameView.HEIGHT-(height*size)); getPosition().setTo(GameView.WIDTH/2.0 - (width/2.0),GameView.HEIGHT-(height*size));
} }
/** /**
@ -46,6 +47,7 @@ public class LevelProgressBar extends GameObject {
/** /**
* Set the progress of the level. * Set the progress of the level.
*
* @param levelProgress the progress * @param levelProgress the progress
*/ */
public void setLevelProgress(int levelProgress){ public void setLevelProgress(int levelProgress){
@ -53,7 +55,8 @@ public class LevelProgressBar extends GameObject {
} }
/** /**
* Create the middle part of the level progress bar * Create the middle part of the level progress bar.
*
* @param progress the progress to display * @param progress the progress to display
* @return the pixel art representing the middle part of the progress bar * @return the pixel art representing the middle part of the progress bar
*/ */

View File

@ -47,6 +47,7 @@ public class LivesLabel extends GameObject {
/** /**
* Set the current life count. * Set the current life count.
*
* @param lifeCount the lives * @param lifeCount the lives
*/ */
public void setLifeCount(int lifeCount) { public void setLifeCount(int lifeCount) {

View File

@ -15,6 +15,7 @@ public class ScoreLabel extends GameObject {
/** /**
* Create a label for the score with default values. * Create a label for the score with default values.
*
* @param gameView the {@link GameView} to display the score label * @param gameView the {@link GameView} to display the score label
*/ */
public ScoreLabel(GameView gameView) { public ScoreLabel(GameView gameView) {
@ -33,7 +34,8 @@ public class ScoreLabel extends GameObject {
} }
/** /**
* Set the game score * Set the game score.
*
* @param score the score * @param score the score
*/ */
public void setScore(int score) { public void setScore(int score) {

View File

@ -1,79 +0,0 @@
package de.thdeg.greiner.superpangworld.graphics.moveable;
import de.thdeg.greiner.superpangworld.gameview.GameView;
import de.thdeg.greiner.superpangworld.graphics.base.GameObject;
import de.thdeg.greiner.superpangworld.graphics.base.MovingGameObject;
import de.thdeg.greiner.superpangworld.graphics.base.Position;
import java.awt.*;
/** This ball follows another ball. */
public class FollowerBall extends GameObject implements MovingGameObject {
private enum Status {FOLLOW, CENTER, HIDE}
private final RandomBall followMe;
private Position targetPosition;
private Status status;
/**
* Creates the GameObject with the GameView to be displayed on.
*
* @param gameView Window to show the GameObject on.
* @param followMe The RandomBall to follow.
*/
public FollowerBall(GameView gameView, RandomBall followMe) {
super(gameView);
this.status = Status.CENTER;
this.followMe = followMe;
this.position = new Position(GameView.WIDTH, GameView.HEIGHT);
this.size = 50;
this.speedInPixel = 2;
}
@Override
public void updatePosition() {
if (gameView.timerExpired("Status", "FollowerBall")) {
gameView.setTimer("Status", "FollowerBall", 3000);
switch (status) {
case HIDE:
status = Status.CENTER;
break;
case CENTER:
status = Status.FOLLOW;
break;
case FOLLOW:
status = Status.HIDE;
break;
}
}
if (status == Status.FOLLOW) {
targetPosition = followMe.getPosition().clone();
targetPosition.y += 25;
} else if (status == Status.CENTER) {
targetPosition = new Position(GameView.WIDTH / 2d, GameView.HEIGHT / 2d);
}
if (status != Status.HIDE) {
double distance = position.distance(targetPosition);
if (distance >= speedInPixel) {
position.right((targetPosition.x - position.x) / distance * speedInPixel);
position.down((targetPosition.y - position.y) / distance * speedInPixel);
}
}
}
@Override
protected void updateStatus() {
}
@Override
public void addToCanvas() {
if (status == Status.HIDE) {
gameView.addOvalToCanvas(position.x, position.y, size, size, 2, true, Color.WHITE);
} else {
gameView.addOvalToCanvas(position.x, position.y, size, size, 2, true, Color.GREEN);
}
}
}

View File

@ -5,6 +5,7 @@ import de.thdeg.greiner.superpangworld.graphics.base.*;
import java.awt.*; import java.awt.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.UUID;
/** /**
* A harpoon which can be fired upwards by the player. * A harpoon which can be fired upwards by the player.
@ -17,9 +18,11 @@ 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";
private boolean stuckAtRoof;
private final long harpoonID;
/** /**
* Create a harpoon with default values * Create a harpoon with default values.
* *
* @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
@ -32,14 +35,17 @@ public class Harpoon extends CollidingGameObject implements MovingGameObject {
height = (int) (5 * size); height = (int) (5 * size);
rotation = 0; rotation = 0;
getPosition().setTo(300,300); getPosition().setTo(300,300);
this.hitBox.width = (int) (width); this.hitBox.width = width;
this.hitBox.height = (int) (height); this.hitBox.height = (int) (440 - position.y);
stuckAtRoof = false;
harpoonID = UUID.randomUUID().getLeastSignificantBits();
} }
@Override @Override
protected void updateHitBoxPosition() { protected void updateHitBoxPosition() {
hitBox.x = (int) (position.x); hitBox.x = (int) (position.x);
hitBox.y = (int) (position.y); hitBox.y = (int) (position.y);
hitBox.height = (int) (440 - position.y);
} }
@Override @Override
@ -56,6 +62,7 @@ public class Harpoon extends CollidingGameObject implements MovingGameObject {
@Override @Override
public void addToCanvas(){ public void addToCanvas(){
gameView.addBlockImageToCanvas(HARPOON, getPosition().x, getPosition().y,size, rotation); gameView.addBlockImageToCanvas(HARPOON, getPosition().x, getPosition().y,size, rotation);
gameView.addRectangleToCanvas(position.x + (width/2.0) - 2,position.y + height, 4,440 - position.y,1,true,Color.lightGray);
} }
/** /**
@ -63,7 +70,12 @@ public class Harpoon extends CollidingGameObject implements MovingGameObject {
*/ */
@Override @Override
public void updatePosition(){ public void updatePosition(){
getPosition().up(speedInPixel); if(position.y > 8){
getPosition().up(Math.min(speedInPixel, position.y-8));
}else if(!stuckAtRoof){
stuckAtRoof = true;
gameView.setTimer("stuckAtRoof"+harpoonID,"harpoon"+harpoonID,1000);
}
} }
/** /**
@ -71,7 +83,7 @@ public class Harpoon extends CollidingGameObject implements MovingGameObject {
*/ */
@Override @Override
public void updateStatus() { public void updateStatus() {
if(position.y <=0 ){ if(stuckAtRoof && gameView.timerExpired("stuckAtRoof"+harpoonID,"harpoon"+harpoonID)){
gamePlayManager.destroy(this); gamePlayManager.destroy(this);
} }
} }

View File

@ -4,9 +4,7 @@ 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 java.awt.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Random;
/** /**
* The rare hexagonal bubble. * The rare hexagonal bubble.
@ -28,8 +26,8 @@ public class HexagonalBubble extends Bubble {
width = (int) (128 * size); width = (int) (128 * size);
height = (int) (128 * size); height = (int) (128 * size);
this.hitBox.width = (int)(width-20); this.hitBox.width = width-20;
this.hitBox.height = (int)(height-20); this.hitBox.height = height-20;
} }
@Override @Override

View File

@ -9,53 +9,43 @@ import java.util.Objects;
/** /**
* The game character controlled by the player. * The game character controlled by the player.
*/ */
public class PlayerObject extends CollidableGameObject { public class PlayerObject extends CollidableGameObject implements Cloneable {
/** Flag, if the player is shooting */ /** Flag, if the player is shooting */
private boolean shooting; private boolean shooting;
/** Debug flag, to display X and O or the real image */
private static final boolean SHOW_X = false; private boolean movingRight;
/** The pixel art of the character */ private boolean movingLeft;
private static final String SPIELFIGUR =
" kkk \n"+ private boolean movingStanding;
" BBBBk \n"+
" BBBBBB \n"+
" BBBBBBBB \n"+
" BBBBBBB \n"+
" BBBBBBB \n"+
"kBBBBBBB \n"+
"kkBBBBBB \n"+
"kkBBBBBBkkk\n"+
"kkBBBBBkkkk\n"+
" BBBBBBkk \n"+
" BBBBBBBk \n"+
" kBBBBBBk \n"+
" BBBBBkb \n"+
" bbbk kbb \n"+
" BBBb kBBb\n"+
" BBBk kkkB";
/** /**
* Create the game character with default values * Create the game character with default values.
*
* @param gameView the {@link GameView} to display the character * @param gameView the {@link GameView} to display the character
*/ */
public PlayerObject(GameView gameView){ public PlayerObject(GameView gameView){
super(gameView); super(gameView);
position.setTo(GameView.WIDTH/2, GameView.HEIGHT/1.5); position.setTo(GameView.WIDTH/2.0, 360);
shooting = false; shooting = false;
size = 3; size = 2;
width = (int) size * 11; width = (int) (26 * size);
height = (int) size * 17; height = (int) (41 * size);
speedInPixel = 5; speedInPixel = 2;
this.hitBox.width = (int) (width - (2*size)); this.hitBox.width = width;
this.hitBox.height = (int) (height - (1*size)); this.hitBox.height = height;
movingRight = false;
movingLeft = false;
movingStanding = true;
} }
@Override @Override
protected void updateHitBoxPosition() { protected void updateHitBoxPosition() {
hitBox.x = (int) (position.x + (1*size)); hitBox.x = (int) (position.x );
hitBox.y = (int) (position.y + (1*size)); hitBox.y = (int) (position.y);
} }
@Override @Override
@ -65,39 +55,66 @@ public class PlayerObject extends CollidableGameObject {
@Override @Override
public void addToCanvas(){ public void addToCanvas(){
if(SHOW_X) { if(!gameView.timerExpired("shootHarpoon","PlayerObject")){
gameView.addTextToCanvas(shooting ? "O" : "X", position.x, position.y, 50, Color.RED, rotation); gameView.addImageToCanvas("behind.png",position.x,position.y,2,0);
}else{ return;
gameView.addBlockImageToCanvas(SPIELFIGUR, position.x, position.y, size, rotation);
} }
shooting = false;
if(gameView.timerExpired("movingStanding","PlayerObject")){
movingStanding = !movingStanding;
gameView.setTimer("movingStanding","PlayerObject",100);
}
if(movingLeft && !movingRight){
if(movingStanding){
gameView.addImageToCanvas("left_standing.png",position.x,position.y,2,0);
}else{
gameView.addImageToCanvas("left_walking.png",position.x,position.y,2,0);
}
}else if(movingRight && !movingLeft){
if(movingStanding){
gameView.addImageToCanvas("right_standing.png",position.x,position.y,2,0);
}else{
gameView.addImageToCanvas("right_walking.png",position.x,position.y,2,0);
}
}else{
gameView.addImageToCanvas("behind.png",position.x,position.y,2,0);
movingStanding = true;
}
movingLeft = false;
movingRight = false;
} }
@Override @Override
public void updateStatus() { public void updateStatus() {
} }
/** Moves the character to the left */ /**
* Moves the character to the left
*/
public void left(){ public void left(){
position.left(speedInPixel);
if(gameView.timerExpired("shootHarpoon","PlayerObject") && position.x>8) {
position.left(Math.min(speedInPixel, position.x-8));
movingLeft = true;
}
} }
/** Moves the character to the right */ /**
* Moves the character to the right
*/
public void right(){ public void right(){
position.right(speedInPixel); if(gameView.timerExpired("shootHarpoon","PlayerObject") && position.x < GameView.WIDTH - width - 8){
position.right(Math.min(speedInPixel, (GameView.WIDTH-position.x)));
movingRight = true;
}
} }
/** Moves the character upwards */ /**
public void up(){ * Lets the character shoot
position.up(speedInPixel); */
}
/** Moves the character downwards */
public void down(){
position.down(speedInPixel);
}
/** Lets the character shoot */
public void shoot(){ public void shoot(){
shooting = true; if(gamePlayManager.shootHarpoon(this.position)){
gamePlayManager.shootHarpoon(this.position); shooting = true;
gameView.setTimer("shootHarpoon","PlayerObject", 100);
}
} }
@Override @Override
@ -118,4 +135,5 @@ public class PlayerObject extends CollidableGameObject {
public int hashCode() { public int hashCode() {
return Objects.hash(super.hashCode(), shooting); return Objects.hash(super.hashCode(), shooting);
} }
} }

View File

@ -1,74 +0,0 @@
package de.thdeg.greiner.superpangworld.graphics.moveable;
import de.thdeg.greiner.superpangworld.gameview.GameView;
import de.thdeg.greiner.superpangworld.graphics.base.GameObject;
import de.thdeg.greiner.superpangworld.graphics.base.MovementPatterns;
import de.thdeg.greiner.superpangworld.graphics.base.MovingGameObject;
import de.thdeg.greiner.superpangworld.graphics.base.Position;
import java.awt.*;
import java.util.*;
import java.util.List;
/** Ball with random movement. */
public class RandomBall extends GameObject implements MovingGameObject {
private final Random random;
private ArrayList<Position> movementPattern;
private int movementPatternIndex;
private Position targetPosition;
private MovementPatterns movementPatterns;
/**
* Creates the GameObject with the GameView to be displayed on.
*
* @param gameView Window to show the GameObject on.
*/
public RandomBall(GameView gameView) {
super(gameView);
this.random = new Random();
this.size = 50;
this.speedInPixel = 4;
movementPatterns = new MovementPatterns();
movementPattern = movementPatterns.getPattern("Centered");
movementPatternIndex = 0;
targetPosition = movementPattern.get(0);
}
@Override
public void updatePosition() {
double distance = position.distance(targetPosition);
if (distance >= speedInPixel) {
position.right((targetPosition.x - position.x) / distance * speedInPixel);
position.down((targetPosition.y - position.y) / distance * speedInPixel);
} else {
if(movementPatternIndex < movementPattern.size()-1){
movementPatternIndex++;
}else{
movementPattern = movementPatterns.getPattern("Centered");
movementPatternIndex = 0;
}
targetPosition = movementPattern.get(movementPatternIndex);
}
}
@Override
protected void updateStatus() {
}
/** Set position to aim at */
public void setRandomTargetPosition() {
targetPosition.x = random.nextInt(GameView.WIDTH);
targetPosition.y = random.nextInt(GameView.HEIGHT);
}
@Override
public void addToCanvas() {
gameView.addOvalToCanvas(position.x, position.y, size, size, 2, true, Color.YELLOW);
gameView.addOvalToCanvas(targetPosition.x, targetPosition.y, size, size, 2, false, Color.WHITE);
}
}

View File

@ -5,9 +5,7 @@ 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.ArrayList; import java.util.ArrayList;
import java.util.Random;
/** /**

View File

@ -4,9 +4,7 @@ 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 java.awt.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Random;
/** /**
* The green bubble with special abilities. * The green bubble with special abilities.
@ -27,8 +25,6 @@ public class SpecialBubble extends Bubble {
" GGGGGWWG \n"+ " GGGGGWWG \n"+
" GGGWWG \n"+ " GGGWWG \n"+
" GGGG \n"; " GGGG \n";
/** Flag if the time is stopped or all bubbles are popped when this bubble gets popped. */
private Status status;
/** /**
* Create a special bubble with default values. * Create a special bubble with default values.
@ -39,8 +35,6 @@ public class SpecialBubble extends Bubble {
public SpecialBubble(GameView gameView, ArrayList<CollidableGameObject> objectsToCollideWith) { public SpecialBubble(GameView gameView, ArrayList<CollidableGameObject> objectsToCollideWith) {
super(gameView,objectsToCollideWith); super(gameView,objectsToCollideWith);
status = Status.FREEZE;
this.hitBox.width = width-20; this.hitBox.width = width-20;
this.hitBox.height = height-20; this.hitBox.height = height-20;
} }
@ -57,29 +51,5 @@ public class SpecialBubble extends Bubble {
} }
@Override @Override
public void updateStatus() { public void updateStatus() {}
}
/**
* Switches the active effect.
*/
private void switchEffect(){
}
/**
* Activates the current effect.
*/
private void activateEffect(){
}
/**
* Enumeration to decide if when the bubble is popped the time is stopped or all bubbles are popped.
*/
private enum Status{
FREEZE,
POP
}
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 B