Browse Source

Weltweiter bestscore und Spielwiederhohlung ansehen ist jetzt verfügbar

Kolja Strohm 6 years ago
parent
commit
b211ee4b91
8 changed files with 697 additions and 203 deletions
  1. 14 3
      Fangen/Game.cpp
  2. 2 0
      Fangen/Game.h
  3. 180 78
      Fangen/Map.cpp
  4. 11 4
      Fangen/Map.h
  5. 347 14
      Fangen/Menü.cpp
  6. 41 3
      Fangen/Menü.h
  7. 99 99
      Fangen/Spieler.cpp
  8. 3 2
      Fangen/Spieler.h

+ 14 - 3
Fangen/Game.cpp

@@ -1,5 +1,6 @@
 #include "Game.h"
 #include <Bild.h>
+#include "../../../Include/KSGKlientV.h"
 
 // Inhalt der Game Klasse aus Game.h
 // Konstruktor
@@ -9,12 +10,15 @@ Game::Game()
 	screen = 0;
 	alpha = 0;
 	menü = 0;
+    client = 0;
 	ref = 1;
 }
 
 // Destruktor
 Game::~Game()
 {
+    if( client )
+        client->release();
 	if( schrift )
 		schrift->release();
 	if( screen )
@@ -29,6 +33,13 @@ bool Game::laden()
 	return 1;
 }
 
+void Game::setMinigameClientZ( MinigameKlientV *client )
+{
+    if( this->client )
+        this->client->release();
+    this->client = client;
+}
+
 void Game::doMausEreignis( MausEreignis &me )
 {
 	if( menü )
@@ -73,15 +84,15 @@ void Game::render( Bild &zRObj )
 void Game::setSchriftZ( Schrift *schrift )
 {
 	this->schrift = schrift;
-	if( !menü && this->schrift && screen )
-		menü = new Menü( schrift, screen );
+    if( !menü && this->schrift && screen )
+        menü = new Menü( schrift, screen, client->getThis() );
 }
 
 void Game::setBildschirmZ( Bildschirm *screen )
 {
 	this->screen = screen;
 	if( !menü && schrift && screen )
-		menü = new Menü( schrift, screen );
+		menü = new Menü( schrift, screen, client->getThis() );
 }
 
 // constant

+ 2 - 0
Fangen/Game.h

@@ -10,6 +10,7 @@ private:
 	Schrift *schrift;
 	Bildschirm *screen;
 	Menü *menü;
+    MinigameKlientV *client;
 	int alpha;
 	int ref;
 
@@ -20,6 +21,7 @@ public:
 	~Game();
 	// nicht constant
 	virtual bool laden() override;
+    virtual void setMinigameClientZ( MinigameKlientV *client ) override;
 	virtual void doMausEreignis( MausEreignis &me ) override;
 	virtual void doTastaturEreignis( TastaturEreignis &te ) override;
 	virtual bool tick( double zeit ) override;

+ 180 - 78
Fangen/Map.cpp

@@ -4,11 +4,13 @@
 #include <Text.h>
 #include <Zeit.h>
 #include <KSGTDatei.h>
+#include <AsynchronCall.h>
 
 // Inhalt der Map Klasse aus Map.h
 // Konstruktor
-Map::Map()
+Map::Map( MinigameKlientV *klient )
 {
+    this->klient = klient;
 	gegner = new RCArray< Spieler >();
 	ziele = new RCArray< Spieler >();
 	spieler = 0;
@@ -21,7 +23,9 @@ Map::Map()
 	map->setPosition( 10, 10 );
 	map->setSize( 200, 200 );
 	beendet = 1;
-	sr = 1;
+    gameTime = 0;
+    tastenStände = 0;
+    rGen = 0;
 	ref = 1;
 }
 
@@ -36,11 +40,19 @@ Map::~Map()
 	feld->release();
 	kam->release();
 	map->release();
+    if( rGen )
+        rGen->release();
+    if( klient )
+        klient->release();
 }
 
 // nicht constant
-void Map::reset()
+void Map::reset( Text *zOptionen )
 {
+    gameTime = 0;
+    tastenStände = 0;
+    if( rGen )
+        rGen = rGen->release();
 	beendet = 0;
 	score = 0;
 	gegner->leeren();
@@ -48,54 +60,46 @@ void Map::reset()
 	if( spieler )
 		spieler = spieler->release();
 	ziele->leeren();
-	InitDatei *opd = new InitDatei( "data/Minigames/Fangen/data/optionen.ini" );
-	if( !opd->laden() )
-		DateiPfadErstellen( "data/Minigames/Fangen/data/optionen.ini" );
-	breite = 800;
-	if( opd->wertExistiert( "Breite" ) )
-		breite = (int)*opd->zWert( "Breite" );
-	else
-		opd->addWert( "Breite", "800" );
-	höhe = 500;
-	if( opd->wertExistiert( "Höhe" ) )
-		höhe = (int)*opd->zWert( "Höhe" );
-	else
-		opd->addWert( "Höhe", "500" );
-	zAnzahl = 1;
-	if( opd->wertExistiert( "Ziele" ) )
-		zAnzahl = (int)*opd->zWert( "Ziele" );
-	else
-		opd->addWert( "Ziele", "1" );
-	neuGegner = 3;
-	if( opd->wertExistiert( "+Gegner" ) )
-		neuGegner = (int)*opd->zWert( "+Gegner" );
-	else
-		opd->addWert( "+Gegner", "3" );
-	geschwindigkeit = 1000;
-	if( opd->wertExistiert( "Geschwindigkeit" ) )
-		geschwindigkeit = (int)*opd->zWert( "Geschwindigkeit" );
-	else
-		opd->addWert( "Geschwindigkeit", "1000" );
-	bool fortsetzen = 0;
-	if( opd->wertExistiert( "Fortsetzen" ) )
-		fortsetzen = (int)*opd->zWert( "Fortsetzen" ) != 0;
-	else
-		opd->addWert( "Fortsetzen", "0" );
-	opd->speichern();
-	opd->release();
+    Text *tmp = zOptionen->getTeilText( zOptionen->positionVon( '=' ) + 1, zOptionen->positionVon( ',' ) );
+    breite = *tmp;
+    tmp->release();
+    tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 1 ) + 1, zOptionen->positionVon( ',', 1 ) );
+    höhe = *tmp;
+    tmp->release();
+    tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 2 ) + 1, zOptionen->positionVon( ',', 2 ) );
+    zAnzahl = *tmp;
+    tmp->release();
+    tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 3 ) + 1, zOptionen->positionVon( ',', 3 ) );
+    neuGegner = *tmp;
+    tmp->release();
+    tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 4 ) + 1, zOptionen->positionVon( ',', 4 ) );
+    geschwindigkeit = *tmp;
+    tmp->release();
+    tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 5 ) + 1, zOptionen->positionVon( ',', 5 ) );
+    bool fortsetzen = (int)*tmp != 0;
+    tmp->release();
 	kamX = 0;
 	kamY = 0;
 	if( breite > 80 )
 		kamX = breite / 2 - 400;
 	if( höhe > 50 )
 		kamY = höhe / 2 - 250;
