Java 在框架上移动正方形 - 如何将其停在框架的边缘?

Java moving square on a frame - how do I stop it at the edge of the Frame?

我有一个使用键盘移动方块的程序。当我按下其中一个箭头键时它可以很好地移动,但是如果我将它移动到框架的边缘,我希望它停止。但是它不会这样做。如果我将方块移动到框架的边缘,它会继续移动并移动到屏幕边缘。

我已将控件放入我的代码中以尝试停止广场,但它们似乎不起作用。不太确定这里出了什么问题。

这是设置和绘制正方形的代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;

@SuppressWarnings("serial")
public class MovingSquare extends JPanel implements ActionListener, KeyListener
{
    // We need a timer to move the shape
    Timer shapeTimer = new Timer(5, this);

    // X and Y coordinates of square (top left corner), and the factors by which it will move or resize each time
    double xPos = 0, yPos = 0, movementX = 0, movementY = 0;

    // Size of the square
    int squareSize = 40;

    // Width and height of the parent frame
    int windowWidth;
    int windowHeight;

    // Movement bounds of the square
    // These will prevent it from being moved off the edge of the frame
    int xBound;
    int yBound;

    // Constructor method for our class
    public MovingSquare(int w, int h)   // Constructor is passed the size of the parent frame
    {
        // Start the timer
        shapeTimer.start();

        addKeyListener(this);
        setFocusable(true);
        setFocusTraversalKeysEnabled(false);

        windowWidth = w;
        windowHeight = h;

        xBound = (windowWidth - squareSize);
        yBound = (windowHeight - squareSize);
    }

    // This is where the fun starts!  Painting the graphics object
    public void paintComponent(Graphics g) 
    {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;

        // Create a new rectangle (which is actually a square!)
        Rectangle2D movableSquare = new Rectangle2D.Double(xPos, yPos, squareSize, squareSize);

        // Draw the above square on the graphics object
        g2.draw(movableSquare);
    }

    public void actionPerformed(ActionEvent e) 
    {
        // Redraw the square when something happens
        repaint();

        // Set the new x and y coordinates, depending on which direction we have moved
        xPos += movementX;
        yPos += movementY;
    }

    public void moveUp() 
    {
        // Check to see if the shape is already at the top edge of the screen
        if (yPos == 0) 
        {
            movementY = 0;
            movementX = 0;
        }

        // Set the movement factor - negative Y because we are moving UP!
        movementY = -0.5;
        movementX = 0;
    }

    public void moveDown() 
    {
        // Check to see if the shape is already at the bottom edge of the screen - specified by the X and Y bounds
        if (yPos == yBound) 
        {
            movementY = 0;
            movementX = 0;              
        }

        // Set the movement factor - positive Y because we are moving DOWN!
        movementY = 0.5;
        movementX = 0;
    }

    public void moveLeft()
    {
        // Check to see if the shape is already at the left hand edge of the screen         
        if (xPos == 0) 
        {
            movementY = 0;
            movementX = 0;              
        }

        // Set the movement factor - negative X because we are moving LEFT!         
        movementX = -0.5;
        movementY = 0;
    }

    public void moveRight() 
    {
        // Check to see if the shape is already at the right hand edge of the screen - specified by the X and Y bounds
        if (xPos == xBound)
        {
            movementY = 0;
            movementX = 0;
        }

        // Set the movement factor - positive X because we are moving RIGHT!            
        movementX = 0.5;
        movementY = 0;
    }

    public void enlargeSquare() 
    {
        // Make the square larger
        squareSize++;
    }

    public void shrinkSquare() 
    {
        // Make the square smaller
        squareSize--;
    }

    public void keyPressed(KeyEvent e) 
    {
        // Get the Key Code of the key that has been pressed
        int keyCode = e.getKeyCode();

        // If the up key has been pressed
        if (keyCode == KeyEvent.VK_UP) 
        {
            // Move shape up
            moveUp();
        }

        // If the down key has been pressed
        if (keyCode == KeyEvent.VK_DOWN) 
        {
            // Move shape down
            moveDown();
        }

        // If the right key is pressed
        if (keyCode == KeyEvent.VK_RIGHT)
        {
            // Move shape right
            moveRight();
        }

        // If the left key is pressed
        if (keyCode == KeyEvent.VK_LEFT) 
        {
            // Move shape left
            moveLeft();
        }

        // If the left brace key is pressed
        if (keyCode == KeyEvent.VK_OPEN_BRACKET)
        {
            shrinkSquare();
        }

        // If the right brace key is pressed
        if (keyCode == KeyEvent.VK_CLOSE_BRACKET)
        {
            enlargeSquare();
        }
    }

