我构建了一个简单的头部足球游戏,我想将其转换为多人游戏(每个客户端将控制一个玩家)。
我试图使用客户端服务器方法添加它不起作用。
这里是原始游戏代码:
import pygame
from player import Player
from ball import Ball
# Add this function to handle player animations
def game_win ():
# Draw the players
# Draw the ball
screen.blit(ball.image, ball.position)
# Draw the goals
screen.blit(goal1, goal1_pos)
screen.blit(goal2, goal2_pos)
# Display the score
scoreR_text = font.render("Score: " + str(scoreR), 1, (255, 255, 255))
scoreL_text = font.render("Score: " + str(scoreL), 1, (255, 255, 255))
screen.blit(scoreR_text, (650, 10))
screen.blit(scoreL_text, (100, 10))
# Display the time remaining
time_text = font.render("Time: " + str(time_remaining), 1, (255, 255, 255))
screen.blit(time_text, (350, 10))
# Add this function to handle player animations
def animate_player(player, player_pos, keys, animation_frames):
if keys[pygame.K_SPACE] or keys[pygame.K_m]:
frame = (pygame.time.get_ticks() // 100) % len(animation_frames)
return animation_frames[frame], player_pos
return player, player_pos
def is_close_to_ball(player_pos, ball_pos, threshold=50):
distance = ((player_pos[0] - ball.position[0])**2 + (player_pos[1] - ball.position[1])**2)**0.5
return distance <= threshold
def initialize_game(screen_size):
'''
'''
# Set the screen size
screen = pygame.display.set_mode(screen_size)
# Load the background image
background = pygame.image.load("background.png").convert()
background = pygame.transform.scale(background, screen_size)
# Load the player images
playerR = pygame.image.load("playerR1.png").convert_alpha()
playerL = pygame.image.load("playerL1.png").convert_alpha()
# Load the ball image
ball = pygame.image.load("ball.png").convert_alpha()
# Load the goal images
goal1 = pygame.image.load("trave1.gif").convert_alpha()
goal2 = pygame.image.load("trave2.gif").convert_alpha()
# Load the animation images
playerR1 = pygame.image.load("playerR2.png").convert_alpha()
playerL1 = pygame.image.load("playerL2.png").convert_alpha()
playerR2 = pygame.image.load("playerR3.png").convert_alpha()
playerL2 = pygame.image.load("playerL3.png").convert_alpha()
playerR = pygame.transform.scale(playerR, (100, 100))
playerL = pygame.transform.scale(playerL, (100, 100))
playerR1 = pygame.transform.scale(playerR1, (100, 100))
playerL1 = pygame.transform.scale(playerL1, (100, 100))
playerR2 = pygame.transform.scale(playerR2, (100, 100))
playerL2 = pygame.transform.scale(playerL2, (100, 100))
ball = pygame.transform.scale(ball, (40, 40))
return screen, background, playerR, playerL, ball, goal1, goal2, playerR1, playerL1, playerR2, playerL2
def Updates_players_location():
playerR.update()
playerL.update()
def bounce_ball_off_screen_edges():
# Bounce the ball off the left and right edges
if ball.position[0] < 0 or ball.position[0] + ball.image.get_width() > screen.get_width():
ball.velocity[0] = -ball.velocity[0]
# Bounce the ball off the top edge
if ball.position[1] <= 0:
ball.position[1] = 0
# Bounce the ball off the bottom edge
if ball.position[1] >= 600 - ball.image.get_height():
if ball.velocity[1] >= 1:
ball.velocity[1] = -ball.velocity[1]
else:
ball.velocity[1] = 0
ball.position[1] = 600 - ball.image.get_height()
# Initialize Pygame
pygame.init()
# Set the screen size
screen_size = (800, 600)
screen, background, playerR, playerL, ball, goal1, goal2, playerR1, playerL1, playerR2, playerL2 = initialize_game(screen_size)
# Set the player positions
playerR = Player(playerR, [600, 500])
playerL = Player(playerL, [100, 500])
# Set the player rectangles
playerR.rect = pygame.Rect(playerR.position[0], playerR.position[1], playerR.image.get_width(), playerR.image.get_height())
playerL.rect = pygame.Rect(playerL.position[0], playerL.position[1], playerL.image.get_width(), playerL.image.get_height())
# Set the ball position
#ball_pos = [400, 300]
#ball.velocity = [5, 0]
# Set the ball rectangle
#ball.rect = pygame.Rect(ball.position[0], ball.position[1], ball.image.get_width(), ball.image.get_height())
ball = Ball(ball, [400, 300], [5, 0])
# Set the goal positions
goal1_pos = [0, 400]
goal2_pos = [700, 400]
# Set the score
scoreR = 0
scoreL = 0
font = pygame.font.Font(None, 36)
# Set the game loop to run
running = True
while running:
# Update player positions
playerR.speed = [0, 0]
playerL.speed = [0, 0]
ball.velocity = [0, 0]
# Handle events
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Handle keyboard inputs
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
playerR.position[0] -= 1
if keys[pygame.K_RIGHT]:
playerR.position[0] += 1
if keys[pygame.K_a]:
playerL.position[0] -= 1
if keys[pygame.K_d]:
playerL.position[0] += 1
if keys[pygame.K_UP]:
if playerR.position[1] >= 600 - playerR.image.get_height():
playerR.speed[1] -= 100
if keys[pygame.K_w]:
if playerL.position[1] >= 600 - playerL.image.get_height():
playerL.speed[1] -= 100
playerR.rect = pygame.Rect(playerR.position[0], playerR.position[1], playerR.image.get_width(), playerR.image.get_height())
playerL.rect = pygame.Rect(playerL.position[0], playerL.position[1], playerL.image.get_width(), playerL.image.get_height())
ball.rect = pygame.Rect(ball.position[0], ball.position[1], ball.image.get_width(), ball.image.get_height())
# Add kicking feature
# Add kicking feature
if keys[pygame.K_SPACE] and is_close_to_ball(playerR.position, ball.position):
kick_strength = 10
dx = ball.position[0] - playerR.position[0]
dy = ball.position[1] - playerR.position[1]
distance = ((dx ** 2) + (dy ** 2)) ** 0.5
ball.velocity[0] += kick_strength * dx / distance
ball.velocity[1] += kick_strength * dy / distance
if keys[pygame.K_m] and is_close_to_ball(playerL.position, ball.position):
kick_strength = 10
dx = ball.position[0] - playerL.position[0]
dy = ball.position[1] - playerL.position[1]
distance = ((dx ** 2) + (dy ** 2)) ** 0.5
ball.velocity[0] += kick_strength * dx / distance
ball.velocity[1] += kick_strength * dy / distance
ball.update()
Updates_players_location()
# Applying gravity
if playerL.position[1] <= 600 - playerL.image.get_height():
playerL.position[1] += 0.5
# Applying gravity
if playerR.position[1] <= 600 - playerR.image.get_height():
playerR.position[1] += 0.5
# Applying gravity
if ball.position[1] <= 600 - ball.image.get_height():
ball.velocity[1] += 0.5
if ball.velocity[1] > 0:
ball.velocity[1] -= 0.2
if ball.velocity[1] < 0:
ball.velocity[1] += 0.2
ball.position[1] += ball.velocity[1]
# Check for ball collision with players
playerR.rect = pygame.Rect(playerR.position[0], playerR.position[1], playerR.image.get_width(), playerR.image.get_height())
playerL.rect = pygame.Rect(playerL.position[0], playerL.position[1], playerL.image.get_width(), playerL.image.get_height())
ball.rect = pygame.Rect(ball.position[0], ball.position[1], ball.image.get_width(), ball.image.get_height())
# Check for player vs player collisions
if playerR.rect.colliderect(playerL.rect):
playerR.speed[0] = 0
playerL.speed[0] = 0
playerR.speed[1] = 0
playerL.speed[1] = 0
if playerR.rect.colliderect(ball.rect):
if ball.rect.centerx > playerR.rect.centerx:
ball.velocity[0] = -ball.velocity[0]
ball.velocity[0] += 5
if ball.rect.centerx < playerR.rect.centerx:
ball.velocity[0] = -ball.velocity[0]
ball.velocity[0] -= 5
if ball.rect.centery < playerR.rect.centery:
ball.velocity[1] = -ball.velocity[1]
ball.velocity[1] -= 5
if playerL.rect.colliderect(ball.rect):
if ball.rect.centerx > playerL.rect.centerx:
ball.velocity[0] = -ball.velocity[0]
ball.velocity[0] += 5
if ball.rect.centerx < playerL.rect.centerx:
ball.velocity[0] = -ball.velocity[0]
ball.velocity[0] -= 5
if ball.rect.centery < playerL.rect.centery:
ball.velocity[1] = -ball.velocity[1]
ball.velocity[1] -= 5
ball.update()
# Check for ball collision with goals
goal1_rect = pygame.Rect(goal1_pos[0], goal1_pos[1], goal1.get_width(), goal1.get_height())
goal2_rect = pygame.Rect(goal2_pos[0], goal2_pos[1], goal2.get_width(), goal2.get_height())
if goal1_rect.colliderect(ball.rect):
scoreR += 1
ball.position[0] = 400
ball.position[1] = 300
if goal2_rect.colliderect(ball.rect):
scoreL += 1
ball.position[0] = 400
ball.position[1] = 300
# Start the timer
timer = pygame.time.get_ticks()
time_limit = 60000 # 60 seconds in milliseconds
time_remaining = time_limit - (pygame.time.get_ticks() - timer)
# Convert time_remaining to seconds
time_remaining = time_remaining // 1000
# End the game if the time limit is reached
if time_remaining <= 0:
running = False
# Check for end of game
if not running:
game_over = font.render("Game Over", 1, (255, 255, 255))
screen.blit(game_over, (350, 300))
pygame.display.update()
pygame.time.wait(3000) # Wait for 3 seconds
break
if playerR.position[0] <= 0:
playerR.position[0] = 0
if playerR.position[0] >= 800 - playerR.image.get_width():
playerR.position[0] = 800 - playerR.image.get_width()
if playerR.position[1] <= 0:
playerR.position[1] = 0
if playerR.position[1] >= 600 - playerR.image.get_height():
playerR.position[1] = 600 - playerR.image.get_height()
if playerL.position[0] <= 0:
playerL.position[0] = 0
if playerL.position[0] >= 800 - playerL.image.get_width():
playerL.position[0] = 800 - playerL.image.get_width()
if playerL.position[1] <= 0:
playerL.position[1] = 0
if playerL.position[1] >= 600 - playerL.image.get_height():
playerL.position[1] = 600 - playerL.image.get_height()
bounce_ball_off_screen_edges()
# Clear the screen
screen.blit(background, (0, 0))
# Handle animations
playerR_frame, playerR_position = animate_player(playerR.image, playerR.position, keys, [playerR.image, playerR1, playerR2])
playerL_frame, playerL_position = animate_player(playerL.image, playerL.position, keys, [playerL.image, playerL1, playerL2])
screen.blit(playerR_frame, playerR_position)
screen.blit(playerL_frame, playerL_position)
game_win()
# Handle animations
# Handle animations
# Update the display
pygame.display.update()
# Quit Pygame
pygame.quit()
这里是课程: 玩家等级:
import pygame
class Player:
def __init__(self, image, position, speed=[0, 0]):
self.image = image
self.position = position
self.speed = speed
self.rect = pygame.Rect(self.position[0], self.position[1], 100, 100)
self.score = 0
def move(self, x, y):
self.position[0] += x
self.position[1] += y
self.rect.x = self.position[0]
self.rect.y = self.position[1]
def set_speed(self, x, y):
self.speed = [x, y]
def update(self):
self.move(self.speed[0], self.speed[1])
def draw(self, screen):
screen.blit(self.image, self.position)
def is_colliding(self, other_rect):
return self.rect.colliderect(other_rect)
# Method to set the player's score
def set_score(self, new_score):
self.score = new_score
# Method to increment the player's score
def increment_score(self, points=1):
self.score += points
这里是球类:
import pygame
class Ball:
def __init__(self, image, position, velocity):
self.image = image
self.position = position
self.velocity = velocity
self.rect = pygame.Rect(self.position[0], self.position[1], self.image.get_width(), self.image.get_height())
def update(self):
self.position[0] += self.velocity[0]
self.position[1] += self.velocity[1]
self.rect = pygame.Rect(self.position[0], self.position[1], self.image.get_width(), self.image.get_hei
这里是网络类:
import socket
import pickle
# Define a class called Network
class Network:
# Constructor method for the Network class
def __init__(self):
# Create a socket object (IPv4 and TCP protocol)
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Define the server's IP address and port number
self.server = "127.0.0.1"
self.port = 5555
# Create a tuple to store the server's address (IP, port)
self.addr = (self.server, self.port)
# Call the connect method and store the received data in self.p
self.p = self.connect()
# Method to get the value of self.p
def getP(self):
return self.p
# Method to receive data from the server
def receive(self):
try:
response = pickle.loads(self.client.recv(2048))
return response
except socket.error as e:
print(e)
# Method to connect to the server and receive data
def connect(self):
try:
# Connect to the server using its address
self.client.connect(self.addr)
# Receive 2048 bytes of data from the server and deserialize it using pickle
return pickle.loads(self.client.recv(2048))
except:
pass
def send(self, data1, data2):
try:
combined_data = (data1, data2)
self.client.send(pickle.dumps(combined_data))
combined_reply = pickle.loads(self.client.recv(2048))
reply1, reply2 = combined_reply # Unpack the two objects in the reply
return reply1, reply2
except socket.error as e:
print(e)
这里是服务器代码:
import socket
from _thread import *
from player import Player
import pickle
from ball import Ball
import pygame
server = "127.0.0.1"
port = 5555
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.bind((server, port))
except socket.error as e:
str(e)
s.listen(2)
print("Waiting for a connection, Server Started")
# Load the player images
ball_image = pygame.image.load("ball.png")
playerR1_image = pygame.image.load("playerR1.png")
playerL1_image = pygame.image.load("playerL1.png")
ball = Ball(ball_image, [400, 300], [5, 0])
players = [Player(playerR1_image, [600, 500]), Player(playerL1_image, [100, 500])]
def threaded_client(conn, player):
conn.send(pickle.dumps(players[player]))
reply = ""
while True:
try:
data_received = pickle.loads(conn.recv(2048))
if not data_received:
print("Disconnected")
break
else:
data1, data2 = data_received # Unpack the two objects
players[player] = data1
ball = data2
if player == 1:
reply1 = players[0]
reply2 = ball
else:
reply1 = players[1]
reply2 = ball
combined_reply = (reply1, reply2) # Combine the two objects in a tuple
print("Received: ", data_received)
print("Sending : ", combined_reply)
conn.sendall(pickle.dumps(combined_reply))
except:
break
print("Lost connection")
conn.close()
currentPlayer = 0
while True:
conn, addr = s.accept()
print("Connected to:", addr)
start_new_thread(threaded_client, (conn, currentPlayer))
currentPlayer += 1
这里是客户端代码:
import pygame
from network import Network
from player import Player
from ball import Ball
# Add this function to handle player animations
def animate_player(player, player_pos, keys, animation_frames):
if keys[pygame.K_SPACE] or keys[pygame.K_m]:
frame = (pygame.time.get_ticks() // 100) % len(animation_frames)
return animation_frames[frame], player_pos
return player, player_pos
def is_close_to_ball(player_pos, ball_pos, threshold=50):
distance = ((player_pos[0] - ball.position[0])**2 + (player_pos[1] - ball.position[1])**2)**0.5
return distance <= threshold
def Updates_players_location():
player1.update()
player2.update()
def bounce_ball_off_screen_edges():
# Bounce the ball off the left and right edges
if ball.position[0] < 0 or ball.position[0] + ball.image.get_width() > screen.get_width():
ball.velocity[0] = -ball.velocity[0]
# Bounce the ball off the top edge
if ball.position[1] <= 0:
ball.position[1] = 0
# Bounce the ball off the bottom edge
if ball.position[1] >= 600 - ball.image.get_height():
if ball.velocity[1] >= 1:
ball.velocity[1] = -ball.velocity[1]
else:
ball.velocity[1] = 0
ball.position[1] = 600 - ball.image.get_height()
def initialize_game(screen_size):
'''
This function initializes the game by setting up the screen, loading and scaling images for the background, players,
ball, goals, and player animations. The images are then returned as a tuple.
Args:
screen_size (tuple): A tuple containing the width and height of the game screen.
Returns:
tuple: A tuple containing the screen, background, player right, player left, ball, goal1, goal2, and player animation images.
'''
# Set the screen size
screen = pygame.display.set_mode(screen_size)
# Load the background image and scale it to the screen size
background = pygame.image.load("background.png").convert()
background = pygame.transform.scale(background, screen_size)
# Load the ball image
ball = pygame.image.load("ball.png").convert_alpha()
# Load the goal images
goal1 = pygame.image.load("trave1.gif").convert_alpha()
goal2 = pygame.image.load("trave2.gif").convert_alpha()
# Load the animation images
# Load the player images
player1 = pygame.image.load("playerR1.png").convert_alpha()
player2 = pygame.image.load("playerL1.png").convert_alpha()
player11 = pygame.image.load("playerR2.png").convert_alpha()
player21 = pygame.image.load("playerL2.png").convert_alpha()
player12 = pygame.image.load("playerR3.png").convert_alpha()
player22 = pygame.image.load("playerL3.png").convert_alpha()
player1 = pygame.transform.scale(player1, (100, 100))
player2 = pygame.transform.scale(player2, (100, 100))
player11 = pygame.transform.scale(player11, (100, 100))
player21 = pygame.transform.scale(player21, (100, 100))
player12 = pygame.transform.scale(player12, (100, 100))
player22 = pygame.transform.scale(player22, (100, 100))
# Scale the ball image
ball = pygame.transform.scale(ball, (40, 40))
# Return a tuple containing the screen, background, player images, ball, goals, and animation images
return screen, background,player1, player2, ball, goal1, goal2, player11, player21, player12, player22
def game_win ():
# Draw the players
# Draw the ball
screen.blit(ball.image, ball.position)
# Draw the goals
screen.blit(goal1, goal1_pos)
screen.blit(goal2, goal2_pos)
# Display the score
scoreR_text = font.render("Score: " + str(scoreR), 1, (255, 255, 255))
scoreL_text = font.render("Score: " + str(scoreL), 1, (255, 255, 255))
screen.blit(scoreR_text, (650, 10))
screen.blit(scoreL_text, (100, 10))
# Initialize pygame
pygame.init()
# Set the screen size
screen_size = (800, 600)
screen, background,player1, player2, ball, goal1, goal2, player11, player21, player12, player22 = initialize_game(screen_size)
# Set the goal positions
goal1_pos = [0, 400]
goal2_pos = [700, 400]
# Initialize scores for both players
scoreR = 0
scoreL = 0
# Create a font for displaying text (e.g., scores) on the screen
font = pygame.font.Font(None, 36)
# The game loop will start after this setup
def main():
running = True
while running:
n = Network()
player1 = n.getP()
clock = pygame.time.Clock()
clock.tick(60)
player2,ball = n.send(player1, ball)
ball = pygame.transform.scale(ball.image, (40, 40))
player1 = pygame.transform.scale(player1.image, (100, 100))
player2 = pygame.transform.scale(player2.image, (100, 100))
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
player1.speed = [0, 0]
ball.velocity = [0, 0]
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Handle keyboard inputs
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player1.position[0] -= 1
if keys[pygame.K_RIGHT]:
player1.position[0] += 1
if keys[pygame.K_UP]:
if player1.position[1] >= 600 - player1.image.get_height():
player1.speed[1] -= 100
player1.rect = pygame.Rect(player1.position[0], player1.position[1], player1.image.get_width(),
player1.image.get_height())
ball.rect = pygame.Rect(ball.position[0], ball.position[1], ball.image.get_width(), ball.image.get_height())
# Add kicking feature
if keys[pygame.K_SPACE] and is_close_to_ball(player1.position, ball.position):
kick_strength = 10
dx = ball.position[0] - player1.position[0]
dy = ball.position[1] - player1.position[1]
distance = ((dx ** 2) + (dy ** 2)) ** 0.5
ball.velocity[0] += kick_strength * dx / distance
ball.velocity[1] += kick_strength * dy / distance
ball.update()
Updates_players_location()
# Applying gravity
if player1.position[1] <= 600 - player1.image.get_height():
player1.position[1] += 0.5
if ball.position[1] <= 600 - ball.image.get_height():
ball.velocity[1] += 0.5
if ball.velocity[1] > 0:
ball.velocity[1] -= 0.2
if ball.velocity[1] < 0:
ball.velocity[1] += 0.2
ball.position[1] += ball.velocity[1]
player1.rect = pygame.Rect(player1.position[0], player1.position[1], player1.image.get_width(),
player1.image.get_height())
ball.rect = pygame.Rect(ball.position[0], ball.position[1], ball.image.get_width(), ball.image.get_height())
if player1.rect.colliderect(ball.rect):
if ball.rect.centerx > player1.rect.centerx:
ball.velocity[0] = -ball.velocity[0]
ball.velocity[0] += 5
if ball.rect.centerx < player1.rect.centerx:
ball.velocity[0] = -ball.velocity[0]
ball.velocity[0] -= 5
if ball.rect.centery < player1.rect.centery:
ball.velocity[1] = -ball.velocity[1]
ball.velocity[1] -= 5
ball.update()
goal1_rect = pygame.Rect(goal1_pos[0], goal1_pos[1], goal1.get_width(), goal1.get_height())
goal2_rect = pygame.Rect(goal2_pos[0], goal2_pos[1], goal2.get_width(), goal2.get_height())
if goal1_rect.colliderect(ball.rect):
player1.increment_score()
ball.position[0] = 400
ball.position[1] = 300
if goal2_rect.colliderect(ball.rect):
player1.increment_score()
ball.position[0] = 400
ball.position[1] = 300
timer = pygame.time.get_ticks()
time_limit = 60000
time_remaining = time_limit - (pygame.time.get_ticks() - timer)
# Convert time_remaining to seconds
time_remaining = time_remaining // 1000
# End the game if the time limit is reached
if time_remaining <= 0:
running = False
# Check for end of game
if not running:
game_over = font.render("Game Over", 1, (255, 255, 255))
screen.blit(game_over, (350, 300))
pygame.display.update()
pygame.time.wait(3000) # Wait for 3 seconds
break
if player1.position[0] <= 0:
player1.position[0] = 0
if player1.position[0] >= 800 - player1.image.get_width():
player1.position[0] = 800 - player1.image.get_width()
if player1.position[1] <= 0:
player1.position[1] = 0
if player1.position[1] >= 600 - player1.image.get_height():
player1.position[1] = 600 - player1.image.get_height()
bounce_ball_off_screen_edges()
# Clear the screen
screen.blit(background, (0, 0))
# Redraw the game window with the updated player positions
# Handle animations
player1_frame, player1_position = animate_player(player1.image, player1.position, keys,
[player1.image, player11, player12])
#screen.blit(player1_frame, player1_position)
#screen.blit(player2_frame, player2_position)
game_win ()
pygame.display.update()
main()