Simple Car Race Game in Java

Car Race Game in Java

When it comes to building gaming applications, we always think of racing games as we loved playing these types of games in our childhood. So today in this article we will develop a Car Race Game in Java with Swing.

This game needs no explanation, but still has a bit of context for the game. The player’s car needs to race with the opponent’s cars without hitting any one of them and maintaining a high speed.

Project Overview: Car Race Game in Java

Project Name:Car Race Game in Java
Abstract:It’s a GUI-based project used with the swing library to organize all the elements that work under the Car Race Game.
Language Used:Java
IDE:VS Code
Java version (Recommended):Java SE 18.0. 2.1
Database:None
Type:Desktop Application
Recommended for:Beginners of Java
Time to build:1-2 hours

What will you learn? 

  • Building the logic of the game with the help of conditionals and loops
  • Learn the OOPs paradigm with the help of classes, objects, and inheritance
  • Creating an attractive User Interface with the help of Java Swing and Java AWT

Features

  • The player will be able to move the car left and right by pressing the left and right key
  • The Score and Speed of the car are updated continuously as the car moves ahead
  • If the car hits another car then the game is over and the player can restart the game by pressing Enter Key

Complete Code for Car Race Game in Java

First of all download the images for the project from here. Now, create a folder for the project and add all the images to this folder. Create a file named CarRace.java and copy the below line of code in that. Comments are provided for explanation.

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.Timer;

// this class is used to build the graphics and the game logic
class CarGame extends JFrame implements KeyListener,ActionListener
{

	private int xpos=300; // x position of the car 
	private int ypos=700; // y position of the car
	private ImageIcon car; // car image 
	private Timer timer; // timer to update the screen
	Random random=new Random(); // random number generator
	
	private int num1=400,num2=0,num3=0; // x position of the obstacles
	private int tree1ypos=400,tree2ypos=-200,tree3ypos=-500,tree4ypos=100,tree5ypos=-300,tree6ypos=500; // y position of the obstacles 
	private int roadmove=0; // y position of the road
	private int carxpos[]={100,200,300,400,500}; // x position of the car
	private int carypos[]= {-240,-480,-720,-960,-1200}; // y position of the car
	private int cxpos1=0,cxpos2=2,cxpos3=4; // x position of the car
	private int cypos1=random.nextInt(5),cypos2=random.nextInt(5),cypos3=random.nextInt(5); // y position of the car
	int y1pos=carypos[cypos1],y2pos=carypos[cypos2],y3pos=carypos[cypos3]; // y position of the car
	private ImageIcon car1,car2,car3; // car image
	private int score=0,delay=100,speed=90; // score,delay and speed of the game
	private ImageIcon tree1,tree2,tree3; // tree image
	private boolean rightrotate=false,gameover=false,paint=false; // boolean variables to control the game logic and the graphics
	
	// constructor to initialize the game
	public CarGame(String title)
	{
		super(title); // call the constructor of the parent class JFrame
		setBounds(300,10,700,700); // set the position and size of the frame
		setVisible(true); // make the frame visible
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // close the frame when the close button is clicked
		setLayout(null); // set the layout of the frame to null
		addKeyListener(this); // add the key listener to the frame
		setFocusable(true); // set the focus to the frame
		setResizable(false); // set the frame to be non resizable
		
	}

