Map.cpp 13 KB

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