Complete Python Pygame Code for a Side‑Scrolling Runner Game
This article presents a full Python pygame implementation of a side‑scrolling runner game, detailing imports, configuration, class definitions for the player, obstacles and background, and the main game loop with input handling, collision detection, scoring and restart logic.
The article provides a complete Python pygame implementation of a side‑scrolling runner game, showing step‑by‑step code for imports, configuration, game objects, and the main loop.
import pygame, sys<br/>import random
Game configuration variables such as window size, score, fonts, and placeholders for objects are defined.
width = 1200 #窗口宽度<br/>height = 508 #窗口高度<br/>size = width, height<br/>score = None<br/>myFont = myFont1 = None<br/>surObject = None<br/>surGameOver = None<br/>bg = None<br/>role = None<br/>object = None<br/>objectList = []<br/>clock = None<br/>gameState = None
The Role class represents the player character, storing its surface, position, size, animation frame, state (running, jumping, double‑jumping), gravity, and vertical velocity.
class Role:<br/> def __init__(self, surface=None, y=None):<br/> self.surface = surface<br/> self.y = y<br/> self.w = (surface.get_width())/12<br/> self.h = surface.get_height()/2<br/> self.currentFrame = -1<br/> self.state = 0 # 0: running, 1: jump, 2: double jump<br/> self.g = 1<br/> self.vy = 0<br/> self.vy_start = -20<br/> def getRect(self):<br/> return (0, self.y+12, self.w, self.h)
The Object class models obstacles, loading their image, randomizing an initial frame, and providing a simple rectangular collision check.
class Object:<br/> def __init__(self, surface, x=0, y=0):<br/> self.surface = surface<br/> self.x = x<br/> self.y = y<br/> self.w = surface.get_width()<br/> self.h = surface.get_height()<br/> self.currentFrame = random.randint(0,6)<br/> self.w = 100<br/> self.h = 100<br/> def getRect(self):<br/> return (self.x, self.y, self.w, self.h)<br/> def collision(self, rect1, rect2):<br/> 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):<br/> return False<br/> return True
The Bg class handles the scrolling background, and initGame() loads assets, creates objects, and initializes the game state.
class Bg:<br/> def __init__(self, surface):<br/> self.surface = surface<br/> self.dx = -10<br/> self.w = surface.get_width()<br/> self.rect = surface.get_rect()<br/><br/>def initGame():<br/> global bg, role, clock, gameState, surObject, surGameOver, score, myFont, myFont1, objectList<br/> score = 0<br/> objectList = []<br/> myFont = pygame.font.Font("./freesansbold.ttf", 32)<br/> myFont1 = pygame.font.Font("./freesansbold.ttf", 64)<br/> clock = pygame.time.Clock()<br/> gameState = 0<br/> surBg = pygame.image.load("image/bg.bmp").convert_alpha()<br/> bg = Bg(surBg)<br/> surGameOver = pygame.image.load("image/gameover.bmp").convert_alpha()<br/> surRole = pygame.image.load("image/role.png").convert_alpha()<br/> role = Role(surRole, 508-85)<br/> surObject = pygame.image.load("image/object.png").convert_alpha()
Helper functions addObject() and updateLogic() manage obstacle generation, background scrolling, player input (space bar for jump and restart), character physics, obstacle movement, scoring, and collision outcomes, switching to a game‑over state when needed.
def addObject():<br/> global surObject, object, objectList<br/> rate = 4<br/> if not random.randint(0,300) < rate:<br/> return<br/> y = random.choice([height-100, height-200, height-300, height-400])<br/> object = Object(surObject, width+40, y)<br/> objectList.append(object)<br/><br/>def updateLogic():<br/> global gameState, score<br/> for event in pygame.event.get():<br/> if event.type == pygame.QUIT:<br/> sys.exit()<br/> elif event.type == pygame.KEYDOWN:<br/> if gameState == 0 and event.key == pygame.K_SPACE:<br/> if role.state == 0:<br/> role.state = 1<br/> role.vy = role.vy_start<br/> elif role.state == 1:<br/> role.state = 2<br/> role.vy = role.vy_start<br/> elif gameState == 1 and event.key == pygame.K_SPACE:<br/> initGame()<br/> if gameState == 0:<br/> bg.dx += 10<br/> if bg.dx == 1200:<br/> bg.dx = 0<br/> if role.state == 0:<br/> role.currentFrame = (role.currentFrame + 1) % 12<br/> else:<br/> role.y += role.vy<br/> role.vy += role.g<br/> if role.y >= 508-85:<br/> role.y = 508-85<br/> role.state = 0<br/> addObject()<br/> for object in objectList:<br/> object.x -= 10<br/> if object.x + object.w <= 0:<br/> objectList.remove(object)<br/> score += 10<br/> if object.collision(role.getRect(), object.getRect()):<br/> if object.currentFrame == 6:<br/> objectList.remove(object)<br/> score += 100<br/> else:<br/> gameState = 1
The article concludes with the full source code and a request for readers to like, share, and follow if they found the tutorial helpful.
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.