feature/MAPG-235-basic-challenge-mode #48
@ -168,6 +168,37 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
#highscoresTable {
|
||||
margin: 1em;
|
||||
border-collapse: collapse;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
#highscoresTable td, #highscoresTable th {
|
||||
border: 1px solid #ddd;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
#highscoresTable tr:nth-child(even) {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
#highscoresTable tr:hover {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
#highscoresTable th {
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
text-align: left;
|
||||
background-color: #e8a349;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#highscoresTable tr.ownPlayer {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 599px) {
|
||||
#mapName {
|
||||
display: none;
|
||||
@ -195,6 +226,9 @@
|
||||
bottom: 25px;
|
||||
left: 10px;
|
||||
}
|
||||
.hideOnMobile {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 600px) {
|
||||
|
@ -31,7 +31,7 @@ main {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
p, h1, h2, input, textarea, select, button, a {
|
||||
p, h1, h2, input, textarea, select, button, a, table {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ const GameType = Object.freeze({ 'SINGLE': 0, 'MULTI': 1, 'CHALLENGE': 2 });
|
||||
googleLink: null,
|
||||
history: [],
|
||||
restrictions: null,
|
||||
finishers: null,
|
||||
|
||||
readyToContinue: true,
|
||||
timeoutEnd: null,
|
||||
@ -296,7 +297,7 @@ const GameType = Object.freeze({ 'SINGLE': 0, 'MULTI': 1, 'CHALLENGE': 2 });
|
||||
return;
|
||||
}
|
||||
|
||||
Game.loadHistory(this.response.history);
|
||||
Game.loadHistory(this.response);
|
||||
|
||||
if (this.response.finished) {
|
||||
|
||||
@ -334,14 +335,14 @@ const GameType = Object.freeze({ 'SINGLE': 0, 'MULTI': 1, 'CHALLENGE': 2 });
|
||||
}
|
||||
|
||||
if (Game.restrictions.timeLimit) {
|
||||
Game.startCountdown(Game.restrictions.timeLimit, function() {
|
||||
Game.startCountdown(Game.restrictions.timeLimit, function () {
|
||||
Game.guess();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
disableRestrictions: function () {
|
||||
|
||||
|
||||
Game.panorama.setOptions({
|
||||
clickToGo: true,
|
||||
linksControl: true,
|
||||
@ -389,11 +390,11 @@ const GameType = Object.freeze({ 'SINGLE': 0, 'MULTI': 1, 'CHALLENGE': 2 });
|
||||
}
|
||||
},
|
||||
|
||||
loadHistory: function (history) {
|
||||
if (!history)
|
||||
loadHistory: function (response) {
|
||||
if (!response.history)
|
||||
return;
|
||||
|
||||
Game.history = history;
|
||||
Game.history = response.history;
|
||||
|
||||
for (var i = 0; i < Game.rounds.length; ++i) {
|
||||
var round = Game.rounds[i];
|
||||
@ -435,6 +436,10 @@ const GameType = Object.freeze({ 'SINGLE': 0, 'MULTI': 1, 'CHALLENGE': 2 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (response.finishers) {
|
||||
Game.finishers = new Set(response.finishers);
|
||||
}
|
||||
},
|
||||
|
||||
reset: function () {
|
||||
@ -466,6 +471,7 @@ const GameType = Object.freeze({ 'SINGLE': 0, 'MULTI': 1, 'CHALLENGE': 2 });
|
||||
distanceInfo.children[0].style.display = null;
|
||||
distanceInfo.children[1].style.display = null;
|
||||
distanceInfo.children[2].style.display = null;
|
||||
document.getElementById('summaryInfo').innerHTML = "Game finished."
|
||||
var scoreInfo = document.getElementById('scoreInfo');
|
||||
scoreInfo.children[0].style.display = null;
|
||||
scoreInfo.children[1].style.display = null;
|
||||
@ -484,6 +490,9 @@ const GameType = Object.freeze({ 'SINGLE': 0, 'MULTI': 1, 'CHALLENGE': 2 });
|
||||
|
||||
document.getElementById('panningBlockerCover').style.display = null;
|
||||
|
||||
Game.history = [];
|
||||
Game.finishers = null;
|
||||
|
||||
Game.initialize();
|
||||
},
|
||||
|
||||
@ -659,7 +668,7 @@ const GameType = Object.freeze({ 'SINGLE': 0, 'MULTI': 1, 'CHALLENGE': 2 });
|
||||
var timeLeft = Math.ceil((Game.timeoutEnd - new Date()) / 1000);
|
||||
data.append('timeLeft', timeLeft);
|
||||
}
|
||||
|
||||
|
||||
Game.disableRestrictions();
|
||||
|
||||
if (Game.guessMarker) {
|
||||
@ -683,7 +692,7 @@ const GameType = Object.freeze({ 'SINGLE': 0, 'MULTI': 1, 'CHALLENGE': 2 });
|
||||
return;
|
||||
}
|
||||
|
||||
Game.loadHistory(this.response.history);
|
||||
Game.loadHistory(this.response);
|
||||
Game.restrictions = this.response.restrictions;
|
||||
|
||||
Game.receiveResult(this.response.position, guessPosition, this.response.result, this.response.allResults);
|
||||
@ -806,6 +815,31 @@ const GameType = Object.freeze({ 'SINGLE': 0, 'MULTI': 1, 'CHALLENGE': 2 });
|
||||
return { width: percent + '%', backgroundColor: color };
|
||||
},
|
||||
|
||||
calculateHighScores: function () {
|
||||
|
||||
var highscores = new Map();
|
||||
highscores.set('me', Game.scoreSum);
|
||||
|
||||
for (var i = 0; i < Game.history.length; ++i) {
|
||||
const round = Game.history[i];
|
||||
if (round.allResults) {
|
||||
for (const result of round.allResults) {
|
||||
if (Game.finishers.has(result.userName)) {
|
||||
if (highscores.has(result.userName)) {
|
||||
highscores.set(result.userName, highscores.get(result.userName) + result.score);
|
||||
} else {
|
||||
highscores.set(result.userName, result.score);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var sortedHighscores = Array.from(highscores, ([userName, score]) => ({ 'userName': userName, 'score': score }))
|
||||
.sort(function (resultA, resultB) { return resultB.score - resultA.score });
|
||||
return sortedHighscores;
|
||||
},
|
||||
|
||||
showSummary: function () {
|
||||
var distanceInfo = document.getElementById('distanceInfo');
|
||||
distanceInfo.children[0].style.display = 'none';
|
||||
@ -865,6 +899,44 @@ const GameType = Object.freeze({ 'SINGLE': 0, 'MULTI': 1, 'CHALLENGE': 2 });
|
||||
var scoreBar = document.getElementById('scoreBar');
|
||||
scoreBar.style.backgroundColor = scoreBarProperties.backgroundColor;
|
||||
scoreBar.style.width = scoreBarProperties.width;
|
||||
|
||||
if (Game.type == GameType.CHALLENGE) {
|
||||
var highscores = this.calculateHighScores();
|
||||
var summaryInfo = document.getElementById('summaryInfo');
|
||||
|
||||
if (highscores.length > 2) {
|
||||
var table = document.getElementById('highscoresTable');
|
||||
for (const result of highscores) {
|
||||
var userName = document.createElement('td');
|
||||
userName.innerHTML = result.userName;
|
||||
var score = document.createElement('td');
|
||||
score.innerHTML = result.score;
|
||||
var line = document.createElement('tr');
|
||||
line.appendChild(userName);
|
||||
line.appendChild(score);
|
||||
table.appendChild(line);
|
||||
|
||||
if (result.userName === 'me') {
|
||||
line.setAttribute('class', 'ownPlayer');
|
||||
}
|
||||
}
|
||||
|
||||
MapGuesser.showModal('highscores');
|
||||
} else if (highscores.length == 2) {
|
||||
|
||||
if (highscores[0].userName === 'me') {
|
||||
summaryInfo.innerHTML = 'You won! <span class="hideOnMobile">' + highscores[1].userName + ' got only ' + highscores[1].score + ' points.</span>';
|
||||
} else {
|
||||
summaryInfo.innerHTML = 'You lost! <span class="hideOnMobile">' + highscores[0].userName + ' won with ' + highscores[0].score + ' points.</span>';
|
||||
}
|
||||
|
||||
} else if (highscores.length == 1) {
|
||||
// summaryInfo.innerHTML = 'You are the first to finish. Challenge other by sending them the link and come back for the results.'
|
||||
summaryInfo.innerHTML = 'You are the first to finish.'
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
rewriteGoogleLink: function () {
|
||||
@ -1112,4 +1184,8 @@ const GameType = Object.freeze({ 'SINGLE': 0, 'MULTI': 1, 'CHALLENGE': 2 });
|
||||
document.getElementById('compassContainer').onclick = function () {
|
||||
Game.panorama.setPov({ heading: 0, pitch: Game.panorama.getPov().pitch });
|
||||
}
|
||||
|
||||
document.getElementById('closeHighscoresButton').onclick = function () {
|
||||
MapGuesser.hideModal();
|
||||
};
|
||||
})();
|
||||
|
@ -193,6 +193,14 @@ class GameFlowController
|
||||
|
||||
if (!isset($currentPlace)) { // game finished
|
||||
$response['finished'] = true;
|
||||
|
||||
// list all players who finished the challenge
|
||||
$response['finishers'] = [];
|
||||
foreach ($this->userInChallengeRepository->getAllByChallengeWithUsers($challenge) as $userInChallenge) {
|
||||
if ($userInChallenge->getCurrentRound() == $currentRound && $userInChallenge->getUser()->getId() != $userId) {
|
||||
$response['finishers'][] = $userInChallenge->getUser()->getDisplayName();
|
||||
}
|
||||
}
|
||||
} else { // continue game
|
||||
$response['place'] = [
|
||||
'panoId' => $currentPlace->getPanoIdCached(),
|
||||
|
@ -32,6 +32,14 @@ class UserInChallengeRepository
|
||||
yield from $this->pdm->selectMultipleFromDb($select, UserInChallenge::class);
|
||||
}
|
||||
|
||||
public function getAllByChallengeWithUsers(Challenge $challenge) : Generator
|
||||
{
|
||||
$select = new Select(\Container::$dbConnection);
|
||||
$select->where('challenge_id', '=', $challenge->getId());
|
||||
|
||||
yield from $this->pdm->selectMultipleFromDb($select, UserInChallenge::class, true, [User::class]);
|
||||
}
|
||||
|
||||
public function getByUserIdAndChallenge(int $userId, Challenge $challenge): ?UserInChallenge
|
||||
{
|
||||
$select = new Select(\Container::$dbConnection);
|
||||
|
@ -12,6 +12,20 @@
|
||||
<div id="players" class="marginTop"></div>
|
||||
<button id="startMultiGameButton" class="button fullWidth marginTop green">Start game</button>
|
||||
</div>
|
||||
<div id="highscores" class="modal">
|
||||
<h2>Highscores</h2>
|
||||
<div>
|
||||
<table id="highscoresTable">
|
||||
<tr>
|
||||
<th>Player</th>
|
||||
<th>Score</th>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button id="closeHighscoresButton" class="gray marginTop" type="button">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section(subheader)
|
||||
@ -42,7 +56,7 @@
|
||||
<div id="distanceInfo">
|
||||
<p>You were <span id="distance" class="bold"></span> close.</p>
|
||||
<p>You didn't guess in this round.</p>
|
||||
<p class="bold">Game finished.</p>
|
||||
<p id="summaryInfo" class="bold">Game finished.</p>
|
||||
</div>
|
||||
<div id="scoreInfo">
|
||||
<p>You earned <span id="score" class="bold"></span> points.</p>
|
||||
|
Loading…
Reference in New Issue
Block a user