ผู้เขียนบทความ : นายธีรภัทร วุ่นซิ้ว รหัสนักศึกษา s167204132041
คณะวิศวกรรมศาสตร์ : สาขาวิศวกรรมไฟฟ้า (สมทบ)
วิชา : 04-000-104 การโปรแกรมคอมพิวเตอร์ การศึกษาภาคที่1/2567
1.ความเป็นมา (Background)
มีแนวคิดคือต้องการเกมยิงเก็บคะแนนเล่นเพื่อผ่อนคลายในเวลาว่างและส่วนตัวมีความชอบในรถถังจึงนำมาสร้างเป็นเกมTank Simulator ในรูปแบบของโค้ดHTMLโดยในตัวเกมจะให้ผู้เล่นควบคุมรถถังได้อย่างอิสระโดยมีก้อนสี่เหลี่ยมสีน้ำเงินจะวิ่งเข้าหาเพื่อให้ผู้เล่นเคลื่อนที่หลบและยิงเพื่อเก็บคะแนน
2.วัตถุประสงค์(Objective)
- เพื่อสร้างความสนุกสนานและความผ่อนคลาย
- เพื่อฝึกทักษะการควบคุม
- เพื่อเสริมสร้างความสามารถในการคิดอย่างรวดเร็ว
- เพื่อสร้างความท้าทาย
- เพื่อพัฒนาทักษะการเขียนโค้ด
3.ขอบเขต(Scope)
- เกมจะเป็นแบบ 2D โดยผู้เล่นควบคุมรถถังที่สามารถเคลื่อนที่ได้ในทิศทางที่ต้องการ
- จะมี ก้อนสี่เหลี่ยมสีน้ำเงิน ที่เคลื่อนที่เข้าหารถถัง ซึ่งผู้เล่นต้องหลบหลีกและยิงเพื่อทำคะแนน
- ผู้เล่นจะใช้ ปุ่มลูกศร หรือ ปุ่ม W, A, S, D เพื่อเคลื่อนที่
- การยิงจะสามารถทำได้โดยการคลิกเมาส์
- ผู้เล่นจะได้รับคะแนนเมื่อสามารถยิงก้อนสี่เหลี่ยมได้
- จะมีการแสดงคะแนนรวมและคะแนนสูงสุด (high score) ในหน้าจอเกม
- เกมมีการตั้งค่าระดับความยากที่เพิ่มขึ้นเมื่อคะแนนสูงขึ้นความเร็วและจำนวนของก้อนสี่เหลี่ยมที่วิ่งเข้ามาจะมากขึ้น
4.ประโยชน์ที่คาดว่าจะได้รับ(Benefits)
- ช่วยผ่อนคลายและลดความเครียด
- พัฒนาทักษะการตอบสนองและการคิดวิเคราะห์
- ส่งเสริมการมีสมาธิ
5.ความรู้ที่เกี่ยวข้อง(Related Knowledge)
- พื้นฐานการเขียนโค้ด HTML, CSS, และ JavaScript:
- การควบคุมฟิสิกส์และการเคลื่อนไหว
- การออกแบบ UI/UX (User Interface / User Experience):
6.การดำเนินงาน(Implementation)
6.1: การตั้งค่าเริ่มต้น
- โครงสร้าง HTML:
- เกมประกอบด้วยสามส่วนหลัก:
- หน้าจอเริ่มเกม: แสดงปุ่ม “START”
- สนามเกม: มีรถถัง ป้อมปืน กระสุน คะแนน และแถบสุขภาพ
- หน้าจอเกมจบ: แสดงเมื่อเกมสิ้นสุด พร้อมปุ่ม “RESTART”
- เกมประกอบด้วยสามส่วนหลัก:
- สไตล์ CSS:
- กำหนดลักษณะทางภาพของเกม เช่น รถถัง ป้อมปืน กระสุน และเป้าหมาย
- ตั้งค่าการจัดวางสำหรับหน้าจอเริ่มเกมและหน้าจอเกมจบ
6.2: เริ่มเกม
- ตัวฟังเหตุการณ์สำหรับปุ่มเริ่มเกม:
- เมื่อคลิกปุ่ม “START”:
- หน้าจอเริ่มเกมจะถูกซ่อน
- สนามเกมจะแสดง
- สถานะของเกมจะถูกรีเซ็ต (คะแนน, สุขภาพ, และตำแหน่งของรถถัง)
- เมื่อคลิกปุ่ม “START”:
6.3: ฟังก์ชันการรีเซ็ตเกม
- รีเซ็ตสถานะของเกม:
- คะแนนจะถูกรีเซ็ตเป็น 0
- สุขภาพจะถูกรีเซ็ตเป็น 100
- ตำแหน่งของรถถังจะถูกรีเซ็ตไปยังตำแหน่งกลางหน้าจอ
- เป้าหมายที่มีอยู่ทั้งหมดจะถูกลบออก
- ตั้งค่าช่วงเวลาในการสร้างเป้าหมายเพื่อสร้างเป้าหมายทุก 2 วินาที
6.4: การเคลื่อนที่ของรถถัง
- การควบคุมด้วยคีย์บอร์ด:
- รถถังสามารถเคลื่อนที่ได้โดยใช้ปุ่ม W, A, S, และ D:
- W: เคลื่อนที่ขึ้น
- A: เคลื่อนที่ไปทางซ้าย
- S: เคลื่อนที่ลง
- D: เคลื่อนที่ไปทางขวา
- ตำแหน่งจะถูกอัปเดต และตำแหน่งใหม่ของรถถังจะแสดงบนหน้าจอ
- รถถังสามารถเคลื่อนที่ได้โดยใช้ปุ่ม W, A, S, และ D:
6.5: การหมุนป้อมปืน
- ป้อมปืนจะหมุนตามตำแหน่งของเมาส์ที่สัมพันธ์กับรถถัง:
- ตัวฟังเหตุการณ์จะติดตามการเคลื่อนที่ของเมาส์ โดยคำนวณมุมระหว่างรถถังและตัวชี้เมาส์
- การหมุนของป้อมปืนจะถูกอัปเดตตามนั้น
6.6: กลไกการยิง
- การยิงกระสุน:
- เมื่อคลิกปุ่มเมาส์ซ้าย:
- กระสุนจะถูกทำให้มองเห็นและตั้งอยู่ที่ตำแหน่งของป้อมปืน
- กระสุนจะเคลื่อนที่ในทิศทางที่ป้อมปืนหมุน
- ตำแหน่งของกระสุนจะถูกอัปเดตอย่างต่อเนื่องจนกว่าจะออกนอกหน้าจอหรือชนเป้าหมาย
- เมื่อคลิกปุ่มเมาส์ซ้าย:
6.7: การสร้างและเคลื่อนที่เป้าหมาย
- การสร้างเป้าหมาย:
- เป้าหมายจะถูกสร้างขึ้นที่ตำแหน่งสุ่มทุก 2 วินาที
- เป้าหมายจะแทนด้วยสี่เหลี่ยมสีน้ำเงินและเคลื่อนที่เข้าหารถถัง
- ตรรกะการเคลื่อนที่ของเป้าหมาย:
- เป้าหมายจะเคลื่อนที่เข้าหารถถังด้วยความเร็วที่กำหนด
- หากเป้าหมายชนกับรถถัง จะมีการลดสุขภาพลง 10
- หากสุขภาพลดลงถึง 0 หน้าจอเกมจบจะแสดงขึ้น
6.8: การตรวจจับการชน
- การชนระหว่างกระสุนและเป้าหมาย:
- เมื่อกระสุนเคลื่อนที่ จะมีการตรวจสอบว่าชนกับเป้าหมายหรือไม่:
- หากตรวจจับได้ว่าชน เป้าหมายจะถูกลบออก และคะแนนจะเพิ่มขึ้น 10
- หากคะแนนถึงจำนวนที่เป็นทวีคูณของ 100 ความเร็วของเป้าหมายจะเพิ่มขึ้น
- เมื่อกระสุนเคลื่อนที่ จะมีการตรวจสอบว่าชนกับเป้าหมายหรือไม่:
- การชนระหว่างรถถังและเป้าหมาย:
- เกมจะตรวจสอบว่าเป้าหมายชนกับรถถังหรือไม่
- หากเกิดการชน สุขภาพจะลดลง และเป้าหมายจะถูกลบออก
6.9: สถานะเกมจบ
- หากสุขภาพลดลงถึง 0 หน้าจอเกมจบจะแสดงขึ้น โดยให้ผู้เล่นสามารถรีสตาร์ตเกมได้
6.10: การรีสตาร์ตเกม
- ปุ่ม “RESTART” จะช่วยให้ผู้เล่นรีเซ็ตสถานะของเกม:
- หน้าจอเกมจบจะถูกซ่อน
- สนามเกมจะแสดงขึ้นอีกครั้ง
- สถานะของเกมจะถูกรีเซ็ตเหมือนขั้นตอนการเริ่มเกม
7. วิธีการใช้งานโปรแกรม (How to Use)
7.1 เริ่มเกม
- เปิดไฟล์ HTML ในเว็บเบราว์เซอร์ (เช่น Chrome, Firefox หรือ Edge)
- เมื่อเปิดหน้าเกมขึ้นมา คุณจะเห็นหน้าจอเริ่มเกมที่มีปุ่ม “START” อยู่กลางหน้าจอ
- คลิกที่ปุ่ม “START” เพื่อเริ่มเกม
7.2 การควบคุมรถถัง
- การเคลื่อนที่ของรถถัง:
- ใช้แป้นพิมพ์เพื่อเคลื่อนที่รถถัง:
- กดปุ่ม W เพื่อเคลื่อนที่ขึ้น
- กดปุ่ม A เพื่อเคลื่อนที่ไปทางซ้าย
- กดปุ่ม S เพื่อเคลื่อนที่ลง
- กดปุ่ม D เพื่อเคลื่อนที่ไปทางขว
- ใช้แป้นพิมพ์เพื่อเคลื่อนที่รถถัง:
- การหมุนป้อมปืน:
- ใช้เมาส์ในการเคลื่อนที่ เพื่อให้ป้อมปืนหมุนตามตำแหน่งของเมาส์
- ป้อมปืนจะชี้ไปในทิศทางที่เมาส์อยู่
7.3 การยิงกระสุน
- เมื่อคุณต้องการยิงกระสุน:
- คลิกปุ่มเมาส์ซ้าย (ปุ่มที่ใช้คลิก) เพื่อยิงกระสุนจากป้อมปืน
- กระสุนจะเคลื่อนที่ไปในทิศทางที่ป้อมปืนชี้
7.4 เป้าหมายในเกม
- เป้าหมาย (สี่เหลี่ยมสีน้ำเงิน) จะปรากฏในสนามเกมและจะเคลื่อนที่เข้าหารถถัง
- เมื่อกระสุนชนเป้าหมาย:
- คะแนนของคุณจะเพิ่มขึ้น 10 คะแนน
- เป้าหมายจะถูกลบออกจากสนาม
7.5 สุขภาพของรถถัง
- รถถังมีสุขภาพเริ่มต้นที่ 100
- หากเป้าหมายชนกับรถถัง:
- สุขภาพจะลดลง 10
- หากสุขภาพลดลงเหลือ 0 คุณจะแพ้เกม
7.6 หน้าจอเกมจบ
- เมื่อสุขภาพของรถถังลดลงถึง 0:
- หน้าจอเกมจบจะปรากฏขึ้น โดยจะมีข้อความ “Game Over!”
- คุณสามารถคลิกที่ปุ่ม “RESTART” เพื่อเริ่มเกมใหม่
7.7 รีสตาร์ตเกม
- คลิกที่ปุ่ม “RESTART” บนหน้าจอเกมจบ:
- สถานะของเกมจะถูกรีเซ็ต (คะแนน, สุขภาพ, และตำแหน่งของรถถัง)
- สนามเกมจะปรากฏขึ้นอีกครั้งและคุณสามารถเริ่มเล่นใหม่ได้
ข้อควรจำ
- คุณสามารถควบคุมรถถังและป้อมปืนได้อย่างอิสระ
- พยายามหลีกเลี่ยงการถูกชนจากเป้าหมายเพื่อรักษาสุขภาพ
- สนุกไปกับการเล่นเกมและพัฒนาทักษะการยิงของคุณ!
หากคุณมีคำถามเพิ่มเติมเกี่ยวกับการใช้งานหรือฟีเจอร์ของเกม คุณสามารถถามได้เลย!
8. การทดลอง (Testing)
- ควบคุมรถถัง: ใช้ปุ่ม W, A, S, D เพื่อเคลื่อนที่ ทำงานได้ราบรื่น
- ยิงกระสุน: ยิงได้โดยการคลิกปุ่มซ้ายของเมาส์ กระสุนเคลื่อนที่ในทิศทางที่ถูกต้อง
- สร้างเป้าหมาย: เป้าหมายปรากฏทุก 2 วินาทีและเคลื่อนที่เข้าหารถถัง
- สุขภาพของรถถัง: เริ่มที่ 100 ลดลงเมื่อถูกชน โดยเกมจบเมื่อสุขภาพถึง
- รีสตาร์ตเกม: ผู้เล่นสามารถรีสตาร์ตได้โดยคลิก “RESTART”
9.สรุปผลและข้อเสนอแนะ (Conclusion and Recommendation)
9.1การควบคุม:
- ใช้ W, A, S, D เคลื่อนที่ และคลิกซ้ายยิงกระสุน
9.2การทำงานของเกม:
- เป้าหมายเคลื่อนที่เข้าหารถถังทุก 2 วินาที
- ชนเป้าหมายลดสุขภาพ และเกมจบเมื่อสุขภาพถึง 0
9.3การให้คะแนน:
- คะแนนเพิ่มเมื่อยิงถูกเป้าหมาย และคะแนนสูงขึ้นทำให้เป้าหมายเคลื่อนที่เร็วขึ้น
ข้อเสนอแนะ
- ปรับปรุงกราฟิก: เพิ่มกราฟิกที่น่าสนใจ
- เพิ่มเสียง: ใส่เสียงเอฟเฟกต์เพื่อเพิ่มอารมณ์
- ปรับสมดุล: ปรับความเร็วและจำนวนเป้าหมายเพื่อความท้าทาย
- ระบบพัฒนา: เพิ่มการพัฒนารถถังหรือกระสุนเพื่อดึงดูดผู้เล่น
10.อ้างอิง
เรียนรู้การสร้างเกมจาก
เรียนรู้วิธีการใช้แชทสร้างเกมจากhttps://www.youtube.com/watch?v=fQuGDsD8cIY&t=9s
ทดลองโค้ดจากhttps://www.onlinegdb.com/
ผู้ช่วยในการทำเกมนี้https://chatgpt.com/
โค้ด (CODE)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tank Simulation</title>
<style>
body {
margin: 0;
background-color: #f0f0f0;
overflow: hidden;
}
.playground {
position: relative;
width: 100vw;
height: 100vh;
display: none;
justify-content: center;
align-items: center;
}
.tank {
position: absolute;
width: 150px;
height: 75px;
background-color: green;
border-radius: 30px;
transform-origin: center;
}
.turret {
position: absolute;
top: 50%;
left: 50%;
width: 60px;
height: 60px;
background-color: gray;
border-radius: 50%;
transform: translate(-50%, -50%);
transform-origin: center;
}
.gun {
position: absolute;
top: 50%;
left: 50%;
width: 75px;
height: 20px;
background-color: lightgray;
transform-origin: 0% 50%;
transform: translate(20%, -50%);
}
.bullet {
position: absolute;
width: 10px;
height: 10px;
background-color: red;
border-radius: 50%;
display: none;
}
.target {
position: absolute;
width: 30px;
height: 30px;
background-color: blue;
display: none;
}
.score {
position: absolute;
top: 10px;
left: 10px;
font-size: 24px;
font-weight: bold;
color: #333;
}
.health {
position: absolute;
top: 40px;
left: 10px;
font-size: 24px;
font-weight: bold;
color: red;
}
.start-screen {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.7);
display: flex;
justify-content: center;
align-items: center;
}
.start-button, .restart-button {
padding: 20px 40px;
font-size: 32px;
background-color: #28a745;
color: white;
border: none;
border-radius: 10px;
cursor: pointer;
}
.start-button:hover, .restart-button:hover {
background-color: #218838;
}
.game-over-screen {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.7);
display: none;
justify-content: center;
align-items: center;
flex-direction: column;
}
</style>
</head>
<body>
<div class="start-screen">
<button class="start-button" id="startButton">START</button>
</div>
<div class="playground">
<div class="tank" id="tank">
<div class="turret" id="turret">
<div class="gun" id="gun"></div>
</div>
</div>
<div class="bullet" id="bullet"></div>
<div class="score" id="score">Score: 0</div>
<div class="health" id="health">HP: 100</div>
</div>
<div class="game-over-screen" id="gameOverScreen">
<h1 style="color: white;">Game Over!</h1>
<button class="restart-button" id="restartButton">RESTART</button>
</div>
<script>
const startButton = document.getElementById('startButton');
const restartButton = document.getElementById('restartButton');
const startScreen = document.querySelector('.start-screen');
const playground = document.querySelector('.playground');
const tank = document.getElementById('tank');
const turret = document.getElementById('turret');
const gun = document.getElementById('gun');
const bullet = document.getElementById('bullet');
const scoreDisplay = document.getElementById('score');
const healthDisplay = document.getElementById('health');
const gameOverScreen = document.getElementById('gameOverScreen');
let score = 0;
let health = 100;
let position = {
top: 50,
left: 50
};
const step = 2;
let targetSpeed = 1;
let tankAngle = 0;
let targetCreationInterval;
startButton.addEventListener('click', () => {
startScreen.style.display = 'none';
playground.style.display = 'flex';
resetGame();
});
restartButton.addEventListener('click', () => {
gameOverScreen.style.display = 'none';
playground.style.display = 'flex';
resetGame();
});
function resetGame() {
score = 0;
health = 100;
position = { top: 50, left: 50 };
scoreDisplay.textContent = `Score: ${score}`;
healthDisplay.textContent = `HP: ${health}`;
document.querySelectorAll('.target').forEach(target => target.remove());
clearInterval(targetCreationInterval);
targetCreationInterval = setInterval(createTarget, 2000);
updateTankPosition();
}
function updateTankPosition() {
tank.style.top = position.top + 'vh';
tank.style.left = position.left + 'vw';
tank.style.transform = `translate(-50%, -50%) rotate(${tankAngle}deg)`;
}
function updateTurretRotation(mouseX, mouseY) {
const tankRect = tank.getBoundingClientRect();
const tankCenterX = tankRect.left + tankRect.width / 2;
const tankCenterY = tankRect.top + tankRect.height / 2;
const dx = mouseX - tankCenterX;
const dy = mouseY - tankCenterY;
const angle = Math.atan2(dy, dx) * (180 / Math.PI);
turret.style.transform = `translate(-50%, -50%) rotate(${angle}deg)`;
}
function moveTank(event) {
if (event.key === 'w' || event.key === 'W') {
position.top = Math.max(position.top - step, 0);
} else if (event.key === 's' || event.key === 'S') {
position.top = Math.min(position.top + step, 100);
} else if (event.key === 'a' || event.key === 'A') {
position.left = Math.max(position.left - step, 0);
} else if (event.key === 'd' || event.key === 'D') {
position.left = Math.min(position.left + step, 100);
}
updateTankPosition();
}
function shoot() {
const turretRect = turret.getBoundingClientRect();
bullet.style.display = 'block';
bullet.style.top = (turretRect.top + turretRect.height / 2) + 'px';
bullet.style.left = (turretRect.left + turretRect.width / 2) + 'px';
let bulletAngle = parseFloat(turret.style.transform.match(/rotate\(([^)]+)deg\)/)[1]) * (Math.PI / 180);
let bulletStep = 8;
const moveBullet = () => {
const bulletX = parseFloat(bullet.style.left);
const bulletY = parseFloat(bullet.style.top);
bullet.style.left = (bulletX + bulletStep * Math.cos(bulletAngle)) + 'px';
bullet.style.top = (bulletY + bulletStep * Math.sin(bulletAngle)) + 'px';
if (bulletX < 0 || bulletX > window.innerWidth || bulletY < 0 || bulletY > window.innerHeight) {
bullet.style.display = 'none';
return;
}
checkCollision(bulletX, bulletY);
requestAnimationFrame(moveBullet);
};
moveBullet();
}
function createTarget() {
const target = document.createElement('div');
target.classList.add('target');
target.style.display = 'block';
target.style.top = Math.random() * (window.innerHeight - 30) + 'px';
target.style.left = Math.random() * (window.innerWidth - 30) + 'px';
playground.appendChild(target);
moveTarget(target);
}
function moveTarget(target) {
const moveInterval = setInterval(() => {
const tankRect = tank.getBoundingClientRect();
const targetRect = target.getBoundingClientRect();
const dx = tankRect.left - targetRect.left;
const dy = tankRect.top - targetRect.top;
const distance = Math.sqrt(dx * dx + dy * dy);
const directionX = dx / distance;
const directionY = dy / distance;
target.style.left = targetRect.left + directionX * targetSpeed + 'px';
target.style.top = targetRect.top + directionY * targetSpeed + 'px';
if (checkTankCollision(targetRect)) {
health -= 10;
healthDisplay.textContent = `HP: ${health}`;
target.remove();
clearInterval(moveInterval);
if (health <= 0) {
gameOverScreen.style.display = 'flex';
playground.style.display = 'none';
}
}
}, 100);
}
function checkCollision(bulletX, bulletY) {
const targets = document.querySelectorAll('.target');
targets.forEach(target => {
const targetRect = target.getBoundingClientRect();
if (bulletX >= targetRect.left && bulletX <= targetRect.right &&
bulletY >= targetRect.top && bulletY <= targetRect.bottom) {
score += 10;
scoreDisplay.textContent = `Score: ${score}`;
target.remove();
bullet.style.display = 'none';
if (score % 100 === 0) {
targetSpeed += 1;
}
}
});
}
function checkTankCollision(targetRect) {
const tankRect = tank.getBoundingClientRect();
return !(targetRect.right < tankRect.left ||
targetRect.left > tankRect.right ||
targetRect.bottom < tankRect.top ||
targetRect.top > tankRect.bottom);
}
document.addEventListener('keydown', moveTank);
document.addEventListener('mousemove', function(event) {
updateTurretRotation(event.clientX, event.clientY);
});
document.addEventListener('mousedown', function(event) {
if (event.button === 0) {
shoot();
}
});
targetCreationInterval = setInterval(createTarget, 2000);
updateTankPosition();
</script>
</body>
</html>