Informatik Projekt

Silvan, Leonard, Elias und Elia


Spielanleitung



Spielanleitung



Tastenbedienung

Um das Spiel zu bedienen braucht man die Taste ,,Leertaste,, und zur Bedienung ins Menu oder in die Spieleinstellungen braucht man die Maus.



Spielverlauf

Beim starten einer Runde wird man direkt auf der Straße landen, wo man anfängt zu laufen. Im weiteren Spielverlauf werden verschiedene Hindernisse erscheinen die man durch Sprünge überwinden muss. Schafft man ess nicht hat man verloren und muss eine neue Runde starten.



Spielansicht

Sartseite

Wenn man das Spiel startet kommt man auf diese Seite. Hier hat man verschiedene Optionen. Man kann zum Beispiel auf die Info Box klicken wo man sieht von wem das Spiel erstellt wurde was das Ziel ist und wie man steuert Wenn man auf die Startbox klickt startet man das Spiel und um das Spiel zu verlassen klickt man auf Exit



Spielansicht

Bei der Spielansicht sieht man wie es während dem Spiel aussieht. Zu erkennen sind die Hindernisse, der Hintergrund, die Spielfigur usw.

Endansicht

Bei der Endansicht sieht man wie es aussieht wenn das Spiel vorbei ist. Man sieht einen GAME OVER Schiftzug und kann seinen Score also Punktestand sehen.



Code des Spieles

