utf8 bug fix and scan pages (#113)
This commit is contained in:
35
src/main/resources/static/css/rainbow-mode.css
Normal file
35
src/main/resources/static/css/rainbow-mode.css
Normal file
@@ -0,0 +1,35 @@
|
||||
/* Rainbow Mode Styles */
|
||||
body {
|
||||
background: linear-gradient(90deg, rgba(255,0,0,1) 0%, rgba(255,154,0,1) 10%, rgba(208,222,33,1) 20%, rgba(79,220,74,1) 30%, rgba(63,218,216,1) 40%, rgba(47,201,226,1) 50%, rgba(28,127,238,1) 60%, rgba(95,21,242,1) 70%, rgba(186,12,248,1) 80%, rgba(251,7,217,1) 90%, rgba(255,0,0,1) 100%);
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.dark-card {
|
||||
background: linear-gradient(90deg, rgba(255,0,0,1) 0%, rgba(255,154,0,1) 10%, rgba(208,222,33,1) 20%, rgba(79,220,74,1) 30%, rgba(63,218,216,1) 40%, rgba(47,201,226,1) 50%, rgba(28,127,238,1) 60%, rgba(95,21,242,1) 70%, rgba(186,12,248,1) 80%, rgba(251,7,217,1) 90%, rgba(255,0,0,1) 100%) !important;
|
||||
color: white !important;
|
||||
}
|
||||
.jumbotron {
|
||||
background: linear-gradient(90deg, rgba(255,0,0,1) 0%, rgba(255,154,0,1) 10%, rgba(208,222,33,1) 20%, rgba(79,220,74,1) 30%, rgba(63,218,216,1) 40%, rgba(47,201,226,1) 50%, rgba(28,127,238,1) 60%, rgba(95,21,242,1) 70%, rgba(186,12,248,1) 80%, rgba(251,7,217,1) 90%, rgba(255,0,0,1) 100%);
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.list-group {
|
||||
background: linear-gradient(90deg, rgba(255,0,0,1) 0%, rgba(255,154,0,1) 10%, rgba(208,222,33,1) 20%, rgba(79,220,74,1) 30%, rgba(63,218,216,1) 40%, rgba(47,201,226,1) 50%, rgba(28,127,238,1) 60%, rgba(95,21,242,1) 70%, rgba(186,12,248,1) 80%, rgba(251,7,217,1) 90%, rgba(255,0,0,1) 100%) !important;
|
||||
color: fff !important;
|
||||
}
|
||||
.list-group-item {
|
||||
background: linear-gradient(90deg, rgba(255,0,0,1) 0%, rgba(255,154,0,1) 10%, rgba(208,222,33,1) 20%, rgba(79,220,74,1) 30%, rgba(63,218,216,1) 40%, rgba(47,201,226,1) 50%, rgba(28,127,238,1) 60%, rgba(95,21,242,1) 70%, rgba(186,12,248,1) 80%, rgba(251,7,217,1) 90%, rgba(255,0,0,1) 100%) !important;
|
||||
color: fff !important;
|
||||
}
|
||||
#support-section {
|
||||
background: linear-gradient(90deg, rgba(255,0,0,1) 0%, rgba(255,154,0,1) 10%, rgba(208,222,33,1) 20%, rgba(79,220,74,1) 30%, rgba(63,218,216,1) 40%, rgba(47,201,226,1) 50%, rgba(28,127,238,1) 60%, rgba(95,21,242,1) 70%, rgba(186,12,248,1) 80%, rgba(251,7,217,1) 90%, rgba(255,0,0,1) 100%) !important;
|
||||
}
|
||||
|
||||
|
||||
#pages-container-wrapper {
|
||||
--background-color: rgba(255, 255, 255, 0.046) !important;
|
||||
--scroll-bar-color: #4c4c4c !important;
|
||||
--scroll-bar-thumb: #d3d3d3 !important;
|
||||
--scroll-bar-thumb-hover: #ffffff !important;
|
||||
}
|
||||
|
||||
13
src/main/resources/static/images/scanner.svg
Normal file
13
src/main/resources/static/images/scanner.svg
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg version="1.1" id="Icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 32 32" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||
.st1{fill:none;stroke:#000000;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||
</style>
|
||||
<path class="st0" d="M30,20H3v6c0,1.1,0.9,2,2,2h23c1.1,0,2-0.9,2-2V20z"/>
|
||||
<line class="st0" x1="30" y1="20" x2="3" y2="4"/>
|
||||
<line class="st0" x1="7" y1="24" x2="10" y2="24"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 691 B |
286
src/main/resources/static/js/game.js
Normal file
286
src/main/resources/static/js/game.js
Normal file
@@ -0,0 +1,286 @@
|
||||
function initializeGame() {
|
||||
const gameContainer = document.getElementById('game-container');
|
||||
const player = document.getElementById('player');
|
||||
|
||||
let playerSize = gameContainer.clientWidth * 0.0625; // 5% of container width
|
||||
player.style.width = playerSize + 'px';
|
||||
player.style.height = playerSize + 'px';
|
||||
|
||||
let playerX = gameContainer.clientWidth / 2 - playerSize / 2;
|
||||
let playerY = gameContainer.clientHeight * 0.1;
|
||||
const scoreElement = document.getElementById('score');
|
||||
const levelElement = document.getElementById('level');
|
||||
const livesElement = document.getElementById('lives');
|
||||
const highScoreElement = document.getElementById('high-score');
|
||||
|
||||
let pdfSize = gameContainer.clientWidth * 0.0625; // 5% of container width
|
||||
let projectileWidth = gameContainer.clientWidth * 0.00625; // 0.5% of container width
|
||||
let projectileHeight = gameContainer.clientHeight * 0.01667; // 1% of container height
|
||||
|
||||
let paused = false;
|
||||
const fireRate = 200; // Time between shots in milliseconds
|
||||
let lastProjectileTime = 0;
|
||||
let lives = 3;
|
||||
let highScore = localStorage.getItem('highScore') ? parseInt(localStorage.getItem('highScore')) : 0;
|
||||
updateHighScore();
|
||||
|
||||
|
||||
|
||||
const keysPressed = {};
|
||||
const pdfs = [];
|
||||
const projectiles = [];
|
||||
let score = 0;
|
||||
let level = 1;
|
||||
let pdfSpeed = 1;
|
||||
let gameOver = false;
|
||||
|
||||
function handleKeys() {
|
||||
if (keysPressed['ArrowLeft']) {
|
||||
playerX -= 10;
|
||||
}
|
||||
if (keysPressed['ArrowRight']) {
|
||||
playerX += 10;
|
||||
}
|
||||
if (keysPressed[' '] && !gameOver) {
|
||||
const currentTime = new Date().getTime();
|
||||
if (currentTime - lastProjectileTime >= fireRate) {
|
||||
shootProjectile();
|
||||
lastProjectileTime = currentTime;
|
||||
}
|
||||
}
|
||||
updatePlayerPosition();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
document.addEventListener('keydown', (event) => {
|
||||
if (event.key === ' ') {
|
||||
event.preventDefault();
|
||||
}
|
||||
keysPressed[event.key] = true;
|
||||
handleKeys();
|
||||
});
|
||||
|
||||
document.addEventListener('keyup', (event) => {
|
||||
keysPressed[event.key] = false;
|
||||
});
|
||||
|
||||
|
||||
function updatePlayerPosition() {
|
||||
player.style.left = playerX + 'px';
|
||||
player.style.bottom = playerY + 'px';
|
||||
}
|
||||
|
||||
function updateLives() {
|
||||
livesElement.textContent = 'Lives: ' + lives;
|
||||
}
|
||||
|
||||
function updateHighScore() {
|
||||
highScoreElement.textContent = 'High Score: ' + highScore;
|
||||
}
|
||||
|
||||
|
||||
function shootProjectile() {
|
||||
const projectile = document.createElement('div');
|
||||
projectile.classList.add('projectile');
|
||||
projectile.style.backgroundColor = 'black';
|
||||
projectile.style.width = projectileWidth + 'px';
|
||||
projectile.style.height = projectileHeight + 'px';
|
||||
projectile.style.left = (playerX + playerSize / 2 - projectileWidth / 2) + 'px';
|
||||
projectile.style.top = (gameContainer.clientHeight - playerY - playerSize) + 'px';
|
||||
gameContainer.appendChild(projectile);
|
||||
projectiles.push(projectile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function spawnPdf() {
|
||||
const pdf = document.createElement('img');
|
||||
pdf.src = 'images/file-earmark-pdf.svg';
|
||||
pdf.classList.add('pdf');
|
||||
pdf.style.width = pdfSize + 'px';
|
||||
pdf.style.height = pdfSize + 'px';
|
||||
pdf.style.left = Math.floor(Math.random() * (gameContainer.clientWidth - pdfSize)) + 'px';
|
||||
pdf.style.top = '0px';
|
||||
gameContainer.appendChild(pdf);
|
||||
pdfs.push(pdf);
|
||||
}
|
||||
|
||||
|
||||
function resetEnemies() {
|
||||
pdfs.forEach((pdf) => gameContainer.removeChild(pdf));
|
||||
pdfs.length = 0;
|
||||
}
|
||||
|
||||
|
||||
function updateGame() {
|
||||
if (gameOver || paused) return;
|
||||
|
||||
pdfs.forEach((pdf, pdfIndex) => {
|
||||
const pdfY = parseInt(pdf.style.top) + pdfSpeed;
|
||||
if (pdfY + 50 > gameContainer.clientHeight) {
|
||||
gameContainer.removeChild(pdf);
|
||||
pdfs.splice(pdfIndex, 1);
|
||||
|
||||
// Deduct 2 points when a PDF gets past the player
|
||||
score -= 0;
|
||||
updateScore();
|
||||
|
||||
// Decrease lives and check if game over
|
||||
lives--;
|
||||
updateLives();
|
||||
if (lives <= 0) {
|
||||
endGame();
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
pdf.style.top = pdfY + 'px';
|
||||
|
||||
// Check for collision with player
|
||||
if (collisionDetected(player, pdf)) {
|
||||
lives--;
|
||||
updateLives();
|
||||
resetEnemies();
|
||||
if (lives <= 0) {
|
||||
endGame();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
projectiles.forEach((projectile, projectileIndex) => {
|
||||
const projectileY = parseInt(projectile.style.top) - 10;
|
||||
if (projectileY < 0) {
|
||||
gameContainer.removeChild(projectile);
|
||||
projectiles.splice(projectileIndex, 1);
|
||||
} else {
|
||||
projectile.style.top = projectileY + 'px';
|
||||
}
|
||||
|
||||
for (let pdfIndex = 0; pdfIndex < pdfs.length; pdfIndex++) {
|
||||
const pdf = pdfs[pdfIndex];
|
||||
if (collisionDetected(projectile, pdf)) {
|
||||
gameContainer.removeChild(pdf);
|
||||
gameContainer.removeChild(projectile);
|
||||
pdfs.splice(pdfIndex, 1);
|
||||
projectiles.splice(projectileIndex, 1);
|
||||
score = score + 10;
|
||||
updateScore();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
setTimeout(updateGame, 1000 / 60);
|
||||
}
|
||||
function resetGame() {
|
||||
playerX = gameContainer.clientWidth / 2;
|
||||
playerY = 50;
|
||||
updatePlayerPosition();
|
||||
|
||||
pdfs.forEach((pdf) => gameContainer.removeChild(pdf));
|
||||
projectiles.forEach((projectile) => gameContainer.removeChild(projectile));
|
||||
|
||||
pdfs.length = 0;
|
||||
projectiles.length = 0;
|
||||
|
||||
score = 0;
|
||||
level = 1;
|
||||
lives = 3;
|
||||
|
||||
gameOver = false;
|
||||
|
||||
updateScore();
|
||||
updateLives();
|
||||
levelElement.textContent = 'Level: ' + level;
|
||||
pdfSpeed = 1;
|
||||
clearTimeout(spawnPdfTimeout); // Clear the existing spawnPdfTimeout
|
||||
setTimeout(updateGame, 1000 / 60);
|
||||
spawnPdfInterval();
|
||||
}
|
||||
|
||||
|
||||
|
||||
function updateScore() {
|
||||
scoreElement.textContent = 'Score: ' + score;
|
||||
checkLevelUp();
|
||||
}
|
||||
|
||||
|
||||
|
||||
function checkLevelUp() {
|
||||
const newLevel = Math.floor(score / 100) + 1;
|
||||
if (newLevel > level) {
|
||||
level = newLevel;
|
||||
levelElement.textContent = 'Level: ' + level;
|
||||
pdfSpeed += 1;
|
||||
}
|
||||
}
|
||||
|
||||
function collisionDetected(a, b) {
|
||||
const rectA = a.getBoundingClientRect();
|
||||
const rectB = b.getBoundingClientRect();
|
||||
return (
|
||||
rectA.left < rectB.right &&
|
||||
rectA.right > rectB.left &&
|
||||
rectA.top < rectB.bottom &&
|
||||
rectA.bottom > rectB.top
|
||||
);
|
||||
}
|
||||
|
||||
function endGame() {
|
||||
gameOver = true;
|
||||
if (score > highScore) {
|
||||
highScore = score;
|
||||
localStorage.setItem('highScore', highScore);
|
||||
updateHighScore();
|
||||
}
|
||||
alert('Game Over! Your final score is: ' + score);
|
||||
setTimeout(() => { // Wrap the resetGame() call in a setTimeout
|
||||
resetGame();
|
||||
}, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
let spawnPdfTimeout;
|
||||
|
||||
function spawnPdfInterval() {
|
||||
console.log("spawnPdfInterval");
|
||||
if (gameOver || paused) {
|
||||
console.log("spawnPdfInterval 2");
|
||||
clearTimeout(spawnPdfTimeout);
|
||||
return;
|
||||
}
|
||||
console.log("spawnPdfInterval 3");
|
||||
spawnPdf();
|
||||
spawnPdfTimeout = setTimeout(spawnPdfInterval, 1000 - level * 50);
|
||||
}
|
||||
|
||||
updatePlayerPosition();
|
||||
updateGame();
|
||||
spawnPdfInterval();
|
||||
|
||||
|
||||
document.addEventListener('visibilitychange', function() {
|
||||
if (document.hidden) {
|
||||
paused = true;
|
||||
} else {
|
||||
paused = false;
|
||||
updateGame();
|
||||
spawnPdfInterval();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
window.initializeGame = initializeGame;
|
||||
3
src/main/resources/static/rainbow.svg
Normal file
3
src/main/resources/static/rainbow.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-rainbow" viewBox="0 0 16 16">
|
||||
<path d="M8 4.5a7 7 0 0 0-7 7 .5.5 0 0 1-1 0 8 8 0 1 1 16 0 .5.5 0 0 1-1 0 7 7 0 0 0-7-7zm0 2a5 5 0 0 0-5 5 .5.5 0 0 1-1 0 6 6 0 1 1 12 0 .5.5 0 0 1-1 0 5 5 0 0 0-5-5zm0 2a3 3 0 0 0-3 3 .5.5 0 0 1-1 0 4 4 0 1 1 8 0 .5.5 0 0 1-1 0 3 3 0 0 0-3-3zm0 2a1 1 0 0 0-1 1 .5.5 0 0 1-1 0 2 2 0 1 1 4 0 .5.5 0 0 1-1 0 1 1 0 0 0-1-1z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 459 B |
Reference in New Issue
Block a user