视频链接:21、贪吃蛇之界面绘制_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1DJ411B75F?p=21&vd_source=b5775c3a4ea16a5306db9c7c1c1486b5
1.游戏中用的的图片素材
1.贪吃蛇游戏的主启动类StartGame;
package com.yundait.snake;
import javax.swing.*;
import java.awt.*;
//贪吃蛇游戏的主启动类;
public class StartGame {
public static void main(String[] args) {
JFrame frame = new JFrame("我的游戏—贪吃蛇");//创建游戏窗口
frame.setBounds(10,10,915,745);//设置窗口的位置和长宽
frame.setResizable(false);//设置窗口尺寸不可调
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//设置窗口关闭事件
Container container = frame.getContentPane();//创建一个内容窗格的容器
container.add(new GamePanel());//将面板放在容器上
frame.setVisible(true);//设置窗口可见
}
}
2.贪吃蛇游戏的数据类Data:存放游戏界的图片
package com.yundait.snake;
import javax.swing.*;
import java.net.URL;
public class Data {
public static URL headerURL = Data.class.getResource("statics/header.png");//获取标题图片
public static ImageIcon header = new ImageIcon(headerURL);//创建标题图标
public static URL upURL = Data.class.getResource("statics/up.png");//获取朝上的头部图片
public static URL downURL = Data.class.getResource("statics/down.png");//获取朝下的头部图片
public static URL leftURL = Data.class.getResource("statics/left.png");//获取朝左的头部图片
public static URL rightURL = Data.class.getResource("statics/right.png");//获取朝右的头部图片
public static URL bodyURL = Data.class.getResource("statics/body.png");//获取朝右的头部图片
public static ImageIcon up = new ImageIcon(upURL);//创建朝上的头部图标
public static ImageIcon down = new ImageIcon(downURL);//创建朝下的头部图标
public static ImageIcon left = new ImageIcon(leftURL);//创建朝左的头部图标
public static ImageIcon right = new ImageIcon(rightURL);//创建朝右的头部图标
public static ImageIcon body = new ImageIcon(bodyURL);//创建朝右的头部图标
public static URL foodURL = Data.class.getResource("statics/food.png");//获取食物图片
public static ImageIcon food = new ImageIcon(foodURL);//创建食物图标
}
3.贪吃蛇游戏的游戏面板GamePanel:主要功能都在类下此实现
package com.yundait.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 GamePanel extends JPanel implements KeyListener, ActionListener {
int length; //定义蛇的长度
int[]snakeX= new int[600];//蛇的X坐标
int[]snakeY= new int[500];//蛇的Y坐标
String direction;//定义小蛇头的方向参数
int food_x;
int food_y;
int score;
Random random = new Random();
boolean isStart;//游戏开始、结束的状态
boolean isFail;//游戏失败状态
Timer timer = new Timer(100,this);//创建一个定时器,每100毫秒执行一次(每秒执行10次)
//构造器方法
public GamePanel() {
init();
this.setFocusable(true);//获得焦点事件
this.addKeyListener(this);//添加键盘监听
}
//数据初始化方法
public void init(){
length = 3;//初始化小蛇长度,包含小蛇头
snakeX[0] = 100;snakeY[0] = 100;//初始化小蛇脑袋的坐标
snakeX[1] = 75;snakeY[1] = 100;//初始化小蛇第1段身体的坐标
snakeX[2] = 50 ;snakeY[2] = 100;//初始化小蛇第2段身体的坐标
direction = "right"; //初始化小蛇头的方向(向右)
isStart = false;//游戏默认处于停止状态
isFail = false;
timer.start();//游戏一开始,就启动定时器。
score = 0;
//把食物随机分派在界面上
food_x = 25 + 25*random.nextInt(34);
food_y = 75 + 25*random.nextInt(24);
}
//绘制面板,我们游戏中的所有东西,都用这支画笔来画
@Override
protected void paintComponent(Graphics g) {
//清屏
super.paintComponent(g);
//绘制静态游戏面板
this.setBackground(new Color(255, 255, 255));//设置面板的颜色
Data.header.paintIcon(this,g,25,11);//把头部广告栏画上去
g.setColor(new Color(110, 164, 176));//设置画笔的颜色
g.fillRect(25,75,850,600);//画一个默认的矩形游戏界面
//把分数画在界面上
g.setColor(Color.white);
g.setFont(new Font("微软雅黑",Font.BOLD,18));
g.drawString("长度:" + length,750,30);
g.drawString("分数:" + score,750,55);
//把食物画在界面上
Data.food.paintIcon(this,g,food_x,food_y);
//使用switch选择结构把小蛇的头画在面板上
switch (direction){
case "right":
Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);//把朝右的小蛇头画在面板上
break;
case "left":
Data.left.paintIcon(this,g,snakeX[0],snakeY[0]);//把朝左的小蛇头画在面板上
break;
case "up":
Data.up.paintIcon(this,g,snakeX[0],snakeY[0]);//把朝上的小蛇头画在面板上
break;
case "down":
Data.down.paintIcon(this,g,snakeX[0],snakeY[0]);//把朝下的小蛇头画在面板上
break;
}
//使用循环结构把小蛇身体画在面板上
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,350);
}
//判断游戏是否失败,失败后显示:"游戏失败,按下空格重新开始"
if (isFail){
g.setColor(Color.red);
g.setFont(new Font("微软雅黑",Font.BOLD,40));
g.drawString("游戏失败,按下空格重新开始",300,350);
}
}
//键盘监听事件
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();//获得键盘按下了哪一个
if (keyCode == KeyEvent.VK_SPACE){
if (isFail){
//游戏重新开始
isFail =false;
init();
}else {
isStart = !isStart;//游戏状态取反
}
repaint();
}
//监听键盘输入,根据键盘输入不同,改变小蛇方向
if (keyCode == KeyEvent.VK_UP && !direction.equals("down")){
direction = "up";
} else if (keyCode == KeyEvent.VK_DOWN && !direction.equals("up")) {
direction = "down";
} else if (keyCode == KeyEvent.VK_LEFT && !direction.equals("right")) {
direction = "left";
} else if (keyCode == KeyEvent.VK_RIGHT && !direction.equals("left")) {
direction = "right";
}
}
//事件监听----需要通过固定的时间来刷新
@Override
public void actionPerformed(ActionEvent e) {
if (isStart && !isFail){
//监听小蛇吃食物
if (snakeX[0] == food_x && snakeY[0] == food_y){
//再次随机一个食物的坐标
food_x = 25 + 25*random.nextInt(34);
food_y = 75 + 25*random.nextInt(24);
//吃完食物,身体长度加1
length = length +1;
score+=10;
}
//使用for循环让小蛇的后一节身体一动到前一节位置
for (int i = length-1; i > 0 ; i--) {
snakeX[i] = snakeX[i-1];
snakeY[i] = snakeY[i-1];
}
//控制小蛇移动,撞墙后游戏失败
if (direction.equals("right")){
snakeX[0] = snakeX[0]+25;
if (snakeX[0]>850){isFail = true;}
} else if (direction.equals("left")) {
snakeX[0] = snakeX[0]-25;
if (snakeX[0]<25){isFail = true;}
} else if (direction.equals("up")) {
snakeY[0] = snakeY[0]-25;
if (snakeY[0]<75){isFail = true;}
} else if (direction.equals("down")) {
snakeY[0] = snakeY[0]+25;
if (snakeY[0]>650){isFail = true;}
}
//判断小蛇是否撞到自己,撞到自己后游戏失败
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 keyTyped(KeyEvent e) {
}//用不到,不需要重写方法,放在这里即可;
@Override
public void keyReleased(KeyEvent e) {
}//用不到,不需要重写方法,放在这里即可;
}
4.GUI编程内容总结