import processing.sound.*; // ----------------Variablen-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- int gState = 0; // Status des Spiels (0 = Menü, 1 = Game, 2 = Steuerung, 3 = Game Over) String spielName = "City Runner"; // Spielname int score; // Score int frameSaver; // Ein Wert dem wir Frames/Zeit zuweisen für Systeme & Animationen int x, y; // Koordinaten Spieler int hX, hY; // Koordinaten Hintergrund int spielerVersion = 0; // Variable für die Spieleranimation int spielerHoehe = 860; // Spielerhöhe (mit imageMode) int sprungkraft = int(70*1.2*1.3); // Stärke der Sprungkraft int leben; // Anzahl Leben vom Spieler (nicht veraenderbar) int lebenSet = 5; // Wie viele Leben der Spieler hat boolean kannSpringen; // Ob der Spieler wieder springen kann float schwerkraft = 0.8; // Wert zur Berechnung der Springphysik float sprungGeschwindigkeit; // Wert zur Berechnung der Springphysik float autoGroesse = 0.5; // Bildverkleinerungsfaktor vom Auto (Autobilder sind orginal zu gross) // Bilder werden definiert PImage hintergrund, info; PImage city; PImage spieler1, spieler2; PImage coinImage; //Schriftart wird definiert PFont western; // Audios werden definiert SoundFile menu; SoundFile game; SoundFile jumpS, damageS, coinS; // Auto Variablen float autoFrameAbstand = 90; // Abstand zwischen den Autos in Frames float autoWahrscheinlichkeit = 70; // wahrscheinlichkeit in prozent ob ein auto erschaffen wird float autoGeschwindigkeitsFaktor = 1.0;// auto geschwindigkeit auf der x-achse ArrayList alleGegner = new ArrayList(); // liste von allen gegnern ArrayList autos = new ArrayList(); // liste von allen autobildern -> verschiedene farben & formen ArrayList coins = new ArrayList(); // liste aller coins/münzen // --------------------------Setup & Continous Mode---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- void setup() { background(#FFFFFF); // alles wird geleert / neugeladen fullScreen(); // vollbild /************** Bilder werden geladen ***************/ hintergrund = loadImage("./bilder/hintergrund.jpg"); hintergrund.resize(width, height); // hintergrund wird verkleinert info = loadImage("./bilder/info.png"); // erklärungsbild wird geladen info.resize(width, height); // erklärungsbild wird vergrössert spieler1 = loadImage("./bilder/spieler1.png"); spieler2 = loadImage("./bilder/spieler2.png"); coinImage = loadImage("./bilder/coin.png"); coinImage.resize(60, 60); city = loadImage("./bilder/city.png"); /************** Schriftart wird geladen ***************/ western = createFont("./schriftarten/western.ttf", 30); /************** Audios werden geladen ***************/ menu = new SoundFile(this, "./sounds/menu.wav"); game = new SoundFile(this, "./sounds/game.wav"); jumpS = new SoundFile(this, "./sounds/jump.wav"); coinS = new SoundFile(this, "./sounds/coin.wav"); damageS = new SoundFile(this, "./sounds/damage.wav"); // 10 verschiedene Auto Elemente werden geladen und in eine Liste gepackt for (int i = 1; i <= 10; i++) { // For-Loop mit 10 Durchläufen, der bei 1 startet PImage geladenesbild = loadImage("./bilder/cars/" + i + ".png"); // Bild wird geladen mit aktuellem i Wert geladenesbild.resize(int(geladenesbild.width*autoGroesse), int(geladenesbild.height*autoGroesse)); // Auto wird verkleinert -> wäre sonst zu gross autos.add(geladenesbild); // auto wird zur liste hinzugefügt } // Alle Elemente werden das erste mal ins Fenster geladen (Menü) drawFrame(true); } void draw() { drawFrame(false); // Alle Elemente werden jeden Frame/Tick geladen } void keyPressed() { // spieler springt, wenn er Springen kann if (key == ' ' && kannSpringen) { spielerSpringen(); jumpS.play(); // springsound wird abgespielt } } void mousePressed() { if (gState != 0) return; // Falls nicht das Menü aktiv ist soll nichts passieren if (mouseX > 240 && mouseX < 640 && mouseY > 530 && mouseY < 890) { // falls der erste button [INFO] gedrückt wird gState = 2; // spielstatus auf Steuerung/Erklärungsscreen gestellt drawFrame(true); // elemente werden geladen } if (mouseX > 240+490 && mouseX < 640+490 && mouseY > 530 && mouseY < 890) { // falls der zweite button [START] gedrückt wird gState = 1; // spielstatus auf Spiel gestellt startTheGame(); // spiel wird gestartet drawFrame(true); // elemente werden geladen } if (mouseX > 240+490*2 && mouseX < 640+490*2 && mouseY > 530 && mouseY < 890) { // falls der dritte button [EXIT] gedrückt wird exit(); // spiel geschlossen } } /******************************************************* Diese Funktion ladet alle Elemente berechnet/macht die Systeme/Funktionen/Kommandos boolean ersteMal ist einfach nur ein wahrheitswert für ob diese funktion das erste mal im state ausgeführt wird -> startwerte setzen würde dieser boolean nicht existieren würden jedes mal alle werte ersetzt ********************************************************/ void drawFrame(boolean erstesMal) { if (gState == 0) {// menü { if (erstesMal) { // falls das Menü das erste mal geladen wird / am Anfang menu.play(); // menü-Musik wird abgespielt und gelooped menu.loop(); } // Hintergrundbild wird angezeigt imageMode(CORNER); image(hintergrund, 0, 0); erstelleMenu(); // Menü wird gezeichnet (Knöpfe, Boxen) score = 0; // Score wird zurückgesetzt } else if (gState == 1) { // game if (erstesMal) { // falls das spiel das erste mal geladen wird / am Anfang startTheGame(); // spielstart funktion menu.stop(); // menümusik wird gestoppt } gameFrame(); // spielfunktionen & bilder werden jedes frame geladen } else if (gState == 2) {// informationen / erklärungsscreen if (erstesMal) { // falls das spiel das erste mal geladen wird frameSaver=frameCount; // aktuelle zeit wird gespeichert } image(info, 0, 0); // erklröungsbild wird geladen if (frameSaver/30f + 13 < frameCount/30f) { // sobald die gespeicherte zeit + 13 kleiner ist als die aktuelle zeit wird wieder das menü geladen gState = 0; } } else if (gState==3) {// 3 Game Over { if (erstesMal) { // falls das spiel das erste mal geladen wird menu.play(); // menü musik wird abgespielt menu.loop(); // menü musik wird gelooped } erstelleGameOver(); // der gameover screen wird geladen } } // ----------------------Spielstart & Frames------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ void startTheGame() { hX = 0; // hintergrund Koordinate X wird zurückgesetzt hY = 0; // hintergrund Koordinate Y wird zurückgesetzt x = 1000; // spieler X-Koordinate wird zurückgesetzt y= 800; // spieler Y-Koordinate wird zurückgesetzt leben=lebenSet; // spielerleben wird auf lebenSet zurückgesetzt score = 0; // score wird zurückgesetzt kannSpringen = true; // spieler kann ab jetzt springen autoGeschwindigkeitsFaktor = 1.5; // spielgeschwindigkeit auf 1.5 alleGegner.clear(); // alle Gegner falls noch von letzer Runde da, werden gelöscht sprungGeschwindigkeit = 0; // sprunggeschwindigkeit / aktuelle spieler gravition wird zurückgesetzt game.play(); // spielmusik gestartet game.loop(); // spielmusik wrid gelooped menu.stop(); // gamemusik wird gestoppt } void gameFrame() { // Der Hintergrund wird hier gezeichnet imageMode(CORNER); image(city, hX, hY); image(city, hX+city.width, hY); image(city, hX-city.width, hY); // Hintergrund wird um -5 immer nach links geschoben hX-=5; // Falls der Hintergrund aus dem Bild gehen sollte wird er wieder nach rechts geschoben, so entsteht dieses endlessrunner Gefühl if (hX<=0)hX+=city.width; // Spielerbild Animation wird erstellt spielerVersion++; if (spielerVersion == 21) spielerVersion = 0; // Je nach dem Wert spielerVerison, der immer um 1 grösser wird, wird das erste oder zweite Spielerbild angezeigt, so entsteht eine Animation imageMode(CENTER); if (spielerVersion <= 10) { // spielerVersion kleiner gleich 10 dann spieler Bild Nummer 1 image(spieler1, x, y); } else image(spieler2, x, y); // Wenn nicht dann spielerbild nummer 2 int tY = 75; strokeWeight(5); stroke(255, 0, 0); line(x-50, y-tY, x-50+120, y-tY); stroke(0, 255, 0); int laenge = int(parseFloat(leben)/parseFloat(lebenSet)*120f); line(x-50, y-tY, x-50+laenge, y-tY); strokeWeight(1); spielerBewegen(); // Spieler Spring Animation if (y >= spielerHoehe - spieler1.height/2) { // Falls der spieler wieder sich auf dem boden befindet, wird spielerZuereckAufBoden(); ausgeführt spielerZuereckAufBoden(); } if (frameCount % int(autoFrameAbstand) == 0 && random(0, 100) <= autoWahrscheinlichkeit) { // Alle x (anzahlAutosProFrameRate*60) Frames wird mit einer x Wahrscheinlichkeit (autoWahrscheinlichkeit) ein Auto erschaffen PImage pimage = autos.get(int(random(1, 10))); // Ein zufälliges Autobild wird ausgewählt Gegner autoGegner = new Gegner(width+300, spielerHoehe-pimage.height/2, pimage); // Der Gegner (Auto) wird erstellt mti den Werten x, y, img alleGegner.add(autoGegner); // Das Auto wird zur Liste hinzugefügt } if (frameCount % 300 == 0) { // Alle 300 Frames wird das Game schnelelr autoGeschwindigkeitsFaktor+=0.2; } if (frameCount % 180 == 0) { // Alle 180 Frames wird eine Münz eer erstellt coins.add(new Coin(width+200, spielerHoehe-coinImage.height/2)); } for (int b = 0; b < alleGegner.size(); b++) { // hier loopen wir durch die liste alle gegner / schauen uns jedes einzelne element der gegnerliste an Gegner autoGegner = alleGegner.get(b); // aktuell ausgewählte gegnerelement // Gegnerbild wird angezgeigt imageMode(CENTER); image(autoGegner.img, autoGegner.x, autoGegner.y); // Gegner wird bewegt (mit autoGegner.speed) autoGegner.x-=autoGegner.speed; if (autoGegner.x < 0) alleGegner.remove(autoGegner); // falls das auto nicht mehr im fensterbereich ist wird es gelöscht boolean beruehertXUntenRechts = x+spieler1.width/2 >= autoGegner.x-autoGegner.img.width/2 && x+spieler1.width/2 <= autoGegner.x+autoGegner.img.width/2; // Ob die X Koordinate an der oberen ecke vom Spieler im Auto ist boolean beruehertXUntenLinks = x-spieler1.width/2 >= autoGegner.x-autoGegner.img.width/2 && x-spieler1.width/2 <= autoGegner.x+autoGegner.img.width/2; // Ob die X Koordinate an der unteren ecke vom spieler im auto ist boolean beruehertY = y+spieler1.height/2 >= autoGegner.y-autoGegner.img.height/2 && y+spieler1.height/2 <= autoGegner.y+autoGegner.img.height/2; // ob der spieler auf gleicher höhe wie das auto ist if (beruehertY && (beruehertXUntenRechts || beruehertXUntenLinks)) { // falls also nun der spieler das auto berührt autoGegner.spielertouch(); // die touch funktion wird ausgeführt alleGegner.remove(autoGegner); // der gegner wird gelöscht } } for (int i = 0; i < coins.size(); i++) { // hier loopen wir auch nochmal durch die coins liste Coin c = coins.get(i); // aktuelle coin c.display(); // coin wird angezeigt / gezeichnet // hier überprüfen wir wieder ob der spieler den coin berührt boolean beruehertXUntenRechts = x+spieler1.width/2 >= c.x-coinImage.width/2 && x+spieler1.width/2 <= c.x+coinImage.width/2; boolean beruehertXUntenLinks = x-spieler1.width/2 >= c.x-coinImage.width/2 && x-spieler1.width/2 <= c.x+coinImage.width/2; boolean beruehertY = y+spieler1.height/2 >= c.y-coinImage.height/2 && y+spieler1.height/2 <= c.y+coinImage.height/2; if (beruehertY && (beruehertXUntenRechts || beruehertXUntenLinks)) c.spielerEinsammeln(); } // die aktuelle anzahl an coins wird am oberen bildschirmrand angezeigt textAlign(LEFT); textSize(30); fill(#FFFFFF); text("Coins: " + score, 60, 60); textAlign(CENTER); } // ---------------Menü & Game Over------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- void erstelleMenu() { // Spieltitel wird angezeigt textAlign(CENTER); textFont(western); fill(255); textSize(200); text(spielName, width/2, 200); noFill(); // knopfkästen werden angezeigt rectMode(CORNER); stroke(255); fill(#000000); rect(width/8*1, height/2, 400, 350); rect(width/8*3, height/2, 400, 350); rect(width/8*5, height/2, 400, 350); // knopftexte werden angezeigt fill(#FFFFFF); textSize(90); text("INFO", 440, 730); fill(255, 0, 0); text("START", 920, 730); fill(#FFFFFF); text("EXIT", 1400, 730); } // Funktion die den Gameover screen zeichnet void erstelleGameOver() { background(0); textAlign(CENTER); textFont(western); fill(255); textSize(200); text("GAME OVER", width/2, height/2); fill(255, 0, 0); text("Score: " + score, width/2, 730); // nach 10 sekunden (nicht genau) wird wieder ins menü gewechselt if (frameSaver/30f + 10 < frameCount/30f) { gState=0; drawFrame(true); } } // --------------Systeme & Funktionen------- (Hier hatten wir Unterstützung da wir keine Ahnung von Klassen hatten) ------------------------------------------------------------------------------------------------------------------------------------------------ //https://lernprocessing.wordpress.com/2010/01/06/objekte-und-klassen/ /* GEGNER OBJEKT (AUTOS) */ class Gegner { int x, y; PImage img; int speed = 0; // Ein sogenannter Konstruktor in einer Klasse, der uns das Leben ein bisschen einfacher macht Gegner(int x, int y, PImage img) { this.x = x; this.y = y; this.img = img; this.speed = int(random(6, 8)*autoGeschwindigkeitsFaktor*1.2); } void spielertouch() { // funktion die bei Berührung ausgeführt wird if (leben-1==-1) { // falls spieler jetzt tot ist game.stop(); // gamemusik wird gestoppt gState = 3; // gameover screen wird angezeigt frameSaver=frameCount; // die aktuelle zeit wird gespeichert drawFrame(true); // alle elemente werden gezeichnet } damageS.play(); // der damagesound wird abgespielt leben--; // ein leben wird abgezgoen } } /* COIN OBJEKT */ class Coin { int x; int y; Coin(int x, int y) { this.x = x; this.y = y; } void display() { // funktion die den code zeichnet this.x-=5; // coin wird von rechts nach links verschoben um 5 werte if (this.x < 0) coins.remove(this); // coin wird gelöscht falls er nicht mehr zusehen ist / aus dem spiel geht image(coinImage, x, y); // coin wird angezeigt } void spielerEinsammeln() { // falls der spieler den coin berührt score++; // score geht um 1 höher coinS.play(); // coinsound wird abgespielt coins.remove(this); // coin wird aus der liste gelöscht } } // funktion die während der spieler springt ausgeführt wird void spielerBewegen() { y += sprungGeschwindigkeit; // spieler koordinate wird mit der sprungGeschwindigkeit addiert sprungGeschwindigkeit += schwerkraft; // die sprunggeschwindigkeit wird mit der schwerkraft addiert sprungGeschwindigkeit = constrain(sprungGeschwindigkeit, -12, 12); // die geschwindigkeit wird auf einen bereich zwischen -12 und 12 begrenzt } void spielerSpringen() { sprungGeschwindigkeit = -sprungkraft; // wenn die sprungtaste gedrückt wird geht die sprungeschwindigkeit um -.. hoch kannSpringen = false; // Spieler kann nicht erneut springen, bis er den Boden erreicht hat } void spielerZuereckAufBoden() y = spielerHoehe - spieler1.height/2; // spieler y wert wird korrigiert sprungGeschwindigkeit = 0; // // sprungeschwindigkeit wird auf 0 gesetzt kannSpringen = true; // Spieler kann erneut springen, da er den Boden erreicht hat

City Runner