启动游戏类
public class StartGame {
public static void main(String[] args) {
JFrame jFrame = new JFrame("贪吃蛇游戏");
jFrame.setBounds(10,10,900,720);//框架大小
jFrame.add(new GamePanel()); //创建游戏面板
jFrame.setResizable(false); //窗口大小不可变
jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //窗口关闭监听
jFrame.setVisible(true); //设置窗口可以见性,建议在测试类最后设置,以免焦点丢失,导致键盘监听失效
}
}
游戏画面素材类
import javax.swing.*;
import java.net.URL;
public class Data{
public static URL headerURL= Data.class.getResource("statics/header2.png"); //获得头目栏资源地址
public static ImageIcon header = new ImageIcon(headerURL); //创建头目栏图标
public static URL bodyURL= Data.class.getResource("statics/body.png"); //获得蛇身体资源地址
public static ImageIcon body = new ImageIcon(bodyURL); //创建蛇身体图标
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 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 foodURL= Data.class.getResource("statics/food.png"); //获得食物资源地址
public static ImageIcon food = new ImageIcon(foodURL); //创建食物图标
}
游戏面板类
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;
/*总思路:
1.创建状态变量
2.利用画笔,“画”到游戏面板
3.编写监听事件或键盘监听
*/
public class GamePanel extends JPanel implements KeyListener , ActionListener {
int length; //蛇的长度
boolean isStart; //游戏是否开始
int[] x = new int[100]; //头部和身体坐标
int[] y = new int[100];
int foodx; //食物坐标
int foody;
Random random = new Random(); //生成随机数,为食物坐标
String des ;//蛇头方向
boolean isFail; //游戏是否失败
int score; //分数
Timer timer = new Timer(100,this); //创建定时器
public void init(){ //初始化方法
x[0] = 100; //蛇初始状态
y[0] = 100;
x[1] = 75;
y[1] = 100;
x[2] = 50;
y[2] = 100;
length = 3; //初始长度
isStart = false; //默认初始游戏状态关
isFail = false; //默认初始状态为非失败
des = "R"; //默认蛇头向右
score = 0; //初始分数为0
foodx = 25 + random.nextInt(34) * 25; //食物初始位置
foody = 75 + random.nextInt(24) * 25;
timer.start(); //定时器记时开始
}
public GamePanel(){ //构造体
init(); //调用初始化方法
this.setFocusable(true); //设置焦点
this.addKeyListener(this); //添加键盘监听
}
@Override
protected void paintComponent(Graphics g) { //画笔
super.paintComponent(g); //清屏
this.setBackground(Color.white); //面板背景色
Data.header.paintIcon(this,g,25,11); //画头目栏
g.fillRect(25,75,850,600); //创建矩形游戏空间
if (des.equals("R")){ //根据方向,画蛇头
Data.right.paintIcon(this,g,x[0],y[0]);
}else if (des.equals("L")){
Data.left.paintIcon(this,g,x[0],y[0]);
}else if (des.equals("U")){
Data.up.paintIcon(this,g,x[0],y[0]);
}else if (des.equals("D")){
Data.down.paintIcon(this,g,x[0],y[0]);
}
for (int i = 1; i < length; i++) { //画身体
Data.body.paintIcon(this,g,x[i],y[i]);
}
Data.food.paintIcon(this,g,foodx,foody); //画食物
g.setColor(Color.white); //画分数
g.setFont(new Font("微软雅黑",Font.BOLD,18)); //画长度和分数
g.drawString("长度"+length,750,35);
g.drawString("分数"+score,750,50);
if (!isStart){ //画游戏未开始画面
g.setColor(Color.white);
g.setFont(new Font("微软雅黑",Font.BOLD,30));
g.drawString("按下空格开始游戏",300,300);
}
if (isFail){ //画失败画面
g.setColor(Color.red);
g.setFont(new Font("微软雅黑",Font.BOLD,30));
g.drawString("失败,按下空格重新开始",300,300);
}
}
@Override
public void keyPressed(KeyEvent e) { //键盘监听事件
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_SPACE ) { //按下空格键监听
if (isFail){ //若游戏失败,游戏重新开始
isFail = false; //ifFail值改变
init(); //初始化
}
else {
isStart = !isStart; //否则,游戏开始与暂停切换
}
repaint(); //重画
}
if (keyCode == KeyEvent.VK_UP){ //按下方向键改变蛇头方法
des = "U";
}else if (keyCode == KeyEvent.VK_DOWN){
des = "D";
}else if (keyCode == KeyEvent.VK_LEFT){
des = "L";
}else if (keyCode == KeyEvent.VK_RIGHT){
des = "R";
}
}
public void actionPerformed(ActionEvent e) { //事件监听事件
if(isStart && !isFail) { //如果游戏为开始状态且未失败事件,让小蛇动起来
for (int i = length - 1; i > 0; i--) { //身体改变
x[i] = x[i - 1];
y[i] = y[i - 1];
}
if (des.equals("R")) { //根据蛇头方向,改变蛇头位置
x[0] = x[0] + 25;
if (x[0] > 850) {
x[0] = 0;
}
}else if (des.equals("L")){
x[0] = x[0] - 25;
if (x[0]<25){
x[0] = 850;
}
}else if (des.equals("U")){
y[0] = y[0] - 25;
if (y[0] < 75){
y[0] = 650;
}
}else if (des.equals("D")){
y[0] = y[0] + 25;
if (y[0] > 650){
y[0] = 75;
}
}
if (foodx == x[0] && foody == y[0] ){ //吃到食物事件
length++;
score = score + 10;
foodx = 25 + 25 * random.nextInt(34);
foody = 75 + 25 * random.nextInt(24);
}
repaint(); //重画
}
for (int i = 1; i < length; i++) { //判断游戏失败事件
if (x[0] == x[i] && y[0] == y[i]){
isFail = true;
}
}
timer.start(); //定时器开启
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
}
效果