Установка границы для движущейся площади - PullRequest
2 голосов
/ 13 февраля 2020

Так что, в основном, я просто играю с системами движения для разных целей и испытываю затруднения, делая квадратную остановку прямо на краю. Квадрат сдвигается с боковой стороны экрана примерно на 50% площади, и я не могу понять, почему это так.

package SnakeMovement;

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

@SuppressWarnings("serial")
public class SnakeMovement extends Canvas implements ActionListener, KeyListener {

    Timer timer = new Timer(5, this);

    int width, height;

    int xSize = 50, ySize = 50;
    int yPos = 0, xPos = 0, yVel = 0, xVel = 0;

    public SnakeMovement(int w, int h) {
        timer.start();

        width = w;
        height = h;

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

    }

    public void paint(Graphics g) {
        super.paint(g);

        g.fillRect(xPos, yPos, xSize, ySize);
    }

    public void actionPerformed(ActionEvent e) {
        xPos += xVel;
        yPos += yVel;

        if (xPos >= width - xSize) {
            xPos = width - xSize;
            xVel = 0;
        }

        repaint();
    }

    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();

        if (key == KeyEvent.VK_W) {
            yVel = -10;
            xVel = 0;
        }

        if (key == KeyEvent.VK_S) {
            yVel = 10;
            xVel = 0;
        }

        if (key == KeyEvent.VK_A) {
            xVel = -10;
            yVel = 0;
        }

        if (key == KeyEvent.VK_D) {
            xVel = 10;
            yVel = 0;
        }

    }

    public void keyReleased(KeyEvent e) {
    }

    public void keyTyped(KeyEvent e) {
    }


}

Я просто хочу, чтобы квадратные остановки с каждой стороны экрана были идеально на краю.

1 Ответ

2 голосов
/ 13 февраля 2020

Попробуйте:

private static final int BORDER_SIZE = 1;
private static final Color RECT_COLOR = Color.BLUE, BORDER_COLOR = Color.RED;

 @Override
 public void paint(Graphics g) {
     super.paint(g);
     g.setColor(BORDER_COLOR);
     g.fillRect(xPos, yPos, xSize, ySize);
     g.setColor(RECT_COLOR);
     g.fillRect(xPos+BORDER_SIZE, yPos+BORDER_SIZE, xSize-2*BORDER_SIZE, ySize-2*BORDER_SIZE);
}

Идея состоит в том, чтобы нарисовать прямоугольник полного размера angular, используя цвет границы. Затем нарисуйте меньший (на 2 * BORDER_SIZE), используя цвет прямоугольника angular.


Ниже приведено mre из вышеперечисленного:
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.Timer;

public class SnakeMovement extends Canvas implements ActionListener, KeyListener {

    private static final int BORDER_SIZE = 1, DELAY = 100;
    private static final Color RECT_COLOR = Color.BLUE, BORDER_COLOR = Color.RED;
    private final int xSize = 50, ySize = 50;
    private int yPos = 0, xPos = 0, yVel = 5, xVel = 5;
    private final Timer timer = new Timer(DELAY, this);

    public SnakeMovement(int width, int height) {
        timer.start();
        addKeyListener(this);
        setFocusTraversalKeysEnabled(false);
        setFocusable(true);
        setPreferredSize(new Dimension(width, height));
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.setColor(BORDER_COLOR);
        g.fillRect(xPos, yPos, xSize, ySize);
        g.setColor(RECT_COLOR);
        g.fillRect(xPos+BORDER_SIZE, yPos+BORDER_SIZE, xSize-2*BORDER_SIZE, ySize-2*BORDER_SIZE);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        xPos += xVel;
        yPos += yVel;
        checkLimits();
        repaint();
    }

    //when canvas edge is reached emerge from the opposite edge
    void checkLimits(){
        //check x and y limits
        if (xPos >= getWidth()) {
            xPos = -xSize;
        }
        if (xPos < -xSize ) {
            xPos = getWidth();
        }

        if (yPos >= getHeight() ) {
            yPos = -ySize;
        }
        if (yPos < -ySize ) {
            yPos = getHeight();
        }
    }

    //two other behaviors when hitting a limit. uncomment the desired behavior  
    /*

        //when canvas edge is reached change direction
        void checkLimits(){
            //check x and y limits
            if (  xPos >= getWidth() - xSize ||  xPos <= 0) {
                xVel = - xVel;
            }

            if (  yPos >= getHeight() - ySize ||  yPos <= 0) {
                yVel = - yVel;
            }
        }
     */

    /*

        //when canvas edge is reached stop movement
        void checkLimits(){
            //check x and y limits
            if (  xPos >= getWidth() - xSize ||  xPos <= 0 ||  yPos >= getHeight() - ySize ||  yPos <= 0) {
                timer.stop();
            }
        }

     */

    @Override
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();

        if (key == KeyEvent.VK_W) {
            yVel = -10;
            xVel = 0;
        }

        if (key == KeyEvent.VK_S) {
            yVel = 10;
            xVel = 0;
        }

        if (key == KeyEvent.VK_A) {
            xVel = -10;
            yVel = 0;
        }

        if (key == KeyEvent.VK_D) {
            xVel = 10;
            yVel = 0;
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    public static void main(String[] args0) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new SnakeMovement(500, 500));
        frame.pack();
        frame.setVisible(true);
    }
}

enter image description here

...