无法实施 object 向鼠标 JAVA 的旋转

Failed to implement object rotation towards mouse JAVA

正如标题所说,就是做不到。尝试了很久,还是失败了。 (我是 java 的新手)
我的图像或 fillRect 旋转了一点,但没有按应有的方式旋转
整个代码 +imgs


    *MAIN game class*
    package game.main;

    import java.awt.Canvas;
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.image.BufferStrategy;

    public class game extends Canvas implements Runnable{

        private static final long serialVersionUID = -392333887196083915L;

        public static final int WIDTH = 640, HEIGHT = WIDTH / 12 * 9;
        private Thread thread;
        private boolean running = false;

        private Handler handler;

        public game(){

            handler = new Handler();

            new window(WIDTH, HEIGHT,"Game",this);

            handler.addObject(new Player(WIDTH/2-32, HEIGHT/2-32, ID.Player, handler));
        }

        public synchronized void start(){
            thread = new Thread(this);
            thread.start();
            running = true;
        }
        public synchronized void stop(){
            try{
                thread.join();
                running = false;
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        // ↓ game loop for update
        public void run(){
            this.requestFocus();
            long lastTime = System.nanoTime();
            double amountOfTicks = 60.0;
            double ns = 1000000000 / amountOfTicks;
            double delta = 0;
            long timer = System.currentTimeMillis();
            int frames = 0;
            while(running){
                long now = System.nanoTime();
                delta += (now - lastTime) / ns;
                lastTime = now;
                while(delta >= 1){
                    tick();
                    delta--;
                }
                if(running)
                    render();
                frames++;

                if(System.currentTimeMillis() - timer > 1000){
                    timer += 1000;
                    System.out.print("FPS:" + frames);
                    frames = 0;
                }
            }
            stop();
        }

        private void tick(){
                    handler.tick();             
                }

        private void render(){
            BufferStrategy bs = this.getBufferStrategy();
            if(bs == null){
                this.createBufferStrategy(3);
                return;
            }

            Graphics g = bs.getDrawGraphics();

            g.setColor(Color.black);
            g.fillRect(0, 0, WIDTH, HEIGHT);

            handler.render(g);

            g.dispose();
            bs.show();
        }



        public static void main(String args[]) {
            new game();
        }


    }
<br>
package game.main;

import java.awt.Graphics;

public abstract class GameObject {

    protected float x, y;
    protected ID id;
    protected float velX, velY;

    public GameObject(float x, float y, ID id){
            this.x = x;
            this.y = y;
            this.id = id;
    }

    public abstract void tick();
    public abstract void render(Graphics g);

    public void setX(int x){
        this.x = x;
    }
    public void setY(int y){
        this.y = y;
    }   
    public float getX(){
        return x;
    }
    public float getY(){
        return y;
    }
    public void setId(ID id){
        this.id = id;
    }
    public ID getId(){
        return id;
    }
    public void setVelX(int velX){
        this.velX = velX;
    }
    public void setVelY(int velY){
        this.velY = velY;
    }
    public float getVelX(){
        return velX;
    }
    public float getVelY(){
        return velY;
    }
}


*GameObject class*
package game.main;

import java.awt.Graphics;

public abstract class GameObject {

    protected float x, y;
    protected ID id;
    protected float velX, velY;

    public GameObject(float x, float y, ID id){
            this.x = x;
            this.y = y;
            this.id = id;
    }

    public abstract void tick();
    public abstract void render(Graphics g);

    public void setX(int x){
        this.x = x;
    }
    public void setY(int y){
        this.y = y;
    }   
    public float getX(){
        return x;
    }
    public float getY(){
        return y;
    }
    public void setId(ID id){
        this.id = id;
    }
    public ID getId(){
        return id;
    }
    public void setVelX(int velX){
        this.velX = velX;
    }
    public void setVelY(int velY){
        this.velY = velY;
    }
    public float getVelX(){
        return velX;
    }
    public float getVelY(){
        return velY;
    }
}


*Handler class*
package game.main;

import java.awt.Graphics;
import java.util.LinkedList;

// render all objects
public class Handler {

    LinkedList<GameObject> object = new LinkedList<GameObject>();

    public void tick(){
        for(int i = 0; i < object.size(); i++){
            GameObject tempObject = object.get(i);

            tempObject.tick();      
        }
    }
    public void render(Graphics g){
        for(int i = 0; i <object.size();i++){
            GameObject tempObject = object.get(i);

            tempObject.render(g);
        }
    }// handling adding objects
    public void addObject(GameObject object){
        this.object.add(object);
    }   
}


*window class*
package game.main;

import java.awt.Canvas;
import java.awt.Dimension;

import javax.swing.JFrame;

public class window extends Canvas{

    private static final long serialVersionUID = 3010486623466540351L;

    public window(int width, int height, String title, game game){
        JFrame frame = new JFrame(title);

        frame.setPreferredSize(new Dimension(width, height));
        frame.setMaximumSize(new Dimension(width, height));
        frame.setMinimumSize(new Dimension(width, height));

        // X button
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // ¤ button maximize
        frame.setResizable(false);
        // window appear in middle of screen instead of top left corner
        frame.setLocationRelativeTo(null);
        // add game to window
        frame.add(game);
        frame.setVisible(true);
        game.start();
    }       
}


* ID class*
package game.main;

public enum ID {

    Player();
}


仅向此添加代码 class

*Player class*
package game.main;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;

public class Player extends GameObject{

    Handler handler;

    public Player(int x, int y, ID id, Handler handler) {
        super(x, y, id);
        this.handler = handler;
    }

    public void tick() {
    }
    public void render(Graphics g) {
        ///////////ADDED//////////////////
        PointerInfo a = MouseInfo.getPointerInfo();
        Point b = a.getLocation();
        int mouseX = (int) b.getX();
        int mouseY = (int) b.getY();
        int centerX = game.WIDTH / 2;
        int centerY = game.HEIGHT / 2;
        double angle = Math.atan2(centerY - mouseY, centerX - mouseX) - Math.PI / 2;
        ((Graphics2D)g).rotate(angle, centerX, centerY);
        //////////////////////////////
        g.setColor(Color.white);
        g.fillRect((int)x, (int)y, 32, 32);

    }
}


它现在是如何工作的以及我想要它的方式。白色 - 原创/绿色 - 我想要这样
Example 1
Example 2
我查看了这个来源:
Get mouse possition (Whosebug)
Java 2d rotation in direction mouse point (Whosebug)
Rotating an object to point towards the mouse

问题是 MouseInfo.getPointerInfo().getLocation(); returns 绝对鼠标位置。您需要相对于您的游戏的鼠标位置 canvas。你可以修改你的gameclass中的render方法如下:

 Point mouseLocation = MouseInfo.getPointerInfo().getLocation();
 SwingUtilities.convertPointFromScreen(mouseLocation, this);
 handler.render(g, mouseLocation);

这需要您相应地修改渲染方法的方法签名。这只是将游戏 canvas 中的 mouseLocation 传递给玩家渲染方法的一种方法。 在播放器的渲染方法中使用 mouseLocation 而不是 MouseInfo.getPointerInfo().getLocation();

为了将玩家置于 canvas 的中心并使他围绕他的中心旋转,您还需要进行一些更改:

  • 您应该设置游戏大小 canvas 而不是 window(JFrame)。为此,请在游戏 canvas 上调用 setPreferredSize(new Dimension(width, height)); 并在 frame.setVisible(true) 之前调用 frame.pack()。这将确保您的游戏 canvas 具有 WIDTHHEIGHT.
  • 指定的大小
  • 您可以将两个字段 refxrefy 添加到您的 GameObject class 来描述您的 GameObject 的参考点(例如它的中心) .然后,您可以通过调用 new Player(WIDTH/2-16, HEIGHT/2-16, 16, 16, ID.Player, handler) 来构造一个新的 Player,玩家的初始位置位于 (WIDTH/2-16, HEIGHT/2-16) 及其参考点是 (16,16) - 当玩家由 32x32 矩形表示时玩家的中心。
  • 在 Player 的渲染方法中,用 int centerX = Math.round(x + refx); int centerY = Math.round(y + refy); 初始化你想要旋转的中心,其中 (x,y) 是你想要旋转的对象的位置和 (refx, refy) 你想要的点相对于对象的位置旋转(例如 x = WIDTH/2-16,y = HEIGTH/2-16,refx = 16,refy = 16)。