#include "Data.h" #include #include // Konstructor GameData::GameData( const char *shipM2, const char *asteroidsM2 ) { world = new Welt2D(); //world->setAirResistance( 0.01f ); schuss = new RCArray< Schuss >(); ship = 0; asteroid = new RCArray< Asteroid >(); aData = new Model2DData*[ 7 ](); sData = new Model2DData*[ 2 ](); M2Datei m2d( asteroidsM2 ); m2d.leseDaten(); for( int i = 0; i < 7; i++ ) { Text name = ""; name.append( (char)( 'a' + i ) ); aData[ i ] = m2d.ladeModel( name ); } m2d.setPfad( shipM2 ); m2d.leseDaten(); for( int i = 0; i < 2; i++ ) { Text name = ""; name.append( (char)( 'a' + i ) ); sData[ i ] = m2d.ladeModel( name ); } shipN = 0; score = 0; scoreCheck = score * 11197; 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; } // Destructor GameData::~GameData() { schuss->release(); if( ship ) ship->release(); asteroid->release(); for( int i = 0; i < 7; i++ ) aData[ i ]->release(); for( int i = 0; i < 2; i++ ) sData[ i ]->release(); delete[] aData; delete[] sData; if( rGen ) rGen->release(); world->release(); } // private Asteroid *GameData::createNewAsteroid() { 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( (float)rGen->rand() * breite, (float)rGen->rand() * höhe ); if( ( ship->getPosition() - Vertex( (float)world->getWorldInfo().size.x, 0 ) - pos ).getLength() > world->getWorldInfo().size.getLength() / 3 && ( ship->getPosition() + Vertex( (float)world->getWorldInfo().size.x, 0 ) - pos ).getLength() > world->getWorldInfo().size.getLength() / 3 && ( ship->getPosition() - Vertex( 0, (float)world->getWorldInfo().size.y ) - pos ).getLength() > world->getWorldInfo().size.getLength() / 3 && ( ship->getPosition() + Vertex( 0, (float)world->getWorldInfo().size.y ) - pos ).getLength() > world->getWorldInfo().size.getLength() / 3 && ( ship->getPosition() - Vertex( (float)world->getWorldInfo().size.x, (float)world->getWorldInfo().size.y ) - pos ).getLength() > world->getWorldInfo().size.getLength() / 3 && ( ship->getPosition() + Vertex( (float)world->getWorldInfo().size.x, (float)world->getWorldInfo().size.y ) - pos ).getLength() > world->getWorldInfo().size.getLength() / 3 && ( ship->getPosition() + Vertex( (float)world->getWorldInfo().size.x, -(float)world->getWorldInfo().size.y ) - pos ).getLength() > world->getWorldInfo().size.getLength() / 3 && ( ship->getPosition() + Vertex( -(float)world->getWorldInfo().size.x, (float)world->getWorldInfo().size.y ) - pos ).getLength() > world->getWorldInfo().size.getLength() / 3 && ( ship->getPosition() - pos ).getLength() > world->getWorldInfo().size.getLength() / 3 ) { if( speed.x < 0 ) pos.x = (float)( breite + 200 ); Asteroid *ast = new Asteroid( aData[ num ]->getThis(), 0, pos, speed, (float)( rGen->rand() * 100 ) / 75.f, (float)sw, aGröße / 1000.f, num ); int aAnz = asteroid->getEintragAnzahl(); for( int i = 0; i < aAnz; i++ ) { if( ast->istModelInnen( asteroid->z( i ) ) ) { ast->release(); return 0; } } return ast; } return 0; } // nicht constant void GameData::reset( Text *zOptionen ) { gameTime = 0; timer = 0; beendet = 0; score = 0; scoreCheck = score * 11197; tastenStände = 0; if( ship ) ship = (Ship*)ship->release(); world->removeAll(); 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(); 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(); rGen = new RandomGenerator(); if( zOptionen->positionVon( '=', 7 ) >= 0 ) { tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 7 ) + 1 ); rGen->setSeed( (__int64)*tmp ); tmp->release(); } ship = new Ship( sData[ shipN ]->getThis(), shipPos, shipSpeed, shipR ); world->addObject( ship ); } bool GameData::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() * 1 + 1; i++ ) { Asteroid *newA = createNewAsteroid(); if( newA ) { asteroid->add( newA ); world->addObject( newA->getThis() ); } } } // Update ship->setTastenstände( tastenStände ); int aAnz = asteroid->getEintragAnzahl(); int sAnz = schuss->getEintragAnzahl(); for( int i = aAnz - 1; i >= 0; i-- ) { if( asteroid->z( i )->getSize() == 0 ) { score += asteroid->z( i )->getScore(); scoreCheck = score * 11197; world->removeObject( asteroid->z( i ) ); asteroid->remove( i ); aAnz--; } } for( int i = sAnz - 1; i >= 0; i-- ) { Vec2< float > pos = schuss->z( i )->getPosition(); if( pos.x < 0 || pos.y < 0 || pos.x > breite || pos.y > höhe ) { sAnz--; world->removeObject( schuss->z( i ) ); 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++ ) { Polygon2D ap; Polygon2D bp; Punkt pa; Punkt pb; if( asteroid->z( j )->istGetroffen( zs, ap, bp, pa, pb, rGen ) ) { Array< Polygon2D > *npaA = new Array< Polygon2D >(); npaA->add( ap ); Model2DData *npdA = new Model2DData(); npdA->erstelleModell( npaA ); float rot = asteroid->z( j )->getDrehung(); char id = asteroid->z( j )->getId(); if( id >= 0 ) id = -id - 1; Asteroid *newA = new Asteroid( npdA, asteroid->z( j )->zTextur()->zTextur()->getThis(), pa.rotation( rot ) + asteroid->z( j )->getPosition(), asteroid->z( j )->getSpeed(), asteroid->z( j )->getDrehungSpeed(), rot, asteroid->z( j )->getSize(), id ); asteroid->add( newA ); world->addObject( newA->getThis() ); Array< Polygon2D > *npaB = new Array< Polygon2D >(); npaB->add( bp ); Model2DData *npdB = new Model2DData(); npdB->erstelleModell( npaB ); newA = new Asteroid( npdB, asteroid->z( j )->zTextur()->zTextur()->getThis(), pb.rotation( rot ) + asteroid->z( j )->getPosition(), asteroid->z( j )->getSpeed(), asteroid->z( j )->getDrehungSpeed(), rot, asteroid->z( j )->getSize(), id ); asteroid->add( newA ); world->addObject( newA->getThis() ); b = 1; asteroid->z( j )->setSize( 0 ); } } if( !b ) b |= ship->istGetroffen( zs ); if( b ) { world->removeObject( schuss->z( i ) ); schuss->remove( i ); sAnz--; } } for( int i = 0; i < aAnz && !beendet; i++ ) beendet |= ship->istModelInnen( asteroid->z( i ) ); beendet |= ( score * 11197 != scoreCheck ); if( score * 11197 != scoreCheck ) { score = 0; scoreCheck = 0; } cs.unlock(); return 1; } // constant int GameData::getScore() const { return score; } bool GameData::istBeendet() const { return beendet; } // Reference Counting GameData *GameData::getThis() { ref++; return this; } GameData *GameData::release() { ref--; if( !ref ) delete this; return 0; }