python
复制代码
import pygame
import socket
import json
import threading
class GameClient:
def __init__(self):
pygame.init()
self.screen_width = 600 # 宽度减小
self.screen_height = 800 # 高度增加
self.screen = pygame.display.set_mode((self.screen_width, self.screen_height))
pygame.display.set_caption("竖版飞机大战")
self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.server_address = ('localhost', 5555)
self.player_id = None
self.game_state = {
'players': {},
'bullets': [],
'enemies': []
}
self.input_state = {
'up': False,
'down': False,
'left': False,
'right': False,
'shoot': False
}
# 连接服务器
self.connect_to_server()
self.running = True
# 启动接收线程
threading.Thread(target=self.receive_data).start()
# 游戏主循环
self.clock = pygame.time.Clock()
self.game_loop()
def connect_to_server(self):
join_message = {'type': 'join'}
self.client_socket.sendto(json.dumps(join_message).encode(), self.server_address)
def receive_data(self):
while self.running:
try:
data, _ = self.client_socket.recvfrom(4096)
message = json.loads(data.decode())
if message['type'] == 'welcome':
self.player_id = message['id']
elif message['type'] == 'update':
self.game_state = message
except:
pass
def game_loop(self):
while self.running:
# 处理输入事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
self.input_state['up'] = True
elif event.key == pygame.K_DOWN:
self.input_state['down'] = True
elif event.key == pygame.K_LEFT:
self.input_state['left'] = True
elif event.key == pygame.K_RIGHT:
self.input_state['right'] = True
elif event.key == pygame.K_SPACE:
self.input_state['shoot'] = True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
self.input_state['up'] = False
elif event.key == pygame.K_DOWN:
self.input_state['down'] = False
elif event.key == pygame.K_LEFT:
self.input_state['left'] = False
elif event.key == pygame.K_RIGHT:
self.input_state['right'] = False
elif event.key == pygame.K_SPACE:
self.input_state['shoot'] = False
# 发送输入状态到服务器
if self.player_id is not None:
input_message = {
'type': 'input',
'id': self.player_id,
**self.input_state
}
self.client_socket.sendto(json.dumps(input_message).encode(), self.server_address)
# 渲染游戏
self.render()
self.clock.tick(60)
pygame.quit()
def render(self):
self.screen.fill((0, 0, 0))
# 绘制玩家
for player_id, player in self.game_state['players'].items():
color = (0, 255, 0) if int(player_id) == self.player_id else (0, 0, 255)
pygame.draw.rect(self.screen, color, (player['x'], player['y'], player['width'], player['height']))
# 显示生命值
if 'health' in player:
font = pygame.font.SysFont(None, 24)
health_text = font.render(f"HP: {player['health']}", True, (255, 255, 255))
self.screen.blit(health_text, (player['x'], player['y'] - 20))
# 显示分数
if 'score' in player:
font = pygame.font.SysFont(None, 24)
score_text = font.render(f"Score: {player['score']}", True, (255, 255, 255))
self.screen.blit(score_text, (player['x'], player['y'] - 40))
# 绘制子弹
for bullet in self.game_state['bullets']:
pygame.draw.rect(self.screen, (255, 255, 0), (bullet['x'], bullet['y'], bullet['width'], bullet['height']))
# 绘制敌机
for enemy in self.game_state['enemies']:
pygame.draw.circle(self.screen, (255, 0, 0), (enemy['x'], enemy['y']), enemy['radius'])
pygame.display.flip()
if __name__ == "__main__":
client = GameClient()
python
复制代码
import socket
import threading
import json
import random
import time
class GameServer:
def __init__(self):
self.players = {}
self.bullets = []
self.enemies = []
self.last_enemy_spawn = 0
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.server_socket.bind(('0.0.0.0', 5555))
self.running = True
# 游戏参数
self.screen_width = 600 # 宽度可以小一些
self.screen_height = 800 # 高度增加
self.player_speed = 5
self.bullet_speed = 7
self.enemy_speed = 3
# 启动接收线程
threading.Thread(target=self.receive_data).start()
threading.Thread(target=self.game_loop).start()
def receive_data(self):
while self.running:
try:
data, addr = self.server_socket.recvfrom(1024)
message = json.loads(data.decode())
if message['type'] == 'join':
player_id = len(self.players)
# 玩家初始位置改为底部
self.players[player_id] = {
'x': 200 if player_id == 0 else 400,
'y': self.screen_height - 100,
'width': 40,
'height': 40,
'addr': addr,
'last_shot': 0
}
response = {'type': 'welcome', 'id': player_id}
self.server_socket.sendto(json.dumps(response).encode(), addr)
elif message['type'] == 'input':
player_id = message['id']
if player_id in self.players:
player = self.players[player_id]
if 'up' in message and message['up']:
player['y'] = max(0, player['y'] - self.player_speed)
if 'down' in message and message['down']:
player['y'] = min(self.screen_height - player['height'], player['y'] + self.player_speed)
if 'left' in message and message['left']:
player['x'] = max(0, player['x'] - self.player_speed)
if 'right' in message and message['right']:
player['x'] = min(self.screen_width - player['width'], player['x'] + self.player_speed)
if 'shoot' in message and message['shoot']:
current_time = time.time()
if current_time - player['last_shot'] > 0.2: # 射击冷却
# 子弹改为向上发射
self.bullets.append({
'x': player['x'] + player['width'] // 2 - 5,
'y': player['y'],
'width': 5,
'height': 10,
'speed': -self.bullet_speed, # 负值表示向上
'owner': player_id
})
player['last_shot'] = current_time
except:
pass
def game_loop(self):
while self.running:
# 生成敌机(从顶部)
current_time = time.time()
if current_time - self.last_enemy_spawn > 2.0: # 每2秒生成一个敌机
self.enemies.append({
'x': random.randint(0, self.screen_width - 20),
'y': -20, # 从屏幕外顶部生成
'radius': 10,
'speed': self.enemy_speed
})
self.last_enemy_spawn = current_time
# 更新子弹位置
for bullet in self.bullets[:]:
bullet['y'] += bullet['speed'] # 速度可以是正或负
if bullet['y'] < -10 or bullet['y'] > self.screen_height + 10:
self.bullets.remove(bullet)
# 更新敌机位置(向下移动)
for enemy in self.enemies[:]:
enemy['y'] += enemy['speed']
if enemy['y'] > self.screen_height + 20:
self.enemies.remove(enemy)
# 碰撞检测
self.check_collisions()
# 广播游戏状态
self.broadcast_state()
time.sleep(0.016) # 约60FPS
def check_collisions(self):
# 子弹与敌机碰撞
for bullet in self.bullets[:]:
for enemy in self.enemies[:]:
if (bullet['x'] < enemy['x'] + enemy['radius'] and
bullet['x'] + bullet['width'] > enemy['x'] and
bullet['y'] < enemy['y'] + enemy['radius'] and
bullet['y'] + bullet['height'] > enemy['y']):
# 增加玩家分数
if bullet['owner'] in self.players:
if 'score' not in self.players[bullet['owner']]:
self.players[bullet['owner']]['score'] = 0
self.players[bullet['owner']]['score'] += 1
if bullet in self.bullets:
self.bullets.remove(bullet)
if enemy in self.enemies:
self.enemies.remove(enemy)
break
# 玩家与敌机碰撞
for player_id, player in self.players.items():
for enemy in self.enemies[:]:
if (player['x'] < enemy['x'] + enemy['radius'] and
player['x'] + player['width'] > enemy['x'] and
player['y'] < enemy['y'] + enemy['radius'] and
player['y'] + player['height'] > enemy['y']):
# 减少玩家生命值
if 'health' not in player:
player['health'] = 3
player['health'] -= 1
if enemy in self.enemies:
self.enemies.remove(enemy)
if player['health'] <= 0:
# 玩家死亡,重置位置
player['x'] = 200 if player_id == 0 else 400
player['y'] = self.screen_height - 100
player['health'] = 3
def broadcast_state(self):
game_state = {
'type': 'update',
'players': self.players,
'bullets': self.bullets,
'enemies': self.enemies
}
for player_id, player in self.players.items():
try:
self.server_socket.sendto(json.dumps(game_state).encode(), player['addr'])
except:
pass
if __name__ == "__main__":
server = GameServer()
input("Press Enter to stop the server...\n")
server.running = False