實驗要求
實現貪吃蛇遊戲基本功能,螢幕上隨機出現一個“食物”,稱為豆子,上下左右控制“蛇”的移動,吃到“豆子”以後“蛇”的身體加長一點,得分增加,“蛇”碰到邊界或,蛇頭與蛇身相撞,蛇死亡,遊戲結束。為遊戲設計初始歡迎介面,遊戲介面,遊戲結束介面。
實驗分析貪吃蛇實驗圖形介面由蛇頭,蛇身,食物等組成。蛇頭部分透過鍵盤方向鍵進行上下左右的移動。豆子隨機生成,操縱蛇頭吃到隨機的豆子,蛇身長度變長,得分增加。據此,可分析出具體需要實現的功能: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; } } }
執行結果
最新評論