	// this method is used to paint the graphics on the screen 
	public void paint(Graphics g)
	{
		g.setColor(new Color(0X82CD47)); // set the color of the grass
		g.fillRect(0, 0, 700, 700);  // draw the grass
		g.setColor(new Color(0X9F8772)); // set the color of the road
		g.fillRect(90,0,10,700); // draw the road
		g.fillRect(600, 0, 10, 700); 
		g.fillRect(100, 0, 500, 700);
		
	// draw the road lines 
	if(roadmove==0)
	{
		for(int i=0; i<=700; i+=100) 
		{ 	// draw the road lines
			g.setColor(Color.white);
			g.fillRect(350, i,10, 70); // 
	
		}
		roadmove=1; // set the roadmove to 1
	}
	else if(roadmove==1)
	{ // draw the road lines again for the next frame
		for(int i=50; i<=700; i+=100)
		{
			g.setColor(Color.white);
			g.fillRect(350, i,10, 70);
		}
		roadmove=0; // set the roadmove to 0
	}
	
	try {
		tree1=new ImageIcon(ImageIO.read(getClass().getResource("tree.png"))); // load the tree image
	} catch (IOException e) {
		e.printStackTrace();
	}
	
	try {
		tree2=new ImageIcon(ImageIO.read(getClass().getResource("tree.png"))); // load the tree image
	} catch (IOException e) {
		e.printStackTrace();
	}

	try {
		tree3=new ImageIcon(ImageIO.read(getClass().getResource("tree.png"))); // load the tree image
	} catch (IOException e) {
		e.printStackTrace();
	}

	tree1.paintIcon(this, g, 0, tree1ypos); // draw the tree image on the screen
	num1=random.nextInt(500); // generate a random number
	tree1ypos+=50; // increment the y position of the tree
	
	tree2.paintIcon(this, g, 0,tree2ypos ); // draw the tree image on the screen
	tree2ypos+=50; // increment the y position of the tree
	
	tree3.paintIcon(this,g,0,tree3ypos); // draw the tree image on the screen
	tree3ypos+=50; // increment the y position of the tree
	tree1.paintIcon(this,g,600,tree4ypos);
	tree4ypos+=50;
	tree3.paintIcon(this, g,600,tree5ypos);
	tree5ypos+=50;
	tree2.paintIcon(this, g,600,tree6ypos);
	tree6ypos+=50;
	
		
	if(tree1ypos>700)
	{ // if the tree goes out of the screen then reset the tree
		num1=random.nextInt(500); // generate a random number
		tree1ypos=-num1; // reset the y position of the tree
	}
	if(tree2ypos>700)
	{ 
		num1=random.nextInt(500);
		tree2ypos=-num1;
	}
	if(tree3ypos>700)
	{
		num1=random.nextInt(500);
		tree3ypos=-num1;
	}
	if(tree4ypos>700)
	{ // if the tree goes out of the screen then reset the tree
		num1=random.nextInt(500);
		tree4ypos=-num1;
	}
	if(tree5ypos>700)
	{
		num1=random.nextInt(500);
		tree5ypos=-num1;
	}
	if(tree6ypos>700)
	{ // if the tree goes out of the screen then reset the tree
		num1=random.nextInt(500);
		tree6ypos=-num1;
	}
	
	
		// load image for car
		try {
			car=new ImageIcon(ImageIO.read(getClass().getResource("gamecar3.png"))); // load the car image 
		} catch (IOException e) {
			e.printStackTrace();
		}
	
		// car=new ImageIcon("gamecar1.png");
		car.paintIcon(this,g,xpos,ypos); // draw the car image on the screen
		
		ypos-=40;
		if(ypos<500)
		{
		ypos=500;	
		}
		
		// load the opponent image for car
		try {
			car1=new ImageIcon(ImageIO.read(getClass().getResource("gamecar1.png")));
		} catch (IOException e) {
				e.printStackTrace();
		}
		// load the opponent image for car
		try {
			car2=new ImageIcon(ImageIO.read(getClass().getResource("gamecar2.png")));
		} catch (IOException e) {
				e.printStackTrace();
		}
		// load the opponent image for car	
		try {
			car3=new ImageIcon(ImageIO.read(getClass().getResource("gamecar4.png")));
		} catch (IOException e) {
				e.printStackTrace();
		}
		
		car1.paintIcon(this, g, carxpos[cxpos1], y1pos); // draw the opponent car image on the screen
		car2.paintIcon(this, g, carxpos[cxpos2], y2pos); 
		car3.paintIcon(this, g, carxpos[cxpos3], y3pos);
		y1pos+=50; // increment the y position of the opponent car
		y2pos+=50;
		y3pos+=50;
		if(y1pos>700)
		{ // if the opponent car goes out of the screen then reset the opponent car
			cxpos1=random.nextInt(5); // generate a random number
			cypos1=random.nextInt(5); 	
			y1pos=carypos[cypos1]; // reset the y position of the opponent car
			
		}
		if(y2pos>700)
		{ // if the opponent car goes out of the screen then reset the opponent car
			cxpos2++;
			if(cxpos2>4)
			{ 
				cxpos2=0; 
			}
			
			cxpos2=random.nextInt(5);
			cypos2=random.nextInt(5);
			y2pos=carypos[cypos2];
			
		}
		if(y3pos>700)
		{
			cxpos3++;
			if(cxpos3>4)
			{
				cxpos3=0;
			}
			cxpos3=random.nextInt(5);
			cypos3=random.nextInt(5);
			y3pos=carypos[cypos3];
		}
	
		if(cxpos1==cxpos2 && cypos1>-100 && cypos2>-100)
		{ 
			cxpos1-=1;
			if(cxpos1<0)
			{
				cxpos1+=2;
			}
		}
		if(cxpos1==cxpos3&& cypos1>-100 && cypos3>-100)
		{
			cxpos3-=1;
			if(cxpos3<0)
			{
				cxpos3+=2;
			}
		}
		if(cxpos2==cxpos3&& cypos3>-100 && cypos2>-100)
		{
			cxpos2-=1;
			if(cxpos2<0)
			{
				cxpos2+=2;
			}
		}
		if(cxpos1<2 && cxpos2<2 && cxpos3<2)
		{
			if(cxpos1==0 && cxpos2==0 && cxpos3==1)
			{
				cxpos3++;
				cxpos2++;
			}
			else if(cxpos1==0 && cxpos2==1 && cxpos3==0)
			{
				cxpos3++;
				cxpos2++;
			}
			else if(cxpos1==1 && cxpos2==0 && cxpos3==0)
			{
				cxpos1++;
				cxpos2++;
			}
		}
		
		// if the opponent car hits the player car then reset the game
		if(y1pos<ypos && y1pos+175>ypos && carxpos[cxpos1]==xpos)
		{ 
		gameover=true;	
		}
		if(y2pos<ypos && y2pos+175>ypos && carxpos[cxpos2]==xpos)
		{ 
		gameover=true;	
		}
		if(y3pos<ypos  && y3pos+175>ypos && carxpos[cxpos3]==xpos)
		{
		gameover=true;	
		}
		if(ypos<y1pos && ypos+175>y1pos && carxpos[cxpos1]==xpos)
		{
		gameover=true;	
		}
		if(ypos<y2pos && ypos+175>y2pos && carxpos[cxpos2]==xpos)
		{
		gameover=true;	
		}
		if(ypos<y3pos  && ypos+175>y3pos && carxpos[cxpos3]==xpos)
		{
		gameover=true;	
		}

		//score 
		g.setColor(Color.red);
		g.fillRect(120,35,220,50);
		g.setColor(Color.black);
		g.fillRect(125,40, 210, 40);
		g.setColor(Color.red);
		g.fillRect(385,35,180,50);
		g.setColor(Color.black);
		g.fillRect(390,40, 170, 40);
		g.setColor(Color.white);
		g.setFont(new Font("MV Boli",Font.BOLD,30));
		g.drawString("Score : "+score, 130, 67);
		g.drawString(speed+" Km/h", 400, 67);
		score++; // increment the score
		speed++; // increment the speed
		if(speed>140)
		{ // if the speed is greater than 140 then reset the speed
			speed=240-delay; 
		
		}
		if(score%50==0)
		{ // if the score is divisible by 50 then increase the delay
			delay-=10;
			if(delay<60)
			{
				delay=60; // set the delay to 60
			}
		}
		//delay 
		try
		{
			
			TimeUnit.MILLISECONDS.sleep(delay); // delay the game
		} 
		catch (InterruptedException e) {
			e.printStackTrace();
		}
		if(y1pos<ypos && y1pos+175>ypos && carxpos[cxpos1]==xpos)
		{
		gameover=true;	
		}
		if(y2pos<ypos && y2pos+175>ypos && carxpos[cxpos2]==xpos)
			
		{
		gameover=true;	
		}
		if(y3pos<ypos  && y3pos+175>ypos && carxpos[cxpos3]==xpos)
		{
		gameover=true;	
		}
		if(gameover)
		{
		g.setColor(Color.gray);
		g.fillRect(120, 210, 460, 200);	
		g.setColor(Color.DARK_GRAY);
		g.fillRect(130, 220, 440, 180);
		g.setFont(new Font("MV Boli",Font.BOLD,50));
		g.setColor(Color.red);
		g.drawString("Game Over !",210, 270);
		g.setColor(Color.white);
		g.setFont(new Font("MV Boli",Font.BOLD,30));
		g.drawString("Press Enter to Restart", 190, 340);
		if(!paint)
		{
			repaint();
			paint=true;
		}
		}
		else
		{
		repaint();
		}
	}
		
