Python对网络来说太慢了

时间:2015-04-24 07:31:39

标签: python sockets networking tcp pygame

我的Python游戏有问题。实际上,这款游戏配有两台电脑(网络tcp)。 服务器 - 计算机和客户端 - 计算机一起工作但速度太慢。

对于简历:服务器发送多点协调,客户端必须收到它。 服务器正确发送点和客户端接收点但速度太慢(滞后)。

# -*- coding: utf-8 -*-

from zModule import *
from load_datas import *
from load_instances import *
from Palet import *
import socket
import Queue
import time
import json
import random
from Chrono import *
from threading import *

r_queue_s = Queue.Queue()
s_queue_s = Queue.Queue()
r_queue_c = Queue.Queue()
s_queue_c = Queue.Queue()

clock = pygame.time.Clock()
screen = pygame.display.get_surface()

bg = pygame.image.load(terrain).convert()
palet_r = pygame.image.load(palet_rouge).convert_alpha()
palet_b = pygame.image.load(palet_bleu).convert_alpha()
ball = pygame.image.load(ball_path).convert_alpha()

palets_count = 10
palets = []

buts = [0, 0]
times = [0, 0]
time_end = 0
time_start = 0
click = False
a = 0


def exit():
    from main import *
    loop()


def events():

    global click

    for e in pygame.event.get():
        if e.type == QUIT:
            sys.exit()
        elif e.type == pygame.MOUSEBUTTONDOWN:
            click = True
        elif e.type == pygame.MOUSEBUTTONUP:
            click = False


def get_datas(role):
    future = None
    try:
        if role == 'server':
            future = r_queue_s.get_nowait()
        elif role == 'client':
            future = r_queue_c.get_nowait()
    except Queue.Empty:
        pass
    return future


def get_local_address():
    return socket.gethostbyname(socket.gethostname())


def start_socket():
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind(('', 1337))
    server.listen(5)
    return server


def connect_to_server(ip):
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.connect((ip, 1337))
    return server


class wait_for_client(Thread):
    def __init__(self, server):
        Thread.__init__(self)
        self.server = server

    def run(self):
        client, infos_client = self.server.accept()
        r_queue_s.put([client, infos_client])


class receive_datas(Thread):
    def __init__(self, client, role):
        Thread.__init__(self)
        self.client = client
        self.role = role

    def run(self):
        while 1:
            datas = self.client.recv(1024)
            if len(datas) > 0:
                if self.role == 'server':
                    r_queue_s.put(datas)
                elif self.role == 'client':
                    r_queue_c.put(datas)
            time.sleep(0.001)


class send_datas(Thread):
    def __init__(self, client, role):
        Thread.__init__(self)
        self.client = client
        self.role = role

    def run(self):
        while 1:
            datas = None
            try:
                if self.role == 'server':
                    datas = s_queue_s.get_nowait()
                elif self.role == 'client':
                    datas = s_queue_c.get_nowait()
            except Queue.Empty:
                pass
            if datas is not None:
                self.client.send(datas)
            time.sleep(0.001)


def send(role, dts):
    if role == 'client':
        s_queue_c.put_nowait(dts)
    elif role == 'server':
        s_queue_s.put_nowait(dts)


def check_move():
    i = False

    for p in palets:
        if p.moving == True:
            i = True

    return i


def check_space(palet, palets):
    min = 9999999
    for p in palets:
        dist = distance(palet.x, palet.y, p.x, p.y)
        if dist < min and p != palet:
            min = dist

    if min > palet.radius * 4:
        return True
    else:
        return False


def maxPower(x, y, mouse_pos, circle_radius):
    d_x = 0
    d_y = 0
    m_x = mouse_pos[0]
    m_y = mouse_pos[1]
    scalaire = 0
    cos = 0
    angle = 0
    dist = distance(x, y, m_x, m_y)

    v = [m_x - x, m_y - y]

    scalaire = 50 * v[1]

    if dist == 0:
        dist = 0.0000001

    cos = scalaire / (50 * dist)

    angle = math.acos(cos)
    d_x = circle_radius * math.sin(angle)
    if m_x < x:
        d_x = -d_x

    scalaire = 50 * v[0]

    cos = scalaire / (50 * dist)

    angle = math.acos(cos)
    d_y = circle_radius * math.sin(angle)
    if m_y < y:
        d_y = -d_y

    return x + d_x, y + d_y


