【问题标题】:Stream pygame joystick input over socket by sending joystick values to array通过将操纵杆值发送到数组来通过套接字流式传输 pygame 操纵杆输入
【发布时间】:2021-07-29 09:37:06
【问题描述】:

我正在尝试构建一个机器人,它将通过在 python 中使用套接字和操纵杆来控制。我一直在尝试将 Pygame 的示例代码中的操纵杆读数发送到一个数组中,但是当我打印数组时,我在移动轴并按下按钮后得到了空白值。这些值出现在数组之外,但显然没有存储在数组中。下面的代码将在用于向机器人传输命令的计算机上运行。我已经引用了会导致看不到服务器错误的行。请帮我弄清楚为什么我不能从操纵杆中获取读数到一个数组中,并请发布代码 sn-ps,而不仅仅是单词描述。

import socket      #send data between server and client
import os          #gain control of command prompt features
import keyboard    #read keystrokes
import pygame       #Read Joystick data


os.system('title client')  #rename command prompt
os.system('cls')           #clear command prompt screen

# client = socket.socket()   #constructor

# hostname = '127.0.0.1'  #server ip

# port = 8080   #server open communication port

# client.connect((hostname,port))  #create connection



# Define some colors.
BLACK = pygame.Color('black')
WHITE = pygame.Color('white')


# This is a simple class that will help us print to the screen.
# It has nothing to do with the joysticks, just outputting the
# information.
class TextPrint(object):
    def __init__(self):
        self.reset()
        self.font = pygame.font.Font(None, 20)

    def tprint(self, screen, textString):
        textBitmap = self.font.render(textString, True, BLACK)
        screen.blit(textBitmap, (self.x, self.y))
        self.y += self.line_height

    def reset(self):
        self.x = 10
        self.y = 10
        self.line_height = 15

    def indent(self):
        self.x += 10

    def unindent(self):
        self.x -= 10


pygame.init()

# Set the width and height of the screen (width, height).
screen = pygame.display.set_mode((500, 700))

pygame.display.set_caption("My Game")

# Loop until the user clicks the close button.
done = False

# Used to manage how fast the screen updates.
clock = pygame.time.Clock()

# Initialize the joysticks.
pygame.joystick.init()

# Get ready to print.
textPrint = TextPrint()

message = []

# -------- Main Program Loop -----------
while not done:
    #
    # EVENT PROCESSING STEP
    #
    # Possible joystick actions: JOYAXISMOTION, JOYBALLMOTION, JOYBUTTONDOWN,
    # JOYBUTTONUP, JOYHATMOTION
    for event in pygame.event.get(): # User did something.
        if event.type == pygame.QUIT: # If user clicked close.
            done = True # Flag that we are done so we exit this loop.
        elif event.type == pygame.JOYBUTTONDOWN:
            print("Joystick button pressed.")
        elif event.type == pygame.JOYBUTTONUP:
            print("Joystick button released.")

    #
    # DRAWING STEP
    #
    # First, clear the screen to white. Don't put other drawing commands
    # above this, or they will be erased with this command.
    screen.fill(WHITE)
    textPrint.reset()

    # Get count of joysticks.
    joystick_count = pygame.joystick.get_count()

    textPrint.tprint(screen, "Number of joysticks: {}".format(joystick_count))
    textPrint.indent()

    # For each joystick:
    for i in range(joystick_count):
        joystick = pygame.joystick.Joystick(i)
        joystick.init()

        try:
            jid = joystick.get_instance_id()
        except AttributeError:
            # get_instance_id() is an SDL2 method
            jid = joystick.get_id()
        textPrint.tprint(screen, "Joystick {}".format(jid))
        textPrint.indent()

        # Get the name from the OS for the controller/joystick.
        name = joystick.get_name()
        textPrint.tprint(screen, "Joystick name: {}".format(name))

        # try:
        #     guid = joystick.get_guid()
        # except AttributeError:
        #     # get_guid() is an SDL2 method
        #     pass
        # else:
        #     textPrint.tprint(screen, "GUID: {}".format(guid))

        # Usually axis run in pairs, up/down for one, and left/right for
        # the other.
        axes = joystick.get_numaxes()
        textPrint.tprint(screen, "Number of axes: {}".format(axes))
        textPrint.indent()

        for i in range(axes):
            axis = joystick.get_axis(i)
            textPrint.tprint(screen, "Axis {} value: {:>6.3f}".format(i, axis))
            message.append(joystick.get_axis(i))
        textPrint.unindent()

        buttons = joystick.get_numbuttons()
        textPrint.tprint(screen, "Number of buttons: {}".format(buttons))
        textPrint.indent()

        for i in range(buttons):
            button = joystick.get_button(i)
            textPrint.tprint(screen, "Button {:>2} value: {}".format(i, button))
            message.append(button)
        textPrint.unindent()

        hats = joystick.get_numhats()
        textPrint.tprint(screen, "Number of hats: {}".format(hats))
        textPrint.indent()

        # Hat position. All or nothing for direction, not a float like
        # get_axis(). Position is a tuple of int values (x, y).
        for i in range(hats):
            hat = joystick.get_hat(i)
            textPrint.tprint(screen, "Hat {} value: {}".format(i, str(hat)))
        textPrint.unindent()

        textPrint.unindent()

        
        #Display values recorded in array
        for i in message:
        value = message[int(i)]
        textPrint.tprint(screen,"values: {}".format(value))

    #
    # ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT
    #

    # Go ahead and update the screen with what we've drawn.
    pygame.display.flip()

    # Limit to 20 frames per second.
    clock.tick(20)

