Cách Làm Game Flappy Bird

Giới thiệu một tí

Ngày nay, nghành nghề điện tử sẽ dần được không ít người quan tiền tâm, phiên bản thân bản thân cũng bước đầu cố gắng tò mò mảng này từ hơi lâu (hơn 10 năm trước) nhưng mà tiếc là dốt Toán/Lý, cũng không hẳn dân học tập Điện tử phải sau sát 10 năm mới tết đến có làm được không nhiều thứ nhằm khoe với chúng ta bè.

Bạn đang xem: Cách làm game flappy bird

Một trong số những vị phúc tinh của dân yêu thích điện tử nhưng lại ngoại đạo như mình đó là Arduino, đó là một board mạch xây dựng được (vì tích hòa hợp cả mạch nạp, mạch nguồn, output, input,...), bạn chỉ việc tập trung vào sử dụng những chân input, output đầu ra của Arduino nhằm "sáng tác", chỉ việc một chút kiến thức và kỹ năng điện tử cơ bạn dạng để không có tác dụng nó chập mạch, cháy nhà.

Với dân gõ code thì chỉ như thế này là đủ, y như tôn chỉ của RoR, bạn cứ thoả sức sáng sủa tạo, mấy chuyện khác nhằm Arduino lo.

Nếu chưa xuất hiện kiến thức về Arduino, các bạn cũng có thể tham khảo bài viết của bác bỏ
viethnguyen (http://kipalog.com/posts/JsG_PhVlQM-anwGna4ZT0g)

Còn hiện nay chúng ta sẽ bước đầu làm vật chơi.

Làm trò chơi Flappy Bird

Đây là video clip demo cho loại game Flappy Bird chúng ta sẽ làm:

*
Video: https://www.youtube.com/watch?v=04cY78Y2d3g

Game này mình áp dụng data hình hình ảnh của một tutorial giống như từ http://arduino.vn, mặc dù vì code xúc tích của trang này nặng nề hiểu quá đề nghị mình chọn cách tự viết từ đầu.

Chuẩn bị

Về phần cứng, chúng ta cần có:

1x màn hình hiển thị Nokia 5110 LCD (giá trung bình 40k/cái)1x nút bấm (Push button, các loại này sở hữu 5k nguyên 1 bao)7x tua dây Jumper Wire (cái này mua 1 bó về dùng dần)1x Board Arduino. Ở phía trên mình cần sử dụng UNO R3, mấy con khác cũng ko khác gì, khác mỗi biện pháp nối dây :v

Tổng thiệt hại không tới 50k, không tính bé Arduino :D

Nối dây phương diện trước

Đây là phần thú vui nhất khi thao tác với Arduino, chắc vì mình chưa hẳn dân siêng điện tử cần cái khâu này khá là vất vả, nhằm tránh làm chúng ta vất vả theo mình thì mình ghi lại cách nối luôn, đỡ phải khám phá datasheet này nọ.

Push Button: Nối vào pin 2 cùng GND của ArduinoMàn hình: Nối lần lượt các chân tương ứng từ màn hình vào Arduino

CLK --> sạc 7DIN --> pin 6D/C --> sạc pin 5CS --> sạc 4

Nguồn năng lượng điện thì sinh sống đây bọn họ sử dụng nguồn từ máy tính xách tay cấp cho Arduino, nếu như muốn đem ra ngoài chơi thì bạn có thể mua 1 viên sạc pin 9V với nối 2 cực của pin sạc vào Vin cùng GND của Arduino.

Nối code mặt sau

Đầu tiên, bọn họ cần define ra những dữ liệu đề nghị dùng, ở đó là các mảng giá bán trị cất hình ảnh (bitmap) cho nhỏ chim, và mấy mẫu ống nước. Trong khi mình define thêm 2 phát triển thành ANIM_FRAME để lý lẽ tốc độ biến hóa hình (để tạo nên hiệu ứng đưa động) của con chim và DELAY_FRAME nhằm điều chỉnh vận tốc xung nhịp xử lý cho khớp ứng với vận tốc của Arduino UNO R3.

Sprite.h

#define ANIM_FRAME 50#define DELAY_FRAME 5static unsigned char PROGMEM flappybird_frame_1<> = 0x03, 0xF0, 0x0C, 0x48, 0x10, 0x84, 0x78, 0x8A, 0x84, 0x8A, 0x82, 0x42, 0x82, 0x3E, 0x44, 0x41,0x38, 0xBE, 0x20, 0x41, 0x18, 0x3E, 0x07, 0xC0 ;static unsigned char PROGMEM flappybird_frame_2<> = 0x03, 0xF0, 0x0C, 0x48, 0x10, 0x84, 0x20, 0x8A, 0x40, 0x8A, 0x40, 0x42, 0x7C, 0x3E, 0x82, 0x41, 0x84, 0xBE, 0x88, 0x41, 0x78, 0x3E, 0x07, 0xC0 ;static unsigned char PROGMEM bar_bottom<> = 0xFF, 0xFF, 0xFF, 0x42, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E ;static unsigned char PROGMEM bar_top<> = 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x42, 0xFF, 0xFF, 0xFF ;Các mảng tài liệu flappybird_frame_* và bar_bottom, bar_top là mảng được convert từ các tool bitmap converter (tool này chỉ chạy trên Windows nên mình copy luôn luôn từ http://arduino.vn :v)

Tiếp đến họ sẽ viết 2 class để giải pháp xử lý 2 thành phần chính trong game, kia là bé chim (Chym.h) và ống nước (Bar.h).

Tương tự như khi lập trình trò chơi trên các thiết bị khác, họ cần một vòng lặp chính (main loop) để giải pháp xử lý tuần từ và liên tục các thao tác: cách xử trí game ngắn gọn xúc tích > Xoá screen > Vẽ lại phần đông thứ lên màn hình

Chính chính vì như thế nên trong 2 class Chym.h cùng Bar.h, chúng ta sẽ tất cả cùng kết cấu dạng:

class Foo void update(); // Hàm xử trí update ngắn gọn xúc tích void render(); // Hàm vẽ đối tượng người dùng lên màn hình hiển thị // những xử lý khácBây giờ họ sẽ hợp tác vào viết code cho đối tượng người sử dụng con Chym

Chym.h

class Chym {private: int frameCount; int x; int y; int deltaIde; int delayFrame; int jumpCount; int maxJumpCount; int moveSpeed; bool _isDead;public: void respawn() x = 24; y = 20; deltaIde = -1; moveSpeed = 1; jumpCount = 0; _isDead = false; Chym() frameCount = 0; delayFrame = 0; maxJumpCount = 20; respawn(); void render() if (frameCount 35) _isDead = true; frameCount++; if (frameCount >= ANIM_FRAME) frameCount = 0; bool isDead() return _isDead; void die() _isDead = true; void cancelJump() jumpCount = 0; flyDown(); void flyUp() { if (jumpCount Giải thích:

Hàm respawn có nhiệm vụ reset lại toạ độ, trạng thái của Chim khi bắt đầu game (hoặc sau thời điểm chết)Hàm render có nhiệm vụ vẽ theo lần lượt 2 hình ảnh tượng trưng mang đến 2 tinh thần của Chim lúc đang bay theo thời gianHàm update có nhiệm vụ điều khiển và tinh chỉnh toạ độ của Chim lên/xuống trải qua biến deltaIde, kiểm tra lúc nào thì con Chim nó chết,...Hàm isDead kiểm soát xem Chim nó chết chưaHàm die để báo cáo con Chim đang chếtHàm cancelJump có trọng trách xử lý kết thúc việc nhảy đầm của nhỏ Chim, và call hàm flyDown để kéo nhỏ Chim trở lại lạiHàm flyUp nhằm nâng toạ độ của Chim lên thông qua biến deltaIde, sản xuất hiệu ứng nhảyHàm flyDown dùng làm giảm toạ độ của Chim (giả lập môi trường thiên nhiên trọng lực đấy)Hàm getX cùng getY dùng để lấy toạ độ của Chim.

Xem thêm: Vai Trò Của Thế Giới Quan Duy Vật Biện Chứng Đối Với Học Viên Trường Chính Trị

Tiếp theo là code súc tích cho mấy dòng ống nước (Bar)

Bar.h:

class Bar {private: int x; int y; int delayFrame; int moveSpeed;public: Bar() delayFrame = 0; x = 0; y = 24; moveSpeed = 2; void setPos(int sx, int sy) x = sx; y = sy; void render() display.drawBitmap(x, y - 30, bar_top, 8, 20, 1); display.drawBitmap(x, y + 10, bar_bottom, 8, 20, 1); void update() delayFrame++; if (delayFrame == DELAY_FRAME) x -= moveSpeed; if (x = x - 16) && (tx = y + 10))?1:0; if (hitX != 0) return hitY; return 0; ;Giải thích:

Hàm setPos dùng để tùy chỉnh thiết lập vị trí của ống nướcHàm render dùng để làm vẽ 2 loại ống nước (trên với dưới) ra screen theo toạ độ lúc này của nóHàm update làm cho nhiệm vụ thay đổi toạ độ của ống nước, tạo cảm xúc là nhỏ chim đang cất cánh tới (nhưng thực chất là loại ống nước bay lui)Hàm hitTest làm trách nhiệm kiểm tra xem con chim và dòng ống nước tất cả va chạm tới nhau không

Phù... Bọn họ đã xây dựng dứt code xử lý xúc tích và ngắn gọn cho các đối tượng có vào game. Bây chừ là lúc ghép nối toàn bộ lại thành một game hoàn chỉnh.

Ở chương trình thiết yếu của Arduino, quăng vào đoạn code sau:

#include #include #include Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 3);#include "Sprite.h"#include "Chym.h"#include "Bar.h"Chym player;Bar bar; Bar bar2;int gameScore = 0;int KNOCK_PIN = 2;int LED_PIN = 8;boolean clicked = false;void loop()void resetGame() player.respawn(); bar.setPos(0, 20); bar2.setPos(50, 30); gameScore = 0;void setup() Serial.begin(9600); display.begin(); display.setContrast(50); display.clearDisplay(); display.display(); digitalWrite(LED_PIN, HIGH); pinMode(KNOCK_PIN, INPUT_PULLUP); pinMode(LED_PIN, OUTPUT); resetGame(); while(1) getInput(); player.update(); bar.update(); bar2.update(); drawLCD(); void getInput() int knock = digitalRead(KNOCK_PIN); if (knock == 0) // push down clicked = true; else clicked = false; void drawLCD() display.clearDisplay(); if (!player.isDead()) int ht1 = bar.hitTest(player.getX(), player.getY()); int ht2 = bar2.hitTest(player.getX(), player.getY()); int die = ht1 + ht2; if (die == 1) // game over player.die(); if (clicked) player.flyUp(); else player.cancelJump(); player.render(); bar.render(); bar2.render(); else display.setCursor(0, 0); display.setTextSize(2); display.println("Game Over!!!"); if (clicked) resetGame(); display.display();Giải thích:

Dòng lệnh thứ nhất này làm nhiệm vụ khởi tạo thành driver tiếp xúc với màn hình hiển thị LCD mà chúng ta đã nối vào Arduino:Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 3);

Từ bây giờ, chúng ta cũng có thể giao tiếp với screen thông qua đối tượng người tiêu dùng display.

Hàm resetGame dùng để làm restart lại game sau khoản thời gian Chim chết.

Hàm cài đặt khởi tạo những thông số cần thiết cho màn hình. Trong hàm này còn có một vòng lặp vô hạn:while(1) ...

Đây là vòng lặp chính của game, các lệnh bên trong đó vẫn chạy tuần từ và liên tục. Trong tầm lặp này bọn họ xử lý câu hỏi đọc trạng thái dấn nút của Push Button trải qua hàm getInput và update xử lý logic cho player (con chim) và 2 cặp ống nước (bar với bar2), sau cùng gọi hàm drawLCD.

Hàm drawLCD này ngoài nhiệm vụ vẽ phần đa thứ lên màn hình thì còn xử lý việc kiểm tra xem Chim gồm đụng vào cặp ống nước như thế nào chưa, nếu va thì sẽ gọi lệnh player.die() để thông báo là Chim chết.

Hàm này còn kiểm tra thay đổi clicked để dìm biết bao giờ nút bấm được nhấn, nếu gồm thì sẽ điện thoại tư vấn lệnh player.flyUp() nhằm chim cất cánh lên.

Cuối thuộc gọi các hàm render() nhằm vẽ các đối tượng người sử dụng hiện bao gồm ra màn hình.

Nếu chim đã chết thì khối lệnh else sẽ được chạy nhằm in ra màn hình hiển thị dòng chữ "Game Over", đồng thời reset lại trò chơi khi người dùng bấm chuột Push Button.

Xong rồi đấy

Bây giờ, đông đảo thứ sẽ hoàn thành, chúng ta cũng có thể nhấn nút Run để build cùng nạp công tác vào Arduino, sau đó thưởng thức thành quả của mình.

Các chúng ta cũng có thể tham khảo mã mối cung cấp của trò chơi tại Github: https://github.com/huytd/arduino-flappybird