进度
- 将网络通信嵌入到之前的demo中
问题
由于项目庞大,嵌入新功能可能导致大片出错,这里新建了个小demo专门用于测试
结果出现了不少棘手的问题:
- socket通信只能传字符串,不能传对象
尝试过将对象转字符串,这样做可以发送数据,但接收数据后由字符串转对象,python无法识别
后来询问gpt,得知应该可以pickle模块来包装对象,成功解决问题 - 由上,引发了新问题:pickle不能包装含有pygame.Surface对象的实例
也就是说,若要实现网络对战,之前的项目要大改:因为底层的植物、僵尸类我都将图片设置成其自身属性
要解决此问题,没有特别好的办法,只能将底层精灵的图片属性改成“图片路径”,在实际运行时根据路径调用显示图片,这样的话pygame.sprite也完全不能用了 - 在新的小demo里按上面的思路构建了新的精灵结构,称为mysprite,可以正确显示和通信,但出现了新问题:通信时服务器和客户端的屏幕会闪烁不断
在不断的摸索中发现:若删除服务器和客户端中的pyClock.tick(60),则不会闪烁,但这样不符合我的预期:因为两端的帧数改变了,精灵刷新地很快
后来我在通信之前增加了一段更新代码(通信之后再更新一次),解决了此问题
class mySprite:
anime_path = ''
amine_speed = 0.1
def __init__(self, pos, status='0', animations=None):
super().__init__()
# 动画相关
if animations is None:
animations = {'0': []}
self.animations = animations
self.status = status
self.import_assets()
self.f = 0
# 位置
self.pos = pygame.math.Vector2(pos)
def import_assets(self):
for status in self.animations.keys():
status_path = self.anime_path + '/' + status
import_assets(status_path, self.animations[status])
def animate(self, screen):
self.f += self.amine_speed
if self.f > len(self.animations[self.status]):
self.f = 0
path = self.animations[self.status][int(self.f)]
image = pygame.image.load(path).convert_alpha()
rect = image.get_rect(center=self.pos)
screen.blit(image, rect)
def update(self, screen):
self.animate(screen)
from Plants import *
from network.server import *
pygame.init()
screen = pygame.display.set_mode(mainScreen)
pygame.display.set_caption("服务器")
mouse_pressed = [None, False, False, False]
class plList:
def __init__(self):
self.plants_list = []
pls = plList()
server = Server()
def main():
global pls
while True:
screen.fill('white')
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
pls.plants_list.append(PL_sunflower(pygame.mouse.get_pos()))
for i in pls.plants_list:
i.update(screen)
# 通信
server.send(pls)
pls = server.recv()
# 游戏主体
for i in pls.plants_list:
i.update(screen)
# 总刷新与收尾
pygame.display.flip()
pyClock.tick(60)
if __name__ == '__main__':
main()