2012-09-12 15 views
6

estoy tratando de ejecutar un servidor trenzado con pygame-clientes:Clientes retorcidos dentro de pygame mainloop?

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... 

Y aquí es el servidor:

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() 

estoy corriendo este servidor con el código de cliente con el reactor.CallLater() método y código pygames y el cliente se conecta bien. ¿Estoy usando incorrectamente el método del reactor o hay algo estructuralmente incorrecto con el código pygames? Cualquier ayuda sería apreciada.

Así que no sé si el bucle dentro de los pygames mordió nunca rompe a llamar el reactor de nuevo?

+0

es algo no funciona? ¿Dónde está tu problema? – sloth

+0

Voy a editar para explicar más a fondo. – tijko

Respuesta

8

Debe no escriba su propio bucle principal (con while) al usar trenzado. trenzado tiene que controlar el bucle principal, y pygame es lo suficientemente flexible como para no preocuparse (que no necesita su propia bucle ).

Debe poner todo lo que está dentro de su bucle principal en una función, y shedule con el reactor trenzado llamando reactor.CallLater()

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) 

De esta manera, se asegura de las carreras del reactor y puede manejar eventos de red.


Aquí hay un pequeño ejemplo de trabajo de un cliente que se acaba de hacer que la última línea recibido:

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() 

Aquí está un ejemplo sencillo usando LoopingCall, como se sugiere Glifo (omití el protocol/clases de fábrica, ya que son los mismos que anteriormente):

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() 
+0

¿Debo llamar 'reactor.run()' después del tic y main? Pensé que tenía que ponerlo en marcha o ¿evitará que se ejecute main y tick alguna vez? Porque sin ella la pantalla de pygame se inicia luego sale y con él la pantalla de pygame no aparece en absoluto (por lo que el principal no se está llamando) – tijko

+1

Sólo tiene que llamar 'main()' una vez (o lo que se llama código para inicializar tu cliente). La parte importante es que 'reactor.callLater (0.1, tick)' se llama una vez antes de llamar 'reactor.run()'. – sloth

+0

todavía tengo que ejecutar 'reactor.ConnectTcp ('192.168.1.2', 6000, ChatClient())' y '' reactor.run' después de que el principal() 'llamar? He seguido adelante y he intentado esto pero, ¿ahora los eventos pygames no están respondiendo? – tijko