[pygame] pygame设计联机对战桌游(三)

本系列总目录:https://blog.csdn.net/wxlxy316/article/details/104246724

内容概要

四、分析桌游需求,制作类图,开始开发桌游(1)

昨日问题

在学习了一定的知识后——实际上是看了太久繁杂的英文教程,感到了倦怠和恶心——我决心为自己做一份甜点休憩一下:从设计简单的卡片展示器着手,先制作出一个简单的雏形来,验证自己的学习成果,再继续我的学习路径

先提几个昨日遇到的问题

python 获取某个对象的引用地址
https://blog.csdn.net/cpongo6/article/details/89249293

出现UnboundLocalError: local variable ‘a’ referenced before assignment异常的情况与解决方法
https://blog.csdn.net/DansonC/article/details/88860885

pygame.event类别汇总
https://blog.csdn.net/qq_41556318/article/details/86303039

这些问题使我感到了深深的沮丧和挫败,并且让我发现我对python对象的有关概念的理解实在是烂透了,因此我打开了菜鸟教程恶补了几天python class的知识:https://www.runoob.com/python3/python3-class.html
,关于学习这些内容时的笔记和感悟我放在文章后部了,现在,我们先讨论一下目前的工作吧!

卡牌展示器

0. 成果总结

1. 卡牌显示器

最终我厘清了一些思路,制作了一份简单的卡牌显示器,它具有如下特性:

  • 定义了两个类:卡堆CardHeap、卡牌Card
  • 卡牌若干,分布在卡堆中,卡牌和卡堆一一对应
  • 卡牌拥有正反两面,可以实现单击翻面特性
  • 卡牌在卡堆中一字排开,存在次序,紧邻排布(未完成)
  • 可以通过鼠标调整卡牌在卡堆中的顺序,也可以调整卡牌移动到不同的卡堆中

代码和素材移步github地址:https://github.com/bridgeL/card_show

2. 精灵类及其容器

学习了pygame.sprite.Sprite类,pygame.sprite.Group类,pygame.sprite.OrderedUpdates类,简单来说,
后两个类是第一个类的容器,且较前者为无序容器,较后者为有序容器,一般来说有序容器较慢,应根据实际情形使用不同的容器打包pygame.sprite.Sprite对象

3. 事件循环

深化了对于Event循环的理解:

  • clock模块,提供适当延时,以保证阵列稳定为预设值
  • 处理event队列,将每一帧间积攒的多个操作,依次处理
  • 获取上一帧中的精灵对象的矩阵坐标,用底图的对应部分覆盖 screen.blit(background,sprite.rect),对于对于组内的精灵可用group.clear(screen,background),会自动迭代处理每一个精灵
  • 运行游戏逻辑,计算这一帧精灵对象的矩阵坐标sprite.update(),对于组内的精灵可用group.update(),会自动迭代处理每一个精灵
  • 绘制组内精灵对象到这一帧group.draw(screen)
  • 应用更改到显示器pygame.display.flip()

1. 游戏对象类

1.1. 卡牌Card

2020/2/11
今日实在太匆忙,代码只做了一个雏形,也来不及写完第三期的官方教程学习笔记,这一期也漏了一些很坑的问题,我明天再来补充

卡牌类继承自pygame.sprite.Sprite类,新增属性imghimgbidlabelheadupmovepos
提供方法overturnisclickmove,重写了方法update,最值得一提的是,我在卡牌类中封装一个公共属性imgb

总所周知,一套卡牌的正面图案各不相同,但是背面图是一致的,如果我们为每个卡牌都加载两份图片(正反两面)的内存空间,那么至少有一半的内存空间是无意义消耗的,因此我为卡牌封装了一个公共属性imgb,存放反面图片,同时设计了属性self.headup和方法Card.overturn(self)这个方法将在翻转卡牌时起作用,它负责将属性self.headup翻转,同时修改self.image指向另一面,self.imghimgb


class Card(pygame.sprite.Sprite):
    imgb = 0

    def __init__(self, id, lable):
        super(Card, self).__init__()
        self.imgh, self.rect = load_img(lable+'.jpg')
        self.image = self.imgh
        self.id = id
        self.lable = lable
        self.headup = True
        self.movepos = [0, 0]

    def update(self):
        if self.movepos[0] != 0 or self.movepos[1] != 0:
            self.rect.move_ip(self.movepos)
            self.movepos = [0, 0]

    def overturn(self):
        self.headup = not self.headup
        if self.headup:
            self.image = self.imgh
        else:
            self.image = Card.imgb

    def isclick(self, pos):
        return self.rect.collidepoint(pos)

    def move(self, rel):
        self.movepos[0] += rel[0]
        self.movepos[1] += rel[1]


比较坑的一点在于,我在摸索这一模式时,经常遇到了

UnboundLocalError: local variable '<module_name>' referenced before assignment

类似这种错误,这是为什么呢?

原代码如下:

class Card(pygame.sprite.Sprite):
    imgb = pygame.image.load('data/back.jpg')

    def __init__(self, id, lable):
        super(Card, self).__init__()
        self.imgh, self.rect = load_img(lable+'.jpg')
        self.image = self.imgh
		...
	...

原来,这份代码在编译class Card类时——尽管此时还没有任何一个card对象实例化——调用了还没有初始化的pygame.image模块的函数,而pygame的初始化函数在main函数里,

经修改如下:

class Card(pygame.sprite.Sprite):
    imgb = 0

    def __init__(self, id, lable):
        super(Card, self).__init__()
        self.imgh, self.rect = load_img(lable+'.jpg')
        self.image = self.imgh
		...
	...
def cardinit():
	Card.imgb = pygame.image.load('data/back.jpg')
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值