嘿嘿 新手来 表现了!!! 2019年结束
游戏截图:
文件布局:
代码分享
用到的一些全局变量
//全局变量
public class Global {public static final int RECT_WIDTH=20;//每个小方格的长宽public static final int WIDTH=30;//长 40个小方格public static final int HEIGHT=30;//宽 40个小方格public static int GRADE;//成绩public static long TIME;//时间public static File file;//文件夹
}
定义蛇类
public class Snake {private SnakeListener snakeListener;public static final int UP=1;public static final int DOWN=-1;public static final int LEFT=2;public static final int RIGHT=-2;//表示蛇运动的方向private int newdirction=RIGHT;private int olddirction=RIGHT;private Point tail;//存储蛇的尾巴public LinkedList<Point> body=new LinkedList<Point>();private Point p;//蛇的颜色private int x,y,z;private boolean suspendFlag = false;// 控制线程的执行private SnakeDriver sd=new SnakeDriver();public static boolean life=true;public Snake(){init();}//获取蛇的长度public int getlenght() {return body.size();}public void init() {int x=Global.WIDTH/2;int y=Global.HEIGHT/2;for(int i=0;i<3;i++) {p=new Point(x-i,y);//默认方向是向右的body.add(p);}}public void move() {
// System.out.println("蛇在移动...");//去尾加头法实现蛇移动 首先要得到蛇头tail=body.removeLast();int x=getSnakehead().x;int y=getSnakehead().y;if(this.newdirction+this.olddirction!=0)this.olddirction=this.newdirction; //控制方向不往反方向行走switch(olddirction) {case UP:y--;break;case DOWN:y++;break;case LEFT:x--;break;case RIGHT:x++;break;}body.addFirst(new Point(x,y));}//得到蛇头位置public Point getSnakehead() {return body.getFirst();}public void eatfood() {
// System.out.println("蛇正在吃食物...");//怎么吃 就是将蛇的尾巴加回来 则用变量存储蛇的尾巴body.addLast(tail);}public void changedirction(int dirction) {this.newdirction=dirction;
// System.out.println("正在改变方向...");}public boolean iseatself(Snake snake) {Point head=snake.getSnakehead();for(int i=1;i<body.size();i++){if(body.get(i).equals(head))return true;}return false;}public void drowMe(Graphics g) {
// System.out.println("蛇正在画出自己...");//g.setColor(Color.blue);for(int i=0;i<body.size();i++) {x=(int) (Math.random()*256);y=(int) (Math.random()*256);z=(int) (Math.random()*256);Color color=new Color(x,y,z);g.setColor(color);g.fillRect(body.get(i).x*Global.RECT_WIDTH, body.get(i).y*Global.RECT_WIDTH, Global.RECT_WIDTH, Global.RECT_WIDTH);}}//增加了自定义的监听器public void addSnakeListener(SnakeListener snakeListener) {if(snakeListener!=null){this.snakeListener=snakeListener;}}public void start() {
// new SnakeDriver().start();sd.start();}//得到线程对象public SnakeDriver getsd() {return sd;}//线程暂停public void suspend() {suspendFlag=true;}public class SnakeDriver extends Thread{//唤醒线程public synchronized void Rouse() {suspendFlag=false;notify();}@Overridepublic void run() {while(life){move();//每移动一次要判断是否吃到食物和墙snakeListener.snakeMove(Snake.this);//调用外部类的当前对象try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}synchronized(this) {while(suspendFlag) {try {wait();} catch (InterruptedException e) {e.printStackTrace();}}}}}}
}
定义食物类
public class Food {//定义两变量来存储food的位置private int x,y;public void drowMe(Graphics g) {
// System.out.println("食物正在画出自己...");g.setColor(Color.red);g.fillRect(x*Global.RECT_WIDTH,y*Global.RECT_WIDTH, Global.RECT_WIDTH,Global.RECT_WIDTH);}public boolean iseatbysnake(Snake snake) {//怎么判断食物被蛇吃了 判断是否在同一位置Point head=snake.getSnakehead();Point p=new Point(x,y);if(p.equals(head))return true;return false;}//增加食物public void addFood(Point p) {x=p.x;y=p.y;}//设置food的位置public Point setloction() {int x=(int)(Math.random()*30)+1;int y=(int)(Math.random()*30)+1;return new Point(x,y);}
}
定义地图类
public class Map {private int[][] map=new int[Global.WIDTH+2][Global.HEIGHT+2];//存储边框的数据位置public Map() {for(int y=0;y<Global.HEIGHT+2;y++){for(int x=0;x<Global.WIDTH+2;x++){if(y==0||y==Global.HEIGHT+2-1)map[x][y]=1;if(x==0||x==Global.WIDTH+2-1)map[x][y]=1;}}}public void drowMe(Graphics g) {
// System.out.println("正在画出地图...");SetRectangle(g);}public boolean iseatbysnake(Snake snake) {Point head=snake.getSnakehead();for(int k=0;k<Global.WIDTH+2;k++) {for(int m=0;m<Global.HEIGHT+2;m++) {if(map[k][m]==1&&head.x==k&&head.y==m)return true;}}return false;}private void SetRectangle(Graphics g){Graphics2D gp=(Graphics2D)g;Rectangle2D rect=new Rectangle2D.Double(20, 20, 600, 600);Stroke s=new BasicStroke(5);gp.setStroke(s);gp.draw(rect);}
}
//定义接口用来监听Snake是否碰撞
public interface SnakeListener {public void snakeMove(Snake snake);
}
GUI显示
public class GamePanel extends JPanel{private Snake snake=new Snake();private Food food;private Map map;private int x,y,z;private JLabel label; private JLabel explain1;private JLabel explain2;private JLabel explain3;private JLabel explain4;private JLabel explain5;private JLabel grade;private JLabel time;private long endtime;//时间public static long TIME;//最终显示时间public static int GRADE;//最终显示分数private JLabel bgm_label;private BufferedImage img=null;private Font font=new Font("宋体",Font.PLAIN,20);public GamePanel() {setLayout(null);//加入说明Count() ;//加入图片addBgm();}public void dispaly(Snake snake,Food food,Map map) {
// System.out.println("面板正在画出自己...");this.snake=snake;this.food=food;this.map=map;repaint(); //自动调用了paintComponent方法}@Overrideprotected void paintComponent(Graphics g) {super.paintComponent(g);SetLine(g);drawNum(g);if(food!=null)food.drowMe(g);if(map!=null)map.drowMe(g);if(snake!=null)snake.drowMe(g);}private void drawNum(Graphics g) {//分数g.setColor(Color.black);g.setFont(new Font("宋体",Font.PLAIN,36));Global.GRADE=(snake.getlenght()-3)*5;g.drawString(""+Global.GRADE+"", 720, 330);//时间endtime=System.currentTimeMillis();Global.TIME=(endtime-Controller.starttime)/1000;g.drawString(""+Global.TIME+""+"秒", 720, 390);}private void SetLine(Graphics g){Graphics2D gl=(Graphics2D)g;Stroke s=new BasicStroke();gl.setStroke(s);for(int i=1;i<30;i++){
// x=(int) (Math.random()*256);
// y=(int) (Math.random()*256);
// z=(int) (Math.random()*256);
// Color color=new Color(x,y,z);x=154;//222y=157;//225z=162;//230Color color=new Color(x,y,z);gl.setColor(color);Line2D Virtical_L=new Line2D.Double(Global.RECT_WIDTH*i+20, 20, Global.RECT_WIDTH*i+20, 620);gl.draw(Virtical_L);Line2D Level_L=new Line2D.Double(20, Global.RECT_WIDTH*i+20, 620, Global.RECT_WIDTH*i+20);gl.draw(Level_L);}}public void Count() {label=new JLabel("版权:12210");label.setLocation(630, 20);label.setSize(200, 50);label.setFont(font);add(label);//解释explain1=new JLabel("说明:↑ ↓ ← →键");explain2=new JLabel("控制方向");explain3=new JLabel("暂停:Space");explain4=new JLabel("继续:Enter");explain5=new JLabel("退出:Esc");explain1.setBounds(630, 90, 200,20);explain2.setBounds(630, 130, 200, 20);explain3.setBounds(630, 170, 200, 20);explain4.setBounds(630, 210, 200, 20);explain5.setBounds(630, 250, 200, 20);explain1.setFont(font);explain2.setFont(font);explain3.setFont(font);explain4.setFont(font);explain5.setFont(font);add(explain1);add(explain2);add(explain3);add(explain4);add(explain5);//分数grade=new JLabel("分数:");grade.setBounds(630, 300, 100, 30);grade.setFont(new Font("宋体",Font.PLAIN,30));add(grade);//时间time=new JLabel("时间:");time.setBounds(630, 360, 100, 30);time.setFont(new Font("宋体",Font.BOLD,30));add(time);}//加入图片public void addBgm() {try {img=ImageIO.read(new File("bgm.png"));} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}bgm_label=new JLabel(new ImageIcon(img));bgm_label.setBounds(630,400,img.getWidth(),img.getHeight());add(bgm_label);}
}
控制游戏
public class Controller extends KeyAdapter implements SnakeListener{private Snake snake;private Food food;private Map map;private GamePanel gamepanel;public static long starttime;//开始游戏时间public Controller(Snake snake, Food food, Map map, GamePanel gamepanel) {super();this.snake = snake;this.food = food;this.map = map;this.gamepanel = gamepanel;}@Overridepublic void keyPressed(KeyEvent e) {super.keyPressed(e);
// System.out.println("改变方向...");switch(e.getKeyCode()) {case KeyEvent.VK_UP:snake.changedirction(Snake.UP);break;case KeyEvent.VK_DOWN:snake.changedirction(Snake.DOWN);break;case KeyEvent.VK_RIGHT:snake.changedirction(Snake.RIGHT);break;case KeyEvent.VK_LEFT:snake.changedirction(Snake.LEFT);break;case KeyEvent.VK_SPACE:snake.suspend();break;case KeyEvent.VK_ESCAPE:System.exit(0);break;default:snake.getsd().Rouse();break;}}@Overridepublic void snakeMove(Snake snake) {
// System.out.println("判断是否迟到食物或墙...");if(food.iseatbysnake(snake)==true) {snake.eatfood();//增加新的食物位置food.addFood(food.setloction());}if(map.iseatbysnake(snake)) {JOptionPane.showMessageDialog(null, "傻瓜,撞到墙啦!");Snake.life=false;JOptionPane.showMessageDialog(null, "分数:"+""+Global.GRADE+""+"分"+" "+"耗时:"+""+Global.TIME+""+"秒");System.exit(0);}if(snake.iseatself(snake)) {JOptionPane.showMessageDialog(null, "傻瓜,吃到自己啦!");Snake.life=false;JOptionPane.showMessageDialog(null, "分数:"+""+Global.GRADE+""+"分"+" "+"耗时:"+""+Global.TIME+""+"秒");System.exit(0);}gamepanel.dispaly(snake, food, map);;}public void startGame() {starttime=System.currentTimeMillis();snake.start();food.addFood(food.setloction());}
}
主程序
class Window extends JFrame{private Snake snake=new Snake();private Food food=new Food();private Map map=new Map();private GamePanel gamepanel=new GamePanel();private Controller controller=new Controller(snake, food, map, gamepanel);//背景音乐的变量private URI uri;private URL url;//增加文字JLabel label;public Window(){this.setBounds(100, 100, 900, 680);this.setTitle("贪吃蛇 version2.0");this.setResizable(false);this.setDefaultCloseOperation(EXIT_ON_CLOSE);snake.addSnakeListener(controller);gamepanel.addKeyListener(controller);gamepanel.setFocusable(true);this.add(gamepanel);this.setVisible(true);music();controller.startGame();}//添加背景音乐public void music() {System.out.println("运行了!");try{File f=new File("周二珂 - 告白气球.wav");uri=f.toURI();url=uri.toURL();AudioClip auu=Applet.newAudioClip(url);auu.loop();}catch(Exception e) {e.printStackTrace();}}
}
class GameThread extends Thread{@Overridepublic void run() {new Window();}
}
public class Client{public static void main(String[] args) throws UnknownHostException, IOException {
// Socket socket=new Socket("127.0.0.1",9999);new GameThread().start();
// Operation ope=new Operation();
// ope.Write(socket);
// ope.Read();
// socket.close(); }}
嘿嘿 新手 看视频学的 加油2020年
应该能执行成功的
源码下载