	public static void main(String args[])
	{
		CarGame c=new CarGame("Car Racing Game");
	}
	@Override
	public void keyPressed(KeyEvent e) {
		if(e.getKeyCode()==KeyEvent.VK_LEFT && !gameover)
		{ // if the left key is pressed then move the car to the left
			xpos-=100;
			if(xpos<100)
			{
				xpos=100; // set the car to the left most position
			}
			
			
		}
		if(e.getKeyCode()==KeyEvent.VK_RIGHT&&!gameover)
		{ 	// if the right key is pressed then move the car to the right
			xpos+=100;
			if(xpos>500)
			{
				xpos=500; // if the car is at the right most position then don't move it
			}
		}
		if(e.getKeyCode()==KeyEvent.VK_ENTER && gameover)
		{ // if the game is over and the enter key is pressed then restart the game
			gameover=false; 	
			paint=false;
			cxpos1=0;
			cxpos2=2;
			cxpos3=4;
			cypos1=random.nextInt(5); // randomize the position of the opponent cars
			cypos2=random.nextInt(5); 
			cypos3=random.nextInt(5);
			y1pos=carypos[cypos1]; // set the position of the opponent cars
			y2pos=carypos[cypos2];
			y3pos=carypos[cypos3];
			speed=90; // set the speed to 90
			score=0; // set the score to 0
			delay=100; // set the delay to 100
			xpos=300; // set the position of the player car to the center
			ypos=700;	 // set the position of the player car to the bottom
		}
	}
	@Override
	public void keyReleased(KeyEvent arg0) {
		// TODO Auto-generated method stub
	}
	@Override
	public void keyTyped(KeyEvent e) {
		if(e.getKeyChar()=='a'&&!gameover)
		{ // if the key pressed is 'a' then move the car left
			xpos-=100; // decrement the xpos by 100
			
		}
		if(e.getKeyChar()=='s'&&!gameover)
		{ // if the key pressed is 's' then move the car right
			xpos+=100; // increment the xpos by 100
		}
		
		repaint();
		
	}
	@Override
	public void actionPerformed(ActionEvent arg0) {}
}

Output for Car Race Game in Java:

Image Output:

output for Car Race Game in Java

Video Output:

Conclusion

Hope you enjoyed building the Car Race Game in Java as much as I enjoyed creating it for you!! We learned how to deal with collisions between different objects and re-rendering the object as they go out of view. You can try adding more functionalities like creating more obstacles in the way or to increase the difficulty of the game you can try increasing the speed of the car after each level.

Thank you for visiting our website.


Also Read:

Share:

Author: Ayush Purawr