Skip to content

Commit 874e226

Browse files
author
Marcel Kaufmann
committed
Level 5 A 4
1 parent a0421bd commit 874e226

File tree

12 files changed

+178
-9
lines changed

12 files changed

+178
-9
lines changed

Game.pde

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class Game {
5252
Check if a coin has fallen out of the screen -> decrease live by 1
5353
*/
5454
void checkIngameCoins( ) {
55-
for (int i = 0; i < ingameCoins.size()-1; i++) {
55+
for (int i = 0; i < ingameCoins.size(); i++) {
5656
Coin coin = ingameCoins.get(i);
5757
boolean isCatched = isInCatcherZone(coin);
5858
boolean isOut = isInOutZone(coin);

tutorial/Level3/CatcherTutorialLevel3A2/CatcherTutorialLevel3A2.pde

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ void draw() {
2222
playerPosX = mouseX;
2323
}
2424
rect(playerPosX, 500, 50, 10);
25-
25+
2626
if(isTimeForNextOne() && !waitingStack.isEmpty()){
2727
Coin newCoin = waitingStack.pop();
2828
coinListInGame.add(newCoin);
2929
}
30-
30+
3131
for(int i = 0; i < coinListInGame.size() ; i++){
3232
Coin currentCoin = coinListInGame.get(i);
3333
currentCoin.display();
@@ -42,4 +42,4 @@ boolean isTimeForNextOne( ) {
4242
return true;
4343
}
4444
return false;
45-
}
45+
}

tutorial/Level3/CatcherTutorialLevel3A3/Game.pde

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@ class Game {
4040
}
4141
return false;
4242
}
43-
}
43+
}

tutorial/Level4/CatcherTutorialLevel4A1/Game.pde

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@ class Game {
4040
}
4141
return false;
4242
}
43-
}
43+
}

tutorial/Level5/CatcherTutorialLevel5A1/Game.pde

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,4 @@ class Game {
5353
}
5454
return false;
5555
}
56-
}
56+
}

tutorial/Level5/CatcherTutorialLevel5A2/Game.pde

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,4 @@ class Game {
5252
}
5353
return false;
5454
}
55-
}
55+
}

