Swing贪吃蛇游戏(二):增加随机产生障碍物功能

在上一篇博文中,介绍了Swing贪吃蛇游戏基本功能的实现:

Swing贪吃蛇游戏(一):基本功能实现 >>>> [url]http://mouselearnjava.iteye.com/blog/1913290[/url]

本文在原有基本功能上增加随机产生障碍物的功能,增加些游戏的难度 :)

随机产生障碍物的功能可以有多种实现,我们可以将分数的改变作为产生随机数的条件,比如

1. 分数每增加50分,在原有的基础上随机产生一个障碍物(不改变原来已经有的障碍物位置)
2. 分数每增加50分,以50的倍数作为产生随机障碍物的个数(比如N),重新生成N个随机障碍物。

两种实现都不难,但是第二种方式的实现对玩游戏来说难度会更大。比如产生8个随机障碍物,那么相对来讲蛇体已经很长,随机产生8个随机障碍物可能同时有多个出现在蛇头附近,更加容易撞到障碍物。

本文的实现采用了方案1.

那么,为了能够完成这个功能,我们需要做哪一些改动呢?

[b]首先,增加一个障碍物类,用于记录障碍物信息。[/b]

package my.games.snake.model;

import java.awt.Graphics2D;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class Barriers implements Serializable {

private static final long serialVersionUID = -7101579102934745505L;

private List<Grid> barriersList = null;

public Barriers() {
barriersList = new ArrayList<Grid>();
}

public void draw(Graphics2D g2) {
for (Grid grid : barriersList) {
grid.draw(g2);
}
}

/**
* @return the barriersList
*/
public List<Grid> getBarriersList() {
return barriersList;
}

/**
* @param barriersList
* the barriersList to set
*/
public void setBarriersList(List<Grid> barriersList) {
this.barriersList = barriersList;
}

}

[b]
其次,增加随机产生随机障碍物的代码。[/b],在SnakeGamePanel类中添加一些逻辑

public class SnakeGamePanel extends JPanel {

/**
* 当分数是达到50的倍数的时,随机产生一个障碍物.
*/
private boolean isNeedToGenerateNewBarrier() {
return score != 0 && score % 50 == 0 && needToGenerateBarrie;
}

/**
* 判断随机产生的位置是否与蛇体和食物冲突, 如果有冲突返回false,如果位置没有冲则返回true
*/
private boolean isBarrierAvailable(int x, int y) {
for (Grid grid : snake.getList()) {
if (x == grid.getX() && y == grid.getY()) {
return false;
}
}
if (food.getX() == x && food.getY() == y) {
return false;
}
return true;
}

/**
* 随机产生一个障碍物
*/
private void generateBarrierByRandom() {
Random r = new Random();
int randomX = r.nextInt(SnakeGameConstant.GRID_COLUMN_NUMBER);
int randomY = r.nextInt(SnakeGameConstant.GRID_ROW_NUMBER);

if (isBarrierAvailable(randomX, randomY)) {
barrier.getBarriersList().add(
new Grid(randomX, randomY, Color.YELLOW));
// 成功生成一个障碍物后,将needToGenerateBarrie标识为false
needToGenerateBarrie = false;
} else {
generateBarrierByRandom();
}
}

}


[b]最后,添加蛇体与障碍物碰撞的判断,修改游戏结束的判断条件。[/b]在SnakeGamePanel类中添加isSnakeHeadTouchBarrier方法,并将这个条件应用于judgeGameOver方法中。

public class SnakeGamePanel extends JPanel 
{
private boolean isSnakeHeadTouchBarrier() {
Grid head = snake.getList().get(0);
for (Grid grid : barrier.getBarriersList()) {
if (head.getX() == grid.getX() && head.getY() == grid.getY()) {
this.gameOverType = GameOverType.TOUCH_BARRIER;
return true;
}
}

return false;
}

private void judgeGameOver() {
if (isSnakeHeadTouchEdge() || isSnakeHeadTouchBody()
|| isSnakeHeadTouchBarrier()) {
gameState = GameState.OVER;
int result = JOptionPane.showConfirmDialog(frame,
SnakeGameConstant.GAME_OVER, SnakeGameConstant.SNAKE_GAME,
JOptionPane.YES_NO_OPTION);
if (result == JOptionPane.YES_OPTION) {
for (int i = SnakeGameConstant.LEFT; i <= SnakeGameConstant.RIGHT; i++) {
for (int j = SnakeGameConstant.UP; j <= SnakeGameConstant.DOWN; j++) {
flag[i][j] = 0;
}
}

gameState = GameState.RUN;
score = 0;
init();
timer.start();
} else {
System.exit(0);
}
}
}
}



障碍物用黄颜色的块表示,效果如下:
[b]1. 达到50分后,随机长生一个障碍物[/b]

[img]http://dl2.iteye.com/upload/attachment/0087/4499/bbd4e637-2dda-3349-afaf-203912f2f86f.jpg[/img]

[b]2. 达到100分后,在原有基础上再随机长生一个障碍物[/b]

[img]http://dl2.iteye.com/upload/attachment/0087/4501/7d7bb667-98dc-3d6e-9e66-9150c4b52b3e.jpg[/img]

[b]3. 达到150分后,在原有基础上再随机长生一个障碍物[/b]

[img]http://dl2.iteye.com/upload/attachment/0087/4503/c026356a-b63f-38c3-9250-b3bb5ef4a6ea.jpg[/img]

详细代码请参考附件MySnakeGame.7z

后续的博文将添加如下功能:

(三)添加游戏进度的存储和读取
(四)完成游戏排行榜
... ...
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值