บทที่ 1 จาก 8 · ดูฟรี
แนะนำคอร์สและเตรียมเครื่องมือ
ยินดีต้อนรับเข้าสู่คอร์ส สร้างเกมบนเว็บแนว Cozy Adventure ด้วย Go + Three.js + Pixel Art ในบทแรกนี้เราจะทำความรู้จักกับแนวเกม Cozy Adventure ว่ามันคืออะไร ทำไมถึงกำลังเป็นที่นิยม และที่สำคัญคือเราจะเตรียมเครื่องมือพัฒนาเกมทั้งหมดให้พร้อม ไม่ว่าจะเป็น Go, Node.js และ Three.js พร้อมตั้งค่าโปรเจคเริ่มต้นที่เราจะใช้ต่อยอดตลอดทั้งคอร์ส
ทำความรู้จักกับเกมแนว Cozy Adventure
คำว่า Cozy ในวงการเกมไม่ได้หมายถึงแค่เกมที่ "น่ารัก" แต่หมายถึงเกมที่สร้างความรู้สึกผ่อนคลาย อบอุ่น ปลอดภัย และไม่กดดันผู้เล่น เกมแนว Cozy Adventure มักมีลักษณะเด่นดังนี้
- ไม่มีการลงโทษที่รุนแรง — ตายหรือพลาดก็ไม่เสียอะไรมาก
- เน้นการสำรวจและค้นหา — ผู้เล่นเดินไปในโลกเพื่อค้นพบสิ่งใหม่ๆ ด้วยจังหวะของตัวเอง
- เรื่องราวอบอุ่น — เน้นมิตรภาพ การช่วยเหลือ การพบปะตัวละครน่ารัก
- ดนตรีและบรรยากาศสบายๆ — เสียงเพลงนุ่มนวล สีโทนอบอุ่น
- เป้าหมายนุ่มนวล — ไม่ใช่การกำจัดบอส แต่อาจเป็นการปลูกต้นไม้ ช่วยชาวบ้าน หรือสะสมของ
ตัวอย่างเกมแนวนี้ที่หลายคนรู้จัก เช่น Stardew Valley, Animal Crossing, A Short Hike หรือ Spiritfarer ในคอร์สนี้เราจะสร้างเกม Cozy Adventure บนเว็บเบราว์เซอร์ ที่ผู้เล่นสามารถเดินสำรวจโลก 3D ที่ตกแต่งด้วย Pixel Art พูดคุยกับ NPC และทำภารกิจเล็กๆ ได้
เครื่องมือที่เราจะใช้ในคอร์สนี้
เกมบนเว็บที่สมบูรณ์ต้องมีทั้ง Frontend สำหรับแสดงผลและ Backend สำหรับจัดการข้อมูล ในคอร์สนี้เราเลือกเครื่องมือดังนี้
| เครื่องมือ | บทบาท | เหตุผลที่เลือก |
|---|---|---|
| Go | Backend server | ประสิทธิภาพสูง เริ่มต้นง่าย เหมาะกับเกม |
| Node.js | จัดการ package ฝั่ง frontend | ใช้ติดตั้ง Three.js ผ่าน npm |
| Three.js | 3D engine บนเว็บ | ไลบรารี 3D ยอดนิยม ทำงานบน WebGL |
| HTML5 | UI และโครงสร้างหน้าเว็บ | มาตรฐานเว็บ ทุกเบราว์เซอร์รองรับ |
สถาปัตยกรรมโดยรวม
┌─────────────┐ HTTP/WebSocket ┌──────────────┐
│ Frontend │ ◄──────────────────► │ Backend │
│ (Browser) │ │ (Go server) │
│ │ │ │
│ Three.js │ │ จัดการ state │
│ HTML5 UI │ │ บันทึกข้อมูล │
│ Pixel Art │ │ ส่งข้อมูลเกม │
└─────────────┘ └──────────────┘
ผู้เล่นเปิดเบราว์เซอร์เข้าเกม → Go server ส่งไฟล์ frontend และข้อมูลเกม → Three.js แสดงผล 3D → HTML จัดการ UI → การกระทำของผู้เล่นส่งกลับไป server
ติดตั้ง Go
Go เป็นภาษาที่เราจะใช้เขียน Backend ขั้นตอนการติดตั้งมีดังนี้
Windows
- ดาวน์โหลดตัวติดตั้งได้จาก https://go.dev/dl/
- เปิดไฟล์
.msiแล้วทำตามขั้นตอน - เปิด Command Prompt แล้วพิมพ์
go version
ถ้าขึ้น go version go1.2x.x windows/amd64 ถือว่าติดตั้งสำเร็จ
macOS
brew install go
หรือดาวน์โหลดจากเว็บไซต์แล้วติดตั้งผ่าน .pkg
Linux
wget https://go.dev/dl/go1.22.0.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.22.0.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
เพิ่มบรรทัด export PATH ใน ~/.bashrc หรือ ~/.zshrc เพื่อให้ใช้ได้ถาวร
ทดสอบ Go ครั้งแรก
สร้างไฟล์ hello.go
package main
import "fmt"
func main() {
fmt.Println("สวัสดีชาวโลก! Go พร้อมทำงานแล้ว")
}
รันด้วยคำสั่ง
go run hello.go
ผลลัพธ์
สวัสดีชาวโลก! Go พร้อมทำงานแล้ว
ติดตั้ง Node.js
Node.js จำเป็นสำหรับการติดตั้ง Three.js และจัดการ package ฝั่ง frontend ผ่าน npm
- ดาวน์โหลดจาก https://nodejs.org/ (แนะนำเวอร์ชัน LTS)
- ติดตั้งตามขั้นตอนปกติของระบบปฏิบัติการ
- ตรวจสอบการติดตั้ง
node --version
npm --version
ผลลัพธ์ควรเป็นเลขเวอร์ชัน เช่น v20.11.0 และ 10.2.4
💡 เคล็ดลับ: หากต้องการจัดการเวอร์ชัน Node.js หลายเวอร์ชัน แนะนำให้ใช้ nvm (macOS/Linux) หรือ nvm-windows
ติดตั้ง Three.js
Three.js เป็นไลบรารี JavaScript สำหรับสร้างกราฟิก 3D บนเว็บผ่าน WebGL เราจะติดตั้งผ่าน npm
สร้างโฟลเดอร์โปรเจคแล้วรันคำสั่ง
mkdir cozy-adventure
cd cozy-adventure
npm init -y
npm install three
ไฟล์ package.json จะถูกสร้างอัตโนมัติ และ Three.js จะอยู่ในโฟลเดอร์ node_modules/three
ตั้งค่าโปรเจคเริ่มต้น
ตอนนี้เรามาสร้างโครงสร้างโปรเจคที่จะใช้ตลอดทั้งคอร์ส
โครงสร้างโฟลเดอร์
cozy-adventure/
├── backend/
│ ├── main.go
│ ├── go.mod
│ └── handlers/
│ └── game.go
├── frontend/
│ ├── index.html
│ ├── css/
│ │ └── style.css
│ ├── js/
│ │ └── main.js
│ └── assets/
│ └── (pixel art จะเพิ่มในบทถัดไป)
├── package.json
└── README.md
สร้าง Backend ด้วย Go
เข้าไปในโฟลเดอร์ backend แล้วสร้าง module
cd backend
go mod init cozy-adventure
สร้างไฟล์ main.go
package main
import (
"log"
"net/http"
)
func main() {
// ให้บริการไฟล์ frontend จากโฟลเดอร์ frontend
fs := http.FileServer(http.Dir("../frontend"))
http.Handle("/", fs)
// API endpoint สำหรับดึงข้อมูลเกม
http.HandleFunc("/api/game-state", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"status":"ok","message":"ยินดีต้อนรับสู่ Cozy Adventure!"}`))
})
log.Println("เซิร์ฟเวอร์เริ่มทำงานที่ http://localhost:8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
รันเซิร์ฟเวอร์
go run main.go
สร้าง Frontend ด้วย HTML5
สร้างไฟล์ frontend/index.html
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cozy Adventure</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div id="game-container">
<canvas id="game-canvas"></canvas>
<div id="ui-overlay">
<h1>Cozy Adventure</h1>
<p id="status-text">กำลังโหลดเกม...</p>
</div>
</div>
<script type="module" src="js/main.js"></script>
</body>
</html>
สร้างไฟล์ frontend/css/style.css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: #2a1f3d;
font-family: 'Courier New', monospace;
overflow: hidden;
}
#game-container {
position: relative;
width: 100vw;
height: 100vh;
}
#game-canvas {
display: block;
width: 100%;
height: 100%;
}
#ui-overlay {
position: absolute;
top: 20px;
left: 20px;
color: #f5e6c8;
text-shadow: 2px 2px 0 #000;
pointer-events: none;
}
#ui-overlay h1 {
font-size: 28px;
margin-bottom: 8px;
}
#status-text {
font-size: 14px;
opacity: 0.8;
}
สร้างไฟล์ frontend/js/main.js
import * as THREE from 'three';
// สร้าง scene, camera, renderer เบื้องต้น
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x9bc4e8); // ท้องฟ้าสีฟ้าอบอุ่น
const camera = new THREE.PerspectiveCamera(
60,
window.innerWidth / window.innerHeight,
0.1,
1000
);
camera.position.set(0, 5, 10);
camera.lookAt(0, 0, 0);
const canvas = document.getElementById('game-canvas');
const renderer = new THREE.WebGLRenderer({ canvas });
renderer.setSize(window.innerWidth, window.innerHeight);
// สร้างพื้นดินชั่วคราว
const groundGeo = new THREE.PlaneGeometry(50, 50);
const groundMat = new THREE.MeshStandardMaterial({ color: 0x7cb342 });
const ground = new THREE.Mesh(groundGeo, groundMat);
ground.rotation.x = -Math.PI / 2;
scene.add(ground);
// แสง
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
scene.add(ambientLight);
const dirLight = new THREE.DirectionalLight(0xfff4e6, 0.8);
dirLight.position.set(5, 10, 5);
scene.add(dirLight);
// ดึงข้อมูลจาก backend
fetch('/api/game-state')
.then(res => res.json())
.then(data => {
document.getElementById('status-text').textContent = data.message;
});
// Render loop
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
// ปรับขนาดเมื่อ resize
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
ทดสอบรันโปรเจค
- ในเทอร์มินัลที่โฟลเดอร์
backendรัน
go run main.go
- เปิดเบราว์เซอร์ไปที่ http://localhost:8080
คุณจะเห็นหน้าจอเกมที่มีพื้นหญ้าเขียว ท้องฟ้าสีฟ้า และข้อความ "ยินดีต้อนรับสู่ Cozy Adventure!" ที่มุมบนซ้าย นั่นคือจุดเริ่มต้นของเกมของคุณ!
⚠️ หมายเหตุ: หากเบราว์เซอร์แสดงหน้าว่าง ให้เปิด Developer Tools (F12) ดูที่แท็บ Console เพื่อตรวจสอบ error ส่วนใหญ่มาจาก path ของไฟล์ไม่ถูกต้อง
สรุปท้ายบท
ในบทนี้เราได้เรียนรู้
- ความหมายและลักษณะเด่นของเกมแนว Cozy Adventure
- เครื่องมือทั้งหมดที่จะใช้: Go (backend), Node.js (package manager), Three.js (3D engine), HTML5 (UI)
- การติดตั้งและตรวจสอบเครื่องมือทั้งหมด
- การสร้างโครงสร้างโปรเจคเริ่มต้นที่จะใช้ตลอดคอร์ส
- การเขียน Go server พื้นฐานที่ให้บริการไฟล์ frontend และ API
- การเขียน Three.js เบื้องต้นเพื่อแสดง scene 3D
ตอนนี้เรามีพื้นที่สีเขียวกับท้องฟ้าสีฟ้าเป็นจุดเริ่มต้น ในบทถัดไปเราจะเจาะลึกการเขียน Backend ด้วย Go ให้ละเอียดขึ้น เรียนรู้การจัดการ state ของเกม การสร้าง API ที่ซับซ้อนขึ้น และการเชื่อมต่อระหว่าง frontend กับ backend อย่างเป็นระบบ
บทถัดไป: พื้นฐาน Backend สำหรับเกมด้วย Go — เราจะเรียนรู้โครงสร้าง Go server ที่เหมาะกับเกม, การจัดการ game state, และการสื่อสารระหว่าง client กับ server ผ่าน HTTP และ WebSocket