如何在 Java 中创建墙障或不可逾越的墙?

How do I create wall barriers or impassable walls in Java?

我正在尝试在我的屏幕 (JFrame) 边缘制作不可逾越的墙。因此,当我将图像向左移动并且它触及框架的左侧时,它会强制图像不动。我尝试了各种方法,但我似乎找不到合适的代码,所以我想知道如何根据我的代码来做。

import javax.swing.*;
import java.awt.event.*;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.net.URL;

public class MovingImages extends JPanel implements KeyListener, ActionListener
{
  Timer t = new Timer(5, this);
  int x = 0, y = 0; //coordinates for the image
  int imageScaleX = 100, imageScaleY = 100; //scale the size of the image 
  int velX = 0, velY = 0;  
//--------------------------------------------------------------------------------------- DISPLAYING IMAGE

  public MovingImages()
  {   
    t.start();
    addKeyListener(this); //enables the KeyListener so keys can be pressed
    setFocusable(true);
  }

  /** This code is only used for importing the image and runs the program even when there is no image
    * @param path is a String that is used to represent the the name or where your file is
    * @return is the tempImage which is the image that the program found
    */  
  public Image getImage(String path)
  {
    Image tempImage = null; 
    try
    {
      URL imageURL = MovingImages.class.getResource(path); //finds where the image is
      tempImage = Toolkit.getDefaultToolkit().getImage(imageURL); //loads image from file
    }
    catch (Exception e)
    {
    }
    return tempImage;
  } 

  /** This code is used to display the image in specified coordinates
    * @param g is a variable that uses the Graphics method
    */
  public void paint(Graphics g)
  {
    Image image = getImage("sprite.png"); //choose the file for your image    
    super.paintComponent(g); //everytime the image moves, it clears the previous image    
    Graphics2D g2 = (Graphics2D) g; //converts graphics into 2D
    g2.drawImage(image, x, y, imageScaleX, imageScaleY, this); //draws image in specific coordinates
  }
//--------------------------------------------------------------------------------------- KEYBOARD FUNCTIONS 

  public void actionPerformed(ActionEvent e)
  {
    x += velX;
    y += velY;
    repaint();    
  }  

  public void up()
  {
    velY = -2; 
  }

  public void down()
  { 
    velY = 2;
  }

  public void left()
  {   
    velX = -2;  
  }

  public void right()
  {   
    velX = 2;
  }

  public void keyPressed(KeyEvent e)
  {
    int keyCode = e.getKeyCode();
    if (keyCode == KeyEvent.VK_UP)
    {
      up();
    }
    if (keyCode == KeyEvent.VK_DOWN)
    {
      down();
    }
    if (keyCode == KeyEvent.VK_LEFT)
    {
      left();
    }
    if (keyCode == KeyEvent.VK_RIGHT)
    {
      right();
    }
  }

  public void keyTyped(KeyEvent e)
  {
  }

  public void keyReleased(KeyEvent e)
  {
    int keyCode = e.getKeyCode();
    if (keyCode == KeyEvent.VK_UP)
    {
      velY = 0;
    }
    if (keyCode == KeyEvent.VK_DOWN)
    {
      velY = 0;
    }
    if (keyCode == KeyEvent.VK_LEFT)
    {
      velX = 0;
    }
    if (keyCode == KeyEvent.VK_RIGHT)
    {
      velX = 0;
    }
  } 
//--------------------------------------------------------------------------------------- MAIN 

  public static void main(String args[])
  {
    MovingImages s = new MovingImages();
    JFrame f = new JFrame();
    f.add(s);
    f.setVisible(true);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setSize(1280, 720);
  }
}

以下回答解释了强制对象留在其容器内的一般原则。在程序的事件循环中,您正在更新对象的 x 和 y 坐标,直接响应键盘输入或在基于保存的速度的定时器循环中。无论哪种情况,基本原则都是相同的:

Detect when an object's edge bumps up against the container's boundary and don't apply any changes to the object coordinate that would move it so it is partially or completely outside the container.

以下伪代码描述了每次更新对象位置时必须发生的事情。我只展示水平运动的代码,垂直运动留作练习。我假设对象的 "position" 是其边界框左下角的坐标。

    int left_edge  = pos_x;
    int right_edge = pox_x + width;
    if (velocity_x < 0)
        pos_x += left_edge > 0 ? velocity_x : 0;
    else if (velocity_x > 0)
        pos_x += right_edge < container_width ? velocity_x : 0;

一些我没有解决的问题留作练习:

  1. 垂直运动
  2. 当物体撞到墙上时速度会发生什么变化。 (a) 物体继续 "try" 移动还是 (b) 那个方向的速度下降到零?例如,如果容器中间有某种屏障,则第一个选项 (a) 可能适用。物体可能会撞到它并停止水平运动,同时仍然有垂直运动,当最终垂直清除障碍物时,然后继续水平运动。
  3. 如果 velocity > 1 上面的代码可能会导致部分结束在容器之外(即你从 x==1 开始 velocity==-2)。您将需要增强此案例的代码,同时牢记您对上面第 2 项的回答。