GUI编程-练习(贪吃蛇游戏)

练习(贪吃蛇)

文件结构

Data类

图像初始化

/**
 * 基础数据、图片
 */

public class Data {
    //头部图片 URL
    public static ImageIcon headerIcon=new ImageIcon(Data.class.getResource("/statics/header.png"));
    //蛇头
    public static ImageIcon upIcon=new ImageIcon(Data.class.getResource("/statics/up.png"));
    public static ImageIcon downIcon=new ImageIcon(Data.class.getResource("/statics/down.png"));
    public static ImageIcon leftIcon=new ImageIcon(Data.class.getResource("/statics/left.png"));
    public static ImageIcon rightIcon=new ImageIcon(Data.class.getResource("/statics/right.png"));
    //蛇身
    public static ImageIcon bodyIcon = new ImageIcon(Data.class.getResource("/statics/body.png"));
    //食物
    public static ImageIcon foodIcon = new ImageIcon(Data.class.getResource("/statics/food.png"));
}

StartGame类

启动程序

/**
 * 主程序,设置窗口、添加面板
 */
public class StartGame {
    public static void main(String[] args) {
        //1.绘制一个静态窗口 JFrame
        JFrame frame=new JFrame("狂神说java-贪吃蛇小游戏");
        frame.setSize(910,720);
        frame.getContentPane().setBackground(Color.RED);
        frame.setLocationRelativeTo(null);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //2.添加面板 JPanel
        frame.add(new GamePanel());
        frame.setVisible(true);
    }
}

GamePanel类

游戏面板,画图

/**
 * 游戏面板,画图
 */
public class GamePanel extends JPanel implements KeyListener, ActionListener {
    int length; //蛇的长度
    int score; //得分
    int[] snakeX=new int[100]; //蛇的坐标x
    int[] snakeY=new int[100]; //蛇的坐标y
    String dir; //移动方向,R:右,L:左,U:上,D:下
    //游戏状态
    boolean isStart=false;
    boolean isFail=false;
    //定时器
    Timer timer = new Timer(100, this);
    //定义一个食物
    int foodX;
    int foodY;
    //创建Random对象
    Random random = new Random();
    //构造器
    public GamePanel() {
        //初始化蛇、食物
        init();
        //获取键盘的监听事件
        this.setFocusable(true);
        this.addKeyListener(this);
    }
    //初始化:蛇、食物、游戏状态
    public void init(){
        length=3;
        score=0;
        snakeX[0]=100;snakeY[0]=100;
        snakeX[1]=75;snakeY[1]=100;
        snakeX[2]=50;snakeY[2]=100;
        dir="R";
        foodX=25+25*random.nextInt(34);
        foodY=75+25*random.nextInt(24);
    }
    //画图:画界面,画蛇
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);//清屏
        this.setBackground(Color.WHITE);//设置面板背景
        Data.headerIcon.paintIcon(this,g,25,11);//绘制头部图片
        g.fillRect(25,75,850,600);//绘制游戏区域
        //画静态的蛇
        switch (dir){
            case "R":
                Data.rightIcon.paintIcon(this,g,snakeX[0],snakeY[0]);
                break;
            case "L":
                Data.leftIcon.paintIcon(this,g,snakeX[0],snakeY[0]);
                break;
            case "U":
                Data.upIcon.paintIcon(this,g,snakeX[0],snakeY[0]);
                break;
            case "D":
                Data.downIcon.paintIcon(this,g,snakeX[0],snakeY[0]);
                break;
        }
        for (int i = 1; i <length ; i++) {
            Data.bodyIcon.paintIcon(this,g,snakeX[i],snakeY[i]);
        }
        //画积分
        g.setColor(Color.WHITE);
        g.setFont(new Font("微软雅黑",Font.BOLD,16));
        g.drawString("长度: "+length,750,30);
        g.drawString("得分: "+score,750,50);
        //画食物
        Data.foodIcon.paintIcon(this,g,foodX,foodY);
        //开始提示
        if(isStart==false){
            g.setColor(Color.BLUE);
            g.setFont(new Font("微软雅黑",Font.BOLD,40));
            g.drawString("按下空格键开始游戏",300,300);

        }
        //失败提示
        if (isFail){
            //画一个文字 String
            g.setColor(Color.WHITE);
            g.setFont(new Font("微软雅黑",Font.ITALIC,40));
            g.drawString("游戏失败,按空格键重新开始",200,400);
        }
    }
    //键盘按下事件
    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode=e.getKeyCode();
        if (keyCode==KeyEvent.VK_SPACE){//如果按下的是空格键
            if(isFail){ //游戏失败,再来一次
                isFail=false;
                init(); //初始化游戏
            }else{
                isStart=!isStart;
            }
            repaint();
            timer.start();
         }
        //键盘控制方向
        if (keyCode==KeyEvent.VK_LEFT) dir="L";
        else if (keyCode==KeyEvent.VK_RIGHT) dir="R";
        else if (keyCode==KeyEvent.VK_UP) dir="U";
        else if (keyCode==KeyEvent.VK_DOWN) dir="D";
    }
    //定时器事件
    @Override
    public void actionPerformed(ActionEvent e) {
        //如果游戏处于开始状态,且游戏没有失败
        if (isStart && isFail==false){
            //移动蛇身
            for(int i=length-1;i>0;i--){
                snakeX[i]=snakeX[i-1];
                snakeY[i]=snakeY[i-1];
            }
            //控制头部移动方向
            if (dir.equals("R")) {
                snakeX[0]=snakeX[0]+25;
                if (snakeX[0]>850) snakeX[0]=25;
            }
            else if (dir.equals("L")) {
                snakeX[0]=snakeX[0]-25;
                if (snakeX[0]<25) snakeX[0]=850;
            }
            else if (dir.equals("U")) {
                snakeY[0]=snakeY[0]-25;
                if (snakeY[0]<75) snakeY[0]=650;
            }
            else if (dir.equals("D")) {
                snakeY[0]=snakeY[0]+25;
                if (snakeY[0]>650) snakeY[0]=75;
            }
            //如果蛇头和食物坐标重合,则吃食物
            if (snakeX[0]==foodX && snakeY[0]==foodY){
                //蛇长度+1
                length++;
                score=score+10;
                //重新生成食物
                foodX=25+25*random.nextInt(34);
                foodY=75+25*random.nextInt(24);
            }
            //失败判断,蛇头与蛇身相撞
            for (int i = 1; i <length ; i++) {
                if(snakeX[0]==snakeX[i] && snakeY[0]==snakeY[i]){
                    isFail=true;
                    break;
                }
            }
            repaint();
        }
        timer.start();
    }
    @Override
    public void keyReleased(KeyEvent e) { }
    @Override
    public void keyTyped(KeyEvent e) { }
}
posted @ 2022-03-29 22:42  老李学Java  阅读(62)  评论(0)    收藏  举报