Compare commits

..

3 Commits

17 changed files with 319 additions and 241 deletions

BIN
assets/Sprite-0001.ase Normal file

Binary file not shown.

BIN
assets/Sprite-0001.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
assets/Sprite-0002.ase Normal file

Binary file not shown.

BIN
assets/Sprite-bob.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 B

BIN
assets/Sprite-robi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

BIN
assets/Sprite-saege.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

View File

@ -1,10 +1,11 @@
class Collectable {
float x, y, cwidth, cheight;
float cwidth, cheight;
boolean is_attached = false;
PVector pos = new PVector();
Collectable(float xpos, float ypos, float cw, float ch) {
x = xpos;
y = ypos;
pos.x = xpos;
pos.y = ypos;
cwidth = cw;
cheight = ch;
}
@ -18,10 +19,7 @@ class Saw extends Collectable {
void drawSaw() {
if (!is_attached) {
stroke(0);
fill(210, 210, 0);
rect(x, y, cwidth, cheight);
fill(0);
image(saw_sprite, pos.x, pos.y);
}
}
}
@ -34,10 +32,7 @@ class Bob extends Collectable {
void drawBob() {
if (!is_attached) {
stroke(0);
fill(255, 209, 152);
rect(x, y, cwidth, cheight);
fill(0);
image(bob_sprite, pos.x, pos.y);
}
}
}

View File

@ -4,75 +4,29 @@ class Files {
return new File(dataPath(filepath)).exists();
}
int[] loadJson(String jsonfile) {
if (!checkSaveFile(jsonfile)) {
void loadJson(String jsonfile) {
// if (!checkSaveFile(jsonfile)) {
try {
JSONArray values = loadJSONArray(jsonfile);
int[] arrayfromjson = new int[values.size()];
return arrayfromjson;
} else {
int[] arrayfromjson = new int[100];
return arrayfromjson;
stats_menu.best_game_time = values.getInt(0);
stats_menu.trees_sawed = values.getInt(1);
stats_menu.game_time = values.getInt(2);
println("Savefile found");
} catch (Exception e) {
println("Savefile not found");
}
}
JSONArray json;
void savetofile(String filename) {
json = new JSONArray();
json.setInt(0, stats_menu.best_game_time);
json.setInt(1, stats_menu.trees_sawed);
json.setInt(2, millis() + stats_menu.game_time);
saveJSONArray(json,"./saves/" + filename + ".json");
}
}
/*
//// This Handles loading and saving the level
JSONArray json;
// This saves the Current save to file
int savetofile(String filename) {
json = new JSONArray();
for (int i = 0; i < level.length; i++) {
JSONArray mapsave = new JSONArray();
mapsave.setInt(0, level[i][0]);
mapsave.setInt(1, level[i][1]);
mapsave.setInt(2, level[i][2]);
mapsave.setInt(3, level[i][3]);
mapsave.setInt(4, level[i][4]);
json.setJSONArray(i, mapsave);
}
saveJSONArray(json,"./saves/" + filename + ".json");
return 1;
}
boolean checkSaveFile(String filepath) {
return new File(dataPath(filepath)).exists();
}
// Check if there already is a safefile and load it if it is possible. If not load empty array
int[][] loadJson(String jsonfile) {
if (!checkSaveFile("./saves/save.json")) {
JSONArray values = loadJSONArray(jsonfile);
// println(values.size());
int[][] arrayfromjson = new int[values.size()][values.size()];
for (int i = 0; i < values.size(); i++) {
JSONArray jsontoarray = values.getJSONArray(i);
int x = jsontoarray.getInt(0);
int y = jsontoarray.getInt(1);
int rectwidth = jsontoarray.getInt(2);
int rectheight = jsontoarray.getInt(3);
int isspike = jsontoarray.getInt(4);
arrayfromjson[i][0] = x;
arrayfromjson[i][1] = y;
arrayfromjson[i][2] = rectwidth;
arrayfromjson[i][3] = rectheight;
arrayfromjson[i][4] = isspike;
}
return arrayfromjson;
} else {
int[][] arrayfromjson = new int[100][5];
return arrayfromjson;
}
}
*/

143
kek2.pde
View File

@ -1,25 +1,19 @@
// Level mit 2 Bereichen. Erster Bereich Straße und Kettensäge und End/Startpunkt. Zweiter Bereich Wald und Bob
// Statistikseite: Spielzeit, Bäume gefällt, Zeit gestoppt
// Wir brauchen Geräusche
// Robi muss noch beschleunigen können
float checkDistance(Log log, Ship ship) {
float testX = ship.x;
float testY = ship.y;
float testX = ship.pos.x;
float testY = ship.pos.y;
// which edge is closest?
if (ship.x < log.x) testX = log.x;
else if (ship.x > log.x+log.logwidth) testX = log.x+log.logwidth;
if (ship.y < log.y) testY = log.y;
else if (ship.y > log.y+log.logheight) testY = log.y+log.logheight;
if (ship.pos.x < log.x) testX = log.x;
else if (ship.pos.x > log.x+log.logwidth) testX = log.x+log.logwidth;
if (ship.pos.y < log.y - log.logheight) testY = log.y - log.logheight;
else if (ship.pos.y > log.y) testY = log.y;
// get distant
float distX = ship.x-testX;
float distY = ship.y-testY;
float distX = ship.pos.x-testX;
float distY = ship.pos.y-testY;
float distance = sqrt( (distX*distX) + (distY*distY) );
line(testX, testY, ship.x, ship.y);
line(testX, testY, ship.pos.x, ship.pos.y);
// if the distance is less than the radius, collision!
return distance;
@ -27,83 +21,121 @@ float checkDistance(Log log, Ship ship) {
// Main Game entry
void play() {
background(50);
background(75, 105, 47);
text(playtime.second(), 20, 20);
// println(playtime.second());
// for(int i = 0; i < trees.length; i++) {
// trees[i].draw();
// }
ship_zero.draw();
saw_zero.drawSaw();
ship_zero.collect(saw_zero);
bob.drawBob();
ship_zero.collect(bob);
// draw wall
for(int i = 0; i < walls.length; i++) {
walls[i].drawLog(i);
}
// draw log
for(int i = 0; i < logs.length; i++) {
logs[i].drawLog(i);
}
// log normal stroke
for(int i = 0; i < logs.length; i++) {
logs[i].strokecolor = logs[i].logcolor;
}
// nearest log stroke (debug)
logs[ship_zero.nextLog].strokecolor = color(255, 0, 0);
// println(ship_zero.newX, " : ", ship_zero.newY);
// println("x: ", ship_zero.x, " : ", ship_zero.y);
println(stats_menu.trees_sawed);
}
// -----
MainMenu main_menu = new MainMenu();
Stats stats_menu = new Stats();
//Log log_zero = new Log(100,200,100,100,false);
void setup() {
// size(1280, 720);
size(600, 600);
textAlign(CENTER, CENTER);
// surface.setResizable(true);
ship_zero = new Ship();
saw_zero = new Saw(100, 100, 20, 50);
bob = new Bob(100, 400, 20, 40);
}
// global state
boolean isgame = false;
boolean ismenu = true;
boolean isend = false;
boolean isstats = false;
boolean ispause = false;
boolean start_slide = true;
Log[] logs = {new Log(100, 200, 100, 100, false), new Log(500, 200, 200, 100, false), new Log(400, 400, 20, 100, true) };
// ----- Objectives
MainMenu main_menu = new MainMenu();
Stats stats_menu = new Stats();
Log[] logs;
// player
Ship ship_zero;
// collectables
Saw saw_zero;
Bob bob;
// stopwatch
StopWatchTimer playtime = new StopWatchTimer();
Files savefile = new Files();
PImage player_sprite;
PImage player_sprite_bob;
PImage saw_sprite;
PImage bob_sprite;
void setup() {
size(600, 600);
textAlign(CENTER, CENTER);
create_level(30);
println(logs[1]);
ship_zero = new Ship();
saw_zero = new Saw(-width+100, 100, 20, 50);
bob = new Bob(500, 400, 20, 40);
player_sprite = loadImage("./assets/Sprite-robi.png");
player_sprite_bob = loadImage("./assets/Sprite-robiwithbob.png");
saw_sprite = loadImage("./assets/Sprite-saege.png");
bob_sprite = loadImage("./assets/Sprite-bob.png");
savefile.loadJson("./saves/save.json");
}
void draw() {
// time debug
// println(millis(), " start: ", playtime.startTime, " pause: ", playtime.pauseTime);
// game state
if (isgame) {
play();
if(keyPressed) {
println(mouseX, " : ", mouseY);
// Go to second or first slide
if(ship_zero.pos.x > 0) {
start_slide = false;
} else {
start_slide = true;
}
// actually move the camera
if(start_slide) {
translate(600, 0);
} else {
translate(0, 0);
}
// Main Entry
play();
// Timer
if (playtime.running) {} else playtime.start();
if (playtime.pause) playtime.resume();
// Win
if(bob.is_attached && dist(ship_zero.pos.x, ship_zero.pos.y ,-400, 300) < 100) {
isgame = false;
isend = true;
}
fill(150, 0, 0, 50);
ellipse(-400, 300, 200, 200);
} else if (ismenu){
// menu code
// play();
@ -113,6 +145,15 @@ void draw() {
stats_menu.draw();
} else if (isend) {
// end screen code
// save
if(playtime.second() < stats_menu.best_game_time) stats_menu.best_game_time = playtime.second();
savefile.savetofile("save");
} else if (ispause) {
main_menu.drawMenu();
if (playtime.running && playtime.pause == false) playtime.pause_start();
}
mouse_released = false;

View File

@ -12,15 +12,18 @@ void keyPressed() {
}
} else if (key == 's') { // SAW
if (ship_zero.hasSaw) {
if(checkDistance(logs[ship_zero.nextLog], ship_zero) < 40) {
logs[ship_zero.nextLog].sawed = true;
Log target_log = logs[ship_zero.nextLog];
if(checkDistance(target_log, ship_zero) < 40) {
target_log.sawed = true;
stats_menu.trees_sawed = stats_menu.trees_sawed + 1;
}
}
} else if (keyCode == ESC && isgame){
} else if (keyCode == ESC){
key = 0;
isgame = false;
ismenu = true;
if (isgame) {
isgame = false;
ispause = true;
}
}
}

15
level.pde Normal file
View File

@ -0,0 +1,15 @@
// Outside wall
Log[] walls = {new Log(-30, 275, 40, 275, false, true), new Log(-30, 600, 40, 275, false, true)};
void create_level(int logcount) {
logs = new Log[logcount];
randomSeed((int)random(0, 30));
for (int i = 1; i < logs.length; i++) {
logs[i] = new Log((int) random(0, width), (int) random(0, height), 20, 60 + random(0, 40), true, false);
}
// 2nd slide entry
logs[0] = new Log(-5, 325, 10, 50, false, true);
// debug log
logs[1] = new Log(-300, 100, 20, 100, true, false);
}

View File

@ -2,16 +2,20 @@ class Log {
float x, y, logwidth, logheight;
boolean sawed = false;
boolean is_tree = false;
boolean is_wall = false;
float a = 0;
boolean render_log = true;
color logcolor;
color strokecolor = logcolor;
Log (float xpos, float ypos, float logw, float logh, boolean ist) {
Log (float xpos, float ypos, float logw, float logh, boolean ist, boolean isw) {
x = xpos;
y = ypos;
logwidth = logw;
logheight = logh;
is_tree = ist;
is_wall = isw;
//draw();
}
@ -19,49 +23,36 @@ class Log {
if (sawed) {
logcolor = color(128, 88, 60);
if (a > -90) a = a - 1;
if (a == -90) render_log = false;
} else if (is_wall) {
logcolor = color(0, 0, 0);
} else {
logcolor = color(133, 79, 51);
}
stroke(strokecolor); // Set stroke color for the log
strokeWeight(1); // Set stroke weight for the log
fill(logcolor); // Set fill color for the log
rect(x, y, logwidth, logheight); // Draw the log as a rectangle
text(logtext, x, y);
strokeWeight(1);
stroke(0);
if (render_log) {
pushMatrix();
translate(x, y);
rotate(radians(a));
stroke(strokecolor); // Set stroke color for the log
strokeWeight(1); // Set stroke weight for the log
fill(logcolor); // Set fill color for the log
rect(0, 0, logwidth, -logheight); // Draw the log as a rectangle
text(logtext, x, y);
strokeWeight(1);
stroke(0);
if(is_tree) {
color bushes = color(107, 117, 48);
fill(bushes);
ellipse(x+logwidth/2, y+5, 170*0.3, 160*0.3);
// Bush
if(is_tree) {
color bushes = color(107, 117, 48);
fill(bushes);
ellipse(0 + logwidth/2, 0 - logheight, 170*0.3, 160*0.3);
}
popMatrix();
}
}
void logCollide(Ship ship) {
if(sawed == false) {
if(ship.newX+10 > x && ship.newX-10 < x + logwidth && ship.newY+10 > y && ship.newY-10 < y + logheight) {
ship.colliding = true;
}
}
}
void draw() {
drawLog(4);
logCollide(ship_zero);
}
}
}
// class Tree extends Log {
// Tree (float x, float y, float logw, float logh, boolean hasC) {
// super(x, y, logw, logh, hasC);
// }
// void draw() {
// color treecolor = color(133, 79, 51);
// // rectMode(CENTER);
// drawLog(1);
// }
// }

View File

@ -22,8 +22,12 @@ class MainMenu extends Menus {
fill(100, 100, 100);
if(drawRectWithMouseColission(x, y, w, h) && mousePressed) {
ismenu = false;
ispause = false;
isgame = true;
}
fill(0);
textAlign(CENTER, CENTER);
textSize(32);
text("Play", x, y);
}
@ -33,6 +37,9 @@ class MainMenu extends Menus {
ismenu = false;
isstats = true;
}
fill(0);
textAlign(CENTER, CENTER);
textSize(32);
text("Stats", x, y);
}
@ -41,6 +48,10 @@ class MainMenu extends Menus {
// color maincolor = color(100, 100, 100);
playButton(300, 300, 150, 50);
statsButton(300, 400, 150, 50);
textSize(100);
textAlign(CENTER, CENTER);
text("Save Bob", 300, 200);
}
void draw() {
@ -50,6 +61,8 @@ class MainMenu extends Menus {
class Stats extends Menus {
int trees_sawed = 0;
int best_game_time = 0;
int game_time = 0;
void menuButton() {
fill(100, 100, 100);
@ -59,23 +72,30 @@ class Stats extends Menus {
isstats = false;
}
fill(0);
textSize(32);
textAlign(CENTER, CENTER);
text("Main Menu", 300, 300);
}
void draw() {
background(50);
menuButton();
String trees = "Trees Sawed: ", trees_sawed;
text("Best Game Time", 50, 50);
text(trees , 50, 70);
text("Insgesamt Spielzeit", 50, 90);
textAlign(LEFT);
textSize(24);
text("Best Game Time", 100, 50);
text(best_game_time, 500, 50);
text("Trees Sawed: " , 100, 70);
text(trees_sawed, 500, 70);
text("Insgesamt Spielzeit", 100, 90);
text(game_time, 500, 90);
}
}
class StopWatchTimer {
int startTime = 0, stopTime = 0;
int startTime = 0, stopTime = 0, pauseTime = 0;
boolean running = false;
boolean pause = false;
void start() {
@ -86,6 +106,19 @@ class StopWatchTimer {
stopTime = millis();
running = false;
}
void pause_start() {
if (!pause) {
pauseTime = millis();
pause = true;
}
}
void resume() {
if (pause) {
startTime = startTime + (millis() - pauseTime);
pauseTime = 0;
pause = false;
}
}
int getElapsedTime() {
int elapsed;
if (running) {

17
readme.org Normal file
View File

@ -0,0 +1,17 @@
** Ingame
*** DONE Level mit 2 Bereichen. Erster Bereich Straße und Kettensäge und End/Startpunkt. Zweiter Bereich Wald und Bob
*** DONE Robi muss noch beschleunigen können
*** TODO Wir brauchen Geräusche
*** DONE setze bob auf den Robi
*** TODO Richtige Texte am Anfang zum erklären
*** TODO Abprallen nicht machen, wenn newx nicht erreicht sein kann, sondern wenn Robi tatsächlich die Wand berührt
*** TODO Roboter muss abprallen, kaputt gehen
*** BUG sometimes a log gets stuck in sawed = false state
** Menu
*** DONE Statistikseite: Spielzeit, Bäume gefällt, Zeit gestoppt
*** DONE Richtige Texte im Menu
*** DONE File loading and saving
Wird noch nicht benutzt
*** DONE nochmal die statistikseite überarbeiten
**** DONE Math for best_game_time
**** TODO Why doesnt bestgametime work

5
saves/save.json Normal file
View File

@ -0,0 +1,5 @@
[
0,
13,
205455
]

154
ship.pde
View File

@ -1,22 +1,26 @@
// Roboter muss abprallen, kaputt gehen
// TODO Abprallen nicht machen, wenn newx nicht erreicht sein kann, sondern wenn Robi tatsächlich die Wand berührt
class Ship {
float x, y, a;
// Movement
PVector pos = new PVector(-width/2, height/2); // position
PVector speed = new PVector(0, 0); // The speed of movement
PVector acceleration = new PVector();
float a; // angle
// For the collision
PVector newPos = new PVector(width/2, height/2);
float newX, newY;
boolean colliding = false;
boolean colliding2 = false;
boolean colliding_logs = false;
boolean hasSaw = false;
float rotationSpeed = 4; // The speed of rotation
float movementSpeed = 2; // The speed of movement
int nextLog;
int health = 3;
Ship() {
x = width / 2;
y = height / 2;
a = -90;
// pos.x = width/2;
// pos.y = height/2;
a = 0;
newX = width/2;
newY = height/2;
}
@ -25,7 +29,9 @@ class Ship {
nextLog = returnIndexOfNearestLog();
logCollide(logs);
// logCollide(trees);
logCollide(walls);
sawIndicator();
simulate();
render();
@ -36,18 +42,18 @@ class Ship {
exit();
}
colliding2 = false;
colliding_logs = false;
}
void sawIndicator() {
if (hasSaw) {
if (checkDistance(logs[nextLog], ship_zero) < 40) {
fill(204, 102, 0);
circle(x, y -20, 20);
circle(pos.x, pos.y -20, 20);
fill(0);
textSize(32);
textAlign(CENTER, CENTER);
text("s", x, y - 27);
text("s", pos.x, pos.y - 27);
}
}
}
@ -56,87 +62,105 @@ class Ship {
float shortest_distance_log_distance = checkDistance(logs[0], ship_zero);
int shortest_distance_log = 0;
for(int i = 0; i < logs.length; i++) {
if(checkDistance(logs[i], ship_zero) < shortest_distance_log_distance) {
shortest_distance_log = i;
shortest_distance_log_distance = checkDistance(logs[i], ship_zero);
// only logs that are not sawed already
if (!logs[i].sawed) {
if(checkDistance(logs[i], ship_zero) < shortest_distance_log_distance) {
shortest_distance_log = i;
shortest_distance_log_distance = checkDistance(logs[i], ship_zero);
}
}
}
return shortest_distance_log;
}
void simulate() {
if(newX > 0 && newX < width && newY > 0 && newY < height) {
colliding = false;
} else {
colliding = true;
}
// First do the Math but dont move something
// Rotate PLayer
if (ROTATEL) {
a -= rotationSpeed;
a -= 0.03;
}
if (ROTATER) {
a += rotationSpeed;
a += 0.03;
}
PVector direction = new PVector();
direction.x = cos(a);
direction.y = sin(a);
direction.mult(0.07);
if (NORTH) {
newX = x + cos(radians(a)) * movementSpeed;
newY = y + sin(radians(a)) * movementSpeed;
// Check if the new position is within the bounds of the screen
if(colliding == false && colliding2 == false) {
x = newX;
y = newY;
} else {
float richtungX = x-newX;
float richtungY = y-newY;
x = (7*richtungX) + x;
y = (7*richtungY) + y;
health = health - 1;
}
} else if (SOUTH) {
newX = x - cos(radians(a)) * movementSpeed;
newY = y - sin(radians(a)) * movementSpeed;
// Check if the new position is within the bounds of the screen
if(colliding == false && colliding2 == false) {
x = newX;
y = newY;
} //else {
// x = newX - x;
// y = newY - y;
//}
acceleration = direction;
// add speed if pressing NORTH
if(NORTH) {
speed.add(acceleration);
speed.limit(1.3);
} else { // decrease it if not
speed.mult(0.95);
}
// Check new pos
newPos = pos.add(speed);
// Collide with outside walls
if( newPos.x > width || newPos.y < 0 || newPos.y > height) {
colliding = true;
// println("collide");
} else {
colliding = false;
}
// Check if the new position is within the bounds of the screen
// - Handle it more like https://processing.org/examples/circlecollision.html
if(colliding == false && colliding_logs == false) {
pos.add(speed);
} else {
speed.limit(0);
speed.sub(acceleration);
pos.add(0, 0);
pos.add(speed.mult(2));
}
// println(speed);
}
void logCollide(Log[] logs) {
for(int i = 0; i < logs.length; i++) {
if(logs[i].sawed == false) {
if (newX+10 > logs[i].x && newX-10 < logs[i].x + logs[i].logwidth && newY+10 > logs[i].y && newY-10 < logs[i].y + logs[i].logheight) {
colliding2 = true;
void logCollide(Log[] loggers) {
for(int i = 0; i < loggers.length; i++) {
if(loggers[i].sawed == false) {
if (newPos.x+10 > loggers[i].x && newPos.x-10 < loggers[i].x + loggers[i].logwidth && newPos.y+10 > loggers[i].y - loggers[i].logheight && newPos.y-10 < loggers[i].y) {
colliding_logs = true;
}
}
}
}
void collect(Collectable c) {
if (newX > c.x && newX < c.x + c.cwidth && newY > c.y && newY < c.y + c.cheight) {
if (pos.dist(c.pos) < 20) {
if (c.getClass() == Saw.class ) hasSaw = true;
c.is_attached = true;
}
}
void render() {
pushMatrix();
translate(x, y);
rotate(radians(a + 90));
translate(pos.x, pos.y);
rotate(a);
stroke(255);
noFill();
line(0, -10, 10, 10);
line(10, 10, 0, 5);
line(0, 5, -10, 10);
line(-10, 10, 0, -10);
// line(0, -10, 10, 10);
// line(10, 10, 0, 5);
// line(0, 5, -10, 10);
// line(-10, 10, 0, -10);
// triangle(- 5, - 5, - 5, 5, 10, 0);
imageMode(CENTER);
if(bob.is_attached) {
image(player_sprite_bob, 0, 0);
} else {
image(player_sprite, 0, 0);
}
if(hasSaw) {
rect(0+2, 0-45, 20, 50);
image(saw_sprite, 20, 0);
}
popMatrix();
}