java - 如何在 Java 中创建墙壁障碍或无法逾越的墙壁?

标签 java swing keyevent

我正在尝试在屏幕边缘(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.

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

    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) 物体是否继续“尝试”移动,或者 (b) 该方向的速度是否降至零?例如,如果容器中间有某种障碍物,则第一个选项 (a) 可能适用。物体可能会撞到它并停止水平移动,同时仍然进行垂直移动,并且当最终垂直清除障碍物时,然后继续水平移动。
  3. 如果velocity > 1上面的代码可能会导致部分结束在容器之外(即从 x==1 开始,使用 velocity==-2 )。您需要增强此案例的代码,同时牢记您对上述第 2 项的回答。

关于java - 如何在 Java 中创建墙壁障碍或无法逾越的墙壁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37370536/

相关文章:

android - setOnClickListener;

java - 如何使用 Tomcat 和 Java 技术提供动态生成的文件?

jquery - jQuery 中触发退格键

java - Spring Boot 处理 SizeLimitExceededException

java - 无法在 JTable 的单个单元格中添加两个按钮

java - 处理窗口的事件

java - JSeparator 不在我的 JPanel 中的正确位置

android - 如何在 Android 中正确覆盖 dispatchKeyEvent

java - Gremlinepipeline 两个顶点之间的边

java - 作为计数器,以定时间隔将值从 1 美元增加到 125 万美元