    public void keyTyped(KeyEvent e) 
    {

    }

    public void keyReleased(KeyEvent e)
    {
        // Get the Key Code of the key that has been released
        int keyCode = e.getKeyCode();

        // If the down key was released
        if (keyCode == KeyEvent.VK_UP) 
        {
            movementX = 0;
            movementY = 0;
        }

        // If the down key was released
        if (keyCode == KeyEvent.VK_DOWN) 
        {
            movementX = 0;
            movementY = 0;
        }

        // If the right key was released
        if (keyCode == KeyEvent.VK_RIGHT) 
        {
            movementX = 0;
            movementY = 0;
        }

        // If the left key was released
        if (keyCode == KeyEvent.VK_UP) 
        {
            movementX = 0;
            movementY = 0;
        }               
    }   
}

这是主要的 class:

import javax.swing.JFrame;

public class Square 
{

public static void main(String args[]) 
{
    // Set width and height of frame
    int frameWidth = 1024;
    int frameHeight = 768;

    // Create new frame and set size
    JFrame frmMain = new JFrame();
    frmMain.setSize(frameWidth, frameHeight);

    // Create a moving square and add to the frame
    MovingSquare mySquare = new MovingSquare(frameWidth, frameHeight);      
    frmMain.add(mySquare);

    // Final configuration settings for frame.
    frmMain.setVisible(true);
    frmMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frmMain.setTitle("Moving Square");
}

}

您的 actionPerformed 方法正在更新您的方块的位置,远远超出了您的 moveXxx 方法的范围,您应该在那里进行范围检查

@Override
public void actionPerformed(ActionEvent e) 
{
    // Set the new x and y coordinates, depending on which direction we have moved
    xPos += movementX;
    yPos += movementY;

    if (xPos < 0) {
        xPos = 0;
    } else if (xPos + squareSize > xBound) {
        xPos = xBound - squareSize;
    }
    if (yPos < 0) {
        yPos = 0;
    } else if (yPos + squareSize > yBound) {
        yPos = yBound - squareSize;
    }

    // Redraw the square when something happens
    repaint();
}

如果知道屏幕和矩形的宽度和高度,则可以轻松检查它是否在内部:

int fX0 = 0, // left x border
    fX1 = frameWidth, // right x border
    fY0 = 0, // top y border
    fY1 = frameHeight; // bottom y border
int rX0, rX1, rY0, rY1; // keep these values updated width the rectangles position:
    //rX0 = rectangle position x
    //rX1 = rectangle position x + rectangle width
    //rY0 = rectangle position y
    //rY1 = rectangle position y + rectangle height
// Then, to check if the rect is inside the frame:
if (
    rX0 >= fX0 &&
    rX1 <  fX1 &&
    rY0 >= fY0 &&
    rY1 <  fY1
) { /* the rectangle is inside the frame bounds */ }
else { /* it's not inside the bounds, e.g. cancel movement */ }

第二种方法是使用矩形 class(我认为来自 awt):

Rectangle f = new Rectangle(0, 0, frameWidth, frameHeight); // bounds of the frame
Rectangle r = new Rectangle(...); // Your square bounds
// To check if r is inside f
if (
    f.contains(r)
) { /* the rectangle is inside the frame bounds */ }
else { /* it's not inside the bounds, e.g. cancel movement */ }

你可以做一个额外的方法:

public boolean Check(){
 if(xPos >0 && xPos-squareSize<frameWidth && yPos>0 && yPos-squareSize<frameHeight){
    //use a flag for example and make it false
  }else
     //flag==true 

   return flag;
 }

进入 KeyEvent 方法(如果 flag==true)然后执行移动,否则什么都不做或将 xpos 和 ypos 坐标重置回默认值或 JFrame 的特定位置。

添加一个 If(into KeyEvent methods)语句来检查坐标也很容易,如果它们被接受则进行移动。

例如:

public void KeyPressed(KeyEvent key){

 if(Check()==true){
  ..........//the code you have into KeyPressed method
  }


}//end of method KeyPressed