[62010494] วิธีการเขียน Class และทำความรู้จักกับมันเพื่อประยุกต์ใช้สร้างเกม
สวัสดีครับผม วันนี้ผมจะพาทุกคนมาทำความรู้จักเกี่ยวกับคลาส ต้องบอกก่อนเลยนะครับว่าผมไม่แน่ใจว่าจะทำให้ทุกคนเห็นภาพได้ง่ายๆอย่างไง แต่สำหรับผมมองว่า Class เนี่ยเปรียบเสมือน “หนังสือที่เก็บรวบรวมวิธีการต่างๆ” อย่างเช่น สมมุติว่าเรามี หนังสือที่ชื่อว่า การทำอาหาร(Class) ในหนังสือก็จะมีวิธีการทำอาหารต่างๆ(Function) ถ้าเราทำเสร็จเราก็จะได้ อาหาร(Object) เป็นต้น ตามทฤษฏี Class คือ การเขียนโปรแกรมเชิงวัตถุ (program code template) เพื่อสร้าง Object เอาล่ะทีนี้เรามาดูกันว่า Class มีหน้าตาหรือรูปแบบเป็นอย่างไร
class class_name
{
access_specifier_1:
member_1;
access_specifier_2:
member_2;
...
} object_names;ทุกคนอาจจะสงสัยว่าทำไมมันคล้ายกับการเขียน structure ใช่แล้วครับมันคล้ายกันแต่ต่างกันที่ว่า Class จะมีการฟังชันก์เป็นสมาชิกของตัวเอง + ตัวกำหนดการเข้าถึง (Access specifier) ซึ่งตัวกำหนดการเข้าถึงจะมีดังนี้
private: สมาชิกประเภทนี้สามารถเข้าถึงได้โดย Class และObjectเดียวกัน และเป็นค่าเริ่มต้น(default) เมื่อเราไม่ได้กำหนดไว้protected: สมาชิกประเภทนี้สามารถเข้าถึงได้ใน Class เดียวกัน และ Class เพิ่มเติมหรือเรียกง่ายๆว่า Class ย่อย(extended classes)public: สมาชิกประเภทนี้สามารถเข้าถึงได้ทุกส่วนของโปรแกรม
ถึงตอนนี้แล้วผมจะให้ทุกคนไปดูรูปแบบ ตัวอย่าง ของ Class แต่ก่อนจะไปดู ผมจะบอกก่อนว่าใน Class นี่จะมีสิ่งที่เราเรียกว่า Constructor กับ Deconstructor ซึ่งเป็น method ของ Class
Constructor ส่วนใหญ่จะไว้ใช้ เซ็ตค่าเริ่มต้น เมื่อเราทำการเรียก class นั้นๆ
Deconstructor ให้ Class ทำอะไรบางอย่างก่อนที่ Class นั้นจะถูกทำลายลง หรือ จบการทำงาน
ไม่จำเป็นต้องมีทั้งคู่ใน Class ก็ได้แต่ต้องมีอย่างใดอย่างหนึ่ง เอาล่ะไปดูตัวอย่างกันเลย จะเป็น Class Constructor
#include <iostream>
using namespace std;
class Line {
public:
void setLength( double len );
double getLength( void );
Line(); // Constructor
private:
double length;
};
// สมาชิกของฟังชันก์ใน Constructor (ในความคิดของผม :: ชุดคำสั่งใน Class Line)
Line::Line(void) {
cout << "Object is being created" << endl;
}
void Line::setLength( double len ) {
length = len;
}
double Line::getLength( void ) {
return length;
}
// ฟังชันก์หลักของโปรแกรม
int main() {
Line line;
// set line length
line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;
return 0;
}เมื่อเราสั่งให้โปรแกรมทำงาน ผลที่ได้จะแสดงออกมาเป็นดังนี้
Object is being created
Length of line : 6แล้วก็มาดูตัวอย่างของ Class Deconstructor กันดีกว่า
#include <iostream>
using namespace std;
class Line {
public:
void setLength( double len );
double getLength( void );
Line(); // Constructor declaration
~Line(); // Destructor: declaration
private:
double length;
};
// Member functions definitions including constructor
Line::Line(void) {
cout << "Object is being created" << endl;
}
Line::~Line(void) {
cout << "Object is being deleted" << endl;
}
void Line::setLength( double len ) {
length = len;
}
double Line::getLength( void ) {
return length;
}
// Main function for the program
int main() {
Line line;
// set line length
line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;
return 0;
}แล้วเมื่อโปรแกรมทำงานและจบการทำงานจะแสดงผลดังนี้
Object is being created // Class ทำงานคือ สร้าง Object แล้ว
Length of line : 6
Object is being deleted // Class จบการทำงาน(ขอขอบคุณ Code ตัวอย่าง จาก https://www.tutorialspoint.com/cplusplus/cpp_constructor_destructor.htm)
เท่านี้เราก็เริ่มรู้จักกับ Class แล้ว ทีนี้มาดูกันว่าเราจะประยุกต์ใช้กับการสร้างเกมอย่างไร
โดยผมจะยกตัวอย่างกับโปรเจคเกมของผมส่วนหนึ่งที่ใช้ Class โดยผมจะมีไฟล์ .h กับ .cpp จะเป็นการทำ Animation (เลื่อนรูปของ sprite-sheet) โดย
Animation.h => กำหนดฟังชันก์ และค่าตัวแปรต่างๆ (อารมณ์ประมาณสารบัญหนังสืออ่ะเนอะ แบบว่ามีอะไรบ้าง)
Animation.cpp => การทำงานของฟังชันก์แต่ละอันที่เรากำหนดแล้วดึงค่าตัวแปรไปใช้ (เปรียบเสมือนรายละเอียดแต่ละหัวข้อของหนังสือ)
อันนี้จะเป็นส่วนของ Animation.h (Header File)
#pragma once#include<SFML/Graphics.hpp>class Animation{public:Animation(sf::Texture* texture,sf ::Vector2u imageCount,float switchTime); //Constructor~Animation(); //Deconstructorvoid Update(int row, float deltaTime , bool isLeft); //Function Memberpublic: //การกำหนดเข้าถึงแบบ publicsf::IntRect uvRect;private: //การกำหนดเข้าถึงแบบ private//sf::IntRect recta;sf::Vector2u imageCount;sf::Vector2u currentImage;float totalTime;float switchTime;};
อันนี้จะเป็นส่วนของ Animation.cpp
#include "Animation.h"Animation::Animation(sf::Texture* texture, sf::Vector2u imageCount, float switchTime) {this->imageCount = imageCount;this->switchTime = switchTime;totalTime = 0.0f;currentImage.x = 0;currentImage.y = 0;uvRect.width = texture->getSize().x / float(imageCount.x);uvRect.height = texture->getSize().y / float(imageCount.y) + 10;}Animation::~Animation() {}void Animation::Update(int row, float deltaTime, bool isLeft){currentImage.y = row;totalTime += deltaTime;if (totalTime >= switchTime) {totalTime -= switchTime;currentImage.x++;if (currentImage.x >= imageCount.x -1 && currentImage.y == 0) {currentImage.x = 0;}if (currentImage.x >= imageCount.x && currentImage.y == 1) {currentImage.x = 0;}}//uvRect.left = currentImage.x * uvRect.width;uvRect.top = currentImage.y * uvRect.height;if (isLeft) {uvRect.left = currentImage.x * uvRect.width;uvRect.width = abs(uvRect.width);}else {uvRect.left = (currentImage.x +1) * abs(uvRect.width);uvRect.width = -abs(uvRect.width);}}
(ทั้งสองอันนี้ที่กล่าวมาอยากให้เห็นภาพว่าเราสามารถเอา Class ไปใช้ได้อย่างไงจึงขอไม่อธิบายส่วนของการทำงานนะครับ)
ส่วนการเรียกไปใช้ในฟังชันก์หลัก(main) ทำได้โดยการ #include Animation.h แล้วกำหนด Animation animation; แล้วเรียกใช้ฟังชันก์ต่างๆใน Class ได้เลย อย่างเช่น animation.update();
สุดท้ายนี้ผมคิดว่า Class เนี่ยมันมีประโยชน์มากเลยนะครับสำหรับการเขียนโปรแกรมเพราะทำให้โปรแกรมที่เราเขียนขึ้นมาดูแล้วเข้าใจได้ง่ายเป็นระเบียบ + การทำงานหลักของโปรแกรมเราไม่ดูหลายบรรทัดเกินไปและไม่เป็นระเบียบ ซึ่งเมื่อเราเขียน Class เป็นจะทำให้พิสูจน์ว่า Skill การเขียนเราเพิ่มขึ้น (อันนี้เอามาจาก Comment ของฝรั่งที่ผมอ่านเจอเลยครับ 555)
ฝากไว้กับการทำงานของ Animation

หากต้องการศึกษาเพิ่มเติมเกี่ยวกับ Parameter ของ Class ที่ผมไม่ได้พูดถึงได้ที่
ซึ่งเป็นบทความที่เขียนดีมากๆอันนึงแล้วก็เป็นภาษาไทยด้วยและขอขอบคุณ MarcusCode ไว้ที่นี้
แล้วก็หากต้องการศึกษาต่อเกี่ยวกับการสือทอดของ Class ได้ที่
เป็นของเพื่อนผมเองซึ่งอธิบายได้ไว้ดีมากๆ
ขอบคุณที่อ่านจนจบขอบคุณมากครับ
นายนิติพัฒน์ บุญเกตุ 62010494