tutorial/Level5/CatcherTutorialLevel5A3/Game.pde

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,4 @@ class Game {
5252
}
5353
return false;
5454
}
55-
}
55+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
class Catcher {
2+
PShape c;
3+
float yPos;
4+
float xPos;
5+
float catcherWidth;
6+
float catcherHeight;
7+
8+
public Catcher( ) {
9+
catcherWidth = gameWidth/8;
10+
catcherHeight = gameHeight/100;
11+
rectMode(CENTER);
12+
fill(255);
13+
c = createShape(RECT, 0, 0, catcherWidth, catcherHeight);
14+
yPos = gameHeight-(gameHeight/8);
15+
xPos = gameWidth/2;
16+
}
17+
18+
void draw() {
19+
xPos = playerPosX;
20+
shape(c, xPos, yPos);
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
float playerPosX;
2+
float gameHeight;
3+
float gameWidth;
4+
Game game;
5+
6+
void setup() {
7+
size(400, 640);
8+
//fullScreen(P2D);
9+
gameWidth = width;
10+
gameHeight = height;
11+
game = new Game();
12+
}
13+
14+
void draw() {
15+
background(50);
16+
if (mousePressed) {
17+
playerPosX = mouseX;
18+
}
19+
game.execute();
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
class Coin {
2+
PShape c;
3+
float xPos;
4+
float yPos;
5+
float coinWidth;
6+
float coinHeigth;
7+
8+
public Coin() {
9+
ellipseMode(CENTER);
10+
init();
11+
}
12+
13+
void init( ) {
14+
coinWidth = gameHeight/50;
15+
coinHeigth = gameHeight/50;
16+
xPos = random(coinWidth, (gameWidth-1)-coinWidth);
17+
yPos = -coinHeigth;
18+
c = createShape(ELLIPSE, 0, 0, coinWidth, coinHeigth);
19+
c.setFill(color(255, 255, 0));
20+
}
21+
22+
void display( ) {
23+
shape(c, xPos, -coinWidth);
24+
c.translate(0, 2);
25+
yPos += 2;
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import java.util.Stack;
2+
3+
class Game {
4+
int lives;
5+
int score;
6+
ArrayList<Coin> coinListInGame = new ArrayList<Coin>();
7+
Stack<Coin> waitingStack = new Stack();
8+
9+
Catcher catcher;
10+
11+
int interval = 1000;
12+
int savedTime = millis();
13+
14+
public Game () {
15+
lives = 5;
16+
score = 0;
17+
catcher = new Catcher();
18+
}
19+
20+
21+
void execute() {
22+
catcher.draw();
23+
if (isTimeForNextOne()) {
24+
if (waitingStack.empty()) {
25+
waitingStack.push(new Coin());
26+
}
27+
Coin newCoin = waitingStack.pop();
28+
coinListInGame.add(newCoin);
29+
}
30+
checkIngameCoins();
31+
println("Score: " + score);
32+
}
33+
34+
void checkIngameCoins( ) {
35+
for (int i = 0; i < coinListInGame.size(); i++) {
36+
Coin coin = coinListInGame.get(i);
37+
boolean isCatched = isInCatcherZone(coin);
38+
boolean isOut = isInOutZone(coin);
39+
if (isCatched) score++;
40+
if (isOut) lives--;
41+
42+
if (isCatched || isOut) {
43+
coin.init();
44+
waitingStack.push(coin);
45+
coinListInGame.remove(coin);
46+
} else {
47+
coin.display();
48+
}
49+
}
50+
}
51+
52+
boolean isInOutZone(Coin coin) {
53+
return coin.yPos + coin.coinHeigth/2 >= gameHeight-1;
54+
}
55+
56+
boolean isInCatcherZone(Coin coin) {
57+
return isInYZone(coin) && isInXZone(coin);
58+
}
59+
60+
boolean isInYZone(Coin coin) {
61+
boolean coinLowerBound =
62+
coin.yPos + coin.coinHeigth/2 >= catcher.yPos - catcher.catcherHeight/2 &&
63+
coin.yPos + coin.coinHeigth/2 <= catcher.yPos + catcher.catcherHeight/2;
64+
boolean coinUpperBound =
65+
coin.yPos - coin.coinHeigth/2 >= catcher.yPos - catcher.catcherHeight/2 &&
66+
coin.yPos - coin.coinHeigth/2 <= catcher.yPos + catcher.catcherHeight/2;
67+
return coinLowerBound || coinUpperBound;
68+
}
69+
70+
boolean isInXZone(Coin coin) {
71+
boolean coinRightBound =
72+
coin.xPos + coin.coinWidth/2 >= catcher.xPos - catcher.catcherWidth/2 &&
73+
coin.xPos + coin.coinWidth/2 <= catcher.xPos + catcher.catcherWidth/2;
74+
boolean coinLeftBound =
75+
coin.xPos - coin.coinWidth/2 >= catcher.xPos - catcher.catcherWidth/2 &&
76+
coin.xPos - coin.coinWidth/2 <= catcher.xPos + catcher.catcherWidth/2;
77+
return coinRightBound || coinLeftBound;
78+
}
79+
80+
81+
boolean isTimeForNextOne( ) {
82+
int currentTime = millis();
83+
if (savedTime + interval < currentTime) {
84+
savedTime = currentTime;
85+
return true;
86+
}
87+
return false;
88+
}
89+
}

tutorial/Level5/Processing_Tutorial_Level_#5-CatcherGameTutorial.md

+11
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,16 @@ println("Lives: "+ lives); // Innerhalb der zyklischen Ausführung
4040

4141
[Mögliche Lösung](https://github.com/Flocksserver/CatcherTutorial/blob/master/tutorial/Level5/CatcherTutorialLevel5A3)
4242

43+
### Aufgabe 4
44+
1. Was war nochmal das Ziel des Spiels? Punkte sammeln! Endlich soll dein *Catcher* die Funktionalität bekommen, die er braucht. Erstelle wie beim Leben eine Variable für die aktuellen Punkte.
45+
2. Jetzt wird es etwas tricky! Überlege dir eine Kollisionserkennung zwischen dem *Catcher* und deinen herunterfallenden Objekten. Vom Prinzip musst du genau wie in Aufgabe 1 vorgehen. Beachte aber, dass diesmal die X **und** die Y-Positionen vom jeweils herunterfallenden Objekt und dem *Catcher* entscheidend sind. Außerdem sind bei der Betrachtung der Y-Richtung nicht nur die untere Kante (*+ objekt.height/2*) sondern auch die obere Kante (*- objekt.height/2*) relevant. Bei der Betrachtung der X-Richtung demnach (*+ objekt.width/2*) und (*- objekt.width/2*). Probiere ruhig etwas länger aus und lass dich nicht entmutigen, wenn du nicht sofort auf eine richtig funktionierende Lösung kommst.
46+
3. Zähle die aktuellen Punkte bei Kontakt mit dem *Catcher* hoch. Entferne das entsprechenden Objekt aus der *ingame*-List, initialisiere es neu und füge es dem Stack hinzu
47+
48+
[Mögliche Lösung](https://github.com/Flocksserver/CatcherTutorial/blob/master/tutorial/Level5/CatcherTutorialLevel5A4)
49+
50+
> Exkurs: Ist dir aufgefallen, dass die Kollisionserkennung nicht ganz korrekt ist wenn du wie ich für die herunterfallenden Objekte Kreise verwendest? Der Algorithmus dafür geht von einem Rechteck aus. Dies wird klar, wenn du die Berechnung der Kollision auf Papier mit den Objekten malst und den Kreis links oder rechts an die Ecke des *Catchers* treffen lässt. Haben wir nun quatsch implementiert? Wieder: Theoretisch ja, praktisch nein! In Spielen (vorrangig bei 3D - aber auch teilweise bei 2D) ist es aus Effizienzgründen gängig, dass eine [*Hitbox*](https://de.wikipedia.org/wiki/Hitbox) definiert wird. Diese Beschreibt den Bereich, in dem Kollision als gegeben angesehen wird. Der Kreis besitzt also eine virtuelle Hitbox um sich herum.
51+
52+
53+
4354
# Nächstes Level
4455
Hier geht es weiter zum [nächsten Level :arrow_right:](https://github.com/Flocksserver/CatcherTutorial/blob/master/tutorial/Level6/Processing_Tutorial_Level_%236-CatcherGameTutorial.md)

0 commit comments

Comments
 (0)