Game Development 9 min read

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.

Python Programming Learning Circle
Python Programming Learning Circle
Python Programming Learning Circle
Python Ski Game Development with Pygame

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() #退出pygame

The 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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PythonGame DevelopmentPygameSki Game
Python Programming Learning Circle
Written by

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.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.