第十三天 前面的十二天如果你看完了,那么今天你就可以试试这一款属于自己的小游戏啦
一步步写的,小白可以看哦。思维简单,eclipse开发,并且资源已经上传,下面就是详细步骤
贪吃蛇小游戏
- 创建java项目
1.1点击file-new-java Project,记得不要选eclipse自带的jdk
1.2导入静态图片 - 绘制静态窗口
public class StartGame {
public static void main(String[] args) {
//绘制一个界面 JFrame
JFrame frame=new JFrame("不辞树贪吃蛇游戏");
//设置界面的大小 set bounds 设定界限
frame.setBounds(10,10,900,720);
//窗口大小不可改变 resizable可调整大小
frame.setResizable(false);
//设置关闭游戏,让游戏界面关闭 DefaultCloseOperation默认关闭操作
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//让窗口展现出来 setVisible可见
frame.setVisible(true);
}
}
- 绘制游戏的面板
//界面
public class GamePanel extends JPanel{
//Graphics:画笔
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(Color.BLACK);//设置我们的背景颜色
}
}
- 画静态的小蛇
4.1、绘制头部区域和游戏区域
1、创建一个存储外部资源的一个类:
public class Data {
//头部图片
public static URL headerUrl=Data.class.getResource("/statics/header.png");
public static ImageIcon head=new ImageIcon(headerUrl);
}
2、在画板中绘制我们的头部信息和游戏区域
public class GamePanel extends JPanel{
//Graphics:画笔
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(Color.WHITE);//设置我们的背景颜色
Data.head.paintIcon(this, g, 25,11); //绘制我们的头部信息
g.fillRect(25, 75, 850, 600);//绘制我们的游戏区
}
}
3、将我们的画板添加到我们的静态窗口中
public class StartGame {
public static void main(String[] args) {
//绘制一个界面 JFrame
JFrame frame=new JFrame("不辞树贪吃蛇游戏");
//设置界面的大小
frame.setBounds(10,10,900,720);
//窗口大小不可改变
frame.setResizable(false);
//设置关闭游戏,让游戏界面关闭
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//在界面添加我们的画板
frame.add(new GamePanel());
//让窗口展现出来
frame.setVisible(true);
}
}
4.2、在画板中引入小蛇坐标
1、在GamePanel类中初始化蛇的坐标和长度
int length; //小蛇的长度
int[] snakeX=new int[600]; //蛇的x坐标
int[] snakeY=new int[500]; //蛇的y坐标
public GamePanel() { //构造方法初始化
init();
}
//初始化蛇的长度和坐标
public void init() {
length=3; //刚开始默认的长度为3
//初始化开始的蛇,给蛇定位,
snakeX[0] = 100; snakeY[0] = 100;
snakeX[1] = 75; snakeY[1] = 100;
snakeX[2] = 50; snakeY[2] = 100;
}
2、在Data类中引入蛇的静态图片
//头部:上下左右 URL路径 getResource 获取资源 ImageIcon图像图标
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 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 URL bodyUrl = Data.class.getResource("/statics/body.png");
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、在面板中绘制我们的静态蛇
Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);//绘制我们的蛇头
for (int i = 1; i < length; i++) {//绘制我们的蛇身
Data.body.paintIcon(this, g, snakeX[i], snakeY[i]);
- 小蛇动起来
5.1初始化方向和定时器,修改构造方法
String fx="R"; //方向:上:U 下:D 左:L 有:R
Timer timer = new Timer(100, this); //定时器:第一个参数,就是定时执行时间
public GamePanel() {
init();
this.setFocusable(true); //获取焦点事件
this.addKeyListener(this);//键盘监听事件
timer.start();//让时间动起来
}
5.2、实现两个接口,并重写里面的方法
KeyListener
ActionListener
5.3、在keyPressed方法中监听键盘
int keyCode=e.getKeyCode(); //获取按下的键
//键盘控制走向
if (keyCode==KeyEvent.VK_LEFT){
fx = "L";
}else if (keyCode==KeyEvent.VK_RIGHT){
fx = "R";
}else if (keyCode==KeyEvent.VK_UP){
fx = "U";
}else if (keyCode==KeyEvent.VK_DOWN){
fx = "D";
}
5.4、在actionPerformed方法中进行定时移动
//除了脑袋都往前移:身体移动
for (int i = length-1; i >0; i--) {
snakeX[i]=snakeX[i-1];//即第i节(后一节)的位置变为(i-1:前一节)节的位置!
snakeY[i]=snakeY[i-1];
}
//通过方向控制,头部移动
if(fx.equals("R")) {
snakeX[0]=snakeX[0]+25;
if(snakeX[0]>850) {snakeX[0]=25;}
}else if(fx.equals("L")) {
snakeX[0]=snakeX[0]-25;
if(snakeX[0]<25) {snakeX[0]=850;}
}else if(fx.equals("U")) {
snakeY[0]=snakeY[0]-25;
if(snakeY[0]<75) {snakeY[0]=650;}
}else if (fx.equals("D")){
snakeY[0] = snakeY[0]+25;
if (snakeY[0]>650) snakeY[0] = 75;
}
repaint(); //需要不断的更新页面实现动画
timer.start(); //让时间动起来
5.5、修改画板画小蛇的方式
修改画板画小蛇的方式
//把小蛇画上去
if (fx.equals("R")){ //蛇的头通过方向变量来判断
Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);
}else if (fx.equals("L")){
Data.left.paintIcon(this,g,snakeX[0],snakeY[0]);
}else if (fx.equals("U")){
Data.up.paintIcon(this,g,snakeX[0],snakeY[0]);
}else if (fx.equals("D")){
Data.down.paintIcon(this,g,snakeX[0],snakeY[0]);
}
for (int i = 1; i < length; i++) {
Data.body.paintIcon(this,g,snakeX[i],snakeY[i]); //蛇的身体长度根据lenth来控制
}
- 设置我们的开始和结束
6.1、定义我们的结束或者开始的标志并初始化
Boolean isStart=false;// 设置我们的开始和暂停的标志
6.2、在画板中判断开始还是结束
// 判断我们的游戏开始还是结束
if (isStart == false) {
g.setColor(Color.white);
g.setFont(new Font("微软雅黑", Font.BOLD, 40));
g.drawString("按下空格开始游戏!", 300, 300);
}
6.3、监听空格键
int keyCode = e.getKeyCode(); // 获取按下的键
if (keyCode == KeyEvent.VK_SPACE) {
isStart = !isStart;
repaint();
}
// 键盘控制走向
if (keyCode == KeyEvent.VK_LEFT) {
fx = "L";
} else if (keyCode == KeyEvent.VK_RIGHT) {
fx = "R";
} else if (keyCode == KeyEvent.VK_UP) {
fx = "U";
} else if (keyCode == KeyEvent.VK_DOWN) {
fx = "D";
}
6.3、定时执行操作
7. 吃食物
7.1、定义食物坐标
//食物
int foodx;
int foody;
Random random=new Random();//产生随机数
7.2、init方法中初始化
//初始化食物
foodx=25+25*random.nextInt(34);
foody=75+25*random.nextInt(24);
7.3、绘制小蛇
//画食物
Data.food.paintIcon(this, g, foodx, foody);
7.4、在定时方法中让小蛇吃食物
//小蛇吃食物
if(snakeX[0]==foodx&&snakeY[0]==foody) {
length++;
foodx=25+25*random.nextInt(34);
foody=75+25*random.nextInt(24);
}
- 分数和失败的判定
8.1、分数和失败判定标识的初始化
boolean isFail = false; //游戏是否结束
int score; //游戏分数!
8.2、init方法中分数的初始化(很重要),绘制我们的分数统计
//分数初始化
score=0;
//画积分
g.setColor(Color.WHITE);
g.setFont(new Font("微软雅黑", Font.BOLD, 18)); // 微软雅黑,加粗 ,40号
g.drawString("长度:"+length, 750, 35);
g.drawString("分数:"+score, 750, 50);
8.3、画板中判断是否游戏失败,
//失败判断
if (isFail){
g.setColor(Color.RED);
g.setFont(new Font("微软雅黑",Font.BOLD,40));
g.drawString("失败, 按下空格重新开始",300,300);
}
8.4、监听空格键(修改)
if (keyCode == KeyEvent.VK_SPACE) {
if(isFail) {//如果游戏失败,重新再来
isFail=false;
init();
}else {
isStart = !isStart;//否则,暂停游戏
}
repaint();
}
8.5、定时操作中失败的判定
//小蛇吃食物
if(snakeX[0]==foodx&&snakeY[0]==foody) {
length++;
foodx=25+25*random.nextInt(34);
foody=75+25*random.nextInt(24);
score=score+10;//分数加10
}
//判断是否蛇头和蛇身碰撞
for (int i = 1; i < length; i++) {
if(snakeX[i]==snakeX[0]&&snakeY[i]==snakeY[0]) {
isFail=true;
}
}