Trò chơi Flappy Bird, mặc dù có lối chơi đơn giản nhưng lại đòi hỏi người lậptrình phải hiểu rõ về nhiều khía cạnh khác nhau của lập trình game như quản lý sựkiện, xử lý đồ họa và quản l
Trang 1TRƯỜNG ĐẠI HỌC GIAO THÔNG VẬN TẢI
Khoa Đào Tạo Quốc Tế Công Nghệ Thông Tin Việt – Anh
Báo Cáo Thực hành Công Nghệ Java:
Game Flappy BirdGiảng viên:
Sinh viên thực hiện:
Nhóm: 9
Họ và tên Mã Sinh viên
Vũ Nhật Minh
Lê Quang Long
Nguyễn Hữu Minh 222601123
Trang 2LỜI NÓI ĐẦU
Trong thời đại công nghệ thông tin phát triển mạnh mẽ, lập trình trở thành một kỹnăng không thể thiếu đối với các kỹ sư và nhà phát triển phần mềm Việc hiểu và
áp dụng các khái niệm lập trình không chỉ giúp chúng ta giải quyết các bài toán kỹthuật mà còn mở ra những khả năng sáng tạo vô hạn Môn lập trình Java cung cấpcho chúng ta những công cụ và kiến thức cơ bản để xây dựng các ứng dụng từ đơn
giản đến phức tạp
Trò chơi Flappy Bird, mặc dù có lối chơi đơn giản nhưng lại đòi hỏi người lậptrình phải hiểu rõ về nhiều khía cạnh khác nhau của lập trình game như quản lý sựkiện, xử lý đồ họa và quản lý vật lý Trong khuôn khổ bài báo cáo này, chúng tôi sẽtrình bày quá trình phát triển trò chơi Flappy Bird bằng ngôn ngữ lập trình Java, từ
khâu thiết kế đến triển khai và thử nghiệm
Bài báo cáo được chia thành các phần cụ thể nhằm giới thiệu một cách có hệ thống
và chi tiết về các bước thực hiện dự án Chúng tôi sẽ đi sâu vào các vấn đề như lựachọn môi trường phát triển, thiết kế giao diện người dùng, xây dựng các đối tượng
trong game và cách xử lý các sự kiện trong trò chơi
Qua bài báo cáo này, chúng tôi hy vọng không chỉ thể hiện được những kiến thức
và kỹ năng đã học được mà còn khơi gợi niềm đam mê lập trình trong mỗi người.Chúng tôi tin rằng với sự nỗ lực và tinh thần học hỏi không ngừng, chúng ta có thể
tạo ra những sản phẩm phần mềm chất lượng và ý nghĩa
Xin chân thành cảm ơn thầy cô và các bạn đã đồng hành và hỗ trợ chúng tôi trongquá trình thực hiện dự án này Những góp ý và động viên của quý thầy cô và cácbạn là nguồn động lực to lớn giúp chúng tôi hoàn thành bài báo cáo này một cách
tốt nhất
Chúng tôi trân trọng giới thiệu bài báo cáo về quá trình phát triển trò chơi FlappyBird bằng Java và hy vọng nhận được những phản hồi quý báu từ quý thầy cô và
các bạn
Trang 3Mục lục
I.Giới thiệu……….3
1.1.Tóm tắt đề bài………3
1.2.Luật chơi………3
II.Thiết kế trò chơi……….3
2.1.Các file sử dụng cho trò chơi……….3
2.2.Thiết kế cửa sổ trò chơi……… 4
2.3.Thiết kế các đối tượng giao diện………6
2.4.Thiết kế các chức năng điều khiển cho trò chơi……… 12
III.Demo chương trình………22
3.1.Giao diện……… 22
3.2.Trong game……… 23
3.3.Kết thúc game……… 24
3.4.Bảng điểm………25
IV.Tổng kết……… 26
4.1.Ưu điểm……… 26
4.2.Nhược điểm……….26
Bảng nhiệm vụ……….27
Tài liệu tham khảo……… 27
Trang 4I.Giới thiệu:
1.1.Tóm tắt đề tài:
Trò chơi Flappy Bird là một trò chơi điện tử phổ biến với giao diện đơn giản nhưng lại mang tính thách thức cao Trong trò chơi này người chơi sẽ điều khiển một con chim bay qua các cặp cột nước cao Mỗi lần vượt qua thành công một cặp cột, người chơi sẽ được cộng thêm điểm
1.2.Luật chơi:
- Người chơi điều khiển chú chim để tránh các ống
- Mỗi lần chú chim bay qua một cặp ống, người chơi sẽ được cộng một điểm
- Trò chơi kết thúc khi chú chim va chạm với ống hoặc chạm đất
II.Thiết kế trò chơi:
2.1.Các file sử dụng cho trò chơi:
2.1.1.File hình ảnh dử dụng cho trò chơi:
2.1.2.File nhạc và hiệu ứng âm thanh cho trò chơi:
Trang 52.2.Thiết kế cửa sổ của trò chơi:
Trong bất kỳ ứng dụng trò chơi nào, một giao diện người dùng thân thiện và trực quan là yếu tố quan trọng giúp nâng cao trải nghiệm của người chơi Việc tạo ra một cửa sổ để hiển thị trò chơi là bước đầu tiên và là bước quan trọng nhất trong việc phát triển trò chơi.Trong Java, việc tạo và quản lý cửa sổ ứng dụng thường được thực hiện thông qua các lớp của thư viện Swing, với Jframe là nền tảng cơ bản
Jframe là một khung cửa sổ tiêu chuẩn trong Java Swing, cung cấp các phương thức và thuộc tính để chúng ta có thể thiết lập kích thước, vị trí, tiêu đề và hành vi của cửa sổ Sử dụng Jframe, chúng ta có thể dễ dàng tạo ra một cửa sổ cho trò chơi Flappy Bird, nơi mà các thành phần giao diện như chú chim, ống cống và điểm số sẽ được hiển thị
Code:
package view;
import javax.swing.JFrame;
import Controller.FlappyBirdController;
public class FlappyBird{
public void execute() {
int boardWidth = 500; // Chiều rộng của cửa sổ trò chơi = 360 pixel
int boardHeight = 700; // Chiều dài của cửa sổ trò chơi = 640 pixel
JFrame frame = new JFrame("Flappy Bird"); // Tạo khung cửa sổ cho trò chơi
frame.setSize(boardWidth, boardHeight); // Thiết lập kích thước cửa sổ
frame.setLocationRelativeTo(null); // Để vị trí cửa sổ ra giữa màn hình
frame.setResizable(false); // ngăn người dùng tự điều chỉnh kích thước cửa sổ
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Khi người dùng bấm
vào nút X cửa sổ sẽ đóng lại
FlappyBirdController flappyBirdController = new FlappyBirdController(); // Khởi tạo đối tượng
Trang 6
frame.add(flappyBirdController); // Thêm cách thành phần của đối tượng vào chương trình
Trang 72.3.Thiết kế các đối tượng giao diện:
Trong một trò chơi, các đối tượng giao diện đóng vai trò then chốt trong việc tạo ra trải nghiệm người chơi hấp dẫn và tương tác Trong trò chơi Flappy Bird, các đối tượng chínhbao gồm chú chim (Bird) và các ống (Pipe), cụ thể là ống trên (TopPipe) và ống dưới (BottomPipe)
-Đối tượng Bird được xác định qua lớp Bird() dùng để điều chỉnh kích thước cùng vị trí ban đầu của đối tượng Bird và tạo hình ảnh cho đối tượng Bird
*Các thuộc tính:
private int x = 500/8;
private double y = 700/2;
private int width = 34;
private int height = 24;
private Image img;
Trang 8public Bird(Image img) {
Trang 9public void setWidth(int width) {
Trang 10private int height = 512;
private boolean passed = false;
private Image img;
Trang 11*Các phương thức Getter và Setter:
public int getX() {
Trang 12public int getHeight() {
Trang 132.4.Thiết kế các chức năng điều khiển cho trò chơi:
Bird bird;
ArrayList<Pipe> pipes;
Sound sound = new Sound();
Bird bird : Đối tượng chim trong trò chơi
ArrayList<Pipe>pipes: Lưu trữ một danh sách các đường ống trong game
Sound sound = new Sound() : Phát âm thanh trong trò chơi
int boardWidth = 500; // Tạo biến chiều rộng cửa sổ
int boardHeight = 700; // Tạo biến chiều dài cửa sổ
*Dùng để điều khiển kích thước cửa sổ của trò chơi
ArrayList<Double> allScores = new ArrayList<>();
static final String SCORE_FILE_PATH = "C:\\Users\\Admin\\eclipworkspace\\Flappi4\\src\\highestscore.txt";
double highestScore;
*Dùng để lưu số điểm người chơi đạt được
Image backgroundImg = new
ImageIcon(getClass().getResource(" /Source/image/flappybirdbg.png")).getImage(); Image birdImg= new
ImageIcon(getClass().getResource(" /Source/image/flappylo.png")).getImage(); Image topPipeImg = new
ImageIcon(getClass().getResource(" /Source/image/toppipe.png")).getImage(); Image bottomPipeImg = new
ImageIcon(getClass().getResource(" /Source/image/bottompipe.png")).getImage(); Image titleScreenImg = new
ImageIcon(getClass().getResource(" /Source/image/flappybirdts2.png")).getImage();
*Dùng để thiết lập các biến chứa hinhf ảnh của các đối tượng giao diện trong trò chơi.// Game State
int gameState;
final int titleState = 0;
final int playState = 1;
int commandNum = 0;
double velocityX = -5; //- tốc độ ống di chuyển sang bên trái trong khi con chim đứng
yên (Vận tốc càng bé ống di chuyển càng nhanh)
double velocityY = 0;
Trang 14double gravity = 0.3; // Thiết lập trọng lực, mỗi 1 khung hình con chim sẽ chậm hoặc
hướng xuống dưới 1px
Random random = new Random(); // Dùng để tạo các ống có chiều cao ngẫu nhiênTimer gameLoop; // Dùng để gọi hàm vẽ các hình ảnh lặp lại nhiều lần
Timer placePipeTimer; // Bộ đếm thời gian vẽ các ống trong thời gian nhất định
boolean gameOver = false;
boolean gamePause = false;
double score = 0; // Thiết lập điểm bằng 0
public FlappyBirdController() {
setPreferredSize(new Dimension(boardWidth, boardHeight)); // Thiết lập kích thước các
thành phần con vừa đủ để bao bọc nội dung bên trong thành phần đó
setFocusable(true); // Dùng để đảm bảo những sự kiện quan trọng diễn ra khi bấm
addKeyListener(this);
*Dùng để theo dõi và điểu khiển trạng thái của trò chơi
// Khởi tạo danh sách điểm
allScores = new ArrayList<>();
// Đọc điểm cao nhất từ tệp văn bản
highestScore = readHighestScore();
*Dùng để quản lý danh sách điểm
bird = new Bird(birdImg);
pipes = new ArrayList<Pipe>();
*Khởi tạo đối tượng Bird và Pipe
Trang 15placePipeTimer = new Timer(1300, new ActionListener() {
placePipeTimer.start(); // Các ống bắt đầu chạy mỗi 1.5s
*Dùng để điều chỉnh độ khó của trò chơi, thời gian càng ít ống càng gần nhau
*placePipeTimer sẽ gọi hàm vẽ các đường ống sau mỗi 1.5s
gameLoop = new Timer(1000 / 70, this); // Hàm vẽ sẽ được gọi liên tục 60 lần trong 1s giúp con chim chạy mượt mà
gameLoop.start(); // Dùng để bắt đầu bộ đếm thời gian
*Bộ đếm thời gian
public void placePipes() {
Pipe pipe = new Pipe();
// (0-1) * pipeHeight/2 => Math.random() pipeHeight/2 = (0-256)
// (pipeHeight/4) = 128
// 1 -> -128 - 256 (pipeHeight/4 - pipeHeight/2) = -3/4 pipeHeight
// randomPipeY = 0 - 128 - (0 -> 256)
// Ống sẽ dịch chuyển lên trong khoảng từ 1/4 - 3/4 chiều dài ống
int randomPipeY = (int) (pipe.getY() - pipe.getHeight() / 4 - Math.random() * pipe.getHeight() / 2);
int openingSpace = boardHeight / 4;
Pipe topPipe = new Pipe(topPipeImg); // Tạo ra ống bên trên
topPipe.setY(randomPipeY); // Tạo ra chiều dài random cho ống bên trên
pipes.add(topPipe); // Lưu ống vào danh sách
Pipe bottomPipe = new Pipe(bottomPipeImg);
bottomPipe.setY(topPipe.getY() + pipe.getHeight() + openingSpace);
pipes.add(bottomPipe);
}
*Dùng để tạo ra các đường ống và lưu chúng vào ArrayList
Trang 16public void paintComponent(Graphics g) {
super.paintComponent(g); // Truy xuất tới lớp cha
g.setFont(new Font("Arial", Font.PLAIN, 16));
g.drawString("Highest Score: " + String.valueOf((int) highestScore),
boardWidth - 150, 20);
}
}
*Dùng để vẽ hình ảnh lên trên nền chương trình
public void draw(Graphics g) {
for int ( i = 0; i < pipes.size(); i++) {
Pipe pipe = pipes.get(i);
g.drawImage(pipe.getImg(), pipe.getX(), pipe.getY(), pipe.getWidth(),
pipe.getHeight(), null);
}
// score
g.setColor(Color.blue); // Thiết lập màu chữ
g.setFont(new Font("Arial", Font.PLAIN, 32)); // THiết lập phông chữ
if (gameOver) {
g.drawString("Game Over: " + String.valueOf((int) score), 150, 330);
// 10: dịch chuyển dòng chữ sang phải // 10px, 35: dịch chuyển dòng chữ
// xuống dưới 35px
Trang 17public void drawTitleScreen(Graphics g) {
g.drawImage(titleScreenImg, 0, 0, this.boardWidth, this.boardHeight,
Trang 18public void playMusic(int i) {
*Dùng để điều khiển âm thanh trong trò chơi
public void move() {
for int ( i = 0; i < pipes.size(); i++) {
Pipe pipe = pipes.get(i);
Trang 19pipes.removeIf(pipe -> pipe.getX() + pipe.getWidth() < 0);
(bird.getY() > boardHeight) { if
gameOver = true;
}
}
*Dùng để xóa bỏ các ống đã di chuyển ra khỏi màn hình
boolean collision(Bird a, Pipe b) {
return a.getX() < b.getX() + b.getWidth() && // a's top left corner doesn't reach b's top
right corner
a.getX() + a.getWidth() > b.getX() && // a's top right corner passes b's top left cornera.getY() < b.getY() + b.getHeight() && // a's top left corner doesn't reach b's bottom left corner
a.getY() + a.getHeight() > b.getY(); // a's bottom left corner passes b's top left corner}
Trang 20if (commandNum < 0) {
commandNum = 1;
}repaint();
}
if (e.getKeyCode() == KeyEvent.VK_S) {commandNum++;
if (commandNum > 1) {
commandNum = 0;
}repaint();
}
Trang 21(gameState == playState) {if
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
// Mỗi khi bấm SPACE cật nhật vị trí Y và con chim hướng lên trên 9px
pipes.clear();
gameOver = false;score = 0;
gameLoop.start();
placePipeTimer.start();
} }
Trang 22public void saveAllScores(ArrayList<Double> scores) {
System.out.println("All scores saved successfully.");
// Update highest score on game panel
while ((line = reader.readLine()) != null) {
double score = Double.parseDouble(line);
Trang 23public class Main {
public static void main(String[] args) { FlappyBird fb = new FlappyBird(); fb.execute();
}
*Hàm main để khởi chạy trò chơi
III.Demo chương trình:
3.1.Giao diện:
Trang 243.2.Trong game:
Trang 253.3.Kết thúc game:
Trang 263.4.Bảng điểm:
Trang 27IV.Tổng kết
4.1.Ưu điểm:
- Đơn giản và dễ chơi: Trò chơi Flappy Bird được lập trình bằng Java có giao diện đơn giản, dễ nhìn và cách chơi dễ hiểu Người chơi chỉ cần điều khiển con chim bay qua các cặp cột nước mà không va chạm
- Tính thách thức cao: Mặc dù cách chơi đơn giản nhưng trò chơi lại mang tính thách thức cao, tạo sự hấp dẫn cho người chơi
- Tùy chỉnh linh hoạt: Trò chơi cho phép người chơi tùy chỉnh các thiết lập như âm thanh,
độ khó, Giúp người chơi có thể tận hưởng trò chơi theo cách của mình
Trang 28Bảng nhiệm vụ:
ST
T Họ và tên Mã Sinh Viên Nhiệm vụ
1 Vũ Nhật Minh 222631127 Phát triển game
2 Lê Quang Long Chuyển đổi sang mô hình mvc
3 Nguyễn Hữu Minh 222601123 Viết báo cáo
Tài liệu tham khảo:
Youtube:https://www.youtube.com/watch?v=Xw2MEG-FBsE
Chat GPT
Trang 2927