java51游戏_简单实现美空军也得玩的游戏-谁能坚持超过50秒?(Java)
前天不知道又在哪里見到這么一句話“誰能堅持超過50秒,我請他吃飯”(可以點擊玩一玩原版游戲),其實這個不就是之前在同學QQ空間里面轉來轉去的一個網頁游戲嗎?什么“據說,美國空軍的飛行員被強制達到2分鐘?!庇谑?#xff0c;又來了一點點興趣再玩一下下。游戲界面如下:
其實前段時間自己也嘗試用 Java 實現了這游戲,具體是按照自己對這游戲的簡單理解使用 Java GUI 進行編程。電腦裝了 JRE 的朋友可以下載附件直接雙擊 .bat 文件試玩一下哦!!!(*^__^*) 嘻嘻……
我的思路是這樣子的(游戲中的方塊用 JLabel 實現):
1、游戲中4個自動移動并且會慢慢加速的方塊是碰到固定的“壁”就按照光的反射特性改變移動的方向,這個我們可以通過條件判斷來改變方塊的具體坐標 x 和 y 來實現;
2、自動移動則用 Java 線程來實現,具體是在線程類的 run() 方法中用死循環不斷改變 x 和 y 坐標,然后不斷地擦除、重繪即可,而碰壁之后反射的算法也是包含在這里的;
3、玩家能夠通過按住鼠標左鍵來移動自己的方塊,這個應該用 java.awt.event 包中的 MouseMotionAdapter 這個鼠標事件監聽器類,Java 文檔中的描述是“接收鼠標移動事件的抽象適配器類”,它包含() 和() 方法,可以監聽鼠標時間按,具體的可以查閱一下該類;對于玩家控制的方塊,要每時每刻都獲取鼠標當前在面板上的坐標 x 、y,以此為 JLabel 方塊的中心進行不斷擦除、重繪,也就達到了跟著鼠標移動的效果了;
4、判斷游戲是否結束,就是遍歷4個自動移動的 JLabel 方塊,看它們在游戲面板中的覆蓋面是否與玩家控制的 JLabel 方塊有一點點重合,重合則說明相碰了,游戲結束;
5、關于游戲計時,這個可以用到 Java 線程中的 java.util.TimerTask 類來實現,不過這里我的游戲中沒實現,偷懶了一下;
6、至于方塊的移動速度,用一定的策略對 Thead.sleep() 方法中的睡眠時間進行減少即可。
我的游戲界面:
1、游戲開始狀態
2、游戲進行中
3、碰壁了,游戲結束
代碼實現:
GlobalVars.java
//常量接口模式:把系統中相關的常量放在專門的常量接口中定義
publicinterfaceGlobalVars?{
/**
*?4個移動方向,L、R為左、右,U、D為上、下
*/
publicstaticfinalintLD?=?-1;//往左下方
publicstaticfinalintRD?=1;//往右下方
publicstaticfinalintRU?=2;//往右上方
publicstaticfinalintLU?=?-2;//往左上方
/**
*?游戲窗口大小
*/
publicstaticfinalintFRAME_WIDTH?=500;
publicstaticfinalintFRAME_HEIGTH?=500;
/**
*?面板大小
*/
publicstaticfinalintPANEL_WIDTH?=400;
publicstaticfinalintPANEL_HEIGTH?=400;
/**
*?玩家JLabel的大小
*/
publicstaticfinalintPLAYER_WIDTH?=50;
publicstaticfinalintPLAYER_HEIGTH?=50;
}
ImpMove.java
importjavax.swing.JLabel;
/**
*?定義一個電腦方、玩家的JLabel都要實現的
*?移動策略的抽象類?ImpMove?,該接口繼承自
*?JLabel,所以可以獲取?JLabel?類中常用?的方法
*?@author?haolloyin
*/
publicabstractclassImpMoveextendsJLabel{
//?移動
protectedabstractvoidmove();
//?開始
protectedabstractvoidbegin();
}
ComputerPanel.java
/**
*?電腦控制的?JLabel?方塊,繼承自?ImpMove
*?抽象類,必須實現其?move()和?begin()方法,
*?它可以在游戲中存在多個具體實例,由玩家
*?確定,它使用了線程因此能夠自動移動
*?@author?haolloyin
*/
publicclassComputerLabelextendsImpMove{
/*?碰到壁必須反彈,這里4個常量用于
*?判斷電腦方塊碰到那一面壁
*/
privatestaticfinalintPL?=?-1;
privatestaticfinalintPR?=1;
privatestaticfinalintPU?=2;
privatestaticfinalintPD?=?-2;
privateintxx;
privateintyy;
privateintwidth;
privateintheigth;
privatePoint?p;
privateRectangle?r;
privateintdirection;//移動方向
privateintspeed?=5;//移動速度
privateThread?go;//驅動其移動的線程實例
privatebooleanisLive?=true;//游戲是否結束
publicComputerLabel(intx,inty,intw,inth,intd)?{
this.width?=?w;
this.heigth?=?h;
init(x,?y,?w,?h,?d);
}
privatevoidinit(intx,inty,intw,inth,intdirection)?{
setBounds(x,?y,?w,?h);
setOpaque(true);
setBackground(Color.green);
r?=?getBounds();
p?=?r.getLocation();
this.direction?=?direction;
}
/**
*??實現了Runnable接口的私有內部類,用于驅動move()方法
*/
privateclassMoveAbleimplementsRunnable?{
publicvoidrun()?{
while(isLive)?{
try{
Thread.sleep(speed);
}catch(InterruptedException?e)?{
e.printStackTrace();
}
//??????????????System.out.println("speed?=?"?+?speed);
move();
}
}
}
/**
*?實現ImpMove抽象類中的move()
*/
@Override
protectedvoidmove()?{
isPengBi();
p.x?+=?xx;
p.y?+=?yy;
setLocation(p.x,?p.y);
}
/**
*?測試是否碰到壁,若是則調
*?用changeDirection()改變移動方向
*/
privatevoidisPengBi()?{
if(p.x?<0)?{
changeDirection(PL);
}elseif(p.x?>?GlobalVars.PANEL_WIDTH?-?width)?{
changeDirection(PR);
}elseif(p.y?<0)?{
changeDirection(PU);
}elseif(p.y?>?GlobalVars.PANEL_HEIGTH?-?heigth)?{
changeDirection(PD);
}
}
/**
*?碰到壁則反彈,即改變移動方向
*/
privatevoidchangeDirection(intpeng)?{
if(peng?==?PL?&&?direction?==?LD)?{//?↙碰左
direction?=?RD;
xx?=1;
yy?=1;
}elseif(peng?==?PL?&&?direction?==?LU)?{//?↖碰左
direction?=?RU;
xx?=1;
yy?=?-1;
}elseif(peng?==?PR?&&?direction?==?RU)?{//?↗碰右
direction?=?LU;
xx?=?-1;
yy?=?-1;
}elseif(peng?==?PR?&&?direction?==?RD)?{//?↘碰右
direction?=?LD;
xx?=?-1;
yy?=1;
}elseif(peng?==?PU?&&?direction?==?RU)?{//?↗碰上
direction?=?RD;
xx?=1;
yy?=1;
}elseif(peng?==?PU?&&?direction?==?LU)?{//?↖碰上
direction?=?LD;
xx?=?-1;
yy?=1;
}elseif(peng?==?PD?&&?direction?==?LD)?{//?↙碰下
direction?=?LU;
xx?=?-1;
yy?=?-1;
}elseif(peng?==?PD?&&?direction?==?RD)?{//?↘碰下
direction?=?RU;
xx?=1;
yy?=?-1;
}
}
/**
*?游戲開始,啟動線程
*/
@Override
protectedvoidbegin()?{
go?=newThread(newMoveAble());
toWhere();
go.start();
}
/**
*?確定方塊的移動方向
*/
privatevoidtoWhere()?{
if(direction?==?LD)?{
xx?=?-1;
yy?=1;
}elseif(direction?==?LU)?{
xx?=?-1;
yy?=?-1;
}elseif(direction?==?RD)?{
xx?=1;
yy?=1;
}elseif(direction?==?RU)?{
xx?=1;
yy?=?-1;
}
}
/**
*?游戲是否結束
*/
publicvoidisDead()?{
this.isLive?=false;
}
/**
*?設置移動速度
*/
publicvoidsetSpeed(intspeed)?{
this.speed?=?speed;
}
}
PlayerPanel.java
/**
*?供玩家控制的?JLabel?方塊,它在整個游戲
*?當中只會存在一個實例對象,繼承自?ImpMove
*?抽象類,必須實現其?move()?和?begin()?方法
*?@author?haolloyin
*/
publicclassPlayerLabelextendsImpMove{
privateRectangle?r;//方塊的大小、位置
privatePoint?now;//方塊的坐標x、y
privateintx;//原來的坐標?x
privateinty;//原來的坐標?y
privateintmax_x?=?PANEL_WIDTH?-?PLAYER_WIDTH;
privateintmax_y?=?PANEL_HEIGTH?-?PLAYER_HEIGTH;
publicPlayerLabel()?{
begin();
}
/**
*?重寫begin()方法,玩家鼠標一單擊中間的
*?JLabel?方塊,則游戲開始
*/
@Override
protectedvoidbegin()?{
setText("點擊吧");
setForeground(Color.black);
setSize(PLAYER_WIDTH,?PLAYER_HEIGTH);
setLocation(150,150);
setOpaque(true);
setBackground(Color.green);
r?=this.getBounds();
now?=newPoint();
/**
*?為當前JLabel對象添加接收鼠標移動事件的抽象適配器類,
*?用于當按下鼠標時獲取當前坐標并開始游戲
*/
addMouseMotionListener(newMouseMotionAdapter()?{
publicvoidmouseDragged(MouseEvent?e)?{
x?=?e.getX();
y?=?e.getY();
move();
}
});
/**
*?添加可以變換鼠標指針樣式的事件監聽器
*/
addMouseListener(newMouseAdapter()?{
publicvoidmouseEntered(MouseEvent?e)?{
//?變成手型鼠標
setBackground(Color.yellow);
setCursor(newCursor(Cursor.HAND_CURSOR));
}
publicvoidmouseExited(MouseEvent?e)?{
//?變成默認鼠標
setBackground(Color.green);
setCursor(newCursor(Cursor.DEFAULT_CURSOR));
}
});
}
/**
*?游戲的主要算法:實現ImpMove抽象類中的move()
*/
@Override
protectedvoidmove()?{
now?=?MouseInfo.getPointerInfo().getLocation();
if(now.x?%10>4)
now.x?=?now.x?/10+1;
else
now.x?/=10;
if(now.y?%10>4)
now.y?=?now.y?/10+1;
else
now.y?/=10;
r.x?+=?(x?-?now.x);
r.y?+=?(y?-?now.y);
/*
*?如果玩家JLabel方塊碰壁了,則保證其
*?始終緊靠著壁,而不是結束游戲
*/
if(r.x?<=0)
r.x?=0;
if(r.y?<=0)
r.y?=0;
if(r.x?>?max_x)
r.x?=?max_x;
if(r.y?>?max_y)
r.y?=?max_y;
now.x?=?x;
now.y?=?y;
setBackground(Color.cyan);
setLocation(r.x,?r.y);
}
/**
*?測試
*/
publicstaticvoidmain(String[]?args)?{
JFrame?jf?=newJFrame();
PlayerLabel?p1?=newPlayerLabel();
jf.setLayout(null);//布局設置為null
jf.add(p1);
jf.setLocation(400,50);
jf.setSize(500,500);
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
GamePanel.java
/**
*??游戲的面板,所有JLabel對象都被添加
*??到該面板,由其來具體控制游戲的運行,
*??類似于中介者模式中的?Mediator
*?@author?haolloyin
*/
publicclassGamePanelextendsJPanel{
//?保存自動移動的JLabel對象,即電腦控制的方塊
privateLinkedList?labels;
//?游戲是否結束
privatebooleanisLive?=true;
//?玩家JLabel
privatePlayerLabel?player;
//游戲進行中判斷是否相碰的線程
privateThread?go;
publicGamePanel()?{
setBounds(50,30,?PANEL_WIDTH,?PANEL_HEIGTH);
setBackground(Color.yellow);
setLayout(null);
init();
}
privatevoidinit()?{
labels?=newLinkedList();
player?=newPlayerLabel();
this.add(player);
player.addMouseListener(newMouseAdapter()?{
publicvoidmousePressed(MouseEvent?me)?{
player.setText("我閃...");
startGame();
}
});
}
privatevoidstartGame()?{
intnum?=?labels.size();
for(inti?=0;?i?
labels.get(i).begin();
}
if(this.go?==null)?{
go?=newThread(newCheckGameIsOver());
go.start();
}
}
privatevoidisOver()?{
Rectangle?r_player?=?player.getBounds();
intnum?=?labels.size();
for(inti?=0;?i?
if(labels.get(i).getBounds().intersects(r_player))?{
System.out.println("Game?Over?...");
System.out.println("你碰到第-->?"+?i?+"?
gameOver();
try{
Thread.sleep(2000);
}catch(InterruptedException?e)?{
e.printStackTrace();
}
System.exit(0);
}
}
}
privatevoidgameOver()?{
intnum?=?labels.size();
for(inti?=0;?i?
ComputerLabel?l?=?(ComputerLabel)labels.get(i);
l.isDead();
}
}
privateclassCheckGameIsOverimplementsRunnable?{
publicvoidrun()?{
while(isLive)?{
isOver();
}
}
}
publicvoidaddLabel(ImpMove?label)?{
this.labels.add(label);
this.add(label);
}
}
Game.java
/**
*?最終游戲測試類,其實就是初始化所有
*?JLabel?對象并啟動游戲
*?@author?haolloyin
*/
publicclassGameextendsJFrame?{
publicGame()?{
setTitle("躲避?游戲");
setLayout(null);
setBounds(300,100,?FRAME_WIDTH,?FRAME_HEIGTH);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
/*
*?測試
*/
publicstaticvoidmain(String[]?args)?{
GamePanel?gamePanel?=newGamePanel();
ComputerLabel?p1?=newComputerLabel(340,320,35,59,?RU);
ComputerLabel?p2?=newComputerLabel(13,30,40,20,?LU);
ComputerLabel?p3?=newComputerLabel(20,200,60,40,?RD);
ComputerLabel?p4?=newComputerLabel(350,60,70,60,?LD);
ComputerLabel?p5?=newComputerLabel(200,20,10,15,?LD);
p1.setBackground(Color.black);
p2.setBackground(Color.DARK_GRAY);
p3.setBackground(Color.magenta);
p4.setBackground(Color.red);
p5.setBackground(Color.red);
p1.setSpeed(4);
p2.setSpeed(5);
p3.setSpeed(6);
p4.setSpeed(3);
p5.setSpeed(2);
gamePanel.addLabel(p1);
gamePanel.addLabel(p2);
gamePanel.addLabel(p3);
gamePanel.addLabel(p4);
gamePanel.addLabel(p5);
Game?game?=newGame();
game.add(gamePanel);
}
}
小結:
1、各個類的設計、結構感覺很亂;
2、上面的一點還體現在關于游戲實體(即 JLabel 方塊)所選取的數據結構很亂;
3、重要方法如 move() 的代碼過多且雜,本來這是整個游戲的重點算法實現,卻這樣子糟糕,+_+;
4、代碼中沒有注釋,所以剛才在理解自己的代碼時花了點時間,%>_<%…嗯,以后這要注意了。
總結
以上是生活随笔為你收集整理的java51游戏_简单实现美空军也得玩的游戏-谁能坚持超过50秒?(Java)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 鼠标移动小球 Java_js实现跟随鼠标
- 下一篇: mongodb java 学习_Mong