【发布时间】:2018-05-01 13:23:22
【问题描述】:
我正在尝试通过在 Jpanel 之上添加 Jpanel 来制作 2D 赛车游戏。这是通过使用我在下面发布的 2 个类来完成的。
问题是这辆车从来没有出现在赛道上……我真的不确定我错过了什么……任何帮助都非常受欢迎!
提前谢谢你!
汽车.java
public class Car extends JPanel implements Runnable
{
private static final long serialVersionUID = 007;
private BufferedImage car = null;
private float x = 100F, y = 100F;
private Thread driveThread = new Thread(this);
private double currentAngle = 0; // angel of the car
private static int[] key = new int[256]; // keyboard input
private float MAX_SPEED = 7F;
private float speed = 0F; // speed of our racing car
private float acceleration = 0.15F;
private int player;
private boolean playable = true;
public Car(int player)
{
this.player = player;
this.setSize(super.getHeight(), super.getWidth());
this.setFocusable(true); // enables keyboard
try
{
if (player == 1)
{
//red car
car = ImageIO.read(this.getClass().getResource(
"/imagesCar/first-0.png"));
System.out.println(car.getColorModel());
} else if(player == 2)
{
//blue car
car = ImageIO.read(this.getClass().getResource(
"/imagesCar/second-0.png"));
x = x +30;
}
} catch (IOException e) {
System.out.println("dupi");
}
// starts the drive thread
startGame();
}
private void startGame() {
driveThread.start();
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
this.setOpaque(false);
// rotation
Graphics2D g2d = (Graphics2D) g;
AffineTransform rot = g2d.getTransform();
// Rotation at the center of the car
float xRot = x + 12.5F;
float yRot = y + 20F;
rot.rotate(Math.toRadians(currentAngle), xRot, yRot);
g2d.setTransform(rot);
//Draws the cars new position and angle
g2d.drawImage(car, (int) x, (int) y, 50, 50, this);
}
protected void calculateCarPosition() {
//calculates the new X and Y - coordinates
x += Math.sin(currentAngle * Math.PI / 180) * speed * 0.5;
y += Math.cos(currentAngle * Math.PI / 180) * -speed * 0.5;
}
protected void carMovement() {
// Player One Key's
if (player == 1) {
if (key[KeyEvent.VK_LEFT] != 0) {
currentAngle-=2;
} else if (key[KeyEvent.VK_RIGHT] != 0) {
currentAngle+=2;
}
if (key[KeyEvent.VK_UP] != 0) {
if (speed < MAX_SPEED) {
speed += acceleration;
}
} else if (key[KeyEvent.VK_DOWN] != 0 && speed > -1) {
speed = speed - 0.1F;
}
speed = speed * 0.99F;
} else {
//Player Two Key's
if (key[KeyEvent.VK_A] != 0) {
currentAngle -= 2;
} else if (key[KeyEvent.VK_D] != 0) {
currentAngle += 2;
}
if (key[KeyEvent.VK_W] != 0) {
if (speed < MAX_SPEED) {
speed += acceleration;
}
} else if (key[KeyEvent.VK_S] != 0 && speed > -1) {
speed = speed - 0.1F;
}
//reduce speed when no key is pressed
speed = speed * 0.99F;
}
}
public void getUnderground() {
}
// get key events!
final protected void processKeyEvent(KeyEvent e) {
key[e.getKeyCode()] = e.getID() & 1;
}
@Override
public void run() {
while (true) {
repaint();
carMovement();
calculateCarPosition();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
RaceTrack.java
public class RaceTrack extends JPanel
{
@Override
public void paintComponent(Graphics g)
{
Color c1 = Color.green;
g.setColor(c1);
g.fillRect(150, 200, 550, 300);
Color c2 = Color.black;
g.setColor(c2);
g.drawRect(50, 100, 750, 500); // outer edge
g.drawRect(150, 200, 550, 300); // inner edge
Color c3 = Color.yellow;
g.setColor(c3);
g.drawRect(100, 150, 650, 400); // mid-lane marker
Color c4 = Color.white;
g.setColor(c4);
g.drawLine(425, 500, 425, 600); // start line
}
}
主要
public static void main(String[] args) {
JFrame mainFrame = new JFrame();
mainFrame.setSize(850,650);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container content = mainFrame.getContentPane();
RaceTrack track = new RaceTrack();
Car carP1 = new Car(1);
track.add(carP1);
content.add(track);
mainFrame.setVisible(true);
}
【问题讨论】:
-
1.
Car没有定义尺寸提示,所以它的默认尺寸是0x0; 2.将Car添加到RaceTrack,使用FlowLayout将布局Car到它的首选大小0x0; 3. Swing 不是线程安全的,所以你可能还有一堆线程竞争条件/违规 -
不确定这是否是解决此问题的正确方法,但我尝试在将
carP1.setPreferredSize(new Dimension(50,50));添加到 RaceTrack 之前添加它。似乎没有解决问题.. -
不要为此任务使用组件。相反,你需要发展“实体”的概念,这些“实体”做“东西”,比如“油漆”。然后,您定义这些“实体”的列表(有时基于那里的功能在不同的列表中)。在您的渲染器中,您循环遍历“可绘制”实体并绘制它们。然后,您将拥有一个线程,其职责是更新所有“可移动”(或以其他方式随时间变化)的实体并安排绘制通道。简单来说,你可以使用 Swing
Timer有“主循环”