【问题标题】:Sending pygames-event data to a twisted-server?将 pygames 事件数据发送到扭曲服务器?
【发布时间】:2012-09-10 07:02:06
【问题描述】:

我正在运行一个带有 twisted 的 pygames 程序,但在从 pygame 事件中发送数据时遇到了问题。

首先是服务器:

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

class Game_Data(LineReceiver):
    def __init__(self, players, clients):
        self.players = players
        self.clients = clients

## the connectionMade method of LineReceiver is being used to create ##
## protocol instances of each client so it can send back any data it gets ##

    def connectionMade(self):
        new_player = 'player_' + str(len(self.players) + 1)
        self.clients.append(self)
        self.players.append(new_player)
        self.players = simplejson.dumps(self.players)
        for client in self.clients:
            client.sendLine(self.players)

## what ever data the server receives it sends right back to any clients ##

    def lineReceived(self,line):
        self.line = line
        print self.line
        for client in self.clients:
            client.sendLine(self.line)


class BlackFactory(Factory):
    def __init__(self):
        self.players = []
        self.clients = []

    def buildProtocol(self, addr):
        return Game_Data(self.players, self.clients)


reactor.listenTCP(6000, BlackFactory())

现在给客户:

import pygame
from twisted.internet.protocol import Protocol, ClientFactory
from twisted.protocols.basic import LineReceiver
from twisted.internet.task import LoopingCall
from twisted.internet import reactor

class BlackClientProtocol(LineReceiver):
    def __init__(self, recv, host):
        self.recv = recv
        self.host = host

    def lineReceived(self, line):
        self.recv(line)
        print line ## prints out as expected ##

    def connectionMade(self):
        self.host = self
        print self.host ## prints out as expected ##

class BlackClient(ClientFactory):
    def __init__(self, recv, host):
        self.recv = recv
        self.host = host

    def buildProtocol(self, addr):
        return BlackClientProtocol(self.recv, self.host)

class Client(object):
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((800, 600))
        pygame.display.flip()
        reactor.callLater(0.1, self.tick)

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

## this trial_func was to see if I could pass the BlackClient another argument ##
## to return an instance of the protocol to be called later in this class ##     

    def trial_func(self, host):
        self.host = host

    def tick(self):
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
                print self.line  ## prints out as expected##
                print self.host  ## does not print out ???##


if __name__ == '__main__':
    c = Client()
    lc = LoopingCall(c.tick)
    lc.start(0.1)
    reactor.connectTCP('192.168.1.2', 6000, BlackClient(c.new_line, c.trial))
    reactor.run()

编辑:这是一个更明确的例子。 cmets是挂断电话。只要您安装了 pygames,它就会运行,pygame 事件是一个简单的KEYDOWN(转义键)事件作为客户端发送数据的触发器。

【问题讨论】:

  • 能否将错误包含在回溯中?它可能会有所帮助。
  • 这个例子充满了语法错误,所以我无法真正回答这个问题。这显然不是您正在运行的实际代码。您可以生成sscce.org 并将其包含在您的问题中吗?
  • @tijko,请将所有相关代码放入问题中,而不是粘贴。另外,请简化您的代码,以便它只是展示与问题相关的部分 - 回答您问题的人想要一些足够完整的东西可以运行,但不是充满不相关逻辑的东西。
  • @Glyph 我终于整理了一些我认为会被认为具有sscce 质量的东西。我很抱歉花了这么长时间。我不知道你是否还会再看这篇文章:(

标签: python client twisted pygame


【解决方案1】:

我查看了您的代码,这似乎是相关部分:

def tick(self):
    flag = 0
    for event in pygame.event.get():
    ...
## call an instance of the protocol and sendLine ##
                    BlackClient(self.new_line(allhands)) ## this line does not work ##
## send allhands data ##
    ...

您希望将数据发送回服务器,但在这里您只是创建了一个 BlackClient 的新实例。

您可能希望使用sendLine 发送该行,但您需要对当前协议实例的引用(或至少对该方法的引用)。


这是一个如何实现这一目标的示例:

class Client(object):
    ...
    # this method is going to be replaced
    def sendLine(self, line):
        pass

    def tick(self):
        flag = 0
        for event in pygame.event.get():
            ...
            ## call sendLine, which is replaced by the sendLine method from the protocol ##
            self.sendLine(yourStuff)        

class BlackClient(ClientFactory):
    def __init__(self, client):
        # keep instance of client
        self.client = client

    def buildProtocol(self, addr):
        # give client.new_line method to protocol
        proto = BlackClientProtocol(self.client.new_line)
        # replace client's sendLine with proto.sendLine
        self.client.sendLine = proto.sendLine
        return proto

if __name__ == '__main__':
    c = Client()
    lc = LoopingCall(c.tick)
    lc.start(0.1)
    protocoll = 
    reactor.connectTCP('192.168.1.2', 6000, BlackClient(c))
    reactor.run()

这只是一个例子;您可能可以稍微清理一下代码。也许您想使用某种调度程序(例如pydispatch

【讨论】:

  • 感谢您的帮助,我知道在使用 BlackClient 时,我只是创建了一个我不需要的 BlackClient 实例,但不确定如何正确完成此操作。感谢您的帮助:)
  • 工厂内部的client 假设是Client 对类的引用吗?
  • @tijko 是对类实例的引用,在本例中为:c
  • 我现在可以看到,有道理。谢谢:)
猜你喜欢
  • 2017-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-16
  • 2022-12-03
  • 1970-01-01
  • 1970-01-01
  • 2021-01-01
  • 1970-01-01
相关资源
最近更新 更多