在上一篇博文中,介绍了
Swing贪吃蛇游戏基本功能的实现:
Swing贪吃蛇游戏(一):基本功能实现 >>>> http://mouselearnjava.iteye.com/blog/1913290
本文在原有基本功能上增加随机产生障碍物的功能,增加些游戏的难度
随机产生障碍物的功能可以有多种实现,我们可以将分数的改变作为产生随机数的条件,比如
1. 分数每增加50分,在原有的基础上随机产生一个障碍物(不改变原来已经有的障碍物位置)
2. 分数每增加50分,以50的倍数作为产生随机障碍物的个数(比如N),重新生成N个随机障碍物。
两种实现都不难,但是第二种方式的实现对玩游戏来说难度会更大。比如产生8个随机障碍物,那么相对来讲蛇体已经很长,随机产生8个随机障碍物可能同时有多个出现在蛇头附近,更加容易撞到障碍物。
本文的实现采用了方案1.
那么,为了能够完成这个功能,我们需要做哪一些改动呢?
首先,增加一个障碍物类,用于记录障碍物信息。
class="java" name="code">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;
}
}
其次,增加随机产生随机障碍物的代码。,在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();
}
}
}
最后,添加蛇体与障碍物碰撞的判断,修改游戏结束的判断条件。在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);
}
}
}
}
障碍物用黄颜色的块表示,效果如下:
1. 达到50分后,随机长生一个障碍物
2. 达到100分后,在原有基础上再随机长生一个障碍物
3. 达到150分后,在原有基础上再随机长生一个障碍物
详细代码请参考附件MySnakeGame.7z
后续的博文将添加如下功能:
(三)添加游戏进度的存储和读取
(四)完成游戏排行榜
... ...
- 大小: 19.4 KB
- 大小: 20.6 KB
- 大小: 21.5 KB
- MySnakeGame.7z (15.3 KB)
- 下载次数: 0