【pygame实现星露谷物语风格游戏】1.窗口的创建与展示

这篇具有很好参考价值的文章主要介绍了【pygame实现星露谷物语风格游戏】1.窗口的创建与展示。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言:

下面是对本系列的一些说明:

首先游戏是一个外国人写的,原视频链接为https://www.youtube.com/watch?v=R9apl6B_ZgI

bilibili搬运视频的链接为:简介_哔哩哔哩_bilibili

至于游戏是不是星露谷物语风格,我也不知道,因为我也没玩过,只不过bilibili的视频标题就是这样的。

游戏的最终效果,可以点进B站的链接去看视频的P1简介部分

原视频是英文,机器翻译,可能会对一些人的学习造成难度

我跟着原视频写了一遍,在代码中添加了中文注释,对原版的代码出现bug的地方做了修改,并且根据自己的理解写了这篇中文版教程。

本系列,python自带的东西一概不会多说,也不会系统的将pygame里的所有API是如何使用的。但是只要是pygame里面的东西,第一次出现的时候都会详细说明是怎么使用的,比如这个函数的参数代表什么,返回值是什么。只要讲过一次,以后再出现就不会细讲了。本游戏是比较典型的2D游戏,所以一套下来pygame中常用到的东西基本都会讲到。

相比于pygame中的API,这次实战更重要的是能够获得2D游戏创作的一些套路,很多东西都是通用的,比如主角的移动,摄像机的设置,伪3D效果,碰撞检测。这些东西无论是在python中写,还是在其他的游戏开发引擎中写,大体思想都是相同的。学会了了这些思想,想要开发新的2D游戏,基本就不会遇到任何困难了。

完成这次实战,更加能够锻炼面向对象编程的能力,因为所有的代码基本都封装到类里面了。

本系列基本上是对代码逐行解读,并且会在每一节的最后,贴出本节修改过的文件里面的全部代码。

接下来是原作者给出的项目文件的链接,我们需要里面的图片素材,音频素材等等:

https://github.com/clear-code-projects/PyDew-Valley

下载完成后文件格式如下图所示pygame 星露谷物语,游戏,pygame,python

原作者在完成一部分功能后,会把截止到目前的所有代码保存到一个文件夹下,总共有23个文件夹,每个文件夹里面都有我们需要的完整素材,我们可以随便打开一个文件夹,里面名为code的文件夹是存放代码的地方,其他的文件夹都是我们用到的音频或者图片的素材,我们可以把除了code的文件夹都复制到我们的项目下,并且在我们的项目下新建一个名为code的文件夹,在这个文件夹里面写代码pygame 星露谷物语,游戏,pygame,python

接下来就是正文部分了,本节将讲述第一部分,窗口的创建与展示:


一.项目的架构:

项目的架构如下图所示,在主文件夹下存放了图中的5个文件夹,其存放的内容分别如箭头标注所示,其中code存放代码,我们每次创建.py文件都在该文件夹下创建。本次所需要编写的是main.py,settings.py和level.py三个文件,后续也会根据功能的增加不断添加新的代码,或者添加新的.py文件。

pygame 星露谷物语,游戏,pygame,python

二.settings.py

再编写一个项目时通常会创建很多常量,我们希望把所有用到的常量都写在一个python文件中,如果要修改一些常量,直接到这个文件中去修改即可。

settings.py就是我们用来存放常量的文件,它的内容如下所示:

from pygame.math import Vector2

# screen

SCREEN_WIDTH = 1280

SCREEN_HEIGHT = 720

TILE_SIZE = 64


# overlay positions

OVERLAY_POSITIONS = {

    'tool' : (40, SCREEN_HEIGHT - 15),

    'seed': (70, SCREEN_HEIGHT - 5)}


PLAYER_TOOL_OFFSET = {

    'left': Vector2(-50,40),

    'right': Vector2(50,40),

    'up': Vector2(0,-10),

    'down': Vector2(0,50)

}


LAYERS = {

    'water': 0,

    'ground': 1,

    'soil': 2,

    'soil water': 3,

    'rain floor': 4,

    'house bottom': 5,

    'ground plant': 6,

    'main': 7,

    'house top': 8,

    'fruit': 9,

    'rain drops': 10

}


APPLE_POS = {

    'Small': [(18,17), (30,37), (12,50), (30,45), (20,30), (30,10)],

    'Large': [(30,24), (60,65), (50,50), (16,40),(45,50), (42,70)]

}


GROW_SPEED = {

    'corn': 1,

    'tomato': 0.7

}


SALE_PRICES = {

    'wood': 4,

    'apple': 2,

    'corn': 10,

    'tomato': 20

}

PURCHASE_PRICES = {

    'corn': 4,

    'tomato': 5

}

 

我们这次只关心其中的两个常量,就是下图中框出来的部分

