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 😊