Pygame崩溃,没有错误报告

时间:2015-07-19 13:16:49

标签: python sockets network-programming pygame python-multithreading

我是python的新手。我曾多次尝试学习时遇到困难,但在查找错误报告后我终于可以搞清楚了。现在,经过8个小时试图解决这个问题后,我的想法就没了。

我正在尝试制作一个非常简单的联网(排序)游戏。客户端告诉服务器鼠标的位置。服务器将新客户端添加到其客户端列表中,并将客户端列表及其位置发送回客户端。之后,客户端将在屏幕上发送到圈子的值进行翻译。

tl; dr每个人的鼠标都应该用白色背景上的圆圈表示。 这是客户端的代码:

import socket
import sys
import pygame
from pygame.locals import *
import inputbox
import threading
import Queue
import time


host = ''
port = 0
server_port = 5000

FPS = 60 # frames per second, the general speed of the program
WINDOWWIDTH = 1280 # size of window's width in pixels
WINDOWHEIGHT = 720 # size of windows' height in pixels

GRAY     = (100, 100, 100)
NAVYBLUE = ( 60,  60, 100)
WHITE    = (255, 255, 255)
RED      = (255,   0,   0)
GREEN    = (  0, 255,   0)
BLUE     = (  0,   0, 255)
YELLOW   = (255, 255,   0)
ORANGE   = (255, 128,   0)
PURPLE   = (255,   0, 255)
CYAN     = (  0, 255, 255)

BGCOLOR = WHITE

ALLCOLORS = (RED, GREEN, BLUE, YELLOW, ORANGE, PURPLE, CYAN)

def server_info_processing(name, sock, queue):
    while True:
        try:

            while True:
                data, addr = sock.recvfrom(1024)
                queue.queue.clear()
                queue.put(data)
        except:
            pass



def main():
    players_pos = []
    pygame.init()
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    FPSCLOCK = pygame.time.Clock()
    DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
    mousex = WINDOWWIDTH / 2
    mousey = WINDOWHEIGHT / 2
    s.bind((host, port))
    s.setblocking(0)
    q = Queue.Queue()
    #server processing thread
    sPThread = threading.Thread(target = server_info_processing, args = ("RecvThread", s, q))
    sPThread.daemon = True
    sPThread.start()
    while True:
        try:
            answer = inputbox.ask(DISPLAYSURF, "Server IP")
            s.sendto(str(mousex) + " " + str(mousey), (answer, server_port))
            break
        except Exception:
            print "The IP address you entered is either not currently available or doesn't exist."

    while True:
        try:
            players_pos = q.get_nowait()
            q.task_done()
            players_pos = eval(players_pos) #The server is returning a string, but we need a list.
        except Queue.Empty:
            pass
        DISPLAYSURF.fill(BGCOLOR)
        for event in pygame.event.get(): # event handling loop
            if event.type == QUIT:
                #send a msg to have the server delete this connection
                print "Quitting."
                s.sendto('quit', (answer, server_port))
                pygame.quit()
                s.close()
                sys.exit()
            elif event.type == MOUSEMOTION:
                mousex, mousey = event.pos
                s.sendto(str(mousex) + " " + str(mousey), (answer, server_port))
            else:
                pygame.event.clear()
        allcolors_index = 0
        for index, value in enumerate(players_pos):
            if allcolors_index < len(ALLCOLORS):
                current_color = ALLCOLORS[allcolors_index]
            else:
                allcolors_index = 0
                current_color = ALLCOLORS[allcolors_index]
            if value:
                pygame.draw.circle(DISPLAYSURF, current_color, (int(players_pos[index][1][0]), int(players_pos[index][1][1])), 50)
                allcolors_index += 1  
        pygame.display.flip()
        FPSCLOCK.tick(FPS)



if __name__ == '__main__':
    main()

这是服务器:

import socket
import time
import threading

host = ''
port = 5000

clients = []

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
s.setblocking(0)
peoples_pos = []
in_database = False
addr_location = None
print "Server Started"



while True:
    try:
        data, addr = s.recvfrom(1024)
        for index, value in enumerate(peoples_pos):
            if data == 'quit':
                if addr == peoples_pos[index][0]:
            #removing the item at the index that contains addr
                    del peoples_pos[index]
            elif addr == peoples_pos[index][0]:
                in_database = True
                addr_location = index
        if data != 'quit':
            if in_database == False:
                peoples_pos.append([])
                peoples_pos[(len(peoples_pos)-1)].append(addr)
                peoples_pos[(len(peoples_pos)-1)].append(data.split())
            else:
                peoples_pos[addr_location][1] = data.split()
                in_database = False
            print time.ctime(time.time()), peoples_pos
            for index, value in enumerate(peoples_pos):
                s.sendto(str(peoples_pos), peoples_pos[index][0])
    except Exception as e:
        pass
s.close()

更新1:似乎客户端中的主要while循环只运行一次。如果在循环的底部放置一个print语句,则会打印文本,但只打印一次。我不知道为什么会这样,无论是症状还是原因,或两者兼而有之。

更新2:似乎使用q.get()通过停止脚本导致问题,直到队列中有项目为止。我不太清楚为什么。我已将其更改为queue.get_nowait()并添加了一个尝试除外。现在,当我移动鼠标时,圆圈会显示,但旧的圆圈不会被删除,客户端会在大约3秒钟后崩溃。

更新3:事实证明旧圈子已被删除,但服务器正在发送旧圈子的数据,就好像它是一个新玩家一样。我修复了那个bug然后让我的线程成为一个守护进程,因为除非它是一个守护进程,当我调用sys.exit()时,线程将不会退出,我必须关闭命令提示符才能恢复。据我所知,代码工作正常。以上是新的更正代码。

0 个答案:

没有答案