今天我一直致力于一个基本的坦克式游戏,两个玩家控制他们的坦克(绿色和红色),然后互相射击。在开发基于旋转的移动系统时,(意味着玩家旋转指向一个方向,然后在该方向上向前或向后直线移动),我在我的代码中遇到了一个缺陷。
问题在于,我不是旋转每个玩家的图像,而是将它们放在游戏画面上,而是旋转整个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
答案 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();
(现在,我正在思考,循环对此非常有帮助)