# Close the window and quit.
# If you forget this line, the program will 'hang'
# on exit if running from IDLE.
pygame.quit()




    # Send to server
    # x = keyboard.read_key()  #read key on keyboard
    # client.send(x.encode())  #send recorded key to server
    # print("You Pressed ", x) #print on client screen the key they pressed 

【问题讨论】:

    标签: python arrays sockets pygame


    【解决方案1】:

    问题解决了!问题是由于“消息”数组不断添加到自身而导致的无限循环,因为它在循环之外。通过在“while not done:”循环中声明数组,它会自行擦除并在需要的地方添加值。代码现在可以工作了。现在我唯一担心的是值“hat”不会引起问题,因为它返回 2 个值而不是 1 个。我会将这个案例标记为已解决!固定代码如下,以防有人想知道我到目前为止的位置!

    import socket      #send data between server and client
    import os          #gain control of command prompt features
    import keyboard    #read keystrokes
    import pygame       #Read Joystick data
    import array
    
    
    os.system('title client')  #rename command prompt
    os.system('cls')           #clear command prompt screen
    
    # client = socket.socket()   #constructor
    
    # hostname = '127.0.0.1'  #server ip
    
    # port = 8080   #server open communication port
    
    # client.connect((hostname,port))  #create connection
    
    
    
    # Define some colors.
    BLACK = pygame.Color('black')
    WHITE = pygame.Color('white')
    
    
    # This is a simple class that will help us print to the screen.
    # It has nothing to do with the joysticks, just outputting the
    # information.
    class TextPrint(object):
        def __init__(self):
            self.reset()
            self.font = pygame.font.Font(None, 20)
    
        def tprint(self, screen, textString):
            textBitmap = self.font.render(textString, True, BLACK)
            screen.blit(textBitmap, (self.x, self.y))
            self.y += self.line_height
    
        def reset(self):
            self.x = 10
            self.y = 10
            self.line_height = 15
    
        def indent(self):
            self.x += 10
    
        def unindent(self):
            self.x -= 10
    
    
    pygame.init()
    
    # Set the width and height of the screen (width, height).
    screen = pygame.display.set_mode((500, 700))
    
    pygame.display.set_caption("My Game")
    
    # Loop until the user clicks the close button.
    done = False
    
    # Used to manage how fast the screen updates.
    clock = pygame.time.Clock()
    
    # Initialize the joysticks.
    pygame.joystick.init()
    
    # Get ready to print.
    textPrint = TextPrint()
    
    #message = array.array('d',[])
    
    # -------- Main Program Loop -----------
    while not done:
        
    
    
    
        #clear message
        message = array.array('d',[])
        #
        # EVENT PROCESSING STEP
        #
        # Possible joystick actions: JOYAXISMOTION, JOYBALLMOTION, JOYBUTTONDOWN,
        # JOYBUTTONUP, JOYHATMOTION
        for event in pygame.event.get(): # User did something.
            if event.type == pygame.QUIT: # If user clicked close.
                done = True # Flag that we are done so we exit this loop.
            elif event.type == pygame.JOYBUTTONDOWN:
                print("Joystick button pressed.")
            elif event.type == pygame.JOYBUTTONUP:
                print("Joystick button released.")
    
        #
        # DRAWING STEP
        #
        # First, clear the screen to white. Don't put other drawing commands
        # above this, or they will be erased with this command.
        screen.fill(WHITE)
        textPrint.reset()
    
        # Get count of joysticks.
        joystick_count = pygame.joystick.get_count()
    
        textPrint.tprint(screen, "Number of joysticks: {}".format(joystick_count))
        textPrint.indent()
    
        # For each joystick:
        for i in range(joystick_count):
            joystick = pygame.joystick.Joystick(i)
            joystick.init()
    
            try:
                jid = joystick.get_instance_id()
            except AttributeError:
                # get_instance_id() is an SDL2 method
                jid = joystick.get_id()
            textPrint.tprint(screen, "Joystick {}".format(jid))
            textPrint.indent()
    
            # Get the name from the OS for the controller/joystick.
            name = joystick.get_name()
            textPrint.tprint(screen, "Joystick name: {}".format(name))
    
            # try:
            #     guid = joystick.get_guid()
            # except AttributeError:
            #     # get_guid() is an SDL2 method
            #     pass
            # else:
            #     textPrint.tprint(screen, "GUID: {}".format(guid))
    
            # Usually axis run in pairs, up/down for one, and left/right for
            # the other.
            axes = joystick.get_numaxes()
            textPrint.tprint(screen, "Number of axes: {}".format(axes))
            textPrint.indent()
    
            for i in range(axes):
                axis = joystick.get_axis(i)
                textPrint.tprint(screen, "Axis {} value: {:>6.3f}".format(i, axis))
                message.append(joystick.get_axis(i))
            textPrint.unindent()
    
            buttons = joystick.get_numbuttons()
            textPrint.tprint(screen, "Number of buttons: {}".format(buttons))
            textPrint.indent()
    
            for i in range(buttons):
                button = joystick.get_button(i)
                textPrint.tprint(screen, "Button {:>2} value: {}".format(i, button))
                message.append(button)
            textPrint.unindent()
    
            hats = joystick.get_numhats()
            textPrint.tprint(screen, "Number of hats: {}".format(hats))
            textPrint.indent()
    
            # Hat position. All or nothing for direction, not a float like
            # get_axis(). Position is a tuple of int values (x, y).
            for i in range(hats):
                hat = joystick.get_hat(i)
                textPrint.tprint(screen, "Hat {} value: {}".format(i, str(hat)))
            textPrint.unindent()
    
            textPrint.unindent()
    
            i = range(len(message))
    
            textPrint.tprint(screen, "array length {}".format(i))
    
    
            for i in range(len(message)):
                value = message[int(i)]
                textPrint.tprint(screen, "value {}: {}".format(i, value))
    
        #
        # ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT
        #
    
        # Go ahead and update the screen with what we've drawn.
        pygame.display.flip()
    
        # Limit to 20 frames per second.
        clock.tick(20)
    
    # Close the window and quit.
    # If you forget this line, the program will 'hang'
    # on exit if running from IDLE.
    pygame.quit()
    
    
    
    
        # Send to server
        # x = keyboard.read_key()  #read key on keyboard
        # client.send(x.encode())  #send recorded key to server
        # print("You Pressed ", x) #print on client screen the key they pressed
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多