一个简单的贪吃蛇小游戏

1.游戏效果显示

一个简单的贪吃蛇小游戏_第1张图片

2.编码过程

1.将图片加载到程序当中

创建一个Images类用来获取游戏中所需要用到的图片,利用面向对象的思维,将图片封装成一个对象来进行操作。
所用到的方法:

getResource

public URL getResource​(String name)

查找具有给定名称的资源。

ImageIcon

public ImageIcon()

创建未初始化的图像图标。

具体代码如下:

public class Images {
    //将图片的路径封装为一个对象
 public static URL bodyRUL = Images.class.getResource("/images/body.png");
    public static URL downRUL = Images.class.getResource("/images/down.png");
    public static URL foodRUL = Images.class.getResource("/images/food.png");
    public static URL headerRUL = Images.class.getResource("/images/header.png");
    public static URL leftRUL = Images.class.getResource("/images/left.png");
    public static URL rightRUL = Images.class.getResource("/images/right.png");
    public static URL upRUL = Images.class.getResource("/images/up.png");
    //将图片封装为程序中的一个对象
 public static ImageIcon bodyImg = new ImageIcon(bodyRUL);
    public static ImageIcon downImg = new ImageIcon(downRUL);
    public static ImageIcon foodImg = new ImageIcon(foodRUL);
    public static ImageIcon headerImg = new ImageIcon(headerRUL);
    public static ImageIcon leftImg = new ImageIcon(leftRUL);
    public static ImageIcon rightImg = new ImageIcon(rightRUL);
    public static ImageIcon upImg = new ImageIcon(upRUL);
}

2.创建窗体

创建一个窗体,并设置它的基本属性,包括大小、位置、标题等属性。
所用到的方法:

JFrame

public JFrame()

构造一个最初不可见的新框架。

setTitle

public void setTitle​(String title)

将此帧的标题设置为指定的字符串。

setVisible

public void setVisible​(boolean b)

显示或隐藏此Window具体取决于参数b的值。

setBounds

public void setBounds​(int x, int y, int width, int height)

移动并调整此组件的大小。 左上角的新位置由xy指定,新大小由widthheight指定。

setResizable

public void setResizable​(boolean resizable)

设置此框架是否可由用户调整大小。

setDefaultCloseOperation

public void setDefaultCloseOperation​(int operation)

设置当用户在此帧上启动“关闭”时默认发生的操作。 您必须指定以下选项之一:

  • DO_NOTHING_ON_CLOSE (在WindowConstants定义):不要做任何事情; 要求程序处理已注册WindowListener对象的windowClosing方法中的操作。
  • HIDE_ON_CLOSE (在WindowConstants定义):在调用任何已注册的WindowListener对象后自动隐藏框架。
  • DISPOSE_ON_CLOSE (在WindowConstants定义):在调用任何已注册的WindowListener对象后自动隐藏和处置框架。
  • EXIT_ON_CLOSE (在WindowConstants定义):使用System exit方法退出应用程序。 仅在应用程序中使用它。
getScreenSize

public abstract Dimension getScreenSize() throws HeadlessException

获取屏幕的大小。

具体代码如下:

public class StartGame {
    public static void main(String[] args) {
        //创建一个窗体
 JFrame jf = new JFrame();
        //给窗体设置一个标题
 jf.setTitle("贪吃蛇");
        //设置窗体弹出的坐标,对应窗体的宽高
 int width = Toolkit.getDefaultToolkit().getScreenSize().width;
        int height = Toolkit.getDefaultToolkit().getScreenSize().height;
        jf.setBounds((width-800)/2,(height-800)/2,800,800);
        //设置窗体大小不可调节
 jf.setResizable(false);
        //关闭窗口的同时终止程序
 jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        //创建面板
GamePanel gp = new GamePanel();
        //将面板放入窗口
jf.add(gp);
        //默认情况下窗体是隐藏效果,必须将窗体进行显现,显现方法一般放到最后
 jf.setVisible(true);
    }
}

3.创建面板

创建面板需要用到JPanel类在这里我们创建一个类GamePanel继承JPanel,并在startGame类中创建面板并添加。
所用到的方法:

paintComponents

public void paintComponents​(Graphics g)

绘制此容器中的每个组件。

setBackground

public void setBackground​(Color c)

设置此组件的背景颜色。

paintIcon

void paintIcon​(Component c, Graphics g, int x, int y)

在指定位置绘制图标。 图标实现可以使用Component参数来获取对绘画有用的属性,例如前景色或背景色。

fillRect

public abstract void fillRect​(int x, int y, int width, int height)

填充指定的矩形。 矩形的左右边缘位于xx + width - 1 。 顶部和底部边缘位于yy + height - 1 。 得到的矩形覆盖了width像素宽, height像素高的区域。 使用图形上下文的当前颜色填充矩形。

setColor

将此图形上下文的当前颜色设置为指定的颜色。 使用此图形上下文的所有后续图形操作都使用此指定颜色。
具体代码如下:
public abstract void setColor​(Color c)

//这个方法比较特殊,相当于图形版的main方法,自动调用
 @Override
 protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        //填充背景颜色
 this.setBackground(new Color(239, 187, 123, 86));
        //画头部图片
 Images.headerImg.paintIcon(this,g,10,10);
        //调节画笔颜色
 g.setColor(new Color(219, 170, 170));
        //画一个矩形
 g.fillRect(10,70,770,685);
}

4.画静态的小蛇

初始化设定小蛇长度与位置,并分别用两个一维数组来存储头和身子的位置。

public void init(){
    //初始化蛇的长度
 length = 3;
    //初始化头部
 snakeX[0] = 175;
    snakeY[0] = 275;
    //初始化第一节身子
 snakeX[1] = 150;
    snakeY[1] = 275;
    //初始化第二节身子
 snakeX[2] = 125;
    snakeY[2] = 275;
    //初始化蛇头的方向
 direction = "R";
}

5.将蛇头按照行走方向改变

利用equals()方法判断蛇头方向画出蛇头

//画蛇
//蛇头
if("R".equals(direction)){
    Images.rightImg.paintIcon(this,g,snakeX[0],snakeY[0]);
}
if("L".equals(direction)){
    Images.leftImg.paintIcon(this,g,snakeX[0],snakeY[0]);
}
if("U".equals(direction)){
    Images.upImg.paintIcon(this,g,snakeX[0],snakeY[0]);
}
if("D".equals(direction)){
    Images.downImg.paintIcon(this,g,snakeX[0],snakeY[0]);
}
//第一节身子
//Images.bodyImg.paintIcon(this,g,snakeX[1],snakeX[1]);
//第二节身子
//Images.bodyImg.paintIcon(this,g,snakeX[2],snakeX[2]);
//优化为循环画身子
for(int i=1; i

6.加入监听

利用监听器来达到暂停的效果
所用到的方法:

setFocusable

public void setFocusable​(boolean focusable)

将此Component的可聚焦状态设置为指定值。 此值将覆盖Component的默认可聚焦性。

addKeyListener

public void addKeyListener​(KeyListener l)

添加指定的键侦听器以从此组件接收键事件。 如果l为null,则不抛出任何异常并且不执行任何操作。

init();
//将焦点定位在当前操作的面板上
this.setFocusable(true);
//加入监听
this.addKeyListener(new KeyAdapter() {
    @Override
 public void keyPressed(KeyEvent e) {//监听键盘的按下操作
 super.keyPressed(e);
        int keyCode = e.getKeyCode();
        System.out.println(keyCode);
        if (keyCode == KeyEvent.VK_SPACE){//监听空格
 if(isDie){
                //恢复初始化动作:
 init();
                //死亡状态改为false:
 isDie = false;
            }
            else{
                //将isStart设置为相反的值
 isStart = !isStart;
                //页面重新绘制:
 repaint();//底层调用的还是paintComponent
 }
        }

7.控制小蛇移动

和暂停类似

//监听方向
if (keyCode == KeyEvent.VK_UP){
    direction = "U";
}
if (keyCode == KeyEvent.VK_DOWN){
    direction = "D";
}
if (keyCode == KeyEvent.VK_LEFT){
    direction = "L";
}
if (keyCode == KeyEvent.VK_RIGHT){
    direction = "R";
}
//动身子
for (int i=length-1; i>0; i--){
    snakeX[i] = snakeX[i-1];
    snakeY[i] = snakeY[i-1];
}
//动头
if ("R".equals(direction)){
    snakeX[0] += 25;
}
if ("L".equals(direction)){
    snakeX[0] -= 25;
}
if ("U".equals(direction)){
    snakeY[0] -= 25;
}
if ("D".equals(direction)){
    snakeY[0] += 25;
}
//防止蛇出边界
if (snakeX[0] > 750){
    snakeX[0] = 25;
}
if (snakeX[0] < 25){
    snakeX[0] = 750;
}
if (snakeY[0] < 100){
    snakeY[0] = 725;
}
if (snakeY[0] > 725){
    snakeY[0] = 100;
}

8.画食物并进行碰撞检测

当食物与蛇头重合,即蛇头的位置等于食物位置时小蛇长度加1,并累加积分。

//碰撞检测
if (snakeX[0] == foodX && snakeY[0] == foodY){
    //蛇的长度+1
 length++;
    //随机生成食物坐标且坐标必须是25的倍数 两种不同的方法
 foodX = ((int) (Math.random()*30)+1)*25;//[25,750]
 foodY = (new Random().nextInt(26)+4)*25;//[100,725]
 score += 10;
}

9.判定游戏结束

当蛇头撞到蛇身时判定小蛇死亡,游戏结束。

//判断蛇是否死亡:
 //蛇什么时候死:只要蛇头跟任意一节身子重合,就是死:
 for (int i = 1; i < length ; i++) {
        if(snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]){
            isDie = true;//蛇死亡了
 }
    }
    repaint();
}

以上是部分代码块,若需要全部代码及素材可以从这里下载。

你可能感兴趣的:(java)