作为一名Java初学者,我正在从事一个Space Invaders项目。希望增加更多级别。
private void LevelInit() {
aliens = new ArrayList<>();
int currentLevel = 1;
if (currentLevel == 1) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
//System.out.println(currentLevel);
}
}
}
else if (currentLevel == 2) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
// System.out.println(currentLevel);
}
}
}
else if (currentLevel == 3) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 6; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
//System.out.println(currentLevel);
}
}
}
player = new Player();
bullet = new Bullet();
}
这个函数是初始化游戏并由构造函数调用的代码背后的逻辑。添加关卡的简单方法是添加更多的外星人。这就是它从昨天更新后的样子,级别被添加,但数组列表被粘在一起。就像12-16-24个外星人被打印在一起一样,一些宇宙飞船受到1次撞击,一些2次,一些3次,当它们都被摧毁时,系统会发出你一起通过了1级、2级和3级的信息,这让我很困惑,为什么它们会这样绑在一起而没有通过。我想不通。此外,
private void update() {
if (deaths == 12) {
inGame = false;
timer.stop();
message = "Next Level!";
}
// player
player.act();
// shot
if (bullet.isVisible()) {
int shotX = bullet.getX();
int shotY = bullet.getY();
for (Alien alien : aliens) {
int alienX = alien.getX();
int alienY = alien.getY();
if (alien.isVisible() && bullet.isVisible()) {
if (shotX >= (alienX)
&& shotX <= (alienX + Constants.ALIEN_WIDTH)
&& shotY >= (alienY)
&& shotY <= (alienY + Constants.ALIEN_HEIGHT)) {
var ii = new ImageIcon(explImg);
alien.setImage(ii.getImage());
alien.setDying(true);
deaths++;
bullet.die();
}
}
}
int y = bullet.getY();
y -= 4;
if (y < 0) {
bullet.die();
} else {
bullet.setY(y);
}
}
// aliens
for (Alien alien : aliens) {
int x = alien.getX();
if (x >= Constants.BOARD_WIDTH - Constants.BORDER_RIGHT && direction != -1) {
direction = -1;
for(Alien a2 : aliens) {
a2.setY(a2.getY() + Constants.GO_DOWN);
}
}
if (x <= Constants.BORDER_LEFT && direction != 1) {
direction = 1;
for(Alien a : aliens) {
a.setY(a.getY() + Constants.GO_DOWN);
}
}
}
for(Alien alien : aliens) {
if (alien.isVisible()) {
int y = alien.getY();
if (y > Constants.GROUND - Constants.ALIEN_HEIGHT) {
inGame = false;
message = "Invasion!";
}
alien.act(direction);
}
}
// bombs
var generator = new Random();
for (Alien alien : aliens) {
int shot = generator.nextInt(15);
Alien.Bomb bomb = alien.getBomb();
if (shot == Constants.CHANCE && alien.isVisible() && bomb.isDestroyed()) {
bomb.setDestroyed(false);
bomb.setX(alien.getX());
bomb.setY(alien.getY());
}
int bombX = bomb.getX();
int bombY = bomb.getY();
int playerX = player.getX();
int playerY = player.getY();
if (player.isVisible() && !bomb.isDestroyed()) {
if (bombX >= (playerX)
&& bombX <= (playerX + Constants.PLAYER_WIDTH)
&& bombY >= (playerY)
&& bombY <= (playerY + Constants.PLAYER_HEIGHT)) {
var ii = new ImageIcon(explImg);
player.setImage(ii.getImage());
player.setDying(true);
bomb.setDestroyed(true);
}
}
if (!bomb.isDestroyed()) {
bomb.setY(bomb.getY() + 1);
if (bomb.getY() >= Constants.GROUND - Constants.BOMB_HEIGHT) {
bomb.setDestroyed(true);
}
}
}
}
此功能用于在发生任何事情时更新游戏。该代码是由一堆YouTube视频和GitHub制作的,所以如果你看到任何复制,请原谅。我需要通过简单地添加更多的外星人来创建新的关卡,尝试使用for循环,但这要么导致外星人移动得更快,要么子弹没有摧毁外星人,它只是击中了外星人。
板类:
public class Board extends JPanel {
private Dimension d;
private List<Alien> aliens;
private Player player;
private Bullet bullet;
private int level;
private int direction = -1;
private int deaths = 0;
private boolean inGame = true;
private String explImg = "src/images/explosion.png";
private String message = "Game Over";
private Timer timer;
public Board() {
initBoard();
gameInit();
LevelInit();
}
private void initBoard() {
addKeyListener(new TAdapter());
setFocusable(true);
d = new Dimension(Constants.BOARD_WIDTH, Constants.BOARD_HEIGHT);
setBackground(Color.black);
timer = new Timer(Constants.DELAY, new GameCycle());
timer.start();
gameInit();
}
private void gameInit() {
aliens = new ArrayList<>();
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j,
Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
}
}
player = new Player();
bullet = new Bullet();
}
private void LevelInit() {
inGame = true;
timer.start();
int level = 1;
if (aliens.isEmpty()) {
level++;
int AlienCount;if(level == 2) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 6; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
}
}
} else if (level == 3) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 6; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
}
}
}
}
player = new Player();
bullet = new Bullet();
}
private void drawAliens(Graphics g) {
for (Alien alien : aliens) {
if (alien.isVisible()) {
g.drawImage(alien.getImage(), alien.getX(), alien.getY(), this);
}
if (alien.isDying()) {
alien.die();
}
}
}
private void drawPlayer(Graphics g) {
if (player.isVisible()) {
g.drawImage(player.getImage(), player.getX(), player.getY(), this);
}
if (player.isDying()) {
player.die();
inGame = false;
}
}
private void drawShot(Graphics g) {
if (bullet.isVisible()) {
g.drawImage(bullet.getImage(), bullet.getX(), bullet.getY(), this);
}
}
private void drawBombing(Graphics g) {
for (Alien a : aliens) {
Alien.Bomb b = a.getBomb();
if (!b.isDestroyed()) {
g.drawImage(b.getImage(), b.getX(), b.getY(), this);
}
}
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
private void doDrawing(Graphics g) {
g.setColor(Color.black);
g.fillRect(0, 0, d.width, d.height);
g.setColor(Color.green);
if (inGame) {
g.drawLine(0, Constants.GROUND,
Constants.BOARD_WIDTH, Constants.GROUND);
drawAliens(g);
drawPlayer(g);
drawShot(g);
drawBombing(g);
} else {
if (timer.isRunning()) {
timer.stop();
}
gameOver(g);
}
Toolkit.getDefaultToolkit().sync();
}
private void gameOver(Graphics g) {
g.setColor(Color.black);
g.fillRect(0, 0, Constants.BOARD_WIDTH, Constants.BOARD_HEIGHT);
g.setColor(new Color(0, 32, 48));
g.fillRect(50, Constants.BOARD_WIDTH / 2 - 30, Constants.BOARD_WIDTH - 100, 50);
g.setColor(Color.white);
g.drawRect(50, Constants.BOARD_WIDTH / 2 - 30, Constants.BOARD_WIDTH - 100, 50);
var small = new Font("Helvetica", Font.BOLD, 14);
var fontMetrics = this.getFontMetrics(small);
g.setColor(Color.white);
g.setFont(small);
g.drawString(message, (Constants.BOARD_WIDTH - fontMetrics.stringWidth(message)) / 2,
Constants.BOARD_WIDTH / 2);
}
private void update() {
if (deaths == aliens.size()) {
inGame = false;
timer.stop();
message = "Next Level!";
}
// player
player.act();
// shot
if (bullet.isVisible()) {
int shotX = bullet.getX();
int shotY = bullet.getY();
for (Alien alien : aliens) {
int alienX = alien.getX();
int alienY = alien.getY();
if (alien.isVisible() && bullet.isVisible()) {
if (shotX >= (alienX)
&& shotX <= (alienX + Constants.ALIEN_WIDTH)
&& shotY >= (alienY)
&& shotY <= (alienY + Constants.ALIEN_HEIGHT)) {
var ii = new ImageIcon(explImg);
alien.setImage(ii.getImage());
alien.setDying(true);
deaths++;
bullet.die();
}
}
}
int y = bullet.getY();
y -= 4;
if (y < 0) {
bullet.die();
} else {
bullet.setY(y);
}
}
// aliens
for (Alien alien : aliens) {
int x = alien.getX();
if (x >= Constants.BOARD_WIDTH - Constants.BORDER_RIGHT && direction != -1) {
direction = -1;
Iterator<Alien> i1 = aliens.iterator();
while (i1.hasNext()) {
Alien a2 = i1.next();
a2.setY(a2.getY() + Constants.GO_DOWN);
}
}
if (x <= Constants.BORDER_LEFT && direction != 1) {
direction = 1;
Iterator<Alien> i2 = aliens.iterator();
while (i2.hasNext()) {
Alien a = i2.next();
a.setY(a.getY() + Constants.GO_DOWN);
}
}
}
Iterator<Alien> it = aliens.iterator();
while (it.hasNext()) {
Alien alien = it.next();
if (alien.isVisible()) {
int y = alien.getY();
if (y > Constants.GROUND - Constants.ALIEN_HEIGHT) {
inGame = false;
message = "Invasion!";
}
alien.act(direction);
}
}
// bombs
var generator = new Random();
for (Alien alien : aliens) {
int shot = generator.nextInt(15);
Alien.Bomb bomb = alien.getBomb();
if (shot == Constants.CHANCE && alien.isVisible() && bomb.isDestroyed()) {
bomb.setDestroyed(false);
bomb.setX(alien.getX());
bomb.setY(alien.getY());
}
int bombX = bomb.getX();
int bombY = bomb.getY();
int playerX = player.getX();
int playerY = player.getY();
if (player.isVisible() && !bomb.isDestroyed()) {
if (bombX >= (playerX)
&& bombX <= (playerX + Constants.PLAYER_WIDTH)
&& bombY >= (playerY)
&& bombY <= (playerY + Constants.PLAYER_HEIGHT)) {
var ii = new ImageIcon(explImg);
player.setImage(ii.getImage());
player.setDying(true);
bomb.setDestroyed(true);
}
}
if (!bomb.isDestroyed()) {
bomb.setY(bomb.getY() + 1);
if (bomb.getY() >= Constants.GROUND - Constants.BOMB_HEIGHT) {
bomb.setDestroyed(true);
}
}
}
}
private void doGameCycle() {
update();
repaint();
}
private class GameCycle implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
doGameCycle();
}
}
private class TAdapter extends KeyAdapter {
@Override
public void keyReleased(KeyEvent e) {
player.keyReleased(e);
}
@Override
public void keyPressed(KeyEvent e) {
player.keyPressed(e);
int x = player.getX();
int y = player.getY();
int key = e.getKeyCode();
if (key == KeyEvent.VK_SPACE) {
if (inGame) {
if (!bullet.isVisible()) {
bullet = new Bullet(x, y);
}
}
}
}
}
}
正如@JoachimSauer所提到的,您的代码需要重构。这是解决你问题的一个可能办法。
添加
您将需要两个额外的变量和一个额外的方法。
-
变量
1: int currentLevel - keeps track of the current level 2: boolean isLevelOver - keeps track if the current level is still active or not
-
方法
private void levelInit(int currentlevel) { aliens = new ArrayList<>(); int alienCount = //calculate alien count depending upon the current level //Add aliens to aliens ArrayList player = new Player(); bullet = new Bullet(); }
您必须提供如何根据currentLevel
计算alienCount
的实现。先前用于将外星人添加到aliens
的嵌套循环也将发生更改。您必须使循环依赖于currentLevel
。
更改
你的方法很少需要改变。
public Board()
{
initBoard();
}
private void initBoard()
{
addKeyListener(new TAdapter());
setFocusable(true);
d = new Dimension(Constants.BOARD_WIDTH, Constants.BOARD_HEIGHT);
setBackground(Color.black);
levelInit(currentLevel);
timer = new Timer(Constants.DELAY, new GameCycle());
timer.start();
}
private void update()
{
if (deaths == aliens.size())
{
isLevelOver = true;
currentLevel++;
message = "Next Level!";
return;
}
...
}
private void doGameCycle()
{
if (isLevelOver)
{
levelInit(currentLevel);
isLevelOver = false;
}
update();
repaint();
}
注释
- 这是实现您想要的目标的可能方法之一。那里可能是其他方式,可能更好,但这就是我想到的与
- 我试图在你的代码中找到尽可能多的添加和更新。然而,我不知道它的结构,你知道。所以可能需要更多的添加或更改
- 我注意到您在
initBoard()
中调用gameInit()
,然后在Board()
构造函数中再次调用我认为那可能没有必要,请调查一下 - 在设置了
isGame = false
之后,您对timer.stop()
进行了一次调用这可能是不必要的,因为您已经在doDrawing(...)
中这样做了也请检查一下 - 你可能应该为屏幕上的
levelCount()
或最大外星人设置一个限制,因为如果你在每个新级别中不断添加更多的外星人,他们可能会填满整个屏幕
我提供了许多提示,这些提示应该会帮助您解决问题。如果你仍然面临任何问题,或者有人发现答案有什么问题,请发表评论。