Pygame简单实现场景系统 (Scene)

目录

前言

文件结构

 常量设置

场景系统实现

设计

实现


前言

我在使用Pygame制作一款游戏时,需要使用场景系统。不过Pygame官方好像没有制作场景模块。所以我打算自己写一个简单的场景系统并分享到CSDN。

您也可以把这篇文章的pygame项目当作您的pygame项目的起始模板。

文件结构

首先,先写一个空Pygame项目,settings.py声明了常量。main.py调用settings.py的常量

Game
├─ settings.py
└─ main.py

 常量设置

将常量分文件,以免过于杂乱

# settings.py

WINDOWWIDTH = 300
WINDOWHEIGHT = 300
WINDOWTITLE = '场景测试'
FPS = 60

场景系统实现

设计

在开始写代码之前,我们先确认需要什么功能,场景模块应该是什么样的

我的想法是:每个场景使用独立的类。而且这个场景类不需要继承其他的类。所有函数(比如切换场景)都将在SceneManager中运行。每个场景的类只需要被SceneManager所调用,自身除了该场景的游戏代码之外无需运行其他代码。所以我将KeyGet放入SceneManager。因为SceneManager要是调用场景类的KeyDown,KeyUp等函数

SceneManager类需要做的事情清单

SceneManager
├─  ChangeScene # 切换场景
├─  KeyGet # 按键获取
└─  Loop # 游戏循环

场景类的所有将被SceneManager所调用的函数(SceneManager有判定场景类是否有即将调用的函数)

class Scene2():
    def __init__(self):
        pass
    def Update(self):
        pass
    def Render(self):
        pass
    def Close(self):
        pass
    def KeyUp(self,Key):
        pass
    def KeyDown(self,Key):
        pass

实现

接下来开始实现SceneManager,首先先导入所需库

import pygame
from pygame.locals import *
from settings import *

然后写SceneManager类,初始化时启动游戏窗口,常量在settings.py里面设置了

class SceneManager():
    def __init__(self,Scene):
        # 参数说明 —— Scene: 起始场景
        # 初始化Pygame
        pygame.init() 
        # 窗口标题 
        pygame.display.set_caption(WINDOWTITLE)
        # Fps时钟
        self.FpsClock = pygame.time.Clock()
        # 设置窗口大小
        self.DisplaySurf = pygame.display.set_mode((WINDOWWIDTH ,WINDOWHEIGHT))
        # 当前场景
        self.CurrentScene = Scene()
        # 已按下的按键,Pygame没有这个接口,自己用其他接口实现
        self.KeyPressed = []

然后,SceneManager类还需要做两件事,分别是:修改当前场景 按键获取 游戏循环 。我们一个一个实现,首先先实现修改当前场景

    def ChangeScene(self,Scene):
        # 参数说明 —— Scene: 将当前场景替换为该场景
        # 执行该场景的Close函数
        if hasattr(self.CurrentScene,'Close'):self.CurrentScene.Close()
        # 切换成新场景
        self.CurrentScene = Scene()

接着是GetKey,这个函数需要调用场景类的KeyUp和KeyDown。还需要设置KeyPressed(那些按键是被按下状态)

    def GetKey(self):
        for event in pygame.event.get():
            # 退出事件
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            # 按键按下
            if event.type == KEYDOWN:
                # 在KeyPressed里添加按键
                self.KeyPressed.append(event.key)
                # 判断是否存在函数后调用按键按下函数
                if hasattr(self.CurrentScene,'KeyDown'): self.CurrentScene.KeyDown(event.key)
            # 按键松开
            if event.type == KEYUP:
                # 删除KeyPressed里的按键
                self.KeyPressed.remove(event.key)
                # 判断是否存在函数后调用按键松开函数
                if hasattr(self.CurrentScene,'KeyUp'): self.CurrentScene.KeyUp(event.key)

最后,是游戏的循环。循环需要按顺序执行: 获取按键 ——> 调用当前场景的Update函数 ——> 调用当前场景的Render函数 ——> fps控制

    def Loop(self):
        while True:
            # 获取按键
            self.GetKey()
            # 调用
            if hasattr(self.CurrentScene,'Update'):self.CurrentScene.Update()
            if hasattr(self.CurrentScene,'Render'):self.CurrentScene.Render()
            pygame.display.update()
            # Fps控制
            self.FpsClock.tick(FPS)

好了,现在就SceneManager的全部功能了,场景类可以调用SceneManager的函数分别是:

GAME.ChangeScene(场景类名称) # 切换场景
GAME.KeyPressed # 返回按下的按钮