pygame 星露谷物语,游戏,pygame,python

他们分别代表了窗口的高度和宽度,其值可以根据各自的情况更改。

至于其他的值代表的含义,以后用到的时候会说,这里可以先把所有的内容都先复制到自己的setting.py中

三.main.py

main.py的作用是给用户提供一个运行程序的接口,在运行main.py后,他会创建一个窗口并将它显示出来。

通常一个项目我们不希望它的main.py文件很长,因此我们并不在main.py中实现游戏的内容,而是希望再level.py中实现游戏的内容,因此在main.py文件中会调用level.py提供的接口,而后续的其他游戏功能的实现,都会写在level.py文件中,或者写在其他的.py文件中再由level.py去调用,总之,这次写完main.py后,我们基本上不会动这个文件了。其完整代码如下所示:

import pygame, sys

from settings import *

from level import Level



class Game:

    def __init__(self):

        #初始化

        pygame.init()

        #设置屏幕

        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

        #设置标题

        pygame.display.set_caption('农场')

        #创建时钟,为以后得到dt使用

        self.clock = pygame.time.Clock()

        #创建关卡对象Level,该类在level.py文件中

        self.level = Level()


    def run(self):

        while True:

            #按键检测

            for event in pygame.event.get():

                """如果按下的是右上角的红叉,就退出程序"""

                if event.type == pygame.QUIT:

                    #退出pygame

                    pygame.quit()

                    #退出python程序,不捕获异常,不加上这一句也能退出,但是会在中断报错

                    sys.exit()


            dt = self.clock.tick() / 1000

            self.level.run(dt)

            #更新画面,一定要写在while循环的最后

            pygame.display.update()



if __name__ == '__main__':

    game = Game()

    game.run()

 

如下是代码解读:

1.导包部分

import pygame, sys

from settings import *

from level import Level

 

首先要导入pygame

sys是对系统进行操作的一个包,用到的很少,下面会进行解释

然后就是从settings(我们自己的settings.py)中导入所有的东西,这样我们就可以直接使用其中的常量了

然后就是从level.py中导入Level类,因为level.py还没写,所以先跳过

2.编写Game类

其中包含了两个函数,__init__函数是初始化的,每次创建一个game对象就会自动调用__init__函数

def __init__(self):

    #初始化

    pygame.init()

    #设置屏幕

    self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

    #设置标题

    pygame.display.set_caption('农场')

    #创建时钟,为以后得到dt使用

    self.clock = pygame.time.Clock()

    #创建关卡对象Level,该类在level.py文件中

    self.level = Level()

 

pygame.init()是初始化pygame,这是pygame作者的硬性要求,在使用pygame之前写上这么一句就行了。只要在这里初始化过一次之后就不用再写了

pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))是创建一个窗口,其中的(SCREEN_WIDTH, SCREEN_HEIGHT)分别是窗口的宽度和高度,这窗口作为返回值被self.screen接收,以后我们要对窗口进行操作,对self.screen进行操作就行了

pygame.display.set_caption('农场')是设置标题,文字可以根据个人喜好随便写,下图箭头所指的位置就是一个窗口的标题

pygame 星露谷物语,游戏,pygame,python

self.clock = pygame.time.Clock()是创建一个Clock对象,翻译过来可能称作时钟更为贴切,作者再time.py这个模块中写了很多关于时间的类,Clock这个类中包含了一些关于游戏时钟的方法,我们在下面会用到其中的一些方法,等用到的时候会再说。

self.level = Level()这个就是创建一个Level对象,但是level.py还没写,所以可以先跳过

下面是run函数,也就是让游戏运行起来的函数:

def run(self):

    while True:

        #按键检测

        for event in pygame.event.get():

            """如果按下的是右上角的红叉,就退出程序"""

            if event.type == pygame.QUIT:

                #退出pygame

                pygame.quit()

                #退出python程序,不捕获异常,不加上这一句也能退出,但是会在中断报错

                sys.exit()


        dt = self.clock.tick() / 1000

        self.level.run(dt)

        #更新画面,一定要写在while循环的最后

        pygame.display.update()

 

我们不希望游戏是窗口闪过一下就退出的,因此我们需要让这个程序一直保持运行,因此我们写了一个死循环While True:,这样我们就能一直运行这个程序除非我们主动关闭它。

这个循环被称为游戏的主循环,和pygame.init()必须写在开头类似,有一个语句是一定要写在主循环的结尾处的,就是pygame.display.update(),它的作用是更新窗口中的画面,就比如一开始主角的位置在(0,0)处,主角向右移动了1个像素,他的坐标变成了(1,0),但是此时游戏的画面中主角还是在原位置,只有执行了pygame.display.update()之后,游戏画面才会被更新,主角才会到他相应的位置。

