Python-基于Pygame的小游戏(滑雪大冒险)(一)

发布于:2024-12-19 ⋅ 阅读:(14) ⋅ 点赞:(0)

前言:《滑雪大冒险》是一款休闲跑酷类游戏,玩家需要在游戏中与雪崩竞速,同时避开雪地上的各种障碍物,如石头、草丛和冰凌等。游戏的核心玩法是在雪山上滑行,避免被身后的雪崩吞没,并尽可能向前推进。与传统跑酷游戏不同的是,这款游戏中没有受伤或失败的概念,只有减速。当玩家的速度降到极慢时,可能会被雪崩追上。那么好,我们今天就一起来学习编写"滑雪大冒险"这款童年单机游戏(由于多方面的限制,制作的游戏可玩性不高,望大家包涵,后面我也会持续优化)。

编程思路:本次编程我们将会用到Python中的pygame,math,tkinter和random。其中,pygame是Python的第三方库,需要我们自行下载安装(不懂怎么下载的同学可以看一下我的前几篇有关pygame的文章,上面有相关教程)。

第一步:导入库

pygame是游戏的主体,包括图片描绘,声音播放等都由它来完成,。random和math主要实现游戏的内部运行逻辑。tkinter则负责最后的得分结算展示

import pygame
import random
import math
from tkinter import messagebox

第二步:初始化游戏

pygame.init()
screen_width = 800
screen_height = 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("滑雪大冒险 - 初级版")
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
BLUE = (0, 0, 255)

我们先提供游戏的初始化部分:设置窗口的大小、标题和颜色,为后续的游戏逻辑和图形渲染做准备。

第三步:创建游戏相关类

游戏相关类其实主要就两个:障碍物(如冰山,石头,树等),滑雪者。

