简体   繁体   中英

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

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

}

You actionPerformed method is updating the position of your square, well beyond what your moveXxx methods are, you should do your range checking there

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

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

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.

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.

For example:

public void KeyPressed(KeyEvent key){

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


}//end of method KeyPressed

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM