#include "Teile.h" #include "Map.h" #include #include #include #include #include #include #include // Inhalt der Map Klasse aus Map.h // Konstruktor Map::Map() { map = new RCArray< Array< int > >(); feld = new LRahmen(); feld->setFarbe( 0xFFFFFFFF ); t = { 0, 0, 0, 0 }; beendet = 1; sr = 1; rend = 0; ref = 1; } // Destruktor Map::~Map() { speichern(); map->release(); feld->release(); } // nicht constant void Map::reset() { next = 0; score = 0; map->leeren(); t = { -1, 0, 0, 0 }; InitDatei *opd = new InitDatei( "data/Minigames/tetris/data/optionen.ini" ); if( !opd->laden() ) DateiPfadErstellen( "data/Minigames/Tetris/data/optionen.ini" ); breite = 15; if( opd->wertExistiert( "Breite" ) ) breite = (int)*opd->zWert( "Breite" ); else opd->addWert( "Breite", "15" ); höhe = 25; if( opd->wertExistiert( "Höhe" ) ) höhe = (int)*opd->zWert( "Höhe" ); else opd->addWert( "Höhe", "25" ); neuTempo = 50; if( opd->wertExistiert( "+Geschwindigkeit" ) ) neuTempo = (int)*opd->zWert( "+Geschwindigkeit" ); else opd->addWert( "+Geschwindigkeit", "50" ); 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(); if( fortsetzen && DateiExistiert( "data/Minigames/Tetris/data/game.save" ) ) { Datei *save = new Datei(); save->setDatei( "data/Minigames/Tetris/data/game.save" ); save->open( Datei::Style::lesen ); int br = 0; int hö = 0; save->lese( (char*)&br, 4 ); save->lese( (char*)&hö, 4 ); if( br == breite && hö == höhe ) { save->lese( (char*)&score, 4 ); save->lese( (char*)&t, sizeof( Tile ) ); for( int y = 0; y < höhe; y++ ) { map->set( new Array< int >(), y ); for( int x = 0; x < breite; x++ ) { int f = 0; save->lese( (char*)&f, 4 ); map->z( y )->set( f, x ); } } geschwindigkeit -= score * neuTempo; if( geschwindigkeit < 100 ) geschwindigkeit = 100; next = geschwindigkeit / 1000.0; } save->close(); save->release(); } if( t.id < 0 ) { t.id = rand() % 7; t.grad = rand() % 4; t.xPos = breite / 2 - 2; t.yPos = 0; } if( !map->getEintragAnzahl() ) { for( int i = 0; i < höhe; i++ ) { Array< int > *line = new Array< int >(); for( int j = 0; j < breite; j++ ) line->add( 0 ); map->add( line ); } } if( breite < 40 || höhe < 25 ) { int br = breite * 20; if( br > 800 ) br = 800; int hö = höhe * 20; if( hö > 500 ) hö = 500; feld->setPosition( 400 - br / 2, 250 - hö / 2 ); feld->setSize( br, hö ); } beendet = 0; } void Map::doMausEreignis( MausEreignis &me ) { } void Map::doTastaturEreignis( TastaturEreignis &te ) { if( beendet ) return; if( te.id == TE_Press ) { int g = t.grad; int xPos = t.xPos; int yPos = t.yPos; if( te.taste == T_Oben ) { g++; if( g >= 4 ) g = 0; } if( te.taste == T_Links ) xPos--; if( te.taste == T_Rechts ) xPos++; if( te.taste == T_Unten ) yPos++; bool ok = 1; for( int x = xPos; x < xPos + 4; x++ ) { for( int y = yPos; y < yPos + 4; y++ ) { if( tiles[ t.id ][ g ][ y - yPos ][ x - xPos ] ) { ok &= x >= 0 && x < breite && y >= 0 && y < höhe; ok &= ( ( x >= 0 && x < breite && y >= 0 && y < höhe ) ? map->z( y )->get( x ) : -1 ) == 0; } } } if( ok ) { t.grad = g; t.xPos = xPos; t.yPos = yPos; rend = 1; } } } bool Map::tick( double tickVal ) { bool ret = rend; rend = 0; if( beendet ) return ret; if( sr ) srand( (int)time( 0 ) ); sr = 0; next -= tickVal; if( next < 0 ) { next = geschwindigkeit / 1000.0; bool ok = 1; for( int x = t.xPos; x < t.xPos + 4; x++ ) { for( int y = t.yPos + 1; y < t.yPos + 5; y++ ) { if( tiles[ t.id ][ t.grad ][ y - t.yPos - 1 ][ x - t.xPos ] ) { ok &= x >= 0 && x < breite && y >= 0 && y < höhe; ok &= ( ( x >= 0 && x < breite && y >= 0 && y < höhe ) ? map->z( y )->get( x ) : -1 ) == 0; } } } if( ok ) t.yPos++; else { for( int x = t.xPos; x < t.xPos + 4; x++ ) { for( int y = t.yPos; y < t.yPos + 4; y++ ) { if( tiles[ t.id ][ t.grad ][ y - t.yPos ][ x - t.xPos ] ) map->z( y )->set( tileFarbe[ t.id ], x ); } } for( int y = 0; y < höhe; y++ ) { bool rm = 1; for( int x = 0; x < breite; x++ ) rm &= map->z( y )->get( x ) != 0; if( rm ) { Array< int > *line = new Array< int >(); for( int i = 0; i < breite; i++ ) line->add( 0 ); map->remove( y ); map->add( line, 0 ); score++; geschwindigkeit -= neuTempo; } } t.id = rand() % 7; t.grad = rand() % 4; t.xPos = breite / 2 - 2; t.yPos = 0; for( int x = t.xPos; x < t.xPos + 4; x++ ) { for( int y = t.yPos; y < t.yPos + 4; y++ ) { if( tiles[ t.id ][ t.grad ][ y - t.yPos ][ x - t.xPos ] ) beendet |= ( ( x >= 0 && x < breite && y >= 0 && y < höhe ) ? map->z( y )->get( x ) : -1 ) != 0; } } if( beendet ) { DateiRemove( "data/Minigames/Tetris/data/game.save" ); KSGTDatei *stb = new KSGTDatei( "data/Minigames/Tetris/data/score.ksgt" ); if( !stb->laden() ) DateiPfadErstellen( "data/Minigames/Tetris/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 *neuTempoT = new Text(); neuTempoT->append( neuTempo ); zeile->add( neuTempoT ); stb->addZeile( 6, zeile ); zeile->release(); stb->speichern(); stb->release(); } } ret = 1; } return ret; } void Map::render( Bild &zRObj ) { int xS = feld->getX(); int yS = feld->getY(); int blockBr = 800 / breite; if( blockBr > 20 ) blockBr = 20; int blockHö = 500 / höhe; if( blockHö > 20 ) blockHö = 20; for( int x = 0; x < breite; x++ ) { for( int y = 0; y < höhe; y++ ) zRObj.fillRegion( xS + x * blockBr, yS + y * blockHö, blockBr - 1, blockHö - 1, map->z( y )->get( x ) ); } for( int x = 0; x < 4; x++ ) { for( int y = 0; y < 4; y++ ) { if( tiles[ t.id ][ t.grad ][ y ][ x ] ) zRObj.fillRegion( xS + ( x + t.xPos ) * blockBr, yS + ( y + t.yPos ) * blockHö, blockBr - 1, blockHö - 1, tileFarbe[ t.id ] ); } } feld->render( zRObj ); } // constant void Map::speichern() const { if( !beendet ) { Datei *d = new Datei(); d->setDatei( "data/Minigames/Tetris/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 ); d->schreibe( (char*)&t, sizeof( Tile ) ); for( int y = 0; y < höhe; y++ ) { for( int x = 0; x < breite; x++ ) { int f = map->z( y )->get( x ); d->schreibe( (char*)&f, 4 ); } } d->close(); d->release(); } else DateiRemove( "data/Minigames/Tetris/data/game.save" ); } 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; }