JPanel没有出现在另一个JPanel中

时间:2018-05-01 02:39:21

标签: java swing jpanel

我正在尝试通过在Jpanel上添加Jpanel来制作2D赛车游戏。这是通过使用我在下面发布的2个类来完成的。

问题是汽车永远不会出现在赛道上......我真的不确定我错过了什么......任何帮助都非常受欢迎!

提前谢谢!

Car.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 个答案:

答案 0 :(得分:1)

  1. Car没有定义的大小提示,因此它的默认大小为0x0
  2. Car添加到使用RaceTrack的{​​{1}}会将FlowLayout布局为Car的首选大小
  3. Swing不是线程安全的,所以你可能也有一堆线程竞争条件/违规
  4.   

    不确定这是否是解决此问题的正确方法

    不要为此目的使用组件,这个问题只是尖叫自定义绘画。

    有很多关于基本游戏开发的博客和教程,所以我不想花很多时间浏览相同的材料。

    基本上,你想要的是为你想要在游戏中使用的对象定义一系列“属性”(AKA“实体”)。并非所有实体都需要具有可绘制性,有些实体可能触发其他操作,或者只是充当其他实体使用的“标记”。

    在这个例子中,我定义了两个基本实体,“可移动”和“可绘制”。 “可绘制的”实体可以是静态的(即轨道)或“可移动的”(即汽车)

    目的是提供一个孤立的功能概念,可以很容易地应用于真实对象,以“描述”他们在游戏中的功能和目的。

    例如......

    0x0

    因此,在您的情况下,public interface MovableEntity extends Entity { public void update(Rectangle bounds); } public interface PaintableEntity extends Entity { public void paint(Graphics2D g2d, ImageObserver imageObserver, Rectangle bounds); } 同时为CarPaintable

    然后,您的“引擎”将维护这些“实体”的一个或多个列表并相应地处理它们。

    这个例子只是使用Swing Movable作为“主循环”

    Timer

    这提供了一定程度的线程安全性,因为mainLoop = new Timer(5, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { Rectangle bounds = new Rectangle(0, 0, getWidth(), getHeight()); // Lots of collision detection and other awesome stuff for (MovableEntity entity : movableEntitys) { entity.update(bounds); } repaint(); } }); mainLoop.start(); 是在事件调度线程的上下文中触发的,这意味着当我们更新实体时,它们不能被绘制。

    然后我们只是使用Timer的{​​{1}}方法充当渲染过程......

    JPanel

    这是一个非常广泛的例子,它基于以简单的方式展示基本概念。有更复杂的可能解决方案遵循相同的基本原则。

    就个人而言,我会定义某种“路径”作为轨道,然后汽车会根据不同因素计算出位置,但这是一个更复杂的解决方案,现在需要。但如果你真的感兴趣,它可能看起来像like this

    可运行的示例...

    paintComponent