Complete Python Code for a Simple Endless Runner Game Using Pygame
This article provides a full Python implementation of a simple endless runner game using Pygame, including definitions for game configuration, player character, obstacles, background, game loop logic, collision detection, scoring, and instructions for running the code, along with promotional links for further Python learning resources.
The article shares the complete source code for a simple endless‑runner style game built with Python and the Pygame library.
First, the required modules are imported.
<code>import pygame, sys
import random</code>Next, the game configuration variables are defined, such as window dimensions, score placeholders, font objects, and placeholders for images and objects.
<code>width = 1200 # window width
height = 508 # window height
size = width, height
score = None # score
myFont = myFont1 = None # fonts
surObject = None # obstacle image
surGameOver = None # game‑over image
bg = None # background object
role = None # player object
object = None # obstacle object
objectList = [] # list of obstacles
clock = None # game clock
gameState = None # 0 = playing, 1 = game over</code>A Role class represents the player character, storing its surface, position, size, animation frame, state (running, jumping, double‑jumping), gravity, and vertical velocity.
<code>class Role:
def __init__(self, surface=None, y=None):
self.surface = surface
self.y = y
self.w = surface.get_width() / 12
self.h = surface.get_height() / 2
self.currentFrame = -1
self.state = 0 # 0: run, 1: jump, 2: double jump
self.g = 1 # gravity
self.vy = 0
self.vy_start = -20
def getRect(self):
return (0, self.y + 12, self.w, self.h)</code>An Object class models obstacles, holding their image, position, size, and a random initial animation frame. It also provides a rectangle for collision detection and a simple collision method.
<code>class Object:
def __init__(self, surface, x=0, y=0):
self.surface = surface
self.x = x
self.y = y
self.w = surface.get_width()
self.h = surface.get_height()
self.currentFrame = random.randint(0, 6)
self.w = 100
self.h = 100
def getRect(self):
return (self.x, self.y, self.w, self.h)
def collision(self, rect1, rect2):
# simple AABB collision test
if (rect2[0] >= rect1[2] - 20) or (rect1[0] + 40 >= rect2[2]) or \
(rect1[1] + rect1[3] < rect2[1] + 20) or (rect2[1] + rect2[3] < rect1[1] + 20):
return False
return True</code>A Bg class handles the scrolling background.
<code>class Bg:
def __init__(self, surface):
self.surface = surface
self.dx = -10
self.w = surface.get_width()
self.rect = surface.get_rect()</code>The initGame function initializes all global objects, loads images, creates font objects, and sets the initial game state.
<code>def initGame():
global bg, role, clock, gameState, surObject, surGameOver, score, myFont, myFont1, objectList
score = 0
objectList = []
myFont = pygame.font.Font("./freesansbold.ttf", 32)
myFont1 = pygame.font.Font("./freesansbold.ttf", 64)
clock = pygame.time.Clock()
gameState = 0
surBg = pygame.image.load("image/bg.bmp").convert_alpha()
bg = Bg(surBg)
surGameOver = pygame.image.load("image/gameover.bmp").convert_alpha()
surRole = pygame.image.load("image/role.png").convert_alpha()
role = Role(surRole, 508 - 85)
surObject = pygame.image.load("image/object.png").convert_alpha()</code>The addObject function randomly creates new obstacles and appends them to objectList .
<code>def addObject():
global surObject, object, objectList
rate = 4
if not random.randint(0, 300) < rate:
return
y = random.choice([height-100, height-200, height-300, height-400])
object = Object(surObject, width + 40, y)
objectList.append(object)</code>The updateLogic function processes events, handles player jumps, updates background scrolling, moves the player, moves obstacles, checks for off‑screen obstacles, updates the score, and performs collision detection to end the game.
<code>def updateLogic():
global gameState, score
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
if gameState == 0 and event.key == pygame.K_SPACE:
if role.state == 0:
role.state = 1
role.vy = role.vy_start
elif role.state == 1:
role.state = 2
role.vy = role.vy_start
elif gameState == 1 and event.key == pygame.K_SPACE:
initGame()
if gameState == 0:
bg.dx += 10
if bg.dx == 1200:
bg.dx = 0
if role.state == 0:
role.currentFrame = (role.currentFrame + 1) % 12
else:
role.y += role.vy
role.vy += role.g
if role.y >= 508 - 85:
role.y = 508 - 85
role.state = 0
addObject()
for object in objectList:
object.x -= 10
if object.x + object.w <= 0:
objectList.remove(object)
score += 10
print("Removed a target")
if object.collision(role.getRect(), object.getRect()):
if object.currentFrame == 6:
objectList.remove(object)
score += 100
print("Collected a coin")
else:
gameState = 1
print("Collision occurred!")
</code>Finally, the article concludes with a note that this is the complete code for the "天天酷跑" game and invites readers to leave comments for any questions.
Promotional sections at the end provide QR‑code links to free Python courses and additional learning resources.
Python Programming Learning Circle
A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.