【发布时间】:2014-07-04 01:23:53
【问题描述】:
当游戏第一次开始时,玩家会生成,朝 0 方向(右)看。按下右键 (vk_right) 将玩家精灵向左转,但方向被设置为将玩家发送到(看起来像)正确的方向。左右键改变角色的方向变量,上/下键加速/减速角色。
我不太擅长三角学,所以我可能到处都有一些错误(这就是我发布此内容的原因)。我似乎无法理解如何让角色朝着他“看”的方向移动(方向变量)。
这是 Player.java 类:
package rpg2d;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.ImageIcon;
public class Player implements KeyListener{
private double x,y,direction;
private double speed;
private final int max_speed;
private int hp,lives;
private Image img;
//other variables
public Player(int x, int y, int hp, int lives, String imgpath) {
this.x = x;
this.y = y;
this.hp = hp;
this.lives = lives;
img = new ImageIcon(this.getClass().getResource(imgpath)).getImage();
//loads the player image from the string path
max_speed = 6;
speed = 0;
direction = 0;
}
//returns the direction the player is 'facing' as an int
public int getDirection() {
return (int)direction;
}
//updates the player's location
public void move() {
x += speed * Math.cos(-1*direction);
y += speed * Math.sin(-1*direction);
}
@Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_LEFT){
turn(.6);
//this is meant to turn the player int a clockwise direction by 0.6
} else if (key == KeyEvent.VK_RIGHT){
turn(-.6);
//counterclockwise by 0.6
}
if (key == KeyEvent.VK_DOWN){
speed -= 0.3;
if(speed < 0) speed = 0;
//decelerate until stopped
} else if (key == KeyEvent.VK_UP){
speed += 0.3;
if(speed > max_speed) speed = max_speed;
//accelerates until it hits maximum speed
}
}
private void turn(double degrees) {
direction += degrees;
if(direction > 180) direction -= 180;
else if(direction < -180) direction += 180;
/* I honestly don't know whether 180 and -180 are the max and min
* for Polar Coordinates, so this could be a problem.
*/
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent arg0) {
}
public int getX() {
return (int)x;
}
public int getY() {
return (int)y;
}
public double getWidth() {
return img.getWidth(null);
}
public double getHeight() {
return img.getHeight(null);
}
public Image getImg() {
return img;
}
}
这是主要的游戏类:
package rpg2d;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
boolean gameRunning = true;
Graphics2D g;
JFrame frame;
JPanel screen;
Player player;
public static void main(String[] args) {
new Main();
}
@SuppressWarnings("serial")
public Main() {
frame = new JFrame("2D RPG Test");
frame.setSize(800,600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
player = new Player(10,10,100,3,"/img/player.png");
screen = new JPanel() {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
AffineTransform trans = new AffineTransform();
AffineTransform old = new AffineTransform();
trans.setToIdentity();
trans.rotate(Math.toRadians(player.getDirection()),player.getWidth()/2,player.getHeight()/2);
g2d.setTransform(trans);
g2d.drawImage(player.getImg(), player.getX(), player.getY(), (int)player.getWidth(), (int)player.getHeight(), null);
g2d.setTransform(old);
g2d.drawString("X: " + player.getX() + " Y: " + player.getY(), 5,10);
trans.setToIdentity();
}
};
frame.add(screen);
frame.setVisible(true);
screen.addKeyListener(player);
screen.requestFocus();
Thread t = new Thread(new Runnable() {
public void run() {
gameLoop();
}
});
t.setDaemon(false);
t.start();
}
public void update() {
player.move();
}
public void gameLoop() {
final int FPS = 60;
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
update();
screen.repaint();
}
}, 0, FPS);
}
}
【问题讨论】:
-
如果这是我的问题,我会摆脱底部的咆哮,因为它会分散注意力并且毫无用处。如果您花时间更详细地描述您的代码以便我们能够理解它,这个问题会更好地解决。如果我能一眼看懂你的代码,我现在可能已经给你答案了。顺便说一句,将 java.util.Timer 与 Swing 应用程序一起使用通常是不安全的。最好使用 javax.swing.Timer。
-
对咆哮感到抱歉。只是每次我发布这样的东西,我最终都会得到这样的回应。我会用代码解释更新帖子。
-
我会说问题出在您的图像上,而不是您的代码上。当我在运行时创建一个简单的箭头形状时,指向右边,它工作得很好。考虑发布您的图片副本
-
请理解,当您在此处发布信息寻求帮助时,您将获得志愿者的免费帮助。我们将尝试回答您的问题,但我们也会尝试帮助解决我们可能会看到的您的代码的任何其他问题。我自己,我会感谢您免费获得的额外努力。例如,我还要告诉你避免使用 KeyListeners 而是支持 Key Bindings,并避免给你的类一个 Graphics 或 Graphics2D 字段,因为这可能是一件危险的事情,并且有可能引发 NPE。
-
您应该避免使用
Thread和java.util.Timer,因为Swing 不是线程安全的,当您调用update时,Swing 可能正在绘制,这可能会导致绘制/更新不干净。考虑使用javax.swing.Timer或创建一个屏幕外缓冲区,您可以在其上进行绘画,然后通过同步机制推送到 UI
标签: java swing graphics trigonometry radians