贪吃蛇小游戏(代码)
package com.msb.game;
import javax.swing.*;
import java.net.URI;
import java.net.URL;
/**
* @Auther: xzq
* Images这个类专门用来获取图片
*/
public class Images {
//将图片的路径封装成一个对象
public static URL headerURL = Images.class.getResource("/Images/header.png");
//将图片封装成一个对象
public static ImageIcon headerImg = new ImageIcon(headerURL);
public static URL bodyURL = Images.class.getResource("/Images/body.png");
public static ImageIcon bodyImg = new ImageIcon(bodyURL);
public static URL foodURL = Images.class.getResource("/Images/food.png");
public static ImageIcon foodImg = new ImageIcon(foodURL);
public static URL upURL = Images.class.getResource("/Images/up.png");
public static ImageIcon upImg = new ImageIcon(upURL);
public static URL downURL = Images.class.getResource("/Images/down.png");
public static ImageIcon downImg = new ImageIcon(downURL);
public static URL leftURL = Images.class.getResource("/Images/left.png");
public static ImageIcon leftImg = new ImageIcon(leftURL);
public static URL rightURL = Images.class.getResource("/Images/right.png");
public static ImageIcon rightImg = new ImageIcon(rightURL);
}
package com.msb.game;
import javax.swing.*;
import java.awt.*;
/**
* @Auther: xzq
*/
public class StartGame {
public static void main(String[] args) {
//创建窗体
JFrame jf = new JFrame();
//设置一个标题
jf.setTitle("贪吃蛇小游戏");
//设置窗体的大小和位置
int width = Toolkit.getDefaultToolkit().getScreenSize().width; //屏幕的宽
int height = Toolkit.getDefaultToolkit().getScreenSize().height; //屏幕的高
jf.setBounds((width-500)/2,(height-500)/2,500,500);
//设置窗体大小不可调节
jf.setResizable(false);
//设置窗口关闭的同时,程序关闭
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//创建面板
GamePanel gp = new GamePanel();
//将面板加入窗口
jf.add(gp);
//显示窗口(默认关闭)
jf.setVisible(true);
}
}
package com.msb.game;
import javafx.scene.input.KeyCode;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
/**
* @Auther: xzq
* GamePanel继承JPanel以后才具备面板功能
*/
public class GamePanel extends JPanel {
//定义两个数组
//蛇的长度:
int length;
//一个数组专门记录蛇的X轴坐标
int[] snakeX = new int[200];
//一个数组专门记录蛇的Y轴坐标
int[] snakeY = new int[200];
//定义蛇的行走方向:
String direction;
//游戏只有两个状态,运行和暂停
boolean isStart = false; //默认暂停
//加入一个定时器
Timer timer;
//定义一个食物坐标
int foodX;
int foodY;
//定义一个积分
int score;
//定义小蛇的状态,判断是否死亡
boolean isDie = false; //默认非死亡
public void init(){
//初始化蛇的长度
length = 3;
//初始化蛇头坐标
snakeX[0] = 175;
snakeY[0] = 275;
//初始化第一节身子的坐标
snakeX[1] = 150;
snakeY[1] = 275;
//初始化第二节身子的坐标
snakeX[2] = 125;
snakeY[2] = 275;
//初始化蛇头的方向
direction = "R";
//初始化食物坐标
foodX = (int)(Math.random()*18+1)*25; //[25,450] [1,18]*25
foodY = (int)(Math.random()*15+3)*25; //[75,425] [3,17]*25
//初始化积分
score = 0;
}
public GamePanel(){
init();
//将焦点定位在当前操作面板上
this.setFocusable(true);
//加入监听
this.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
super.keyPressed(e);
int keyCode = e.getKeyCode(); //监听键盘输入的按键
System.out.println(keyCode);
if(keyCode==KeyEvent.VK_SPACE){ //如果是空格
if(isDie){
init(); //小蛇死亡,恢复初始状态
isDie = false;
}else{
isStart = !isStart;
repaint(); //重绘动作
}
}
//监听向上箭头
if(keyCode==KeyEvent.VK_UP){
direction = "U";
}
//监听向下箭头
if(keyCode==KeyEvent.VK_DOWN){
direction = "D";
}
//监听向左箭头
if(keyCode==KeyEvent.VK_LEFT){
direction = "L";
}
//监听向右箭头
if(keyCode==KeyEvent.VK_RIGHT){
direction = "R";
}
}
});
//对定时器进行初始化动作
timer =new Timer(100, new ActionListener() {
/*
ActionListener是 事件监听
相对于每100ms监听一下你是否发生了动作
具体的动作放入actionPerformed
*/
@Override
public void actionPerformed(ActionEvent e) {
if(isStart && !isDie){ //非死亡状态才能动
//后一节身子到前一节身子的位置
for (int i = length-1; i > 0; i--) {
snakeX[i] = snakeX[i-1];
snakeY[i] = snakeY[i-1];
}
//动蛇头
if(direction=="U"){
snakeY[0] -= 25;
}
if(direction=="D"){
snakeY[0] += 25;
}
if(direction=="L"){
snakeX[0] -= 25;
}
if(direction=="R"){
snakeX[0] += 25;
}
//防止超出边界
if(snakeY[0]<75){
snakeY[0] = 425;
}
if(snakeY[0]>425){
snakeY[0] = 75;
}
if(snakeX[0]<25){
snakeX[0] = 450;
}
if(snakeX[0]>450){
snakeX[0] = 25;
}
//发生碰撞,蛇头碰到食物或者食物出现在蛇身体里
for (int i = 0; i < length; i++) {
if(snakeX[i]==foodX && snakeY[i]==foodY){
length++;
foodX = (int)(Math.random()*18+1)*25; //[25,450] [1,18]*25
foodY = (int)(Math.random()*15+3)*25; //[75,425] [3,17]*25
score += 10;
}
}
//死亡判断
for (int i = 1; i < length; i++) {
if(snakeX[0]==snakeX[i] && snakeY[0]==snakeY[i]){
isDie = true;
}
}
repaint(); //重绘
}
}
});
timer.start();
}
//paintComponent这个方法比较特殊,属于图形版的main方法,自动调用
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
//填充背景颜色
this.setBackground(new Color(181, 201, 177));
//画头部图片
/*
paintIcon四个参数:this:当前面板,g:当前画笔,x和y对应坐标
*/
Images.headerImg.paintIcon(this,g,10,10);
//改变画笔颜色
g.setColor(new Color(233, 250, 239));
//画一个矩形
g.fillRect(10,70,460,380);
//画小蛇
//1.画蛇头
if("U".equals(direction)){
Images.upImg.paintIcon(this,g,snakeX[0],snakeY[0]);
}
if("D".equals(direction)){
Images.downImg.paintIcon(this,g,snakeX[0],snakeY[0]);
}
if("L".equals(direction)){
Images.leftImg.paintIcon(this,g,snakeX[0],snakeY[0]);
}
if("R".equals(direction)){
Images.rightImg.paintIcon(this,g,snakeX[0],snakeY[0]);
}
//2.画蛇身
for (int i = 1; i < length; i++) {
Images.bodyImg.paintIcon(this,g,snakeX[i],snakeY[i]);
}
//如果游戏是暂停的,有提示语
if(isStart==false){
//画一个文字
g.setColor(new Color(114,98,255)); //画笔颜色
//三个参数:字体、加粗、色号
g.setFont(new Font("宋体",Font.BOLD,20));
//画文字
g.drawString("点击空格开始游戏",170,250);
}
//画食物
Images.foodImg.paintIcon(this,g,foodX,foodY);
//画积分
g.setColor(new Color(255, 16, 55)); //画笔颜色
g.setFont(new Font("宋体",Font.BOLD,20));
g.drawString("积分:"+score,350,50);
//死亡之后
if(isDie){
g.setColor(new Color(114,98,255)); //画笔颜色
g.setFont(new Font("宋体",Font.BOLD,20));
g.drawString("游戏结束,你获得"+score+"积分,请按空格重新开始",30,250);
}
}
}