Java-Gaming.org    
Featured games (91)
games approved by the League of Dukes
Games in Showcase (576)
games submitted by our members
Games in WIP (497)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  2D racing game  (Read 3102 times)
synLB and 1 Guest are viewing this topic.
Offline raulinjho

Junior Newbie





« Posted 2007-12-17 19:14:45 »

hey guys,

I am doing right now my very first java game. it is a 2d racing game.

I want to implement a map-editor where I can create new racing tracks. Therefor I´ve got some quadratic images with the parts of the track.
The problem is that I use a double for - loop to draw the squares (by calling the paintComponent - Method) and I want to call it only once, but I´ve everytime when I call the repaint() -method (in an other class) it gets repaintet as well which makes my game quite slow... Sad

So what can I do to draw the track only once ?
and is there a better way to bulid up the track, without  using the double for -loop?

I hope you got what I mean Smiley

thanks for your help

best regards


these are the two classes :

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;


   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(
                  "ressources/car1.png"));
            
            System.out.println(car.getColorModel());
         } else if(player == 2){
            //blue car
            car = ImageIO.read(this.getClass().getResource(
                  "ressources/car2.png"));
            x = x +30;
         }
//         background = ImageIO.read(this.getClass().getResource("ressources/level1.png"));

      } catch (IOException e) {
         System.out.println("dupi");
      }

      // starts the drive thread
      startGame();

   }

   private void startGame() {
      // TODO Auto-generated method stub
      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, 25, 40, 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();
         }

      }

   }

}

--------------------------------------------------------------------------------------------------------

public class Circuit extends JPanel {


   private static final long serialVersionUID = 1;
   private BufferedImage[] street = new BufferedImage[7];
   private int[][] circuitIndex = new int[10][10];
   private boolean built = false;

   public Circuit() {

      setSize(1000, 1000);

      try {
         street[0] = ImageIO.read(this.getClass().getResource(
               "ressources/gw.png"));
         street[1] = ImageIO.read(this.getClass().getResource(
               "ressources/gs.png"));
         street[2] = ImageIO.read(this.getClass().getResource(
               "ressources/ur.png"));
         street[3] = ImageIO.read(this.getClass().getResource(
               "ressources/ul.png"));
         street[4] = ImageIO.read(this.getClass().getResource(
               "ressources/ol.png"));
         street[5] = ImageIO.read(this.getClass().getResource(
               "ressources/or.png"));

      } catch (IOException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }

      // TODO: read from textfile to fill the index

      circuitIndex[0][0] = 2;
      circuitIndex[0][1] = 0;
      circuitIndex[0][2] = 3;
      circuitIndex[0][3] = 6;
      circuitIndex[0][4] = 6;

      circuitIndex[1][0] = 1;
      circuitIndex[1][1] = 6;
      circuitIndex[1][2] = 5;
      circuitIndex[1][3] = 3;
      circuitIndex[1][4] = 6;

      circuitIndex[2][0] = 5;
      circuitIndex[2][1] = 0;
      circuitIndex[2][2] = 0;
      circuitIndex[2][3] = 4;
      circuitIndex[2][4] = 6;

      circuitIndex[3][0] = 6;
      circuitIndex[3][1] = 6;
      circuitIndex[3][2] = 6;
      circuitIndex[3][3] = 6;
      circuitIndex[3][4] = 6;

      circuitIndex[4][0] = 6;
      circuitIndex[4][1] = 6;
      circuitIndex[4][2] = 6;
      circuitIndex[4][3] = 6;
      circuitIndex[4][4] = 6;

   }

   @Override
   protected void paintComponent(Graphics g) {
      // TODO Auto-generated method stub
      super.paintComponent(g);
      Graphics2D g2d = (Graphics2D) g;
      for (int i = 0; i <= 4; i++) {
         for (int j = 0; j <= 4; j++) {

            if (circuitIndex[j] == 0) {
               g2d.drawImage(street[0], i * 200, j * 200, this);
            } else if (circuitIndex[j] == 1) {
               g2d.drawImage(street[1], i * 200, j * 200, this);
            } else if (circuitIndex[j] == 2) {
               g2d.drawImage(street[2], i * 200, j * 200, this);
            } else if (circuitIndex[j] == 3) {
               g2d.drawImage(street[3], i * 200, j * 200, this);
            } else if (circuitIndex[j] == 4) {
               g2d.drawImage(street[4], i * 200, j * 200, this);
            } else if (circuitIndex[j] == 5) {
               g2d.drawImage(street[5], i * 200, j * 200, this);
            } else if (circuitIndex[j] == 0) {
               g2d.drawImage(street[1], i * 200, j * 200, this);
            }

         }
      }
   }
}
Offline SimonH
« Reply #1 - Posted 2007-12-17 21:34:00 »

