如何从游戏循环外面给出Pong游戏的方向?

时间:2017-03-26 22:30:27

标签: python pygame python-multithreading asyncsocket python-sockets

我正在尝试使用简单的服务器/客户端套接字来控制游戏中的拨片。这个想法是让客户端能够通过向服务器发送指令来控制球拍,该服务器将该指示传递给游戏。所以我创建了一个线程来监听客户端的方向并将它们存储在一个varibale中,另一个线程用于运行游戏。 问题在于,当客户端发送lettre“z”(向上移动划桨)时,游戏开始,但是他发送了另一个游戏粉碎的碎片。

我不知道我是否已经解释了这个问题,我是python的新手,我会帮助你告诉我如何解决这个问题!

这是我的代码:

def update(val):
    ax.cla()
    yy = sy.val    
    chk1 = yy>upper
    chk2 = yy<lower
    chk3 = (yy>=lower) & (yy<=avg)
    chk4 = (yy>avg) & (yy<=upper)
    ax.bar(df.index[chk1.values], avg.iloc[chk1.values], width=1, edgecolor='k', color='blue')
    ax.bar(df.index[chk2.values], avg.iloc[chk2.values], width=1, edgecolor='k', color='brown')
    ax.bar(df.index[chk3.values], avg.iloc[chk3.values], width=1, edgecolor='k', color='orange')
    ax.bar(df.index[chk4.values], avg.iloc[chk4.values], width=1, edgecolor='k', color='aqua')
    ax.bar(df.index, avg, width=1, edgecolor='k', color='silver')
    ax.errorbar(df.index, avg, yerr=conf95, fmt='.',capsize=15, color='k')
    ax.axhline(y=yy,xmin=0,xmax=10,linewidth=1,color='k')
    fig.canvas.draw_idle()

sy.on_changed(update)  

1 个答案:

答案 0 :(得分:1)

您正在等待1024字节的数据,但它没有到达,因此线程挂起。如果要逐个键发送,请将其更改为1,或使用非阻塞套接字。

您也不使用新套接字连接到收听套接字。你需要其中两个。一个是服务器,一个是客户端。

这是你想要的,有点简化。它只会改变窗口背景。如果你正在认真规划网络游戏,你应该坚持使用线程模块。它为您提供比低级线程更多的灵活性。但是这段代码足以让你看到如何做你想做的事情。此外,没有时间戳和同步。在localhost和本地以太网上使用它时,它可以正常工作。

代码:



from thread import start_new_thread as thread
from time import sleep
from collections import deque
import pygame
import socket

running = 1
done = 0
evt_queue = deque() # deque() is thread safe with fast memory access of end items

def Quit ():
    global running
    print "Quitting"
    running = 0
    while done!=2:
        sleep(0.001)

def sender ():
    """Runs in thread and sends all valid events through socket."""
    global done
    print "Starting sender..."
    s = socket.socket()
    s.connect(("127.0.0.1", 1234))
    print "Sender connected!"
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                s.send("Q")
                break
            elif event.type == pygame.KEYDOWN:
                if event.unicode:
                    # Ensure only one byte is always sent:
                    k = event.unicode.encode("UTF-8")[0].upper()
                    s.send(k)
                    if k=="Q": break
    s.close()
    done += 1
    print "Sender done!"

def listener (client):
    """Thread that waits for events from client and puts them on queue."""
    global done
    print "Listening!"
    while running:
        try: e = client.recv(1) # Breaks when sender closes the connection
        except: break
        evt_queue.append(e)
    done += 1
    print "Listener done!"

# Dictionary with events and their associated functions
actions = {
    "W":
        lambda: screen.fill((255, 255, 255)),
    "K":
        lambda: screen.fill((0, 0, 0)),
    "R":
        lambda: screen.fill((255, 0, 0)),
    "G":
        lambda: screen.fill((0, 255, 0)),
    "B":
        lambda: screen.fill((0, 0, 255)),
    "Q": Quit,
    None: lambda: None}

def MainLoop ():
    """Manages the game. This example only changes window colours."""
    clock = pygame.time.Clock()
    while running:
        try: e = evt_queue.popleft()
        except: e = None
        action = actions.get(e, actions[None])
        action()
        clock.tick(64)
        pygame.display.flip()

pygame.init()
screen = pygame.display.set_mode((640, 480))
s = socket.socket()
s.bind(("127.0.0.1", 1234))
s.listen(1)
thread(sender,())
print "Waiting for connection..."
client, address = s.accept()
print "Connection from", address
thread(listener,(client,))
MainLoop()
s.close()
pygame.quit()