准备工作
- 理解GUI图形化界面操作
- 理解面向对象
- 理解数组使用
- 理解随机数的使用
- 理解定时器的使用
- 理解将图片转化为流对象
代码实现
- 图片工具类
public class GetImage {
//静态属性获取蛇的上下左右,头,身体,食物的图片的BufferedImage对象
static BufferedImage right=GetImage.GetImg("/image/right.png");
static BufferedImage left=GetImage.GetImg("/image/left.png");
static BufferedImage down=GetImage.GetImg("/image/down.png");
static BufferedImage up=GetImage.GetImg("/image/up.png");
static BufferedImage header=GetImage.GetImg("/image/header.png");
static BufferedImage body=GetImage.GetImg("/image/body.png");
static BufferedImage food=GetImage.GetImg("/image/food.png");
//静态方法加载图片转化为BufferedImage对象
public static BufferedImage GetImg(String path){
BufferedImage img;
try {
//加载图片路径
img=ImageIO.read(GetImage.class.getResource(path));
//返回结果
return img;
} catch (IOException e) {
e.printStackTrace();
}
//如果路径错误,返回为null
return null;
}
}
- 面板类
public class GameJPanel extends JPanel {
//定义小蛇的初始长度
int length;
//定义小蛇的X轴坐标
int[] snakeX = new int[100];
//定义小蛇的Y轴坐标
int[] snakeY = new int[100];
//定义游戏开始
boolean isStart = false;
//定义头部背景图片
BufferedImage header;
//定义小蛇的头部图片
BufferedImage right;
BufferedImage left;
BufferedImage down;
BufferedImage up;
//定义小蛇的身体图片
BufferedImage body;
//定义小蛇的方向
String direction = "R";
//定义食物的X坐标
int foolX;
//定义食物的Y坐标
int foolY;
//定义一个记分板
int score;
//定义定时器
Timer timer;
//定义小蛇是否死亡
boolean isDie = false;
public GameJPanel() {
//初始化面板
init();
//将焦点置为面板
setFocusable(true);
//设置监听器监听键盘按钮
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
super.keyPressed(e);
//获取键盘的key值
char c = e.getKeyChar();
if (c == KeyEvent.VK_SPACE) {
if (isDie) {
//如果小蛇死了,初始化界面,小蛇状态改变
init();
score = 0;
isDie = false;
}else {
//否则游戏开始
isStart = !isStart;
}
//重复重绘画面(动的效果)
repaint();
}
if (isStart){
//如果游戏开始,监听键盘按钮是哪个方向移动小蛇
if (c == 119) {
direction = "U";
}
if (c == 115) {
direction = "D";
}
if (c == 97) {
direction = "L";
}
if (c == 100) {
direction = "R";
}
}
}
});
//每隔0.15秒做一次actionPerformed(定时器,小蛇移动)
timer = new Timer(150, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//当游戏开始
if (isStart && isDie == false) {
//身体先动
for (int i = length - 1; i > 0; i--) {
snakeX[i] = snakeX[i - 1];
snakeY[i] = snakeY[i - 1];
}
//头部动
if (direction.equals("R")) {
snakeX[0] += 25;
}
if (direction.equals("U")) {
snakeY[0] -= 25;
}
if (direction.equals("L")) {
snakeX[0] -= 25;
}
if (direction.equals("D")) {
snakeY[0] += 25;
}
//防止小蛇跑出边界
//右边界
if (snakeX[0] > 750) {
snakeX[0] = 25;
}
//下边界
if (snakeY[0] > 725) {
snakeY[0] = 100;
//左边界
}
if (snakeX[0] < 25) {
snakeX[0] = 750;
//上边界
}
if (snakeY[0] < 100) {
snakeY[0] = 725;
}
//如果小蛇碰到自己任何一节身体,则死亡
for (int i = 1; i < length; i++) {
if (snakeX[i] == snakeX[0] && snakeY[i] == snakeY[0]) {
isDie = true;
}
}
if (snakeX[0] == foolX && snakeY[0] == foolY) {
//每吃一个食物蛇长度加一
length++;
//随机食物出现的位置
int X = 25 + 25 * (new Random().nextInt(28));
int Y = 100 + 25 * (new Random().nextInt(25));
foolX = X;
foolY = Y;
//通过判断长度判断当前分数
score = (length - 3) * 10;
}
//重新绘制图像
repaint();
}
}
});
//调用定时器启动
timer.start();
}
public void init() {
//初始化背景、蛇和食物的位置
length = 3;
snakeX[0] = 250;
snakeY[0] = 375;
snakeX[1] = 225;
snakeY[1] = 375;
snakeX[2] = 200;
snakeY[2] = 375;
//设置面板背景图片
setBackground(new Color(0x226C6F));
//设置食物初始坐标
foolX = 325;
foolY = 300;
//初始化游戏为暂停
isStart = false;
//初始化游戏向右方向
direction="R";
}
//画板方法
@Override
public void paint(Graphics g) {
//添加画板
super.paint(g);
g.drawImage(GetImage.food, foolX, foolY, null);
//将头部背景图片画入
g.drawImage(GetImage.header, 10, 10, null);
//将小蛇头部画入
if (direction.equals("R")) {
g.drawImage(GetImage.right, snakeX[0], snakeY[0], null);
}
if (direction.equals("L")) {
g.drawImage(GetImage.left, snakeX[0], snakeY[0], null);
}
if (direction.equals("U")) {
g.drawImage(GetImage.up, snakeX[0], snakeY[0], null);
}
if (direction.equals("D")) {
g.drawImage(GetImage.down, snakeX[0], snakeY[0], null);
}
//将小蛇身体画入
for (int i = 1; i < length; i++) {
g.drawImage(GetImage.body, snakeX[i], snakeY[i], null);
}
//设置当游戏开始或者暂停时出现画面
if (isStart == false) {
g.setColor(new Color(0x894D14));
g.setFont(new Font("微软雅黑", Font.BOLD, 40));
g.drawString("点击空格开始或者暂停", 200, 300);
}
//设置积分数
g.setColor(new Color(0xFFFFFF));
g.setFont(new Font("微软雅黑", Font.BOLD, 20));
g.drawString("积分: " + score, 620, 40);
if (isDie) {
//如果小蛇死亡,则出现死亡画面
g.setColor(new Color(0xFF3DFD));
g.setFont(new Font("微软雅黑", Font.BOLD, 40));
g.drawString("游戏结束,请重新按空格进行游戏", 100, 400);
}
}
}
- 窗体和启动入口
public class GameJFrame extends JFrame{
//构造方法中设置一些属性
public GameJFrame(){
//设置窗体标题
setTitle("贪吃蛇小游戏");
//设置窗体不能改变大小
setResizable(false);
//获取当前电脑的屏幕的宽度
int width=Toolkit.getDefaultToolkit().getScreenSize().width;
//获取当前电脑的屏幕的高度
int height=Toolkit.getDefaultToolkit().getScreenSize().height;
//设置窗体的大小(x轴,y轴,宽度,高度)
setBounds((width-800)/2,(height-800)/2,800,800);
//设置窗体关闭按钮结束程序
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
//创建一个窗体:
GameJFrame frame=new GameJFrame();
//创建一个面板:
GameJPanel panel=new GameJPanel();
//将面板添加到窗体中
frame.add(panel);
//设置窗体可见
frame.setVisible(true);
}
}
图片素材