Why not have a big (1000x1000 pixel) BufferedImage for the whole track? Draw your street tiles onto it at startup, then when repaint() is called you need only draw the image (or faster still, only those parts of the image which had cars on them last frame).

People make games and games make people
Offline erikd

JGO Ninja


Medals: 15
Projects: 4
Exp: 14 years


Maximumisness


« Reply #2 - Posted 2007-12-17 22:54:39 »

I'd just make sure to draw only the tiles that are visible. Drawing in Java2D should easily be fast enough to handle that every frame.
Assuming the track will scroll, you'll have to repaint the whole screen anyway so I don't think doing some kind of 'dirty rectangles' algorithm will help much, if any.

I don't think the double for-loop really slows things down, it might be that your image drawing is not accellerated somehow. I'd advise looking at BufferStrategy and active rendering.
What might also help performance is to have your tiles in power-of-two dimensions, 32x32 or 64x64 or whatever, but try to convert your game to use BufferStrategy and active rendering first and see how that goes.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline broumbroum

Junior Member





« Reply #3 - Posted 2007-12-18 00:07:04 »

Your rendering is quite the poor manner, I apologize for it. This is passive rendering, that is delegation to Swing EDT for the refresh to proceed. I can suggest you to use another rendering API that has some enhancements on active rendering. I've built one on my own, which is known as the "sf3jswing project". It directly renders to the Canvas which is activated on runtime right after to be added in a container. I named it the RenderingScene class. Today I tested it for up to 60hz refresh period. Here it is : http://www.developpez.net/forums/showpost.php?p=2639576&postcount=80 and the latest source code is there : http://sf3jswing.cvs.sourceforge.net/sf3jswing/AnimationDemo3/src/net/library/jiga/sf3/game/RenderingScene.java?hideattic=0&view=log
I've also considered LWJGL API as a good introduction to gaming active rendering.

::::... :..... :::::: ;;;:::™ b23:production 2006 GNU/GPL @ http://b23prodtm.webhop.info
on sf.net: /projects/sf3jswing
Java (1.6u10 plz) Web Start pool
dev' VODcast[/ur
Offline raulinjho

Junior Newbie





« Reply #4 - Posted 2007-12-19 21:13:00 »

thanks guys for your tips

i tried to use BufferStrategy but i didn't get it how it works
I always get an IllegalStateException: Component must have a valid peer

here is the code again, so please tell me what the mistake is Smiley



Quote

public class Race extends JFrame {

   private static final long serialVersionUID = 1L;
   private static final int WIDTH = 800;
   private static final int HEIGTH = 600;
   private JPanel jContentPane = null;
   private JPanel jCars = null;
   
   private RacingCars player1;

   public Race() {
      super();
      initialize();
      player1.startCar();
   }

   private void initialize() {
      this.setSize(new Dimension(WIDTH, HEIGTH));
      this.setContentPane(getJContentPane());
      this.setTitle("JRace 2008");
      jContentPane.setVisible(true);
      jCars.setVisible(true);
      
   }

   private JPanel getJContentPane() {
      if (jContentPane == null) {
         jContentPane = new JPanel();
         jContentPane.setLayout(null);
         jContentPane.add(getJCars(), null);
      }
      return jContentPane;
   }

   private JPanel getJCars() {
      if (jCars == null) {
         jCars = new JPanel();
         jCars.setLayout(null);
         jCars.setBounds(new Rectangle(0, 0, WIDTH, HEIGTH));
         
         player1 = new RacingCars(1);
         jCars.add(player1);
      }
      return jCars;
   }



Quote
public class RacingCars extends Canvas implements Runnable {

   private static final long serialVersionUID = 1L;
   private BufferedImage car = null;
   private float x = 100F, y = 100F; // starting point of the car
   private double currentAngle = 0; // angel of the car
   private static int[] key = new int[256]; // keyboard input
   private float MAX_SPEED = 7F; // maximum speed
   private float speed = 0F; // speed of our racing car
   private float acceleration = 0.15F; // acceleration
   private int player;
   private Thread run = new Thread(this);

   public BufferStrategy strategy;
   public Graphics g;

   public RacingCars(int player) {

      
      this.player = player;
      setVisible(true);
      setFocusable(true); // enables keyboard

      try {
         if (player == 1) {
            // red car
            car = ImageIO.read(this.getClass().getResource(
                  "ressources/car1.png"));

         } else if (player == 2) {
            // blue car
            car = ImageIO.read(this.getClass().getResource(
                  "ressources/car2.png"));
            x = x + 30;
         }

      } catch (IOException e) {
         System.out.println("Error while filereading !");
      }
      
   }

