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) { } } }