GUI - 贪吃蛇小游戏

自己完成的过程确很有意思,作为基础练习,进行了部分改进,以后或许会再次改进?

  1. 贪吃蛇头部不可与前进方向相反
  2. 增加了食物的数量和种类

SnakeInit

package com.thf.Snake;

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 SnakeInit extends JPanel implements KeyListener, ActionListener {
    
    
    private int[] SnakeX = new int[816];
    private int[] SnakeY = new int[816];
    private int[] FoodX = new int[3];
    private int[] FoodY = new int[3];
    private int FoodNum;
    private int[] FoodKind = new int[3];
    private int SnakeLength;
    private boolean GameState;
    String Direction01;
    boolean isFail= false;
    int score;
    Timer timer = new Timer(100,this);
    Random random = new Random();
    public SnakeInit() {
    
    
        init();
        this.setFocusable(true);
        this.addKeyListener(this);
        timer.start();
    }
    public void init(){
    
    
        GameState=false;//如果不在此将其初始化为false,则只需要按一次空格
        SnakeLength = 3;
        SnakeX[0] = 100; SnakeY[0] = 75;//蛇头坐标
        SnakeX[1] = 75;  SnakeY[1] = 75;//蛇的初始身体坐标
        SnakeX[2] = 50;  SnakeY[2] = 75;//蛇的初始身体坐标
        Direction01= "right";
        FoodNum = 3;
        //产生食物的数量,种类和位置
        for (int i = 0; i < FoodNum; i++) {
    
    
            FoodX[i] = 25+25*random.nextInt(34);
            //rand.nextInt(34);中的34是随机数的上限,产生的随机数为0-34的整数,不包括34。
            FoodY[i] = 75+25*random.nextInt(24);
            FoodKind[i] = random.nextInt(30);
        }
        score = 0;
    }
    @Override
    protected void paintComponent(Graphics g) {
    
    
        super.paintComponent(g);
        this.setBackground(Color.black);
        g.setColor(Color.DARK_GRAY);
        // 绘制外层矩形框
        g.drawRect(25,75,850,600);
        for(int i = 0; i < 34; i ++) {
    
    
            // 绘制第i条竖直线
            g.drawLine(50+25*i,75,50+25*i,675);
            if(i<=23){
    
    
                // 绘制第i条水平线
                g.drawLine(25,100+25*i,875,100+25*i);
            }
        }
        g.setColor(Color.DARK_GRAY);
        g.drawRect(25,1,850,70);
        //绘制食物
        for (int i = 0; i <FoodNum ; i++) {
    
    
            if(0<=FoodKind[i]&&FoodKind[i]<=26){
    
    
                GameData.food.paintIcon(this,g,FoodX[i],FoodY[i]);
            }else if(27<=FoodKind[i]&&FoodKind[i]<=28){
    
    
                GameData.yellowFood.paintIcon(this,g,FoodX[i],FoodY[i]);//黄色食物
            }else if(FoodKind[i]==29){
    
    
                GameData.redFood.paintIcon(this,g,FoodX[i],FoodY[i]);//红色食物
            }

        }

        //设定并绘制贪吃蛇的头部方向
        if (Direction01.equals("right") ) {
    
    
            GameData.right.paintIcon(this, g, SnakeX[0], SnakeY[0]);
        }
        if (Direction01.equals("left") ) {
    
    
            GameData.left.paintIcon(this, g, SnakeX[0], SnakeY[0]);
        }
        if (Direction01.equals("up") ) {
    
    
            GameData.up.paintIcon(this, g, SnakeX[0], SnakeY[0]);
        }
        if (Direction01.equals("down") ) {
    
    
            GameData.down.paintIcon(this, g, SnakeX[0], SnakeY[0]);
        }
        //绘制贪吃蛇的身体
        for (int i = 1; i < SnakeLength; i++) {
    
    
            GameData.body.paintIcon(this, g, SnakeX[i], SnakeY[i]);
        }
        g.setColor(Color.DARK_GRAY);
        g.setFont(new Font("仿宋",Font.PLAIN,15));
        g.drawString("得分"+score,30,30);
        g.drawString("长度"+SnakeLength,30,50);
        g.drawString("蓝色食物分数+10,长度+1",150,30);
        g.drawString("红色食物分数-10,长度-3",150,50);
        g.drawString("黄色食物分数+100,长度+1",350,30);
        //打印开始文字
        /*
        Font.PLAIN(普通)
        Font.BOLD(加粗)
        Font.ITALIC(斜体)
        Font.BOLD+ Font.ITALIC(粗斜体)
         */
        if(!GameState){
    
    
            g.setColor(Color.lightGray);
            g.setFont(new Font("仿宋",Font.BOLD,40));
            g.drawString("按空格开始游戏",300,400);
        } else if (isFail) {
    
    
            g.setColor(Color.lightGray);
            g.setFont(new Font("仿宋",Font.BOLD,40));
            g.drawString("按空格重新开始游戏",300,400);
        }

    }

    @Override
    public void keyTyped(KeyEvent e) {
    
    

    }
    //按键监听
    @Override
    public void keyPressed(KeyEvent e) {
    
    
        int keycode = e.getKeyCode();
        if (keycode == KeyEvent.VK_SPACE) {
    
    
            if(isFail){
    
    
                //如果isFail的状态改变为true,则令其重新为false,并且初始化所有数据
                isFail=false;
                init();
            }else {
    
    
                GameState = !GameState;
            }
            repaint();
        }
        if(GameState){
    
    
            if(keycode == KeyEvent.VK_UP||keycode == KeyEvent.VK_W){
    
    
                if(Direction01.equals("down")){
    
    
                    Direction01 = "down";
                }else{
    
    
                    Direction01 = "up";
                }
            }else if(keycode == KeyEvent.VK_DOWN||keycode == KeyEvent.VK_S){
    
    
                if(Direction01.equals("up")){
    
    
                    Direction01 = "up";
                }else{
    
    
                    Direction01 = "down";
                }
            }else if(keycode == KeyEvent.VK_LEFT||keycode == KeyEvent.VK_A){
    
    
                if(Direction01.equals("right")){
    
    
                    Direction01 = "right";
                }else{
    
    
                    Direction01 = "left";
                }
            }else if(keycode == KeyEvent.VK_RIGHT||keycode == KeyEvent.VK_D){
    
    
                if(Direction01.equals("left")){
    
    
                    Direction01 = "left";
                }else{
    
    
                    Direction01 = "right";
                }
            }
        }

    }

    @Override
    public void keyReleased(KeyEvent e) {
    
    

    }
    //监听事件
    @Override
    public void actionPerformed(ActionEvent e) {
    
    
        //绘制食物
        if(GameState&&!isFail){
    
    
            for (int i = 0; i <FoodNum ; i++) {
    
    
                if(SnakeX[i]==FoodX[i]&&SnakeY[i]==FoodY[i]&&FoodKind[i]>=0&&FoodKind[i]<=26){
    
    
                    //蓝色食物分数+10,长度+1
                    SnakeLength++;
                    score+=10;
                    FoodX[i] = 25+25*random.nextInt(34);
                    FoodY[i] = 75+25*random.nextInt(24);
                    FoodKind[i] =random.nextInt(30);
                }else if(SnakeX[i]==FoodX[i]&&SnakeY[i]==FoodY[i]&&FoodKind[i]>=27&&FoodKind[i]<=28){
    
    
                    //黄色食物分数+100,长度+1
                    SnakeLength++;
                    score+=100;
                    FoodX[i] = 25+25*random.nextInt(34);
                    FoodY[i] = 75+25*random.nextInt(24);
                    FoodKind[i] =random.nextInt(30);
                }else if(SnakeX[i]==FoodX[i]&&SnakeY[i]==FoodY[i]&&FoodKind[i]==29){
    
    
                    //红色食物分数-10,长度-3
                    if((SnakeLength-=3)<=2){
    
    
                        SnakeLength=2;//保证贪吃蛇长度最低为2
                    }else {
    
    
                        SnakeLength-=3;
                    }
                    score-=10;
                    FoodX[i] = 25+25*random.nextInt(34);
                    FoodY[i] = 75+25*random.nextInt(24);
                    FoodKind[i] =random.nextInt(30);
                }
            }
            //让蛇的身体随着时间变动,只适用于蛇的长度不变或者长度增加1
            for (int i = SnakeLength-1; i >0; i--) {
    
    
                SnakeX[i] = SnakeX[i-1];
                SnakeY[i] = SnakeY[i-1];
            }
            if(Direction01.equals("right")){
    
    //蛇的右边界判定
                SnakeX[0] = SnakeX[0] + 25;
                if(SnakeX[0]>850){
    
    
                    SnakeX[0]=25;
                }
            }else if(Direction01.equals("up")){
    
    //蛇的上边界判定
                SnakeY[0] = SnakeY[0] - 25;
                if(SnakeY[0]<75){
    
    
                    SnakeY[0]=650;
                }
            }else if(Direction01.equals("down")){
    
    //蛇的下边界判定
                SnakeY[0] = SnakeY[0] + 25;
                if(SnakeY[0]>650){
    
    
                    SnakeY[0]=75;
                }
            }else if(Direction01.equals("left")){
    
    //蛇的左边界判定
                SnakeX[0] = SnakeX[0] - 25;
                if(SnakeX[0]<25){
    
    
                    SnakeX[0]=850;
                }
            }
            //蛇的身体和头部碰撞导致的失败判定
            for (int i = 1; i <SnakeLength ; i++) {
    
    
                if(SnakeX[0]==SnakeX[i]&&SnakeY[0]==SnakeY[i]) {
    
    
                    isFail = true;
                }
            }
            repaint();
        }
    }
}