class Skier(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.images = [
            pygame.image.load("skier_1.png")
        ]
        self.image = self.images[0]
        self.rect = self.image.get_rect()
        self.rect.center = (screen_width // 2, screen_height - 50)
        self.speed = 5
        self.direction = 0
        self.score = 0
        self.animation_index = 0
        self.is_jumping = False
        self.jump_height = 600
        self.jump_velocity = 0
        self.gravity = 0.1

    def update(self):
        if not self.is_jumping:
            self.rect.x += self.speed * self.direction
            if self.rect.left < 0:
                self.rect.left = 0
            if self.rect.right > screen_width:
                self.rect.right = screen_width
        else:
            self.jump_velocity += self.gravity
            self.rect.y += self.jump_velocity
            if self.rect.y >= screen_height - 50:
                self.rect.y = screen_height - 50
                self.is_jumping = False

        # 更新动画
        self.animation_index = (self.animation_index + 1) % len(self.images)
        self.image = self.images[self.animation_index]

    def turn(self, direction):
        self.direction = direction

    def jump(self):
        if not self.is_jumping:
            self.is_jumping = True
            self.jump_velocity = -math.sqrt(2 * self.gravity * self.jump_height)


class Obstacle(pygame.sprite.Sprite):
    def __init__(self, type):
        super().__init__()
        if type == "tree":
            self.image = pygame.image.load("tree.png")
        elif type == "rock":
            self.image = pygame.image.load("rock.png")
        elif type == "iceberg":
            self.image = pygame.image.load("iceberg.png")
        self.rect = self.image.get_rect()
        self.rect.x = screen_width + random.randint(0, 200)
        self.rect.y = screen_height - random.randint(100, 300)
        self.speed = 3

    def update(self):
        self.rect.x -= self.speed
        if self.rect.right < 0:
            self.kill()

第四步:游戏主循环

这一步是实现游戏整体效果的核心,需要调用到上面创建的各个类。


skier = Skier()
obstacles = pygame.sprite.Group()
clock = pygame.time.Clock()
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                skier.turn(-1)
            elif event.key == pygame.K_RIGHT:
                skier.turn(1)
            elif event.key == pygame.K_UP:
                skier.jump()
            elif event.key == pygame.K_DOWN:
                skier.speed -= 1

    screen.fill(WHITE)

    skier.update()
    obstacles.update()

    # 随机生成障碍物
    if random.randint(0, 100) < 1:
        obstacle_type = random.choice(["tree", "rock", "iceberg"])
        obstacle = Obstacle(obstacle_type)
        obstacles.add(obstacle)

    # 检测碰撞
    if pygame.sprite.spritecollide(skier, obstacles, False):
        running = False
        messagebox.showinfo("游戏结束", "得分:" + str(skier.score))


    screen.blit(skier.image, skier.rect)
    obstacles.draw(screen)
    # 显示分数
    font = pygame.font.Font(None, 36)
    score_text = font.render(f"Score: {skier.score}", True, WHITE)
    screen.blit(score_text, (10, 10))

    skier.score += 1

    pygame.display.flip()
    clock.tick(50)



pygame.quit()

第五步:准备游戏相关图片

温馨体示:图片需要放在PyCharm的python项目下。(不理解的同学可以看我前几篇文章)

滑雪者(skier_1.png):

树(tree.png):

冰山(iceberg.png):

石头(rock.png):

第六步:完整代码展示

import pygame
import random
import math
from tkinter import messagebox

pygame.init()
screen_width = 800
screen_height = 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("滑雪大冒险 - 初级版")
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
BLUE = (0, 0, 255)


class Skier(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.images = [
            pygame.image.load("skier_1.png")
        ]
        self.image = self.images[0]
        self.rect = self.image.get_rect()
        self.rect.center = (screen_width // 2, screen_height - 50)
        self.speed = 5
        self.direction = 0
        self.score = 0
        self.animation_index = 0
        self.is_jumping = False
        self.jump_height = 600
        self.jump_velocity = 0
        self.gravity = 0.1

    def update(self):
        if not self.is_jumping:
            self.rect.x += self.speed * self.direction
            if self.rect.left < 0:
                self.rect.left = 0
            if self.rect.right > screen_width:
                self.rect.right = screen_width
        else:
            self.jump_velocity += self.gravity
            self.rect.y += self.jump_velocity
            if self.rect.y >= screen_height - 50:
                self.rect.y = screen_height - 50
                self.is_jumping = False

        # 更新动画
        self.animation_index = (self.animation_index + 1) % len(self.images)
        self.image = self.images[self.animation_index]

    def turn(self, direction):
        self.direction = direction

    def jump(self):
        if not self.is_jumping:
            self.is_jumping = True
            self.jump_velocity = -math.sqrt(2 * self.gravity * self.jump_height)


class Obstacle(pygame.sprite.Sprite):
    def __init__(self, type):
        super().__init__()
        if type == "tree":
            self.image = pygame.image.load("tree.png")
        elif type == "rock":
            self.image = pygame.image.load("rock.png")
        elif type == "iceberg":
            self.image = pygame.image.load("iceberg.png")
        self.rect = self.image.get_rect()
        self.rect.x = screen_width + random.randint(0, 200)
        self.rect.y = screen_height - random.randint(100, 300)
        self.speed = 3

    def update(self):
        self.rect.x -= self.speed
        if self.rect.right < 0:
            self.kill()


skier = Skier()
obstacles = pygame.sprite.Group()
clock = pygame.time.Clock()
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                skier.turn(-1)
            elif event.key == pygame.K_RIGHT:
                skier.turn(1)
            elif event.key == pygame.K_UP:
                skier.jump()
            elif event.key == pygame.K_DOWN:
                skier.speed -= 1

    screen.fill(WHITE)

    skier.update()
    obstacles.update()

    # 随机生成障碍物
    if random.randint(0, 100) < 1:
        obstacle_type = random.choice(["tree", "rock", "iceberg"])
        obstacle = Obstacle(obstacle_type)
        obstacles.add(obstacle)

    # 检测碰撞
    if pygame.sprite.spritecollide(skier, obstacles, False):
        running = False
        messagebox.showinfo("游戏结束", "得分:" + str(skier.score))


    screen.blit(skier.image, skier.rect)
    obstacles.draw(screen)
    # 显示分数
    font = pygame.font.Font(None, 36)
    score_text = font.render(f"Score: {skier.score}", True, WHITE)
    screen.blit(score_text, (10, 10))

    skier.score += 1

    pygame.display.flip()
    clock.tick(50)



pygame.quit()

第七步:运行效果展示

(后续还会更新哦)

第八步:玩法介绍

左,右方向键控制滑雪者的滑行速度,上方向键控制滑雪者起跳。