疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java版贪吃蛇小游戏的实现


 

  

  使用的IDE eclipse

  JDK版本 1.6

  辅助类 Coordinate.java

  package com.nn.util;

  /**

  *坐标点

  */

  public class Coordinate {

  public int x;

  public int y;

  public Coordinate(int newX, int newY) {

  x = newX;

  y = newY;

  }

  public boolean equals(Coordinate other) {

  if (x == other.x && y == other.y) {

  return true;

  }

  return false;

  }

  @Override

  public String toString() {

  return "Coordinate: [" + x + "," + y + "]";

  }

  }

  接口 Direction

  package com.nn.entity;

  public interface Direction {

  public class Dir{

  public static final int UP = 1;

  public static final int DOWN = 2;

  public static final int LEFT = 3;

  public static final int RIGHT = 4;

  }

  }

  实体类 Snake.java

  package com.nn.entity;

  import java.util.ArrayList;

  import com.nn.entity.Direction.Dir;

  import com.nn.util.Coordinate;

  public class Snake{

  //小方块x坐标

  private int x;

  //小方块y坐标

  private int y;

  //宽度

  public static final int TILE_W = 10;

  //高度

  public static final int TILE_H = 10;

  //下一个方向

  private int mNextDirection = Dir.RIGHT;

  //游戏是否结束

  private boolean isEnd;

  //存放贪吃蛇

  private ArrayList mSnakeTrail = new ArrayList();

  //存放豆子

  private ArrayList mAppleList = new ArrayList();

  public Snake()

  {

  initNewGame();

  }

  //初始化新游戏

  public void initNewGame()

  {

  //初始化蛇身

  mSnakeTrail.add(new Coordinate(5, 7));

  mSnakeTrail.add(new Coordinate(6, 7));

  mSnakeTrail.add(new Coordinate(7, 7));

  mSnakeTrail.add(new Coordinate(8, 7));

  mSnakeTrail.add(new Coordinate(9, 7));

  mSnakeTrail.add(new Coordinate(10, 7));

  //初始化豆子

  mAppleList.add(new Coordinate(20,3));

  //设置初始状态为false

  isEnd = false;

  }

  public ArrayList getmSnakeTrail() {

  return mSnakeTrail;

  }

  public ArrayList getmAppleList() {

  return mAppleList;

  }

  public boolean isEnd() {

  return isEnd;

  }

  public int getmNextDirection() {

  return mNextDirection;

  }

  public void setEnd(boolean isEnd) {

  this.isEnd = isEnd;

  }

  }

  frame类 继承JFrame SnakeFrame.java

  package com.nn.ui;

  import java.awt.Dimension;

  import java.awt.Toolkit;

  import javax.swing.JFrame;

  /**

  *游戏界面

  */

  public class SnakeFrame extends JFrame{

  private static final long serialVersionUID = 1L;

  //宽度

  private static final int width = 530;

  //高度

  private static final int height = 450;

  //高度偏移量

  private static final int offset = 15;

  public SnakeFrame(){

  init();

  }

  /**

  * 初始化游戏界面

  */

  private void init()

  {

  this.setTitle("Java版贪吃蛇_1.0");

  //frame的高度 宽度

  this.setSize(width, height);

  //窗口居中显示

  Toolkit toolkit = Toolkit.getDefaultToolkit();

  Dimension screen = toolkit.getScreenSize();

  int w = screen.width;

  int h = screen.height;

  //计算左上角坐标点的x y值

  this.setLocation((w-this.getWidth())/2, (h-this.getHeight())/2-offset);

  //设置默认关闭的操作

  this.setDefaultCloseOperation(EXIT_ON_CLOSE);

  //设置窗口大小不可改变

  this.setResizable(false);

  //设置可见性

  this.setVisible(true);

  this.setLayout(null);

  }

  }

  panel j继承JPanel SnakePanel.java

  package com.nn.ui;

  import java.awt.Color;

  import java.awt.Font;

  import java.awt.Graphics;

  import java.awt.event.ActionEvent;

  import java.awt.event.ActionListener;

  import java.util.ArrayList;

  import javax.swing.JButton;

  import javax.swing.JPanel;

  import com.nn.control.PlayControl;

  import com.nn.entity.Snake;

  import com.nn.util.Coordinate;

  public class SnakePanel extends JPanel{

  private static final long serialVersionUID = 1L;

  //panel的宽度

  private static final int width = 400;

  //panel的高度

  private static final int height = 400;

  //坐标点x

  private static final int x = 10;

  //坐标点y

  private static final int y = 10;

  //方块尺寸

  private static final int SIZE = 10;

  //是否开启网格

  private boolean isOpen = false;

  private Snake snake;

  //开启作弊

  private JButton girdButton;

  private JButton aboutButton;

  //暂停 继续按钮

  private JButton PauseButton;

  //重新开始游戏

  private JButton StartButton;

  public Snake getSnake() {

  return snake;

  }

  private ArrayList mSnakeTrail = null;

  private ArrayList mAppleList = null;

  public SnakePanel() {

  snake = new Snake();

  this.setLayout(null);

  StartButton = new JButton("重新开始");

  StartButton.setLocation(420,100);

  StartButton.setSize(90,26);

  this.add(StartButton);

  PauseButton = new JButton("暂停游戏");

  PauseButton.setLocation(420, 150);

  PauseButton.setSize(90,26);

  this.add(PauseButton);

  girdButton = new JButton("开启网格");

  girdButton.setLocation(420, 200);

  girdButton.setSize(90,26);

  this.add(girdButton);

  aboutButton = new JButton("关于游戏");

  aboutButton.setLocation(420, 250);

  aboutButton.setSize(90,26);

  this.add(aboutButton);

  girdButton.addActionListener(new GirdActionListener());

  aboutButton.addActionListener(new AboutActionListerner());

  }

  class GirdActionListener implements ActionListener{

  int i = 1;

  public void actionPerformed(ActionEvent e) {

  if(i%2==1)

  {

  girdButton.setText("关闭网格");

  isOpen = false;

  i++;

  }

  else if(i%2==0){

  girdButton.setText("开启网格");

  isOpen = true;

  i++;

  }

  }

  }

  class AboutActionListerner implements ActionListener{

  public void actionPerformed(ActionEvent e) {

  }

  }

  @Override

  public void paintComponent(Graphics g) {

  super.paintComponent(g);

  creatGameWindow(g);

  if(snake.isEnd())

  {

  paintWords(g);

  }

  //将焦点定在Jpanel上

  this.requestFocus();

  }

  /**

  * 安装玩家控制器

  * @param control

  */

  public void setGameControl(PlayControl control){

  this.addKeyListener(control);

  }

  private void creatGameWindow(Graphics g) {

  g.setColor(Color.BLACK);

  g.drawRect(x, y, width, height);

  g.setColor(Color.WHITE);

  g.fillRect(x+1, y+1, width-1, height-1);

  g.setColor(Color.GRAY);

  /***************test******************/

  paintLine(g);

  /***************test******************/

  mSnakeTrail = snake.getmSnakeTrail();

  mAppleList = snake.getmAppleList();

  if(mSnakeTrail==null)

  {

  return;

  }

  g.setColor(Color.BLACK);

  for(int i=0;i

  g.fillRect(this.x+mSnakeTrail.get(i).x*SIZE, this.y+mSnakeTrail.get

  (i).y*SIZE, Snake.TILE_W, Snake.TILE_H);

  }

  //画豆子

  g.fillRect(this.x+mAppleList.get(0).x*SIZE, this.y+mAppleList.get(0).y*SIZE,

  Snake.TILE_W, Snake.TILE_H);

  }

  //画网格

  private void paintLine(Graphics g)

  {

  for(int i = 1;i < 40;i++)

  {

  g.drawLine(this.x, i*10+this.y, 400+this.x, i*10+this.y);

  }

  for(int i = 1;i < 40;i++)

  {

  g.drawLine(i*10+this.x,this.y,i*10+this.x,400+this.y);

  }

  }

  //结束提示

  private void paintWords(Graphics g){

  Font font = new Font("宋体", Font.BOLD, 64);

  g.setFont(font);

  g.setColor(Color.RED);

  g.drawString("游戏结束",60,220);

  }

  }

  最关键的类 控制类 PlayControl.java

  package com.nn.control;

  import java.awt.event.KeyEvent;

  import java.awt.event.KeyListener;

  import java.util.ArrayList;

  import java.util.Random;

  import com.nn.entity.Direction.Dir;

  import com.nn.ui.SnakePanel;

  import com.nn.util.Coordinate;

  public class PlayControl implements KeyListener{

  private SnakePanel panel;

  //蛇头在list中索引

  private int headIndex;

  /**

  * 贪吃蛇列表

  */

  ArrayList mSnakeTrail;

  /*

  * 豆子列表

  */

  private ArrayList mAppleList;

  //新产生的豆子

  Coordinate newCoordinate;

  private int mNextDirection;

  //是否绘制出结束提示

  private boolean isDraw = false;

  private Random random = new Random();

  public PlayControl(SnakePanel panel)

  {

  this.panel = panel;

  mSnakeTrail = panel.getSnake().getmSnakeTrail();

  mAppleList = panel.getSnake().getmAppleList();

  mNextDirection = panel.getSnake().getmNextDirection();

  headIndex = mSnakeTrail.size()-1;

  Thread thread = new Thread(runnable);

  thread.start();

  }

  //响应键盘按下事件

  public void keyPressed(KeyEvent e) {

  if(isDraw){

  return;

  }

  switch (e.getKeyCode()) {

  case KeyEvent.VK_UP:

  if(mNextDirection!=Dir.DOWN)

  {

  mNextDirection = Dir.UP;

  //moveUp();

  }

  break;

  case KeyEvent.VK_DOWN:

  if(mNextDirection!=Dir.UP)

  {

  mNextDirection = Dir.DOWN;

  //moveDown();

  }

  break;

  case KeyEvent.VK_LEFT:

  if(mNextDirection!=Dir.RIGHT)

  {

  mNextDirection = Dir.LEFT;

  //moveLeft();

  }

  break;

  case KeyEvent.VK_RIGHT:

  if(mNextDirection!=Dir.LEFT)

  {

  mNextDirection = Dir.RIGHT;

  //moveRight();

  }

  break;

  }

  }

  @Override

  public void keyReleased(KeyEvent e) {

  }

  @Override

  public void keyTyped(KeyEvent e) {

  }

  //向上移动

  private void moveUp()

  {

  if(!isEndGame()){

  //每移动一次 先在头部加一块 list增加一个元素

  mSnakeTrail.add(new Coordinate(mSnakeTrail.get(headIndex).x, mSnakeTrail.get

  (headIndex).y-1));

  //如果判断吃到豆子

  if(isEat()){

  //吃到豆子的处理

  afterEatApple();

  }

  //否则 移除第一个元素

  else {

  mSnakeTrail.remove(0);

  }

  //重新绘制

  panel.repaint();

  }

  }

  //向下移动

  private void moveDown()

  {

  if(!isEndGame()){

  mSnakeTrail.add(new Coordinate(mSnakeTrail.get(headIndex).x, mSnakeTrail.get

  (headIndex).y+1));

  if(isEat()){

  afterEatApple();

  }

  else {

  mSnakeTrail.remove(0);

  }

  panel.repaint();

  }

  }

  //向左移动

  private void moveLeft()

  {

  if(!isEndGame()){

  mSnakeTrail.add(new Coordinate(mSnakeTrail.get(headIndex).x-1,

  mSnakeTrail.get(headIndex).y));

  if(isEat())

  {

  afterEatApple();

  }

  else {

  mSnakeTrail.remove(0);

  }

  panel.repaint();

  }

  }

  //向右移动

  private void moveRight()

  {

  if(!isEndGame()){

  mSnakeTrail.add(new Coordinate(mSnakeTrail.get(headIndex).x+1,

  mSnakeTrail.get(headIndex).y));

  if(isEat())

  {

  afterEatApple();

  }

  else {

  mSnakeTrail.remove(0);

  }

  panel.repaint();

  }

  }

  //增加一个坐标点到存放蛇的list 添加到list的末尾

  private void afterEatApple(){

  //每增加一个 索引值加1 重新开始游戏时要回复初始值

  headIndex++;

  mAppleList.add(new Coordinate(random.nextInt(40), random.nextInt(40)));

  mAppleList.remove(0);

  newCoordinate = mAppleList.get(0);

  //System.out.println("蛇身长度:"+mSnakeTrail.size());

  }

  //判断蛇是否吃到豆子

  private boolean isEat()

  {

  return mSnakeTrail.get(mSnakeTrail.size()-1).equals(mAppleList.get(0));

  }

  //判断是否到边界或者碰到自己的身体

  private boolean isEndGame(){

  int x = mSnakeTrail.get(headIndex).x;

  int y = mSnakeTrail.get(headIndex).y;

  if(touchBody()||x<0||x>39||y<0||y>39){

  afterEndGame();

  return true;

  }

  return false;

  }

  //碰到自己身体

  private boolean touchBody(){

  for(int i =0;i

  {

  if(mSnakeTrail.get(headIndex).equals(mSnakeTrail.get(i))){

  return true;

  }

  }

  return false;

  }

  //游戏结束处理

  private void afterEndGame()

  {

  mSnakeTrail.remove(headIndex);

  panel.getSnake().setEnd(true);

  panel.repaint();

  this.isDraw = true;

  }

  Runnable runnable = new Runnable() {

  public void run() {

  moveRight();

  while(!isEndGame())

  {

  if(mNextDirection==Dir.UP) moveUp();

  else if(mNextDirection==Dir.DOWN) moveDown();

  else if(mNextDirection==Dir.LEFT) moveLeft();

  else if(mNextDirection==Dir.RIGHT) moveRight();

  try {

  Thread.sleep(200);

  } catch (InterruptedException e) {

  e.printStackTrace();

  }

  }

  }

  };

  }

  最后是测试类 SnakeTest.java

  package com.nn.main;

  import com.nn.control.PlayControl;

  import com.nn.ui.SnakeFrame;

  import com.nn.ui.SnakePanel;

  /**

  *启动游戏

  *

  */

  public class SnakeTest {

  public static void main(String[] args) {

  SnakeFrame frame = new SnakeFrame();

  SnakePanel panel = new SnakePanel();

  PlayControl playControl = new PlayControl(panel);

  panel.setGameControl(playControl);

  //setContentPane()把panel设置为JFrame的内容面板

  frame.setContentPane(panel);

  }

  }