python - pygame 主循环中的扭曲客户端?

标签 python twisted pygame program-entry-point

我正在尝试使用 pygame-clients 运行一个扭曲的服务器:

class ChatClientProtocol(LineReceiver):
    def lineReceived(self,line):
        print (line)

class ChatClient(ClientFactory):
    def __init__(self):
        self.protocol = ChatClientProtocol

def main():
    flag = 0
    default_screen()
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
               return
            elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                pos = pygame.mouse.get_pos()
                # some rect.collidepoint(pos) rest of loop... 

这是服务器:

from twisted.internet.protocol import Factory
from twisted.protocols.basic import LineReceiver
from twisted.internet import reactor

class Chat(LineReceiver):
    def __init__(self, users, players):
        self.users = users
        self.name = None
        self.players = players

    def connectionMade(self):
        new = 'player_' + str(len(self.players) + 1)
        self.players.append(new)
        self.sendLine(str(self.players,))

class ChatFactory(Factory):
    def __init__(self):
        self.users = {} #maps instances to clients 
        self.players = []

    def buildProtocol(self, addr):
        return Chat(self.users,self.players)


reactor.listenTCP(6000, ChatFactory())
reactor.run()

我在没有 reactor.CallLater() 方法和 pygames 代码的情况下使用客户端代码运行此服务器,并且客户端连接正常。我是不是使用了错误的 react 器方法,还是 pygames 代码在结构上有问题?任何帮助将不胜感激。

所以我不知道 pygames 位中的循环是否曾经中断以再次调用 react 器?

最佳答案

在使用 twisted 时,您不应该编写自己的主循环(使用 while)。 twisted 必须控制主循环,而 pygame 足够灵活,无需关心(它不需要它的自己的循环)。

您应该将主循环中的所有内容放入一个函数中,并通过调用 reactor.CallLater()

将其与扭曲的 react 器一起调度
def main():
    flag = 0
    default_screen()
    reactor.callLater(0.1, tick)

def tick():
   for event in pygame.event.get():
        if event.type == pygame.QUIT:
            reactor.stop() # just stop somehow
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
            reactor.stop() # just stop somehow
        elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
            pos = pygame.mouse.get_pos()
            # some stuff
   reactor.callLater(0.1, tick)

通过这种方式,您可以确保 react 器运行并可以处理网络事件。


这是一个客户端的小示例,它只会呈现收到的最后一行:

from twisted.internet import reactor
from twisted.internet.protocol import ClientFactory
from twisted.protocols.basic import LineReceiver

import pygame

class ChatClientProtocol(LineReceiver):

    def __init__(self, recv):
        self.recv = recv

    def lineReceived(self,line):
        self.recv(line)

class ChatClient(ClientFactory):
    def __init__(self, recv):
        self.protocol = ChatClientProtocol
        self.recv = recv

    def buildProtocol(self, addr):
        return ChatClientProtocol(self.recv)

class Client(object):

    def __init__(self):
        self.line = 'no message'
        pygame.init()
        self.screen = pygame.display.set_mode((200, 200))
        reactor.callLater(0.1, self.tick)

    def new_line(self, line):
        self.line = line

    def tick(self):
        self.screen.fill((0,0,0))
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                reactor.stop() # just stop somehow
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
                reactor.stop() # just stop somehow
        self.screen.blit(pygame.font.SysFont('mono', 12, bold=True).render(self.line, True, (0, 255, 0)), (20,20))
        pygame.display.flip()
        reactor.callLater(0.1, self.tick)

if __name__ == '__main__':
    c = Client()
    reactor.connectTCP('127.0.0.1',6000, ChatClient(c.new_line))    
    reactor.run()

这是一个使用 LoopingCall 的简单示例,正如 Glyph 所建议的那样(我省略了协议(protocol)/工厂类,因为它们与上面的相同):

from twisted.internet.task import LoopingCall

class Client(object):

    def __init__(self):
        self.line = 'no message'
        pygame.init()
        self.screen = pygame.display.set_mode((200, 200))

    def new_line(self, line):
        self.line = line

    def tick(self):
        self.screen.fill((0,0,0))
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                reactor.stop() # just stop somehow
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
                reactor.stop() # just stop somehow
        self.screen.blit(pygame.font.SysFont('mono', 12, bold=True).render(self.line, True, (0, 255, 0)), (20,20))
        pygame.display.flip()

if __name__ == '__main__':
    c = Client()

    lc = LoopingCall(c.tick)
    lc.start(0.1)
    reactor.connectTCP('127.0.0.1',6000, ChatClient(c.new_line))    
    reactor.run()

关于python - pygame 主循环中的扭曲客户端?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12381446/

相关文章:

python - 是否必须安装 pygame 才能运行 pygame 游戏?

python - python 的 httplib 的替代品?

python - 如何检测从 pb.Root 继承的服务器中丢失的客户端连接?

python - 嵌套的 if 语句、干净的代码和 Pythonic,带有 Controller /键盘输入

python - 尝试使用字典定义巴恩斯利蕨类植物的参数时遇到问题

python - 根据特定索引处的值从元组列表中删除重复项

Python:忽略后台进程中的信号

python - Twisted 的 Serialport 和消失的串口设备

python - 类型错误 : 'pygame.Surface' object is not callable [Pygame module]

python - 在 Python 中创建 Zigzag 数组的函数