Advertisement
Guest User

Untitled

a guest
Sep 29th, 2013
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.28 KB | None | 0 0
  1. #include <SFML/Graphics.hpp>
  2. #include <vector>
  3. #include <cassert>
  4. #include <chrono>
  5. #include <thread>
  6. #include <random>
  7. #include <iostream>
  8. #include <cmath>
  9. #include <mutex>
  10. #include <future>
  11.  
  12. class BlockGrid;
  13.  
  14. float pointDirection(sf::Vector2f looker, sf::Vector2f target);
  15. template <typename T> int sign(T val);
  16. bool lineOfSight(sf::Vector2f point1, sf::Vector2f point2, BlockGrid & grid);
  17. float distance(sf::Vector2f point1, sf::Vector2f point2);
  18.  
  19. class Screen
  20. {
  21. public:
  22. virtual Screen * update(sf::RenderWindow & window) = 0;
  23. virtual void draw(sf::RenderTarget & target) = 0;
  24. };
  25.  
  26. class Random
  27. {
  28. std::default_random_engine engine;
  29.  
  30. public:
  31. Random::Random()
  32. {
  33. std::random_device device;
  34.  
  35. engine.seed(device());
  36. }
  37.  
  38. Random::Random(long seed)
  39. {
  40. engine.seed(seed);
  41. }
  42.  
  43. bool Random::nextBool()
  44. {
  45. std::uniform_int_distribution<int> distribution(0, 1);
  46.  
  47. return distribution(engine) != 0;
  48. }
  49.  
  50. int Random::nextInt()
  51. {
  52. return engine();
  53. }
  54.  
  55. int Random::nextInt(int n)
  56. {
  57. std::uniform_int_distribution<int> distribution(0, n - 1);
  58.  
  59. return distribution(engine);
  60. }
  61.  
  62.  
  63. float Random::nextFloat()
  64. {
  65. std::uniform_real_distribution<float> distribution(0.f, 1.f);
  66.  
  67. return distribution(engine);
  68. }
  69.  
  70. double Random::nextDouble()
  71. {
  72. std::uniform_real_distribution<float> distribution(0.f, 1.f);
  73.  
  74. return distribution(engine);
  75. }
  76.  
  77. void Random::setSeed(long seed)
  78. {
  79. engine.seed(seed);
  80. }
  81.  
  82. int Random::random_range(int lowerBound, int upperBound)
  83. {
  84. return nextInt(upperBound) + lowerBound;
  85. }
  86.  
  87. int Random::irandom_range(int lowerBound, int upperBound)
  88. {
  89. int number = nextInt((upperBound + 1) - lowerBound) + lowerBound;
  90.  
  91. return number;
  92. }
  93. };
  94.  
  95. class BlockGrid
  96. {
  97. friend void generate(BlockGrid & grid);
  98.  
  99. int blockSize;
  100.  
  101. std::vector<std::vector<bool>> blocks;
  102.  
  103. sf::Vector2i size;
  104.  
  105. void setSolid(int x, int y, bool solid)
  106. {
  107. assert(x >= 0 && x < size.x && y >= 0 && y < size.y);
  108.  
  109. blocks[x][y] = solid;
  110. }
  111.  
  112. public:
  113. BlockGrid(sf::Vector2i size) : blockSize(25), size(size)
  114. {
  115. blocks.resize(size.x);
  116.  
  117. for (auto & vector : blocks)
  118. vector.resize(size.y);
  119.  
  120. for (int x = 0; x < size.x; ++x)
  121. for (int y = 0; y < size.y; ++y)
  122. blocks[x][y] = false;
  123. }
  124.  
  125. bool isSolid(int x, int y)
  126. {
  127. assert(x >= 0 && x < size.x && y >= 0 && y < size.y);
  128.  
  129. return blocks[x][y];
  130. }
  131.  
  132. sf::Vector2i getSize() {return size;}
  133.  
  134. int getBlockSize() {return blockSize;}
  135.  
  136. void draw(sf::RenderTarget & target, sf::FloatRect bounds)
  137. {
  138. static sf::RectangleShape rectangle(sf::Vector2f(blockSize, blockSize));
  139.  
  140. int leftBlockBound = bounds.left/blockSize;
  141. int rightBlockBound = (bounds.left + bounds.width)/blockSize;
  142. int topBlockBound = bounds.top/blockSize;
  143. int bottomBlockBound = (bounds.top + bounds.height)/blockSize;
  144.  
  145. if (leftBlockBound < 0)
  146. leftBlockBound = 0;
  147.  
  148. if (topBlockBound < 0)
  149. topBlockBound = 0;
  150.  
  151. if (rightBlockBound > size.x)
  152. rightBlockBound = size.x;
  153.  
  154. if (bottomBlockBound > size.y)
  155. bottomBlockBound = size.y;
  156.  
  157. for (int x = leftBlockBound; x < rightBlockBound; ++x)
  158. for (int y = topBlockBound; y < bottomBlockBound; ++y)
  159. {
  160. if (blocks[x][y])
  161. rectangle.setFillColor(sf::Color::Black);
  162. else
  163. rectangle.setFillColor(sf::Color::White);
  164.  
  165. rectangle.setPosition(x*blockSize, y*blockSize);
  166.  
  167. target.draw(rectangle);
  168. }
  169. }
  170.  
  171. BlockGrid getSubset(sf::FloatRect bounds)
  172. {
  173. int leftBlockBound = bounds.left/blockSize;
  174. int rightBlockBound = (bounds.left + bounds.width)/blockSize;
  175. int topBlockBound = bounds.top/blockSize;
  176. int bottomBlockBound = (bounds.top + bounds.height)/blockSize;
  177.  
  178. if (leftBlockBound < 0)
  179. leftBlockBound = 0;
  180.  
  181. if (topBlockBound < 0)
  182. topBlockBound = 0;
  183.  
  184. if (rightBlockBound > size.x)
  185. rightBlockBound = size.x;
  186.  
  187. if (bottomBlockBound > size.y)
  188. bottomBlockBound = size.y;
  189.  
  190. BlockGrid blockGrid(sf::Vector2i(rightBlockBound - leftBlockBound, bottomBlockBound - topBlockBound));
  191.  
  192. for (int x = leftBlockBound; x < rightBlockBound; ++x)
  193. for (int y = topBlockBound; y < bottomBlockBound; ++y)
  194. blockGrid.setSolid(x - leftBlockBound, y - topBlockBound, blocks[x][y]);
  195.  
  196. return blockGrid;
  197. }
  198. };
  199.  
  200. void generate(BlockGrid & grid)
  201. {
  202. Random random;
  203.  
  204. for (int x = 0; x < grid.getSize().x; ++x)
  205. for (int y = 0; y < grid.getSize().y; ++y)
  206. if (random.nextBool() && random.nextBool() && random.nextBool())
  207. grid.setSolid(x, y, true);
  208. }
  209.  
  210. class Bullet
  211. {
  212. float speed;
  213. float direction;
  214.  
  215. sf::Vector2f position;
  216.  
  217. public:
  218. Bullet(sf::Vector2f position, float speed, float direction) : position(position), speed(speed), direction(direction) {}
  219.  
  220. void update()
  221. {
  222. position.x += std::cos(direction)*speed;
  223. position.y += std::sin(direction)*speed;
  224. }
  225.  
  226. void draw(sf::RenderTarget & target)
  227. {
  228. static sf::RectangleShape rectangle(sf::Vector2f(2, 2));
  229.  
  230. rectangle.setFillColor(sf::Color::Black);
  231. rectangle.setPosition(position);
  232.  
  233. target.draw(rectangle);
  234. }
  235.  
  236. sf::Vector2f getPosition() {return position;}
  237.  
  238. bool operator==(const Bullet & other) {return (position == other.position && speed == other.speed && direction == other.direction);}
  239. };
  240.  
  241. class Turret
  242. {
  243. int size;
  244.  
  245. bool canShoot;
  246.  
  247. sf::Vector2f position;
  248.  
  249. int shotsPerSecond;
  250.  
  251. sf::Clock clock;
  252.  
  253. void shoot(sf::Vector2f target, std::vector<Bullet> & bullets)
  254. {
  255. float angle = pointDirection(position, target);
  256.  
  257. bullets.push_back(Bullet(position, 5, angle));
  258. }
  259.  
  260. public:
  261. Turret(sf::Vector2f position, int shotsPerSecond) : size(15), canShoot(false), position(position), shotsPerSecond(shotsPerSecond) {}
  262.  
  263. void update(sf::Vector2f target, std::vector<Bullet> & bullets, BlockGrid & grid)
  264. {
  265. if (canShoot && lineOfSight(position, target, grid))
  266. {
  267. canShoot = false;
  268.  
  269. clock.restart();
  270.  
  271. shoot(target, bullets);
  272. }
  273.  
  274. if (!canShoot && shotsPerSecond != 0)
  275. {
  276. if (clock.getElapsedTime().asSeconds() > 1/shotsPerSecond)
  277. canShoot = true;
  278. }
  279. }
  280.  
  281. void draw(sf::RenderTarget & target)
  282. {
  283. static sf::RectangleShape rectangle(sf::Vector2f(size, size));
  284.  
  285. rectangle.setFillColor(sf::Color(255, 255, 0));
  286.  
  287. rectangle.setOrigin(rectangle.getSize().x/2, rectangle.getSize().y/2);
  288.  
  289. rectangle.setPosition(position);
  290.  
  291. target.draw(rectangle);
  292. }
  293.  
  294. sf::Vector2f getPosition() {return position;}
  295.  
  296. int getSize() {return size;}
  297.  
  298. bool operator==(const Turret & other) {return position == other.position && shotsPerSecond == other.shotsPerSecond;}
  299. };
  300.  
  301. class MovingTurret
  302. {
  303. float speed;
  304.  
  305. sf::Vector2f position;
  306.  
  307. int size;
  308. int shotsPerSecond;
  309.  
  310. bool canShoot;
  311.  
  312. sf::Clock clock;
  313.  
  314. void shoot(sf::Vector2f target, std::vector<Bullet> & bullets)
  315. {
  316. float angle = pointDirection(position, target);
  317.  
  318. bullets.push_back(Bullet(position, 5, angle));
  319. }
  320.  
  321. public:
  322. MovingTurret(sf::Vector2f position, float speed, int shotsPerSecond) : position(position), speed(speed), shotsPerSecond(shotsPerSecond), canShoot(false), size(10)
  323. {
  324.  
  325. }
  326.  
  327. void update(sf::Vector2f target, std::vector<Bullet> & bullets, BlockGrid & grid)
  328. {
  329. bool hasLineOfSight = lineOfSight(position, target, grid);
  330.  
  331. if (canShoot && hasLineOfSight)
  332. {
  333. canShoot = false;
  334.  
  335. clock.restart();
  336.  
  337. shoot(target, bullets);
  338. }
  339.  
  340. if (!canShoot && shotsPerSecond != 0)
  341. {
  342. if (clock.getElapsedTime().asSeconds() > 1/shotsPerSecond)
  343. canShoot = true;
  344. }
  345.  
  346. if (!(distance(position, target) < 100 && hasLineOfSight))
  347. {
  348. sf::Vector2f cornerPosition;
  349.  
  350. cornerPosition.x = position.x - size/2;
  351. cornerPosition.y = position.y - size/2;
  352.  
  353. int xMove = target.x - position.x;
  354. int yMove = target.y - position.y;
  355.  
  356. if (std::abs(xMove) > speed)
  357. xMove = xMove > 0 ? speed : -speed;
  358.  
  359. if (std::abs(yMove) > speed)
  360. yMove = yMove > 0 ? speed : -speed;
  361.  
  362. int prevX = position.x;
  363. int prevY = position.y;
  364.  
  365. for (int i = 0; i < std::abs(xMove); ++i)
  366. {
  367. int increment = sign(xMove);
  368.  
  369. position.x += increment;
  370.  
  371. std::vector<sf::Vector2i> blocks;
  372.  
  373. blocks.push_back(sf::Vector2i((position.x - size/2)/grid.getBlockSize(), (position.y - size/2)/grid.getBlockSize()));
  374. blocks.push_back(sf::Vector2i(std::ceil((position.x + size/2) /grid.getBlockSize()), std::ceil((position.y + size/2)/grid.getBlockSize())));
  375. blocks.push_back(sf::Vector2i(std::ceil((position.x + size/2)/grid.getBlockSize()), (position.y - size/2)/grid.getBlockSize()));
  376. blocks.push_back(sf::Vector2i((position.x - size/2)/grid.getBlockSize(), std::ceil((position.y + size/2)/grid.getBlockSize())));
  377.  
  378. if (position.x < 0 || position.x > grid.getBlockSize()*grid.getSize().x - size)
  379. {
  380. position.x = prevX;
  381.  
  382. break;
  383. }
  384.  
  385. for (auto block : blocks)
  386. if (block.x < grid.getSize().x && block.y < grid.getSize().y && block.x >= 0 && block.y >= 0 && grid.isSolid(block.x, block.y))
  387. {
  388. position.x = prevX;
  389.  
  390. break;
  391. }
  392.  
  393. prevX = position.x;
  394. }
  395.  
  396. for (int i = 0; i < std::abs(yMove); ++i)
  397. {
  398. int increment = sign(yMove);
  399.  
  400. position.y += increment;
  401.  
  402. std::vector<sf::Vector2i> blocks;
  403.  
  404. blocks.push_back(sf::Vector2i((position.x - size/2)/grid.getBlockSize(), (position.y - size/2)/grid.getBlockSize()));
  405. blocks.push_back(sf::Vector2i(std::ceil((position.x + size/2) /grid.getBlockSize()), std::ceil((position.y + size/2)/grid.getBlockSize())));
  406. blocks.push_back(sf::Vector2i(std::ceil((position.x + size/2)/grid.getBlockSize()), (position.y - size/2)/grid.getBlockSize()));
  407. blocks.push_back(sf::Vector2i((position.x - size/2)/grid.getBlockSize(), std::ceil((position.y + size/2)/grid.getBlockSize())));
  408.  
  409. if (position.y < 0 || position.y > grid.getBlockSize()*grid.getSize().y - size)
  410. {
  411. position.y = prevY;
  412.  
  413. break;
  414. }
  415.  
  416. for (auto block : blocks)
  417. if (block.x < grid.getSize().x && block.y < grid.getSize().y && block.x >= 0 && block.y >= 0 && grid.isSolid(block.x, block.y))
  418. {
  419. position.y = prevY;
  420.  
  421. break;
  422. }
  423.  
  424. prevY = position.y;
  425. }
  426.  
  427. /*position = cornerPosition;
  428.  
  429. int extra = (size/2) % 2 == 0 ? 0 : 1;
  430.  
  431. position.x += size/2 + extra;
  432. position.y += size/2 + extra;*/
  433. }
  434. }
  435.  
  436. void draw(sf::RenderTarget & target)
  437. {
  438. static sf::RectangleShape rectangle(sf::Vector2f(size, size));
  439.  
  440. rectangle.setFillColor(sf::Color::Green);
  441.  
  442. rectangle.setSize(sf::Vector2f(size, size));
  443.  
  444. rectangle.setPosition(position);
  445.  
  446. rectangle.setOrigin(rectangle.getSize().x/2, rectangle.getSize().y/2);
  447.  
  448. target.draw(rectangle);
  449. }
  450.  
  451. sf::Vector2f getPosition() {return position;}
  452.  
  453. int getSize() {return size;}
  454. };
  455.  
  456. class Player
  457. {
  458. sf::Vector2f position;
  459.  
  460. int size;
  461.  
  462. public:
  463. Player() : position(0, 0), size(25) {}
  464.  
  465. void update(BlockGrid & grid)
  466. {
  467. int xMove = 0;
  468. int yMove = 0;
  469.  
  470. int prevX = position.x;
  471. int prevY = position.y;
  472.  
  473. int moveAmount = 3;
  474.  
  475. if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
  476. xMove = -moveAmount;
  477.  
  478. if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
  479. xMove = moveAmount;
  480.  
  481. if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
  482. yMove = -moveAmount;
  483.  
  484. if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
  485. yMove = moveAmount;
  486.  
  487.  
  488.  
  489. for (int i = 0; i < std::abs(xMove); ++i)
  490. {
  491. int increment = sign(xMove);
  492.  
  493. position.x += increment;
  494.  
  495. std::vector<sf::Vector2i> blocks;
  496.  
  497. blocks.push_back(sf::Vector2i(position.x/grid.getBlockSize(), position.y/grid.getBlockSize()));
  498. blocks.push_back(sf::Vector2i(std::ceil(position.x/grid.getBlockSize()), std::ceil(position.y/grid.getBlockSize())));
  499. blocks.push_back(sf::Vector2i(std::ceil(position.x/grid.getBlockSize()), position.y/grid.getBlockSize()));
  500. blocks.push_back(sf::Vector2i(position.x/grid.getBlockSize(), std::ceil(position.y/grid.getBlockSize())));
  501.  
  502. if (position.x < 0 || position.x > grid.getBlockSize()*grid.getSize().x - size)
  503. {
  504. position.x = prevX;
  505.  
  506. break;
  507. }
  508.  
  509. for (auto block : blocks)
  510. if (grid.isSolid(block.x, block.y))
  511. {
  512. position.x = prevX;
  513.  
  514. break;
  515. }
  516.  
  517. prevX = position.x;
  518. }
  519.  
  520. for (int i = 0; i < std::abs(yMove); ++i)
  521. {
  522. int increment = sign(yMove);
  523.  
  524. position.y += increment;
  525.  
  526. std::vector<sf::Vector2i> blocks;
  527.  
  528. blocks.push_back(sf::Vector2i(position.x/grid.getBlockSize(), position.y/grid.getBlockSize()));
  529. blocks.push_back(sf::Vector2i(std::ceil(position.x/grid.getBlockSize()), std::ceil(position.y/grid.getBlockSize())));
  530. blocks.push_back(sf::Vector2i(std::ceil(position.x/grid.getBlockSize()), position.y/grid.getBlockSize()));
  531. blocks.push_back(sf::Vector2i(position.x/grid.getBlockSize(), std::ceil(position.y/grid.getBlockSize())));
  532.  
  533. if (position.y < 0 || position.y > grid.getBlockSize()*grid.getSize().y - size)
  534. {
  535. position.y = prevY;
  536.  
  537. break;
  538. }
  539.  
  540. for (auto block : blocks)
  541. if (grid.isSolid(block.x, block.y))
  542. {
  543. position.y = prevY;
  544.  
  545. break;
  546. }
  547.  
  548. prevY = position.y;
  549. }
  550. }
  551.  
  552. void draw(sf::RenderTarget & target)
  553. {
  554. static sf::RectangleShape rectangle(sf::Vector2f(size, size));
  555.  
  556. rectangle.setFillColor(sf::Color::Red);
  557.  
  558. rectangle.setPosition(position);
  559.  
  560. target.draw(rectangle);
  561. }
  562.  
  563. int getSize() {return size;}
  564.  
  565. sf::Vector2f getPosition() {return position;}
  566. };
  567.  
  568.  
  569.  
  570. float pointDirection(sf::Vector2f looker, sf::Vector2f target)
  571. {
  572. return 3.12 + std::atan2(looker.y - target.y, looker.x - target.x);
  573. }
  574.  
  575. float distance(sf::Vector2f point1, sf::Vector2f point2)
  576. {
  577. return std::sqrt(std::pow(point1.x - point2.x, 2) + std::pow(point1.y - point2.y, 2));
  578. }
  579.  
  580. bool bulletGridCollision(Bullet bullet, BlockGrid & blockGrid, int blockSize)
  581. {
  582. return blockGrid.isSolid(static_cast<int> (bullet.getPosition().x/blockSize), static_cast<int> (bullet.getPosition().y/blockSize));
  583. }
  584.  
  585. bool playerBulletCollision(Player player, Bullet bullet)
  586. {
  587. sf::FloatRect rect;
  588.  
  589. rect.left = player.getPosition().x;
  590. rect.top = player.getPosition().y;
  591.  
  592. rect.width = player.getSize();
  593. rect.height = player.getSize();
  594.  
  595. if (rect.contains(bullet.getPosition()))
  596. return true;
  597. else
  598. return false;
  599. }
  600.  
  601. template <typename T> int sign(T val) {
  602. return (T(0) < val) - (val < T(0));
  603. }
  604.  
  605. void populateTurrets(std::vector<Turret> & turrets, BlockGrid & grid)
  606. {
  607. std::vector<sf::Vector2i> emptyBlocks;
  608.  
  609. for (int x = 0; x < grid.getSize().x; ++x)
  610. for (int y = 0; y < grid.getSize().y; ++y)
  611. if (!grid.isSolid(x, y))
  612. emptyBlocks.push_back(sf::Vector2i(x, y));
  613.  
  614.  
  615. Random random;
  616.  
  617. for (auto block : emptyBlocks)
  618. if (random.irandom_range(0, 32) == 0)
  619. turrets.push_back(Turret(sf::Vector2f(block.x*grid.getBlockSize() + grid.getBlockSize()/2, block.y*grid.getBlockSize() + grid.getBlockSize()/2), 1));
  620. }
  621.  
  622. void populateMovingTurrets(std::vector<MovingTurret> & turrets, BlockGrid & grid)
  623. {
  624. std::vector<sf::Vector2i> emptyBlocks;
  625.  
  626. for (int x = 0; x < grid.getSize().x; ++x)
  627. for (int y = 0; y < grid.getSize().y; ++y)
  628. if (!grid.isSolid(x, y))
  629. emptyBlocks.push_back(sf::Vector2i(x, y));
  630.  
  631.  
  632. Random random;
  633.  
  634. for (auto block : emptyBlocks)
  635. if (random.irandom_range(0, 128) == 0)
  636. turrets.push_back(MovingTurret(sf::Vector2f(block.x*grid.getBlockSize() + grid.getBlockSize()/2, block.y*grid.getBlockSize() + grid.getBlockSize()/2), 1, 1));
  637. }
  638.  
  639. bool lineOfSight(sf::Vector2f point1, sf::Vector2f point2, BlockGrid & grid)
  640. {
  641. float angle = pointDirection(point1, point2);
  642.  
  643. for (float distanceWalked = 0; distanceWalked < distance(point1, point2); distanceWalked += 0.9)
  644. {
  645. int posX = point1.x + std::cos(angle)*distanceWalked;
  646. int posY = point1.y + std::sin(angle)*distanceWalked;
  647.  
  648. if (grid.isSolid(posX/grid.getBlockSize(), posY/grid.getBlockSize()))
  649. return false;
  650. }
  651.  
  652. return true;
  653. }
  654.  
  655. class GameScreen : public Screen
  656. {
  657. std::vector<Bullet> bullets;
  658. std::vector<Turret> turrets;
  659. std::vector<MovingTurret> movingTurrets;
  660.  
  661. std::vector<Turret *> activeTurrets;
  662. std::vector<MovingTurret *> activeMovingTurrets;
  663.  
  664. Player player;
  665.  
  666. BlockGrid blockGrid;
  667.  
  668. sf::FloatRect activeBounds;
  669.  
  670. sf::View view;
  671.  
  672. public:
  673. GameScreen(const sf::RenderWindow & window) : blockGrid(sf::Vector2i(100, 20)), view(window.getDefaultView())
  674. {
  675. generate(blockGrid);
  676.  
  677. populateTurrets(turrets, blockGrid);
  678. populateMovingTurrets(movingTurrets, blockGrid);
  679.  
  680. activeBounds.left = 0;
  681. activeBounds.top = 0;
  682. activeBounds.width = window.getSize().x*1.1;
  683. activeBounds.height = window.getSize().y*1.1;
  684. }
  685.  
  686. Screen * update(sf::RenderWindow & window)
  687. {
  688. sf::Event evt;
  689.  
  690. while (window.pollEvent(evt))
  691. {
  692. if (evt.type == sf::Event::Closed)
  693. std::exit(0);
  694. }
  695.  
  696. for (Bullet & bullet : bullets)
  697. bullet.update();
  698.  
  699. activeTurrets.clear();
  700. activeMovingTurrets.clear();
  701.  
  702. for (Turret & turret : turrets)
  703. if (turret.getPosition().x > activeBounds.left - 10 && turret.getPosition().x < activeBounds.left + activeBounds.width + 10 && turret.getPosition().y > activeBounds.top - 10 && turret.getPosition().y < activeBounds.top + activeBounds.height + 10)
  704. activeTurrets.push_back(&turret);
  705.  
  706. for (MovingTurret & turret : movingTurrets)
  707. if (turret.getPosition().x > activeBounds.left - 10 && turret.getPosition().x < activeBounds.left + activeBounds.width + 10 && turret.getPosition().y > activeBounds.top - 10 && turret.getPosition().y < activeBounds.top + activeBounds.height + 10)
  708. activeMovingTurrets.push_back(&turret);
  709.  
  710. for (Turret * turret : activeTurrets)
  711. turret->update(player.getPosition(), bullets, blockGrid);
  712.  
  713. for (MovingTurret * turret : activeMovingTurrets)
  714. turret->update(player.getPosition(), bullets, blockGrid);
  715.  
  716. player.update(blockGrid);
  717.  
  718. activeBounds.left = view.getCenter().x - view.getSize().x/2;
  719. activeBounds.top = view.getCenter().y - view.getSize().y/2;
  720.  
  721. std::vector<Bullet> toRemove;
  722.  
  723. for (Bullet & bullet : bullets)
  724. {
  725. if (bullet.getPosition().x < 0 || bullet.getPosition().x >= blockGrid.getBlockSize()*blockGrid.getSize().x || bullet.getPosition().y < 0 || bullet.getPosition().y >= blockGrid.getBlockSize()*blockGrid.getSize().y)
  726. {
  727. toRemove.push_back(bullet);
  728.  
  729. continue;
  730. }
  731.  
  732. if (bulletGridCollision(bullet, blockGrid, 25))
  733. toRemove.push_back(bullet);
  734. }
  735.  
  736. for (Bullet & bullet : toRemove)
  737. bullets.erase(std::find(bullets.begin(), bullets.end(), bullet));
  738.  
  739. for (Bullet & bullet : bullets)
  740. if (playerBulletCollision(player, bullet))
  741. std::cout << "Player died.\n";
  742.  
  743. return this;
  744. }
  745.  
  746. void draw(sf::RenderTarget & target)
  747. {
  748. target.clear(sf::Color::White);
  749.  
  750. view.setCenter(player.getPosition());
  751.  
  752. if (view.getCenter().x - view.getSize().x/2 < 0)
  753. view.setCenter(view.getSize().x/2, view.getCenter().y);
  754.  
  755. if (view.getCenter().y - view.getSize().y/2 < 0)
  756. view.setCenter(view.getCenter().x, view.getSize().y/2);
  757.  
  758. if (view.getCenter().x >= blockGrid.getBlockSize()*blockGrid.getSize().x - view.getSize().x/2)
  759. view.setCenter(blockGrid.getBlockSize()*blockGrid.getSize().x - view.getSize().x/2, view.getCenter().y);
  760.  
  761. if (view.getCenter().y >= blockGrid.getBlockSize()*blockGrid.getSize().y - view.getSize().y/2)
  762. view.setCenter(view.getCenter().x, blockGrid.getBlockSize()*blockGrid.getSize().y - view.getSize().y/2);
  763.  
  764.  
  765.  
  766. target.setView(view);
  767.  
  768. blockGrid.draw(target, activeBounds);
  769.  
  770. player.draw(target);
  771.  
  772. for (Bullet & bullet : bullets)
  773. bullet.draw(target);
  774.  
  775. for (Turret * turret : activeTurrets)
  776. turret->draw(target);
  777.  
  778. for (MovingTurret * turret : activeMovingTurrets)
  779. turret->draw(target);
  780. }
  781. };
  782.  
  783. class MainMenuScreen : public Screen
  784. {
  785. sf::Text titleText;
  786. sf::Text quitText;
  787. sf::Text playText;
  788. sf::Text instructionsText;
  789.  
  790.  
  791. public:
  792. MainMenuScreen(sf::Vector2i windowSize, sf::Font & font)
  793. {
  794. titleText.setFont(font);
  795. quitText.setFont(font);
  796. playText.setFont(font);
  797. instructionsText.setFont(font);
  798.  
  799. titleText.setColor(sf::Color::Black);
  800. titleText.setCharacterSize(30);
  801. titleText.setString("Death By Dots");
  802. titleText.setOrigin(titleText.getLocalBounds().width/2, titleText.getLocalBounds().height/2);
  803. titleText.setPosition(windowSize.x/2, windowSize.y/7);
  804.  
  805. playText.setColor(sf::Color::Black);
  806. playText.setCharacterSize(20);
  807. playText.setString("Play");
  808. playText.setOrigin(playText.getLocalBounds().width/2, playText.getLocalBounds().height/2);
  809. playText.setPosition(windowSize.x/2, windowSize.y/4);
  810.  
  811. instructionsText.setColor(sf::Color::Black);
  812. instructionsText.setCharacterSize(20);
  813. instructionsText.setString("Instructions");
  814. instructionsText.setOrigin(instructionsText.getLocalBounds().width/2, instructionsText.getLocalBounds().height/2);
  815. instructionsText.setPosition(windowSize.x/2, windowSize.y/3);
  816.  
  817. quitText.setColor(sf::Color::Black);
  818. quitText.setCharacterSize(20);
  819. quitText.setString("Quit");
  820. quitText.setOrigin(quitText.getLocalBounds().width/2, quitText.getLocalBounds().height/2);
  821. quitText.setPosition(windowSize.x/2, windowSize.y/2);
  822. }
  823.  
  824. Screen * update(sf::RenderWindow & window)
  825. {
  826. sf::Event evt;
  827.  
  828. while (window.pollEvent(evt))
  829. {
  830. if (evt.type == sf::Event::Closed)
  831. return nullptr;
  832.  
  833. if (evt.type == sf::Event::MouseButtonPressed)
  834. {
  835. if (evt.mouseButton.x >= playText.getGlobalBounds().left && evt.mouseButton.y >= playText.getGlobalBounds().top &&
  836. evt.mouseButton.x < playText.getGlobalBounds().left + playText.getGlobalBounds().width &&
  837. evt.mouseButton.y < playText.getGlobalBounds().top + playText.getGlobalBounds().height)
  838. return new GameScreen(window);
  839.  
  840. if (evt.mouseButton.x >= quitText.getGlobalBounds().left && evt.mouseButton.y >= quitText.getGlobalBounds().top &&
  841. evt.mouseButton.x < quitText.getGlobalBounds().left + quitText.getGlobalBounds().width &&
  842. evt.mouseButton.y < quitText.getGlobalBounds().top + quitText.getGlobalBounds().height)
  843. {
  844. return nullptr;
  845. }
  846. }
  847. }
  848.  
  849. return this;
  850. }
  851.  
  852. void draw(sf::RenderTarget & target)
  853. {
  854. target.clear(sf::Color::White);
  855.  
  856. target.draw(titleText);
  857. target.draw(playText);
  858. target.draw(instructionsText);
  859. target.draw(quitText);
  860. }
  861. };
  862.  
  863.  
  864. int main()
  865. {
  866. sf::Font font;
  867.  
  868. font.loadFromFile("arial.ttf");
  869.  
  870. sf::RenderWindow window(sf::VideoMode(500, 500), "Gun Game");
  871.  
  872. Screen * currentScreen = new MainMenuScreen(sf::Vector2i(window.getSize().x, window.getSize().y), font);
  873.  
  874. sf::Clock clock;
  875.  
  876.  
  877.  
  878. /*sf::RectangleShape startRectangle(sf::Vector2f(blockGrid.getBlockSize()*3, blockGrid.getSize().y*blockGrid.getBlockSize()));
  879.  
  880. startRectangle.setPosition(0, 0);
  881.  
  882. startRectangle.setFillColor(sf::Color(0, 0, 255, 50));
  883.  
  884. sf::RectangleShape endRectangle(sf::Vector2f(blockGrid.getBlockSize()*3, blockGrid.getSize().y*blockGrid.getBlockSize()));
  885.  
  886. endRectangle.setPosition(blockGrid.getBlockSize()*(blockGrid.getSize().x - 3), 0);
  887.  
  888. endRectangle.setFillColor(sf::Color(255, 0, 0, 50));*/
  889.  
  890. while (true)
  891. {
  892. if (clock.getElapsedTime().asSeconds() > 0.05)
  893. {
  894. clock.restart();
  895.  
  896. //UPDATES
  897.  
  898. Screen * screen = currentScreen->update(window);
  899.  
  900. if (screen == nullptr)
  901. {
  902. delete currentScreen;
  903.  
  904. std::exit(0);
  905. }
  906.  
  907. if (screen != currentScreen)
  908. {
  909. delete currentScreen;
  910.  
  911. currentScreen = screen;
  912.  
  913. continue;
  914. }
  915.  
  916. //DRAW
  917.  
  918. currentScreen->draw(window);
  919.  
  920. window.display();
  921. }
  922.  
  923. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  924. }
  925. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement