Java-GUI练习, 贪吃蛇

写一个贪吃蛇

键盘监听

定时器Timer

时间监听

画笔

1、数据中心类

定义图片URL

定义图标

头部上下左右、身体、实物、横幅的图标

2、游戏启动类

main方法启动游戏

定义主窗口

设置主窗口大小值,可见,大小,关闭事件

添加画板

3、游戏画板类

  • 定义数据

    • 蛇的长度
    • 蛇的坐标
    • 头部方向
    • 食物的坐标
    • random随机食物坐标
    • 积分
    • 游戏的启动状态
    • 游戏的失败状态
    • 定时器Timer(int多少毫秒执行一次,对象)
  • 构造器:

    • 调用初始化方法,
    • 获得焦点
    • 获得键盘事件
    • 启动定时器
  • 初始化方法

    • 初始化蛇的长度
    • 初始化蛇的头部位置,身体位置
    • 初始化头部的朝向
    • 随机食物的坐标
    • 积分初始化0
  • 绘制画板

    • 清屏
    • 设置画板背景颜色
    • 设置画板界面大小及位置 fillRect
    • 把横幅画上去,数据中心获取(data)
    • 积分画上去
      • 设置积分字体。setFont(Font)
      • 设置标语,drawString(字体,x,y)
    • 画食物
    • 画小蛇头
      • 判断四个方向使用不同的ImageIcon
    • 画小蛇身体
      • 坐标就是蛇头的后一个坐标
    • 判断游戏是否开始
      • 设置标语,drawString(字,x,y)
    • 判断游戏是否失败
      • 设置标语,drawString(字,x,y)
  • 键盘监听事件

    • 可以实现KeyListener接口,重写keyPresssed按下方法
    • 监听空格
    • 监听上下左右键
  • 事件监听,需要通过固定事件来刷新

    • 判断游戏开始、失败状态
    • 判断是否吃到食物
    • 让小蛇头部移动(for)
      • 判断方向及边界
    • 让小蛇身体移动(for)小蛇身体坐标就是前一节的坐标
    • 判断是否失败(for)
    • 重画
    • 定时器开启

1, 数据类

  • 定义各部分的图片数据
package com.ccc.testsnake;

import javax.swing.*;
import java.net.URL;

public class Data {
    private static URL urlHeader = Data.class.getResource("z-image/header.png");
    private static URL urlUp = Data.class.getResource("z-image/up.png");
    private static URL urlDown = Data.class.getResource("z-image/down.png");
    private static URL urlLeft = Data.class.getResource("z-image/left.png");
    private static URL urlRight = Data.class.getResource("z-image/right.png");
    private static URL urlBody = Data.class.getResource("z-image/body.png");
    private static URL urlfood = Data.class.getResource("z-image/food.png");
    private static URL urlfood2 = Data.class.getResource("z-image/up.png");
    public static ImageIcon headerImageIcon = new ImageIcon(urlHeader);
    public static ImageIcon UpImageIcon = new ImageIcon(urlUp);
    public static ImageIcon downImageIcon = new ImageIcon(urlDown);
    public static ImageIcon leftImageIcon = new ImageIcon(urlLeft);
    public static ImageIcon rightImageIcon = new ImageIcon(urlRight);
    public static ImageIcon bodyImageIcon = new ImageIcon(urlBody);
    public static ImageIcon foodImageIcon = new ImageIcon(urlfood);
    public static ImageIcon food2ImageIcon = new ImageIcon(urlfood2);
}

2, 启动类

  • 启动游戏, 设置主窗体参数
package com.ccc.testsnake;

import javax.swing.*;
import java.awt.*;

public class StartSnakeGame {
    public static void main(String[] args) {
        JFrame jFrame = new JFrame("空格开始游戏");

        //添加panel 画板
        jFrame.add(new GamePanel());
        jFrame.setVisible(true);
        jFrame.setResizable(false);
        jFrame.setBackground(Color.WHITE);
        jFrame.setBounds(700,300,870,725);
        jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }
}

3, 画板类

  • 画蛇,
  • 监听
package com.ccc.testsnake;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

public class GamePanel extends JPanel implements KeyListener, ActionListener {
    private int length;//蛇的长度
    private String direction;//蛇头的方向
    private int count ;//分数
    private boolean isStart = false;//开始状态
    private boolean isFailed = false;//失败状态
    private int[] snakeX;private int[] snakeY;
    private int foodX;private int foodY;
    private int food2X;private int food2Y;
    Random random;//随机数
    Timer timer = new Timer(120,this);//定时器

    public GamePanel() {
        init();
        this.addKeyListener(this);
        this.setFocusable(true);
        timer.start();
    }

    //初始化方法
    private void init(){
        length = 3;
        snakeX = new int[825];
        snakeY = new int[625];
        direction = "R";
        random = new Random();
        foodX = 300;foodY = 300;
        food2X = 600;food2Y = 600;
        //初始化蛇默认坐标
        for (int i = 0; i <length; i++) {
            snakeX[i] = 100-(25*i);snakeY[i] = 100;//边界 x 25,y 75
        }
//        snakeX[0] = 100;snakeY[0] = 100;
//        snakeX[1] = 75;snakeY[1] = 100;
//        snakeX[2] = 50;snakeY[2] = 100;

    }
    //画板


    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        this.setBackground(Color.BLACK);
        //画横幅
        Data.headerImageIcon.paintIcon(this,g,0,11);
        g.fillRect(25,75,800,600);
        g.setColor(Color.PINK);
        g.setFont(new Font("微软雅黑",Font.BOLD,20));
        g.drawString("积       分:"+count+"分",440,30);
        g.drawString("你有多长:"+length+"cm",440,50);
        //画食物
        Data.foodImageIcon.paintIcon(this,g,foodX,foodY);
        if (((length+foodX)%3)==0){
            Data.food2ImageIcon.paintIcon(this,g,food2X,food2Y);
        }


        //画蛇头
        if (direction .equals("U")){
            Data.UpImageIcon.paintIcon(this,g,snakeX[0],snakeY[0]);
        }else if(direction.equals("D")){
            Data.downImageIcon.paintIcon(this,g,snakeX[0],snakeY[0]);
        }else if(direction.equals("L")){
            Data.leftImageIcon.paintIcon(this,g,snakeX[0],snakeY[0]);
        }else if(direction.equals("R")){
            Data.rightImageIcon.paintIcon(this,g,snakeX[0],snakeY[0]);
        }
        //画身体
        for (int i = 1; i < length; i++) {
            Data.bodyImageIcon.paintIcon(this,g,snakeX[i],snakeY[i]);
        }
        if (isFailed==true){
            g.setColor(Color.YELLOW);
            g.setFont(new Font("微软雅黑",Font.BOLD,28));
            if (count<500){
                g.drawString("才吃这么点! 按空格重新开始!  得分:"+count,200,400);
            }else if (count<1000){
                g.drawString("吃饱了吧! 按空格重新开始! 得分:"+count,200,400);
            }else{
                g.drawString("无敌!!! 按空格重新开始! 得分:"+count,200,400);
            }

        }
        if (isStart==false){
            g.setColor(Color.RED);
            g.setFont(new Font("微软雅黑",Font.BOLD,28));
            g.drawString("就这? 按空格开始!",300,400);
        }
    }
    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        if (keyCode==KeyEvent.VK_SPACE){
            if (isFailed){
                isFailed = false;count =0;
            }else{
                isStart = !isStart;
            }
            repaint();
        }
        if(isStart==true && isFailed == false){
            if ((keyCode==KeyEvent.VK_UP || keyCode == KeyEvent.VK_W)&& direction!="D"){
                direction = "U";
            }else if ((keyCode==KeyEvent.VK_DOWN || keyCode == KeyEvent.VK_S) && direction!="U"){
                direction = "D";
            }else if ((keyCode==KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_A) && direction!="R"){
                direction = "L";
            }else if ((keyCode==KeyEvent.VK_RIGHT || keyCode == KeyEvent.VK_D) && direction!="L"){
                direction = "R";
            }
        }

    }

    @Override
    public void actionPerformed(ActionEvent e) {
            if (isStart==true && isFailed==false){

                for (int i = 1; i < length; i++) {
                    //食物不能和身体重叠
                    if (foodX == snakeX[i] && foodY == snakeY[i]   ){
                        foodX = 25+25* random.nextInt(32);
                        foodY = 75+25* random.nextInt(24);

                    }
                    if (food2Y == snakeY[i] &&food2X == snakeX[i] ){
                        food2Y = 75+25* random.nextInt(23);
                        food2X = 25+25* random.nextInt(31);
                    }
                    //头部不能和身体重叠
                    if (snakeX[0]==snakeX[i] && snakeY[0] ==snakeY[i]){
                        isFailed = true;
                        init();
                    }
                }

                //如果头部坐标相同,代表吃到了食物,长度加1,分数加20
                if (snakeX[0]==foodX && snakeY[0] == foodY){
                    length++;
                    count+=20;
                    foodX = 25+25* random.nextInt(32);
                    foodY = 75+25* random.nextInt(24);
                }else if (snakeX[0]==food2X && snakeY[0] == food2Y){
                    length+=5;count+=100;
                    food2X = 25+25* random.nextInt(32);
                    food2Y = 75+25* random.nextInt(24);
                    for (int i = 0; i < 5; i++) {
                        snakeX[length-1-i] = snakeX[length-6];
                        snakeY[length-1-i] = snakeY[length-6];
                    }
                }
                //小蛇动起来
                for (int i = length-1; i >0 ; i--) {
                    snakeX[i] = snakeX[i-1];
                    snakeY[i] = snakeY[i-1];
                }
                //蛇头怎么移动
                if (direction.equals("U")){
                    snakeY[0] -=25;
                }else  if (direction.equals("D")){
                    snakeY[0] +=25;
                }else  if (direction.equals("L")){
                    snakeX[0] -=25;
                }else  if (direction.equals("R")){
                    snakeX[0] +=25;
                }
                //撞到墙失败
                if (snakeX[0]==825 || snakeX[0]==0 || snakeY[0]==50 || snakeY[0]==675 ){
                    isFailed = true;
                    init();
                }
                repaint();
            }
    }





    @Override
    public void keyReleased(KeyEvent e) {

    }
    @Override
    public void keyTyped(KeyEvent e) {

    }
}

请添加图片描述

下载地址

https://download.csdn.net/download/xbd_zc/52913026
下载

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值