由于一次循环调用一次pygame.display.update(),一次循环更新一次画面,因此一次循环我们称为一帧。

pygame.event.get()是一个检测运行中出现的事件的方法,它会将这一次循环(这一帧)中所有出现的事件都检测出来,并且以一个列表的形式返回。

而pygame中的事件大概有退出(pygame.QUIT),键盘按下,键盘松开等等,这里我们只用到退出事件,退出事件指的是用户点击窗口右上角的X。

pygame.event.get()返回这一帧发生的所有时间的列表,我们用for循环来遍历这个列表,如果发现列表中有一个事件是退出(if event.type == pygame.QUIT:),那我们就退出pygame(pygame.quit()),然后再推出这个python程序(sys.exit())

这里用到了刚刚导包的时候导入的sys,sys.exit()的作用是退出这个python程序,如果我们不写这句话,也可以退出,只不过是以程序错误的形式被迫退出的,如下图所示,如果不写sys.exit(),点击窗口右上角的X退出,下面的窗口会提示报错信息,进而中断整个程序

pygame 星露谷物语,游戏,pygame,python

而加上了这句话,就相当于我们主动退出,不会报错

pygame 星露谷物语,游戏,pygame,python

 dt = self.clock.tick() / 1000,其中dt这个变量代表英文完整版翻译过来应该是变化的事件,它代表的是一帧(一次循环)所花费的事件,单位为秒

他的得到的过程如下:

 self.clock.tick()就是我们上面说的Clock类中的一个方法,它的返回值是这一帧距离上一帧经过了多少毫秒。再除以1000,得到的就是这一帧距离上一帧过去了多少秒了。

tick()这个方法还有一个作用就是控制游戏的帧率,如果括号内传入参数,这个方法就会控制游戏的帧率不超过这个参数的值,比如在这里写self.clock.tick(60),那么就会控制游戏的帧率不超过60,主要原理就是通过暂停来让游戏主循环进行的不那么快,一秒最多只能循环60次。

dt这个变量再后续会又用,等用到了再说,先知道他是代表一帧所花的时间就行

self.level.run(dt) 这个语句是调用上面创建的Level类的run函数,因为还没写level.py,先跳过。

3.主函数

上面编写的Game类是不会自己运行的,需要你在主函数中创建一个game对象,此时会自动调用__init__函数,然后再在主函数中调用game的run函数即可。

if __name__ == '__main__':

    game = Game()

    game.run()

 

四.level.py

我们在main.py创建了一个Level类,并且调用了他的run函数,因此我们要在level.py中写一个Level类,并实现他的run函数。相似的,Level类中的__init__函数是用来初始化的,run函数是用来运行游戏的。

在我们启动的main.py后,首先创建一个Game类的对象game,自动调用game的__init__函数,在这个__init__函数中,我们创建了一个Level类的对象level,自动调用了level的__init__函数,至此,游戏的初始化完成。我们调用game的run()函数,在game的run()函数中,我们写了一个游戏的主循环,每一次循环我们都调用了level的run函数。因此,我们也可以猜出来,Level类的run()函数,才是实现游戏的主要部分。

完整代码如下:

import pygame

from settings import *


class Level():

    def __init__(self):

        #得到屏幕的画面,得到的这个画面与main.py中的screen相同

        self.display_surface = pygame.display.get_surface()

    def run(self,dt):

        #窗口的背景设为黑色

        self.display_surface.fill('black')

 

本次的level部分实际上并没有实现什么东西,只不过写了一个大概的框架,留着以后填充。

1.导包部分

import pygame

from settings import *

 

pygame是一定要导的

settings作为记录本项目所有常量的文件,也是一定要导的

2.Level类

class Level():

    def __init__(self):

        #得到屏幕的画面,得到的这个画面与main.py中的screen相同

        self.display_surface = pygame.display.get_surface()

    def run(self,dt):

        #窗口的背景设为黑色

        self.display_surface.fill('black')

 

其中pygame.display.get_surface()是得到窗口,由于我们的窗口是在main.py中创建的,并且用了Game类中的self.screen来接受它,这就导致了如果我们想在Level类中对窗口进行操作,还得去调用main.py中的Game类中的screen对象,这需要我们在开头import main ,但是在main.py中我们import了level,又在level.py中import了mian,这在逻辑上是十分混乱的,我们还不如直接写到同一个文件中去。好在pygame提供了这样的一个方法,让我们能获取窗口,这里的display_surface与main.py中的screen指的是同一块窗口。

self.display_surface.fill('black')是将窗口填充为黑色,参数可以用字符串的形式来表示颜色,也可以用一个列表的形式,利用RGB来表示颜色,比如(0,0,0)代表黑色,(255,0,0)代表红色等等。

五.总结