def init_game():
    global palets

    palets = []

    for i in range(palets_count):
        if i < 5:
            team = -1
        else:
            team = 1
        palets.append(Palet((positions[i][0], positions[i][1]), 20.5, 5, team, 'palet', 0.994, i))

    palets.append(Palet((ball_start[0], ball_start[1]), 16.5, 1, 0, 'ball', 0.990, -1))


class Jeu_reseau():

    def start(self, role):

        selected = None
        select = False
        draw_vector = False
        draw_circle = False
        played = False
        old_played = False
        e = 0

        global palets
        global chrono
        global buts
        global times
        global time_start
        global time_end
        global a
        global click

        init_game()

        while True:

            dt = clock.tick(100)

            if a == 1:
                chrono.add_millisecond(dt)

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()
                elif event.type == pygame.MOUSEBUTTONDOWN:
                    click = True
                elif event.type == pygame.MOUSEBUTTONUP:
                    click = False


            future = get_datas(role)
            to_read = False
            if future is not None:
                try:
                    datas = json.loads(future)
                    self.current_team = datas['team']
                    to_read = True
                except ValueError:
                    pass

            screen.blit(bg, (0, 0))


            mouse_pos = pygame.mouse.get_pos()

            if self.team == self.current_team:

                for palet in palets:

                    palet.move(palets)
                    old_played = played
                    played = check_move()

                    if distance(palet.x, palet.y, mouse_pos[0],
                                mouse_pos[1]) < palet.radius and palet.team == self.current_team and not played:
                        palet.inside = True

                    select = False

                    for p in palets:
                        if p.selected:
                            select = True

                    if palet.moving == False and palet.inside == True and click == True and select == False:
                        palet.temp = True
                        palet.selected = True
                        palet.circle_radius = int(distance(palet.x, palet.y, mouse_pos[0], mouse_pos[1]))
                        if palet.circle_radius > 5 * palet.radius:
                            palet.circle_radius = 5 * palet.radius
                        if palet.circle_radius > palet.radius:
                            draw_circle = True
                        x, y = maxPower(palet.x, palet.y, mouse_pos, palet.circle_radius)

                    elif palet.temp and pygame.mouse.get_pressed()[0] == 0:
                        if palet.circle_radius > palet.radius:
                            dx = palet.x - x
                            dy = palet.y - y
                            palet.angle = 0.5 * math.pi + math.atan2(dy, dx)
                            palet.speed = math.hypot(dx, dy) / 10
                            #old_played=played
                            played = True
                            if a == 0:
                                chrono = Chrono(0, 0, 0)
                                time_start = time.time()
                                a = 1
                        else:
                            pass
                        palet.temp = False
                        palet.inside = False
                        palet.circle_radius = 0
                    else:
                        palet.circle_radius = 0
                        palet.temp = False
                        palet.inside = False
                    if palet.circle_radius > palet.radius:
                        draw_vector = True
                    if palet.type == 'palet':
                        if palet.team == -1:
                            palet.draw(screen, palet_r)
                        else:
                            palet.draw(screen, palet_b)
                    else:
                        palet.draw(screen, ball)

                    if palet.selected:
                        selected = palet

                    if not played and palet.speed == 0 and palet.type == 'palet':

                        if palet.x - palet.radius < terrain_size[0][0]:
                            palet.x = terrain_size[0][0] + palet.radius + 50

                            i = 0
                            while not check_space(palet, palets):
                                if i < len(modif_pos):
                                    palet.y += modif_pos[i]
                                    i += 1
                                else:
                                    break

                        elif palet.x + palet.radius > terrain_size[0][1]:
                            palet.x = terrain_size[0][1] - palet.radius - 50

                            i = 0
                            while not check_space(palet, palets):
                                if i < len(modif_pos):
                                    palet.y += modif_pos[i]
                                    i += 1
                                else:
                                    break

                    if draw_vector:
                        selected.drawVector(screen, x, y)
                        draw_vector = False
                    if draw_circle:
                        selected.drawCircle(screen)
                        draw_circle = False
                    if selected:
                        if palet.type == 'palet':
                            if palet.team == -1:
                                palet.draw(screen, palet_r)
                            else:
                                palet.draw(screen, palet_b)
                        else:
                            palet.draw(screen, ball)

                    if old_played == True and played == False:
                        e += 1

                    if e == 2:
                        print 'zzzz'
                        self.current_team *= -1
                        e = 0


                    # if datas.but == -1:
                    #     buts[0] += 1
                    #     datas.but = 0
                    #     Jeu_local().start([1], False, names, solo)
                    # elif datas.but == 1:
                    #     buts[1] += 1
                    #     datas.but = 0
                    #     Jeu_local().start([-1], False, names, solo)

                    duration = chrono.__str__()

                    # if solo:
                    #     zTextDraw(screen, "Rouges " + str(buts[0]) + "  \n  " + str(buts[1]) + " Bleus", 50, (400, 50), None,
                    #               BLACK)
                    # else:
                    #     zTextDraw(screen, names[0] + " " + str(buts[0]) + "  \n  " + str(buts[1]) + " " + names[1], 50,
                    #               (400, 50), None, BLACK)
                    #
                    # if a == 0:
                    #     zTextDraw(screen, "00:00", 30, (536, 100), None, BLACK)
                    # else:
                    #     zTextDraw(screen, duration, 30, (536, 100), None, BLACK)
                    #

                    if palet.id == -1:
                        print palet.x, palet.y
                    to_send = {}
                    to_send['team'] = self.current_team
                    to_send['palet'] = {}
                    to_send['palet']['id'] = palet.id
                    to_send['palet']['x'] = palet.x
                    to_send['palet']['y'] = palet.y

                    send(role, json.dumps(to_send))
                    #print json.dumps(to_send)
                    #
                    # if buts[0] >= 2 or buts[1] >= 2:
                    #     times = [duration.split(":")[0], duration.split(":")[1]]
                    #     time_end = time.time()
                    #     if not solo:
                    #         save_scores(names[0], names[1], buts[0] - buts[1], buts[0], buts[1], time_end,
                    #                     time_end - time_start)
                        #     show_end_screen(names, solo)
            else:
                for palet in palets:
                    if to_read:
                        if palet.id == datas['palet']['id']:
                            palet.x = datas['palet']['x']
                            palet.y = datas['palet']['y']
                            #print palet.id, palet.x, palet.y
                            if palet.id == -1:
                                print palet.x, palet.y



                    if palet.type == 'palet':
                            if palet.team == -1:
                                palet.draw(screen, palet_r)
                            else:
                                palet.draw(screen, palet_b)
                    else:
                        palet.draw(screen, ball)

            pygame.display.flip()


    def init_server(self, name):
        print 'server'
        self.team = -1
        self.names = []
        self.names.append(name)
        self.local_socket = start_socket()
        self.local_socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
        a = wait_for_client(self.local_socket)
        a.start()

        local_ip = get_local_address()

        screen.fill((255, 255, 255))

        zTextDraw(screen, "En attente d'un joueur. " + local_ip, 50, (50, 50), None, BLACK)
        pygame.display.flip()

        future = None
        while future is None:
            time.sleep(0.001)
            events()
            future = get_datas('server')
        self.distant_socket, self.distant_socket_infos = future
        self.distant_socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
        a._Thread__stop()

        b = receive_datas(self.distant_socket, 'server')
        b.start()
        c = send_datas(self.distant_socket, 'server')
        c.start()

        future = None
        while future is None:
            time.sleep(0.001)
            events()
            future = get_datas('server')
        self.names.append(future)

        s_queue_s.put(self.names[0] + ',' + self.names[1])

        screen.fill((255, 255, 255))
        zTextDraw(screen, "Vous jouez avec " + self.names[1], 50, (50, 50), None, BLACK)

        pygame.display.flip()

        self.current_team = random.choice([-1, 1])
        s_queue_s.put(json.dumps(self.current_team))
        print self.current_team

        self.start('server')

    def init_client(self, server_ip, name):
        print 'client'
        self.team = 1
        self.distant_socket = connect_to_server(server_ip)
        a = receive_datas(self.distant_socket, 'client')
        a.start()
        b = send_datas(self.distant_socket, 'client')
        b.start()

        s_queue_c.put(name)

        future = None
        while future is None:
            time.sleep(0.001)
            events()
            future = get_datas('client')
        self.names = future.split(',')
        future = None
        while future is None:
            time.sleep(0.001)
            events()
            future = get_datas('client')
        self.current_team = json.loads(future)
        print self.current_team

        screen.fill((255, 255, 255))
        zTextDraw(screen, "Vous jouez avec " + self.names[0], 50, (50, 50), None, BLACK)

        pygame.display.flip()

        self.start('client')   

0 个答案:

没有答案