Commit 9ce8d047 authored by Nils Hein's avatar Nils Hein
Browse files

Refactoring des Codes für den GameScreen

parent 9bb0ae59
package org.milderjoghurt.frozennumbers.screens;
import biz.pavonis.hexameter.api.Hexagon;
import biz.pavonis.hexameter.api.HexagonOrientation;
import biz.pavonis.hexameter.api.HexagonalGrid;
import biz.pavonis.hexameter.api.HexagonalGridBuilder;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.Music;
......@@ -10,80 +14,55 @@ import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Group;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import org.milderjoghurt.frozennumbers.FrozenNumbersGame;
import org.milderjoghurt.frozennumbers.model.Bubble;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import biz.pavonis.hexameter.api.Hexagon;
import biz.pavonis.hexameter.api.HexagonOrientation;
import biz.pavonis.hexameter.api.HexagonalGrid;
import biz.pavonis.hexameter.api.HexagonalGridBuilder;
import java.util.*;
public class GameScreen implements Screen {
//Playerstruct
class Player {
public Bubble active;
public Vector2 sPos;
public int score = 0;
float timer = 0;
boolean lower;
public Bubble active; //Aktive Bubble eines Spielers
public Vector2 sPos; //Startposition eines Spielers
public int score = 0; //Punktestand
float timer = 0; //Zeit bis zum automatischen abschuss
boolean lower; //Zeigt an ob der Spieler oben oder unten ist
}
Player p1 = new Player();
Player p2 = new Player();
List<Hexagon> removes;
List<Hexagon> frozenHexagons;
List<Bubble> fallingBubbles;
float bubbleradius = 32;
HexagonalGrid map;
Map<Hexagon, Bubble> nachbarn;
ShapeRenderer renderer = new ShapeRenderer();
float bound = 0;
Sprite bg, bgOverlay;
Sprite nextTop,nextTopOverlay, nextBottom, nextBottomOverlay;
Vector2 mapoffset;
private Rectangle m_Bounds;
float wWidth, wHeight;
float timerDefault = 5;
boolean firstMoveP1 = true;
boolean firstMoveP2 = true;
Player p1 = new Player(); //Spieler 1
Player p2 = new Player(); //Spieler 2
List<Hexagon> removes; //Die aus dem Field zu entfernenden Bubbles
List<Hexagon> frozenHexagons; //Alle Frozen Bubbles
List<Bubble> fallingBubbles; //Alle fallende Bubbles
float bubbleRadius = 32; //Radius einer Bubble
HexagonalGrid map; //Hexagonal Grid
Map<Hexagon, Bubble> field; //Map der Bubbles auf dem Hexgrid
float CenterY, CenterX = 0; //Mittelpunkt des Screens
Sprite bg, bgOverlay; //Hintergrund
Sprite nextTop, nextTopOverlay, nextBottom, nextBottomOverlay; //Buttons der Gui
Vector2 mapOffset; //Offset für das Hexgrid
float wWidth, wHeight; //Screenbreite und Höhe
float timerDefault = 5; //Defaultzeit bis zum ablauf des Timers
private Rectangle m_Bounds; //Begrenzung der Spielfläche
private Hexagon getCurrentHex(Bubble b) {
Vector2 p = b.getPos();
return getHexfromPixel(p.x, p.y);
}
public GameScreen() {
wWidth = FrozenNumbersGame.viewport.getWorldWidth();
wHeight = FrozenNumbersGame.viewport.getWorldHeight();
p1.lower = true;
p2.lower = false;
nachbarn = new HashMap<Hexagon, Bubble>();
removes = new ArrayList<Hexagon>();
frozenHexagons = new ArrayList<Hexagon>();
fallingBubbles = new ArrayList<Bubble>();
HexagonalGridBuilder hexbulder = new HexagonalGridBuilder();
bubbleradius = wWidth / 14;
m_Bounds = new Rectangle(0, bubbleradius, wWidth, wHeight - bubbleradius);
//Grid soll 14 bubbles breit sein
bubbleRadius = wWidth / 14;
//Spielfeldbegrenzung setzen
m_Bounds = new Rectangle(0, bubbleRadius, wWidth, wHeight - bubbleRadius);
//Hintergrund setzen
bg = new Sprite(FrozenNumbersGame.assets.get("backgrounds/background.jpg", Texture.class));
float scaleX = wWidth / bg.getWidth();
float scaleY = wHeight / bg.getHeight();
......@@ -94,219 +73,198 @@ public class GameScreen implements Screen {
bgOverlay.setScale(scaleX, scaleY);
bgOverlay.setCenter(wWidth / 2.0f, wHeight / 2.0f);
//Gui setzen
nextBottom = new Sprite(FrozenNumbersGame.assets.get("sprites/btn_next.png", Texture.class));
nextBottom.setScale(scaleX, scaleY);
nextBottom.setCenter(wWidth / 4.0f, wHeight * 0.05f);
nextTop = new Sprite(FrozenNumbersGame.assets.get("sprites/btn_next.png", Texture.class));
nextTop.setScale(scaleX, scaleY);
nextTop.rotate(180);
nextTop.setCenter(wWidth / 4.0f * 3.0f, wHeight * 0.95f);
nextBottom.setAlpha(0.1f);
nextTop.setAlpha(0.1f);
nextBottomOverlay = new Sprite(FrozenNumbersGame.assets.get("sprites/btn_next.png", Texture.class));
nextBottomOverlay.setScale(scaleX, scaleY);
nextBottomOverlay.setCenter(wWidth / 4.0f, wHeight * 0.05f);
nextTop = new Sprite(FrozenNumbersGame.assets.get("sprites/btn_next.png", Texture.class));
nextTop.setScale(scaleX, scaleY);
nextTop.rotate(180);
nextTop.setCenter(wWidth / 4.0f * 3.0f, wHeight * 0.95f);
nextTop.setAlpha(0.1f);
nextTopOverlay = new Sprite(FrozenNumbersGame.assets.get("sprites/btn_next.png", Texture.class));
nextTopOverlay.setScale(scaleX, scaleY);
nextTopOverlay.rotate(180);
nextTopOverlay.setCenter(wWidth / 4.0f * 3.0f, wHeight * 0.95f);
//Mittelpunkt bestimmen
CenterY = wHeight / 2f;
CenterX = wWidth / 2f;
//Bubbledatenhaltung initialisieren
field = new HashMap<Hexagon, Bubble>();
removes = new ArrayList<Hexagon>();
frozenHexagons = new ArrayList<Hexagon>();
fallingBubbles = new ArrayList<Bubble>();
//Hexgrid initialisieren
HexagonalGridBuilder hexbulder = new HexagonalGridBuilder();
hexbulder.setGridHeight(15);
hexbulder.setGridWidth(11);
hexbulder.setRadius(bubbleradius);
hexbulder.setRadius(bubbleRadius);
hexbulder.setOrientation(HexagonOrientation.FLAT_TOP);
map = hexbulder.build();
Hexagon test = map.getByPixelCoordinate(wWidth / 2.0f, wHeight / 2.0f);
mapoffset = new Vector2(0, (wHeight / 2.0f) - (float) test.getCenterY());
Hexagon test = map.getByPixelCoordinate(CenterX, CenterY);
mapOffset = new Vector2(0, CenterY - (float) test.getCenterY());
bound = wHeight / 2f;//float) map.getByGridCoordinate(0, 6 ).getCenterY();
//Spieler initialisieren
p1.lower = true;
p2.lower = false;
p1.sPos = new Vector2(wWidth / 2.0f, 100 * scaleY);
p2.sPos = new Vector2(wWidth / 2.0f, wHeight - 100 * scaleY);
p1.timer = timerDefault;
p2.timer = timerDefault;
//TODO: Main Game Sound
}
@Override
public void show() {
FrozenNumbersGame.assets.get("snd/theme.ogg", Music.class).setVolume(0.1f);
//Liefert das Hexagon auf dem siech die Bubble befindet
private Hexagon getCurrentHex(Bubble b) {
Vector2 p = b.getPos();
return getHexfromPixel(p.x, p.y);
}
//Liefert ein Hexagon auf Basis von Worldkoordinaten
private Hexagon getHexfromPixel(float x, float y) {
return map.getByPixelCoordinate(x - mapoffset.y, y - mapoffset.y);
return map.getByPixelCoordinate(x - mapOffset.y, y - mapOffset.y);
}
//Liefert den Mittelpunkt eines Hexagons in Worldkoordinaten
private Vector2 getHexCenter(Hexagon hex) {
return new Vector2((float) hex.getCenterX() + mapoffset.x, (float) hex.getCenterY() + mapoffset.y);
return new Vector2((float) hex.getCenterX() + mapOffset.x, (float) hex.getCenterY() + mapOffset.y);
}
private void sendFlying(Vector2 source, Vector2 target, Player p){
Vector2 speed = target.cpy().sub(source).nor();
p.active.isFlying = true;
p.timer = timerDefault;
p.active.setVel(speed.cpy().scl(100.0f));
p.active.setForce(speed.scl(100));
FrozenNumbersGame.assets.get("snd/shot.mp3", Sound.class).play();
}
private void playerlogic(Player p, boolean lower) {
//Wenn die aktuelle Bubble in der Map gelandet ist neue Bubble erzeugen
if (p.active == null) {
p.active = new Bubble(p.sPos.cpy());
p.active.setSize(bubbleradius * 2, bubbleradius * 2);
p.active.setSize(bubbleRadius * 2, bubbleRadius * 2);
p.active.setCenter(p.sPos.x, p.sPos.y);
p.active.isFlying = false;
}
if (Gdx.input.justTouched()) {
Vector2 touchPoint = new Vector2();
FrozenNumbersGame.viewport.unproject(touchPoint.set(Gdx.input.getX(), Gdx.input.getY()));
if (p.active != null) {
if (!p.active.isFlying && lower && touchPoint.y < bound) {
Vector2 star = new Vector2(touchPoint.x, touchPoint.y);
Vector2 ssrc = new Vector2(wWidth / 2, bubbleradius * 2);
Vector2 speed = star.cpy().sub(ssrc).nor();
speed.set(speed.x, Math.abs(speed.y));
p.active.setVel(speed.cpy().scl(100.0f));
p.active.setForce(speed.scl(100));
p.active.isFlying = true;
FrozenNumbersGame.assets.get("snd/shot.mp3", Sound.class).play();
p.timer = timerDefault;
}
if (!p.active.isFlying && !lower && touchPoint.y > bound) {
Vector2 star = new Vector2(touchPoint.x, touchPoint.y);
Vector2 ssrc = new Vector2(wWidth / 2, wHeight - bubbleradius * 2);
Vector2 speed = star.cpy().sub(ssrc).nor();
speed.set(speed.x, -1 * Math.abs(speed.y));
p.active.setVel(speed.cpy().scl(100.0f));
p.active.setForce(speed.scl(100));
p.active.isFlying = true;
FrozenNumbersGame.assets.get("snd/shot.mp3", Sound.class).play();
p.timer = timerDefault;
//Active Bubble Logic
if (p.active != null) {
if (!p.active.isFlying) {
//Logic zum Bubbleabschuss
Vector2 touchPoint = new Vector2();
if (Gdx.input.justTouched() || p.timer <= 0) {
FrozenNumbersGame.viewport.unproject(touchPoint.set(Gdx.input.getX(), Gdx.input.getY()));
if (p.timer <= 0) {
float randomX = -0.2f * wWidth + (new Random().nextFloat() * 1.4f * wWidth);
touchPoint = new Vector2(randomX, (float) (wHeight / 2.0));
}
if (lower && touchPoint.y <= CenterY) {
sendFlying(p.sPos,touchPoint,p);
} else if (!lower && touchPoint.y >= CenterY) {
sendFlying(p.sPos,touchPoint,p);
}
}
}
}
if(p.timer <= 0)
{
float randomX = -0.2f*wWidth + (new Random().nextFloat()*1.4f*wWidth);
Vector2 touchPoint = new Vector2(randomX,(float) (wHeight/2.0));
if (p.active != null) {
if (!p.active.isFlying && lower && touchPoint.y <= bound) {
Vector2 star = new Vector2(touchPoint.x, touchPoint.y);
Vector2 ssrc = new Vector2(wWidth / 2, bubbleradius * 2);
Vector2 speed = star.cpy().sub(ssrc).nor();
speed.set(speed.x, Math.abs(speed.y));
p.active.setVel(speed.cpy().scl(100.0f));
p.active.setForce(speed.scl(100));
p.active.isFlying = true;
FrozenNumbersGame.assets.get("snd/shot.mp3", Sound.class).play();
}
if (!p.active.isFlying && !lower && touchPoint.y >= bound) {
Vector2 star = new Vector2(touchPoint.x, touchPoint.y);
Vector2 ssrc = new Vector2(wWidth / 2, wHeight - bubbleradius * 2);
Vector2 speed = star.cpy().sub(ssrc).nor();
speed.set(speed.x, -1 * Math.abs(speed.y));
p.active.setVel(speed.cpy().scl(100.0f));
p.active.setForce(speed.scl(100));
p.active.isFlying = true;
FrozenNumbersGame.assets.get("snd/shot.mp3", Sound.class).play();
}
p.timer = timerDefault;
}
}
if (p.active != null) {
if (p.active.isFlying) {
Hexagon point = getCurrentHex(p.active);
boolean hit = false;
for (Hexagon h : map.getNeighborsOf(point)) {
if (nachbarn.containsKey(h)) {
if (p.active.getPos().dst(getHexCenter(h)) < 2 * (bubbleradius * 0.85)) {
hit = true;
FrozenNumbersGame.assets.get("snd/hit.mp3", Sound.class).play();
break;
}
//Fliegende Bubble und Collisionsprüfung
if (p.active.isFlying) {
Hexagon point = getCurrentHex(p.active);
boolean hit = false;
for (Hexagon h : map.getNeighborsOf(point)) {
if (field.containsKey(h)) {
if (p.active.getPos().dst(getHexCenter(h)) < 2 * (bubbleRadius * 0.85)) {
hit = true;
FrozenNumbersGame.assets.get("snd/hit.mp3", Sound.class).play();
break;
}
}
}
if ((p.active.getPos().y > bound - bubbleradius / 2.0 && lower) || (p.active.getPos().y < bound + bubbleradius / 2.0 && !lower)) {
hit = true;
FrozenNumbersGame.assets.get("snd/hit.mp3", Sound.class).play();
}
if ((p.active.getPos().y > CenterY - bubbleRadius / 2.0 && lower) || (p.active.getPos().y < CenterY + bubbleRadius / 2.0 && !lower)) {
hit = true;
FrozenNumbersGame.assets.get("snd/hit.mp3", Sound.class).play();
}
if (p.active.getPos().x > m_Bounds.getWidth() - (bubbleRadius)
|| p.active.getPos().x < m_Bounds.getX() + (bubbleRadius)) {
p.active.setVel(p.active.getVel().scl(-1, 1));
}
p.active.Update(0.1f);
if (p.active.getPos().x > m_Bounds.getWidth() - (bubbleradius)
|| p.active.getPos().x < m_Bounds.getX() + (bubbleradius)) {
p.active.setVel(p.active.getVel().scl(-1, 1));
}
p.active.Update(0.1f);
if (hit) {
p.active.isFlying = false;
p.active.setVel(new Vector2(0, 0));
if (!nachbarn.containsKey(point))
nachbarn.put(point, new Bubble(p.active));
p.active = null;
p.score += checkScore(point);
for (Hexagon h : map.getNeighborsOf(point)) {
if(nachbarn.containsKey(h))
p.score += checkScore(h);
}
if (hit) {
p.active.isFlying = false;
p.active.setVel(new Vector2(0, 0));
if (!field.containsKey(point))
field.put(point, new Bubble(p.active));
p.active = null;
p.score += checkScore(point);
for (Hexagon h : map.getNeighborsOf(point)) {
if (field.containsKey(h))
p.score += checkScore(h);
}
}
}
//Moving falling Bubbles
for (Iterator<Bubble> iterator = fallingBubbles.iterator(); iterator.hasNext(); ) {
Bubble b = iterator.next();
Vector2 speed = new Vector2(0,(float) -(wHeight/2.0 - b.getPos().y)).nor();
b.setVel(speed.cpy().scl(25.0f));
Bubble b = iterator.next();
Vector2 speed = new Vector2(0, (float) -(wHeight / 2.0 - b.getPos().y)).nor();
b.setVel(speed.cpy().scl(25.0f));
b.setForce(speed.scl(25));
b.isFlying = true;
b.Update(0.1f);
//Scoring and deleting Bubble
int points = 5;
float y = b.getPos().y;
if(y < 3* bubbleradius && lower)
{
p.score+=points;
iterator.remove();
p2.timer=0;
}
if(y > wHeight - 3* bubbleradius && !lower)
{
p.score+=points;
iterator.remove();
p1.timer=0;
}
b.isFlying = true;
b.Update(0.1f);
//Scoring and deleting Bubble
int points = 5;
float y = b.getPos().y;
if (y < 3 * bubbleRadius && lower) {
p.score += points;
iterator.remove();
p2.timer = 0;
}
if (y > wHeight - 3 * bubbleRadius && !lower) {
p.score += points;
iterator.remove();
p1.timer = 0;
}
}
}
private int checkScore(Hexagon h) {
int sum = 0;
Bubble active = nachbarn.get(h);
Bubble active = field.get(h);
List<Bubble> nei = new ArrayList<Bubble>();
for (Hexagon n : map.getNeighborsOf(h)) {
if (nachbarn.containsKey(n)) {
sum += nachbarn.get(n).getValue();
nei.add(nachbarn.get(n));
if (field.containsKey(n)) {
sum += field.get(n).getValue();
nei.add(field.get(n));
}
}
if (sum % 10 == active.getValue() && nei.size() > 1) {
if (!nachbarn.get(h).isFrozen()) {
if (!field.get(h).isFrozen()) {
removes.add(h);
removes.addAll(map.getNeighborsOf(h));
}
return (nei.size()+1)*10;
return (nei.size() + 1) * 10;
}
return 0;
}
@Override
public void render(float delta) {
removes.clear();
......@@ -317,9 +275,8 @@ public class GameScreen implements Screen {
playerlogic(p1, true);
playerlogic(p2, false);
for (Hexagon h : nachbarn.keySet()) {
Bubble bu = nachbarn.get(h);
for (Hexagon h : field.keySet()) {
Bubble bu = field.get(h);
Vector2 star = new Vector2(getHexCenter(h));
Vector2 ssrc = bu.getPos();
......@@ -332,7 +289,7 @@ public class GameScreen implements Screen {
//Freezing bubbles
for (Hexagon hexagon : removes) {
//Gdx.audio.newSound(new FileHandle("plop")).play();
Bubble b = nachbarn.get(hexagon);
Bubble b = field.get(hexagon);
if (b != null) {
b.setFrozen(1);
frozenHexagons.add(hexagon);
......@@ -342,61 +299,38 @@ public class GameScreen implements Screen {
//Countdown Internal Bubble Freezecounter
for (Iterator<Hexagon> iterator = frozenHexagons.iterator(); iterator.hasNext(); ) {
Hexagon hex = iterator.next();
Bubble b = (nachbarn.get(hex));
Bubble b = (field.get(hex));
if (b != null && b.deltaTime(delta)) {
//Removing Frozen Bubbles
FrozenNumbersGame.assets.get("snd/pop.mp3", Sound.class).play();
nachbarn.remove(hex);
field.remove(hex);
iterator.remove();
checkLooseBubbles();
}
if(b == null){
iterator.remove();
checkLooseBubbles();
if (b == null) {
iterator.remove();
checkLooseBubbles();
}
}
boolean checkForEmptyP1 = true;//lower
boolean checkForEmptyP2 = true;//upper
for(Hexagon h : nachbarn.keySet())
{
if(nachbarn.get(h)!=null)
{
double y = h.getCenterY();
if(y > wHeight-3*bubbleradius)
{
FrozenNumbersGame.m_Screens.put("GameOverScreen", new GameOverScreen(p1.score, p2.score/2, p1));
FrozenNumbersGame.game.setScreen(FrozenNumbersGame.m_Screens.get("GameOverScreen"));
}else if(y < 4*bubbleradius){
FrozenNumbersGame.m_Screens.put("GameOverScreen", new GameOverScreen(p1.score/2, p2.score, p2));
for (Hexagon h : field.keySet()) {
if (field.get(h) != null) {
double y = h.getCenterY();
if (y > wHeight - 3 * bubbleRadius) {
FrozenNumbersGame.m_Screens.put("GameOverScreen", new GameOverScreen(p1.score, p2.score / 2, p1));
FrozenNumbersGame.game.setScreen(FrozenNumbersGame.m_Screens.get("GameOverScreen"));
} else if (y < 4 * bubbleRadius) {
FrozenNumbersGame.m_Screens.put("GameOverScreen", new GameOverScreen(p1.score / 2, p2.score, p2));
FrozenNumbersGame.game.setScreen(FrozenNumbersGame.m_Screens.get("GameOverScreen"));
}
}
/*if(h.getCenterY()< wHeight / 2.0f){
checkForEmptyP1 = false;
firstMoveP1 = false;
}
if((h.getCenterY()-20)> wHeight / 2.0f){
checkForEmptyP2 = false;
firstMoveP2 = false;
}*/
}
/*if(!firstMoveP1 && checkForEmptyP1) {
FrozenNumbersGame.m_Screens.put("GameOverScreen", new GameOverScreen(p1.score, p2.score, p1));
FrozenNumbersGame.game.setScreen(FrozenNumbersGame.m_Screens.get("GameOverScreen"));
}
if(!firstMoveP2 && checkForEmptyP2) {
FrozenNumbersGame.m_Screens.put("GameOverScreen", new GameOverScreen(p1.score, p2.score, p2));
FrozenNumbersGame.game.setScreen(FrozenNumbersGame.m_Screens.get("GameOverScreen"));
}*/
FrozenNumbersGame.viewport.apply(true);
Gdx.gl.glClearColor(0f, 0f, 0f, 1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
renderer.setProjectionMatrix(FrozenNumbersGame.viewport.getCamera().combined);
Batch batch = FrozenNumbersGame.batch;
batch.setProjectionMatrix(FrozenNumbersGame.viewport.getCamera().combined);
batch.begin();
......@@ -409,32 +343,32 @@ public class GameScreen implements Screen {
nextBottomOverlay.draw(batch);
//Timer darstellung
float bW = (nextBottom.getWidth()-(nextBottom.getWidth()*(p1.timer/timerDefault)));
float tW = (nextTop.getWidth()-(nextTop.getWidth()*(p2.timer/timerDefault)));
nextBottomOverlay.setRegion(0,0,(int)bW,(int)nextBottom.getHeight());
nextBottomOverlay.setBounds(nextBottom.getX(),nextBottom.getY(),bW,nextBottom.getHeight());
float bW = (nextBottom.getWidth() - (nextBottom.getWidth() * (p1.timer / timerDefault)));
float tW = (nextTop.getWidth() - (nextTop.getWidth() * (p2.timer / timerDefault)));
nextBottomOverlay.setRegion(0, 0, (int) bW, (int) nextBottom.getHeight());
nextBottomOverlay.setBounds(nextBottom.getX(), nextBottom.getY(), bW, nextBottom.getHeight());