Meta Description" name="description" />
<!DOCTYPE html>
<html lang="km">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>THE Cambodia game - ដោយ មុត សាមេត</title>
<style>
body {
margin: 0;
padding: 0;
background: #111;
color: white;
font-family: 'Khmer OS Battambang', sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
overflow: hidden;
}
#gameHeader {
text-align: center;
margin-bottom: 5px;
}
#gameHeader h1 { margin: 0; color: #f39c12; font-size: 24px; }
#gameHeader p { margin: 2px; color: #bdc3c7; font-size: 14px; }
#canvasContainer {
position: relative;
box-shadow: 0 0 20px rgba(0,0,0,0.8);
}
canvas {
border: 3px solid #f39c12;
background-color: #87CEEB;
display: block;
}
/* គោះបញ្ជាលើអេក្រង់ទូរស័ព្ទ (Mobile Controls) */
.controls {
margin-top: 10px;
display: flex;
gap: 15px;
}
button {
padding: 12px 20px;
font-size: 16px;
font-weight: bold;
background: #27ae60;
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
user-select: none;
}
button:active { background: #2ecc71; }
.btn-action { background: #e74c3c; }
.btn-action:active { background: #c0392b; }
</style>
</head>
<body>
<div id="gameHeader">
<h1>THE Cambodia game</h1>
<p>បង្កើតដោយ៖ <b>មុត សាមេត</b></p>
</div>
<div id="canvasContainer">
<canvas id="gameCanvas" width="800" height="400"></canvas>
</div>
<div class="controls">
<button id="btnLeft">⬅ ឆ្វេង</button>
<button id="btnJump">⬆ លោត</button>
<button id="btnRight">ស្តាំ ➡</button>
<button id="btnAttack" class="btn-action">🗡 វាយសាម៉ូរ៉ៃ</button>
<button id="btnCraft" class="btn-action" style="background:#f39c12">🛡 ធ្វើអាវក្រោះ</button>
</div>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
// --- ប្រព័ន្ធសំឡេង (Web Audio API) ---
const AudioContext = window.AudioContext || window.webkitAudioContext;
const audioCtx = new AudioContext();
function playSound(freq, type, duration) {
if (audioCtx.state === 'suspended') audioCtx.resume();
const osc = audioCtx.createOscillator();
const gain = audioCtx.createGain();
osc.type = type;
osc.frequency.setValueAtTime(freq, audioCtx.currentTime);
gain.gain.setValueAtTime(0.1, audioCtx.currentTime);
gain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + duration);
osc.connect(gain);
gain.connect(audioCtx.destination);
osc.start();
osc.stop(audioCtx.currentTime + duration);
}
// --- តួអង្គ EREN ---
const eren = {
x: 100,
y: 280,
width: 30,
height: 50,
speed: 4,
dx: 0,
dy: 0,
gravity: 0.5,
jumpPower: -11,
isGrounded: false,
direction: 'right',
hp: 100,
maxHp: 100,
defense: 0, // កម្រិតការពារ
isAttacking: false,
attackTimer: 0,
// របស់រើសបាន
inventory: { wood: 0, iron: 0, food: 0 }
};
// --- បរិស្ថាន និង តំបន់ (Biomes) ---
let currentRegionIndex = 0;
const regions = [
{ name: "តំបន់ប្រាសាទបុរាណ (Grassland)", bg: "#87CEEB", ground: "#2ed573", detail: "temple" },
{ name: "វាលខ្សាច់ (Desert)", bg: "#f7d794", ground: "#eccc68", detail: "pyramid" },
{ name: "តំបន់ទឹកកក (Snowland)", bg: "#dff9fb", ground: "#c7ecee", detail: "ice" }
];
// --- NPC & បិសាច ---
const npc = { x: 300, y: 280, width: 30, height: 50, name: "កសិករ", dialog: "" };
let monsters = [{ x: 600, y: 290, width: 35, height: 40, hp: 30, speed: 1.5, dir: -1 }];
let items = [
{ x: 450, y: 305, type: 'food', label: '🍎' },
{ x: 550, y: 305, type: 'iron', label: '⚙️' }
];
// --- ប្រព័ន្ធបញ្ជា (Keyboard) ---
const keys = {};
window.addEventListener('keydown', e => {
keys[e.code] = true;
if(e.code === 'KeyF') attack();
});
window.addEventListener('keyup', e => keys[e.code] = false);
// ប៊ូតុង Touch លើ Mobile
document.getElementById('btnLeft').ontouchstart = () => keys['ArrowLeft'] = true;
document.getElementById('btnLeft').ontouchend = () => keys['ArrowLeft'] = false;
document.getElementById('btnRight').ontouchstart = () => keys['ArrowRight'] = true;
document.getElementById('btnRight').ontouchend = () => keys['ArrowRight'] = false;
document.getElementById('btnJump').onclick = () => { if(eren.isGrounded) eren.dy = eren.jumpPower; playSound(400, 'sine', 0.1); };
document.getElementById('btnAttack').onclick = () => attack();
document.getElementById('btnCraft').onclick = () => craftArmor();
function attack() {
eren.isAttacking = true;
eren.attackTimer = 10;
playSound(600, 'square', 0.15); // សំឡេងដាវ
}
function craftArmor() {
if(eren.inventory.iron >= 2) {
eren.inventory.iron -= 2;
eren.defense += 5;
alert("អ្នកបានធ្វើអាវក្រោះដែក! កម្លាំងការពារកើនឡើង +5");
playSound(800, 'triangle', 0.3);
} else {
alert("ត្រូវរកដែក ⚙️ ឲ្យបាន ២ ដើម្បីធ្វើអាវក្រោះ!");
}
}
// --- UPDATE GAME LOOP ---
function update() {
// ផ្លាស់ទី Eren
if (keys['ArrowRight'] || keys['KeyD']) {
eren.dx = eren.speed;
eren.direction = 'right';
} else if (keys['ArrowLeft'] || keys['KeyA']) {
eren.dx = -eren.speed;
eren.direction = 'left';
} else {
eren.dx = 0;
}
if ((keys['ArrowUp'] || keys['KeyW'] || keys['Space']) && eren.isGrounded) {
eren.dy = eren.jumpPower;
eren.isGrounded = false;
playSound(400, 'sine', 0.1);
}
// ទំនាញផែនដី
eren.dy += eren.gravity;
eren.x += eren.dx;
eren.y += eren.dy;
// ជើងប៉ះដី
if (eren.y + eren.height >= 330) {
eren.y = 330 - eren.height;
eren.dy = 0;
eren.isGrounded = true;
}
// ផ្លាស់ប្តូរតំបន់ (Map Transition)
if (eren.x > canvas.width) {
eren.x = 0;
currentRegionIndex = (currentRegionIndex + 1) % regions.length;
// Reset 怪物
monsters = [{ x: 700, y: 290, width: 35, height: 40, hp: 30, speed: 1.5, dir: -1 }];
} else if (eren.x < 0) {
eren.x = canvas.width - eren.width;
}
// ធ្វើបច្ចុប្បន្នភាពបិសាច
monsters.forEach(m => {
m.x += m.speed * m.dir;
if(m.x > 750 || m.x < 400) m.dir *= -1;
// វាយ Eren
if(Math.abs(eren.x - m.x) < 25 && Math.abs(eren.y - m.y) < 25) {
let dmg = 0.5 - (eren.defense * 0.05);
if(dmg < 0.1) dmg = 0.1;
eren.hp -= dmg;
if(eren.hp < 0) eren.hp = 0;
}
// Eren វាយបិសាច
if(eren.isAttacking) {
let swordX = eren.direction === 'right' ? eren.x + eren.width : eren.x - 30;
if(swordX < m.x + m.width && swordX + 30 > m.x && eren.y < m.y + m.height) {
m.hp -= 15;
playSound(200, 'sawtooth', 0.2);
}
}
});
monsters = monsters.filter(m => m.hp > 0);
if(eren.attackTimer > 0) eren.attackTimer--;
else eren.isAttacking = false;
// ឆែកមើល NPC (និយាយសួរ)
if (Math.abs(eren.x - npc.x) < 50) {
npc.dialog = "ជម្រាបសួរ Eren! ប្រយ័ត្នបិសាចខាងមុខ!";
} else {
npc.dialog = "";
}
// រើស Items
items.forEach((item, index) => {
if(Math.abs(eren.x - item.x) < 20) {
if(item.type === 'food') {
eren.hp = Math.min(100, eren.hp + 20);
playSound(500, 'sine', 0.2);
} else if(item.type === 'iron') {
eren.inventory.iron++;
playSound(700, 'triangle', 0.2);
}
items.splice(index, 1);
}
});
}
// --- DRAW GRAPHICS ---
function draw() {
let region = regions[currentRegionIndex];
ctx.fillStyle = region.bg;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// គូរប្រាសាទបុរាណ (Background Detail)
if(region.detail === 'temple') {
ctx.fillStyle = "#7f8c8d";
ctx.fillRect(600, 180, 120, 150);
ctx.fillRect(630, 130, 60, 50); // កំពូលប្រាសាទ
ctx.fillStyle = "#2c3e50";
ctx.fillRect(645, 250, 30, 80); // ទ្វារ
}
// គូរដើមឈើ & ថ្ម
ctx.fillStyle = "#795548"; ctx.fillRect(180, 230, 20, 100);
ctx.fillStyle = "#2e7d32"; ctx.beginPath(); ctx.arc(190, 220, 40, 0, Math.PI*2); ctx.fill(); // ដើមឈើ
ctx.fillStyle = "#95a5a6"; ctx.beginPath(); ctx.arc(380, 325, 10, 0, Math.PI*2); ctx.fill(); // ថ្ម
// គូរដី
ctx.fillStyle = region.ground;
ctx.fillRect(0, 330, canvas.width, 70);
// គូរ NPC (កសិករ)
ctx.fillStyle = "#e67e22";
ctx.fillRect(npc.x, npc.y, npc.width, npc.height);
ctx.fillStyle = "white"; ctx.fillText("NPC", npc.x + 3, npc.y - 5);
if(npc.dialog !== "") {
ctx.fillStyle = "black";
ctx.fillRect(npc.x - 40, npc.y - 35, 140, 25);
ctx.fillStyle = "white";
ctx.font = "12px Khmer OS Battambang";
ctx.fillText(npc.dialog, npc.x - 35, npc.y - 18);
}
// គូរ Items
items.forEach(item => {
ctx.font = "20px Arial";
ctx.fillText(item.label, item.x, item.y);
});
// គូរ Monster (បិសាច)
monsters.forEach(m => {
ctx.fillStyle = "#c0392b";
ctx.fillRect(m.x, m.y, m.width, m.height);
ctx.fillStyle = "black"; ctx.fillRect(m.x + 5, m.y + 5, 5, 5); // ភ្នែក
});
// គូរ EREN (តួរអង្គ)
// ខោខ្មៅ
ctx.fillStyle = "#000000";
ctx.fillRect(eren.x, eren.y + 25, eren.width, 25);
// អាវស
ctx.fillStyle = "#FFFFFF";
ctx.fillRect(eren.x, eren.y, eren.width, 25);
// ក្បាល
ctx.fillStyle = "#ffdbac";
ctx.fillRect(eren.x + 5, eren.y - 15, 20, 15);
// គូរដាវសាម៉ូរ៉ៃ
ctx.strokeStyle = "#bdc3c7";
ctx.lineWidth = 4;
ctx.beginPath();
if(eren.direction === 'right') {
let swordAngle = eren.isAttacking ? 10 : -30;
ctx.moveTo(eren.x + eren.width, eren.y + 15);
ctx.lineTo(eren.x + eren.width + 25, eren.y + swordAngle);
} else {
let swordAngle = eren.isAttacking ? 10 : -30;
ctx.moveTo(eren.x, eren.y + 15);
ctx.lineTo(eren.x - 25, eren.y + swordAngle);
}
ctx.stroke();
// គូរ UI ឈាម 100/100 និងព័ត៌មាន
ctx.fillStyle = "rgba(0,0,0,0.6)";
ctx.fillRect(10, 10, 220, 75);
// HP Bar
ctx.fillStyle = "red";
ctx.fillRect(20, 20, 150, 15);
ctx.fillStyle = "#2ecc71";
ctx.fillRect(20, 20, (eren.hp / eren.maxHp) * 150, 15);
ctx.fillStyle = "white";
ctx.font = "12px Arial";
ctx.fillText(`HP: ${Math.ceil(eren.hp)} / ${eren.maxHp}`, 25, 32);
ctx.fillText(`តំបន់: ${region.name}`, 20, 52);
ctx.fillText(`ដែក: ${eren.inventory.iron} | កម្លាំងការពារ: ${eren.defense}`, 20, 70);
}
// Loop ដំណើរការហ្គេម
function loop() {
update();
draw();
requestAnimationFrame(loop);
}
loop();
</script>
</body>
</html>1
1
13KB
13KB
235.0ms
296.0ms
235.0ms