-	if( fortsetzen && DateiExistiert( "data/Minigames/Fangen/data/game.save" ) )
+	if( fortsetzen && DateiExistiert( "data/Minigames/Fangen/data/game.save" ) && klient )
 	{
-		Datei *save = new Datei();
+        if( capture.istOffen() )
+            capture.close();
+        capture.setDatei( "data/Minigames/Fangen/data/game.mgc" );
+        capture.open( Datei::Style::schreiben | Datei::Style::ende | Datei::Style::lesen );
+        Datei *save = new Datei();
 		save->setDatei( "data/Minigames/Fangen/data/game.save" );
 		save->open( Datei::Style::lesen );
 		int br = 0;
 		int hö = 0;
+        __int64 seed;
+        save->lese( (char*)&seed, 8 );
+        rGen = new RandomGenerator();
+        rGen->setSeed( seed );
+        save->lese( (char*)&gameTime, 8 );
 		save->lese( (char*)&br, 4 );
 		save->lese( (char*)&hö, 4 );
 		if( br == breite && hö == höhe )
@@ -113,17 +117,38 @@ void Map::reset()
 		save->close();
 		save->release();
 	}
+    else
+    {
+        rGen = new RandomGenerator();
+        if( klient )
+        {
+            if( capture.istOffen() )
+                capture.close();
+            DateiRemove( "data/Minigames/Fangen/data/game.mgc" );
+            capture.setDatei( "data/Minigames/Fangen/data/game.mgc" );
+            capture.erstellen();
+            capture.open( Datei::Style::schreiben );
+            __int64 seed = rGen->getSeed();
+            capture.schreibe( (char*)&seed, 8 );
+        }
+        else
+        {
+            tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 6 ) + 1 );
+            rGen->setSeed( (__int64)*tmp );
+            tmp->release();
+        }
+    }
 	if( !spieler )
-		spieler = new Spieler( SPIELER, breite, höhe );
+		spieler = new Spieler( SPIELER, breite, höhe, rGen );
 	if( !gegner->getEintragAnzahl() )
 	{
 		for( int i = 0; i < neuGegner; i++ )
-			gegner->add( new Spieler( GEGNER, breite, höhe ) );
+			gegner->add( new Spieler( GEGNER, breite, höhe, rGen ) );
 	}
 	if( !ziele->getEintragAnzahl() )
 	{
 		for( int i = 0; i < zAnzahl; i++ )
-			ziele->add( new Spieler( ZIEL, breite, höhe ) );
+			ziele->add( new Spieler( ZIEL, breite, höhe, rGen ) );
 	}
 }
 
@@ -134,37 +159,78 @@ void Map::doMausEreignis( MausEreignis &me )
 
 void Map::doTastaturEreignis( TastaturEreignis &te )
 {
-
+    cs.lock();
+    bool ok = 1;
+    if( !beendet )
+    {
+        char tmp = tastenStände;
+        if( te.taste == 'w' || te.taste == 'W' || te.taste == T_Oben )
+        {
+            if( te.id == TE_Press )
+                tastenStände |= 1;
+            else
+                tastenStände &= ~1;
+        }
+        if( te.taste == 'd' || te.taste == 'D' || te.taste == T_Rechts )
+        {
+            if( te.id == TE_Press )
+                tastenStände |= 2;
+            else
+                tastenStände &= ~2;
+        }
+        if( te.taste == 'a' || te.taste == 'A' || te.taste == T_Links )
+        {
+            if( te.id == TE_Press )
+                tastenStände |= 4;
+            else
+                tastenStände &= ~4;
+        }
+        if( te.taste == 's' || te.taste == 'S' || te.taste == T_Unten )
+        {
+            if( te.id == TE_Press )
+                tastenStände |= 8;
+            else
+                tastenStände &= ~8;
+        }
+        if( tmp != tastenStände && klient )
+        {
+            if( klient )
+            {
+                capture.schreibe( (char*)&gameTime, 8 );
+                capture.schreibe( &tastenStände, 1 );
+            }
+        }
+    }
+    cs.unlock();
 }
 
 bool Map::tick( double tickVal )
 {
 	if( beendet || !spieler )
 		return 0;
-	if( sr )
-		srand( (unsigned int)time( 0 ) );
-	sr = 0;
+    cs.lock();
+    gameTime += tickVal;
 	double t = tickVal * geschwindigkeit / 1000;
-	spieler->tick( t, breite, höhe );
+	spieler->tick( t, breite, höhe, tastenStände );
 	int anz = gegner->getEintragAnzahl();
 	for( int i = 0; i < anz; i++ )
 	{
-		gegner->z( i )->tick( t, breite, höhe );
+		gegner->z( i )->tick( t, breite, höhe, tastenStände );
 		if( gegner->z( i )->berührt( spieler->getX(), spieler->getY() ) )
 			beendet = 1;
 	}
 	anz = ziele->getEintragAnzahl();
 	for( int i = 0; i < anz; i++ )
 	{
-		ziele->z( i )->tick( t, breite, höhe );
+		ziele->z( i )->tick( t, breite, höhe, tastenStände );
 		if( ziele->z( i )->berührt( spieler->getX(), spieler->getY() ) )
 		{
 			score++;
 			ziele->leeren();
 			for( int i = 0; i < zAnzahl; i++ )
-				ziele->add( new Spieler( ZIEL, breite, höhe ) );
+				ziele->add( new Spieler( ZIEL, breite, höhe, rGen ) );
 			for( int i = 0; i < neuGegner; i++ )
-				gegner->add( new Spieler( GEGNER, breite, höhe ) );
+				gegner->add( new Spieler( GEGNER, breite, höhe, rGen ) );
 		}
 	}
 	if( breite > 800 )
@@ -183,8 +249,38 @@ bool Map::tick( double tickVal )
 		if( kamY + 500 > höhe )
 			kamY = höhe - 500;
 	}
-	if( beendet )
+	if( beendet && klient )
 	{
+        capture.close();
+        DateiRemove( "data/Minigames/Fangen/data/upload.mgc" );
+        DateiUmbenennen( "data/Minigames/Fangen/data/game.mgc", "data/Minigames/Fangen/data/upload.mgc" );
+        int tmpScore = score;
+        MinigameKlientV *tmpKlient = klient->getThis();
+        new AsynchronCall( [ tmpScore, tmpKlient ]()
+        {
+            InitDatei *opd = new InitDatei( "data/Minigames/Fangen/data/optionen.ini" );
+            opd->laden();
+            Text optionen = "Width=";
+            optionen += opd->zWert( "Breite" )->getText();
+            optionen += ",Height=";
+            optionen += opd->zWert( "Höhe" )->getText();
+            optionen += ",Ziele=";
+            optionen += opd->zWert( "Ziele" )->getText();
+            optionen += ",Gegner=";
+            optionen += opd->zWert( "+Gegner" )->getText();
+            optionen += ",Speed=";
+            optionen += opd->zWert( "Geschwindigkeit" )->getText();
+            opd->release();
+            int status = tmpKlient->reportEndOfGame( "Fangen", optionen, tmpScore );
+            if( status == 2 )
+            {
+                Datei d;
+                d.setDatei( "data/Minigames/Fangen/data/upload.mgc" );
+                tmpKlient->uploadGameCapture( &d );
+            }
+            DateiRemove( "data/Minigames/Fangen/data/upload.mgc" );
+            tmpKlient->release();
+        } );
 		KSGTDatei *stb = new KSGTDatei( "data/Minigames/Fangen/data/score.ksgt" );
 		if( !stb->laden() )
 			DateiPfadErstellen( "data/Minigames/Fangen/data/score.ksgt" );
@@ -216,6 +312,7 @@ bool Map::tick( double tickVal )
 		stb->release();
         DateiRemove( "data/Minigames/Fangen/data/game.save" );
 	}
+    cs.unlock();
 	return 1;
 }
 
@@ -265,34 +362,39 @@ void Map::render( Bild &zRObj )
 	}
 }
 
-// constant
-void Map::speichern() const
+void Map::speichern()
 {
-	if( !beendet && spieler )
-	{
-		Datei *d = new Datei();
-		d->setDatei( "data/Minigames/Fangen/data/game.save" );
-		d->erstellen();
-		d->open( Datei::Style::schreiben );
-		d->schreibe( (char*)&breite, 4 );
-		d->schreibe( (char*)&höhe, 4 );
-		d->schreibe( (char*)&score, 4 );
-		spieler->save( d );
-		int anz = gegner->getEintragAnzahl();
-		d->schreibe( (char*)&anz, 4 );
-		for( int i = 0; i < anz; i++ )
-			gegner->z( i )->save( d );
-		anz = ziele->getEintragAnzahl();
-		d->schreibe( (char*)&anz, 4 );
-		for( int i = 0; i < anz; i++ )
-			ziele->z( i )->save( d );
-		d->close();
-		d->release();
-	}
-	else
-		DateiRemove( "data/Minigames/Fangen/data/game.save" );
+    if( !beendet && spieler )
+    {
+        if( capture.istOffen() )
+            capture.close();
+        Datei *d = new Datei();
+        d->setDatei( "data/Minigames/Fangen/data/game.save" );
+        d->erstellen();
+        d->open( Datei::Style::schreiben );
+        __int64 seed = rGen->getSeed();
+        d->schreibe( (char*)&seed, 8 );
+        d->schreibe( (char*)&gameTime, 8 );
+        d->schreibe( (char*)&breite, 4 );
+        d->schreibe( (char*)&höhe, 4 );
+        d->schreibe( (char*)&score, 4 );
+        spieler->save( d );
+        int anz = gegner->getEintragAnzahl();
+        d->schreibe( (char*)&anz, 4 );
+        for( int i = 0; i < anz; i++ )
+            gegner->z( i )->save( d );
+        anz = ziele->getEintragAnzahl();
+        d->schreibe( (char*)&anz, 4 );
+        for( int i = 0; i < anz; i++ )
+            ziele->z( i )->save( d );
+        d->close();
+        d->release();
+    }
+    else if( klient )
+        DateiRemove( "data/Minigames/Fangen/data/game.save" );
 }
 
