Map.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. #include "Map.h"
  2. #include <Datei.h>
  3. #include <InitDatei.h>
  4. #include <KSGTDatei.h>
  5. #include <Rahmen.h>
  6. #include <TastaturEreignis.h>
  7. #include <Zeit.h>
  8. #include <Text.h>
  9. #include <AsynchronCall.h>
  10. // Inhalt der Map Klasse aus Map.h
  11. // Konstruktor
  12. Map::Map( MinigameKlientV *klient )
  13. {
  14. this->klient = klient;
  15. schlange = new Array< Pos >();
  16. ziele = new Array< Pos >();
  17. feld = new LRahmen();
  18. feld->setFarbe( 0xFFFFFFFF );
  19. kam = new LRahmen();
  20. kam->setFarbe( 0xFF777777 );
  21. map = new LRahmen();
  22. map->setFarbe( 0xFFFFFFFF );
  23. map->setPosition( 10, 10 );
  24. map->setSize( 200, 200 );
  25. beendet = 1;
  26. gameTime = 0;
  27. rGen = 0;
  28. move = 1;
  29. sr = 1;
  30. rend = 0;
  31. ref = 1;
  32. }
  33. // Destruktor
  34. Map::~Map()
  35. {
  36. speichern();
  37. schlange->release();
  38. ziele->release();
  39. feld->release();
  40. kam->release();
  41. map->release();
  42. if( rGen )
  43. rGen->release();
  44. if( klient )
  45. klient->release();
  46. }
  47. // nicht constant
  48. void Map::reset( Text *zOptionen )
  49. {
  50. gameTime = 0;
  51. if( rGen )
  52. rGen = rGen->release();
  53. next = 0;
  54. beendet = 0;
  55. richtung = 0;
  56. addAnzahl = 0;
  57. score = 0;
  58. schlange->leeren();
  59. ziele->leeren();
  60. Text *tmp = zOptionen->getTeilText( zOptionen->positionVon( '=' ) + 1, zOptionen->positionVon( ',' ) );
  61. breite = *tmp;
  62. tmp->release();
  63. tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 1 ) + 1, zOptionen->positionVon( ',', 1 ) );
  64. höhe = *tmp;
  65. tmp->release();
  66. tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 2 ) + 1, zOptionen->positionVon( ',', 2 ) );
  67. zAnzahl = *tmp;
  68. tmp->release();
  69. tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 3 ) + 1, zOptionen->positionVon( ',', 3 ) );
  70. neuAnzahl = *tmp;
  71. tmp->release();
  72. tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 4 ) + 1, zOptionen->positionVon( ',', 4 ) );
  73. geschwindigkeit = *tmp;
  74. tmp->release();
  75. tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 5 ) + 1, zOptionen->positionVon( ',', 5 ) );
  76. bool fortsetzen = (int)*tmp != 0;
  77. tmp->release();
  78. kamPos.x = 0;
  79. kamPos.y = 0;
  80. if( breite > 80 )
  81. kamPos.x = breite / 2 - 40;
  82. if( höhe > 50 )
  83. kamPos.y = höhe / 2 - 25;
  84. if( fortsetzen && DateiExistiert( "data/Minigames/Snake/data/game.save" ) && klient )
  85. {
  86. if( capture.istOffen() )
  87. capture.close();
  88. capture.setDatei( "data/Minigames/Snake/data/game.mgc" );
  89. capture.open( Datei::Style::schreiben | Datei::Style::ende | Datei::Style::lesen );
  90. Datei *save = new Datei();
  91. save->setDatei( "data/Minigames/Snake/data/game.save" );
  92. save->open( Datei::Style::lesen );
  93. int br = 0;
  94. int hö = 0;
  95. __int64 seed;
  96. save->lese( (char*)&seed, 8 );
  97. rGen = new RandomGenerator();
  98. rGen->setSeed( seed );
  99. save->lese( (char*)&gameTime, 8 );
  100. save->lese( (char*)&br, 4 );
  101. save->lese( (char*)&hö, 4 );
  102. if( br == breite && hö == höhe )
  103. {
  104. save->lese( (char*)&score, 4 );
  105. save->lese( (char*)&richtung, 4 );
  106. int anz = 0;
  107. save->lese( (char*)&anz, 4 );
  108. for( int i = 0; i < anz; i++ )
  109. {
  110. Pos p;
  111. save->lese( (char*)&p.x, 2 );
  112. save->lese( (char*)&p.y, 2 );
  113. schlange->add( p );
  114. }
  115. save->lese( (char*)&anz, 4 );
  116. for( int i = 0; i < anz; i++ )
  117. {
  118. Pos p;
  119. save->lese( (char*)&p.x, 2 );
  120. save->lese( (char*)&p.y, 2 );
  121. ziele->add( p );
  122. }
  123. next = 1.0 / geschwindigkeit;
  124. }
  125. save->close();
  126. save->release();
  127. }
  128. else
  129. {
  130. rGen = new RandomGenerator();
  131. if( klient )
  132. {
  133. if( capture.istOffen() )
  134. capture.close();
  135. DateiRemove( "data/Minigames/Snake/data/game.mgc" );
  136. capture.setDatei( "data/Minigames/Snake/data/game.mgc" );
  137. capture.erstellen();
  138. capture.open( Datei::Style::schreiben );
  139. __int64 seed = rGen->getSeed();
  140. capture.schreibe( (char*)&seed, 8 );
  141. }
  142. else
  143. {
  144. tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 6 ) + 1 );
  145. rGen->setSeed( (__int64)*tmp );
  146. tmp->release();
  147. }
  148. }
  149. if( !schlange->getEintragAnzahl() )
  150. schlange->add( Pos{ (short)( breite / 2 ), (short)( höhe / 2 ) } );
  151. }
  152. void Map::doMausEreignis( MausEreignis &me )
  153. {
  154. }
  155. void Map::doTastaturEreignis( TastaturEreignis &te )
  156. {
  157. if( !move )
  158. return;
  159. cs.lock();
  160. if( !beendet )
  161. {
  162. bool save = 0;
  163. if( te.taste == 'w' || te.taste == 'W' || te.taste == T_Oben )
  164. {
  165. if( te.id == TE_Press && richtung != 2 )
  166. {
  167. save = 1;
  168. move = 0;
  169. richtung = 0;
  170. }
  171. }
  172. if( te.taste == 'd' || te.taste == 'D' || te.taste == T_Rechts )
  173. {
  174. if( te.id == TE_Press && richtung != 3 )
  175. {
  176. save = 1;
  177. move = 0;
  178. richtung = 1;
  179. }
  180. }
  181. if( te.taste == 'a' || te.taste == 'A' || te.taste == T_Links )
  182. {
  183. if( te.id == TE_Press && richtung != 1 )
  184. {
  185. save = 1;
  186. move = 0;
  187. richtung = 3;
  188. }
  189. }
  190. if( te.taste == 's' || te.taste == 'S' || te.taste == T_Unten )
  191. {
  192. if( te.id == TE_Press && richtung != 0 )
  193. {
  194. save = 1;
  195. move = 0;
  196. richtung = 2;
  197. }
  198. }
  199. if( klient && save )
  200. {
  201. capture.schreibe( (char*)&gameTime, 8 );
  202. capture.schreibe( (char*)&te.taste, 1 );
  203. }
  204. }
  205. cs.unlock();
  206. }
  207. bool Map::tick( double tickVal )
  208. {
  209. if( beendet )
  210. return 0;
  211. bool ret = rend;
  212. cs.lock();
  213. gameTime += tickVal;
  214. rend = 0;
  215. next -= tickVal;
  216. while( next < 0 && !beendet )
  217. {
  218. move = 1;
  219. ret = 1;
  220. next += 1.0 / geschwindigkeit;
  221. int nx = schlange->get( 0 ).x;
  222. int ny = schlange->get( 0 ).y;
  223. if( richtung == 0 )
  224. ny--;
  225. if( richtung == 1 )
  226. nx++;
  227. if( richtung == 2 )
  228. ny++;
  229. if( richtung == 3 )
  230. nx--;
  231. if( breite > 80 )
  232. {
  233. kamPos.x = nx - 40;
  234. if( kamPos.x < 0 )
  235. kamPos.x = 0;
  236. if( kamPos.x + 80 > breite )
  237. kamPos.x = breite - 80;
  238. }
  239. if( höhe > 50 )
  240. {
  241. kamPos.y = ny - 25;
  242. if( kamPos.y < 0 )
  243. kamPos.y = 0;
  244. if( kamPos.y + 50 > höhe )
  245. kamPos.y = höhe - 50;
  246. }
  247. int sAnz = schlange->getEintragAnzahl();
  248. for( int i = 0; i < sAnz; i++ )
  249. beendet |= nx == schlange->get( i ).x && ny == schlange->get( i ).y;
  250. beendet |= nx < 0 || nx >= breite;
  251. beendet |= ny < 0 || ny >= höhe;
  252. int zAnz = ziele->getEintragAnzahl();
  253. bool neuZ = !zAnz;
  254. for( int i = 0; i < zAnz; i++ )
  255. neuZ |= nx == ziele->get( i ).x && ny == ziele->get( i ).y;
  256. if( neuZ )
  257. {
  258. addAnzahl += neuAnzahl;
  259. ziele->leeren();
  260. for( int i = 0; i < zAnzahl; i++ )
  261. ziele->add( Pos{ (short)( rGen->rand() * breite ), (short)( rGen->rand() * höhe ) } );
  262. if( zAnz )
  263. score++;
  264. }
  265. if( !beendet )
  266. {
  267. schlange->add( Pos{ (short)nx, (short)ny }, 0 );
  268. if( !addAnzahl )
  269. schlange->remove( sAnz );
  270. else
  271. addAnzahl--;
  272. }
  273. else if( klient )
  274. {
  275. capture.close();
  276. DateiRemove( "data/Minigames/Snake/data/upload.mgc" );
  277. DateiUmbenennen( "data/Minigames/Snake/data/game.mgc", "data/Minigames/Snake/data/upload.mgc" );
  278. int tmpScore = score;
  279. MinigameKlientV *tmpKlient = klient->getThis();
  280. new AsynchronCall( [ tmpScore, tmpKlient ]()
  281. {
  282. InitDatei *opd = new InitDatei( "data/Minigames/Snake/data/optionen.ini" );
  283. opd->laden();
  284. Text optionen = "Width=";
  285. optionen += opd->zWert( "Breite" )->getText();
  286. optionen += ",Height=";
  287. optionen += opd->zWert( "Höhe" )->getText();
  288. optionen += ",Ziele=";
  289. optionen += opd->zWert( "Ziele" )->getText();
  290. optionen += ",Anhang=";
  291. optionen += opd->zWert( "Anhängen" )->getText();
  292. optionen += ",Speed=";
  293. optionen += opd->zWert( "Geschwindigkeit" )->getText();
  294. opd->release();
  295. int status = tmpKlient->reportEndOfGame( "Snake", optionen, tmpScore );
  296. if( status == 2 )
  297. {
  298. Datei d;
  299. d.setDatei( "data/Minigames/Snake/data/upload.mgc" );
  300. tmpKlient->uploadGameCapture( &d );
  301. }
  302. DateiRemove( "data/Minigames/Snake/data/upload.mgc" );
  303. tmpKlient->release();
  304. } );
  305. KSGTDatei *stb = new KSGTDatei( "data/Minigames/Snake/data/score.ksgt" );
  306. if( !stb->laden() )
  307. DateiPfadErstellen( "data/Minigames/Snake/data/score.ksgt" );
  308. RCArray< Text > *zeile = new RCArray< Text >();
  309. Zeit *zeit = getZeit();
  310. zeile->add( zeit->getZeit( "y-m-d h:i:s" ) );
  311. zeit->release();
  312. Text *scoreT = new Text();
  313. scoreT->append( score );
  314. zeile->add( scoreT );
  315. Text *breiteT = new Text();
  316. breiteT->append( breite );
  317. zeile->add( breiteT );
  318. Text *höheT = new Text();
  319. höheT->append( höhe );
  320. zeile->add( höheT );
  321. Text *geschwindigkeitT = new Text();
  322. geschwindigkeitT->append( geschwindigkeit );
  323. zeile->add( geschwindigkeitT );
  324. Text *zAnzahlT = new Text();
  325. zAnzahlT->append( zAnzahl );
  326. zeile->add( zAnzahlT );
  327. Text *nAnzahlT = new Text();
  328. nAnzahlT->append( neuAnzahl );
  329. zeile->add( nAnzahlT );
  330. stb->addZeile( 7, zeile );
  331. zeile->release();
  332. stb->speichern();
  333. stb->release();
  334. DateiRemove( "data/Minigames/Snake/data/game.save" );
  335. }
  336. }
  337. cs.unlock();
  338. return ret;
  339. }
  340. void Map::render( Bild &zRObj )
  341. {
  342. int xStart = 0;
  343. int yStart = 0;
  344. if( breite < 80 )
  345. xStart = 400 - breite * 5;
  346. else
  347. xStart -= kamPos.x * 10;
  348. if( höhe < 50 )
  349. yStart = 250 - höhe * 5;
  350. else
  351. yStart -= kamPos.y * 10;
  352. feld->setPosition( xStart, yStart );
  353. feld->setSize( breite * 10, höhe * 10 );
  354. feld->render( zRObj );
  355. bool rMap = breite > 80 || höhe > 50;
  356. int sLän = schlange->getEintragAnzahl();
  357. for( int i = 0; i < sLän; i++ )
  358. zRObj.fillRegion( xStart + schlange->get( i ).x * 10, yStart + schlange->get( i ).y * 10, 9, 9, 0xFFFFFFFF );
  359. int zAnz = ziele->getEintragAnzahl();
  360. for( int i = 0; i < zAnz; i++ )
  361. zRObj.fillRegion( xStart + ziele->get( i ).x * 10, yStart + ziele->get( i ).y * 10, 9, 9, 0xFF00FF00 );
  362. if( rMap )
  363. {
  364. const Punkt &dOff = zRObj.getDrawOff();
  365. map->render( zRObj );
  366. for( int i = 0; i < sLän; i++ )
  367. zRObj.setPixelDP( 10 + ( 200 * schlange->get( i ).x ) / breite + dOff.x, 10 + ( 200 * schlange->get( i ).y ) / höhe + dOff.y, 0xFFFFFFFF );
  368. for( int i = 0; i < zAnz; i++ )
  369. zRObj.setPixelDP( 10 + ( 200 * ziele->get( i ).x ) / breite + dOff.x, 10 + ( 200 * ziele->get( i ).y ) / höhe + dOff.y, 0xFF00FF00 );
  370. kam->setPosition( 10 + ( 200 * kamPos.x ) / breite, 10 + ( 200 * kamPos.y ) / höhe );
  371. kam->setSize( 16000 / breite, ( 10000 ) / höhe );
  372. if( kam->getBreite() > 200 )
  373. kam->setSize( 200, kam->getHeight() );
  374. if( kam->getHeight() > 200 )
  375. kam->setSize( kam->getBreite(), 200 );
  376. kam->render( zRObj );
  377. }
  378. }
  379. void Map::speichern()
  380. {
  381. if( !beendet )
  382. {
  383. if( capture.istOffen() )
  384. capture.close();
  385. Datei *d = new Datei();
  386. d->setDatei( "data/Minigames/Snake/data/game.save" );
  387. d->erstellen();
  388. d->open( Datei::Style::schreiben );
  389. __int64 seed = rGen->getSeed();
  390. d->schreibe( (char*)&seed, 8 );
  391. d->schreibe( (char*)&gameTime, 8 );
  392. d->schreibe( (char*)&breite, 4 );
  393. d->schreibe( (char*)&höhe, 4 );
  394. d->schreibe( (char*)&score, 4 );
  395. d->schreibe( (char*)&richtung, 4 );
  396. int anz = schlange->getEintragAnzahl();
  397. d->schreibe( (char*)&anz, 4 );
  398. for( int i = 0; i < anz; i++ )
  399. {
  400. short p = schlange->get( i ).x;
  401. d->schreibe( (char*)&p, 2 );
  402. p = schlange->get( i ).y;
  403. d->schreibe( (char*)&p, 2 );
  404. }
  405. anz = ziele->getEintragAnzahl();
  406. d->schreibe( (char*)&anz, 4 );
  407. for( int i = 0; i < anz; i++ )
  408. {
  409. short p = ziele->get( i ).x;
  410. d->schreibe( (char*)&p, 2 );
  411. p = ziele->get( i ).y;
  412. d->schreibe( (char*)&p, 2 );
  413. }
  414. d->close();
  415. d->release();
  416. }
  417. else if( klient )
  418. DateiRemove( "data/Minigames/Snake/data/game.save" );
  419. }
  420. // constant
  421. int Map::getScore() const
  422. {
  423. return score;
  424. }
  425. bool Map::istBeendet() const
  426. {
  427. return beendet;
  428. }
  429. // Reference Counting
  430. Map *Map::getThis()
  431. {
  432. ref++;
  433. return this;
  434. }
  435. Map *Map::release()
  436. {
  437. ref--;
  438. if( !ref )
  439. delete this;
  440. return 0;
  441. }