Top-down car simmulator

Hello,

I’m trying to write simple Top-down car simulator. Ofc i browse the forum and the internet before and there is massive amount of answers but… nothing works for me that why i created new topic.

Best related-topics:

My car is made up with 4 images(wheels) + 1 image(body). X,Y of images are in the relation to an imaginary center of Car (200,200)

Car class constructor:

	public Car()
	{	
		MiddlePoint.x = 200;
		MiddlePoint.y = 200;
			
	    LwheelU = new Wheels(MiddlePoint.x - 60.5 ,MiddlePoint.y -85);
	    LwheelD = new Wheels(MiddlePoint.x - 60.5, MiddlePoint.y + 65);    
	    RwheelU = new Wheels(MiddlePoint.x + 36.5, MiddlePoint.y -85);
	    RwheelD = new Wheels(MiddlePoint.x + 36.5,MiddlePoint.y + 65);    
	    body = new Body(MiddlePoint.x - 36.5, (MiddlePoint.y - (251/1.9))); 
	}

Global game parameters: [#EDIT 1.0]

	//this variable will decide if the specified car is controlled by a human player or by the computer (in Part II of this tutorial you will learn how to add opponents and this variable will come in handy)
	public	double acceleration = 0.4; 
	//the acceleration variable will add to the speed variable on every enterFrame event (in this case 24 times per second); a higher value translates in a faster acceleration of the car
	public double speedDecay = 0.96; 
	//when the car is not accelerated (the UP Key is released), the car will have to slow down smoothly; the speed will multiply with this value (less than 1); the lower this value is, the faster the car will slow down
	public double rotationStep = 1;
	//this is the number of degrees that will increase or decrease the car's rotation (angle) when the left or right keys are pressed
	public double maxSpeed = 3;
	//this is the speed limit on our track; increase it if you want the car to go faster
	public double backSpeed = 1;
	//this is the speed limit when going backwards
	public double speedx = 0, speedy = 0;
	public double rotation = 0;
    //**********************

Move method [#Edit 1.0]

if(speed < 0.3) 
			speed *= 0.70;  //Friction
		else
			speed = 0;
		  
		  
		if (up && speed < maxSpeed)
		{
			speed -=acceleration;
		}
 		if (down)
		{
			speed += backSpeed;
		}		
		if (left )
		{
			rotation -= rotationStep * (speed/maxSpeed);
		}
		if (right )
		{
			rotation += rotationStep * (speed/maxSpeed);
		}
			
		speedx = Math.sin(Math.toRadians(rotation)) * speed;
		speedy = Math.cos(Math.toRadians(rotation)) * speed;
		
		MiddlePoint.x += speedx;
		MiddlePoint.y += speedy;
			
		carAngle = Math.toRadians(rotation);

I’m drawing all elements like that:


		 AffineTransform at;
		 at = new AffineTransform();	
		 at.translate(MiddlePoint.x - 60.5 ,MiddlePoint.y -85);
		 at.rotate(Math.toRadians(carAngle), MiddlePoint.x, Sr_PKT.y);
		 g2d.drawImage(LwheelU.getImage(),at,null);

I’m using timer to refresh actions on board


    public void paint(Graphics g) 
    {
        super.paint(g);
        Car.paint(g);
     
        Toolkit.getDefaultToolkit().sync();
        g.dispose();
    }

    public void actionPerformed(ActionEvent e) 
    {
    	Car.move();
        repaint();  
    }

At the moment car is moving UP/DOWN but when it comes to UP/DOWN + Right/left it is starting to act very weird. The huge problem is also that elements like wheels/body are ,not connecteted"
look:

Actually i just want the car to move correctly - i dont need any kind of colission , friction.

Thanks in advance for any kind of help

Kamil,

##################################

EDIT 1.0

  • Changed keyboard handling to set Flags TRUE (PRESSED) and FALSE (RELEASED)
  • update move function:
    [list]
    [li]Whole x,y changing is now in move function
  • Go UP/DOWN works fine (Frictions stops the car)
  • LEFT/RIGHT doesn’t work correct (or it does but my drawing function is bugged)

[/li]
[/list]

Since you haven’t gotten any replies yet, I’ll go ahead and reply despite the fact that I haven’t used the API you’re using (Java2D)? So, no guarantees that any of this will be helpful.

First, I know switching frameworks can be a pain, but if you’re just using Java2D out of habit or inertia, now might be a good time to switch to something like LibGDX or LWJGL that might be better suited for the kind of thing you’re doing.

One thing that’s always a red flag for me is when quads are treated as originating at a corner rather than at the center, as this (IMO) makes it difficult to reason about the effects of transforms, especially hierarchical transforms as you have here. If Java2D has support for anchor points, you should probably take advantage of it. If not, that might be a good motivator for switching frameworks.

In any case, I think things would be easier if you could set things up so that quads/sprites have their origins at the center rather than at a corner (as appears to be the case in your code - forgive me if I’m incorrect about that). This would get rid of the ‘middle point’ stuff and make things a lot simpler in general. Note that you can do this with Java2D, I think - it just requires jumping through some hoops that you wouldn’t have to otherwise.

What you’re looking for is a simple (in principle, at least) hierarchal transform (apologies if what I’m saying here is stuff you already know). This involves concatenating transforms in sequence to yield transforms for the various nodes in the hierarchy. Your hierarchy consists of a root (the body) and four children (the wheels). The body is rendered using the body transform, of course. The transform for any given wheel (assuming column-vector notation) is B*Wi, where B is the body transform and Wi is the transform for wheel ‘i’. The transform for a wheel should include its local rotation and its offset relative to the body. Again, this is all easiest if quads are anchored at their center (otherwise, some additional steps may be involved).

Anyway, maybe you already know all this and are just having trouble getting the implementation correct. If so, maybe you could post some more code showing what’s happening in context.

Hey,

I’m using this libraries:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.geom.AffineTransform;
  • Yes i’m doing that the Middle_point(SR_PKT) is my center of the car all car elements are in relation to this center so i have only to move this point to move whole Car otherwise i would have to move every single element separate.

I manage to remove BUG with wheels. The problem was that i was first translating points and then rotate them when the correct way is to rotate and then transform.

		 at = new AffineTransform();	
		 at.rotate(carAngle, Sr_PKT.x, Sr_PKT.y);
		 at.translate(Sr_PKT.x - 60.5 ,Sr_PKT.y -85);
 at.rotate(Math.toRadians(carAngle2), 24/2, 55/2);
		 g2d.drawImage(LwheelU.getImage(),at,null);

2nd rotate with carAngle2 is used to get realistic look of moving front wheels

This is my brand new move function:

	public void move() 
	{	  
		if (up && speed < maxSpeed)
			speed +=acceleration;

 		if (down && speed > -maxSpeed)
			speed += -acceleration;
	
		if (left )
			rotation -= rotationStep * (speed/maxSpeed);
		
		if (left)
			carAngle2 -= 1;
		
		if (right)
			rotation += rotationStep * (speed/maxSpeed);
		
		if (right)
			carAngle2 +=1;
		
		if (carAngle2 > 35)
			carAngle2 = 35;
		if (carAngle2 < -35)
			carAngle2 = -35;
		
			speedx = Math.sin(rotation * (Math.PI/180)) * speed;
			speedy = Math.cos(rotation *(Math.PI/180)) * speed *  -1 ;
		
		Sr_PKT.x += speedx;
		Sr_PKT.y += speedy;
			
		carAngle = rotation * (Math.PI/180);
	}	

Everything works good now. The only problem is i dont have friction so if i stop holding UP key car wont stop moving
#EDIT

I have done friction right now so everything works good i guess you can close the topic now :slight_smile:

		if (speed > 0.3 || speed < -0.3)
			speed *= speedDecay;
		else 
			speed = 0;

Glad you got the transform problem sorted (sorry if you already knew everything I mentioned in my previous post - I wasn’t sure at what level the problem was, but it sounds like it was a simple order-of-operations problem).