The simplistic yet addictive gameplay of endless runner games has made them a mainstay in the gaming industry. Here we will have a look at the Python and Pygame libraries to see how you can make your very own Dino Run, an endless runner game. This game takes its cues from the original Chrome Dino, but it has its own special touches that set it apart.
Getting Started
To build Dino Run, you’ll need:
- Python: Ensure Python is installed (preferably version 3.x).
- Pygame Library: Install it using the command:
pip install pygame
. - Assets: You’ll need images, sounds, and sprite sheets for the following:
- Dinosaur
- Obstacles
- Clouds
- Ground
The following structure should be created in a project directory called Google Dino Run. You may find the necessary materials on websites like OpenGameArt.org or Kenney.nl, which offer free game assets, or you can make them yourself using programs like Piskel, GIMP, or Adobe Photoshop. The dinosaur, its environment, and any obstacles should all have sprites in these assets, along with sound effects for things like impacts and hopping.
DinoRun/ ├── assets/ │ ├── dino.png │ ├── dino_ducking.png │ ├── ground.png │ ├── cloud.png │ ├── cacti-small.png │ ├── ptera.png │ ├── numbers.png │ ├── replay_button.png │ ├── game_over.png │ ├── logo.png │ ├── ai_apps_jump.wav │ ├── ai_apps_die.wav │ └── ai_apps_checkPoint.wav ├── dino_run.py
Game Features
- Endless Gameplay: The game loops indefinitely until the player loses.
- Dynamic Obstacles: Includes cacti, flying Pteranodons (Pteras), and moving clouds.
- Speed Increase: The difficulty ramps up as the player’s score increases.
- High Score Tracking: Keeps track of the best score during the session.
- Sound Effects: Adds immersive audio for jumping, dying, and reaching milestones.
- Intro Screen: Displays a blinking dino before the game begins.
Setting Up the Project
Before we dive into the code, let’s set up our environment:
- Install Pygame: First, make sure you have Python and Pygame installed. You can install Pygame by running:
pip install pygame
- Assets: Download or create the necessary images and sounds for the game. You’ll need:
- dino.png: The dinosaur sprite.
- dino_ducking.png: The dinosaur sprite when it ducks.
- cacti-small.png: Different cacti images for obstacles.
- ptera.png: The pterodactyl sprite.
- ground.png: The ground sprite.
- cloud.png: Cloud images for background decoration.
- Sound effects for jump, die, and checkpoint.
2. Code Walkthrough
Let’s break down the main sections of the code:
Game Initialization
We start by initializing Pygame and setting up the main game loop:
pygame.init()
scr_size = (width, height) = (600, 150)
FPS = 60
screen = pygame.display.set_mode(scr_size)
clock = pygame.time.Clock()
pygame.display.set_caption("Dino Run")
Here, we initialize the game window, set the size of the screen, and set the FPS (frames per second) for the game loop.
Game Assets Loading
We use helper functions to load images and sprite sheets. The load_image()
function loads individual images, while load_sprite_sheet()
loads sprite sheets, which contain multiple frames for character animations (like the dinosaur’s walking or ducking).
def load_image(name, sizex=-1, sizey=-1, colorkey=None):
fullname = os.path.join('assets', name)
image = pygame.image.load(fullname)
image = image.convert()
if colorkey is not None:
if colorkey is -1:
colorkey = image.get_at((0, 0))
image.set_colorkey(colorkey, RLEACCEL)
if sizex != -1 or sizey != -1:
image = pygame.transform.scale(image, (sizex, sizey))
return image, image.get_rect()
This function ensures the image is scaled properly and handles transparency (color keying) for smoother animations.
Main Game Logic
The Dino
class represents the main character, the dinosaur. It manages animations, jumping, ducking, and detecting collisions. The dinosaur’s movement is controlled using the self.movement
attribute, which updates the position of the sprite in each frame.
class Dino():
def __init__(self, sizex=-1, sizey=-1):
self.images, self.rect = load_sprite_sheet('dino.png', 5, 1, sizex, sizey, -1)
self.rect.bottom = int(0.98 * height)
self.rect.left = width / 15
self.image = self.images[0]
self.index = 0
self.counter = 0
self.score = 0
self.isJumping = False
self.isDead = False
self.isDucking = False
self.isBlinking = False
self.movement = [0, 0]
self.jumpSpeed = 11.5
3. Obstacle Creation
We have two types of obstacles in the game: cacti and pterodactyls. The Cactus
and Ptera
classes are responsible for creating these obstacles and moving them towards the dinosaur. When the dinosaur collides with an obstacle, the game ends.
class Cactus(pygame.sprite.Sprite):
def __init__(self, speed=5, sizex=-1, sizey=-1):
pygame.sprite.Sprite.__init__(self, self.containers)
self.images, self.rect = load_sprite_sheet('cacti-small.png', 3, 1, sizex, sizey, -1)
self.rect.bottom = int(0.98 * height)
self.rect.left = width + self.rect.width
self.image = self.images[random.randrange(0, 3)]
self.movement = [-1 * speed, 0]
4. Game Logic and Events
The game loop is where the action happens. We handle events like key presses (for jumping and ducking), update the position of obstacles and the dinosaur, and check for collisions.
while not gameQuit:
while startMenu:
pass
while not gameOver:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameQuit = True
gameOver = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
if playerDino.rect.bottom == int(0.98 * height):
playerDino.isJumping = True
playerDino.movement[1] = -1 * playerDino.jumpSpeed
Key Presses: pygame.K_SPACE
for jumping and pygame.K_DOWN
for ducking. Collision Detection: We use pygame.sprite.collide_mask()
to detect if the dinosaur collides with an obstacle.
5. Game Over and Restart
When the dinosaur dies, the gameOver flag is set to True, and the game over screen is displayed. The player can restart the game by pressing the space bar or return to the main menu.
def disp_gameOver_msg(retbutton_image, gameover_image):
retbutton_rect = retbutton_image.get_rect()
retbutton_rect.centerx = width / 2
retbutton_rect.top = height * 0.52
gameover_rect = gameover_image.get_rect()
gameover_rect.centerx = width / 2
gameover_rect.centery = height * 0.35
screen.blit(retbutton_image, retbutton_rect)
screen.blit(gameover_image, gameover_rect)
6. Running the Game
To run the game, simply call the main()
function:
def main():
isGameQuit = introscreen()
if not isGameQuit:
gameplay()
This function starts by displaying the intro screen and then moves on to the gameplay loop.
Conclusion
If you are interested in learning the basics of game programming with Pygame, Dino Run is a great project to work on. Enhancements such as power-ups, different difficulty settings, and a multiplayer mode are all within the game’s reach. Jump into the coding, try different things, and enjoy making your own infinite runner!