モモ企画お馴染みの花絵柄・柴犬をモチーフに作成したスロットです。このスロットはゲームとして多少は遊べると思いますが、本来はゲームソースの説明が主旨となります。従って、このソースをベースに、更にアレンジして頂くことを目的としています。

仕様 |
1. 縦・横・斜めの一致 2. 画像一致条件によるボーナスコイン 3. 特定絵柄によるコイン数の増減 4. ゲームリセットボタン 5. 獲得倍数の入力(ハズレ減算・当たりに応じた倍数計算) 6. キャンバス内、スタート&ストップ 7. コイン数0で終了(ゲームセット) 8. 画像一致で、ライン上にカラーボーダー点滅表示 9. 1億コイン獲得でハイスコア表示後、ゲームセット※表示しているハイスコア以下は保存なし 10.ハイスコア削除ボタン 11.1億コイン獲得で、キャンバス内アクション画像表示 12.横ライン2画像一致で加算(重複含む) 13.INFO:案内表示ボタン |
細かい仕様は実際のデモ画面のINFOで確認して下さい
多少アレンジした4×4クロススロット見たい方はご自由にどうぞ。
ファイル構成 |
index.html script.js style.css 画像格納ファイルassets ファイルパスは環境に合わせて下さい |
画像 0.png~23.pngまでの24画像 600px正方形 参考使用画像 花の写真素材屋 |
ソースコードは、ある程度の動作確認をしております。コードをコピペで使用しても構いませんが、動作の不具合やバグなどが確認された場合、使用された方の自己責任で適切な修正・追加をお願いします。
HTML |
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name=viewport content="width=device-width,initial-scale=1.0">
<title>4列スロット(4×4)</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<canvas id="slotCanvas"></canvas>
<div class="ui">
<label>獲得倍数<input id="betInput" type="number" min="1" step="5" value="1" style="width:90px;"></label>
<p>🎯 <span class="coin-label">COIN</span> <span id="coinDisplay">200</span></p>
<button id="resetButton">RESET</button>
</div>
<!-- スコア表示領域 -->
<div id="legendaryScoreWrapper">
<span id="legendaryScore">Legendary Score: ----</span>
<button id="clearLegendaryScore">✖️ DELETE</button>
<button id="openGuide" class="open-button">📘 INFO</button>
</div>
<div id="gameGuide" class="guide-box">
<button id="closeGuide" class="close-button">✖</button>
<h2>🎰 ゲーム案内</h2>
<h3><font color="Yellow">画像を揃えるとコインが獲得できるゲームです</font></h3>
<ul>
<li>当たり条件:縦・横・斜め(クロス)の各画像一致</li>
<li>獲得倍数:設定数値に応じた当たりの報酬</li>
<li>COIN:取得したコイン数</li>
<li>Legendary Score: ハイスコアの表示</li>
<li>RESET:ゲーム初期状態に戻す</li>
<li>DELETE:ハイスコアの削除</li>
<li>スタートは画像表示画面をクリック&タップ</li>
<li>ストップは各4列の任意の位置でクリック&タップ</li>
<li>1億以上のコインを獲得するとゲーム終了(ハイスコア表示)</li>
<li>ハイスコアの更新は現在の数値以上で更新(初期は表示)</li>
<li>横列2画像一致で50(重複画像加算)</li>
<li><font color="pink">当たりボーナス(画像一致)の条件:</font>横10万・ 斜め(クロス)20万・縦30万 バラ 100万
パラソルの下にいる犬たち 60万 アジサイ(BAR) ボーナスなし 柴犬-10万 P・T・Y画像は全てのライン共通 -5万</li>
<li>INF:この案内表示</li>
<h3><font color="#ff0099">1億超えて終了したら貴方は神!!</font></h3>
</ul>
</div>
<script src="script.js"></script>
</body>
</html>
JS |
const COLS = 4, ROWS = 4, cellSize = 120;
let canvas = document.getElementById('slotCanvas');
let ctx = canvas.getContext('2d');
canvas.width = COLS * cellSize;
canvas.height = ROWS * cellSize;
canvas.style.borderColor = "#0066ff";//canvasボーダー
const markerColors = {normal: "#5fbefdff"};//キャンバス内マークcolor
let offsetY = Array(COLS).fill(0);
let spinning = Array(COLS).fill(false);
let reels = Array.from({ length: COLS }, () => Array.from({ length: ROWS }, () => Math.floor(Math.random() * 24)));
let images = [], imagesLoaded = 0;
let coin = 200; //初期コイン
let spinSpeed = 20; //スピード調整
let isGameOver = false;
let spinSpeedArray = Array(COLS).fill(24);
let stopCount = 0;
let snapping = Array(COLS).fill(false);
let snapTarget = Array(COLS).fill(0);
const totalStops = COLS;
//======24画像========
for (let i = 0; i < 24; i++) {
const img = new Image();
img.src = `../assets/${i}.png`;//===任意のアドレス=======
img.onload = () => {
imagesLoaded++;
if (imagesLoaded === 24) drawReels();
};
images.push(img);
}
function drawReels(state = "normal") {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 🎰 画像描画
for (let col = 0; col < COLS; col++) {
for (let row = 0; row < ROWS; row++) {
const x = col * cellSize;
const y = row * cellSize + offsetY[col];
const img = images[reels[col][row]];
ctx.drawImage(img, x, y % canvas.height, cellSize, cellSize);
}
}
// 🧱 仕切り線
ctx.strokeStyle = "rgba(255, 255, 255, 0.3)";
ctx.lineWidth = 2;
for (let i = 1; i < COLS; i++) {
const x = i * cellSize;
ctx.beginPath();
ctx.moveTo(x, 0);
ctx.lineTo(x, canvas.height);
ctx.stroke();
}
// 🟨 マーカー描画(状態に応じた色)
drawFrameMarkers(markerColors[state]);
}
//=========呼び出し=============
window.addEventListener("DOMContentLoaded", () => {
initializeCoin();
updateCoinDisplay();
updateLegendaryScoreDisplay();
});
//=======canvasクリック==========
canvas.addEventListener("click", () => {
setBetInputEnabled(false);
if (isGameOver) {
coin = 200;
document.getElementById("coinDisplay").textContent = coin;
document.getElementById("betInput").value = 1;
isGameOver = false;
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawReels();
}
});
//=======canvasタッチ==========
let touchEventHappened = false;
canvas.addEventListener("touchstart", (e) => {
e.preventDefault();
setBetInputEnabled(false);
if (isGameOver) {
coin = 200;
isGameOver = false;
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawReels();
return;
}
const rect = canvas.getBoundingClientRect();
const x = e.touches[0].clientX - rect.left;
const touchedCol = Math.floor(x / cellSize);
if (spinning.every(s => s === false) && snapping.every(s => s === false)) {
spinning = spinning.map(() => true);
spinSpeedArray = spinSpeedArray.map(() => 4);
offsetY = offsetY.map(() => 0);
stopCount = 0;
requestAnimationFrame(spinStep);
return;
}
if (touchedCol >= 0 && touchedCol < COLS && spinning[touchedCol] === true) {
spinning[touchedCol] = "stopping";
}
}, { passive: false });
//========= 通常のスロット停止処理==============
function spinStep() {
let needsAnimation = false;
for (let col = 0; col < COLS; col++) {
if (spinning[col] === true) {
offsetY[col] += spinSpeed;
if (offsetY[col] >= cellSize) {
offsetY[col] -= cellSize;
reels[col].pop();
reels[col].unshift(Math.floor(Math.random() * 24));
}
needsAnimation = true;
} else if (spinning[col] === "stopping") {
offsetY[col] += spinSpeedArray[col];
if (offsetY[col] >= cellSize) {
offsetY[col] -= cellSize;
reels[col].pop();
reels[col].unshift(Math.floor(Math.random() * 24));
}
needsAnimation = true;
spinning[col] = false;
// 🎯 即停止:offsetYをリセット
offsetY[col] = 0;
stopCount++;
// 🎯 全リール停止かつ吸着完了を確認
if (spinning.every(s => s === false) && snapping.every(s => s === false)) {
setBetInputEnabled(true);
requestAnimationFrame(() => {
drawReels();
const matchedLines = getMatchedLines(reels);
const bet = parseInt(document.getElementById("betInput").value, 10) || 1;
if (matchedLines.length > 0) {
blinkLines(matchedLines);
matchedLines.forEach(line => {
console.log(`Applying reward for: ${line.type}, symbol: ${line.symbol}`);
const coinBefore = getCoin();
applyMatchReward(line.type, bet, line.symbol);
const coinAfter = getCoin();
console.log(`Coin before: ${coinBefore}, after: ${coinAfter}`);
});
} else {//====ハズレ減算===========
const currentCoin = getCoin();
const updatedCoin = Math.max(0, currentCoin - bet);
setCoin(updatedCoin);
drawReels();
}
// ✅ ここで判定・保存(条件付き)
const finalCoin = getCoin();
const currentLegendary = parseInt(localStorage.getItem("legendaryCoin"), 10) || 0;
if (finalCoin >= 100_000_000 && finalCoin > currentLegendary) {
showLegendaryAnimation();
localStorage.setItem("legendaryCoin", finalCoin);
updateLegendaryScoreDisplay(); // ← 表示更新
}
});
}
needsAnimation = true;
}
}
drawReels();
if (getCoin() === 0) {//======コイン0処理=======
showGameOverMessage(ctx);
isGameOver = true;
}
if (needsAnimation) requestAnimationFrame(spinStep);
}
//======スコア更新==================
function updateCoinDisplay() {
const coin = getCoin();
const display = document.getElementById("coinDisplay");
if (display) display.textContent = coin.toLocaleString();
}
//======スピン中操作=================
canvas.addEventListener("click", (e) => {
if (touchEventHappened) {
touchEventHappened = false;
return;
}
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const clickedCol = Math.floor(x / cellSize);
if (spinning.every(s => s === false) && snapping.every(s => s === false)) {
spinning = spinning.map(() => true);
spinSpeedArray = spinSpeedArray.map(() => 4);
offsetY = offsetY.map(() => 0);
stopCount = 0;
requestAnimationFrame(spinStep);
return;
}
if (clickedCol >= 0 && clickedCol < COLS && spinning[clickedCol] === true) {
spinning[clickedCol] = "stopping";
}
});
//================================
function normalizeReels(reels) {
const normalized = reels.map(col => {
const newCol = Array.isArray(col) ? [...col] : [];
while (newCol.length < ROWS) {
newCol.push(Math.floor(Math.random() * 24));
}
return newCol;
});
return normalized;
}
//====================ラインマッチ=======================
function getMatchedLines(reels) {
const normalizedReels = normalizeReels(reels);
const lines = [];
// 横揃い
for (let row = 0; row < reels[0].length; row++) {
const symbol = reels[0][row];
if (reels[1][row] === symbol && reels[2][row] === symbol && reels[3][row] === symbol) {
lines.push({
type: "row",
index: row,
symbol: symbol
});
}
}
// 縦揃い
for (let col = 0; col < COLS; col++) {
const symbol = normalizedReels[col][0];
if (symbol !== undefined && normalizedReels[col].every(v => v === symbol)) {
lines.push({
type: "col",
index: col,
symbol: symbol
});
}
}
// 斜め揃い(左上→右下)
const diag1Symbol = normalizedReels[0][0];
if (
diag1Symbol !== undefined &&
normalizedReels.every((reel, i) => reel[i] === diag1Symbol)
) {
lines.push({
type: "diag1",
symbol: diag1Symbol
});
}
// 斜め揃い(右上→左下)
const diag2Symbol = normalizedReels[COLS - 1][0];
if (
diag2Symbol !== undefined &&
normalizedReels.every((_, i) => {
const col = COLS - 1 - i;
return normalizedReels[col][i] === diag2Symbol;
})
) {
lines.push({
type: "diag2",
symbol: diag2Symbol
});
}
return lines;
}
//==============ラインブリンクボーダー====================
let isBlinking = false;
function blinkLines(lines) {
isBlinking = true;
let blinkCount = 0;
const maxBlinks = 6;
const interval = setInterval(() => {
drawReels(); // 通常描画
ctx.lineWidth = 8;
ctx.strokeStyle = (blinkCount % 2 === 0) ? "#f0f" : "#0ff";
for (const line of lines) {
ctx.beginPath();
if (line.type === "row") {
const y = line.index * cellSize + cellSize / 2;
ctx.moveTo(0, y);
ctx.lineTo(canvas.width, y);
} else if (line.type === "col") {
const x = line.index * cellSize + cellSize / 2;
ctx.moveTo(x, 0);
ctx.lineTo(x, canvas.height);
} else if (line.type === "diag1") {
ctx.moveTo(0, 0);
ctx.lineTo(canvas.width, canvas.height);
} else if (line.type === "diag2") {
ctx.moveTo(canvas.width, 0);
ctx.lineTo(0, canvas.height);
}
ctx.stroke();
}
blinkCount++;
if (blinkCount >= maxBlinks) {
clearInterval(interval);
drawReels(); // 最後に通常描画
isBlinking = false;
}
}, 500);
}
//==============ラインマーク===========================
function drawFrameMarkers(color = markerColors.normal) {
const markerSize = 10;
const margin = 0;
ctx.fillStyle = color;
// ◀ 左端 → 内向き三角形
for (let row = 0; row < ROWS; row++) {
const y = row * cellSize + cellSize / 2;
ctx.beginPath();
ctx.moveTo(margin + markerSize, y);
ctx.lineTo(margin, y - markerSize / 2);
ctx.lineTo(margin, y + markerSize / 2);
ctx.closePath();
ctx.fill();
}
// ▶ 右端 → 左向き
for (let row = 0; row < ROWS; row++) {
const y = row * cellSize + cellSize / 2;
ctx.beginPath();
ctx.moveTo(canvas.width - margin - markerSize, y);
ctx.lineTo(canvas.width - margin, y - markerSize / 2);
ctx.lineTo(canvas.width - margin, y + markerSize / 2);
ctx.closePath();
ctx.fill();
}
// ▲ 上端 → 下向き
for (let col = 0; col < COLS; col++) {
const x = col * cellSize + cellSize / 2;
ctx.beginPath();
ctx.moveTo(x, margin + markerSize);
ctx.lineTo(x - markerSize / 2, margin);
ctx.lineTo(x + markerSize / 2, margin);
ctx.closePath();
ctx.fill();
}
// ▼ 下端 → 上向き
for (let col = 0; col < COLS; col++) {
const x = col * cellSize + cellSize / 2;
ctx.beginPath();
ctx.moveTo(x, canvas.height - margin - markerSize);
ctx.lineTo(x - markerSize / 2, canvas.height - margin);
ctx.lineTo(x + markerSize / 2, canvas.height - margin);
ctx.closePath();
ctx.fill();
}
// 🔶 四隅 → 斜め向き三角形(角の語り部)
// ⬉ 左上(↘向き)
ctx.beginPath();
ctx.moveTo(margin, margin + markerSize);
ctx.lineTo(margin + markerSize, margin);
ctx.lineTo(margin + markerSize, margin + markerSize);
ctx.closePath();
ctx.fill();
// ⬈ 右上(↙向き)
ctx.beginPath();
ctx.moveTo(canvas.width - margin, margin + markerSize);
ctx.lineTo(canvas.width - margin - markerSize, margin);
ctx.lineTo(canvas.width - margin - markerSize, margin + markerSize);
ctx.closePath();
ctx.fill();
// ⬋ 左下(↗向き)
ctx.beginPath();
ctx.moveTo(margin, canvas.height - margin - markerSize);
ctx.lineTo(margin + markerSize, canvas.height - margin);
ctx.lineTo(margin + markerSize, canvas.height - margin - markerSize);
ctx.closePath();
ctx.fill();
// ⬊ 右下(↖向き)
ctx.beginPath();
ctx.moveTo(canvas.width - margin, canvas.height - margin - markerSize);
ctx.lineTo(canvas.width - margin - markerSize, canvas.height - margin);
ctx.lineTo(canvas.width - margin - markerSize, canvas.height - margin - markerSize);
ctx.closePath();
ctx.fill();
}
const betInput = document.getElementById("betInput");
const coinDisplay = document.getElementById("coinDisplay");
//==================入力制限============================
betInput.addEventListener("input", () => {
let value = betInput.value.trim();
// 数値かつ整数か判定
if (!/^\d+$/.test(value)) {
betInput.value = ""; // 無効な入力は消去
return;
}
let bet = parseInt(value, 10);
let coin = parseInt(coinDisplay.textContent.replace(/,/g, ""), 10);
betInput.max = coin;
// コイン数を超えたら最大値に制限
if (bet > coin) {
betInput.value = coin;
}
});
//=============ゲームオーバーメッセージ==================
function showGameOverMessage(ctx) {
ctx.fillStyle = "rgba(0, 0, 0, 0.7)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#fff";
ctx.font = "bold 32px sans-serif";
ctx.textAlign = "center";
ctx.fillText("コインが尽きました", canvas.width / 2, canvas.height / 2 - 20);
ctx.font = "24px sans-serif";
ctx.fillText("リセットでリプレイです", canvas.width / 2, canvas.height / 2 + 20);
}
//=================リセット============================
document.getElementById("resetButton").addEventListener("click", () => {
// 🪙 コインとベットの初期化
coin = 200;
localStorage.setItem("coin", 200);
document.getElementById("coinDisplay").textContent = coin;
document.getElementById("betInput").value = 1;
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawReels();
// 🎭 状態フラグの初期化
isGameOver = false;
isSpinning = false;
});
window.addEventListener("keydown", function (e) {
if ((e.key === "F5") || (e.ctrlKey && e.key === "r")) {
e.preventDefault();
}
});
//==============リロード表示============================
function getCoin() {
return parseInt(localStorage.getItem("coin") || "200", 10);
}
function setCoin(value) {
localStorage.setItem("coin", value);
updateCoinDisplay(); // 表示更新
}
function initializeCoin() {
if (!localStorage.getItem("coin")) {
localStorage.setItem("coin", "200");
}
}
//=================スコア減算===========================
function applyMatchReward(type, bet, symbol) {
const coin = getCoin();
// 横2画像一致だけは独立処理
if (type === "row2_left" || type === "row2_center" || type === "row2_right") {
const updatedCoin = getCoin() + 50;
setCoin(updatedCoin);
updateCoinDisplay();
return;
}
let rewardMultiplier = 0;
switch (type) {
case "horizontal":
case "row":
rewardMultiplier = 100_000;
break;
case "diagonal":
case "diag1":
case "diag2":
rewardMultiplier = 200_000;
break;
case "col":
case "vertical":
case "column":
rewardMultiplier = 300_000;
break;
default:
rewardMultiplier = 0;
}
// 絵柄による固定報酬
let symbolBonus = 0;
switch (symbol) {
case 3:
symbolBonus = 1_000_000;
break;
case 23:
symbolBonus = 500_000;
break;
case 17:
symbolBonus = -100_000;
bet = 0;
break;
case 16:
symbolBonus = 0;
bet = 0;
break;
case 20:
case 21:
case 22:
symbolBonus = -50_000;
bet = 0;
break;
default:
symbolBonus = 0;
}
const reward = rewardMultiplier * bet + symbolBonus;
const updatedCoin = Math.max(0, coin + reward - bet);
setCoin(updatedCoin);
updateCoinDisplay();
}
//=================入力非表示===========================
function setBetInputEnabled(enabled) {
const input = document.getElementById("betInput");
if (input) input.disabled = !enabled;
}
//==================ハイスコア処理=======================
function updateLegendaryScoreDisplay() {
const legendaryValue = localStorage.getItem("legendaryCoin");
const scoreElement = document.getElementById("legendaryScore");
if (legendaryValue && scoreElement) {
const numericValue = parseInt(legendaryValue, 10);
scoreElement.textContent = `Legendary Score: ${numericValue.toLocaleString()}`;
}
}
document.getElementById("clearLegendaryScore").addEventListener("click", () => {
localStorage.removeItem("legendaryCoin");
const scoreElement = document.getElementById("legendaryScore");
if (scoreElement) {
scoreElement.textContent = "Legendary Score: ----";
}
});
//================ゲームセット演出========================
function showLegendaryAnimation() {
const img = new Image();
img.src = '../assets/23_1.png';//===任意のアドレス=======
img.onload = () => {
const startTime = performance.now();
function animate(time) {
const elapsed = time - startTime;
const progress = elapsed / 5000;
ctx.clearRect(0, 0, canvas.width, canvas.height);
let alpha = 1;
if (progress < 0.2) {
alpha = progress / 0.2;
} else if (progress > 0.8) {
alpha = 1 - (progress - 0.8) / 0.2;
}
ctx.globalAlpha = alpha;
const scale = 1 + progress;
const floatY = -progress * 100;
const offsetX = Math.sin(elapsed / 200) * 10;
const offsetY = Math.cos(elapsed / 300) * 10;
const imgWidth = img.width * scale;
const imgHeight = img.height * scale;
const x = canvas.width / 2 - imgWidth / 2 + offsetX;
const y = canvas.height / 2 - imgHeight / 2 + offsetY + floatY;
ctx.drawImage(img, x, y, imgWidth, imgHeight);
ctx.globalAlpha = 1;
if (elapsed < 5000) {
requestAnimationFrame(animate);
} else {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 文言を描画(canvas上)
const message = "その瞬間、伝説は静かに舞い上がり、記憶の空に溶けていった。";
ctx.font = "20px serif";
ctx.fillStyle = "rgba(255, 255, 255, 0.8)";
ctx.textAlign = "center";
ctx.textBaseline = "top";
const maxWidth = canvas.width * 0.8;
const lineHeight = 28;
const x = canvas.width / 2;
const y = canvas.height / 2 - lineHeight; // 上に少しずらす
drawWrappedText(ctx, message, x, y, maxWidth, lineHeight);
}
}
requestAnimationFrame(animate);
};
}
function drawWrappedText(ctx, text, x, y, maxWidth, lineHeight) {
const words = text.split(/(\s|、|。)/); // 区切りで分割
let line = "";
let lines = [];
for (let i = 0; i < words.length; i++) {
const testLine = line + words[i];
const testWidth = ctx.measureText(testLine).width;
if (testWidth > maxWidth && line !== "") {
lines.push(line);
line = words[i];
} else {
line = testLine;
}
}
lines.push(line);
lines.forEach((l, i) => {
ctx.fillText(l, x, y + i * lineHeight);
});
}
//============INF=================
const openBtn = document.getElementById('openGuide');
const closeBtn = document.getElementById('closeGuide');
const guideBox = document.getElementById('gameGuide');
openBtn.addEventListener('click', () => {
guideBox.style.display = 'block';
});
closeBtn.addEventListener('click', () => {
guideBox.style.display = 'none';
});
//=================================
CSS |
body {
background: #222;
font-family: sans-serif;
text-align: center;
color: #e7e7e7;
}
html {
touch-action: manipulation;
}
canvas {
background: #111;
display: block;
margin: 1em auto;
border: 4px solid #888;
border-radius: 12px;
box-shadow: 0 0 20px rgba(255, 255, 255, 0.2);
}
.ui {
display: flex;
align-items: center;
justify-content: space-between;
width: 452px; /* キャンバスと同じ幅 */
padding: 10px 15px;
margin: 10px auto;
border: 2px solid #ccc;
border-radius: 12px;
background-color: #4e9217;
font-family: "Segoe UI", sans-serif;
box-shadow: 2px 2px 6px rgba(0,0,0,0.1);
}
.ui label,
.ui p {
margin: 0;
font-size: 16px;
}
/* COINだけサイズを変える */
.coin-label {
font-size: 20px !important; /* 強制的に上書き */
color: rgb(39, 39, 39);
font-weight: bold;
}
#coinDisplay {
font-size: 20px; /* お好みのサイズに調整 */
font-weight: bold;
color: #ff73e8; /* ゴールド系でコイン感 */
text-shadow: 2px 1px 2px #272525;
}
.ui input {
font-size: 18px;
padding: 4px;
border-radius: 6px;
border: 1px solid #aaa;
}
.ui button {
font-size: 16px;
padding: 6px 12px;
border-radius: 8px;
border: none;
background-color: #252ca3;
color: white;
cursor: pointer;
transition: background-color 0.3s ease;
}
.ui button:hover {
background-color: #38688f;
}
input[type="number"] {
width: 120px;
font-size:14px;
}
#legendaryScore {
font-size: 18px;
font-weight: bold;
color: gold;
text-shadow: 1px 1px 4px rgba(255,215,0,0.6);
font-family: 'Cinzel', serif; /* 伝説感あるフォントもおすすめ */
}
#clearLegendaryScore {
font-size: 18px;
margin-left: 8px;
background: transparent;
border: none;
color: crimson;
cursor: pointer;
font-weight: bold;
}
#clearLegendaryScore:hover {
text-decoration: underline;
}
/* 初期状態で非表示 */
#gameGuide {
display: none;
position: fixed; /* fixedで画面中央に固定 */
top: 40%;
left: 50%;
transform: translate(-50%, -50%); /* 中央に寄せる */
width: 430px;
background: #353434;
border: 2px solid #21e271;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
font-size: 14px;
font-family: sans-serif;
margin: 0 auto;
opacity: 0.9;
z-index: 100;
}
.open-button{
cursor: pointer;
font-size: 12px;
padding: 2px 4px;
background-color: #0078D4;
color: white;
text-shadow: 2px 1px 2px #272525;
border: none;
border-radius: 4px;
}
.close-button {
cursor: pointer;
font-size: 12px;
padding: 8px 12px;
margin: 8px;
background-color: #0078D4;
color: white;
border: none;
border-radius: 4px;
}
.close-button {
float: right;
background-color: #d40000;
font-size: 18px;
border-radius: 6px;
}
#gameGuide ul {
list-style: none; /* デフォルトの「・」を消す */
padding-left: 0; /* 左余白をなくす */
margin: 10px;
}
#gameGuide li {
position: relative;
padding-left: 1.4em; /* ▶の分だけ左に余白を作る */
text-align: left; /* テキストを左寄せ */
}
#gameGuide li::before {
content: "▶";
position: absolute;
left: 0; /* 左端に固定 */
color: #80ccff; /* お好みで色調整 */
}
以上です・・・・・。