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

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

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

时间: 2024-10-05 04:37:32

Java版贪吃蛇小游戏的实现的相关文章

c语言版贪吃蛇小游戏

编译环境:windows 7 64位 编译工具:codeblocks 13.12 备注:未使用graphics.h 声明:个人原创,未经允许,禁止转载!!! 数据结构:双向链表 1.程序未使用graphis.h中的 函数,所以采用先清屏,再打印的方式显示图形,大约每秒刷新一次: 2.除蛇头元素外,其它元素的状态(行进方向)均重复前一元素: 3.蛇的图形元素为笑脸,可在源码中更改symbol参数选用不同元素. 游戏截图1                                      

贪吃蛇小游戏java实现代码分析

贪吃蛇小游戏java实现代码分析 贪吃蛇的小游戏,网上的代码比较多,今天周五,在教研室没啥事做,在电脑中发现了一个贪吃蛇的小游戏,于是就看了下实现的源码,发现别人写的代码确实挺好的,自己也是边加注释边进行理解的去看别人实现的游戏源码,发现还是挺有意思的.自己花了一个下午的时间看了源码,也加了一点小小的功能,于是,不写篇博客觉得对不起自己也,哈哈哈. 此游戏代码的思路非常的清晰,也相当好理解,没有太多难的地方,不过有很多值得学习的地方,因为,这份源码中,对java.awt包中的很多类的很多方法都进

贪吃蛇小游戏 (一)

贪吃蛇是一款儿时爱不释手的游戏.近日修行,想玩玩游戏开发.便简单写了个控制台版的贪吃蛇. 程序的简单框架: 建立一张固定大小的MAP,保存输出信息. 当信息有变动时,用system("cls")进行清屏操作,再重新输出实现伪动态. 重点算法在蛇身的移动,转向与增长.三者均基于链表实现. 移动与转向:通过判定移动方向,确定下一步移动的位置后,新建表头结点.将新表头结点置为表头.删除末尾结点. 增长:通过判断尾部移动方向,确定位置后在尾部添加节点. 熟练运用链表的同学,相信也是小菜一碟了.

一个简单的“贪吃蛇”小游戏

一个简单的“贪吃蛇”小游戏 页面结构 简单的21x21的方块,页面结构 id为container的div包含所21个class名为row的div,每个row代表贪吃蛇的一整行,每个row中又包含21个div,代表这一行的每一个div方格,如果这个方格是空的话,div的类名为blank,如果这一个方格表示“贪吃蛇”的“食物”,div的类名为food,如果这一个方格表示“蛇”,div的类名为snake. CSS JS 然后我们思考下一个贪吃蛇游戏需要那些参数, 首先,界面中可见的元素无非就是空方格,

贪吃蛇小游戏的初步尝试制作

这里利用二维数组做为地图,利用集合来存放蛇头和蛇尾的位置坐标,初步实现一个需要键盘控制的贪吃蛇小游戏. 首先,Main函数下面需要一个大循环来让游戏失败的时候能够重新开始,这里我们用了定义了一个bool型的sc,判断sc的true和flase来确定游戏是否开始: static void Main(string[] args)        { bool sc = true; while (sc) //大循环,用于游戏失败重新开始            { 下面是定义一个集合snake_x来存放蛇

使用Html5+JS做的贪吃蛇小游戏

学习了Html5的Canvas的使用,和JS创建对象,做了一个贪吃蛇小游戏,来巩固JS面向对象编程和Canvas的用法. Node.js 1 /** 2 * 格子类,组成贪吃蛇和舞台 3 */ 4 function Node(x,y){ 5 this.x=x; 6 this.y=y; 7 /** 8 * 比较两个格子是否重合 9 */ 10 this.equals=function(x,y){ 11 return this.x==x&&this.y==y; 12 } 13 } Snake.

用C写一个功能较为完善的贪吃蛇小游戏

主要功能: 方向控制-食物与增长-变速 1 #include<stdio.h> 2 #include<time.h>//种子-随机数 3 #include<windows.h>//system函数,控制台句柄 4 #include<conio.h>//按键 5 //界面(欢迎界面-游戏界面-结束得分界面)-驱动-方向控制-食物 6 //位置锁定-打印-删除 7 int snake_x[520]={0}; 8 int snake_y[520]={0}; 9 i

Java版贪吃蛇(比较完善的版本)

很认真的写的一个java版的贪吃蛇游戏,图形界面,支持菜单操作,键盘监听,可加速,减速,统计得分,设定运动速度,设定游戏背景颜色等!应该没有Bug了,因为全被我修改没了.哈哈. 下面是项目各包及类的层次关系: 游戏的主要运行界面截图如下: 下面是部分代码,详细源码见此链接:http://pan.baidu.com/s/1bnubnzh //Snake类: package com.huowolf.entities; import java.awt.Color; import java.awt.Gr

贪吃蛇小游戏编写心得

https://github.com/Devilzero/6 package 贪吃蛇; import java.awt.*; import java.awt.event.*; public class GreedSnake //主类 { /** * @param args */ public static void main(String[] args) { new MyWindow(); } } class MyPanel extends Panel implements KeyListene