---
# System prepended metadata

title: ĐỌC HIỂU CODE MÔN MÃ NGUỒN MỞ - NGUYỄN MINH DƯƠNG_725105048

---

# ĐỌC HIỂU CODE MÔN MÃ NGUỒN MỞ - NGUYỄN MINH DƯƠNG_725105048

 

# Đoạn code chính thực thi trờ chơi
# 1. **Lớp `Component` - Thành phần cơ bản của trò chơi**
Lớp này định nghĩa các thuộc tính chung của một đối tượng trong trò chơi như kích thước, màu sắc, vị trí và phương thức cập nhật (vẽ lên canvas).



## **Thuộc tính**
- `x, y`: Tọa độ của đối tượng trên canvas.
- `width, height`: Kích thước của đối tượng.
- `color`: Màu sắc của đối tượng (áp dụng nếu không phải ảnh).
- `gameArea`: Đối tượng chứa thông tin khu vực chơi.
- `gameContext`: Lấy đối tượng `context` từ `canvas`, cho phép vẽ lên nó.
- `speedX, speedY`: Tốc độ di chuyển của đối tượng.
- `gravity, gravitySpeed`: Ảnh hưởng của trọng lực lên đối tượng.

## **Phương thức**
### `1.Hàm update()`: 
- Vẽ hình chữ nhật lên `canvas` dựa vào tọa độ, màu sắc, kích thước.
    - ![Uploading file..._8bqk2lbiv]()
    - Đây là phương thức `update()` trong lớp `Component`. Nó có nhiệm vụ vẽ một hình chữ nhật đại diện cho đối tượng trên `canvas`.  
---
##### **Phân tích từng dòng**
```javascript
this.gameContext.fillStyle = this.color;
```
- Đặt màu nền (`fillStyle`) cho hình chữ nhật bằng giá trị `this.color`.
- `this.color` được truyền vào khi tạo đối tượng, ví dụ: `"red"`, `"#2CB01A"`

---

```javascript
this.gameContext.fillRect(this.x, this.y, this.width, this.height);
```
- Vẽ một hình chữ nhật màu `this.color` lên `canvas` với:
  - `this.x`, `this.y`: Tọa độ góc trên bên trái.
  - `this.width`, `this.height`: Kích thước của hình chữ nhật.
- Đây là phần nền của đối tượng.

---

```javascript
this.gameContext.strokeStyle = 'black';
```
- Thiết lập màu viền (`strokeStyle`) của hình chữ nhật thành **màu đen**.

---

```javascript
this.gameContext.lineWidth  = 10;
```
- Đặt độ dày của viền là **10px**.

---

```javascript
this.gameContext.strokeRect(this.x, this.y, this.width, this.height);
```
- Vẽ viền màu đen quanh hình chữ nhật với độ dày 10px.

---

##### **Tóm tắt hoạt động của `update()`**
1. Vẽ một hình chữ nhật màu (`fillRect`).
2. Vẽ một viền đen xung quanh hình chữ nhật (`strokeRect`).
3. Hình chữ nhật này sẽ đại diện cho các đối tượng như chướng ngại vật.

---

##### **Tại sao cần `strokeRect`?**
- Nếu chỉ có `fillRect()`, hình sẽ không có viền, trông kém nổi bật.
- `strokeRect()` giúp dễ nhìn thấy đối tượng hơn, đặc biệt khi nền có màu tương tự đối tượng.

📝 **Tóm lại**: Phương thức này giúp hiển thị một đối tượng hình chữ nhật có màu nền và viền đen trên `canvas`. 🚀

**--------------------------------------------------------------------------------------------------------------------------------------------------------**
.....................................................................
### `2.Hàm crashWith(otherObj)`: 
- Kiểm tra xem đối tượng hiện tại có va chạm với `otherObj` không bằng cách so sánh tọa độ biên của hai đối tượng.
- Đây là **hàm khởi tạo (`constructor`)** của lớp `Component`. Nó chịu trách nhiệm thiết lập các thuộc tính ban đầu cho một đối tượng game.  
---

#### Phân tích từng dòng
##### 2.1 Nhận tham số đầu vào
```javascript
constructor({ gameArea, width, height, color, x, y }) {
```
- Hàm khởi tạo nhận một **đối tượng** chứa các thuộc tính:
  - `gameArea`: Khu vực trò chơi (`GameArea`).
  - `width`, `height`: Kích thước đối tượng.
  - `color`: Màu sắc.
  - `x`, `y`: Tọa độ ban đầu trên canvas.

 **Lưu ý**: Cú pháp `{ gameArea, width, height, ... }` là **destructuring** để trích xuất các giá trị từ một object.

---

##### 2.2 Gán các giá trị đầu vào cho thuộc tính của đối tượng
```javascript
this.x = x;
this.y = y;
this.width = width;
this.color = color;
this.height = height;
```
- Gán các tham số đầu vào cho đối tượng `this` (đối tượng đang được tạo ra).
- `this.x`, `this.y`: Xác định vị trí trên canvas.
- `this.width`, `this.height`: Xác định kích thước đối tượng.
- `this.color`: Xác định màu sắc của đối tượng.
---

##### 2.3 Lưu tham chiếu đến `GameArea`
```javascript
this.gameArea = gameArea;
this.gameContext = gameArea.canvas.getContext('2d');
```
- `this.gameArea = gameArea;`: Lưu tham chiếu đến `GameArea` để sử dụng sau này.
- `this.gameContext = gameArea.canvas.getContext('2d');`:  
  - Lấy **context 2D** của `canvas`, cho phép vẽ lên canvas.
  - Được sử dụng trong `update()` để vẽ hình.
---

