Map.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. #include "Map.h"
  2. #include <InitDatei.h>
  3. #include <Datei.h>
  4. #include <Text.h>
  5. #include <M2Datei.h>
  6. #include <DateiSystem.h>
  7. #include <TastaturEreignis.h>
  8. #include <KSGTDatei.h>
  9. #include <Zeit.h>
  10. #include <Rahmen.h>
  11. #include <Globals.h>
  12. #include <AsynchronCall.h>
  13. #include <iostream>
  14. // Inhalt der Map Klasse aus Map.h
  15. // Konstruktor
  16. Map::Map( MinigameKlientV *klient )
  17. {
  18. this->klient = klient;
  19. schuss = new RCArray< Schuss >();
  20. ship = 0;
  21. asteroid = new RCArray< Asteroid >();
  22. aData = new Model2DData*[ 7 ]();
  23. aTextur = new Bild*[ 7 ]();
  24. sData = new Model2DData*[ 2 ]();
  25. sTextur = new Bild*[ 2 ]();
  26. M2Datei m2d( "data/Minigames/Asteroids/models/asteroids.m2" );
  27. m2d.leseDaten();
  28. LTDBDatei td;
  29. td.setDatei( new Text( "data/Minigames/Asteroids/bilder/asteroids.ltdb" ) );
  30. td.leseDaten( 0 );
  31. for( int i = 0; i < 7; i++ )
  32. {
  33. Text name = "";
  34. name.append( (char)( 'a' + i ) );
  35. aData[ i ] = m2d.ladeModel( name );
  36. aTextur[ i ] = td.laden( 0, new Text( (char*)( Text( name ) += ".png" ) ) );
  37. }
  38. m2d.setPfad( "data/Minigames/Asteroids/models/ship.m2" );
  39. m2d.leseDaten();
  40. td.setDatei( new Text( "data/Minigames/Asteroids/bilder/ship.ltdb" ) );
  41. td.leseDaten( 0 );
  42. for( int i = 0; i < 2; i++ )
  43. {
  44. Text name = "";
  45. name.append( (char)( 'a' + i ) );
  46. sData[ i ] = m2d.ladeModel( name );
  47. sTextur[ i ] = td.laden( 0, new Text( (char*)( Text( name ) += ".png" ) ) );
  48. }
  49. kam = new LRahmen();
  50. kam->setFarbe( 0xFF777777 );
  51. map = new LRahmen();
  52. map->setFarbe( 0xFFFFFFFF );
  53. map->setPosition( 10, 10 );
  54. map->setSize( 200, 200 );
  55. shipN = 0;
  56. score = 0;
  57. breite = 0;
  58. höhe = 0;
  59. aGröße = 0;
  60. maxTimer = 0;
  61. mTimer = 0;
  62. timer = 0;
  63. beendet = 1;
  64. rend = 0;
  65. gameTime = 0;
  66. tastenStände = 0;
  67. rGen = 0;
  68. ref = 1;
  69. }
  70. // Destruktor
  71. Map::~Map()
  72. {
  73. speichern();
  74. schuss->release();
  75. if( ship )
  76. ship->release();
  77. asteroid->release();
  78. for( int i = 0; i < 7; i++ )
  79. {
  80. aData[ i ]->release();
  81. aTextur[ i ]->release();
  82. }
  83. for( int i = 0; i < 2; i++ )
  84. {
  85. sData[ i ]->release();
  86. sTextur[ i ]->release();
  87. }
  88. delete[] aData;
  89. delete[] aTextur;
  90. delete[] sData;
  91. delete[] sTextur;
  92. kam->release();
  93. map->release();
  94. if( rGen )
  95. rGen->release();
  96. if( klient )
  97. klient->release();
  98. }
  99. // nicht constant
  100. void Map::reset( Text *zOptionen )
  101. {
  102. gameTime = 0;
  103. timer = 0;
  104. beendet = 0;
  105. score = 0;
  106. tastenStände = 0;
  107. if( ship )
  108. ship = ship->release();
  109. schuss->leeren();
  110. asteroid->leeren();
  111. Text *tmp = zOptionen->getTeilText( zOptionen->positionVon( '=' ) + 1, zOptionen->positionVon( ',' ) );
  112. breite = *tmp;
  113. tmp->release();
  114. tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 1 ) + 1, zOptionen->positionVon( ',', 1 ) );
  115. höhe = *tmp;
  116. tmp->release();
  117. tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 2 ) + 1, zOptionen->positionVon( ',', 2 ) );
  118. aGröße = *tmp;
  119. tmp->release();
  120. tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 3 ) + 1, zOptionen->positionVon( ',', 3 ) );
  121. maxTimer = *tmp;
  122. tmp->release();
  123. mTimer = maxTimer;
  124. tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 4 ) + 1, zOptionen->positionVon( ',', 4 ) );
  125. shipN = *tmp;
  126. tmp->release();
  127. tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 5 ) + 1, zOptionen->positionVon( ',', 5 ) );
  128. bool fortsetzen = (int)*tmp != 0;
  129. tmp->release();
  130. Vec2< float > shipPos( (float)( breite / 2 ), (float)( höhe / 2 ) );
  131. Vec2< float > shipSpeed( 0, 0 );
  132. float shipR = (float)-PI / 2;
  133. if( rGen )
  134. rGen = rGen->release();
  135. if( fortsetzen && DateiExistiert( "data/Minigames/Asteroids/data/game.save" ) && klient )
  136. {
  137. if( capture.istOffen() )
  138. capture.close();
  139. capture.setDatei( "data/Minigames/Asteroids/data/game.mgc" );
  140. capture.open( Datei::Style::schreiben | Datei::Style::ende | Datei::Style::lesen );
  141. Datei *save = new Datei();
  142. save->setDatei( "data/Minigames/Asteroids/data/game.save" );
  143. save->open( Datei::Style::lesen );
  144. int br = 0;
  145. int hö = 0;
  146. int gr = 0;
  147. int shn = 0;
  148. __int64 seed;
  149. save->lese( (char*)&seed, 8 );
  150. rGen = new RandomGenerator();
  151. rGen->setSeed( seed );
  152. save->lese( (char*)&gameTime, 8 );
  153. save->lese( (char*)&br, 4 );
  154. save->lese( (char*)&hö, 4 );
  155. save->lese( (char*)&gr, 4 );
  156. save->lese( (char*)&shn, 4 );
  157. if( br == breite && hö == höhe && gr == aGröße && shn == shipN )
  158. {
  159. save->lese( (char*)&score, 4 );
  160. save->lese( (char*)&mTimer, 4 );
  161. // Schiff laden
  162. save->lese( (char*)&shipPos.x, 4 );
  163. save->lese( (char*)&shipPos.y, 4 );
  164. save->lese( (char*)&shipSpeed.x, 4 );
  165. save->lese( (char*)&shipSpeed.y, 4 );
  166. save->lese( (char*)&shipR, 4 );
  167. int anz = 0;
  168. save->lese( (char*)&anz, 4 );
  169. for( int i = 0; i < anz; i++ )
  170. { // Asteroiden Laden
  171. char n = 0;
  172. float x = 0;
  173. float y = 0;
  174. float xs = 0;
  175. float ys = 0;
  176. float rs = 0;
  177. float r = 0;
  178. float gr = 0;
  179. save->lese( &n, 1 );
  180. save->lese( (char*)&x, 4 );
  181. save->lese( (char*)&y, 4 );
  182. save->lese( (char*)&xs, 4 );
  183. save->lese( (char*)&ys, 4 );
  184. save->lese( (char*)&rs, 4 );
  185. save->lese( (char*)&r, 4 );
  186. save->lese( (char*)&gr, 4 );
  187. asteroid->add( new Asteroid( aData[ n ]->getThis(), aTextur[ n ]->getThis(),
  188. Vec2< float >( x, y ), Vec2< float >( xs, ys ), rs, r, gr, n ) );
  189. }
  190. save->lese( (char*)&anz, 4 );
  191. for( int i = 0; i < anz; i++ )
  192. { // Schüsse Laden
  193. float x = 0;
  194. float y = 0;
  195. float xs = 0;
  196. float ys = 0;
  197. save->lese( (char*)&x, 4 );
  198. save->lese( (char*)&y, 4 );
  199. save->lese( (char*)&xs, 4 );
  200. save->lese( (char*)&ys, 4 );
  201. schuss->add( new Schuss( Vec2< float >( x, y ), Vec2< float >( xs, ys ) ) );
  202. }
  203. }
  204. save->close();
  205. save->release();
  206. }
  207. else
  208. {
  209. rGen = new RandomGenerator();
  210. if( klient )
  211. {
  212. if( capture.istOffen() )
  213. capture.close();
  214. DateiRemove( "data/Minigames/Asteroids/data/game.mgc" );
  215. capture.setDatei( "data/Minigames/Asteroids/data/game.mgc" );
  216. capture.erstellen();
  217. capture.open( Datei::Style::schreiben );
  218. __int64 seed = rGen->getSeed();
  219. capture.schreibe( (char*)&seed, 8 );
  220. }
  221. else
  222. {
  223. tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 6 ) + 1 );
  224. rGen->setSeed( (__int64)*tmp );
  225. tmp->release();
  226. }
  227. }
  228. ship = new Ship( sData[ shipN ]->getThis(), sTextur[ shipN ]->getThis(), shipPos, shipSpeed, shipR );
  229. }
  230. void Map::doMausEreignis( MausEreignis &me )
  231. {
  232. }
  233. void Map::doTastaturEreignis( TastaturEreignis &te )
  234. {
  235. cs.lock();
  236. bool ok = 1;
  237. if( !beendet )
  238. {
  239. char tmp = tastenStände;
  240. if( te.taste == 'w' || te.taste == 'W' || te.taste == T_Oben )
  241. {
  242. if( te.id == TE_Press )
  243. tastenStände |= 1;
  244. else
  245. tastenStände &= ~1;
  246. }
  247. if( te.taste == 'd' || te.taste == 'D' || te.taste == T_Rechts )
  248. {
  249. if( te.id == TE_Press )
  250. tastenStände |= 2;
  251. else
  252. tastenStände &= ~2;
  253. }
  254. if( te.taste == 'a' || te.taste == 'A' || te.taste == T_Links )
  255. {
  256. if( te.id == TE_Press )
  257. tastenStände |= 4;
  258. else
  259. tastenStände &= ~4;
  260. }
  261. if( te.taste == T_Space )
  262. {
  263. if( te.id == TE_Press )
  264. {
  265. tastenStände |= 8;
  266. ok = 0;
  267. }
  268. else
  269. tastenStände &= ~8;
  270. }
  271. if( tmp != tastenStände && klient )
  272. {
  273. if( klient )
  274. {
  275. capture.schreibe( (char*)&gameTime, 8 );
  276. capture.schreibe( &tastenStände, 1 );
  277. }
  278. }
  279. }
  280. if( te.taste == T_Space && te.id == TE_Press )
  281. {
  282. if( klient && ok )
  283. {
  284. capture.schreibe( (char*)&gameTime, 8 );
  285. capture.schreibe( "\x10", 1 );
  286. }
  287. schuss->add( ship->getSchuss() );
  288. }
  289. cs.unlock();
  290. }
  291. bool Map::tick( double tickVal )
  292. {
  293. if( beendet )
  294. {
  295. bool ret = rend;
  296. rend = 0;
  297. return ret;
  298. }
  299. cs.lock();
  300. gameTime += tickVal;
  301. // Timer
  302. timer -= tickVal;
  303. if( timer <= 0 )
  304. {
  305. mTimer -= 25;
  306. if( mTimer < 500 )
  307. mTimer = 500;
  308. timer = mTimer / 1000.0;
  309. for( int i = 0; i < rGen->rand() * 4 + 1; i++ )
  310. {
  311. int num = (int)(rGen->rand() * 7);
  312. double sw = ( rGen->rand() * 360 ) / 180.0 * PI;
  313. Vec2< float > speed( (float)cos( sw ), (float)sin( sw ) );
  314. speed *= (float)( rGen->rand() * 40 );
  315. Vec2< float > pos( -200.f, höhe / 2.f );
  316. if( speed.x < 0 )
  317. pos.x = (float)( breite + 200 );
  318. 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 ) );
  319. }
  320. }
  321. // Update
  322. int aAnz = asteroid->getEintragAnzahl();
  323. for( int i = 0; i < aAnz; i++ )
  324. asteroid->z( i )->tick( tickVal, breite, höhe );
  325. int sAnz = schuss->getEintragAnzahl();
  326. for( int i = 0; i < sAnz; i++ )
  327. schuss->z( i )->tick( tickVal );
  328. ship->tick( tickVal, breite, höhe, tastenStände );
  329. for( int i = aAnz - 1; i >= 0; i-- )
  330. {
  331. if( !asteroid->z( i )->amLeben() )
  332. {
  333. score++;
  334. asteroid->remove( i );
  335. aAnz--;
  336. }
  337. }
  338. for( int i = sAnz - 1; i >= 0; i-- )
  339. {
  340. Vec2< float > pos = schuss->z( i )->getPos();
  341. if( pos.x < 0 || pos.y < 0 || pos.x > breite || pos.y > höhe )
  342. {
  343. sAnz--;
  344. schuss->remove( i );
  345. }
  346. }
  347. // Collision
  348. for( int i = sAnz - 1; i >= 0; i-- )
  349. {
  350. Schuss *zs = schuss->z( i );
  351. bool b = 0;
  352. for( int j = 0; j < aAnz; j++ )
  353. b |= asteroid->z( j )->istGetroffen( zs );
  354. if( b )
  355. {
  356. schuss->remove( i );
  357. sAnz--;
  358. }
  359. }
  360. for( int i = 0; i < aAnz && !beendet; i++ )
  361. beendet |= ship->istTod( asteroid->z( i ) );
  362. if( beendet && klient )
  363. {
  364. capture.close();
  365. DateiRemove( "data/Minigames/Asteroids/data/upload.mgc" );
  366. DateiUmbenennen( "data/Minigames/Asteroids/data/game.mgc", "data/Minigames/Asteroids/data/upload.mgc" );
  367. int tmpScore = score;
  368. MinigameKlientV *tmpKlient = klient->getThis();
  369. new AsynchronCall( [ tmpScore, tmpKlient ]()
  370. {
  371. InitDatei *opd = new InitDatei( "data/Minigames/Asteroids/data/optionen.ini" );
  372. opd->laden();
  373. Text optionen = "Width=";
  374. optionen += opd->zWert( "Breite" )->getText();
  375. optionen += ",Height=";
  376. optionen += opd->zWert( "Höhe" )->getText();
  377. optionen += ",Size=";
  378. optionen += opd->zWert( "Größe" )->getText();
  379. optionen += ",Timer=";
  380. optionen += opd->zWert( "Timer" )->getText();
  381. optionen += ",Ship=";
  382. optionen += opd->zWert( "Ship" )->getText();
  383. opd->release();
  384. int status = tmpKlient->reportEndOfGame( "Asteroids", optionen, tmpScore );
  385. if( status == 2 )
  386. {
  387. Datei d;
  388. d.setDatei( "data/Minigames/Asteroids/data/upload.mgc" );
  389. tmpKlient->uploadGameCapture( &d );
  390. }
  391. DateiRemove( "data/Minigames/Asteroids/data/upload.mgc" );
  392. tmpKlient->release();
  393. } );
  394. KSGTDatei *stb = new KSGTDatei( "data/Minigames/Asteroids/data/score.ksgt" );
  395. if( !stb->laden() )
  396. DateiPfadErstellen( "data/Minigames/Asteroids/data/score.ksgt" );
  397. RCArray< Text > *zeile = new RCArray< Text >();
  398. Zeit *zeit = getZeit();
  399. zeile->add( zeit->getZeit( "y-m-d h:i:s" ) );
  400. zeit->release();
  401. Text *scoreT = new Text();
  402. scoreT->append( score );
  403. zeile->add( scoreT );
  404. Text *breiteT = new Text();
  405. breiteT->append( breite );
  406. zeile->add( breiteT );
  407. Text *höheT = new Text();
  408. höheT->append( höhe );
  409. zeile->add( höheT );
  410. Text *timerT = new Text();
  411. timerT->append( maxTimer );
  412. zeile->add( timerT );
  413. Text *aGrößeT = new Text();
  414. aGrößeT->append( aGröße );
  415. zeile->add( aGrößeT );
  416. Text *shipT = new Text();
  417. shipT->append( shipN );
  418. zeile->add( shipT );
  419. stb->addZeile( 7, zeile );
  420. zeile->release();
  421. stb->speichern();
  422. stb->release();
  423. DateiRemove( "data/Minigames/Asteroids/data/game.save" );
  424. }
  425. cs.unlock();
  426. return 1;
  427. }
  428. void Map::render( Bild &zRObj )
  429. {
  430. Punkt kamP = ship->getKamPos( breite, höhe );
  431. zRObj.addScrollOffset( kamP.x, kamP.y );
  432. int aAnz = asteroid->getEintragAnzahl();
  433. for( int i = 0; i < aAnz; i++ )
  434. asteroid->z( i )->render( zRObj );
  435. int sAnz = schuss->getEintragAnzahl();
  436. for( int i = 0; i < sAnz; i++ )
  437. schuss->z( i )->render( zRObj );
  438. ship->render( zRObj );
  439. zRObj.addScrollOffset( -kamP.x, -kamP.y );
  440. if( breite >= 800 || höhe >= 500 )
  441. { // Minimap
  442. const Punkt &dOff = zRObj.getDrawOff();
  443. map->render( zRObj );
  444. zRObj.setPixelDP( 10 + ( ship->getPos().x * 200 ) / breite + dOff.x, 10 + ( ship->getPos().y * 200 ) / höhe + dOff.y, 0xFF00FF00 );
  445. for( int i = 0; i < aAnz; i++ )
  446. zRObj.setPixelDP( 10 + ( asteroid->z( i )->getPos().x * 200 ) / breite + dOff.x, 10 + ( asteroid->z( i )->getPos().y * 200 ) / höhe + dOff.y, 0xFFFF0000 );
  447. for( int i = 0; i < sAnz; i++ )
  448. 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 );
  449. kam->setPosition( 10 + ( 200 * kamP.x ) / breite, 10 + ( 200 * kamP.y ) / höhe );
  450. kam->setSize( ( 200 * 800 ) / breite, ( 200 * 500 ) / höhe );
  451. if( kam->getBreite() > 200 )
  452. kam->setSize( 200, kam->getHeight() );
  453. if( kam->getHeight() > 200 )
  454. kam->setSize( kam->getBreite(), 200 );
  455. kam->render( zRObj );
  456. }
  457. }
  458. void Map::speichern()
  459. {
  460. if( !beendet && klient )
  461. {
  462. if( capture.istOffen() )
  463. capture.close();
  464. Datei *d = new Datei();
  465. d->setDatei( "data/Minigames/Asteroids/data/game.save" );
  466. d->erstellen();
  467. d->open( Datei::Style::schreiben );
  468. __int64 seed = rGen->getSeed();
  469. d->schreibe( (char*)&seed, 8 );
  470. d->schreibe( (char*)&gameTime, 8 );
  471. d->schreibe( (char*)&breite, 4 );
  472. d->schreibe( (char*)&höhe, 4 );
  473. d->schreibe( (char*)&aGröße, 4 );
  474. d->schreibe( (char*)&shipN, 4 );
  475. d->schreibe( (char*)&score, 4 );
  476. d->schreibe( (char*)&mTimer, 4 );
  477. ship->save( d );
  478. int anz = asteroid->getEintragAnzahl();
  479. d->schreibe( (char*)&anz, 4 );
  480. for( int i = 0; i < anz; i++ )
  481. asteroid->z( i )->save( d );
  482. anz = schuss->getEintragAnzahl();
  483. d->schreibe( (char*)&anz, 4 );
  484. for( int i = 0; i < anz; i++ )
  485. schuss->z( i )->save( d );
  486. d->close();
  487. d->release();
  488. }
  489. else if( klient )
  490. DateiRemove( "data/Minigames/Asteroids/data/game.save" );
  491. }
  492. // constant
  493. int Map::getScore() const
  494. {
  495. return score;
  496. }
  497. bool Map::istBeendet() const
  498. {
  499. return beendet;
  500. }
  501. // Reference Counting
  502. Map *Map::getThis()
  503. {
  504. ref++;
  505. return this;
  506. }
  507. Map *Map::release()
  508. {
  509. ref--;
  510. if( !ref )
  511. delete this;
  512. return 0;
  513. }