[MOD] Whack-a-Mole Point Game

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • [MOD] Whack-a-Mole Point Game



      Hello, friends!
      This mode is a whack-a-mole game where you earn points to obtain dark matter.
      A mole appears every second, and clicking it earns you 100 points. The game lasts 30 seconds. If you don't reach 1,000 points, you won't receive any.
      You can play up to 10 times a day.
      You can adjust the dark matter and time by modifying the internal code.

      SQL

      SQL-Query

      1. CREATE TABLE `uni1_gamedu` (
      2. `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
      3. `username` VARCHAR(32) NOT NULL DEFAULT '',
      4. `user_id` INT UNSIGNED NOT NULL DEFAULT 0,
      5. `time` INT NOT NULL DEFAULT 0,
      6. `score` INT UNSIGNED NOT NULL DEFAULT 0,
      7. `type` TINYINT UNSIGNED NOT NULL DEFAULT 0,
      8. `universe` TINYINT UNSIGNED NOT NULL,
      9. PRIMARY KEY (`id`)
      10. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;


      Add php source
      includes/pages/game/ShowGameduPage.class.php

      PHP Source Code

      1. <?php
      2. /**
      3. * 2Moons
      4. * @noonn
      5. */
      6. class ShowGameduPage extends AbstractGamePage
      7. {
      8. public static $requireModule = 0;
      9. function __construct()
      10. {
      11. parent::__construct();
      12. }
      13. function show()
      14. {
      15. global $LNG, $USER, $resource;
      16. $db = Database::get();
      17. //Delete data older than one day
      18. $sql = "DELETE FROM uni1_gamedu WHERE type = '0' AND time < :time;";
      19. $db->delete($sql, array(
      20. ':time' => (TIMESTAMP - (60 * 60 * 24))
      21. ));
      22. //Check remaining time
      23. $sql = "SELECT * FROM uni1_gamedu WHERE type = '0' AND universe = :uni AND user_id = :userid AND time > :time ORDER BY time ASC;";
      24. $search = $db->select($sql, array(
      25. ':uni' => Universe::current(),
      26. ':userid' => $USER['id'],
      27. ':time' => (TIMESTAMP - (60 * 60 * 24))
      28. ));
      29. $SearchResult = array();
      30. foreach($search as $s)
      31. {
      32. $ver = TIMESTAMP - $s['time']; //Save time
      33. $restart = pretty_time((60 * 60 * 24) - $ver);
      34. $SearchResult[] = array(
      35. 'username' => $s['username'],
      36. 'time' => $restart,
      37. 'universe' => $s['universe']
      38. );
      39. }
      40. //Check remaining times
      41. $sql = "SELECT COUNT(*) as count FROM uni1_gamedu WHERE type = '0' AND universe = :universe AND user_id = :user_id;";
      42. $Count = $db->selectSingle($sql, array(
      43. ':universe' => Universe::current(),
      44. ':user_id' => $USER['id']
      45. ), 'count');
      46. if(isset($_POST['feld']) && $_POST['feld']=="1")
      47. {
      48. $point = HTTP::_GP('gp', 0);
      49. if(!ctype_digit((string)$point)) {
      50. $this->printMessage("<span style=font-size:1.2em;color:#9BC800>An incorrect score was entered.</span>", array(array(
      51. 'label' => $LNG['sys_back'],
      52. 'url' => 'game.php?page=gamedu'
      53. )));
      54. }
      55. if($Count >= 10){
      56. $this->printMessage("<span style=font-size:1.2em;color:yellow>You cannot exceed the current possible number of times.</font>", array(array(
      57. 'label' => $LNG['sys_back'],
      58. 'url' => 'game.php?page=gamedu'
      59. )));
      60. }elseif($point >= 1000 && $point <= 30000 && $Count < 10){
      61. $USER[$resource[921]] += 50; // <-- 50 dark matter award
      62. $sql = "INSERT INTO uni1_gamedu SET username = :username, user_id = :user_id, time = :time, score = :score, type = '0', universe = :universe;";
      63. $db->insert($sql, array(
      64. ':username' => $USER['username'],
      65. ':user_id' => $USER['id'],
      66. ':time' => TIMESTAMP,
      67. ':score' => $point,
      68. ':universe' => Universe::current()
      69. ));
      70. $this->printMessage("<span style=font-size:1.2em;color:yellow>Obtain 50 dark matter, ".$point." points were registered.</font>", array(array(
      71. 'label' => $LNG['sys_back'],
      72. 'url' => 'game.php?page=gamedu'
      73. )));
      74. }elseif($point < 1000){
      75. $this->printMessage("<span style=font-size:1.2em;color:yellow>If your score is lower than 1,000, you cannot register and will not be counted towards your total.<br>You can try again.</font>", array(array(
      76. 'label' => $LNG['sys_back'],
      77. 'url' => 'game.php?page=gamedu'
      78. )));
      79. }else{
      80. $this->printMessage("<span style=font-size:1.2em;color:yellow>This is an unusual approach.</font>", array(array(
      81. 'label' => $LNG['sys_back'],
      82. 'url' => 'game.php?page=gamedu'
      83. )));
      84. }
      85. }
      86. $sql = "SELECT username, id, max(score) as score FROM uni1_gamedu WHERE type = '0' AND universe = :universe GROUP BY username ORDER BY score DESC LIMIT 10;";
      87. $rank = $db->select($sql, array(
      88. ':universe' => Universe::current()
      89. ));
      90. $rankplayer = array();
      91. foreach($rank as $rankplayerrow) {
      92. $rankplayer[$rankplayerrow['id']] = "{$rankplayerrow['username']} {$rankplayerrow['score']}";
      93. }
      94. $this->assign(array(
      95. 'rank' => $rankplayer,
      96. 'count' => $Count,
      97. 'SearchResult' => $SearchResult
      98. ));
      99. $this->display('page.gamedu.default.tpl');
      100. }
      101. }
      Display All

      The tpl source is in the reply below.
      You can change the image path in css: background: url('styles/theme/gow/dudgi.png') center/cover no-repeat; /* <--------- Mole Image Path */

      I've attached the mole image. You can change it to a different image.

      Have a good day.
      --------------------------------------------------------------------------------------
    • Add tpl source

      page.gamedu.default.tpl

      HTML Source Code

      1. {block name="title" prepend}{$LNG.lm_fleettrader}{/block}
      2. {block name="content"}
      3. <style>
      4. .tdst {
      5. background-color:#252F3B;
      6. height:30px;
      7. text-align:left;
      8. }
      9. #gameBoard {
      10. display: grid;
      11. grid-template-columns: repeat(6, 100px);
      12. gap: 10px;
      13. justify-content: center;
      14. margin: 20px auto;
      15. }
      16. .hole {
      17. width: 100px;
      18. height: 100px;
      19. background-color: #1a2a3a;
      20. border-radius: 50%;
      21. position: relative;
      22. overflow: hidden;
      23. box-shadow: inset 0 5px 10px #000;
      24. cursor: pointer;
      25. }
      26. .mole {
      27. position: absolute;
      28. bottom: -100%;
      29. left: 0;
      30. width: 100%;
      31. height: 100%;
      32. background: url('styles/theme/gow/dudgi.png') center/cover no-repeat; /* <--------- Mole Image Path */
      33. transition: bottom 0.2s;
      34. }
      35. .mole.up {
      36. bottom: 0;
      37. }
      38. </style>
      39. <div class="content_page" style="font-size:1.2em">
      40. <div class="title">Whack-a-Mole Game </div>
      41. <div>
      42. <table align="center" width="100%">
      43. <tr>
      44. <td align=center>
      45. <font color="lime">Click Start Game</font> and a mole will appear randomly for 30 seconds.<br>
      46. Catch a mole by clicking on it to earn points!<br>
      47. <font color="lime">Catch as many as you can!</font><br>
      48. <font color="lime">Currently available number of turns: {10 - $count}</font><br>
      49. <form name="f" action="" method="post">
      50. <input type="hidden" name="gpoint" value="">
      51. <!-- Game board -->
      52. <div id="gameBoard"></div>
      53. <br>
      54. <table>
      55. <tr>
      56. <td style="width:250px;text-align:left;">
      57. <font color="#01DF01">[Score ranking]</font><br>
      58. {foreach name=rank key=id item=score from=$rank}
      59. {if !$smarty.foreach.rank.first}<br>{/if}*{$score} Point
      60. {/foreach}
      61. </td>
      62. <td class="transparent center" width="20%">
      63. <input type="button" name="combo" value="0">Acquisition&nbsp;&nbsp;
      64. <input type="button" value="Timer" name="b">
      65. </td>
      66. <td align="center" style="width:400px">
      67. Current score : <input type="text" size=6 name="gp" value="0" readonly><br>
      68. <textarea style="background:#002B44;color:#fff;height:7.25em;" NAME="report" ROWS="5" COLS="60"></textarea>
      69. </td>
      70. <td>
      71. <input class="submit0" type="button" onclick="init();" value="Game start">
      72. <br><br>
      73. <input type="hidden" name="feld" value="1">
      74. <input class="submit0" type="button" onclick="save_rank()" value="Registration">
      75. </td>
      76. </tr>
      77. </table>
      78. </form>
      79. </td>
      80. </tr>
      81. </table>
      82. <table width="100%" border="0" cellpadding="0" cellspacing="1">
      83. <tr>
      84. <th colspan="4">
      85. <br>
      86. </th>
      87. </tr>
      88. <tr class="title" >
      89. <th style="height:20px" class="fontsize12 title">Number of games</th>
      90. <th class="fontsize12 title">User</th>
      91. <th class="fontsize12 title">waiting</th>
      92. <th class="fontsize12 title">Universe</th>
      93. </tr>
      94. {foreach item=SearchInfo from=$SearchResult}
      95. <tr id="tdcolor">
      96. <td style="height:27px;color:#9BC800" class="fontsize13 bline">{$SearchInfo@iteration}</td>
      97. <td style="height:27px;" class="fontsize12 bline">{$SearchInfo.username}</td>
      98. <td style="height:27px;color:#9BC800" class="fontsize12 bline">{$SearchInfo.time}</td>
      99. <td style="height:27px;" class="fontsize12 bline">{$SearchInfo.universe}</td>
      100. </tr>
      101. {/foreach}
      102. </table>
      103. <br><br>
      104. </div>
      105. </div>
      106. <br>
      107. {/block}
      108. {block name="script" append}
      109. <script>
      110. let score = 0;
      111. let combo = 0;
      112. let timeLeft = 30;
      113. let timerId = null;
      114. let moleTimer = null;
      115. let gameStarted = false;
      116. function createGameBoard() {
      117. const board = document.getElementById('gameBoard');
      118. board.innerHTML = '';
      119. for (let i = 0; i < 12; i++) {
      120. const hole = document.createElement('div');
      121. hole.className = 'hole';
      122. const mole = document.createElement('div');
      123. mole.className = 'mole';
      124. mole.addEventListener('click', function() { hitMole(mole); });
      125. hole.appendChild(mole);
      126. board.appendChild(hole);
      127. }
      128. }
      129. function init() {
      130. if (gameStarted) return;
      131. gameStarted = true;
      132. score = 0;
      133. combo = 0;
      134. timeLeft = 30;
      135. document.f.gp.value = 0;
      136. document.f.combo.value = 0;
      137. document.f.report.value = '';
      138. document.f.b.value = '30 seconds left';
      139. createGameBoard();
      140. runTimer();
      141. startMoles();
      142. }
      143. function runTimer() {
      144. timerId = setInterval(() => {
      145. timeLeft--;
      146. document.f.b.value = timeLeft + 's left';
      147. if (timeLeft <= 0) endGame();
      148. }, 1000);
      149. }
      150. function startMoles() {
      151. const moles = document.querySelectorAll('.mole');
      152. moleTimer = setInterval(() => {
      153. const randomIndex = Math.floor(Math.random() * moles.length);
      154. const mole = moles[randomIndex];
      155. mole.classList.add('up');
      156. setTimeout(() => {
      157. mole.classList.remove('up');
      158. }, 500); // ← Hold for 0.5 seconds
      159. }, 1000); // ← The next mole is about 1 second apart
      160. }
      161. function hitMole(mole) {
      162. if (!mole.classList.contains('up')) return;
      163. mole.classList.remove('up');
      164. score += 100;
      165. combo++;
      166. document.f.gp.value = score;
      167. document.f.combo.value = combo;
      168. document.f.report.value = "Mole hit! +100p\n" + document.f.report.value;
      169. }
      170. function endGame() {
      171. clearInterval(timerId);
      172. clearInterval(moleTimer);
      173. gameStarted = false;
      174. alert('Game end!\nTotal score: ' + score + 'points\nRanking registration is possible!');
      175. document.f.report.value = "Total score: " + score + "points\n" + document.f.report.value;
      176. }
      177. function save_rank() {
      178. if (Number(document.f.gp.value) > 0) {
      179. document.f.gpoint.value = document.f.gp.value;
      180. document.f.submit();
      181. }
      182. }
      183. window.onload = createGameBoard;
      184. </script>
      185. {/block}
      Display All
      --------------------------------------------------------------------------------------