+// constant
 int Map::getScore() const
 {
 	return score;

+ 11 - 4
Fangen/Map.h

@@ -3,6 +3,8 @@
 
 #include <Bild.h>
 #include "Spieler.h"
+#include <Random.h>
+#include "../../../Include/KSGKlientV.h"
 
 using namespace Framework;
 
@@ -24,22 +26,27 @@ private:
 	int zAnzahl;
 	int neuGegner;
 	bool beendet;
-	bool sr;
+    double gameTime;
+    Datei capture;
+    Critical cs;
+    MinigameKlientV *klient;
+    RandomGenerator *rGen;
+    char tastenStände;
 	int ref;
 
 public:
 	// Konstruktor
-	Map();
+	Map( MinigameKlientV *klient );
 	// Destruktor
 	~Map();
 	// nicht constant
-	void reset();
+	void reset( Text *zOptionen );
 	void doMausEreignis( MausEreignis &me );
 	void doTastaturEreignis( TastaturEreignis &te );
 	bool tick( double tickVal );
 	void render( Bild &zRObj );
+    void speichern();
 	// constant
-	void speichern() const;
 	int getScore() const;
 	bool istBeendet() const;
 	// Reference Counting

+ 347 - 14
Fangen/Menü.cpp

@@ -10,6 +10,8 @@
 #include <Schrift.h>
 #include <DateiSystem.h>
 #include <Rahmen.h>
+#include <AsynchronCall.h>
+#include <Bildschirm.h>
 
 // Inhalt der MenüVerloren Klasse aus Menü.h
 // Kontruktor
@@ -83,13 +85,14 @@ Men
 
 // Inhalt der MenüSpiel Klasse aus Menü.h
 // Konstruktor
-MenüSpiel::MenüSpiel( Schrift *zSchrift, Bildschirm *zScreen )
+MenüSpiel::MenüSpiel( Schrift *zSchrift, Bildschirm *zScreen, MinigameKlientV *klient )
 {
 	scoreT = initTextFeld( 690, 10, 100, 20, zSchrift, TextFeld::Style::Text, "Score: 0" );
 	beenden = initKnopf( 690, 40, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Beenden" );
-	map = new Map();
+	map = new Map( klient );
 	verloren = new MenüVerloren( zSchrift );
 	beendet = 0;
+    timePuffer = 0;
 	ref = 1;
 }
 
@@ -105,7 +108,62 @@ Men
 // nicht constant
 void MenüSpiel::reset()
 {
-	map->reset();
+    InitDatei *opd = new InitDatei( "data/Minigames/Fangen/data/optionen.ini" );
+    if( !opd->laden() )
+        DateiPfadErstellen( "data/Minigames/Fangen/data/optionen.ini" );
+    Text optionen = "Width=";
+    if( opd->wertExistiert( "Breite" ) )
+        optionen += (int)*opd->zWert( "Breite" );
+    else
+    {
+        opd->addWert( "Breite", "800" );
+        optionen += 800;
+    }
+    optionen += ",Height=";
+    if( opd->wertExistiert( "Höhe" ) )
+        optionen += (int)*opd->zWert( "Höhe" );
+    else
+    {
+        opd->addWert( "Höhe", "500" );
+        optionen += 500;
+    }
+    optionen += ",Ziele=";
+    if( opd->wertExistiert( "Ziele" ) )
+        optionen += (int)*opd->zWert( "Ziele" );
+    else
+    {
+        opd->addWert( "Ziele", "1" );
+        optionen += 1;
+    }
+    optionen += ",Gegner=";
+    if( opd->wertExistiert( "+Gegner" ) )
+        optionen += (int)*opd->zWert( "+Gegner" );
+    else
+    {
+        opd->addWert( "+Gegner", "3" );
+        optionen += 3;
+    }
+    optionen += ",Speed=";
+    if( opd->wertExistiert( "Geschwindigkeit" ) )
+        optionen += (int)*opd->zWert( "Geschwindigkeit" );
+    else
+    {
+        opd->addWert( "Geschwindigkeit", "1000" );
+        optionen += 1000;
+    }
+    bool fortsetzen = 0;
+    optionen += ",Fortsetzen=";
+    if( opd->wertExistiert( "Fortsetzen" ) )
+        optionen += (int)*opd->zWert( "Fortsetzen" ) != 0;
+    else
+    {
+        opd->addWert( "Fortsetzen", "0" );
+        optionen += 0;
+    }
+    opd->speichern();
+    opd->release();
+    optionen += ",Seed=0";
+	map->reset( &optionen );
 	beendet = 0;
 	scoreT->setText( "Score: " );
 	scoreT->zText()->append( map->getScore() );
@@ -146,8 +204,13 @@ void Men
 
 bool MenüSpiel::tick( double tickVal )
 {
+    timePuffer += tickVal;
 	bool ret = beenden->tick( tickVal );
-	ret |= map->tick( tickVal );
+    while( timePuffer >= 0.01 )
+    {
+        ret |= map->tick( 0.01 );
+        timePuffer -= 0.01;
+    }
 	scoreT->setText( "Score: " );
 	scoreT->zText()->append( map->getScore() );
 	if( map->istBeendet() )
@@ -186,17 +249,155 @@ Men
 }
 
 
+// Inhalt der MenüWiederhohlung Klasse
+// Konstruktor
+MenüWiederhohlung::MenüWiederhohlung( Schrift *zSchrift, Bildschirm *zScreen, Datei *datei, Text *zOptionen )
+{
+    scoreT = initTextFeld( 690, 10, 100, 20, zSchrift, TextFeld::Style::Text, "Score: 0" );
+    beenden = initKnopf( 690, 40, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Beenden" );
+    this->datei = datei;
+    if( !datei->istOffen() )
+        datei->open( Datei::Style::lesen );
+    __int64 seed;
+    datei->lese( (char*)&seed, 8 );
+    zOptionen->append( ",Fortsetzen=0,Seed=" );
+    zOptionen->append( seed );
+    map = new Map( 0 );
+    map->reset( zOptionen );
+    beendet = 0;
+    nowTime = 0;
+    nextTime = 0;
+    tastenStände = 0;
+    datei->lese( (char*)&nextTime, 8 );
+    timePuffer = 0;
+    ref = 1;
+}
+
+// Destruktor
+MenüWiederhohlung::~MenüWiederhohlung()
+{
+    scoreT->release();
+    beenden->release();
+    map->release();
+    datei->close();
+    datei->release();
+}
+
+// nicht constant
+void MenüWiederhohlung::doMausEreignis( MausEreignis &me )
+{
+    bool vera = me.verarbeitet;
+    beenden->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        beendet = 1;
+    if( map->istBeendet() )
+        beendet = 1;
+}
+
+void MenüWiederhohlung::doTastaturEreignis( TastaturEreignis &te )
+{}
+
+bool MenüWiederhohlung::tick( double tickVal )
+{
+    bool ret = beenden->tick( tickVal );
+    // TODO Replay Activity
+    while( nextTime >= 0 && nowTime + tickVal >= nextTime )
+    {
+        while( nowTime < nextTime )
+        {
+            ret |= map->tick( 0.01 );
+            tickVal -= 0.01;
+            nowTime += 0.01;
+        }
+        char aktion;
+        datei->lese( &aktion, 1 );
+        if( datei->istEnde() )
+            nextTime = -1;
+        else
+            datei->lese( (char*)&nextTime, 8 );
+        TastaturEreignis te;
+        te.verarbeitet = 0;
+        if( aktion != tastenStände )
+        {
+            if( ( aktion & ~1 ) == ( tastenStände & ~1 ) )
+            {
+                te.taste = T_Oben;
+                te.id = ( ( aktion | 1 ) == aktion ) ? TE_Press : TE_Release;
+            }
+            if( ( aktion & ~2 ) == ( tastenStände & ~2 ) )
+            {
+                te.taste = T_Rechts;
+                te.id = ( ( aktion | 2 ) == aktion ) ? TE_Press : TE_Release;
+            }
+            if( ( aktion & ~4 ) == ( tastenStände & ~4 ) )
+            {
+                te.taste = T_Links;
+                te.id = ( ( aktion | 4 ) == aktion ) ? TE_Press : TE_Release;
+            }
+            if( ( aktion & ~8 ) == ( tastenStände & ~8 ) )
+            {
+                te.taste = T_Unten;
+                te.id = ( ( aktion | 8 ) == aktion ) ? TE_Press : TE_Release;
+            }
+            tastenStände = aktion;
+        }
+        map->doTastaturEreignis( te );
+    }
+    timePuffer += tickVal;
+    while( timePuffer > 0 )
+    {
+        ret |= map->tick( 0.01 );
+        nowTime += 0.01;
+        timePuffer -= 0.01;
+    }
+    scoreT->setText( "Score: " );
+    scoreT->zText()->append( map->getScore() );
+    return ret;
+}
+
+void MenüWiederhohlung::render( Bild &zRObj )
+{
+    map->render( zRObj );
+    scoreT->render( zRObj );
+    beenden->render( zRObj );
+}
+
+// constant
+bool MenüWiederhohlung::istBeendet() const
+{
+    return beendet;
+}
+
+// Reference Counting
+MenüWiederhohlung *MenüWiederhohlung::getThis()
+{
+    ref++;
+    return this;
+}
+
+MenüWiederhohlung *MenüWiederhohlung::release()
+{
+    if( !--ref )
+        delete this;
+    return 0;
+}
+
+
 // Inhalt der MenüStatistik Klasse aus Menü.h
 // Konstruktor
-MenüStatistik::MenüStatistik( Schrift *zSchrift, Bildschirm *zScreen )
+MenüStatistik::MenüStatistik( Schrift *zSchrift, Bildschirm *zScreen, MinigameKlientV *klient )
 {
+    this->klient = klient;
+    wiederH = 0;
+    screen = zScreen->getThis();
 	ansichtT = initTextFeld( 245, 10, 50, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, "Ansicht:" );
 	ansicht = initAuswahlBox( 295, 10, 120, 20, zSchrift, AuswahlBox::Style::Normal | AuswahlBox::Style::Hintergrund, { "Tabelle", "Diagramm" } );
 	optionen = initKontrollKnopf( 425, 10, 130, 20, zSchrift, KontrollKnopf::Style::Normal, "Optionen beachten" );
-	gesammtT = initObjTabelle( 115, 40, 570, 420, zSchrift, ObjTabelle::Style::normal, { { "Score", 70, 0, 0 }, { "Datum", 145, 0, 0 }, { "Breite", 70, 0, 0 }, { "Höhe", 70, 0, 0 }, { "Ziele", 70, 0, 0 }, { "+Gegner", 70, 0, 0 }, { "Tempo", 70, 0, 0 } }, 20 );
-	optionenT = initObjTabelle( 115, 40, 570, 420, zSchrift, ObjTabelle::Style::normal, { { "Score", 70, 0, 0 }, { "Datum", 145, 0, 0 }, { "Breite", 70, 0, 0 }, { "Höhe", 70, 0, 0 }, { "Ziele", 70, 0, 0 }, { "+Gegner", 70, 0, 0 }, { "Tempo", 70, 0, 0 } }, 20 );
-	gesammtD = initLinienDiagramm( 100, 40, 600, 420, zSchrift, LDiag::Style::DatenRahmen, 0 );
-	optionenD = initLinienDiagramm( 100, 40, 600, 420, zSchrift, LDiag::Style::DatenRahmen, 0 );
+    worldBestT = initObjTabelle( 115, 40, 570, 120, zSchrift, ObjTabelle::Style::normal | ObjTabelle::Style::VScroll, { { "Score", 60, 0, 0 },{ "Spieler", 100, 0, 0 },{ "Ansehen", 55, 0, 0 },{ "Breite", 70, 0, 0 },{ "Höhe", 70, 0, 0 },{ "Ziele", 70, 0, 0 },{ "+Gegner", 60, 0, 0 },{ "Tempo", 65, 0, 0 } }, 20 );
+    gesammtT = initObjTabelle( 115, 170, 570, 290, zSchrift, ObjTabelle::Style::normal | ObjTabelle::Style::VScroll, { { "Score", 70, 0, 0 }, { "Datum", 145, 0, 0 }, { "Breite", 70, 0, 0 }, { "Höhe", 70, 0, 0 }, { "Ziele", 70, 0, 0 }, { "+Gegner", 60, 0, 0 }, { "Tempo", 65, 0, 0 } }, 20 );
+	optionenT = initObjTabelle( 115, 170, 570, 290, zSchrift, ObjTabelle::Style::normal | ObjTabelle::Style::VScroll, { { "Score", 70, 0, 0 }, { "Datum", 145, 0, 0 }, { "Breite", 70, 0, 0 }, { "Höhe", 70, 0, 0 }, { "Ziele", 70, 0, 0 }, { "+Gegner", 60, 0, 0 }, { "Tempo", 65, 0, 0 } }, 20 );
+	gesammtD = initLinienDiagramm( 100, 170, 600, 290, zSchrift, LDiag::Style::DatenRahmen, 0 );
+	optionenD = initLinienDiagramm( 100, 170, 600, 290, zSchrift, LDiag::Style::DatenRahmen, 0 );
 	zurück = initKnopf( 350, 470, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Zurück" );
 	löschen = initKnopf( 10, 470, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Zurücksetzen" );
 	schrift = zSchrift->getThis();
@@ -214,6 +415,23 @@ Men
 	}
 	for( int j = 0; j < 7; j++ )
 		( (TextFeld*)optionenT->zZeichnung( j, 0 ) )->release();
+    while( !asyncFinished )
+    {
+        Sleep( 100 );
+    }
+    anz = worldBestT->getZeilenAnzahl();
+    for( int i = 0; i < anz; i++ )
+    {
+        for( int j = 0; j < 8; j++ )
+        {
+            if( j == 2 )
+                ( (Knopf*)worldBestT->zZeichnung( j, 0 ) )->release();
+            else
+                ( (TextFeld*)worldBestT->zZeichnung( j, 0 ) )->release();
+        }
+        worldBestT->removeZeile( 0 );
+    }
+    worldBestT->release();
 	ansichtT->release();
 	ansicht->release();
 	optionen->release();
@@ -224,11 +442,17 @@ Men
 	zurück->release();
 	löschen->release();
 	schrift->release();
+    klient->release();
+    if( wiederH )
+        wiederH->release();
+    screen->release();
 }
 
 // nicht constant
 void MenüStatistik::reset()
 {
+    if( wiederH )
+        wiederH = wiederH->release();
 	int anz = gesammtT->getZeilenAnzahl();
 	for( int i = 1; i < anz; i++ )
 	{
@@ -239,6 +463,81 @@ void Men
 	anz = optionenT->getZeilenAnzahl();
 	for( int i = 1; i < anz; i++ )
 		optionenT->removeZeile( 1 );
+    anz = worldBestT->getZeilenAnzahl();
+    for( int i = 1; i < anz; i++ )
+    {
+        for( int j = 0; j < 8; j++ )
+        {
+            if( j == 2 )
+                ( (Knopf*)worldBestT->zZeichnung( j, 1 ) )->release();
+            else
+                ( (TextFeld*)worldBestT->zZeichnung( j, 1 ) )->release();
+        }
+        worldBestT->removeZeile( 1 );
+    }
+    ObjTabelle *tmpWBT = worldBestT->getThis();
+    MinigameKlientV *tmpKlient = klient->getThis();
+    Schrift *tmpSchrift = schrift->getThis();
+    new AsynchronCall( [ this, tmpWBT, tmpKlient, tmpSchrift ]()
+    {
+        Array< int > score;
+        RCArray< Text > player;
+        RCArray< Text > option;
+        int anz = tmpKlient->getMinigameBestscoreList( "Fangen", &score, &player, &option );
+        for( int i = 0; i < anz; i++ )
+        {
+            TextFeld *scoreT = initTextFeld( 0, 0, 0, 0, tmpSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, Text( score.get( i ) ) );
+            TextFeld *spielerT = initTextFeld( 0, 0, 0, 0, tmpSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, player.z( i )->getText() );
+            Text optionen = option.z( i )->getText();
+            Text *breite = optionen.getTeilText( optionen.positionVon( '=' ) + 1, optionen.positionVon( ',' ) );
+            Text *höhe = optionen.getTeilText( optionen.positionVon( '=', 1 ) + 1, optionen.positionVon( ',', 1 ) );
+            Text *ziele = optionen.getTeilText( optionen.positionVon( '=', 2 ) + 1, optionen.positionVon( ',', 2 ) );
+            Text *gegner = optionen.getTeilText( optionen.positionVon( '=', 3 ) + 1, optionen.positionVon( ',', 3 ) );
+            Text *tempo = optionen.getTeilText( optionen.positionVon( '=', 4 ) + 1 );
+            TextFeld *breiteT = initTextFeld( 0, 0, 0, 0, tmpSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, breite->getText() );
+            breite->release();
+            TextFeld *höheT = initTextFeld( 0, 0, 0, 0, tmpSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, höhe->getText() );
+            höhe->release();
+            TextFeld *zieleT = initTextFeld( 0, 0, 0, 0, tmpSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, ziele->getText() );
+            ziele->release();
+            TextFeld *gegnerT = initTextFeld( 0, 0, 0, 0, tmpSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, gegner->getText() );
+            gegner->release();
+            TextFeld *tempoT = initTextFeld( 0, 0, 0, 0, tmpSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, tempo->getText() );
+            tempo->release();
+            Knopf *ansehenK = initKnopf( 0, 0, 0, 0, tmpSchrift, Knopf::Style::Normal, "Ansehen" );
+            ansehenK->setMausEreignis( [ this, optionen ]( void *p, void *obj, MausEreignis me ) -> bool
+            {
+                if( me.id == ME_RLinks && !me.verarbeitet )
+                {
+                    ( (Knopf*)obj )->removeStyle( Knopf::Style::Erlaubt );
+                    getThis();
+                    new AsynchronCall( [ this, optionen, obj ]()
+                    {
+                        Datei *d = klient->downloadGameCapture( "Fangen", optionen );
+                        ( (Knopf*)obj )->addStyle( Knopf::Style::Erlaubt );
+                        if( wiederH )
+                            wiederH = wiederH->release();
+                        Text options = optionen.getText();
+                        wiederH = new MenüWiederhohlung( schrift, screen, d, &options );
+                        release();
+                    } );
+                }
+                return 1;
+            } );
+            tmpWBT->addZeile( optionen.getText() );
+            tmpWBT->setZeichnungZ( 0, i + 1, scoreT );
+            tmpWBT->setZeichnungZ( 1, i + 1, spielerT );
+            tmpWBT->setZeichnungZ( 2, i + 1, ansehenK );
+            tmpWBT->setZeichnungZ( 3, i + 1, breiteT );
+            tmpWBT->setZeichnungZ( 4, i + 1, höheT );
+            tmpWBT->setZeichnungZ( 5, i + 1, zieleT );
+            tmpWBT->setZeichnungZ( 6, i + 1, gegnerT );
+            tmpWBT->setZeichnungZ( 7, i + 1, tempoT );
+        }
+        tmpKlient->release();
+        tmpWBT->release();
+        tmpSchrift->release();
+    }, &asyncFinished );
 	InitDatei *opd = new InitDatei( "data/Minigames/Fangen/data/optionen.ini" );
 	opd->laden();
 	if( !opd->wertExistiert( "Breite" ) )
@@ -373,8 +672,16 @@ void Men
 
 void MenüStatistik::doMausEreignis( MausEreignis &me )
 {
+    if( wiederH )
+    {
+        wiederH->doMausEreignis( me );
+        return;
+    }
 	ansicht->doMausEreignis( me );
 	optionen->doMausEreignis( me );
+    gesammtT->doMausEreignis( me );
+    optionenT->doMausEreignis( me );
+    worldBestT->doMausEreignis( me );
 	bool vera = me.verarbeitet;
 	löschen->doMausEreignis( me );
 	if( !vera && me.verarbeitet && me.id == ME_RLinks )
@@ -415,6 +722,13 @@ void Men
 
 bool MenüStatistik::tick( double tickVal )
 {
+    if( wiederH )
+    {
+        bool ret = wiederH->tick( tickVal );
+        if( wiederH->istBeendet() )
+            wiederH = wiederH->release();
+        return ret;
+    }
 	bool ret = ansicht->tick( tickVal );
 	ret |= optionen->tick( tickVal );
 	ret |= löschen->tick( tickVal );
@@ -423,11 +737,25 @@ bool Men
 	ret |= optionenT->tick( tickVal );
 	ret |= gesammtD->tick( tickVal );
 	ret |= optionenD->tick( tickVal );
+    ret |= worldBestT->tick( tickVal );
 	return ret;
 }
 
 void MenüStatistik::render( Bild &zRObj )
 {
+    if( wiederH )
+    {
+        wiederH->render( zRObj );
+        return;
+    }
+    schrift->setSchriftSize( 12 );
+    Text weltScore = "Welt Score:";
+    schrift->setDrawPosition( 10, 40 );
+    schrift->renderText( &weltScore, zRObj, 0xFFFFFFFF );
+    Text localScore = "Dein Score:";
+    schrift->setDrawPosition( 10, 170 );
+    schrift->renderText( &localScore, zRObj, 0xFFFFFFFF );
+    worldBestT->render( zRObj );
 	if( !ansicht->getAuswahl() )
 	{
 		if( optionen->hatStyle( KontrollKnopf::Style::Selected ) )
@@ -455,6 +783,11 @@ bool Men
 	return beendet;
 }
 
+bool MenüStatistik::istWiederhohlung() const
+{
+    return wiederH != 0;
+}
+
 // Reference Counting
 MenüStatistik *MenüStatistik::getThis()
 {
@@ -689,14 +1022,14 @@ Men
 
 // Inhalt der Menü Klasse aus Menü.h
 // Konstruktor
-Menü::Menü( Schrift *zSchrift, Bildschirm *zScreen )
+Menü::Menü( Schrift *zSchrift, Bildschirm *zScreen, MinigameKlientV *klient )
 {
 	spielen = initKnopf( 350, 180, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Spielen" );
-	spielenF = new MenüSpiel( zSchrift, zScreen );
+	spielenF = new MenüSpiel( zSchrift, zScreen, klient->getThis() );
 	optionen = initKnopf( 350, 220, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Optionen" );
 	optionenF = new MenüOptionen( zSchrift, zScreen );
 	statistik = initKnopf( 350, 260, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Statistik" );
-	statistikF = new MenüStatistik( zSchrift, zScreen );
+	statistikF = new MenüStatistik( zSchrift, zScreen, klient );
 	beenden = initKnopf( 350, 300, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Beenden" );
 	ram = new LRahmen();
 	ram->setFarbe( 0xFFFFFFFF );
@@ -825,7 +1158,7 @@ bool Men
 
 void Menü::render( Bild &zRObj )
 {
-	if( status != 3 && hintergrund )
+	if( status != 3 && hintergrund && ( status != 2 || !statistikF->istWiederhohlung() ) )
 		zRObj.drawBild( 0, 0, hintergrund->getBreite(), hintergrund->getHeight(), *hintergrund );
 	switch( status )
 	{
@@ -847,7 +1180,7 @@ void Men
 		optionenF->render( zRObj );
 		break;
 	case 2:
-		if( hintergrund )
+		if( hintergrund && !statistikF->istWiederhohlung() )
 			zRObj.alphaRegion( 0, 0, hintergrund->getBreite(), hintergrund->getHeight(), 0xD0000000 );
 		statistikF->render( zRObj );
 		break;

+ 41 - 3
Fangen/Menü.h

@@ -39,12 +39,13 @@ private:
 	Knopf *beenden;
 	Map *map;
 	MenüVerloren *verloren;
+    double timePuffer;
 	bool beendet;
 	int ref;
 
 public:
 	// Konstruktor
-	MenüSpiel( Schrift *zSchrift, Bildschirm *zScreen );
+	MenüSpiel( Schrift *zSchrift, Bildschirm *zScreen, MinigameKlientV *klient );
 	// Destruktor
 	~MenüSpiel();
 	// nicht constant
@@ -60,6 +61,37 @@ public:
 	MenüSpiel *release();
 };
 
+class MenüWiederhohlung
+{
+private:
+    TextFeld *scoreT;
+    Knopf *beenden;
+    Map *map;
+    Datei *datei;
+    double nowTime;
+    double nextTime;
+    bool beendet;
+    char tastenStände;
+    double timePuffer;
+    int ref;
+
+public:
+    // Konstruktor
+    MenüWiederhohlung( Schrift *zSchrift, Bildschirm *zScreen, Datei *datei, Text *zOptionen );
+    // Destruktor
+    ~MenüWiederhohlung();
+    // nicht constant
+    void doMausEreignis( MausEreignis &me );
+    void doTastaturEreignis( TastaturEreignis &te );
+    bool tick( double tickVal );
+    void render( Bild &zRObj );
+    // constant
+    bool istBeendet() const;
+    // Reference Counting
+    MenüWiederhohlung *getThis();
+    MenüWiederhohlung *release();
+};
+
 class MenüStatistik
 {
 private:
@@ -68,17 +100,22 @@ private:
 	KontrollKnopf *optionen;
 	ObjTabelle *gesammtT;
 	ObjTabelle *optionenT;
+    ObjTabelle *worldBestT;
 	LDiag *gesammtD;
 	LDiag *optionenD;
 	Knopf *löschen;
 	Knopf *zurück;
 	Schrift *schrift;
+    MinigameKlientV *klient;
+    MenüWiederhohlung *wiederH;
+    Bildschirm *screen;
+    bool asyncFinished;
 	bool beendet;
 	int ref = 1;
 
 public:
 	// Konstruktor
-	MenüStatistik( Schrift *zSchrift, Bildschirm *zScreen );
+	MenüStatistik( Schrift *zSchrift, Bildschirm *zScreen, MinigameKlientV *klient );
 	// Destruktor
 	~MenüStatistik();
 	// nicht constant
@@ -88,6 +125,7 @@ public:
 	void render( Bild &zRObj );
 	// constant
 	bool istBeendet() const;
+    bool istWiederhohlung() const;
 	// Reference Counting
 	MenüStatistik *getThis();
 	MenüStatistik *release();
@@ -148,7 +186,7 @@ private:
 
 public:
 	// Konstruktor
-	Menü( Schrift *zSchrift, Bildschirm *zScreen );
+	Menü( Schrift *zSchrift, Bildschirm *zScreen, MinigameKlientV *klient );
 	// Destruktor
 	~Menü();
 	// nicht constant#

+ 99 - 99
Fangen/Spieler.cpp

@@ -5,48 +5,48 @@
 
 // Inhalt der Spieler Klasse aus Spieler.h
 // Konstruktor
-Spieler::Spieler( SpielerTyp typ, int mapBr, int mapHö )
+Spieler::Spieler( SpielerTyp typ, int mapBr, int mapHö, RandomGenerator *zRand )
 {
-	if( typ == GEGNER )
-	{
-		xSpeed = ( ( rand() % 8001 ) / 1000.0 - 4.0 ) * 60;
-		ySpeed = ( ( rand() % 8001 ) / 1000.0 - 4.0 ) * 60;
-		durchlässig = 3;
-		farbe = 0xFFFF0000;
-	}
-	if( typ == ZIEL )
-	{
-		xSpeed = ( ( rand() % 7001 ) / 1000.0 - 4.0 ) * 60;
-		ySpeed = ( ( rand() % 7001 ) / 1000.0 - 4.0 ) * 60;
-		durchlässig = 3;
-		farbe = 0xFF00FFFF;
-	}
-	if( typ == SPIELER )
-	{
-		xSpeed = 0;
-		ySpeed = 0;
-		farbe = 0xFF00FF00;
-		durchlässig = 0;
-	}
-	xPos = ( rand() % ( mapBr - 100 ) ) + 50;
-	yPos = ( rand() % ( mapHö - 100 ) ) + 50;
-	ref = 1;
+    if( typ == GEGNER )
+    {
+        xSpeed = ( ( zRand->rand() * 8001 ) / 1000.0 - 4.0 ) * 60;
+        ySpeed = ( ( zRand->rand() * 8001 ) / 1000.0 - 4.0 ) * 60;
+        durchlässig = 3;
+        farbe = 0xFFFF0000;
+    }
+    if( typ == ZIEL )
+    {
+        xSpeed = ( ( zRand->rand() * 7001 ) / 1000.0 - 4.0 ) * 60;
+        ySpeed = ( ( zRand->rand() * 7001 ) / 1000.0 - 4.0 ) * 60;
+        durchlässig = 3;
+        farbe = 0xFF00FFFF;
+    }
+    if( typ == SPIELER )
+    {
+        xSpeed = 0;
+        ySpeed = 0;
+        farbe = 0xFF00FF00;
+        durchlässig = 0;
+    }
+    xPos = ( zRand->rand() * ( mapBr - 100 ) ) + 50;
+    yPos = ( zRand->rand() * ( mapHö - 100 ) ) + 50;
+    ref = 1;
 }
 
 Spieler::Spieler( SpielerTyp typ, Datei *zD )
 {
-	if( typ == GEGNER )
-		farbe = 0xFFFF0000;
-	if( typ == ZIEL )
-		farbe = 0xFF00FFFF;
-	if( typ == SPIELER )
-		farbe = 0xFF00FF00;
-	zD->lese( (char*)&xPos, 8 );
-	zD->lese( (char*)&yPos, 8 );
-	zD->lese( (char*)&xSpeed, 8 );
-	zD->lese( (char*)&ySpeed, 8 );
-	zD->lese( (char*)&durchlässig, 8 );
-	ref = 1;
+    if( typ == GEGNER )
+        farbe = 0xFFFF0000;
+    if( typ == ZIEL )
+        farbe = 0xFF00FFFF;
+    if( typ == SPIELER )
+        farbe = 0xFF00FF00;
+    zD->lese( (char*)&xPos, 8 );
+    zD->lese( (char*)&yPos, 8 );
+    zD->lese( (char*)&xSpeed, 8 );
+    zD->lese( (char*)&ySpeed, 8 );
+    zD->lese( (char*)&durchlässig, 8 );
+    ref = 1;
 }
 
 // Destruktor
@@ -56,97 +56,97 @@ Spieler::~Spieler()
 }
 
 // nicht constant
-void Spieler::tick( double z, int mapBr, int mapHö )
+void Spieler::tick( double z, int mapBr, int mapHö, char tastenStände )
 {
-	if( farbe == 0xFF00FF00 )
-	{
-		if( getTastenStand( T_Links ) )
-			xPos -= 150 * z;
-		if( getTastenStand( T_Rechts ) )
-			xPos += 150 * z;
-		if( getTastenStand( T_Oben ) )
-			yPos -= 150 * z;
-		if( getTastenStand( T_Unten ) )
-			yPos += 150 * z;
-	}
-	if( durchlässig )
-	{
-		durchlässig -= z;
-		if( durchlässig < 0 )
-			durchlässig = 0;
-	}
-	xPos += xSpeed * z;
-	yPos += ySpeed * z;
-	if( xPos < 10 )
-	{
-		xPos = 10;
-		xSpeed = -xSpeed;
-	}
-	else if( xPos > mapBr - 10 )
-	{
-		xPos = mapBr - 10;
-		xSpeed = -xSpeed;
-	}
-	else if( yPos < 10 )
-	{
-		yPos = 10;
-		ySpeed = -ySpeed;
-	}
-	else if( yPos > mapHö - 10 )
-	{
-		yPos = mapHö - 10;
-		ySpeed = -ySpeed;
-	}
+    if( farbe == 0xFF00FF00 )
+    {
+        if( ( tastenStände | 4 ) == tastenStände )
+            xPos -= 150 * z;
+        if( ( tastenStände | 2 ) == tastenStände )
+            xPos += 150 * z;
+        if( ( tastenStände | 1 ) == tastenStände )
+            yPos -= 150 * z;
+        if( ( tastenStände | 8 ) == tastenStände )
+            yPos += 150 * z;
+    }
+    if( durchlässig )
+    {
+        durchlässig -= z;
+        if( durchlässig < 0 )
+            durchlässig = 0;
+    }
+    xPos += xSpeed * z;
+    yPos += ySpeed * z;
+    if( xPos < 10 )
+    {
+        xPos = 10;
+        xSpeed = -xSpeed;
+    }
+    else if( xPos > mapBr - 10 )
+    {
+        xPos = mapBr - 10;
+        xSpeed = -xSpeed;
+    }
+    else if( yPos < 10 )
+    {
+        yPos = 10;
+        ySpeed = -ySpeed;
+    }
+    else if( yPos > mapHö - 10 )
+    {
+        yPos = mapHö - 10;
+        ySpeed = -ySpeed;
+    }
 }
 
 void Spieler::render( Bild &zRObj )
 {
-	if( !durchlässig || (int)( durchlässig * 8 ) % 2 )
-	{
-		zRObj.drawKreis( (int)xPos, (int)yPos, 10, farbe );
-		zRObj.drawKreis( (int)xPos - 3, (int)yPos - 3, 2, farbe );
-		zRObj.drawKreis( (int)xPos + 3, (int)yPos - 3, 2, farbe );
-		zRObj.drawLinieV( (int)xPos, (int)yPos - 1, 4, farbe );
-		zRObj.drawLinieH( (int)xPos - 3, (int)yPos  + 5, 6, farbe );
-	}
+    if( !durchlässig || (int)( durchlässig * 8 ) % 2 )
+    {
+        zRObj.drawKreis( (int)xPos, (int)yPos, 10, farbe );
+        zRObj.drawKreis( (int)xPos - 3, (int)yPos - 3, 2, farbe );
+        zRObj.drawKreis( (int)xPos + 3, (int)yPos - 3, 2, farbe );
+        zRObj.drawLinieV( (int)xPos, (int)yPos - 1, 4, farbe );
+        zRObj.drawLinieH( (int)xPos - 3, (int)yPos + 5, 6, farbe );
+    }
 }
 
 // constant
 bool Spieler::berührt( double px, double py ) const
 {
-	return !durchlässig && sqrt( (double)( px - xPos ) * ( px - xPos ) + ( py - yPos ) * ( py - yPos ) ) <= 20;
+    return !durchlässig && sqrt( (double)( px - xPos ) * ( px - xPos ) + ( py - yPos ) * ( py - yPos ) ) <= 20;
 }
 
 int Spieler::getX() const
 {
-	return (int)xPos;
+    return (int)xPos;
 }
 
 int Spieler::getY() const
 {
-	return (int)yPos;
+    return (int)yPos;
 }
 
 void Spieler::save( Datei *zD ) const
 {
-	zD->schreibe( (char*)&xPos, 8 );
-	zD->schreibe( (char*)&yPos, 8 );
-	zD->schreibe( (char*)&xSpeed, 8 );
-	zD->schreibe( (char*)&ySpeed, 8 );
-	zD->schreibe( (char*)&durchlässig, 8 );
+    zD->schreibe( (char*)&xPos, 8 );
+    zD->schreibe( (char*)&yPos, 8 );
+    zD->schreibe( (char*)&xSpeed, 8 );
+    zD->schreibe( (char*)&ySpeed, 8 );
+    zD->schreibe( (char*)&durchlässig, 8 );
 }
 
 // Reference Counting
 Spieler *Spieler::getThis()
 {
-	ref++;
-	return this;
+    ref++;
+    return this;
 }
 
 Spieler *Spieler::release()
 {
-	ref--;
-	if( !ref )
-		delete this;
-	return 0;
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
 }

+ 3 - 2
Fangen/Spieler.h

@@ -3,6 +3,7 @@
 
 #include <Bild.h>
 #include <Datei.h>
+#include <Random.h>
 
 using namespace Framework;
 
@@ -26,12 +27,12 @@ private:
 
 public:
 	// Konstruktor
-	Spieler( SpielerTyp typ, int mapBr, int mapHö );
+	Spieler( SpielerTyp typ, int mapBr, int mapHö, RandomGenerator *zRand );
 	Spieler( SpielerTyp typ, Datei *zD );
 	// Destruktor
 	~Spieler();
 	// nicht constant
-	void tick( double z, int mapBr, int mapHö );
+	void tick( double z, int mapBr, int mapHö, char tastenStände );
 	void render( Bild &zRObj );
 	// constant
 	bool berührt( double px, double py ) const;