Java實現(xiàn)經(jīng)典游戲Flappy Bird的示例代碼
前言
《布谷鳥闖關(guān)-簡單版》是一個基于java的布谷鳥闖關(guān)游戲,摁上鍵控制鳥的位置穿過管道間的縫隙,需要做碰撞檢測,監(jiān)聽鍵盤事件,背景圖片的切換,障礙物管道產(chǎn)生時y軸上需要隨機位置。
主要設(shè)計
- 設(shè)計游戲界面,用swing實現(xiàn)
- 設(shè)計背景
- 設(shè)計移動墻
- 設(shè)計布谷鳥
- 設(shè)計障礙物
- 設(shè)計背景音樂和音效
- 由幾個關(guān)鍵的布爾類型變量start,crash,over是產(chǎn)生鍵鍵盤事件時用來控制界面顯示的彈框的
- 操作:空格鍵開始游戲,enter鍵取消"game over"彈框,摁空格鍵繼續(xù),上鍵(up)是對鳥的控制
- 工具類ImageMgr專用于讀取圖片
功能截圖
游戲開始:

控制布谷鳥

飛過障礙物

撞到障礙物,游戲結(jié)束

代碼實現(xiàn)
游戲啟動類
public class Main {
public static void main(String[] args) {
Cuckoo frame = new Cuckoo();
while (true){
try {
Thread.sleep(100);
if(!frame.crash){
frame.repaint();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}核心類
/**
* 1.窗口
* 2.背景
* 3.移動墻
* 4.布谷鳥
* 5.障礙物
* 6.背景音樂
* 7.音效
* 8.歡迎界面
* 9.game over
*/
public class Cuckoo extends Frame {
private int step;
private int score;
private int height;
private int moveLeft;
private int pipeMove;
boolean crash = false;
private boolean over = false;
private boolean start = false;
private static int bird_y = 270;
private static final int L_X = 800;
private static final int L_Y = 200;
private static final int SPEED = 2;
private static final int BIRD_X = 100;
private static final int GAME_X_Y_0 = 0;
private static final int GAME_WIDTH = 288;
private static final int GAME_HEIGHT = 512;
private static final int PIPE_WIDTH = ImageMgr.pipe.getWidth();
private static final int PIPE_HEIGHT = ImageMgr.pipe.getHeight();
private static final int READY_WIDTH = ImageMgr.ready.getWidth();
private static final int READY_HEIGHT = ImageMgr.ready.getHeight();
private static final int START_WIDTH = ImageMgr.start.getWidth();
private static final int BIRD_WIDTH = ImageMgr.bird[0].getWidth();
private static final int BIRD_HEIGHT = ImageMgr.bird[0].getWidth();
private static final int GROUND_HEIGHT = ImageMgr.ground.getHeight();
private static final int GAME_OVER_WIDTH = ImageMgr.gameOver.getWidth();
private static final int GAME_OVER_HEIGHT = ImageMgr.gameOver.getHeight();
private static final int BACKGROUND_HEIGHT = ImageMgr.background.getHeight();
private static Image offScreenImage;
private static Rectangle pipeRectangle1;
private static Rectangle pipeRectangle2;
private static Rectangle birdRectangle;
Cuckoo(){
setVisible(true);
setResizable(false);
//setTitle("cuckoo");
setBounds(L_X, L_Y,GAME_WIDTH,GAME_HEIGHT);
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()){
case KeyEvent.VK_SPACE : start = true;break;
case KeyEvent.VK_ENTER : reopen();break;
}
}
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_UP) {
bird_y -= 20;
}
}
});
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
@Override
public void update(Graphics g) {
if(offScreenImage == null){
offScreenImage = this.createImage(GAME_WIDTH,GAME_HEIGHT);
}
Graphics gOffScreen = offScreenImage.getGraphics();
Color c = gOffScreen.getColor();
gOffScreen.setColor(Color.BLACK);
gOffScreen.fillRect(0,0,GAME_WIDTH,GAME_HEIGHT);
gOffScreen.setColor(c);
paint(gOffScreen);
g.drawImage(offScreenImage,0,0,null);
}
@Override
public void paint(Graphics g) {
background(g);
ground(g);
start(g);
if(start){
bird(g);
pipe(g);
colliedWith();
gameOver(g);
score(g);
}
}
//如果碰撞后,可以嗯enter鍵重開
private void reopen(){
if(crash){
score = 0;
over = false;
crash = false;
start = false;
moveLeft = 0;
pipeMove = 0;
//bird_y = 270;//繼上次死的位置開始
}
}
private void score(Graphics g){
Font font = new Font("微軟雅黑",Font.BOLD,18);
g.setFont(font);
Color c = g.getColor();
g.setColor(Color.lightGray);
g.drawString("score " + score,20,70);
g.setColor(c);
}
private void background(Graphics g){
g.drawImage(ImageMgr.background,
GAME_X_Y_0 - moveLeft,GAME_X_Y_0,
GAME_WIDTH - moveLeft,GAME_HEIGHT,
GAME_X_Y_0,
GAME_X_Y_0,
GAME_WIDTH,
GAME_HEIGHT, null);
g.drawImage(ImageMgr.background,
GAME_WIDTH-1 - moveLeft,GAME_X_Y_0,
GAME_WIDTH*2 - moveLeft, GAME_HEIGHT,
GAME_X_Y_0,
GAME_X_Y_0,
GAME_WIDTH,
GAME_HEIGHT, null);
moveLeft += SPEED;
//游戲啟動計分
if(start && moveLeft % 100 == 0){
score += 1;
}
if(moveLeft >= GAME_WIDTH){
moveLeft = 0;
}
}
private void ground(Graphics g){
g.drawImage(ImageMgr.ground,0,BACKGROUND_HEIGHT - GROUND_HEIGHT,null);
}
private void bird(Graphics g){
Color c = g.getColor();
g.setColor(Color.BLUE);
g.drawRect(BIRD_X, bird_y,BIRD_WIDTH,BIRD_HEIGHT);
g.setColor(c);
g.drawImage(ImageMgr.bird[step++], BIRD_X, bird_y,null);
if(step >= ImageMgr.bird.length){
step = 0;
}
if(start){
bird_y += 4;
}
birdRectangle = new Rectangle(BIRD_X,bird_y,BIRD_WIDTH,BIRD_HEIGHT);
}
private void pipe(Graphics g){
drawPipe(g);
pipeMove += SPEED;
if(pipeMove >= GAME_WIDTH + PIPE_WIDTH){
pipeMove = 0;
Random ran = new Random();
height = ran.nextInt(10)*20;
drawPipe(g);
}
}
private void drawPipe(Graphics g){
g.setColor(Color.RED);
// g.drawRect(GAME_WIDTH - pipeMove,GAME_HEIGHT/5*3 - height,PIPE_WIDTH,PIPE_HEIGHT);
// g.drawRect(GAME_WIDTH - pipeMove,-GAME_HEIGHT/5*4 - height,PIPE_WIDTH,PIPE_HEIGHT);
g.drawImage(ImageMgr.pipe,GAME_WIDTH - pipeMove,GAME_HEIGHT/5*3 - height,null);
g.drawImage(ImageMgr.pipe,GAME_WIDTH - pipeMove,-GAME_HEIGHT/5*4 - height,null);
pipeRectangle1 = new Rectangle(GAME_WIDTH - pipeMove,GAME_HEIGHT/5*3 - height,PIPE_WIDTH,PIPE_HEIGHT);
pipeRectangle2 = new Rectangle(GAME_WIDTH - pipeMove,-GAME_HEIGHT/5*4 - height,PIPE_WIDTH,PIPE_HEIGHT);
}
private void gameOver(Graphics g){
if(over){
g.drawImage(ImageMgr.gameOver,GAME_WIDTH/2 - GAME_OVER_WIDTH/2, GAME_HEIGHT/2 - GAME_OVER_HEIGHT,null);
}
}
private void start(Graphics g){
if(!start){
g.drawImage(ImageMgr.ready,GAME_WIDTH/2 - READY_WIDTH/2, GAME_HEIGHT/2 - READY_HEIGHT,null);
g.drawImage(ImageMgr.start,GAME_WIDTH/2 - START_WIDTH/2, GAME_HEIGHT/2,null);
}
}
private void colliedWith(){
if(birdRectangle.intersects(pipeRectangle1) || birdRectangle.intersects(pipeRectangle2)){
crash = true;
over = true;
//gameOver(g);
}
}
}工具類
public class ImageMgr {
static BufferedImage background,ground,pipe,gameOver,start,ready;
static BufferedImage[] bird = new BufferedImage[3];
private static final ImageMgr INSTANCE = new ImageMgr();
//nothing
private ImageMgr(){
initImage();
};
private void initImage(){
try {
background = ImageIO.read(Objects.requireNonNull(Cuckoo.class.getClassLoader().getResourceAsStream("images/bg_light.png")));
ground = ImageIO.read(Objects.requireNonNull(Cuckoo.class.getClassLoader().getResourceAsStream("images/ground.png")));
pipe = ImageIO.read(Objects.requireNonNull(Cuckoo.class.getClassLoader().getResourceAsStream("images/pipe.png")));
gameOver = ImageIO.read(Objects.requireNonNull(Cuckoo.class.getClassLoader().getResourceAsStream("images/gameover.png")));
start = ImageIO.read(Objects.requireNonNull(Cuckoo.class.getClassLoader().getResourceAsStream("images/start.png")));
ready = ImageIO.read(Objects.requireNonNull(Cuckoo.class.getClassLoader().getResourceAsStream("images/ready.png")));
for(int i = 0;i < 3;i++){
bird[i] = ImageIO.read(Objects.requireNonNull(Cuckoo.class.getClassLoader().getResourceAsStream("images/blueBird_" + (i+1) + ".png")));
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static ImageMgr getInstance(){
return INSTANCE;
}
}總結(jié)
通過此次的《布谷鳥闖關(guān)-簡單版》實現(xiàn),讓我對JAVA的相關(guān)知識有了進一步的了解,對java這門語言也有了比以前更深刻的認識。
java的一些基本語法,比如數(shù)據(jù)類型、運算符、程序流程控制和數(shù)組等,理解更加透徹。java最核心的核心就是面向?qū)ο笏枷?,對于這一個概念,終于悟到了一些。
以上就是Java實現(xiàn)經(jīng)典游戲Flappy Bird的示例代碼的詳細內(nèi)容,更多關(guān)于Java Flappy Bird游戲的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring?Boot攔截器和監(jiān)聽器實現(xiàn)對請求和響應(yīng)處理實戰(zhàn)
這篇文章主要介紹了Spring?Boot攔截器和監(jiān)聽器實現(xiàn)對請求和響應(yīng)處理實戰(zhàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-06-06
Java高并發(fā)之CyclicBarrier的用法詳解
CyclicBarrier 是 Java 中的一種同步工具,它可以讓多個線程在一個屏障點處等待,直到所有線程都到達該點后,才能繼續(xù)執(zhí)行。本文就來和大家聊聊它的用法,需要的可以參考一下2023-03-03
WIN7系統(tǒng)JavaEE(java)環(huán)境配置教程(一)
這篇文章主要介紹了WIN7系統(tǒng)JavaEE(java+tomcat7+Eclipse)環(huán)境配置教程,本文重點在于java配置,感興趣的小伙伴們可以參考一下2016-06-06
詳解使用IntelliJ IDEA新建Java Web后端resfulAPI模板
這篇文章主要介紹了詳解使用IntelliJ IDEA新建Java Web后端resfulAPI模板,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08
SpringData Repository Bean方法定義規(guī)范代碼實例
這篇文章主要介紹了SpringData Repository Bean方法定義規(guī)范代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-08-08

