#include "Map.h" #include #include #include #include #include #include #include #include // Inhalt der Map Klasse aus Map.h // Konstruktor Map::Map( KSGClient::MinigameServerClient *klient ) { this->klient = klient; schlange = new Array< Pos >(); ziele = new Array< Pos >(); feld = new LRahmen(); feld->setFarbe( 0xFFFFFFFF ); kam = new LRahmen(); kam->setFarbe( 0xFF777777 ); map = new LRahmen(); map->setFarbe( 0xFFFFFFFF ); map->setPosition( 10, 10 ); map->setSize( 200, 200 ); beendet = 1; gameTime = 0; rGen = 0; move = 1; sr = 1; rend = 0; ref = 1; } // Destruktor Map::~Map() { speichern(); schlange->release(); ziele->release(); feld->release(); kam->release(); map->release(); if( rGen ) rGen->release(); if( klient ) klient->release(); } // nicht constant void Map::reset( Text *zOptionen ) { gameTime = 0; if( rGen ) rGen = rGen->release(); next = 0; beendet = 0; richtung = 0; addAnzahl = 0; score = 0; scoreCheck = score * 11197; schlange->leeren(); ziele->leeren(); 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 ) ); neuAnzahl = *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(); kamPos.x = 0; kamPos.y = 0; if( breite > 80 ) kamPos.x = breite / 2 - 40; if( höhe > 50 ) kamPos.y = höhe / 2 - 25; if( fortsetzen && DateiExistiert( "data/Minigames/Snake/data/game.save" ) && klient ) { if( capture.istOffen() ) capture.close(); capture.setDatei( "data/Minigames/Snake/data/game.mgc" ); capture.open( Datei::Style::schreiben | Datei::Style::ende | Datei::Style::lesen ); Datei *save = new Datei(); save->setDatei( "data/Minigames/Snake/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 ) { save->lese( (char*)&score, 4 ); scoreCheck = score * 11197; save->lese( (char*)&richtung, 4 ); int anz = 0; save->lese( (char*)&anz, 4 ); for( int i = 0; i < anz; i++ ) { Pos p; save->lese( (char*)&p.x, 2 ); save->lese( (char*)&p.y, 2 ); schlange->add( p ); } save->lese( (char*)&anz, 4 ); for( int i = 0; i < anz; i++ ) { Pos p; save->lese( (char*)&p.x, 2 ); save->lese( (char*)&p.y, 2 ); ziele->add( p ); } next = 1.0 / geschwindigkeit; } save->close(); save->release(); } else { rGen = new RandomGenerator(); if( klient ) { if( capture.istOffen() ) capture.close(); DateiRemove( "data/Minigames/Snake/data/game.mgc" ); capture.setDatei( "data/Minigames/Snake/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( !schlange->getEintragAnzahl() ) schlange->add( Pos{ (short)( breite / 2 ), (short)( höhe / 2 ) } ); } void Map::doMausEreignis( MausEreignis &me ) { } void Map::doTastaturEreignis( TastaturEreignis &te ) { if( !move ) return; cs.lock(); if( !beendet ) { bool save = 0; if( te.taste == 'w' || te.taste == 'W' || te.taste == T_Oben ) { if( te.id == TE_Press && richtung != 2 ) { save = 1; move = 0; richtung = 0; } } if( te.taste == 'd' || te.taste == 'D' || te.taste == T_Rechts ) { if( te.id == TE_Press && richtung != 3 ) { save = 1; move = 0; richtung = 1; } } if( te.taste == 'a' || te.taste == 'A' || te.taste == T_Links ) { if( te.id == TE_Press && richtung != 1 ) { save = 1; move = 0; richtung = 3; } } if( te.taste == 's' || te.taste == 'S' || te.taste == T_Unten ) { if( te.id == TE_Press && richtung != 0 ) { save = 1; move = 0; richtung = 2; } } if( klient && save ) { capture.schreibe( (char*)&gameTime, 8 ); capture.schreibe( (char*)&te.taste, 1 ); } } cs.unlock(); } bool Map::tick( double tickVal ) { if( beendet ) return 0; bool ret = rend; cs.lock(); gameTime += tickVal; rend = 0; next -= tickVal; while( next < 0 && !beendet ) { move = 1; ret = 1; next += 1.0 / geschwindigkeit; int nx = schlange->get( 0 ).x; int ny = schlange->get( 0 ).y; if( richtung == 0 ) ny--; if( richtung == 1 ) nx++; if( richtung == 2 ) ny++; if( richtung == 3 ) nx--; if( breite > 80 ) { kamPos.x = nx - 40; if( kamPos.x < 0 ) kamPos.x = 0; if( kamPos.x + 80 > breite ) kamPos.x = breite - 80; } if( höhe > 50 ) { kamPos.y = ny - 25; if( kamPos.y < 0 ) kamPos.y = 0; if( kamPos.y + 50 > höhe ) kamPos.y = höhe - 50; } int sAnz = schlange->getEintragAnzahl(); for( int i = 0; i < sAnz; i++ ) beendet |= nx == schlange->get( i ).x && ny == schlange->get( i ).y; beendet |= nx < 0 || nx >= breite; beendet |= ny < 0 || ny >= höhe; int zAnz = ziele->getEintragAnzahl(); bool neuZ = !zAnz; for( int i = 0; i < zAnz; i++ ) neuZ |= nx == ziele->get( i ).x && ny == ziele->get( i ).y; if( neuZ ) { addAnzahl += neuAnzahl; ziele->leeren(); for( int i = 0; i < zAnzahl; i++ ) ziele->add( Pos{ (short)( rGen->rand() * breite ), (short)( rGen->rand() * höhe ) } ); if( zAnz ) { score++; scoreCheck = score * 11197; } } if( score * 11197 != scoreCheck ) { beendet = 1; score = 0; scoreCheck = 0; } if( !beendet ) { schlange->add( Pos{ (short)nx, (short)ny }, 0 ); if( !addAnzahl ) schlange->remove( sAnz ); else addAnzahl--; } else if( klient ) { capture.close(); DateiRemove( "data/Minigames/Snake/data/upload.mgc" ); DateiUmbenennen( "data/Minigames/Snake/data/game.mgc", "data/Minigames/Snake/data/upload.mgc" ); int tmpScore = score; KSGClient::MinigameServerClient *tmpKlient = klient->getThis(); new AsynchronCall( [ tmpScore, tmpKlient ]() { InitDatei *opd = new InitDatei( "data/Minigames/Snake/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 += ",Anhang="; optionen += opd->zWert( "Anhängen" )->getText(); optionen += ",Speed="; optionen += opd->zWert( "Geschwindigkeit" )->getText(); opd->release(); Datei d; d.setDatei( "data/Minigames/Snake/data/upload.mgc" ); tmpKlient->reportEndOfGame( "Snake", optionen, tmpScore, &d ); DateiRemove( "data/Minigames/Snake/data/upload.mgc" ); tmpKlient->release(); } ); KSGTDatei *stb = new KSGTDatei( "data/Minigames/Snake/data/score.ksgt" ); if( !stb->laden() ) DateiPfadErstellen( "data/Minigames/Snake/data/score.ksgt" ); RCArray< Text > *zeile = new RCArray< Text >(); Zeit *zeit = getZeit(); zeile->add( zeit->getZeit( "y-m-d h:i:s" ) ); zeit->release(); Text *scoreT = new Text(); scoreT->append( score ); zeile->add( scoreT ); Text *breiteT = new Text(); breiteT->append( breite ); zeile->add( breiteT ); Text *höheT = new Text(); höheT->append( höhe ); zeile->add( höheT ); Text *geschwindigkeitT = new Text(); geschwindigkeitT->append( geschwindigkeit ); zeile->add( geschwindigkeitT ); Text *zAnzahlT = new Text(); zAnzahlT->append( zAnzahl ); zeile->add( zAnzahlT ); Text *nAnzahlT = new Text(); nAnzahlT->append( neuAnzahl ); zeile->add( nAnzahlT ); stb->addZeile( 7, zeile ); zeile->release(); stb->speichern(); stb->release(); DateiRemove( "data/Minigames/Snake/data/game.save" ); } } cs.unlock(); return ret; } void Map::render( Bild &zRObj ) { int xStart = 0; int yStart = 0; if( breite < 80 ) xStart = 400 - breite * 5; else xStart -= kamPos.x * 10; if( höhe < 50 ) yStart = 250 - höhe * 5; else yStart -= kamPos.y * 10; feld->setPosition( xStart, yStart ); feld->setSize( breite * 10, höhe * 10 ); feld->render( zRObj ); bool rMap = breite > 80 || höhe > 50; int sLän = schlange->getEintragAnzahl(); for( int i = 0; i < sLän; i++ ) zRObj.fillRegion( xStart + schlange->get( i ).x * 10, yStart + schlange->get( i ).y * 10, 9, 9, 0xFFFFFFFF ); int zAnz = ziele->getEintragAnzahl(); for( int i = 0; i < zAnz; i++ ) zRObj.fillRegion( xStart + ziele->get( i ).x * 10, yStart + ziele->get( i ).y * 10, 9, 9, 0xFF00FF00 ); if( rMap ) { const Punkt &dOff = zRObj.getDrawOff(); map->render( zRObj ); for( int i = 0; i < sLän; i++ ) zRObj.setPixelDP( 10 + ( 200 * schlange->get( i ).x ) / breite + dOff.x, 10 + ( 200 * schlange->get( i ).y ) / höhe + dOff.y, 0xFFFFFFFF ); for( int i = 0; i < zAnz; i++ ) zRObj.setPixelDP( 10 + ( 200 * ziele->get( i ).x ) / breite + dOff.x, 10 + ( 200 * ziele->get( i ).y ) / höhe + dOff.y, 0xFF00FF00 ); kam->setPosition( 10 + ( 200 * kamPos.x ) / breite, 10 + ( 200 * kamPos.y ) / höhe ); kam->setSize( 16000 / breite, ( 10000 ) / höhe ); if( kam->getBreite() > 200 ) kam->setSize( 200, kam->getHeight() ); if( kam->getHeight() > 200 ) kam->setSize( kam->getBreite(), 200 ); kam->render( zRObj ); } } void Map::speichern() { if( !beendet ) { if( capture.istOffen() ) capture.close(); Datei *d = new Datei(); d->setDatei( "data/Minigames/Snake/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 ); d->schreibe( (char*)&richtung, 4 ); int anz = schlange->getEintragAnzahl(); d->schreibe( (char*)&anz, 4 ); for( int i = 0; i < anz; i++ ) { short p = schlange->get( i ).x; d->schreibe( (char*)&p, 2 ); p = schlange->get( i ).y; d->schreibe( (char*)&p, 2 ); } anz = ziele->getEintragAnzahl(); d->schreibe( (char*)&anz, 4 ); for( int i = 0; i < anz; i++ ) { short p = ziele->get( i ).x; d->schreibe( (char*)&p, 2 ); p = ziele->get( i ).y; d->schreibe( (char*)&p, 2 ); } d->close(); d->release(); } else if( klient ) DateiRemove( "data/Minigames/Snake/data/game.save" ); } // constant int Map::getScore() const { return score; } bool Map::istBeendet() const { return beendet; } // Reference Counting Map *Map::getThis() { ref++; return this; } Map *Map::release() { ref--; if( !ref ) delete this; return 0; }