java - 在Java中连续移动图像

标签 java loops if-statement graphics applet

我正在尝试用 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 SwingConcurrency 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 可能应该放在 initstart 方法中,具体取决于您是否可以弄清楚如何“暂停” 线程

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/

相关文章:

java - 使用 JaxB 编码实现公共(public)接口(interface)的对象列表

c++ - 矩阵c++对角线元素之和

python - 迭代来自 torch.utils.data.random_split 的子集

java - 数组 If 语句问题

excel - 如果 Google Sheets 或 MS Excel 中的值为负数,如何在数字前加上加号 "+"?

java - Cipher.getBlockSize() 即使使用 256 位 key 也会返回 128 位

java - 在 Java 中为变量分配动态名称

javascript - 如何为屏幕宽度向现有的 javascript 函数添加额外的 if 语句?

java - 如何在android中的另一个类中创建警报对话框

java - 迭代器循环的奇怪打印行为