码迷,mamicode.com
首页 > 编程语言 > 详细

Java版贪吃蛇小游戏的实现

时间:2014-07-25 16:37:01      阅读:424      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   java   color   使用   os   io   

使用的IDE eclipse

JDK版本 1.6

bubuko.com,布布扣

辅助类 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<Coordinate> mSnakeTrail = new ArrayList<Coordinate>();  
      
    //存放豆子  
    private ArrayList<Coordinate> mAppleList = new ArrayList<Coordinate>();  
  
    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<Coordinate> getmSnakeTrail() {  
        return mSnakeTrail;  
    }  
      
    public ArrayList<Coordinate> 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<Coordinate> mSnakeTrail = null;  
      
    private ArrayList<Coordinate> 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<mSnakeTrail.size();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<Coordinate> mSnakeTrail;  
      
    /* 
     * 豆子列表 
     */  
    private ArrayList<Coordinate> 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<mSnakeTrail.size()-1;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);  
}  
}  

bubuko.com,布布扣

大致说下思路,panel面板增加控制器获得游戏控制权,控制器根据输入在列表中更新蛇身所在位置的坐标,并通知panel重绘,直至游戏结束,鼠标监听事件return。当然程序有不恰当的地方,比如说控制层和业务层混杂在了一起,代码中存在硬编码,代码的复用性不高,只是个练习的小程序,还有很多不完善的地方。

Java版贪吃蛇小游戏的实现,布布扣,bubuko.com

Java版贪吃蛇小游戏的实现

标签:style   blog   http   java   color   使用   os   io   

原文地址:http://www.cnblogs.com/sphere/p/3867841.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!