package com.oracle.Game; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import javax.swing.JComponent; import javax.swing.JFrame; public class SnakeGame extends KeyAdapter implements Runnable { private boolean start=false; private JFrame frame; private Thread timerThread; //-------------變量定義Start------------- int[] SnakeXs=new int[900]; int[] SnakeYs=new int[900]; //定義初始蛇的長度 int len=6; //定義初始方向 int diraction=4; //定義食物的X,Y坐標 int a; int b; //定義一個分數 int score; //定義一個變量記錄吃了多少個 int count; //是否Game Over boolean IsGameOver = false; //是否加速 int time; boolean BiteWall ; //-------------變量定義End------------- /** * 構造方法,用於構造及初始化所需要的其它對象 */ public SnakeGame(){ //-------------構造&初始對象Start------------- for(int i=0;i<len;i++){ SnakeXs[i]=(len-1-i)*20;SnakeYs[i]=0; } //初始化食物坐標 a=100; b=100; //初始化分數 score=0; //初始化時間 time=400; //-------------構造&初始對象End------------- frame = new JFrame(); frame.getContentPane().add(new Screen()); frame.addKeyListener(this); //-------------窗口大小設置 frame.setSize(寬, 高); frame.setSize(600+5*2+200, 600+25+5*2); frame.setVisible(true); frame.repaint(); } /** * 鍵盤事件響應 * @param evt * 按鍵事件 */ public void keyPressed(KeyEvent evt){ switch(evt.getKeyCode()){ case KeyEvent.VK_ENTER: if(!start){ timerThread = new Thread(this); timerThread.start(); start = true; } break; case KeyEvent.VK_ESCAPE: start = false; System.exit(1); break; case KeyEvent.VK_LEFT: //-------------按左方向鍵的事件響應Start------------- if(diraction==1||diraction==2) { diraction=3; } //-------------按左方向鍵的事件響應End------------- break; case KeyEvent.VK_RIGHT: //-------------按右方向鍵的事件響應Start------------- if(diraction==1||diraction==2) { diraction=4; } //-------------按右方向鍵的事件響應End------------- break; case KeyEvent.VK_DOWN: //-------------按下方向鍵的事件響應Start------------- if(diraction==3||diraction==4) { diraction=2; } //-------------按下方向鍵的事件響應End------------- break; case KeyEvent.VK_UP: //-------------按上方向鍵的事件響應Start------------- if(diraction==3||diraction==4) { diraction=1; } //-------------按上方向鍵的事件響應End------------- break; case KeyEvent.VK_R: BiteWall=!BiteWall; break; } frame.repaint(); } /** * 線程方法主體,主要用於在主線程展示窗體的同時在窗體中同時做其它任務 */ public void run(){ while(true){ try{ //-------定時時間間隔 Thread.sleep(毫秒);------- Thread.sleep(time); }catch (InterruptedException e){ e.printStackTrace(); } if(start==false) return; //-------------定時時間間隔事件任務Start------------- //-------------定時時間間隔事件任務End------------- frame.repaint(); } } class Screen extends JComponent{ private static final long serialVersionUID = 1155019838145337862L; public void paint(Graphics g){ Graphics2D g2d = (Graphics2D)g; //-------------畫圖處理Start------------- // g2d.drawOval(0, 0, 100, 100); // g2d.fillOval(100, 100, 200, 100); // g2d.setColor(Color.BLUE); // g2d.drawString("今天是2018年1月4號", 0, 10); //畫出背景板 g2d.setColor(Color.orange); g2d.fillRect(0, 0, 800, 600); g2d.setColor(Color.black); g2d.fillRect(0, 0, 600, 600); //畫出背景方格 for(int i=0;i<30;i++){ for(int j=0;j<30;j++){ g2d.setColor(Color.white); g2d.drawRect(i*20,j*20 , 20,20); } } //畫出初始位置的蛇身體 for(int i=0;i<len;i++){ g2d.setColor(Color.green); g2d.fillRect(SnakeXs[i]+1,SnakeYs[i]+1,20-2,20-2); } //畫出第一個食物的點 g2d.setColor(Color.green); g2d.fillRect(a+1,b+1, 20-2, 20-2); if(SnakeXs[0]==a&&SnakeYs[0]==b){ count++; len++; //吃到食物身體變長一節 score+=10; //吃到食物分數增加10分 //創造一個新的食物 a=(int)(Math.random()*30)*20; b=(int)(Math.random()*30)*20; g2d.setColor(Color.green); g2d.fillRect(a+1,b+1, 20-2, 20-2); } //判斷是否撞牆停止游戲 if(BiteWall==true){ if(SnakeXs[0]<0){ SnakeXs[0] = 580; }else if(SnakeXs[0]>580){ SnakeXs[0] = 0; } if(SnakeYs[0]<0){ SnakeYs[0] = 580; }else if(SnakeYs[0]>580){ SnakeYs[0] = 0; } }else{ //如果撞牆了則顯示GameOver if(SnakeXs[0]<0 || SnakeXs[0]>580 ||SnakeYs[0]<0 || SnakeYs[0]>580){ IsGameOver = true; } } for(int i=1;i<len;i++){ if(SnakeXs[0]==SnakeXs[i]&&SnakeYs[0]==SnakeYs[i]){ IsGameOver=true; break; } } if(IsGameOver){ g2d.setFont(new Font("宋體",Font.BOLD,80)); g2d.setColor(Color.orange); g2d.drawString("Game Over!!", 80, 250); start=false; } //顯示出分數 g2d.setFont(new Font("宋體",Font.BOLD,20)); g2d.setColor(Color.red); g2d.drawString("分數:"+score, 650, 200); g2d.drawString("吃了:"+count+"個", 650, 300); g2d.setColor(Color.blue); g2d.drawString("巨無霸恐怖貪吃蛇", 620, 100); //判斷分數超過一定值之后加速 switch(score/100){ case 1: time=300; break; case 2: time=200; break; case 3: time=100; break; case 4: time=50; break; } //蛇身的移動 for(int i=len-1;i>0;i--){ SnakeXs[i]=SnakeXs[i-1];SnakeYs[i]=SnakeYs[i-1]; } //蛇頭的移動 switch(diraction){ case 1: SnakeYs[0]=SnakeYs[0]-20; break; case 2: SnakeYs[0]=SnakeYs[0]+20; break; case 3: SnakeXs[0]=SnakeXs[0]-20; break; case 4: SnakeXs[0]=SnakeXs[0]+20; break; } //-------------畫圖處理End------------- } } /** * 主方法用於啟動窗體 * @param args */ public static void main(String[] args){ //構造窗體對象用於展示 new SnakeGame(); } }
通過控制按鍵控制“蛇”的移動方向,同時利用 Math.random() 方法創建一個隨機出生的“食物”,“吃到食物”后讓“蛇”的身長增加並且記錄“吃到一次食物”后的分數,當分數到達某一等級之后改變“蛇”的移動速度來增加游戲難度。另外還可以單獨為“食物”,“蛇”創建單獨的對象來實現更加方便的調用修改.具體結果界面如下: