#include "Map.h" #include #include #include #include #include #include #include #include #include #include #include #include // Inhalt der Map Klasse aus Map.h // Konstruktor Map::Map( MinigameKlientV *klient ) { this->klient = klient; schuss = new RCArray< Schuss >(); ship = 0; asteroid = new RCArray< Asteroid >(); aData = new Model2DData*[ 7 ](); aTextur = new Bild*[ 7 ](); sData = new Model2DData*[ 2 ](); sTextur = new Bild*[ 2 ](); M2Datei m2d( "data/Minigames/Asteroids/models/asteroids.m2" ); m2d.leseDaten(); LTDBDatei td; td.setDatei( new Text( "data/Minigames/Asteroids/bilder/asteroids.ltdb" ) ); td.leseDaten( 0 ); for( int i = 0; i < 7; i++ ) { Text name = ""; name.append( (char)( 'a' + i ) ); aData[ i ] = m2d.ladeModel( name ); aTextur[ i ] = td.laden( 0, new Text( (char*)( Text( name ) += ".png" ) ) ); } m2d.setPfad( "data/Minigames/Asteroids/models/ship.m2" ); m2d.leseDaten(); td.setDatei( new Text( "data/Minigames/Asteroids/bilder/ship.ltdb" ) ); td.leseDaten( 0 ); for( int i = 0; i < 2; i++ ) { Text name = ""; name.append( (char)( 'a' + i ) ); sData[ i ] = m2d.ladeModel( name ); sTextur[ i ] = td.laden( 0, new Text( (char*)( Text( name ) += ".png" ) ) ); } kam = new LRahmen(); kam->setFarbe( 0xFF777777 ); map = new LRahmen(); map->setFarbe( 0xFFFFFFFF ); map->setPosition( 10, 10 ); map->setSize( 200, 200 ); shipN = 0; score = 0; breite = 0; höhe = 0; aGröße = 0; maxTimer = 0; mTimer = 0; timer = 0; beendet = 1; rend = 0; gameTime = 0; tastenStände = 0; rGen = 0; ref = 1; } // Destruktor Map::~Map() { speichern(); schuss->release(); if( ship ) ship->release(); asteroid->release(); for( int i = 0; i < 7; i++ ) { aData[ i ]->release(); aTextur[ i ]->release(); } for( int i = 0; i < 2; i++ ) { sData[ i ]->release(); sTextur[ i ]->release(); } delete[] aData; delete[] aTextur; delete[] sData; delete[] sTextur; kam->release(); map->release(); if( rGen ) rGen->release(); if( klient ) klient->release(); } // nicht constant void Map::reset( Text *zOptionen ) { gameTime = 0; timer = 0; beendet = 0; score = 0; tastenStände = 0; if( ship ) ship = ship->release(); schuss->leeren(); asteroid->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 ) ); aGröße = *tmp; tmp->release(); tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 3 ) + 1, zOptionen->positionVon( ',', 3 ) ); maxTimer = *tmp; tmp->release(); mTimer = maxTimer; tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 4 ) + 1, zOptionen->positionVon( ',', 4 ) ); shipN = *tmp; tmp->release(); tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 5 ) + 1, zOptionen->positionVon( ',', 5 ) ); bool fortsetzen = (int)*tmp != 0; tmp->release(); Vec2< float > shipPos( (float)( breite / 2 ), (float)( höhe / 2 ) ); Vec2< float > shipSpeed( 0, 0 ); float shipR = (float)-PI / 2; if( rGen ) rGen = rGen->release(); if( fortsetzen && DateiExistiert( "data/Minigames/Asteroids/data/game.save" ) && klient ) { if( capture.istOffen() ) capture.close(); capture.setDatei( "data/Minigames/Asteroids/data/game.mgc" ); capture.open( Datei::Style::schreiben | Datei::Style::ende | Datei::Style::lesen ); Datei *save = new Datei(); save->setDatei( "data/Minigames/Asteroids/data/game.save" ); save->open( Datei::Style::lesen ); int br = 0; int hö = 0; int gr = 0; int shn = 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 ); save->lese( (char*)&gr, 4 ); save->lese( (char*)&shn, 4 ); if( br == breite && hö == höhe && gr == aGröße && shn == shipN ) { save->lese( (char*)&score, 4 ); save->lese( (char*)&mTimer, 4 ); // Schiff laden save->lese( (char*)&shipPos.x, 4 ); save->lese( (char*)&shipPos.y, 4 ); save->lese( (char*)&shipSpeed.x, 4 ); save->lese( (char*)&shipSpeed.y, 4 ); save->lese( (char*)&shipR, 4 ); int anz = 0; save->lese( (char*)&anz, 4 ); for( int i = 0; i < anz; i++ ) { // Asteroiden Laden char n = 0; float x = 0; float y = 0; float xs = 0; float ys = 0; float rs = 0; float r = 0; float gr = 0; save->lese( &n, 1 ); save->lese( (char*)&x, 4 ); save->lese( (char*)&y, 4 ); save->lese( (char*)&xs, 4 ); save->lese( (char*)&ys, 4 ); save->lese( (char*)&rs, 4 ); save->lese( (char*)&r, 4 ); save->lese( (char*)&gr, 4 ); asteroid->add( new Asteroid( aData[ n ]->getThis(), aTextur[ n ]->getThis(), Vec2< float >( x, y ), Vec2< float >( xs, ys ), rs, r, gr, n ) ); } save->lese( (char*)&anz, 4 ); for( int i = 0; i < anz; i++ ) { // Schüsse Laden float x = 0; float y = 0; float xs = 0; float ys = 0; save->lese( (char*)&x, 4 ); save->lese( (char*)&y, 4 ); save->lese( (char*)&xs, 4 ); save->lese( (char*)&ys, 4 ); schuss->add( new Schuss( Vec2< float >( x, y ), Vec2< float >( xs, ys ) ) ); } } save->close(); save->release(); } else { rGen = new RandomGenerator(); if( klient ) { if( capture.istOffen() ) capture.close(); DateiRemove( "data/Minigames/Asteroids/data/game.mgc" ); capture.setDatei( "data/Minigames/Asteroids/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(); } } ship = new Ship( sData[ shipN ]->getThis(), sTextur[ shipN ]->getThis(), shipPos, shipSpeed, shipR ); } 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 == T_Space ) { if( te.id == TE_Press ) { tastenStände |= 8; ok = 0; } else tastenStände &= ~8; } if( tmp != tastenStände && klient ) { if( klient ) { capture.schreibe( (char*)&gameTime, 8 ); capture.schreibe( &tastenStände, 1 ); } } } if( te.taste == T_Space && te.id == TE_Press ) { if( klient && ok ) { capture.schreibe( (char*)&gameTime, 8 ); capture.schreibe( "\x10", 1 ); } schuss->add( ship->getSchuss() ); } cs.unlock(); } bool Map::tick( double tickVal ) { if( beendet ) { bool ret = rend; rend = 0; return ret; } cs.lock(); gameTime += tickVal; // Timer timer -= tickVal; if( timer <= 0 ) { mTimer -= 25; if( mTimer < 500 ) mTimer = 500; timer = mTimer / 1000.0; for( int i = 0; i < rGen->rand() * 4 + 1; i++ ) { int num = (int)(rGen->rand() * 7); double sw = ( rGen->rand() * 360 ) / 180.0 * PI; Vec2< float > speed( (float)cos( sw ), (float)sin( sw ) ); speed *= (float)( rGen->rand() * 40 ); Vec2< float > pos( -200.f, höhe / 2.f ); if( speed.x < 0 ) pos.x = (float)( breite + 200 ); asteroid->add( new Asteroid( aData[ num ]->getThis(), aTextur[ num ]->getThis(), pos, speed, (float)( rGen->rand() * 100 ) / 75.f, (float)sw, aGröße / 1000.f, num ) ); } } // Update int aAnz = asteroid->getEintragAnzahl(); for( int i = 0; i < aAnz; i++ ) asteroid->z( i )->tick( tickVal, breite, höhe ); int sAnz = schuss->getEintragAnzahl(); for( int i = 0; i < sAnz; i++ ) schuss->z( i )->tick( tickVal ); ship->tick( tickVal, breite, höhe, tastenStände ); for( int i = aAnz - 1; i >= 0; i-- ) { if( !asteroid->z( i )->amLeben() ) { score++; asteroid->remove( i ); aAnz--; } } for( int i = sAnz - 1; i >= 0; i-- ) { Vec2< float > pos = schuss->z( i )->getPos(); if( pos.x < 0 || pos.y < 0 || pos.x > breite || pos.y > höhe ) { sAnz--; schuss->remove( i ); } } // Collision for( int i = sAnz - 1; i >= 0; i-- ) { Schuss *zs = schuss->z( i ); bool b = 0; for( int j = 0; j < aAnz; j++ ) b |= asteroid->z( j )->istGetroffen( zs ); if( b ) { schuss->remove( i ); sAnz--; } } for( int i = 0; i < aAnz && !beendet; i++ ) beendet |= ship->istTod( asteroid->z( i ) ); if( beendet && klient ) { capture.close(); DateiRemove( "data/Minigames/Asteroids/data/upload.mgc" ); DateiUmbenennen( "data/Minigames/Asteroids/data/game.mgc", "data/Minigames/Asteroids/data/upload.mgc" ); int tmpScore = score; MinigameKlientV *tmpKlient = klient->getThis(); new AsynchronCall( [ tmpScore, tmpKlient ]() { InitDatei *opd = new InitDatei( "data/Minigames/Asteroids/data/optionen.ini" ); opd->laden(); Text optionen = "Width="; optionen += opd->zWert( "Breite" )->getText(); optionen += ",Height="; optionen += opd->zWert( "Höhe" )->getText(); optionen += ",Size="; optionen += opd->zWert( "Größe" )->getText(); optionen += ",Timer="; optionen += opd->zWert( "Timer" )->getText(); optionen += ",Ship="; optionen += opd->zWert( "Ship" )->getText(); opd->release(); int status = tmpKlient->reportEndOfGame( "Asteroids", optionen, tmpScore ); if( status == 2 ) { Datei d; d.setDatei( "data/Minigames/Asteroids/data/upload.mgc" ); tmpKlient->uploadGameCapture( &d ); } DateiRemove( "data/Minigames/Asteroids/data/upload.mgc" ); tmpKlient->release(); } ); KSGTDatei *stb = new KSGTDatei( "data/Minigames/Asteroids/data/score.ksgt" ); if( !stb->laden() ) DateiPfadErstellen( "data/Minigames/Asteroids/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 *timerT = new Text(); timerT->append( maxTimer ); zeile->add( timerT ); Text *aGrößeT = new Text(); aGrößeT->append( aGröße ); zeile->add( aGrößeT ); Text *shipT = new Text(); shipT->append( shipN ); zeile->add( shipT ); stb->addZeile( 7, zeile ); zeile->release(); stb->speichern(); stb->release(); DateiRemove( "data/Minigames/Asteroids/data/game.save" ); } cs.unlock(); return 1; } void Map::render( Bild &zRObj ) { Punkt kamP = ship->getKamPos( breite, höhe ); zRObj.addScrollOffset( kamP.x, kamP.y ); int aAnz = asteroid->getEintragAnzahl(); for( int i = 0; i < aAnz; i++ ) asteroid->z( i )->render( zRObj ); int sAnz = schuss->getEintragAnzahl(); for( int i = 0; i < sAnz; i++ ) schuss->z( i )->render( zRObj ); ship->render( zRObj ); zRObj.addScrollOffset( -kamP.x, -kamP.y ); if( breite >= 800 || höhe >= 500 ) { // Minimap const Punkt &dOff = zRObj.getDrawOff(); map->render( zRObj ); zRObj.setPixelDP( 10 + ( ship->getPos().x * 200 ) / breite + dOff.x, 10 + ( ship->getPos().y * 200 ) / höhe + dOff.y, 0xFF00FF00 ); for( int i = 0; i < aAnz; i++ ) zRObj.setPixelDP( 10 + ( asteroid->z( i )->getPos().x * 200 ) / breite + dOff.x, 10 + ( asteroid->z( i )->getPos().y * 200 ) / höhe + dOff.y, 0xFFFF0000 ); for( int i = 0; i < sAnz; i++ ) zRObj.setPixelDP( 10 + ( (int)schuss->z( i )->getPos().x * 200 ) / breite + dOff.x, 10 + ( (int)schuss->z( i )->getPos().y * 200 ) / höhe + dOff.y, 0xFF00FFFF ); kam->setPosition( 10 + ( 200 * kamP.x ) / breite, 10 + ( 200 * kamP.y ) / höhe ); kam->setSize( ( 200 * 800 ) / breite, ( 200 * 500 ) / 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 && klient ) { if( capture.istOffen() ) capture.close(); Datei *d = new Datei(); d->setDatei( "data/Minigames/Asteroids/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*)&aGröße, 4 ); d->schreibe( (char*)&shipN, 4 ); d->schreibe( (char*)&score, 4 ); d->schreibe( (char*)&mTimer, 4 ); ship->save( d ); int anz = asteroid->getEintragAnzahl(); d->schreibe( (char*)&anz, 4 ); for( int i = 0; i < anz; i++ ) asteroid->z( i )->save( d ); anz = schuss->getEintragAnzahl(); d->schreibe( (char*)&anz, 4 ); for( int i = 0; i < anz; i++ ) schuss->z( i )->save( d ); d->close(); d->release(); } else if( klient ) DateiRemove( "data/Minigames/Asteroids/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; }