   public void createStrategy() {
      createBufferStrategy(2);
      strategy = getBufferStrategy();
   }

   public 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;

   }

   public Graphics rotate(Graphics g) {

      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);
      return g2d;

   }

   // get key events!
   final protected void processKeyEvent(KeyEvent e) {
      key[e.getKeyCode()] = e.getID() & 1;
   }

   protected void userInput() {

      // Player One Key's
      if (player == 1) {

         if (key[KeyEvent.VK_LEFT] != 0) {
            currentAngle -= 2;
            System.out.println(currentAngle);

         } 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 render(Graphics g) {

      userInput();
      calculateCarPosition();
      rotate(g);
      g.drawImage(car, (int) x, (int) y, this);

   }
   
   public void startCar(){
      run.start();
   }

   @Override
   public void run() {

      createStrategy();

      while (true) {

         try {
            g = strategy.getDrawGraphics();
            render(g);
         } finally {
            g.dispose();
         }
         strategy.show();

         try {
            Thread.sleep(10);
         } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
         }
      }
   }
}

thanks for your hepl Smiley

Offline DzzD
« Reply #5 - Posted 2007-12-19 22:00:02 »

plz, provide java console output and line (viewable in Java console) that cause this error, than finding your error will be immediate

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
public Race() {
      super();
      initialize();
      player1.startCar();
   }

   private void initialize() {
      this.setSize(new Dimension(WIDTH, HEIGTH));
      this.setContentPane(getJContentPane());
      this.setTitle("JRace 2008");
      jContentPane.setVisible(true);
      jCars.setVisible(true);
     
   }


does'nt it come from one of those lines :

1  
2  
jContentPane.setVisible(true);
jCars.setVisible(true);


or maybe this one:
1  
createBufferStrategy(2);


Offline raulinjho

Junior Newbie





« Reply #6 - Posted 2007-12-20 07:22:06 »

here is the error msg:

Exception in thread "Thread-2" java.lang.IllegalStateException: Component must have a valid peer
   at java.awt.Component$FlipBufferStrategy.createBuffers(Unknown Source)
   at java.awt.Component$FlipBufferStrategy.<init>(Unknown Source)
   at java.awt.Component$FlipSubRegionBufferStrategy.<init>(Unknown Source)
   at java.awt.Component.createBufferStrategy(Unknown Source)
   at java.awt.Canvas.createBufferStrategy(Unknown Source)
   at java.awt.Component.createBufferStrategy(Unknown Source)
   at java.awt.Canvas.createBufferStrategy(Unknown Source)
   at at.fhjoanneum.ima.prog2.javarace.RacingCars.createStrategy(RacingCars.java:60)
   at at.fhjoanneum.ima.prog2.javarace.RacingCars.run(RacingCars.java:175)
   at java.lang.Thread.run(Unknown Source)

the addNotify()-method was missing...

I would also need a transparent background ... is this possible by using canvas ?
Offline broumbroum

Junior Member





« Reply #7 - Posted 2007-12-29 12:41:31 »

previous quoted error is thrown by the AWT EDT when you add the canvas as the canvas-component is not a child of any window or frame.

::::... :..... :::::: ;;;:::™ b23:production 2006 GNU/GPL @ http://b23prodtm.webhop.info
on sf.net: /projects/sf3jswing
Java (1.6u10 plz) Web Start pool
dev' VODcast[/ur
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

xsi3rr4x (12 views)
2014-04-15 18:08:23

BurntPizza (11 views)
2014-04-15 03:46:01

UprightPath (24 views)
2014-04-14 17:39:50

UprightPath (10 views)
2014-04-14 17:35:47

Porlus (27 views)
2014-04-14 15:48:38

tom_mai78101 (49 views)
2014-04-10 04:04:31

BurntPizza (108 views)
2014-04-08 23:06:04

tom_mai78101 (207 views)
2014-04-05 13:34:39

trollwarrior1 (176 views)
2014-04-04 12:06:45

CJLetsGame (182 views)
2014-04-01 02:16:10
List of Learning Resources
by Longarmx
2014-04-08 03:14:44

Good Examples
by matheus23
2014-04-05 13:51:37

Good Examples
by Grunnt
2014-04-03 15:48:46

Good Examples
by Grunnt
2014-04-03 15:48:37

Good Examples
by matheus23
2014-04-01 18:40:51

Good Examples
by matheus23
2014-04-01 18:40:34

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:22:30

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:05:20
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!