全部代码:

# main.py

import pygame
from pygame.locals import *
from settings import *

class SceneManager():
    def __init__(self,Scene):
        pygame.init()
        pygame.display.set_caption(WINDOWTITLE)
        self.FpsClock = pygame.time.Clock()
        self.DisplaySurf = pygame.display.set_mode((WINDOWWIDTH ,WINDOWHEIGHT))
        self.CurrentScene = Scene()
        self.KeyPressed = []
    def ChangeScene(self,Scene):
        if hasattr(self.CurrentScene,'Close'):self.CurrentScene.Close()
        self.CurrentScene = Scene()
    def GetKey(self):
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == KEYDOWN:
                self.KeyPressed.append(event.key)
                if hasattr(self.CurrentScene,'KeyDown'): self.CurrentScene.KeyDown(event.key)
            if event.type == KEYUP:
                self.KeyPressed.remove(event.key)
                if hasattr(self.CurrentScene,'KeyUp'): self.CurrentScene.KeyUp(event.key)
    def Loop(self):
        while True:
            self.GetKey()
            if hasattr(self.CurrentScene,'Update'):self.CurrentScene.Update()
            if hasattr(self.CurrentScene,'Render'):self.CurrentScene.Render()
            pygame.display.update()
            self.FpsClock.tick(FPS)

class Scene1():
    def __init__(self):
        print("Scene1 启动")
    def Update(self):
        # 切换到Scene2
        GAME.ChangeScene(Scene2)
    def Render(self):
        print("Scene1 Render")
    def Close(self):
        print("Scene1 被关闭")
    def KeyUp(self,Key):
        print("在 Scene1 时按下按钮")
    def KeyDown(self,Key):
        print("在 Scene1 时松开按钮")

class Scene2():
    def __init__(self):
        print("我是 Scene2")
    def Update(self):
        print("按下的按键有",GAME.KeyPressed)

GAME = SceneManager(Scene1)
GAME.Loop()
# settings.py 

WINDOWWIDTH = 300
WINDOWHEIGHT = 300
WINDOWTITLE = 'Pygame 场景测试'
FPS = 60

 你可以使用该项目作为您的Pygame起始项目。建议收藏备用

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
实现Pygame中的视野移动,可以通过改变绘制游戏场景的窗口位置来实现。以下是一个简单的示例代码,演示了如何在Pygame实现视野移动: ```python import pygame # 初始化Pygame pygame.init() # 设置窗口尺寸 window_width = 800 window_height = 600 window = pygame.display.set_mode((window_width, window_height)) pygame.display.set_caption("Pygame视野移动示例") # 设置游戏场景尺寸 scene_width = 2000 scene_height = 2000 # 设置玩家初始位置 player_x = window_width // 2 player_y = window_height // 2 # 设置视野尺寸 view_width = window_width view_height = window_height # 加载游戏场景图片 scene_image = pygame.image.load("scene.jpg") scene_rect = scene_image.get_rect() # 游戏主循环 running = True while running: # 处理事件 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # 获取玩家输入,控制视野移动 keys = pygame.key.get_pressed() if keys[pygame.K_LEFT] and player_x > view_width // 2: player_x -= 5 if keys[pygame.K_RIGHT] and player_x < scene_width - view_width // 2: player_x += 5 if keys[pygame.K_UP] and player_y > view_height // 2: player_y -= 5 if keys[pygame.K_DOWN] and player_y < scene_height - view_height // 2: player_y += 5 # 计算视野在场景中的位置 view_x = player_x - view_width // 2 view_y = player_y - view_height // 2 # 绘制游戏场景 window.blit(scene_image, (0, 0), (view_x, view_y, view_width, view_height)) # 绘制玩家 pygame.draw.circle(window, (255, 0, 0), (window_width // 2, window_height // 2), 10) # 更新窗口显示 pygame.display.flip() # 退出Pygame pygame.quit() ``` 在这个示例中,我们首先设置了游戏窗口的尺寸和标题。然后,我们定义了游戏场景的尺寸和玩家的初始位置。视野的尺寸与窗口尺寸相同。我们加载了游戏场景图片,并在游戏主循环中处理玩家输入,根据玩家输入来改变玩家的位置。然后,我们计算视野在场景中的位置,并将游戏场景中对应的部分绘制到窗口上。最后,我们绘制玩家,并更新窗口显示。 这个示例代码只是一个简单的演示,你可以根据自己的需求进行修改和扩展。希望对你有帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

四十岁学做码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值