0

I am creating a 2d game where the camera follows the player. The problem occurs when a new player joins his position is not changed in the client side. The player's position is sent to the server, but as the player's position does not change, only the environment around him, and he remains in place, how can I change the position of the client and send it to the other client where it will be displayed. I'm doing this for an infinite number of players, so I need to use a "FOR" loop. And how in the "FOR" loop can I change player two, which is also the environment.

Server:

import socket, pickle, time, _thread, threading

#########################################
data = {
    "id": [],
    "coordinates": []
}
#########################################
s = socket.socket()
s.bind(("0.0.0.0", 25565))
s.listen()
#########################################
def new_client(client,addr):
    global data
    while True:
        try:
            client.send(pickle.dumps(data))
            data = pickle.loads(client.recv(1024000))
        except:
            index = data["id"].index(addr[1])
            data["coordinates"].remove(data["coordinates"][index])
            data["id"].remove(addr[1])
            print(f"Player {addr[1]} left.")
            break
        time.sleep(0.016)
#########################################
def petla_print():
    while True:
        if () not in data["coordinates"]:
            data["coordinates"].append(())
        print(data)

_thread.start_new_thread(petla_print, ())
#########################################
print("Server running.")
while True:
    conn, addr = s.accept()
    data["id"].append(addr[1])
    _thread.start_new_thread(new_client,(conn,addr))

client:

import socket, threading, time, pickle, re
import sys, pygame

#######################################
player_ids_except_me = []
player_coords_except_me = []
fps = 60
#########################################
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((1280, 720))

floor_x = 0
floor_y = 600
direction = None

floor = pygame.Rect(floor_x, floor_y, 900, 100)
player = pygame.Rect(500, 500, 100, 100)
#########################################
def draw():
    global floor, player, a, cam_poz_y, cam_poz_x
    screen.fill((0, 0, 0))
    floor = pygame.draw.rect(screen, (0, 255, 0), floor)
    player = pygame.draw.rect(screen, (255, 255, 255), player)
    floor = pygame.Rect(floor_x, floor_y, 900, 100)
    player = pygame.Rect(500, 500, 100, 100)

    cam_poz_x = ((floor_x)*(-1))+500
    cam_poz_y = (floor_y-1090)*(-1)
    for i in range(len(player_ids_except_me)):
        a_pos = pygame.Rect(player_coords_except_me[i][0], player_coords_except_me[i][1], 100, 100)
        a = pygame.draw.rect(screen, (255, 0, 0), a_pos)

    pygame.display.update()

def hit(obj1, obj2):
    x_obj1 = obj1.x
    y_obj1 = obj1.y
    height_obj1 = obj1.height
    width_obj1 = obj1.width
    x_obj2 = obj2.x
    y_obj2 = obj2.y
    height_obj2 = obj2.height
    width_obj2 = obj2.width
    if y_obj1+height_obj1 > y_obj2 and x_obj1 > x_obj2-width_obj1 and x_obj1 < x_obj2+width_obj2 and y_obj1 < y_obj2+height_obj1:
        touching = True
        return touching
    else:
        touching = False
        return touching
#######################################
client_socket = socket.socket()
client_socket.connect(('192.168.0.62', 25565))

client_id = str(client_socket).split(" ")
client_id = int(client_id[6].replace(")", "").replace(",", ""))

#########################################
while True:
    data = pickle.loads(client_socket.recv(1024000))
    clock.tick(fps)
    for event in pygame.event.get():
        if event.type == pygame.QUIT: sys.exit()

    keys = pygame.key.get_pressed()
    if keys[pygame.K_w]:
        floor_y += 20
    if keys[pygame.K_a]:
        floor_x += 10
    if keys[pygame.K_d]:
        floor_x -= 10
        

    floor_y -= 10
    

    if hit(player, floor) == True:
        floor_y += 10

    draw()


    try:
        index = data["id"].index(client_id)
        data["coordinates"][index] = (cam_poz_x, cam_poz_y)
    except:
        pass

    client_socket.send(pickle.dumps(data))

    try:
        player_ids_except_me = data["id"]
        player_ids_except_me.remove(client_id)
        player_coords_except_me = data["coordinates"]
        player_coords_except_me.remove((cam_poz_x, cam_poz_y)).remove(())
    except:
        pass

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
PawełeK
  • 33
  • 6
  • It's difficult to know what exactly is not working as you haven't really done a great job of letting us know what you expect. I can say that what you're doing with `client_socket.send(pickle.dumps(data))` and `data = pickle.loads(client.recv(1024000))` will *not* work reliably. With TCP, there's no guarantee that all your data will be sent or received in a single call. You need to specify exactly how many bytes are being sent (and use `sendall` to ensure they are sent) and how many are to be received and use loop to ensure you've gotten them all. See https://stackoverflow.com/a/9563694/1076479 – Gil Hamilton Feb 13 '23 at 18:25
  • Im reciving and sending data properly. The problem is that i dont know how i can change position of player created in for loop. – PawełeK Feb 14 '23 at 09:46
  • I mean this fragment of code: ` for i in range(len(player_ids_except_me)): a_pos = pygame.Rect(player_coords_except_me[i][0], player_coords_except_me[i][1], 100, 100) a = pygame.draw.rect(screen, (255, 0, 0), a_pos) ` – PawełeK Feb 14 '23 at 20:10
  • Not trying to be rude, but you're definitely *not* sending and receiving properly. And how would you even know? You're not checking to see whether you sent what you intended, or that you got the data you expected. It might work a few times, but once you have multiple players sending updates frequently, this will definitely break. I suppose you can wait until you start getting exceptions from `pickle` to worry about that. – Gil Hamilton Feb 14 '23 at 23:48
  • As for what's happening, I see no update to all the clients. I see the server receiving from a client, updating its global state and only sending that state back to the same client. If client 1 moved, don't you also need to tell clients 2 and 3 that client 1 moved? – Gil Hamilton Feb 14 '23 at 23:50
  • Would be helpful to add some print statements in both client and server. If you track exactly what you're doing at each step, you will be able to see where things break down. That can involve a lot of verbose output, but definitely works (people debug kernel drivers this way). Client: "my `data` is this". "Updated my `data`; "sending my `data` to server". Server: "my `data` is this", "got `data` from client A", "updated client A's state to `data`", "sending `data` to client A". (Welcome to the fun of debugging!) – Gil Hamilton Feb 14 '23 at 23:57

0 Answers0