228 lines
7.4 KiB
HTML
228 lines
7.4 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Blue Archive Memory (8×8)</title>
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.min.js"></script>
|
||
<script defer src="https://stats.ponywave.de/script" data-website-id="9ef713d2-adb9-4906-9df5-708d8a8b9131" data-tag="ba_memory"></script>
|
||
<style>
|
||
body {
|
||
margin: 0;
|
||
min-height: 100vh;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
background: #f0f4f8;
|
||
font-family: 'Arial', sans-serif;
|
||
}
|
||
|
||
#game-container {
|
||
margin-top: 2rem;
|
||
text-align: center;
|
||
}
|
||
|
||
.button-container {
|
||
margin: 20px 0;
|
||
display: flex;
|
||
gap: 10px;
|
||
}
|
||
|
||
button {
|
||
padding: 10px 20px;
|
||
font-size: 16px;
|
||
border: none;
|
||
border-radius: 5px;
|
||
background: #4CAF50;
|
||
color: white;
|
||
cursor: pointer;
|
||
transition: background 0.3s;
|
||
}
|
||
|
||
button:hover {
|
||
background: #45a049;
|
||
}
|
||
|
||
#timer {
|
||
font-size: 24px;
|
||
color: #2c3e50;
|
||
margin: 10px 0;
|
||
}
|
||
|
||
canvas {
|
||
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||
border-radius: 10px;
|
||
}
|
||
footer {
|
||
margin-top: 2rem;
|
||
padding: 1rem 0;
|
||
color: #666;
|
||
font-size: 0.9rem;
|
||
text-align: center;
|
||
border-top: 1px solid #ddd;
|
||
width: 100%;
|
||
}
|
||
|
||
footer a {
|
||
color: #4CAF50;
|
||
text-decoration: none;
|
||
transition: color 0.3s;
|
||
}
|
||
|
||
footer a:hover {
|
||
color: #45a049;
|
||
text-decoration: underline;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div id="game-container">
|
||
<div id="timer">⏱️ Vergangene Zeit: 0 Minuten 00 Sekunden</div>
|
||
<div id="canvas-container"></div>
|
||
<div class="button-container">
|
||
<button onclick="initializeGame()">🔄 Neustart</button>
|
||
<button onclick="takeScreenshot()">📸 Screenshot</button>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
let rows = 8, cols = 8;
|
||
let cardSize = 80;
|
||
let cards = [];
|
||
let flippedCards = [];
|
||
let matchedPairs = 0;
|
||
let images = {};
|
||
let pairs = [
|
||
["1.png", "A.png"], ["2.png", "B.png"], ["3.png", "C.png"], ["4.png", "D.png"],
|
||
["5.png", "E.png"], ["6.png", "F.png"], ["7.png", "G.png"], ["8.png", "H.png"],
|
||
["9.png", "I.png"], ["10.png", "J.png"], ["11.png", "K.png"], ["12.png", "L.png"],
|
||
["13.png", "M.png"], ["14.png", "N.png"], ["15.png", "O.png"], ["16.png", "P.png"],
|
||
["17.png", "Q.png"], ["18.png", "R.png"], ["19.png", "S.png"], ["20.png", "T.png"],
|
||
["21.png", "U.png"], ["22.png", "V.png"], ["23.png", "W.png"], ["24.png", "X.png"],
|
||
["25.png", "Y.png"], ["26.png", "Z.png"], ["27.png", "AA.png"], ["28.png", "BB.png"],
|
||
["29.png", "CC.png"], ["30.png", "DD.png"], ["31.png", "EE.png"], ["32.png", "FF.png"]
|
||
];
|
||
let startTime, clearTime, gameOver;
|
||
|
||
function preload() {
|
||
images["back"] = loadImage("cards/back.png");
|
||
for (let pair of pairs) {
|
||
images[pair[0]] = loadImage("cards/" + pair[0]);
|
||
images[pair[1]] = loadImage("cards/" + pair[1]);
|
||
}
|
||
}
|
||
|
||
function setup() {
|
||
let canvas = createCanvas(cols * cardSize, rows * cardSize);
|
||
canvas.parent('canvas-container');
|
||
initializeGame();
|
||
}
|
||
|
||
function initializeGame() {
|
||
cards = [];
|
||
flippedCards = [];
|
||
matchedPairs = 0;
|
||
gameOver = false;
|
||
|
||
let tempCards = [];
|
||
for (let pair of pairs) {
|
||
tempCards.push({ id: pair[0], img: images[pair[0]], pair: pair[1] });
|
||
tempCards.push({ id: pair[1], img: images[pair[1]], pair: pair[0] });
|
||
}
|
||
shuffle(tempCards, true);
|
||
|
||
for (let i = 0; i < rows; i++) {
|
||
for (let j = 0; j < cols; j++) {
|
||
let index = i * cols + j;
|
||
cards.push({
|
||
x: j * cardSize,
|
||
y: i * cardSize,
|
||
...tempCards[index],
|
||
flipped: false,
|
||
matched: false
|
||
});
|
||
}
|
||
}
|
||
|
||
startTime = millis();
|
||
select('#timer').html(`⏱️ Vergangene Zeit: ${formatTime(0)}`);
|
||
}
|
||
|
||
function draw() {
|
||
background(255);
|
||
for (let card of cards) {
|
||
if (card.flipped || card.matched) {
|
||
image(card.img, card.x, card.y, cardSize, cardSize);
|
||
} else {
|
||
image(images["back"], card.x, card.y, cardSize, cardSize);
|
||
}
|
||
}
|
||
|
||
if (!gameOver) {
|
||
select('#timer').html(`⏱️ Vergangene Zeit: ${formatTime(millis() - startTime)}`);
|
||
}
|
||
}
|
||
|
||
function mousePressed() {
|
||
if (flippedCards.length >= 2 || gameOver) return;
|
||
|
||
for (let card of cards) {
|
||
if (!card.flipped && !card.matched &&
|
||
mouseX > card.x && mouseX < card.x + cardSize &&
|
||
mouseY > card.y && mouseY < card.y + cardSize) {
|
||
card.flipped = true;
|
||
flippedCards.push(card);
|
||
|
||
if (flippedCards.length === 2) {
|
||
setTimeout(checkMatch, 1000);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
function checkMatch() {
|
||
let [card1, card2] = flippedCards;
|
||
if (card1.pair === card2.id) {
|
||
card1.matched = true;
|
||
card2.matched = true;
|
||
matchedPairs++;
|
||
if (matchedPairs === pairs.length) {
|
||
clearTime = millis() - startTime;
|
||
select('#timer').html(`🎉 Gewonnen! Zeit: ${formatTime(clearTime)}`);
|
||
gameOver = true;
|
||
}
|
||
} else {
|
||
card1.flipped = false;
|
||
card2.flipped = false;
|
||
}
|
||
flippedCards = [];
|
||
}
|
||
|
||
function takeScreenshot() {
|
||
let filename = `memory_${new Date().toISOString().slice(0,10)}.png`;
|
||
saveCanvas(filename, 'png');
|
||
}
|
||
|
||
function formatTime(ms) {
|
||
let totalSeconds = Math.floor(ms / 1000);
|
||
let minutes = Math.floor(totalSeconds / 60);
|
||
let seconds = totalSeconds % 60;
|
||
return `${minutes} Minuten ${seconds.toString().padStart(2, '0')} Sekunden`;
|
||
}
|
||
</script>
|
||
<footer>
|
||
<p>Basierend auf einem Projekt von
|
||
<a href="https://github.com/lia-2025/memory-game-ex" target="_blank" rel="noopener noreferrer">
|
||
Lia-2025
|
||
</a>
|
||
</p>
|
||
<p>© <span id="current-year"></span> - Übersetzt & überarbeitet von Akamaru</p>
|
||
</footer>
|
||
|
||
<script>
|
||
document.getElementById('current-year').textContent = new Date().getFullYear();
|
||
</script>
|
||
</body>
|
||
</html>
|