##### 2.4 Khởi tạo các thuộc tính liên quan đến chuyển động
```javascript
this.score = 0;
this.speedX = 0;
this.speedY = 0;
this.gravity = 0;
this.gravitySpeed = 0;
```
 - `this.score = 0;`: Điểm số ban đầu là `0`.
 - `this.speedX = 0;`: Tốc độ di chuyển theo trục `X`.
 - `this.speedY = 0;`: Tốc độ di chuyển theo trục `Y`.
 - `this.gravity = 0;`: Trọng lực mặc định là `0`, sau này có thể thay đổi.
 - `this.gravitySpeed = 0;`: Tốc độ rơi do trọng lực, khởi tạo bằng `0`.

-> **Giải thích về trọng lực (`gravity`)**
- Nếu `gravity > 0`: Đối tượng rơi xuống dần theo thời gian.
- Nếu `gravity < 0`: Đối tượng bay lên (như khi nhấn phím **Space**).
- `gravitySpeed` sẽ tăng dần, tạo hiệu ứng rơi tự nhiên.

-> **Ví dụ sử dụng gravity trong game:**
```javascript
this.gravity = 0.05; // Trọng lực nhỏ để rơi từ từ.
this.gravitySpeed += this.gravity;
this.y += this.gravitySpeed;
```
-> Mỗi lần cập nhật, `gravitySpeed` tăng lên, khiến nhân vật rơi xuống nhanh hơn.

---

#####  Tóm tắt
- Hàm `constructor` **khởi tạo** một đối tượng với:
  - **Kích thước**, **màu sắc**, **vị trí** trên `canvas`.
  - **Tham chiếu đến `GameArea`** để vẽ lên canvas.
  - **Tốc độ di chuyển** (`speedX`, `speedY`) và **trọng lực** (`gravity`, `gravitySpeed`).

🚀 **Tóm lại**: Đây là bước đầu tạo ra một **thực thể (entity) di chuyển được** trong trò chơi! 🎮

---

































# 2. **Lớp `MyGamePiece` - Đối tượng điều khiển chính (chim)**
Lớp này kế thừa từ `Component` nhưng thay đổi cách hiển thị từ hình chữ nhật sang hình ảnh con chim.

### **Phương thức**
- `constructor(obj)`: Thay vì vẽ một hình chữ nhật, nó tải hình ảnh (`/static/img/convit.png`) vào `this.img`.
- `update()`: Dùng `drawImage` để vẽ hình ảnh thay vì hình chữ nhật.
- `newPos()`: Cập nhật vị trí mới của chim dựa vào trọng lực và tốc độ.
- `checkHitTop()` và `checkHitBottom()`: Kiểm tra xem chim có vượt quá viền trên hoặc viền dưới màn hình không.

---

# 3. **Lớp `TextComponent` - Hiển thị văn bản (điểm số)**
Lớp này kế thừa `Component` nhưng thay vì vẽ hình chữ nhật, nó hiển thị văn bản lên màn hình.

- `update(text)`: Dùng `fillText` để hiển thị điểm số.

---

# 4. **Lớp `GameArea` - Quản lý toàn bộ trò chơi**
Lớp này điều khiển các thành phần trong game, cập nhật màn hình và xử lý logic trò chơi.

### **Thuộc tính**
- `gameRunning`: Trạng thái trò chơi (đang chạy hay dừng).
- `canvas`: Phần tử HTML `canvas` để vẽ trò chơi.
- `context`: Đối tượng để vẽ lên `canvas`.
- `frameNo`: Đếm số frame đã chạy (dùng để tạo chướng ngại vật).
- `myPiece`: Đối tượng chim mà người chơi điều khiển.
- `myScore`: Đối tượng hiển thị điểm số.
- `myObstacles`: Mảng chứa các chướng ngại vật.

### **Phương thức**
#### `start()`
- Kiểm tra nếu trò chơi đã chạy thì không làm gì.
- Ẩn phần giới thiệu (`bird-running`), tắt nhạc intro.
- Chạy nhạc nền (`maplestory_playing.mp3`).
- Ẩn nút `START GAME`, thêm `canvas` vào trang.
- Chạy hàm `updateGameArea()` liên tục mỗi 10ms.

#### `checkCrash()`
- Duyệt qua mảng `myObstacles` để kiểm tra xem chim có va chạm với bất kỳ chướng ngại vật nào không.

#### `updateGameArea()`
- Xóa màn hình (`clearRect`).
- Nếu đủ số frame, tạo một chướng ngại vật mới.
- Cập nhật vị trí của tất cả chướng ngại vật và vẽ lại.
- Cập nhật điểm số.
- Cập nhật vị trí và vẽ lại chim.
- Nếu chim va vào chướng ngại vật, gọi `loseGame()`.

#### `loseGame()`
- Dừng nhạc nền, xóa canvas, ẩn hướng dẫn.
- Hiển thị điểm số của người chơi.
- Gửi điểm lên backend bằng hàm `submitPoint(score)`.

---

# 5. **Xử lý phím (`onkeyup`, `onkeydown`)**
- Khi **bấm phím cách (SPACE)**: Chim bay lên (`gravity = -0.2`).
- Khi **nhả phím cách**: Chim rơi xuống (`gravity = 0.05`).

---

# 6. **Giao diện HTML**
- **Nút "START GAME"**: Gọi `myGameArea.start()`.
- **Hướng dẫn chơi**: Hiển thị cách điều khiển.
- **Phần hiển thị điểm khi thua**: `text-losegame`.

---

### **Tóm tắt chức năng chính**
- **Nhấn SPACE** để chim bay lên.
- **Tự động rơi xuống** khi không nhấn.
- **Tránh chướng ngại vật** để đạt điểm cao.
- Khi **va chạm**, hiển thị điểm và dừng trò chơi.

