Learn how to create a Chrome Dinosaur Game using Python and Pygame with this beginner-friendly tutorial. Follow step-by-step instructions to build your game.
Table of Contents
- Setting Up Your Environment
- Importing Libraries and Initializing Pygame
- Defining Constants and Loading Assets
- Creating the Dinosaur Class
- Creating the Cloud Class
- Creating the Obstacle Classes
- Main Game Function
- Menu Function
- Running the Game
- Full Dinosaur Game Source Code
- Conclusion
The Chrome Dinosaur Game is a beloved pastime for many when the internet goes down. Recreating this game using Python and Pygame is a fantastic way to learn game development. This tutorial will guide you through the process step-by-step, making it accessible even for beginners. By the end of this guide, you will have a fully functional game that you can play and share with friends.
Setting Up Your Environment
Before diving into the code, you need to set up your development environment. Ensure you have Python installed on your computer. You can download it from the official Python website. Next, install Pygame, a library that makes it easy to create games using Python. You can install it using pip:
pip install pygame
Once you have Python and Pygame set up, you're ready to start coding.
Below is the complete code for our Chrome Dinosaur Game. We'll go through it step by step to understand how it works.
Importing Libraries and Initializing Pygame
First, we import the necessary libraries and initialize Pygame.
import pygame import random pygame.init()
Defining Constants and Loading Assets
Next, we define global constants for the screen dimensions and load the game assets such as images for the dinosaur, obstacles, clouds, and background. You can download the assets from the following GitHub repository.
# Global Constants
SCREEN_HEIGHT = 600
SCREEN_WIDTH = 1100
SCREEN = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
START = pygame.image.load("Assets\Dino\DinoStart.png")
RUNNING = [
pygame.image.load("Assets\Dino\DinoRun1.png"),
pygame.image.load("Assets\Dino\DinoRun2.png"),
]
JUMPING = pygame.image.load("Assets\Dino\DinoJump.png")
DUCKING = [
pygame.image.load("Assets\Dino\DinoDuck1.png"),
pygame.image.load("Assets\Dino\DinoDuck2.png"),
]
SMALL_CACTUS = [
pygame.image.load("Assets\Cactus\SmallCactus1.png"),
pygame.image.load("Assets\Cactus\SmallCactus2.png"),
pygame.image.load("Assets\Cactus\SmallCactus3.png"),
]
LARGE_CACTUS = [
pygame.image.load("Assets\Cactus\LargeCactus1.png"),
pygame.image.load("Assets\Cactus\LargeCactus2.png"),
pygame.image.load("Assets\Cactus\LargeCactus3.png"),
]
BIRD = [
pygame.image.load("Assets\Bird\Bird1.png"),
pygame.image.load("Assets\Bird\Bird2.png"),
]
CLOUD = pygame.image.load("Assets\Other\Cloud.png")
BG = pygame.image.load("Assets\Other\Track.png")
Creating the Dinosaur Class
The Dinosaur class handles the dinosaur's state, including running, ducking, and jumping.
class Dinosaur:
X_POS = 80
Y_POS = 310
Y_POS_DUCK = 340
JUMP_VEL = 8.5
def __init__(self):
# Get the images of the dinosaur's actions
self.duck_img = DUCKING
self.run_img = RUNNING
self.jump_img = JUMPING
# Set the state variables of the dinosaur
self.dino_duck = False
self.dino_run = True
self.dino_jump = False
self.step_index = 0
self.jump_vel = self.JUMP_VEL
self.image = self.run_img[0]
self.dino_rect = self.image.get_rect()
self.dino_rect.x = self.X_POS
self.dino_rect.y = self.Y_POS
def update(self, userInput):
if self.dino_duck:
self.duck()
if self.dino_run:
self.run()
if self.dino_jump:
self.jump()
if self.step_index >= 10:
self.step_index = 0
if userInput[pygame.K_UP] and not self.dino_jump:
self.dino_duck = False
self.dino_run = False
self.dino_jump = True
elif userInput[pygame.K_DOWN] and not self.dino_jump:
self.dino_duck = True
self.dino_run = False
self.dino_jump = False
elif not (userInput[pygame.K_DOWN] or self.dino_jump):
self.dino_duck = False
self.dino_run = True
self.dino_jump = False
def duck(self):
self.image = self.duck_img[self.step_index // 5]
self.dino_rect = self.image.get_rect()
self.dino_rect.x = self.X_POS
self.dino_rect.y = self.Y_POS_DUCK
self.step_index += 1
def run(self):
self.image = self.run_img[self.step_index // 5]
self.dino_rect = self.image.get_rect()
self.dino_rect.x = self.X_POS
self.dino_rect.y = self.Y_POS
self.step_index += 1
def jump(self):
self.image = self.jump_img
if self.dino_jump:
self.dino_rect.y -= self.jump_vel * 4
self.jump_vel -= 0.8
if self.jump_vel < -self.JUMP_VEL:
self.dino_jump = False
self.jump_vel = self.JUMP_VEL
def draw(self, SCREEN):
SCREEN.blit(self.image, (self.dino_rect.x, self.dino_rect.y))
Creating the Cloud Class
The Cloud class handles the clouds that move across the screen.
class Cloud:
def __init__(self):
self.x = SCREEN_WIDTH + random.randint(800, 1000)
self.y = random.randint(50, 100)
self.image = CLOUD
self.width = self.image.get_width()
def update(self):
self.x -= game_speed
if self.x < -self.width:
self.x = SCREEN_WIDTH + random.randint(2500, 3000)
self.y = random.randint(50, 100)
def draw(self, SCREEN):
SCREEN.blit(self.image, (self.x, self.y))
Creating the Obstacle Classes
The Obstacle class and its subclasses (SmallCactus, LargeCactus, and Bird) handle the obstacles that the dinosaur must avoid.
class Obstacle:
def __init__(self, image, type):
self.image = image
self.type = type
self.rect = self.image[self.type].get_rect()
self.rect.x = SCREEN_WIDTH
def update(self):
self.rect.x -= game_speed
if self.rect.x < -self.rect.width:
obstacles.pop()
def draw(self, SCREEN):
SCREEN.blit(self.image[self.type], self.rect)
class SmallCactus(Obstacle):
def __init__(self, image):
self.type = random.randint(0, 2)
super().__init__(image, self.type)
self.rect.y = 325
class LargeCactus(Obstacle):
def __init__(self, image):
self.type = random.randint(0, 2)
super().__init__(image, self.type)
self.rect.y = 300
class Bird(Obstacle):
def __init__(self, image):
self.type = 0
super().__init__(image, self.type)
self.rect.y = 250
self.index = 0
def draw(self, SCREEN):
if self.index >= 9:
self.index = 0
SCREEN.blit(self.image[self.index // 5], self.rect)
self.index += 1
Main Game Function
The main function handles the game loop, updating the game state, drawing the screen, and detecting collisions.
def main():
global game_speed, x_pos_bg, y_pos_bg, points, obstacles
run = True
clock = pygame.time.Clock()
player = Dinosaur()
cloud = Cloud()
game_speed = 14
x_pos_bg = 0
y_pos_bg = 380
points = 0
font = pygame.font.Font("freesansbold.ttf", 20)
obstacles = []
death_count = 0
def score():
global game_speed, points
points += 1
if points % 100 == 0:
game_speed += 1
text = font.render("Points: " + str(points), True, (0, 0, 0))
textRect = text.get_rect()
textRect.center = (1000, 40)
SCREEN.blit(text, textRect)
def background():
global x_pos_bg, y_pos_bg
image_width = BG.get_width()
SCREEN.blit(BG, (x_pos_bg, y_pos_bg))
SCREEN.blit(BG, (image_width + x_pos_bg, y_pos_bg))
if x_pos_bg <= -image_width:
SCREEN.blit(BG, (image_width + x_pos_bg, y_pos_bg))
x_pos_bg = 0
x_pos_bg -= game_speed
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
SCREEN.fill((255, 255, 255))
userInput = pygame.key.get_pressed()
player.draw(SCREEN)
player.update(userInput)
if len(obstacles) == 0:
if random.randint(0, 2) == 0:
obstacles.append(SmallCactus(SMALL_CACTUS))
elif random.randint(0, 2) == 1:
obstacles.append(LargeCactus(LARGE_CACTUS))
elif random.randint(0, 2) == 2:
obstacles.append(Bird(BIRD))
for obstacle in obstacles:
obstacle.draw(SCREEN)
obstacle.update()
if player.dino_rect.colliderect(obstacle.rect):
pygame.time.delay(1000)
death_count += 1
menu(death_count)
background()
cloud.draw(SCREEN)
cloud.update()
score()
clock.tick(30)
pygame.display.update()
Menu Function
The menu function handles the start and restart screens.
def menu(death_count):
global points
run = True
while run:
SCREEN.fill((255, 255, 255))
font = pygame.font.Font("freesansbold.ttf", 30)
if death_count == 0:
text = font.render("Press any Key to Start", True, (0, 0, 0))
elif death_count > 0:
text = font.render("Press any Key to Restart", True, (0, 0, 0))
score = font.render("Your Score: " + str(points), True, (0, 0, 0))
scoreRect = score.get_rect()
scoreRect.center = (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 + 50)
SCREEN.blit(score, scoreRect)
textRect = text.get_rect()
textRect.center = (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2)
SCREEN.blit(text, textRect)
SCREEN.blit(START, (SCREEN_WIDTH // 2 - 20, SCREEN_HEIGHT // 2 - 140))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
exit()
elif event.type == pygame.KEYDOWN:
main()
menu(death_count=0)
Running the Game
Save the code into a Python file (e.g., dino_game.py) and run it. Use the up arrow key to jump, the down arrow key to duck, and see how long you can survive the obstacles!
Full Dinosaur Game Source Code
import pygame
import random
pygame.init()
# Global Constants
SCREEN_HEIGHT = 600
SCREEN_WIDTH = 1100
SCREEN = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
START = pygame.image.load("Assets\Dino\DinoStart.png")
RUNNING = [
pygame.image.load("Assets\Dino\DinoRun1.png"),
pygame.image.load("Assets\Dino\DinoRun2.png"),
]
JUMPING = pygame.image.load("Assets\Dino\DinoJump.png")
DUCKING = [
pygame.image.load("Assets\Dino\DinoDuck1.png"),
pygame.image.load("Assets\Dino\DinoDuck2.png"),
]
SMALL_CACTUS = [
pygame.image.load("Assets\Cactus\SmallCactus1.png"),
pygame.image.load("Assets\Cactus\SmallCactus2.png"),
pygame.image.load("Assets\Cactus\SmallCactus3.png"),
]
LARGE_CACTUS = [
pygame.image.load("Assets\Cactus\LargeCactus1.png"),
pygame.image.load("Assets\Cactus\LargeCactus2.png"),
pygame.image.load("Assets\Cactus\LargeCactus3.png"),
]
BIRD = [
pygame.image.load("Assets\Bird\Bird1.png"),
pygame.image.load("Assets\Bird\Bird2.png"),
]
CLOUD = pygame.image.load("Assets\Other\Cloud.png")
BG = pygame.image.load("Assets\Other\Track.png")
class Dinosaur:
X_POS = 80
Y_POS = 310
Y_POS_DUCK = 340
JUMP_VEL = 8.5
def __init__(self):
# Get the images of the dinosaur's actions
self.duck_img = DUCKING
self.run_img = RUNNING
self.jump_img = JUMPING
# Set the state variables of the dinosaur
self.dino_duck = False
self.dino_run = True
self.dino_jump = False
self.step_index = 0
self.jump_vel = self.JUMP_VEL
self.image = self.run_img[0]
self.dino_rect = self.image.get_rect()
self.dino_rect.x = self.X_POS
self.dino_rect.y = self.Y_POS
def update(self, userInput):
if self.dino_duck:
self.duck()
if self.dino_run:
self.run()
if self.dino_jump:
self.jump()
if self.step_index >= 10:
self.step_index = 0
if userInput[pygame.K_UP] and not self.dino_jump:
self.dino_duck = False
self.dino_run = False
self.dino_jump = True
elif userInput[pygame.K_DOWN] and not self.dino_jump:
self.dino_duck = True
self.dino_run = False
self.dino_jump = False
elif not (userInput[pygame.K_DOWN] or self.dino_jump):
self.dino_duck = False
self.dino_run = True
self.dino_jump = False
def duck(self):
self.image = self.duck_img[self.step_index // 5]
self.dino_rect = self.image.get_rect()
self.dino_rect.x = self.X_POS
self.dino_rect.y = self.Y_POS_DUCK
self.step_index += 1
def run(self):
self.image = self.run_img[self.step_index // 5]
self.dino_rect = self.image.get_rect()
self.dino_rect.x = self.X_POS
self.dino_rect.y = self.Y_POS
self.step_index += 1
def jump(self):
self.image = self.jump_img
if self.dino_jump:
self.dino_rect.y -= self.jump_vel * 4
self.jump_vel -= 0.8
if self.jump_vel < -self.JUMP_VEL:
self.dino_jump = False
self.jump_vel = self.JUMP_VEL
def draw(self, SCREEN):
SCREEN.blit(self.image, (self.dino_rect.x, self.dino_rect.y))
class Cloud:
def __init__(self):
self.x = SCREEN_WIDTH + random.randint(800, 1000)
self.y = random.randint(50, 100)
self.image = CLOUD
self.width = self.image.get_width()
def update(self):
self.x -= game_speed
if self.x < -self.width:
self.x = SCREEN_WIDTH + random.randint(2500, 3000)
self.y = random.randint(50, 100)
def draw(self, SCREEN):
SCREEN.blit(self.image, (self.x, self.y))
class Obstacle:
def __init__(self, image, type):
self.image = image
self.type = type
self.rect = self.image[self.type].get_rect()
self.rect.x = SCREEN_WIDTH
def update(self):
self.rect.x -= game_speed
if self.rect.x < -self.rect.width:
obstacles.pop()
def draw(self, SCREEN):
SCREEN.blit(self.image[self.type], self.rect)
class SmallCactus(Obstacle):
def __init__(self, image):
self.type = random.randint(0, 2)
super().__init__(image, self.type)
self.rect.y = 325
class LargeCactus(Obstacle):
def __init__(self, image):
self.type = random.randint(0, 2)
super().__init__(image, self.type)
self.rect.y = 300
class Bird(Obstacle):
def __init__(self, image):
self.type = 0
super().__init__(image, self.type)
self.rect.y = 250
self.index = 0
def draw(self, SCREEN):
if self.index >= 9:
self.index = 0
SCREEN.blit(self.image[self.index // 5], self.rect)
self.index += 1
def main():
global game_speed, x_pos_bg, y_pos_bg, points, obstacles
run = True
clock = pygame.time.Clock()
player = Dinosaur()
cloud = Cloud()
game_speed = 14
x_pos_bg = 0
y_pos_bg = 380
points = 0
font = pygame.font.Font("freesansbold.ttf", 20)
obstacles = []
death_count = 0
def score():
global game_speed, points
points += 1
if points % 100 == 0:
game_speed += 1
text = font.render("Points: " + str(points), True, (0, 0, 0))
textRect = text.get_rect()
textRect.center = (1000, 40)
SCREEN.blit(text, textRect)
def background():
global x_pos_bg, y_pos_bg
image_width = BG.get_width()
SCREEN.blit(BG, (x_pos_bg, y_pos_bg))
SCREEN.blit(BG, (image_width + x_pos_bg, y_pos_bg))
if x_pos_bg <= -image_width:
SCREEN.blit(BG, (image_width + x_pos_bg, y_pos_bg))
x_pos_bg = 0
x_pos_bg -= game_speed
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
SCREEN.fill((255, 255, 255))
userInput = pygame.key.get_pressed()
player.draw(SCREEN)
player.update(userInput)
if len(obstacles) == 0:
if random.randint(0, 2) == 0:
obstacles.append(SmallCactus(SMALL_CACTUS))
elif random.randint(0, 2) == 1:
obstacles.append(LargeCactus(LARGE_CACTUS))
elif random.randint(0, 2) == 2:
obstacles.append(Bird(BIRD))
for obstacle in obstacles:
obstacle.draw(SCREEN)
obstacle.update()
if player.dino_rect.colliderect(obstacle.rect):
pygame.time.delay(1000)
death_count += 1
menu(death_count)
background()
cloud.draw(SCREEN)
cloud.update()
score()
clock.tick(30)
pygame.display.update()
def menu(death_count):
global points
run = True
while run:
SCREEN.fill((255, 255, 255))
font = pygame.font.Font("freesansbold.ttf", 30)
if death_count == 0:
text = font.render("Press any Key to Start", True, (0, 0, 0))
elif death_count > 0:
text = font.render("Press any Key to Restart", True, (0, 0, 0))
score = font.render("Your Score: " + str(points), True, (0, 0, 0))
scoreRect = score.get_rect()
scoreRect.center = (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 + 50)
SCREEN.blit(score, scoreRect)
textRect = text.get_rect()
textRect.center = (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2)
SCREEN.blit(text, textRect)
SCREEN.blit(START, (SCREEN_WIDTH // 2 - 20, SCREEN_HEIGHT // 2 - 140))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
exit()
elif event.type == pygame.KEYDOWN:
main()
menu(death_count=0)
Conclusion
Creating a Chrome Dinosaur Game using Python and Pygame is a rewarding project. It offers a hands-on way to learn game development principles while creating something fun. Follow this guide step-by-step, and you’ll have a functional game to play and share.
You can find the image assets used in this project here.
Special thanks to Atharvashirsh Tiwary for developing this project.
That’s a wrap!
I hope you enjoyed this article
Did you like it? Let me know in the comments below 🔥 and you can support me by buying me a coffee.
And don’t forget to sign up to our email newsletter so you can get useful content like this sent right to your inbox!
Thanks!
Faraz 😊

