import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.geom.Line2D; import java.util.*; /** * Version:1.5 * 功能:畫出10*10個方格 * 0 1 2 3 4 5 6 7 8 9 * 10 11 * ...................... * ....................99 * 在任意位置顯示一個方格,並讓鍵盤控制運動方向,連續運動 * 產生隨機蘋果,能夠判斷是否吃掉。 * 改動:用可變長數組來存放蛇身。 * 完成基本效果 */ public class SnakeDemo5 { private JFrame frame; private int AppleDisplayFlag = 1; // 蘋果是否顯示標誌位 private int UPFlag = 0;int DownFlag=0;int LeftFlag=0;int RightFlag=0; private int SnakeHead = 2; private int AppleIndex = 0; private int numberOfRow = 20; // 改變每行的box數量 private int numberOfBox = numberOfRow * numberOfRow; private int[] BoxDisplayFlag = new int[numberOfBox];// 刷新時遍歷,根據flag選擇是否顯示對應的box private Vector snakeBody = new Vector(); int snakeEndBuf = 0; public static void main(String[] args) { SnakeDemo5 snake = new SnakeDemo5(); snake.go(); } private void go(){ frame = new JFrame(); MyDrawPanel myDrawPanel = new MyDrawPanel(); frame.addKeyListener(myDrawPanel); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(myDrawPanel); // 把本身的畫板加到frame框架中 frame.setSize(300, 300); // 框架窗口大小 frame.setVisible(true); // 最後把frame顯示出來 snakeBody.add(SnakeHead); snakeBody.add(1); snakeBody.add(0); for(int i=0; i<snakeBody.size();i++){ // 初始化,畫板2號格子蛇頭,snakeBody的0號元素。 BoxDisplayFlag[(int) snakeBody.get(i)] = 1; } AppleIndex = (int) (Math.random()*100); while(true){ if(DownFlag == 1){ snakeEndBuf = (int) snakeBody.get(snakeBody.size()-1); for(int i=snakeBody.size()-1; i>0; i--){ // 更新蛇身,前一個(顯示位置)賦給後一個 snakeBody.set(i, snakeBody.get(i-1)); } SnakeHead += numberOfRow; snakeBody.set(0, SnakeHead); // 蛇頭單獨算 if(AppleIndex == SnakeHead){ // 吃了蘋果 AppleIndex = (int) (Math.random()*100); snakeBody.add(snakeEndBuf); // 把蘋果加到蛇身尾部,蛇長+1(原尾部的蛇身已經前一個覆蓋掉) } for(int i=0; i<BoxDisplayFlag.length; i++){BoxDisplayFlag[i]=0;} // 清零 for(int i=0; i<snakeBody.size(); i++){ BoxDisplayFlag[(int) snakeBody.get(i)]=1; } frame.repaint(); // 刷新 } if(UPFlag == 1){ snakeEndBuf = (int) snakeBody.get(snakeBody.size()-1); for(int i=snakeBody.size()-1; i>0; i--){ snakeBody.set(i, snakeBody.get(i-1)); } SnakeHead -= numberOfRow; snakeBody.set(0, SnakeHead); if(AppleIndex == SnakeHead){ // 吃了蘋果 AppleIndex = (int) (Math.random()*100); snakeBody.add(snakeEndBuf); } for(int i=0; i<BoxDisplayFlag.length; i++){BoxDisplayFlag[i]=0;} // 清零 for(int i=0; i<snakeBody.size(); i++){ BoxDisplayFlag[(int) snakeBody.get(i)]=1; } frame.repaint(); // 刷新 } if(LeftFlag == 1){ snakeEndBuf = (int) snakeBody.get(snakeBody.size()-1); for(int i=snakeBody.size()-1; i>0; i--){ snakeBody.set(i, snakeBody.get(i-1)); } SnakeHead -= 1; snakeBody.set(0, SnakeHead); if(AppleIndex == SnakeHead){ // 吃了蘋果 AppleIndex = (int) (Math.random()*100); snakeBody.add(snakeEndBuf); } for(int i=0; i<BoxDisplayFlag.length; i++){BoxDisplayFlag[i]=0;} // 清零 for(int i=0; i<snakeBody.size(); i++){ BoxDisplayFlag[(int) snakeBody.get(i)]=1; } frame.repaint(); // 刷新 } if(RightFlag == 1){ snakeEndBuf = (int) snakeBody.get(snakeBody.size()-1); for(int i=snakeBody.size()-1; i>0; i--){ snakeBody.set(i, snakeBody.get(i-1)); } SnakeHead += 1; snakeBody.set(0, SnakeHead); if(AppleIndex == SnakeHead){ // 吃了蘋果 AppleIndex = (int) (Math.random()*100); snakeBody.add(snakeEndBuf); } for(int i=0; i<BoxDisplayFlag.length; i++){BoxDisplayFlag[i]=0;} // 清零 for(int i=0; i<snakeBody.size(); i++){ BoxDisplayFlag[(int) snakeBody.get(i)]=1; } frame.repaint(); // 刷新 } try{ Thread.sleep(100); // 控制運行速度 }catch (Exception ex){}; } } /* 本身的畫板panel */ class MyDrawPanel extends JPanel implements KeyListener { double width = 0, height = 0; public void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; double leftX = 0, topY = 0; for(int i=0; i<numberOfRow; i++){ width = (double) getWidth()/numberOfRow; height = (double) getHeight()/numberOfRow; g2.draw(new Line2D.Double(leftX+i*width, topY, leftX+i*width,numberOfRow*height));// 豎 g2.draw(new Line2D.Double(leftX, topY+i*height,numberOfRow*width, topY+i*height));// 行 } /* numberOfBox個Box,編號0-numberOfBox 查詢須要顯示的方格*/ for(int i=0; i<numberOfBox; i++){ if(BoxDisplayFlag[i] == 1){ width = (double) getWidth()/numberOfRow; height = (double) getHeight()/numberOfRow; topY =(double)(i / (numberOfRow)) * (double) getHeight() / numberOfRow; leftX =(double)(i % (numberOfRow)) * (double) getWidth() / numberOfRow; g2.fillRect((int)leftX,(int)topY,(int)width,(int)height); } } if(AppleDisplayFlag == 1){ // 蘋果能夠顯示 double topY_apple=0, leftX_apple=0; width = (double) getWidth()/numberOfRow; height = (double) getHeight()/numberOfRow; topY_apple =(double)(AppleIndex / (numberOfRow)) * (double) getHeight() / numberOfRow; leftX_apple =(double)(AppleIndex % (numberOfRow)) * (double) getWidth() / numberOfRow; g2.fillRect((int)leftX_apple,(int)topY_apple,(int)width,(int)height); System.out.println(AppleIndex); } } @Override public void keyTyped(KeyEvent e) { } @Override public void keyPressed(KeyEvent e) { // System.out.println("被按下"+ (char)e.getKeyCode()); // 測試 switch(e.getKeyCode()) { case KeyEvent.VK_UP: UPFlag =1; DownFlag = 0; LeftFlag = 0; RightFlag = 0; break; case KeyEvent.VK_DOWN: UPFlag =0; DownFlag = 1; LeftFlag = 0; RightFlag = 0; break; case KeyEvent.VK_LEFT: UPFlag =0; DownFlag = 0; LeftFlag = 1; RightFlag = 0; break; case KeyEvent.VK_RIGHT: UPFlag =0; DownFlag = 0; LeftFlag = 0; RightFlag = 1; break; } } @Override public void keyReleased(KeyEvent e) { } } }