GUI编程实战--贪吃蛇
GUI编程实战--贪吃蛇
参考:遇见狂神说
界面绘制
- 帧:如果时间片足够小,就是动画,一秒30帧。连起来是动画,拆开是静态的图片
- 键盘监听
- 定时器 Timer
package com.ssl.Snake;
import javax.swing.*;
//游戏的主启动类
public class StartGame {
    public static void main(String[] args) {
        JFrame frame = new JFrame("基于java-GUI的贪吃蛇小游戏");
        frame.setBounds(50,50,900,800);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setResizable(false);  //大小不可变
        //正常游戏界面都应该在面板上!
        frame.add(new GamePanel());
    }
}
package com.ssl.Snake;
import javax.swing.*;
import java.net.URL;
//数据中心
public class Data {
    //相对定位  tx.jpg
    //绝对定位  /  相当于当前项目
    public static URL headerURL = Data.class.getResource("statics/header.png");
    public static ImageIcon header = new ImageIcon(headerURL);
    public static URL headURL = Data.class.getResource("statics/head.png");
    public static ImageIcon head = new ImageIcon(headURL);
    public static URL leftURL = Data.class.getResource("statics/left.png");
    public static ImageIcon left = new ImageIcon(leftURL);
    public static URL rightURL = Data.class.getResource("statics/right.png");
    public static ImageIcon right = new ImageIcon(rightURL);
    public static URL upURL = Data.class.getResource("statics/up.png");
    public static ImageIcon up = new ImageIcon(upURL);
    public static URL downURL = Data.class.getResource("statics/down.png");
    public static ImageIcon down = new ImageIcon(downURL);
    public static URL foodURL = Data.class.getResource("statics/food.png");
    public static ImageIcon food = new ImageIcon(foodURL);
    public static URL bodyURL = Data.class.getResource("statics/body.png");
    public static ImageIcon body = new ImageIcon(bodyURL);
}
package com.ssl.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.security.Key;
import java.util.Random;
//游戏面板
public class GamePanel extends JPanel implements KeyListener, ActionListener {
    //定义蛇的数据结构
    int length;   //蛇的长度
    int[] snakeX = new int[600];  //蛇的x坐标  25*25
    int[] snakeY = new int[500];  //蛇的y坐标  25*25
    //脑袋的初始方向
    String fx;
    //游戏当前状态   开始/停止
    boolean isStart;
    //游戏速度
    int speed = 100;
    //定时器
    Timer timer = new Timer(speed,this);   //100ms执行一次
    //食物的坐标  x:25:850 y:150:725
    int foodx;
    int foody;
    Random random = new Random();
    //游戏失败
    boolean isfall = false;
    //成绩
    int score;
    //构造器
    public GamePanel(){
        init();
        //获得焦点和键盘事件
        this.setFocusable(true);   //获得焦点事件
        this.addKeyListener(this);
    }
    public void init(){
        //初始化长度为3
        length=3;
        snakeX[0]=100; snakeY[0]=200;  //脑袋坐标
        snakeX[1]=75; snakeY[1]=200;  //第一个身体
        snakeX[2]=50; snakeY[2]=200;  //第二个身体
        fx = "R";
        isStart = false;
        speed=100;
        timer.start();//定时器
        //把食物随机放上
        foodx = 25 + 25 * random.nextInt(34);
        foody = 150 +25 * random.nextInt(24);
        score = 0;
    }
    //绘制面板,游戏中所用东西都用这个画笔来画。
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);  //清屏,不用会闪烁
        //绘制静态的面板
        this.setBackground(Color.WHITE);
        Data.head.paintIcon(this,g,0,0);  //广告栏
        g.fillRect(25,150,850,600);//默认的游戏界面
        //画积分
        g.setColor(Color.BLACK);
        //设置字体
        g.setFont(new Font("微软雅黑",Font.BOLD,20));
        //放入字
        g.drawString("长度:"+length,750,50);
        g.drawString("得分:"+score,750,100);
        //画食物
        Data.food.paintIcon(this,g,foodx,foody);
        //把小蛇画上去
        //头    需要通过方向来判断
        if(fx.equals("R")){
            Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);
        }else if(fx.equals("L")){
            Data.left.paintIcon(this,g,snakeX[0],snakeY[0]);
        }else if(fx.equals("U")){
            Data.up.paintIcon(this,g,snakeX[0],snakeY[0]);
        }else if(fx.equals("D")){
            Data.down.paintIcon(this,g,snakeX[0],snakeY[0]);
        }
        //身体
        for(int i=1;i<length;i++){
            Data.body.paintIcon(this,g,snakeX[i],snakeY[i]);
        }
        //游戏状态
        if(!isStart){
            g.setColor(Color.WHITE);
            //设置字体
            g.setFont(new Font("微软雅黑",Font.BOLD,40));
            //放入字
            g.drawString("按下空格开始游戏",300,400);
        }
        //如果游戏失败
        if(isfall){
            g.setColor(Color.RED);
            //设置字体
            g.setFont(new Font("微软雅黑",Font.BOLD,40));
            //放入字
            g.drawString("游戏失败,按下空格重新开始",150,400);
        }
    }
    @Override
    public void keyTyped(KeyEvent e) {
    }
    //键盘的监听事件
    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();   //获得键盘的按键
        if(keyCode == KeyEvent.VK_SPACE){    //如果按下的是空格键
            if(isfall){
                //重新开始
                isfall = false;
                init();
            }else{
                isStart = !isStart;
            }
            repaint();
        }
        //小蛇移动
        if(keyCode == KeyEvent.VK_UP && (fx.equals("R")||fx.equals("L")) ){
            fx="U";
        }else if(keyCode == KeyEvent.VK_DOWN && (fx.equals("R")||fx.equals("L"))){
            fx="D";
        }else if(keyCode == KeyEvent.VK_LEFT && (fx.equals("U")||fx.equals("D")) ){
            fx="L";
        }else if(keyCode == KeyEvent.VK_RIGHT && (fx.equals("U")||fx.equals("D"))){
            fx="R";
        }
    }
    @Override
    public void keyReleased(KeyEvent e) {
    }
    //事件监听  通过固定的事件刷新 1s 10次
    @Override
    public void actionPerformed(ActionEvent e) {
        //如果游戏是开始状态,就让小蛇动起来
        if(isStart && isfall == false){
            //吃食物
            if(snakeX[0]==foodx && snakeY[0]==foody){
                length++;
                foodx = 25 + 25 * random.nextInt(34);
                foody = 150 +25 * random.nextInt(24);
                //变速
                speed= speed - 1;
                score+=10;
            }
            //身体的移动  后一节变到前一节
            for(int i=length -1;i>0;i--){
                snakeX[i]=snakeX[i-1];
                snakeY[i]=snakeY[i-1];
            }
            //右移
            if(fx.equals("R")){
                snakeX[0]=snakeX[0]+25;
            }else if(fx.equals("L")){
                snakeX[0]=snakeX[0]-25;
            }else if(fx.equals("U")){
                snakeY[0]=snakeY[0]-25;
            }else if(fx.equals("D")){
                snakeY[0]=snakeY[0]+25;
            }
            //边界判断
            if(snakeX[0]>850){
                snakeX[0]=25;
            }
            if(snakeX[0]<25){
                snakeX[0]=850;
            }
            if(snakeY[0]>725){
                snakeY[0]=150;
            }
            if(snakeY[0]<150){
                snakeY[0]=725;
            }
            //失败判定,撞到自己就算失败
            for(int i=1;i<length;i++){
                if(snakeX[0]==snakeX[i]&&snakeY[0]==snakeY[i])
                    isfall=true;
            }
            repaint();
        }
        if(speed<50){
            speed=50;
        }
        timer.start();//定时器
    }
}
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号