关于本次程序用到的的技能有:数组、监听器、适配器、定时器、本次用到的Java的swing不需要记住这已经被淘汰
效果展示
窗口
import javax.swing.*;
import java.awt.*;
public class DomeMain {
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-800)/2,(height-800)/2,800,800);
//设置窗体大小不可调
jf.setResizable(false);
//关闭窗口的同时关闭程序
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//创建面板:
GamePanel gp = new GamePanel();
//将面板放入窗体
jf.add(gp);
//默认情况下窗体是隐藏效果,必须将窗体进行显现:细节-->这个显现方法最好放在最后
jf.setVisible(true);
}
}
把图片抽象化
import javax.swing.*;
import java.net.URL;
//本类专门用来获取游戏中所涉及的图片
public class Images {
//面向对象的语言,面向对象的思维-->将图片进行封装,封装成为一个对象,这样在程序中才可以通过操作这个对象来操做图片
//将图片封装为一个对象
public static URL bodyURL = Images.class.getResource("/images/body.jpg");
//将图片封装为程序的一个对象
public static ImageIcon bodyImg = new ImageIcon(bodyURL);
//将图片封装为一个对象
public static URL foodURL = Images.class.getResource("/images/food.jpg");
//将图片封装为程序的一个对象
public static ImageIcon foodImg = new ImageIcon(foodURL);//将图片封装为一个对象
public static URL headURL = Images.class.getResource("/images/head.jpg");
//将图片封装为程序的一个对象
public static ImageIcon headImg = new ImageIcon(headURL);//将图片封装为一个对象
public static URL downURL = Images.class.getResource("/images/head - down.jpg");
//将图片封装为程序的一个对象
public static ImageIcon downImg = new ImageIcon(downURL);
//将图片封装为一个对象
public static URL leftURL = Images.class.getResource("/images/head - left.jpg");
//将图片封装为程序的一个对象
public static ImageIcon leftImg = new ImageIcon(leftURL);
//将图片封装为一个对象
public static URL rightURL = Images.class.getResource("/images/head - right.jpg");
//将图片封装为程序的一个对象
public static ImageIcon rightImg = new ImageIcon(rightURL);
//将图片封装为一个对象
public static URL titleURL = Images.class.getResource("/images/title.jpg");
//将图片封装为程序的一个对象
public static ImageIcon titleImg = new ImageIcon(titleURL);
}
程序的逻辑代码
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
//GamePanel继承了JPanel以后,才具备面板的功能,才能成为一个面板
public class GamePanel extends JPanel{//paintComponent这个方法比较特殊,这个方法就属于图形版的main方法,自动调用
//定义两个数组
//蛇的长度
int lenght;
//一个数组,专门存储蛇的X轴坐标
int[] snakeX = new int[200];
//一个数组,专门存储蛇的Y轴坐标
int[] snakeY = new int[200];
//游戏只有两个状态:开始,结束
boolean isStart = false;//默认是暂停
//加入一个定时器
Timer timer;
//定义蛇的行走放向
String direction;
//定义食物的X,Y轴坐标
int foodX;
int foodY;
//定义一个积分
int score;
//加入一个变量,判断小蛇的死亡状态
boolean isDie = false;//默认情况小蛇没有死亡
public void init(){
//初始化蛇的长度
lenght = 3;
//初始化蛇头坐标
snakeX[0] = 175;
snakeY[0] = 275;
//初始化第一节身子坐标
snakeX[1] = 150;
snakeY[1] = 275;
//初始化第二节身子坐标
snakeX[2] = 125;
snakeY[2] = 275;
//初始化蛇的蛇头方向
direction = "R";//U D L R
//初始化食物的坐标
foodX = 300;
foodY = 200;
//初始化一个积分
score = 0;
}
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{//小蛇没有死亡的情况下
System.out.println("点击了空格");
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() {
@Override
public void actionPerformed(ActionEvent e) {//事件监听,相当于每100ms监听一下你是否发生了一个动作具体的动作放入actionPerformed
if (isStart&&isDie == false){//游戏是开始状态的时候,蛇才动,后一节身子走到前一节身子的位置上
for (int i = lenght-1;i>0;i--){
snakeX[i] = snakeX[i-1];
snakeY[i] = snakeY[i-1];
}
//动头
if ("R".equals(direction)){
snakeX[0]+=25;
}
if ("L".equals(direction)){
snakeX[0]-=25;
}
if ("U".equals(direction)){
snakeY[0]-=25;
}
if ("D".equals(direction)){
snakeY[0]+=25;
}
//防止蛇超出边界
if (snakeX[0]>750){
snakeX[0] = 25;
}
if (snakeX[0]<25){
snakeX[0] = 750;
}
if (snakeY[0]<100){
snakeY[0] = 725;
}
if (snakeY[0]>750){
snakeY[0] = 100;
}
//检测碰撞操作:
//食物的坐标和蛇头的坐标一样是,算作碰到
if (snakeX[0] == foodX&&snakeY[0] == foodY){
//蛇的长度+1
lenght++;
//食物的坐标改变,随机生成坐标坐标必须是25的倍数
/*
[25,750] -> [1,30]*25
Math.random() -> [0.0,1.0)
Math.random()*30 -> [0.0,30.0)
(int)(Math.random()*30)+1 ->[1,30]
*/
/*
[100,725] -> [4,29]*25
[4,29]->[0,25]+4
[0,25]
new Random().nextInt(26) -> [0,26) ->[0,25]
*/
foodX = ((int)(Math.random()*30)+1)*25;//【25,750】
foodY = (new Random().nextInt(26)+4)*25;//【100,725】
//吃上食物以后 积分加十分
score += 10;
}
//死亡判定
for (int i = 1;i<lenght;i++){
if (snakeX[i] == snakeX[0]&&snakeY[i] == snakeY[0]){
//将死亡状态改为true
isDie = true;
}
}
repaint();//重绘
}
}
});
//定时器必须要启动
timer.start();
}
@Override
protected void paintChildren(Graphics g) {
super.paintChildren(g);
//填充背景颜色
this.setBackground(new Color(77,255,36));
//paintIcon四个参数:this指的是当前面板 g:指的是当前使用的画笔 x,y对应的坐标
Images.titleImg.paintIcon(this,g,2,10);//头部图片
//调整话笔颜色
g.setColor(new Color(240,245,117));
//画一个矩形
g.fillRect(6,70,775,685);
//画小蛇
//蛇头朝向
if("R".equals(direction)){
Images.rightImg.paintIcon(this,g,snakeX[0],snakeY[0]);
}else if ("L".equals(direction)){
Images.leftImg.paintIcon(this,g,snakeX[0],snakeY[0]);
}else if ("U".equals(direction)){
Images.headImg.paintIcon(this,g,snakeX[0],snakeY[0]);
}else if("D".equals(direction)){
Images.downImg.paintIcon(this,g,snakeX[0],snakeY[0]);
}
// //第一节身子
// Images.bodyImg.paintIcon(this,g,snakeX[1],snakeY[1]);
// //第二节身子
// Images.bodyImg.paintIcon(this,g,snakeX[2],snakeY[2]);
//优化为循环画蛇的部分
for (int i = 1;i<lenght;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,40));
//画文字:三个参数:文字内容,X轴坐标,Y轴坐标
g.drawString("点击空格开始游戏",250,300);
}
//画食物:
Images.foodImg.paintIcon(this,g,foodX,foodY);
//画积分
g.setColor(new Color(255,3,9));//颜色
//三个参数:字体,加粗,字号
g.setFont(new Font("微软雅黑",Font.BOLD,20));
//画文字:三个参数:文字内容,X轴坐标,Y轴坐标
g.drawString(""+score,650,40);
//画入死亡状态
if (isDie){
g.setColor(new Color(255,3,9));//颜色
//三个参数:字体,加粗,字号
g.setFont(new Font("微软雅黑",Font.BOLD,35));
//画文字:三个参数:文字内容,X轴坐标,Y轴坐标
g.drawString("小蛇死亡 共得分:"+score,200,200);
}
}
}