Browse Source

Aufgabe 09

master
Kai Simon 2 years ago
parent
commit
6ddf373bc9
  1. 2
      GameProject/src/base/BreakoutGame.java
  2. 28
      GameProject/src/controller/BreakoutController.java
  3. 21
      GameProject/src/controller/MineController.java
  4. 2
      GameProject/src/log4j2.xml
  5. 119
      GameProject/src/playground/BreakoutLevel0.java
  6. 152
      GameProject/src/playground/BreakoutLevel2.java
  7. 70
      GameProject/src/playground/BreakoutLevel3.java
  8. 98
      GameProject/src/playground/BreakoutLevelBaseAdvanced.java

2
GameProject/src/base/BreakoutGame.java

@ -19,7 +19,7 @@ public class BreakoutGame extends GameLoop {
@Override
public void defineLevels() {
this.resetLevels(); // removes Level1 added by superclass constructor
this.addLevel(new BreakoutLevel1()); // FIXME add this as soon as your level exists
this.addLevel(new BreakoutLevel3()); // FIXME add this as soon as your level exists
}
/**

28
GameProject/src/controller/BreakoutController.java

@ -0,0 +1,28 @@
package controller;
import java.awt.event.KeyEvent;
import gameobjects.GameObject;
public class BreakoutController extends EgoController{
public BreakoutController(double width, double height) {
super(width, height);
}
@Override
public void onUp(KeyEvent kc, GameObject ego) {
}
@Override
public void onDown(KeyEvent kc, GameObject ego) {
}
@Override
public void onSpace(KeyEvent e, GameObject ego) {
}
}

21
GameProject/src/controller/MineController.java

@ -4,7 +4,14 @@ import gameobjects.GameObject;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
/**
* Stops GameObject movement at bottom of level and let it 'fly' in x-direction towards ego object.
* If the object flies outside of the level (by x-coordinate) it is removed.
*
* The behavior looks like a sinking sea mine, which stays at a certain depth and moves left/right to catch the player.
*
*
*/
public class MineController extends ObjectController {
int rad = 3;
@ -17,13 +24,19 @@ public class MineController extends ObjectController {
this.lineSpeed = lineSpeed;
}
/**
* Fetches ego object by name 'ego' from current level and determines it's x-position.
* The controlled GameObject will move towards this position (in x-direction only).
* y-direction speed is reduced to zero, if the objects reached lower bound of level (high y-values).
* Only deletes the object if it flies out of visible game area.
*/
@Override
public void updateObject() {
if (gameObject.getY() >= this.getPlayground().getSizeY() - 10) {
this.gameObject.setVY(0);
if (xSpeed == 0.) {
GameObject ego = getPlayground().getObject("ego");
GameObject ego = this.getPlayground().getObject("ego");
double egoXPos = ego.getX();
if (egoXPos > this.gameObject.getX()) {
xSpeed = 50;
@ -38,9 +51,9 @@ public class MineController extends ObjectController {
}
if (this.gameObject.getX() < 0 || (this.gameObject.getX() > this.getPlayground().getSizeX())) {
logger.debug("deleting" + this.gameObject.getId());
getPlayground().deleteObject(this.gameObject.getId());
this.getPlayground().deleteObject(this.gameObject.getId());
}
applySpeedVector();
this.applySpeedVector();
}
}

2
GameProject/src/log4j2.xml

@ -20,7 +20,7 @@
<appender-ref ref="File" />
</root>
<Logger name="base.BreakoutGame" level="info">
<Logger name="base.GameLoop" level="info">
</Logger>
<Logger name="playground" level="info">

119
GameProject/src/playground/BreakoutLevel0.java

@ -0,0 +1,119 @@
package playground;
import java.awt.Color;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import collider.RectCollider;
import controller.EgoController;
import controller.ReboundController2;
import gameobjects.FallingStar;
import gameobjects.GameObject;
import gameobjects.RectObject;
/**
* simple solution example for Breakout game.
*
* not implemented: penalty if balls hits ground, no score for removed bricks, no bonus items, no
* lives.
* </ul>
*
*/
public class BreakoutLevel0 extends BreakoutLevelBase {
private static Logger logger = LogManager.getLogger(BreakoutLevelBase.class);
protected GameObject createEgoObject() {
RectObject ro = new RectObject("ego", this, 350, 550, 0, 0, 80, 10, Color.BLUE);
ro.generateColliders();
EgoController ec = new EgoController(80,10);
ro.addController(ec);
logger.info("ego created.");
return ro;
}
protected GameObject createBall() {
GameObject co = new FallingStar("ball1", this, 350, 350, 100, 100, Color.RED, 5);
co.addController(new ReboundController2());
logger.info("ball created.");
return co;
}
/**
* creates one brick. For
* collision {@link RectCollider} is used.
*/
@Override
protected GameObject createBrick(int row, int column) {
double xSize = 60;
double ySize = 30;
double xStart = 40;
double yStart = 40;
double space = 5;
Color c = Color.BLUE;
RectObject ro = new RectObject("brick" + row + "/" + column, this, xStart + column * (xSize + space),
yStart + row * (ySize + space), 0, 0, xSize - 4, ySize - 4, c);
RectCollider rc = new RectCollider("egal", ro, xSize - 4, ySize - 4);
ro.addCollider(rc);
return ro;
}
/**
* lets ball bounce in Y direction, deletes brick.
*/
@Override
protected void actionIfBallHitsBrick(GameObject ball, GameObject brick) {
ball.setVY(ball.getVY() * -1); // bounce effect for ball
this.deleteObject(brick.getId()); // remove brick from field
logger.debug("deleted brick " + brick.getId());
}
/**
* Let the ball bounce off in Y direction.
*
*/
@Override
protected void actionIfBallHitsEgo(GameObject ball, GameObject ego) {
double ballY = ball.getY();
double egoY = ego.getY();
ball.setY(ballY < egoY ? ballY - 10 : ballY + 10); // radius 5 hard coded.
ball.setVY(ball.getVY() * -1);
logger.debug("ball bounces of ego object.");
}
/**
* Prepares a Breakout level with a 3 x 3 matrix of blocks on top. This method relies on the
* methods {@link #createEgo}, {@link #createBall} and {@link #createBrick}, among others.
*
* @param level String passes by the game engine (not used currently and can be ignored).
*/
@Override
public void prepareLevel(String level) {
for (int y = 3; y < 6; y++) {
for (int x = 0; x < 3; x++) {
logger.trace("trying to create brick X, Y (" + x + "," + y + ")");
GameObject brick = this.createBrick(x, y);
this.addObject(brick);
}
}
this.ego = this.createEgoObject();
this.ball = this.createBall();
this.addObject(this.ego);
this.addObject(this.ball);
logger.info("level preperation succeeded.");
}
}

152
GameProject/src/playground/BreakoutLevel2.java

@ -0,0 +1,152 @@
package playground;
import java.awt.Color;
import java.util.Random;
import controller.BreakoutController;
import controller.LimitedTimeController;
import controller.ReboundController;
import gameobjects.GameObject;
import gameobjects.RectObject;
public class BreakoutLevel2 extends BreakoutLevelBaseAdvanced {
@Override
protected int calcNrBricksX() {
return 6;
}
@Override
protected int calcNrBricksY() {
return 5;
}
@Override
protected double getBrickSizeX() {
return 60.0;
}
@Override
protected double getBrickSizeY() {
return 30.0;
}
@Override
protected double getBrickStartX() {
return 90.0;
}
@Override
protected double getBrickStartY() {
return 60.0;
}
/** Create Explosion effect with random Colors that lasts 2 Seconds.
*
* @param ball GameObject
* @param brick GameObject
*/
@Override
protected void actionIfBallHitsBrick(GameObject ball, GameObject brick) {
//logger.info(brick.getId()+" is hitted and deleted!");
ball.setVY(ball.getVY() * -1.0);
int max = 240;
int min = -240;
Random rand = new Random();
for(int i = 0; i < 20; i++) {
Color randColor = new Color(rand.nextFloat(), rand.nextFloat(), rand.nextFloat());
gameobjects.FallingStar explosion = new gameobjects.FallingStar("explosion"+gameTime+i, this, brick.getX(), brick.getY(), rand.nextInt(max - min + 1) + min, rand.nextInt(max - min + 1) + min, randColor, 2);
explosion.addController(new LimitedTimeController(gameTime, 2));
this.addObjectNow(explosion);
this.deleteObject(brick.getId());
}
}
/** Lets Ball bounce of from Ego.
* If the right or left end part is hitted, the ball bounces of in the end part direction doesn't matter from which site
*
* @param ball Gameobject
* @param ego GameObject
*/
@Override
protected void actionIfBallHitsEgo(GameObject ball, GameObject ego) {
RectObject egoCopyCastedInRectObject = (RectObject) ego;
double egoMiddleX = ego.getX();
double ballX = ball.getX();
double egoWidth = egoCopyCastedInRectObject.getWidth();// Maybe an easier and cleaner way instead of casting an new
double egoHalfWidth = egoWidth / 2.0;
double egoEndPerc = 45.0;
double egoDistEndPartFromMiddle = (egoEndPerc * egoHalfWidth) / 100;
double egoEndPartStartLeft = egoMiddleX - egoDistEndPartFromMiddle;
double egoEndPartStartRight = egoMiddleX + egoDistEndPartFromMiddle;
if ((ballX < egoEndPartStartLeft && (ball.getVX() > 0.0)) || (ballX > egoEndPartStartRight && (ball.getVX() < 0.0))) {
ball.setVX(ball.getVX() * -1.0);
}
ball.setVY(ball.getVY() * -1.0);
}
/** Creates Ego object with an extra Controller for Breakout.
*
* @return ego
*/
@Override
protected GameObject createEgoObject() {
RectObject ego = new RectObject("ego", this, 350, 550, 0, 0, 60, 10, Color.blue);
ego.addController(new BreakoutController(ego.getWidth(), ego.getHeight()));
ego.addCollider(new collider.RectCollider(ego.getId(), ego, ego.getWidth(), ego.getHeight()));
return ego;
}
/** Creates Ball.
*
* @return ball
*/
@Override
protected GameObject createBall() {
gameobjects.FallingStar ball = new gameobjects.FallingStar("ball", this, 350, 350, 130, 130, Color.red, 5);
ball.addController(new ReboundController());
return ball;
}
/** Creates Brick with a random color.
*
* @param row int
* @param column int
*
* @return brick
*/
@Override
protected GameObject createBrick(int row, int column) {
double rnd = Math.random();
Color clr;
if (rnd <= .25) {
clr = Color.red;
} else {
if (rnd <= .5) {
clr = Color.blue;
} else {
if (rnd <= .75) {
clr = Color.yellow;
} else {
clr = Color.green;
}
}
}
RectObject brick = new RectObject("brick" + row + column, this, getBrickStartX() + (row * (getBrickSizeX() * 2)), getBrickStartY() + (column * (getBrickSizeY() * 2)), 0, 0, getBrickSizeX(), getBrickSizeY(), clr);
brick.addCollider(new collider.RectCollider(brick.getId(), brick, brick.getWidth(), brick.getHeight()));
return brick;
}
}

70
GameProject/src/playground/BreakoutLevel3.java

@ -0,0 +1,70 @@
package playground;
import java.awt.Color;
import gameobjects.GameObject;
public class BreakoutLevel3 extends BreakoutLevel2 {
gameobjects.TextObject textPoints, textLives;
/** Creates flags and TextObjects to display scores and Lives.
*
* @param level String
*/
@Override
public void prepareLevel(String level) {
setGlobalFlag("points", 0);
getOrCreateGlobalFlag("lives", 3);
textPoints = new gameobjects.TextObject("textPoints", this, 50 , 10, 0, 0, "Score: 0", 10, Color.black);
textLives = new gameobjects.TextObject("textLives", this, 600 , 10, 0, 0, "Lives: "+(int)getOrCreateGlobalFlag("lives", 3), 10, Color.black);
this.addObject(textPoints);
this.addObject(textLives);
super.prepareLevel(level);
}
/** Sets the Score if a Brick is hitted.
*
* @param ball GameObject
* @param brick
*/
@Override
protected void actionIfBallHitsBrick(GameObject ball, GameObject brick) {
super.actionIfBallHitsBrick(ball, brick);
setGlobalFlag("points", (int)(getGlobalFlag("points")) + 10);
textPoints.setText("Score: "+(int)getGlobalFlag("points"));
}
/** If the Ball goes under the Ego, Lives are decreased and Ball is set above Ego.
*/
@Override
public void applyGameLogic() {
super.applyGameLogic();
if(ball.getY() > ego.getY()) {
setGlobalFlag("lives", (int)(getGlobalFlag("lives")) - 1);
textLives.setText("Lives: "+(int)getGlobalFlag("lives"));
if(ball.getVY() > 0) {
ball.setVY(ball.getVY() *- 1);
}
ball.setY(ego.getY()-20.0);
}
}
/** game ends if egoLives < 0 .
*
* @return gameOver boolean
*/
@Override
public boolean gameOver() {
if((int)getGlobalFlag("lives") < 0) {
return true;
}
return false;
}
}

98
GameProject/src/playground/BreakoutLevelBaseAdvanced.java

@ -0,0 +1,98 @@
package playground;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
/**
* Advanced version of abstract {@link BreakoutLevelBase} providing a complete implementation of
* {@link #prepareLevel(String)}. Additionally abstract methods for number of bricks in X and Y
* direction are provided as well as abstract methods for brick sizes and start coordinates.
*
* @see #calcNrBricksX()
* @see #calcNrBricksY()
* @see #getBrickSizeX()
* @see #getBrickSizeY()
* @see #getBrickStartX()
* @see #getBrickStartY()
*
*/
public abstract class BreakoutLevelBaseAdvanced extends BreakoutLevelBase {
private static Logger logger = LogManager.getLogger(BreakoutLevelBaseAdvanced.class);
/**
* provides the number of bricks to be set in horizontal direction.
*
* @return positive value of how many bricks are to be next to each other in X direction
*/
protected abstract int calcNrBricksX();
/**
* provides the number of bricks to be set in vertical direction.
*
* @return positive value of how many bricks are to be next to each other in Y direction
*/
protected abstract int calcNrBricksY();
/**
* provides the length of one brick.
*
* @return positive value of how long a brick should be in X direction.
*/
protected abstract double getBrickSizeX();
/**
* provides the height of one brick.
*
* @return positive value of how high a brick should be in Y direction.
*/
protected abstract double getBrickSizeY();
/**
* provides the start coordinate of upper left corner (X value).
*
* @return positive value of the X coordinate to use as the starting point of the upper left
* corner of the brick set.
*/
protected abstract double getBrickStartX();
/**
* provides the start coordinate of upper left corner (Y value).
*
* @return positive value of the Y coordinate to use as the starting point of the upper left
* corner of the brick set.
*/
protected abstract double getBrickStartY();
/**
* Prepares a complete Breakout type level and uses the values provided by implementations of
* {@link #calcNrBricksX()} and {@link #calcNrBricksY()} to generate the stone matrix.
* Furthermore, it relies on the methods {@link #createEgoObject()}, {@link #createBall} and {@link #createBrick},
* which are meant to be overwritten in subclasses. <br>
* Attention: For collision detection bricks created by {@link #createBrick(int, int)} need to have the String 'brick' in ID.
*
* @see LevelBreakoutBase#prepareLevel(String) for further information.
*
* @param level String passes by the game engine (not used currently and can be ignored).
*
*/
@Override
public void prepareLevel(String level) {
for (int y = 0; y < this.calcNrBricksY(); y++) {
for (int x = 0; x < this.calcNrBricksX(); x++) {
logger.trace("trying to create brick X, Y (" + x + "," + y + ")");
this.addObject(this.createBrick(x, y));
}
}
this.ego = this.createEgoObject();
this.ball = this.createBall();
this.addObject(this.ego);
this.addObject(this.ball);
logger.info("level preperation succeeded.");
}
}
Loading…
Cancel
Save