實驗要求
實作貪吃蛇游戲基本功能,螢屏上隨機出現一個“食物”,稱為豆子,上下左右控制“蛇”的移動,吃到“豆子”以后“蛇”的身體加長一點,得分增加,“蛇”碰到邊界或,蛇頭與蛇身相撞,蛇死亡,游戲結束,為游戲設計初始歡迎界面,游戲界面,游戲結束界面,
實驗分析
貪吃蛇實驗圖形界面由蛇頭,蛇身,食物等組成,
蛇頭部分通過鍵盤方向鍵進行上下左右的移動,豆子隨機生成,操縱蛇頭吃到隨機的豆子,蛇身長度變長,得分增加,據此,可分析出具體需要實作的功能:
1.構建合適的網格,并且設定好墻,
2.在適當的位置產生豆子,即網格內部,且不是蛇身的地方,
3.通過鍵盤控制實作蛇頭的移動
4.實作蛇身的重繪,當蛇在去吃食物的移動程序中,蛇頭按照方向去往鄰近的一個網格,蛇身的每一個結點取代上一個結點的位置,蛇尾處的結點消失,蛇吃到豆子的那一次移動,豆子即為蛇頭的位置,其余不再取代上一個結點的位置,
5.判斷是否撞墻與撞到自身,即蛇頭的位置是否與墻及自己身體的坐標重合,
6.進行計分與計時,
實驗進行
構建網格與其他說明界面
private JLabel label2 = new JLabel("所花時間:");
private JLabel label3 = new JLabel("得分"); // 標簽
private JLabel label4 = new JLabel("說 明:");
private JTextArea explain = new JTextArea("游戲界面按上下左右鍵實作移動,按ESC重新開始,按空格鍵可以實作暫停和開始");
private JLabel score = new JLabel("");
private JLabel Time = new JLabel("");
private Font f = new Font("微軟雅黑",Font.PLAIN,15);
private Font f2 = new Font("微軟雅黑",Font.PLAIN,13);
private JPanel p = new JPanel(); //面板
private int hour =0; // 定義時間,小時,分鐘,秒
private int min =0;
private int sec =0 ;
private int sco=0;
private boolean pause = false;
add(label3);
label3.setBounds(500, 10, 80, 20);
label3.setFont(f);
add(score);
score.setBounds(500, 35, 80, 20);
score.setFont(f);
add(label2);
label2.setBounds(500, 60, 80, 20);
label2.setFont(f); // 標簽
add(Time);
Time.setBounds(500, 85, 80, 20);
Time.setFont(f);
add(p);
p.setBounds(498, 110, 93, 1);
p.setBorder(BorderFactory.createLineBorder(Color.black));
add(label4);
label4.setBounds(500, 115, 80, 20);
label4.setFont(f);
add(explain);
explain.setBounds(498, 138, 90, 350);
explain.setFont(f2);
explain.setLineWrap(true);
explain.setOpaque(false);
//墻
g.setStroke( new BasicStroke(4,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL));
g.setBackground(Color.black);
g.drawRect(2, 7, 491, 469); // 第一個塊的顏色,位置
//網格線
for(int i = 1;i < 22;i++)
{
g.setStroke( new BasicStroke(1,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL));
g.setColor(Color.black);
g.drawLine(5+i*22,9,5+i*22,472);
if(i <= 20)
{
g.drawLine(4,10+i*22,491,10+i*22);
}
}
進行蛇整體的布局及移動還有食物的生成
public class Snake extends JComponent { //建一個貪吃蛇的類對其進行編輯
private static final long serialVersionUID = 3794762291171148906L; // 定義了一個私有的靜態的不可改變的long型別的 名字是VersionUID,
private final int MAX_SIZE = 400;//蛇身體最長為400節
private Tile temp = new Tile(0,0);
private Tile temp2 = new Tile(0,0);
private Tile head = new Tile(227,100);//頭部的位置初始化為(227,100)
private Tile[] body = new Tile[MAX_SIZE];
private String direction = "R";//默認向右走
private String current_direction = "R";//當前方向
private boolean first_launch = false;
private boolean iseaten = false;
private boolean isrun = true;
private int randomx,randomy;
private int body_length = 5;//身體長度初始化為5
private Thread run;
public void paintComponent(Graphics g1){ // 指呼叫父類的繪制事件,在重寫父類函式時經常會呼叫一下相應的父類方法
super.paintComponent(g1); // super關鍵字用來呼叫父類中定義的構造器,控制物件的父類的部分結構
Graphics2D g = (Graphics2D) g1; // 畫(Graphics g)
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,RenderingHints.VALUE_STROKE_NORMALIZE);
//畫頭部
g.setColor(Color.red); // 設定顏色
g.fillRoundRect(head.x, head.y, 20, 20, 10, 10);
g.setPaint(new GradientPaint(115,135,Color.CYAN,230,135,Color.MAGENTA,true));
if(!first_launch) //定義蛇初始化身體的顏色
{
//初始化身體
int x = head.x;
for(int i = 0;i < body_length;i++)
{
x -= 22;//相鄰兩個方塊的間距為2個像素,方塊寬度都為20像素
body[i].x = x;
body[i].y = head.y;
g.fillRoundRect(body[i].x, body[i].y, 20, 20, 10, 10);
}
//初始化食物位置
ProduceRandom();
g.fillOval(randomx, randomy, 19, 19);
}
else
{
//每次重繪身體
for(int i = 0;i < body_length;i++)
{
g.fillRoundRect(body[i].x, body[i].y, 20, 20, 10, 10);
}
if(EatFood())//被吃了重新產生食物,并且計入得分
{
ProduceRandom();
g.fillOval(randomx, randomy, 19, 19);
iseaten = false;
sco++;
showScore();
}
else
{
g.fillOval(randomx, randomy, 19, 19);
}
}
對是否撞墻以及是否撞到自己進行判斷以及處理
public void HitWall(){//判斷是否撞墻
if(current_direction == "L")
{
if(head.x < 7)
{
int result=JOptionPane.showConfirmDialog(null, "Game over! Try again?", "Information", JOptionPane.YES_NO_OPTION);
if(result==JOptionPane.YES_NO_OPTION)
{
direction = "R";//默認向右走
current_direction = "R";//當前方向
first_launch = false;
iseaten = false;
isrun = true;
body_length = 5;
head = new Tile(227,100);
hour =0;
min =0;
sec =0 ;
for(int i = 0; i < MAX_SIZE;i++)
{
body[i].x = 0;
body[i].y = 0;
}
run = new Thread();
run.start();
System.out.println("Start again");
}
else
{
run.stop();
}
}
}
if(current_direction == "R")
{
if(head.x > 489)
{
int result=JOptionPane.showConfirmDialog(null, "Game over! Try again?", "Information", JOptionPane.YES_NO_OPTION);
if(result==JOptionPane.YES_NO_OPTION)
{
direction = "R";//默認向右走
current_direction = "R";//當前方向
first_launch = false;
iseaten = false;
isrun = true;
body_length = 5;
head = new Tile(227,100);
hour =0;
min =0;
sec =0 ;
for(int i = 0; i < MAX_SIZE;i++)
{
body[i].x = 0;
body[i].y = 0;
}
run = new Thread();
run.start();
System.out.println("Start again");
}
else
{
run.stop();
}
}
}
if(current_direction == "U")
{
if(head.y < 12)
{
int result=JOptionPane.showConfirmDialog(null, "Game over! Try again?", "Information", JOptionPane.YES_NO_OPTION);
if(result==JOptionPane.YES_NO_OPTION)
{
direction = "R";//默認向右走
current_direction = "R";//當前方向
first_launch = false;
iseaten = false;
isrun = true;
body_length = 5;
head = new Tile(227,100);
hour =0;
min =0;
sec =0 ;
for(int i = 0; i < MAX_SIZE;i++)
{
body[i].x = 0;
body[i].y = 0;
}
run = new Thread();
run.start();
System.out.println("Start again");
}
else
{
run.stop();
}
}
}
if(current_direction == "D")
{
if(head.y > 472)
{
int result=JOptionPane.showConfirmDialog(null, "Game over! Try again?", "Information", JOptionPane.YES_NO_OPTION);
if(result==JOptionPane.YES_NO_OPTION)
{
direction = "R";//默認向右走
current_direction = "R";//當前方向
first_launch = false;
iseaten = false;
isrun = true;
body_length = 5;
head = new Tile(227,100);
hour =0;
min =0;
sec =0 ;
for(int i = 0; i < MAX_SIZE;i++)
{
body[i].x = 0;
body[i].y = 0;
}
run = new Thread();
run.start();
System.out.println("Start again");
}
else
{
run.stop();
}
}
}
}
public void HitSelf(){//判斷是否撞到自己身上
for(int i = 0;i < body_length; i++)
{
if(body[i].x == head.x && body[i].y == head.y)
{
int result=JOptionPane.showConfirmDialog(null, "Game over! Try again?", "Information", JOptionPane.YES_NO_OPTION);
if(result==JOptionPane.YES_NO_OPTION)
{
direction = "R";//默認向右走
current_direction = "R";//當前方向
first_launch = false;
iseaten = false;
isrun = true;
body_length = 5;
head = new Tile(227,100);
hour =0;
min =0;
sec =0 ;
for(int j = 0; j < MAX_SIZE;j++)
{
body[j].x = 0;
body[j].y = 0;
}
run = new Thread();
run.start();
System.out.println("Start again");
}
else
{
run.stop();
}
break;
}
}
}
運行結果

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/241923.html
標籤:其他
上一篇:Vue實作隨機驗證碼功能
