欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java贪吃蛇极速版

程序员文章站 2024-03-07 20:10:09
本文为大家推荐了一款由java实现经典小游戏:贪吃蛇,相信大家都玩过,如何实现的呐? 效果图: 废话不多说,直接奉上代码: 1、 public cl...

本文为大家推荐了一款由java实现经典小游戏:贪吃蛇,相信大家都玩过,如何实现的呐?

效果图:

java贪吃蛇极速版

java贪吃蛇极速版

废话不多说,直接奉上代码:

1、

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();
  }
}

2、

package mvctest;

//snakecontrol.java
import java.awt.event.keyevent;
import java.awt.event.keylistener;


public class snakecontrol implements keylistener{
  snakemodel model;

  public snakecontrol(snakemodel model){
    this.model = model;
  }

  public void keypressed(keyevent e) {
    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();
    }
  }

  public void keyreleased(keyevent e) {
  }

  public void keytyped(keyevent e) {
  }
}

3、

package mvctest;


//snakemodel.java
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;
    }
  }

  
  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;
  }
}

4、

package mvctest;

//snakeview.java
import javax.swing.*;
import java.awt.*;
import java.util.iterator;
import java.util.linkedlist;
import java.util.observable;
import java.util.observer;


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;

  public snakeview(snakemodel model, snakecontrol control) {
    this.model = model;
    this.control = control;

    mainframe = new jframe("greedsnake");

    container cp = mainframe.getcontentpane();

    // 创建顶部的分数显示
    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();
  }
}

本文的目的就是带着大家回味经典,但是更主要的目的就是帮助大家学习好java程序设计。