zoukankan      html  css  js  c++  java
  • hello

    // snakemodel
    
    package mvctest;
    
     
    
    import javax.swing.*;
    
     
    
    import java.util.Arrays;
    
    import java.util.LinkedList;
    
    import java.util.Observable;
    
    import java.util.Random;
    
     
    
     
    
    class snakemodel extends Observable implements Runnable {
    
             boolean[][] matrix;                         // 指示位置上有没蛇体或食物
    
             LinkedList nodearray = new LinkedList();    // 蛇体
    
             node food;
    
             int maxx;
    
             int maxy;
    
             int direction = 2;                          // 蛇运行的方向
    
             boolean running = false;                    // 运行状态
    
     
    
             int timeinterval = 200;                     // 时间间隔,毫秒
    
             double speedchangerate = 0.75;              // 每次得速度变化率
    
             boolean paused = false;                     // 暂停标志
    
     
    
             int score = 0;                              // 得分
    
             int countmove = 0;                          // 吃到食物前移动的次数
    
     
    
             // up and down should be even
    
             // right and left should be odd
    
             public static final int up = 2;
    
             public static final int down = 4;
    
             public static final int left = 1;
    
             public static final int right = 3;
    
     
    
             public snakemodel( int maxx, int maxy) {
    
                 this.maxx = maxx;
    
                 this.maxy = maxy;
    
     
    
                 reset();
    
             }
    
     
    
             public void reset(){
    
                 direction = snakemodel.up;              // 蛇运行的方向
    
                 timeinterval = 200;                     // 时间间隔,毫秒
    
                 paused = false;                         // 暂停标志
    
                 score = 0;                              // 得分
    
                 countmove = 0;                          // 吃到食物前移动的次数
    
     
    
                 // initial matirx, 全部清0
    
                 matrix = new boolean[maxx][];
    
                 for (int i = 0; i < maxx; ++i) {
    
                     matrix[i] = new boolean[maxy];
    
                     Arrays.fill(matrix[i], false);
    
                 }
    
     
    
                 // initial the snake
    
                 // 初始化蛇体,如果横向位置超过20个,长度为10,否则为横向位置的一半
    
                 int initarraylength = maxx > 20 ? 10 : maxx / 2;
    
                 nodearray.clear();
    
                 for (int i = 0; i < initarraylength; ++i) {
    
                     int x = maxx / 2 + i;//maxx被初始化为20
    
                     int y = maxy / 2;    //maxy被初始化为30
    
                     //nodearray[x,y]: [10,15]-[11,15]-[12,15]~~[20,15]
    
                     //默认的运行方向向上,所以游戏一开始nodearray就变为:
    
                     //       [10,14]-[10,15]-[11,15]-[12,15]~~[19,15]
    
                     nodearray.addLast(new node(x, y));
    
                     matrix[x][y] = true;
    
                 }
    
     
    
                 // 创建食物
    
                 food = createfood();
    
                 matrix[food.x][food.y] = true;
    
             }
    
     
    
             public void changedirection(int newdirection) {
    
                 // 改变的方向不能与原来方向同向或反向
    
                 if (direction % 2 != newdirection % 2) {
    
                     direction = newdirection;
    
                 }
    
             }
    
     
    
             /**
    
              * 运行一次
    
              * @return
    
              */
    
             public boolean moveon() {
    
                 node n = (node) nodearray.getFirst();
    
                 int x = n.x;
    
                 int y = n.y;
    
     
    
                 // 根据方向增减坐标值
    
                 switch (direction) {
    
                     case up:
    
                         y--;
    
                         break;
    
                     case down:
    
                         y++;
    
                         break;
    
                     case left:
    
                         x--;
    
                         break;
    
                     case right:
    
                         x++;
    
                         break;
    
                 }
    
     
    
                 // 如果新坐标落在有效范围内,则进行处理
    
                 if ((0 <= x && x < maxx) && (0 <= y && y < maxy)) {
    
                 
    
                     if (matrix[x][y]) {        // 如果新坐标的点上有东西(蛇体或者食物)
    
                         if (x == food.x && y == food.y) {       // 吃到食物,成功
    
                             nodearray.addFirst(food);           // 从蛇头赠长
    
     
    
                             // 分数规则,与移动改变方向的次数和速度两个元素有关
    
                             int scoreget = (10000 - 200 * countmove) / timeinterval;
    
                             score += scoreget > 0 ? scoreget : 10;
    
                             countmove = 0;
    
     
    
                             food = createfood();                // 创建新的食物
    
                             matrix[food.x][food.y] = true;      // 设置食物所在位置
    
                             return true;
    
                         } else                                  // 吃到蛇体自身,失败
    
                             return false;
    
                        
    
                     } else {                 // 如果新坐标的点上没有东西(蛇体),移动蛇体
    
                         nodearray.addFirst(new node(x, y));
    
                         matrix[x][y] = true;
    
                         n = (node) nodearray.removeLast();
    
                         matrix[n.x][n.y] = false;
    
                         countmove++;
    
                         return true;
    
                     }
    
                 }
    
                 return false;                                   // 触到边线,失败
    
             }
    
     
    
             public void run() {
    
                 running = true;
    
                 while (running) {
    
                     try {
    
                         Thread.sleep(timeinterval);
    
                     } catch (Exception e) {
    
                         break;
    
                     }
    
     
    
                     if (!paused) {
    
                         if (moveon()) {
    
                             setChanged();           // model通知view数据已经更新
    
                             notifyObservers();
    
                         } else {
    
                             JOptionPane.showMessageDialog(null,
    
                                     "you failed",
    
                                     "game over",
    
                                     JOptionPane.INFORMATION_MESSAGE);
    
                             break;
    
                         }
    
                     }
    
                 }
    
                 running = false;
    
             }
    
     
    
             private node createfood() {
    
                 int x = 0;
    
                 int y = 0;
    
                 // 随机获取一个有效区域内的与蛇体和食物不重叠的位置
    
                 do {
    
                     Random r = new Random();
    
                     x = r.nextInt(maxx);
    
                     y = r.nextInt(maxy);
    
                 } while (matrix[x][y]);
    
     
    
                 return new node(x, y);
    
             }
    
     
    
             public void speedup() {
    
                 timeinterval *= speedchangerate;
    
             }
    
     
    
             public void speeddown() {
    
                 timeinterval /= speedchangerate;
    
             }
    
     
    
             public void changepausestate() {
    
                 paused = !paused;
    
             }
    
     
    
             public String tostring() {
    
                 String result = "";
    
                 for (int i = 0; i < nodearray.size(); ++i) {
    
                     node n = (node) nodearray.get(i);
    
                     result += "[" + n.x + "," + n.y + "]";
    
                 }
    
                 return result;
    
             }
    
          }
    
     
    
          class node {
    
             int x;
    
             int y;
    
     
    
             node(int x, int y) {
    
                 this.x = x;
    
                 this.y = y;
    
             }
    
          }
    
     
    
     
    
     
    
     
    
     
    
     
    
     
    
     
    
     
    
     
    
     
    
     
    
     
    
     
    
    // snakeview
    
     
    
    package mvctest;
    
     
    
    import javax.swing.*;
    
     
    
    import java.awt.*;
    
    import java.util.Iterator;
    
    import java.util.LinkedList;
    
    import java.util.Observable;
    
    import java.util.Observer;
    
     
    
    /**
    
    * mvc模式中得viewer,只负责对数据的显示,而不用理会游戏的控制逻辑
    
    */
    
    public class snakeview implements Observer {
    
       snakecontrol control = null;
    
       snakemodel model = null;
    
     
    
       JFrame mainframe;
    
       Canvas paintcanvas;
    
       JLabel labelscore;
    
     
    
       public static final int canvaswidth = 200;
    
       public static final int canvasheight = 300;
    
     
    
       public static final int nodewidth = 10;
    
       public static final int nodeheight = 10;
    
     
    
       JMenuBar jMenuBar = new JMenuBar();
    
       JMenu jMenu = new JMenu("menu");
    
       JMenuItem reset = new JMenuItem("reset");
    
       JMenuItem newgame = new JMenuItem("newgame");
    
      
    
      
    
     
    
      
    
       public snakeview(snakemodel model, snakecontrol control) {
    
           this.model = model;
    
           this.control = control;
    
     
    
           mainframe = new JFrame("greedsnake");
    
     
    
           Container cp = mainframe.getContentPane();
    
           jMenuBar.add(jMenu);
    
           jMenu.add(reset);
    
           jMenu.add(newgame);
    
          
    
           // 创建顶部的分数显示
    
           labelscore = new JLabel("score:");
    
           cp.add(labelscore, BorderLayout.NORTH);
    
     
    
           // 创建中间的游戏显示区域
    
           paintcanvas = new Canvas();
    
           paintcanvas.setSize(canvaswidth + 1, canvasheight + 1);
    
           paintcanvas.addKeyListener(control);
    
           cp.add(paintcanvas, BorderLayout.CENTER);
    
     
    
           // 创建底下的帮助栏
    
           JPanel panelbuttom = new JPanel();
    
           panelbuttom.setLayout(new BorderLayout());
    
           JLabel labelhelp;
    
           labelhelp = new JLabel("pageup, pagedown for speed;", JLabel.CENTER);
    
           panelbuttom.add(labelhelp, BorderLayout.NORTH);
    
           labelhelp = new JLabel("enter or r or s for start;", JLabel.CENTER);
    
           panelbuttom.add(labelhelp, BorderLayout.CENTER);
    
           labelhelp = new JLabel("space or p for pause", JLabel.CENTER);
    
           panelbuttom.add(labelhelp, BorderLayout.SOUTH);
    
           cp.add(panelbuttom, BorderLayout.SOUTH);
    
     
    
           mainframe.addKeyListener(control);
    
           mainframe.pack();
    
           mainframe.setResizable(false);
    
           mainframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
           mainframe.setVisible(true);
    
       }
    
     
    
       void repaint() {
    
           Graphics g = paintcanvas.getGraphics();
    
     
    
           //draw background
    
           g.setColor(Color.white);
    
           g.fillRect(0, 0, canvaswidth, canvasheight);
    
     
    
           // draw the snake
    
           g.setColor(Color.black);
    
           LinkedList na = model.nodearray;
    
           Iterator it = na.iterator();
    
           while (it.hasNext()) {
    
               node n = (node) it.next();
    
               drawnode(g, n);
    
           }
    
     
    
           // draw the food
    
           g.setColor(Color.red);
    
           node n = model.food;
    
           drawnode(g, n);
    
     
    
           updatescore();
    
       }
    
     
    
       private void drawnode(Graphics g, node n) {
    
           g.fillRect(n.x * nodewidth,
    
                   n.y * nodeheight,
    
                   nodewidth - 1,
    
                   nodeheight - 1);
    
       }
    
     
    
       public void updatescore() {
    
           String s = "score: " + model.score;
    
           labelscore.setText(s);
    
       }
    
     
    
       public void update(Observable o, Object arg) {
    
           repaint();
    
       }
    
    }
    
     
    
     
    
     
    
    // snakecontrol
    
    package mvctest;
    
     
    
    import java.awt.event.KeyEvent;
    
    import java.awt.event.KeyListener;
    
     
    
    /**
    
    * mvc中的controler,负责接收用户的操作,并把用户操作通知model
    
    */
    
    public class snakecontrol  implements KeyListener{
    
       snakemodel model;
    
     
    
       public snakecontrol(snakemodel model){
    
           this.model = model;
    
       }
    
     
    
    @Override
    
    public void keyPressed(KeyEvent e) {
    
          // TODO Auto-generated method stub
    
           int keycode = e.getKeyCode();
    
         if (model.running){                // 运行状态下,处理的按键
    
             switch (keycode) {
    
                 case KeyEvent.VK_UP:
    
                     model.changedirection(snakemodel.up);
    
                     break;
    
                 case KeyEvent.VK_DOWN:
    
                     model.changedirection(snakemodel.down);
    
                     break;
    
                 case KeyEvent.VK_LEFT:
    
                     model.changedirection(snakemodel.left);
    
                     break;
    
                 case KeyEvent.VK_RIGHT:
    
                     model.changedirection(snakemodel.right);
    
                     break;
    
                 case KeyEvent.VK_ADD:
    
                 case KeyEvent.VK_PAGE_UP:
    
                     model.speedup();
    
                     break;
    
                 case KeyEvent.VK_SUBTRACT:
    
                 case KeyEvent.VK_PAGE_DOWN:
    
                     model.speeddown();
    
                     break;
    
                 case KeyEvent.VK_SPACE:
    
                 case KeyEvent.VK_P:
    
                     model.changepausestate();
    
                     break;
    
                 default:
    
             }
    
         }
    
     
    
         // 任何情况下处理的按键,按键导致重新启动游戏
    
         if (keycode == KeyEvent.VK_R ||
    
                 keycode == KeyEvent.VK_S ||
    
                 keycode == KeyEvent.VK_ENTER) {
    
             model.reset();
    
         }
    
    }
    
     
    
    @Override
    
    public void keyReleased(KeyEvent e) {
    
          // TODO Auto-generated method stub
    
         
    
    }
    
     
    
    @Override
    
    public void keyTyped(KeyEvent e) {
    
          // TODO Auto-generated method stub
    
         
    
    }
    
    }
    
     
    
     
    
     
    
    // greedSnake
    
    package mvctest;
    
     
    
    public class greedSnake {
    
          public static void main(String[] args) {
    
               snakemodel model = new snakemodel(20,30);
    
                snakecontrol control = new snakecontrol(model);
    
                snakeview view = new snakeview(model,control);
    
                //添加一个观察者,让view成为model的观察者
    
                model.addObserver(view);
    
               
    
                (new Thread(model)).start();
    
     
    
          }
    
    }
  • 相关阅读:
    ABP框架系列之六:(Value-Objects-值对象)
    ElementUI如何展开指定Tree树节点
    JS如何将变量作为一个对象的Key
    分布式追踪系统架构与设计
    11.浅聊几种主流Docker网络的实现原理
    Python连接MongoDB数据库并执行操作
    1.ZooKeeper ACL权限控制
    Pika 连接 rabbitmq 集群
    js for等循环 跳出多层循环
    Django ForeignKey不需要参照完整性?
  • 原文地址:https://www.cnblogs.com/liangweixiong/p/6457917.html
Copyright © 2011-2022 走看看