-1

I have an assignment about making a car simulation program in Java. I'm currently having trouble with moving the car in the map. Here's the code of the Map (main) class

import java.awt.Graphics;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;

import project.Car;
public class Map extends JPanel {

public static void main(String[] args)
{
JFrame f = new JFrame();
f.setSize(800, 450);
f.add(new Map());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);

Car carA = new Car();
Car carB = new Car();    

/*
int rX = randX();
carA.positionX = carA.setPositionX(rX);

System.out.println(carA.getPositionX());
*/  
}

public static int randX()
{
  Random rnX = new Random();

  int randomX = rnX.nextInt((40 - 0) + 1) + 0;

  if (randomX >= 0 && randomX <= 4 || randomX == 20 && randomX <= 24  || randomX >= 25)
  {
      randX();
  }

  return randomX;
 }

 public static int randY()
 {
  Random rnY = new Random();

  int randomY = rnY.nextInt((55 - 15) + 1) + 15;

  if (randomY >= 0 && randomY <= 4 || randomY >= 25 && randomY <= 29 || randomY >= 30)
  {
      randY();
  }

  return randomY;
}

//paint a = new paint();

public void paint(Graphics g)
{
g.drawRect (0 , 0, 500,200); //
g.drawRect (20, 25, 450,150); // The road
g.drawRect (40, 50, 400,100); //

g.drawRect (10 , 10, 8,8); //One of the car's initialization

}

}

And here's the Car class

import java.awt.Graphics;
import java.awt.Toolkit;
import java.util.Random;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.util.Timer;
import java.util.TimerTask;


public class Car extends JPanel
{
int positionX = 0;
int positionY = 0;
int weight = 0;
//int lane = 0;

public int getPositionX()
{
    return positionX;
}

public int setPositionX(int newPosX)
{
    positionX = newPosX;
    return positionX;
}

public int getPositionY()
{
    return positionY;
}

public int setPositionY(int newPosY)
{
    positionY = newPosY;
    return positionY;
}

public int Accelerate()
{
    Toolkit toolkit = Toolkit.getDefaultToolkit();
    Timer timer = new Timer();
    timer.schedule(new RemindTask(), 0, //initial delay
    1 * 1000); //subsequent rate
    //schedule(TimerTask task, long delay);
    return positionX;
}

class RemindTask extends TimerTask 
{
//int numWarningBeeps = 3;

public void run()
{
    if(positionX <= 450 && positionY <= 23)
    {
        positionX += 1;
    }
    else if(positionX == 450 && positionY <= 23)
    {
        positionY+= 1;
    }
    else if(positionY <= 150 && positionX >= 15)
    {
        positionX -= 1;
    }
    else if(positionY == 150 && positionX == 23)
    {
        positionY -= 1;
    }
}
}

public static int main(int[] args)
{

    return 0;
}
}

As it seems, I don't know how to apply the timer I've made, nor I know whether it works or not.. Please give me some guidance on how to apply timer so that the car can move around in the designated area..

pgiecek
  • 7,970
  • 4
  • 39
  • 47
KaeM
  • 3
  • 2
  • 8
  • Where are you drawing the cars? – isnot2bad Jul 24 '14 at 17:28
  • In that g.drawRect (10 , 10, 8,8); , it's in Map class :D – KaeM Jul 24 '14 at 17:29
  • No, this only draws a rectangle at a hard coded position. There is nowhere a Car object in your Map code. – isnot2bad Jul 24 '14 at 17:30
  • Ohh so that's how it works.. So I got to draw it in the Car class? – KaeM Jul 24 '14 at 17:31
  • Possibly. Fact is that your code right now does not draw any cars at all. How are your plans to achieve this? – isnot2bad Jul 24 '14 at 17:32
  • Thanks for pointing that out.. I've moved the that drawRect(10, 10, 8, 8) into car and changed it into drawRect(getPositionX(), getPositionY, 8, 8); . I'm now confused about how to call that method into class Map.. May I have some explanation on how to do so? – KaeM Jul 24 '14 at 17:37

2 Answers2

3
  1. I'd stay away from making each car a panel. You have to deal with positioning panels, sizing them, possibly layering them, among other things, which IMO is unnecessary an may over-complicate and cause issues.

    Instead just use one panel as the painting surface, and create a class which will be the model; model in the sense that it will just be responsible for holding the manipulating the state of a car. It can also has a method to render the car, but the actual rendering will be delegated to the graphics context of the main panel.

  2. Don't use a java.util.Timer. instead use a javax.swing.Timer, which is more suitable for dealing with repainting the UI, among other things related to Swing. You can see more at How to use Swing Timers. Basically, all you do is pass a determined delay and an ActionListener to the Timer constructor. Every tick (delay), the actionPerformed of the ActionListener will be called. That is where you will change the state of the car and repaint the main painting surface.

You can see an example of those above points in this answer

enter image description here

Community
  • 1
  • 1
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • Thanks! I'm checking the solution you gave me now.. I didn't know anything about JPanel till this project came up and I had to look it up and fumble with the code.. – KaeM Jul 24 '14 at 17:45
0

Why do you have method returning an integer in a class supposed to be used as an Object?

It seems you are doing this because you are used to C++, as a main method in Java does not return a value, but rather void. So it should be:

public static void main(String[] args) {
     //code here, don't return anything
}

I see you using it in your actual main class, Map, but I find it really unnecessary to do that.

Regardless, you shouldn't be having a main in your Car class.

In your overall code, you are not even calling for either car to move (which I presume is the Accelerate() method)

Have you tried calling Accelerate() for both Car instances?

Also, in your Accelerate() method, you are getting the Default Toolkit for no reason. You should remove that.

You are also returning an int in Accelerate but it will return the same position as before. Why? Timers are run on another thread. You are setting the cars position a second after, and then returning the position after scheduling the Task.

I wouldn't say it's a big deal as you are still setting the position, but I suggest making Accelerate return void rather than an integer.

Aside from that, you shouldn't be using Timers like this or using the JFrame paint function, but rather a JPanel to render all objects you want. Making each object render itself as a JPanel is not a good idea.

  • I'm still new to Java. Returning integer.. I guess you mean that car class right? Yeah.. That's wrong, thanks for pointing that out. Yes I am used to C++ as I had it in my first semester while Java was in second semester but the material wasn't as deep as C++.. So in short, other than Map (main) class, (The others are used the same way as car, as an object) I shouldn't put any main because the methods from the object class itself will be called in Map class, right?? I tried calling it but I called it wrongly I guess, I've edited the code.. I'm checking that accelerate part Oh and the.. – KaeM Jul 24 '14 at 17:51
  • toolkit thingy was because I saw a certain source code which seems to use it for timer tasking.. – KaeM Jul 24 '14 at 17:52
  • Yeah, you just have a "hanging" unused instance of Toolkit there and I don't see it being used. Also, all applications should have ONE Main class. This being because the Main is what is utilized to start up your application as when running your application, it runs the main method in your main class. So regardless, only one main class/method should be utilized in an application. – 0-4930-42390eo23o2e0-23oe0-23o Jul 24 '14 at 18:33