GameData

package com.thf.Snake;

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

public class GameData {
    
    
    public static URL upURL = GameData.class.getResource("/com/thf/Image/up.png");
    public static ImageIcon up =new ImageIcon(upURL);
    public static URL downURL = GameData.class.getResource("/com/thf/Image/down.png");
    public static ImageIcon down =new ImageIcon(downURL);
    public static URL leftURL = GameData.class.getResource("/com/thf/Image/left.png");
    public static ImageIcon left =new ImageIcon(leftURL);
    public static URL rightURL = GameData.class.getResource("/com/thf/Image/right.png");
    public static ImageIcon right =new ImageIcon(rightURL);
    public static URL foodURL = GameData.class.getResource("/com/thf/Image/food.png");
    public static ImageIcon food =new ImageIcon(foodURL);
    public static URL redFoodURL = GameData.class.getResource("/com/thf/Image/redFood.png");
    public static ImageIcon redFood =new ImageIcon(redFoodURL);
    public static URL yellowFoodURL = GameData.class.getResource("/com/thf/Image/yellowFood.png");
    public static ImageIcon yellowFood =new ImageIcon(yellowFoodURL);
    public static URL bodyURL = GameData.class.getResource("/com/thf/Image/body.png");
    public static ImageIcon body =new ImageIcon(bodyURL);
}

附带图片资源

right.jpg
在这里插入图片描述
redfood.jpg
redfood
up.jpg
在这里插入图片描述
left.jpg
在这里插入图片描述
food.jpg
在这里插入图片描述
down.jpg
在这里插入图片描述

body.jpg
在这里插入图片描述
yellowfood.jpg
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41017444/article/details/113870601
今日推荐