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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28531137/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 13:45:41  来源:igfitidea点击:

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

javagraphicsshapes

提问by Sam

I have a program to move a square about using the keyboard. It moves around fine when I press one of the arrow keys, but if I move it to the edge of the frame, I want it to stop. It does not do this however. If I move the square to the edge of the frame it keeps going and moves right past the edge of the screen.

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

I have put controls into my code to try stopping the square, but they don't seem to be working. Not really sure what is going wrong here.

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

This is the code to set up and draw the square:

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

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;
        }               
    }   
}

And this is the main 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");
}

}

采纳答案by MadProgrammer

You actionPerformedmethod is updating the position of your square, well beyond what your moveXxxmethods are, you should do your range checking there

您的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();
}

回答by RegisteredUser

If you know the width and height of ths screen and the rect, you can easiely check if it's inside:

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

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 */ }

The second method of doing this is by using the Rectangle class (from awt I think):

第二种方法是使用 Rectangle 类(我认为来自 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 */ }

回答by crAlexander

You can make an extra method:

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

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;
 }

Into KeyEvent method(if flag==true) then do the movement else do nothing or reset the xpos and ypos coordinates back to default or to a specific position of the JFrame.

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

Also it is easy to add an If(into KeyEvent methods)statement to check the coordinates and if they are accepted then do the movement.

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

For example:

例如:

public void KeyPressed(KeyEvent key){

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


}//end of method KeyPressed