本次,我们在settings.py中创建了本项目所需要的所有常量,并且在main.py中完成了游戏窗口的创建与显示,并且创建了Level对象并在游戏主循环中调用其run()函数。在level.py中,我们编写了Level类的框架,包括一个初始化__init__函数和一个run()函数,这两个函数等待我们的后续完善。文章来源地址https://www.toymoban.com/news/detail-859445.html

到了这里,关于【pygame实现星露谷物语风格游戏】1.窗口的创建与展示的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 星露谷物语(Stardew Valley)Mod Farmtronics 机器人自动浇水代码

    模组介绍:【星露谷物语】你想要一群可爱可编程的工作机器人吗?Farmtronics模组介绍_哔哩哔哩_bilibili Farmtronics使用的编程语言语法 MiniScript-QuickRef.pages Api 接口参考 ·乔斯特劳特/法姆电子学维基 ·吉特哈布 (github.com) Farmtronics.zip-10634-1-2-0-1658871311 SMAPI 3.16.2 1.机器人使用笛卡

    2024年02月09日
    浏览(44)
  • 在MacOS上使用NSWindow展示了多种不同风格的窗口

        A showcase of many of the different styles of windows possible with NSWindow on MacOS. In some examples, NSToolbar, and NSVisualEffectView are used. No private API\\\'s are used. To test each style, clone the project, open it in Xcode, uncomment each block of code in  WindowController.swift  and run. The numbers above each block correspond to each style

    2024年02月07日
    浏览(41)
  • 使用Pygame创建一个简单游戏界面

    首先需要安装Pygame 模块,在Python代码中添加引用。 1. 引用代码如下: 2. 定义初始化窗口函数: 在初始化窗口函数中,定义窗口大小和窗口标题。 3. 创建一个循环,不断更新界面和检测事件 加载背景图片,将背景图片对象放置在窗口上,位置(0,0) 最左角,图片有实际的

    2024年02月13日
    浏览(49)
  • 使用Python和Pygame创建A*寻路算法与保护金塔游戏

    在本教程中,我们将使用Python编程语言和Pygame游戏开发库来创建一个有趣的项目。我们将结合A*寻路算法和保护金塔游戏机制,以展示如何使用寻路算法来指导游戏角色移动,并保护金塔免受入侵者的攻击。 A*寻路算法是一种常用的路径搜索算法,常用于游戏开发和人工智能

    2024年02月06日
    浏览(56)
  • Hazel游戏引擎(011)窗口抽象和GLFW创建窗口

    文中若有代码、术语等错误,欢迎指正 此节目的 为了有窗口效果,但不想使用原生的window32写起,所以用glfw窗口库。 也为了完成008计划事件系统的 创建窗口 部分 图示 添加glfw子模块 修改premake 解决方案下的premake修改 效果 目前类图 Application类可以调用创建窗口函数,而窗

    2024年02月13日
    浏览(36)
  • 【Python】pygame弹球游戏实现

    游戏源码: pygame_os库:

    2024年02月12日
    浏览(80)
  • Python利用pygame实现飞机大战游戏

    文章目录: 一:运行效果 1.演示 2.思路和功能 二:代码 文件架构 Demo 必备知识:python图形化编程pygame游戏模块 效果图 ◕‿◕✌✌✌ Python利用pygame实现飞机大战游戏运行演示 参考:【Python游戏】1小时开发飞机大战游戏-Pygame版本(1小时40分钟) 博主提取资源: 提取

    2024年04月09日
    浏览(90)
  • pygame第7课——实现简单一个打砖块游戏

    pygame课程 课程名称 第1课:pygame安装 链接 :https://blog.csdn.net/weixin_42636075/article/details/130512509 第2课:pygame加载图片 链接 :https://blog.csdn.net/weixin_42636075/article/details/130562606 第3课:画图小程序 链接 :https://blog.csdn.net/weixin_42636075/article/details/130801371 第4课:颜色监测(迷宫小游戏

    2024年04月16日
    浏览(39)
  • 使用Python+pygame实现贪吃蛇小游戏

    使用第三方库pygame,关于Python中pygame游戏模块的安装使用可见 https://blog.csdn.net/cnds123/article/details/119514520 给出两种实现。 第一种 运行效果如下: 游戏源码如下: 第二种 就不给出运行效果图了,你可以运行看看。 下面给出另一种实现源码: OK! 

    2024年01月16日
    浏览(80)
  • 基于Python的PyGame的俄罗斯方块游戏设计与实现

    近年来,随着游戏产业的突飞猛进,游戏玩家的技术也是与日俱增,当你看见游戏高手完美的表演时,你是否想过我也能达到那种水平,本程序用Python语言编写俄罗斯方块,左侧显示正在运行的游戏,右边显示下一个出现的形状、等级和积分等。游戏运行时随着等级的提高而

    2024年02月04日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包