Python Ski Game Development with Pygame
This article introduces a complete Python ski game built with Pygame, explaining the game mechanics, displaying screenshots of the interface and animation, and providing the full source code along with required image assets for readers to understand and recreate the project.
The article presents a fun ski game developed in Python using the Pygame library, adapted from Chapter 25 of "Computer Programming for Kids and other Beginners".
The game features a skier sliding down a mountain, controlled by the left and right arrow keys, with obstacles such as trees and flags that affect the score.
Visual examples of the game interface and animation are shown via images, illustrating how the skier moves and how obstacles appear.
The full source code is provided below; it defines constants, the skier class, obstacle handling, map creation, animation, and the main event loop. All code is kept intact and wrapped in a code block for easy reference.
#用于定义常量的类
class const:
class ConstError(TypeError):
pass
def _setattr__(self, name, value):
if self.__dict__._has_key(name):
raise self.ConstError("Can't rebind const (%s)" % name)
self.__dict__._[name] = value
const.MaxSpeed = 10 #设置最大的下滑速度
import pygame, sys, random
# 滑雪者在不同的方向上应该显示的图像
skier_images = ["skier_down.png", "skier_right1.png", "skier_right2.png",
"skier_left2.png", "skier_left1.png"]
# 滑雪者角色类
class SkierClass(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("skier_down.png")
self.rect = self.image.get_rect()
self.rect.center = [320, 100]
self.angle = 0
def turn(self, direction):
# 当滑雪者转向时,加载对应的图片并且修改速度值
self.angle = self.angle + direction
if self.angle < -2: self.angle = -2
if self.angle > 2: self.angle = 2
center = self.rect.center
self.image = pygame.image.load(skier_images[self.angle])
self.rect = self.image.get_rect()
self.rect.center = center
speed = [self.angle, const.MaxSpeed - abs(self.angle) * 2]
return speed
def move(self, speed):
# move the skier right and left
self.rect.centerx = self.rect.centerx + speed[0]*2
if self.rect.centerx < 20: self.rect.centerx = 20
if self.rect.centerx > 620: self.rect.centerx = 620
# 表示障碍物的类定义,包括树和旗子
class ObstacleClass(pygame.sprite.Sprite):
def __init__(self, image_file, location, type):
pygame.sprite.Sprite.__init__(self)
self.image_file = image_file
self.image = pygame.image.load(image_file)
self.rect = self.image.get_rect()
self.rect.center = location
self.type = type
self.passed = False
def update(self):
global speed
self.rect.centery -= speed[1]
if self.rect.centery < -32:
self.kill()
# create one "screen" of obstacles: 640 x 640
# use "blocks" of 64 x 64 pixels, so objects aren't too close together
def create_map():
global obstacles
locations = []
for i in range(10): # 10 obstacles per screen
row = random.randint(0, 9)
col = random.randint(0, 9)
location = [col * 64 + 32, row * 64 + 32 + 640] #center x, y for obstacle
if not (location in locations): # prevent 2 obstacles in the same place
locations.append(location)
type = random.choice(["tree", "flag"])
if type == "tree": img = "skier_tree.png"
elif type == "flag": img = "skier_flag.png"
obstacle = ObstacleClass(img, location, type)
obstacles.add(obstacle)
# 重绘显示区域,形成动画效果
def animate():
screen.fill([255, 255, 255])
obstacles.draw(screen)
screen.blit(skier.image, skier.rect)
screen.blit(score_text, [10, 10])
pygame.display.flip()
# 初始化各种对象
pygame.init()
screen = pygame.display.set_mode([640,640])
clock = pygame.time.Clock()
speed = [0, const.MaxSpeed] # 速度值,包含方向与向下的速度
obstacles = pygame.sprite.Group() # group of obstacle objects
skier = SkierClass()
map_position = 0
points = 0
create_map() # create one screen full of obstacles
font = pygame.font.Font(None, 50)
# 事件处理循环
running = True
while running:
clock.tick(30) #设定每秒帧数
for event in pygame.event.get():
if event.type == pygame.QUIT: running = False
if event.type == pygame.KEYDOWN: # 如果按下了键盘上的键
if event.key == pygame.K_LEFT: # 如果按下了向左的方向键
speed = skier.turn(-1)
elif event.key == pygame.K_RIGHT: #如果按下了向右的方向键
speed = skier.turn(1)
skier.move(speed) # 滑雪者向左或向右移动
map_position += speed[1] # 修改地图的位置,使得障碍物向上移动,造成了滑雪者向下滑行的效果
if map_position >= 640:
create_map()
map_position = 0
# 检查滑雪者是否碰到了树或旗子
hit = pygame.sprite.spritecollide(skier, obstacles, False)
if hit:
if hit[0].type == "tree" and not hit[0].passed: #碰到了树,并且这个树还没有被“处理”过
points = points - 100
skier.image = pygame.image.load("skier_crash.png") # 显示滑雪者翻倒的图片
animate()
pygame.time.delay(1000)
skier.image = pygame.image.load("skier_down.png") # 显示滑雪者正常滑行的图片
skier.angle = 0
speed = [0, const.MaxSpeed]
hit[0].passed = True
elif hit[0].type == "flag" and not hit[0].passed: # 碰到了一个旗子
points += 10
hit[0].kill() # 清除点这个被碰到的旗子
obstacles.update()
score_text = font.render("Score: " +str(points), 1, (0, 0, 0)) #更新提示的文本信息
animate()
pygame.quit() #退出pygameThe article also lists the image resources required for the game, providing file names and example screenshots for skier states, obstacles, and flags.
Readers can follow the tutorial to understand the structure of a simple Pygame project, adapt the code, and create their own ski game.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
