我正在尝试用 Java 为我的计算机科学课重新创建一个 DigDug 游戏。
由于我只是一个初学者,所以我只会让怪物向上移动然后再向下移动,而不是追赶玩家。不过,我很难让怪物持续移动。它会上升,但不会再下降,也不会重复。
以前,如果玩家到达该点,它会立即飞出屏幕,或者根本不会移动。我尝试过 for 循环、while 循环和 do-while 循环。我也尝试过延迟,但它停止了我的整个程序。目标是当玩家达到某个点(340、270)时,让所有怪物上下移动。
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.awt.Font;
import java.awt.event.*;
import javax.swing.Timer;
import java.util.ArrayList;
import java.awt.event.KeyAdapter;
public class DigDug extends Applet implements MouseMotionListener, MouseListener, KeyListener
{
private final Color c_background = new Color(32, 73, 150);
private final Color c_first = new Color(230, 185, 9);
private final Color c_second = new Color(224, 128, 18);
private final Color c_third = new Color(232, 61, 14);
private final Color c_last = new Color(184, 0, 0);
private final Color c_score = new Color(232, 42, 96);
public boolean ifEntered = false;
public boolean isMoving1 = false;
private int count = 0;
private int otherCount = 0;
private Image flower;
private Image diggy;
private Image enemies1;
private Image enemies2;
private Image enemies3;
private Image arrowUp;
private Image arrowDown;
private Image arrowLeft;
private Image arrowRight;
//private ArrayList<Point> enemies = new ArrayList<Point>();
Font myFont = new Font("SansSerif",Font.BOLD, 16);
private Timer timer;
private Point Up;
private int digx = 685;
private int digy = 45;
private int e1x = 76;
private int e1y = 210; //i created a variable that would hold the enemies's values
private int e2x = 465;
private int e2y = 342;
private int e3x = 546;
private int e3y = 127;
private boolean ifW = false;
private boolean ifA = false;
private boolean ifS = false;
private boolean ifD = false;
private boolean yaas = false;
private int arrowX = digx+5;
private int arrowY = digy+5;
private ArrayList<Integer> xpts = new ArrayList<Integer>();
private ArrayList<Integer> ypts = new ArrayList<Integer>();
public void init()
{
diggy = getImage(getDocumentBase(), "Dig_Dug.png");
flower = getImage(getDocumentBase(), "flower.gif");
enemies1 = getImage(getDocumentBase(), "Pooka.png");
enemies2 = getImage(getDocumentBase(), "Fygar.gif");
enemies3 = getImage(getDocumentBase(), "Pooka.png");
arrowUp = getImage(getDocumentBase(), "ArrowUp.png");
arrowDown = getImage(getDocumentBase(), "ArrowDown.png");
arrowRight = getImage(getDocumentBase(), "Arrow-Point-Right.png");
arrowLeft = getImage(getDocumentBase(), "ArrowLeft copy.png");
setBackground(c_background);
setSize(700,500);
addMouseMotionListener(this);
addMouseListener(this);
setFont(myFont);
addKeyListener(this);
Up = new Point(digx, digy);
}
public void paint(Graphics g)
{
score(g);
background(g);
g.setColor(Color.white);
//g.fillRect(player.x, player.y, 10, 10);
if(ifEntered)
{
if(digx > 330)
digx--;
else if(digy < 247)
digy++;
repaint();
}
if(digx == 330 && digy == 247)
{
yaas = true; //checks if the player has reached spot
//(random variable i created
}
if(yaas == true) //this if statement is where i am having the problem
{
//int count = 0;
//int count = 0;
boolean isUp = false;
for(int i = 0; i < count; i++)
{
if(e1y == 210)
{
while(e1y != 120)
{
e1y--;
}
isUp = true;
}
if(e1y == 120 && isUp == true)
{
while(e1y != 210)
{
e1y++;
}
isUp = false;
}
count++;
}
}
g.drawImage(diggy, digx, digy, 20, 20, null);
g.drawImage(flower, 680, 41, 20, 20, null);
g.drawImage(enemies1, e1x, e1y, 20, 20, null);
g.drawImage(enemies2, e2x, e2y, 20, 20, null);
g.drawImage(enemies3, e3x, e3y, 20, 20, null);
if(digy > e1y && digy < (e1y+20) && digx > e1x && digx < (e1x+20) ||e1y == digy || e1x == digx )
{
background(g);
g.setColor(Color.white);
g.drawString("GAME OVER", 294, 260);
// repaint();
}
if(digy > e2y && digy < (e2y+20) && digx > e2x && digx < (e2x+20)||e2y == digy || e2x == digx )
{
background(g);
g.setColor(Color.white);
g.drawString("GAME OVER", 294, 260);
// repaint();
}
if(digy > e3y && digy < (e3y+20) && digx > e3x && digx < (e3x+20) || e3y == digy && e3x == digx)
{
background(g);
g.setColor(Color.white);
g.drawString("GAME OVER", 294, 260);
// repaint();
}
}
public void score(Graphics g)
{
g.setColor(c_score);
g.drawString("1UP", 101, 21);
g.drawString("HIGH SCORE", 271, 21);
g.setColor(Color.white);
g.drawString(" " + count, 118, 35);
g.drawString(" " + count, 317, 35);
}
public void background(Graphics g)
{
g.setColor(c_first);
g.drawRect(0,65, 700, 120);
g.fillRect(0, 65, 700, 120);
g.setColor(c_second);
g.drawRect(0,166, 700, 120);
g.fillRect(0,166, 700, 120);
g.setColor(c_third);
g.drawRect(0, 267, 700, 120);
g.fillRect(0, 267, 700, 120);
g.setColor(c_last);
g.drawRect(0, 388, 700, 120);
g.fillRect(0, 388, 700, 120);
}
最佳答案
首先,您需要了解 Painting in AWT and Swing和 Concurrency in Java 。我也不鼓励使用 Applet
,Applet 有自己的一堆问题,您现在可能不需要处理这些问题。
paint
方法不是更新 UI 状态的地方,paint
方法应该只绘制当前状态。您也不应该在 paint
方法中更改 UI 的状态,这可能会导致无休止的问题
首先,您需要某种“游戏循环”,该循环负责更新游戏状态并安排 UI 更新
在主循环中,我们维护一个运动“delta”,这描述了特定对象的变化量以及方向,在这个例子中,我只处理enemies1
,但你可以想象任何会移动的东西也需要它自己。
在游戏循环的每个周期中,我们将增量应用到对象当前位置,进行边界检查并根据需要反转增量...
e1y += moveDelta;
if (e1y >= 210) {
e1y = 209;
moveDelta *= -1;
} else if (e1y <= 120) {
e1y = 121;
moveDelta *= -1;
}
下面的 mainLoop
可能应该放在 init
或 start
方法中,具体取决于您是否可以弄清楚如何“暂停” 线程
Thread mainLoop = new Thread(new Runnable() {
@Override
public void run() {
int moveDelta = -1;
gameOver = false;
while (!gameOver) {
if (ifEntered) {
if (digx > 330) {
digx--;
} else if (digy < 247) {
digy++;
}
repaint();
}
// Removed some code here for testing
e1y += moveDelta;
if (e1y >= 210) {
e1y = 209;
moveDelta *= -1;
} else if (e1y <= 120) {
e1y = 121;
moveDelta *= -1;
}
if (digy > e1y && digy < (e1y + 20) && digx > e1x && digx < (e1x + 20) || e1y == digy || e1x == digx) {
gameOver = true;
} else if (digy > e2y && digy < (e2y + 20) && digx > e2x && digx < (e2x + 20) || e2y == digy || e2x == digx) {
gameOver = true;
} else if (digy > e3y && digy < (e3y + 20) && digx > e3x && digx < (e3x + 20) || e3y == digy && e3x == digx) {
gameOver = true;
}
try {
Thread.sleep(40);
} catch (InterruptedException ex) {
}
repaint();
}
}
});
mainLoop.start();
然后,您需要将 paint
方法替换为仅绘制游戏当前状态的代码
@Override
public void paint(Graphics g) {
super.paint(g);
score(g);
background(g);
g.setColor(Color.white);
//g.fillRect(player.x, player.y, 10, 10);
if (gameOver) {
g.setColor(Color.white);
g.drawString("GAME OVER", 294, 260);
} else {
g.drawImage(diggy, digx, digy, 20, 20, null);
g.drawImage(flower, 680, 41, 20, 20, null);
g.drawImage(enemies1, e1x, e1y, 20, 20, null);
g.drawImage(enemies2, e2x, e2y, 20, 20, null);
g.drawImage(enemies3, e3x, e3y, 20, 20, null);
}
}
现在,我建议您转储 Applet
,转而使用 JPanel
(用于核心逻辑)和 JFrame
(用于显示)和 Swing Timer
而不是 Thread
。首先您可以免费获得双缓冲
关于java - 在Java中连续移动图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30827043/