如何正确旋转我的球员? Java的

时间:2014-11-09 12:58:25

标签: java swing

今天我一直致力于一个基本的坦克式游戏,两个玩家控制他们的坦克(绿色和红色),然后互相射击。在开发基于旋转的移动系统时,(意味着玩家旋转指向一个方向,然后在该方向上向前或向后直线移动),我在我的代码中遇到了一个缺陷。

问题在于,我不是旋转每个玩家的图像,而是将它们放在游戏画面上,而是旋转整个JFrame画布。

这会导致第一个玩家完美地工作,但第二个玩家在他/她旋转时绕第一个玩家运行。

希望有人知道如何更改我的移动系统以旋转玩家图像,然后放置它,这样每个玩家都可以单独移动而不会相互影响。

这是我的播放器代码(播放器1和播放器2的代码实际上完全相同,除了 加载图像,以及一些变量的名称)

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

public class Player 
{
    imageLoader loader = new imageLoader();
    private BufferedImage player = loader.loadImage("/player2.png");

    public int xPos = 400;
    public int yPos = 400;
    public double degrees = 90.0;

    public Input input;

    public void render(Graphics g)
    {
        ((Graphics2D) g).rotate(Math.toRadians(degrees), xPos+16, yPos+16);
        g.drawImage(player, xPos, yPos, null);
    }

    public void moveForward()
    {
        xPos += (int) (Math.sin(degrees * (Math.PI/180)) * 4);
        yPos += (int) (Math.cos(degrees * (Math.PI/180)) * -4);
    }
    public void moveBackward()
    {
        xPos -= (int) (Math.sin(degrees * (Math.PI/180)) * 4);
        yPos -= (int) (Math.cos(degrees * (Math.PI/180)) * -4);
    }
    public void rotateLeft()
    {
        degrees = degrees - 4;
    }
    public void rotateRight()
    {
        degrees = degrees + 4;
    }

}

这是我的主要游戏文件(处理渲染,绘制JFrame等)

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;

public class main extends Canvas implements Runnable
{
    private static final long serialVersionUID = 1L;
    public static final int WIDTH = 320, HEIGHT = WIDTH/12*9, SCALE = 4;
    public static final String NAME = "Tanks";    

    private JFrame frame;
    public boolean running = false;
    public int tickCount = 0;
    Player player = new Player();
    Player2 player2 = new Player2();
    public Input input;
    Graphics g;
    Graphics2D g2d;

    public main()
    {
        setMinimumSize(new Dimension(WIDTH*SCALE, HEIGHT*SCALE));
        setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
        setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));

        frame = new JFrame(NAME);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());

        frame.add(this, BorderLayout.CENTER);
        frame.pack();

        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private synchronized void start()
    {
        running = true;
        new Thread(this).start();
    }

    private synchronized void stop()
    {
        running = false;
    }

    public void run()
    {
        long lastTime = System.nanoTime();
        double nsPerTick = 1000000000D/60D;
        int ticks = 0;
        int frames = 0;
        long lastTimer = System.currentTimeMillis();
        double delta = 0;

        Init();

        while(running)
        {
            long now = System.nanoTime();
            delta+=(now - lastTime)/nsPerTick;
            lastTime = now;
            boolean shouldRender = true;

            while(delta >= 1)
            {
                ticks++;
                tick();
                delta-=1;
                shouldRender = true;
            }
            try
            {
                Thread.sleep(2);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            if(shouldRender)
            {
                frames++;
                render();
            }

            if(System.currentTimeMillis()-lastTimer >= 1000)
            {
                lastTimer += 1000;
                //System.out.println("FRAMES: " + frames + "  |  " + "TICKS: " + ticks);
                frames = 0;
                ticks = 0;
            }
        }
    }

    public void Init()
    {
        input = new Input(this);
    }

    public void tick() //Updates game
    {
        tickCount++;
        if(input.up.isPressed()) 
        {
            player.moveForward();
        }
        if(input.down.isPressed()) 
        {
            player.moveBackward();
        }
        if(input.left.isPressed()) 
        {
            player.rotateLeft();
        }
        if(input.right.isPressed()) 
        {
            player.rotateRight();
        }
        //Player 2 Controls
        if(input.w.isPressed()) 
        {
            player2.moveForward();
        }
        if(input.s.isPressed()) 
        {
            player2.moveBackward();
        }
        if(input.a.isPressed()) 
        {
            player2.rotateLeft();
        }
        if(input.d.isPressed()) 
        {
            player2.rotateRight();
        }
    }

    public void render() //Print out what is updated
    {
        BufferStrategy bs = getBufferStrategy();
        if(bs == null)
        {
            createBufferStrategy(3);
            return;
        }
        g = bs.getDrawGraphics();
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, WIDTH*SCALE, HEIGHT*SCALE);

        player.render(g);
        player2.render(g);

        g.dispose(); //Clears up memory
        bs.show(); //Push image to screen
    }

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

非常感谢,

Ryan Corkery

1 个答案:

答案 0 :(得分:0)

使用Graphics创建Graphics#create上下文的副本并对其进行转换/翻译...

public void render(Graphics g)
{
    Graphics2D g2d = (Graphics2D)g.create();
    g2d.rotate(Math.toRadians(degrees), xPos+16, yPos+16);
    g2d.drawImage(player, xPos, yPos, null);
    g2d.dispose();
}

或者,如果您不相信render方法做正确的事情......

Graphics2D g2d = (Graphics2D)g.create();
player.render(g2d);
g2d.dispose();
g2d = (Graphics2D)g.create();
player2.render(g);
g2d.dispose();

(现在,我正在思考,循环对此非常有帮助)