一个类似蛋仔派对的小游戏
有几个玩家
完整代码如下
import pygame
import random
# 初始化 pygame
pygame.init()
# 屏幕设置
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("简易蛋仔派对游戏")
# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
YELLOW = (255, 255, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
# 角色类
class Character:
def __init__(self, x, y, color):
self.width = 50
self.height = 50
self.x = x
self.y = y
self.vel_x = 0
self.vel_y = 0
self.jump_force = -15
self.gravity = 1
self.score = 0
self.is_invincible = False
self.invincible_time = 0
self.color = color
def move(self, dx):
self.vel_x = dx
self.x += self.vel_x
if self.x < 0:
self.x = 0
elif self.x > SCREEN_WIDTH - self.width:
self.x = SCREEN_WIDTH - self.width
def jump(self):
self.vel_y = self.jump_force
def apply_gravity(self):
self.vel_y += self.gravity
self.y += self.vel_y
if self.y >= SCREEN_HEIGHT - self.height:
self.y = SCREEN_HEIGHT - self.height
self.vel_y = 0
def draw(self):
pygame.draw.rect(screen, self.color, (self.x, self.y, self.width, self.height))
def update_invincible(self):
if self.is_invincible:
self.invincible_time -= 1
if self.invincible_time <= 0:
self.is_invincible = False
# 道具类(这里以金币和无敌道具为例)
class Coin:
def __init__(self):
self.radius = 15
self.x = random.randint(self.radius, SCREEN_WIDTH - self.radius)
self.y = random.randint(self.radius, SCREEN_HEIGHT // 2)
self.collected = False
def draw(self):
pygame.draw.circle(screen, YELLOW, (self.x, self.y), self.radius)
class InvinciblePowerup:
def __init__(self):
self.radius = 15
self.x = random.randint(self.radius, SCREEN_WIDTH - self.radius)
self.y = random.randint(self.radius, SCREEN_HEIGHT // 2)
self.collected = False
def draw(self):
pygame.draw.circle(screen, RED, (self.x, self.y), self.radius)
# 障碍类
class Obstacle:
def __init__(self):
self.width = random.randint(30, 100)
self.height = random.randint(30, 80)
self.x = SCREEN_WIDTH
self.y = random.randint(0, SCREEN_HEIGHT - self.height)
self.speed = random.randint(3, 7)
def move(self):
self.x -= self.speed
def draw(self):
pygame.draw.rect(screen, BLACK, (self.x, self.y, self.width, self.height))
# 虚拟摇杆类
class Joystick:
def __init__(self, x, y, radius):
self.x = x
self.y = y
self.radius = radius
self.center_x = x
self.center_y = y
self.knob_x = x
self.knob_y = y
self.dx = 0
self.dy = 0
def update(self, mouse_x, mouse_y):
dist = ((mouse_x - self.center_x) ** 2 + (mouse_y - self.center_y) ** 2) ** 0.5
if dist <= self.radius:
self.knob_x = mouse_x
self.knob_y = mouse_y
else:
self.knob_x = self.center_x + (mouse_x - self.center_x) * self.radius / dist
self.knob_y = self.center_y + (mouse_y - self.center_y) * self.radius / dist
self.dx = (self.knob_x - self.center_x) / self.radius
self.dy = (self.knob_y - self.center_y) / self.radius
def draw(self):
pygame.draw.circle(screen, BLACK, (self.center_x, self.center_y), self.radius)
pygame.draw.circle(screen, WHITE, (int(self.knob_x), int(self.knob_y)), self.radius // 2)
# 创建角色、摇杆、道具和障碍
player = Character(SCREEN_WIDTH // 2 - 25, SCREEN_HEIGHT - 50, BLACK)
joystick = Joystick(50, SCREEN_HEIGHT - 50, 40)
coins = [Coin() for _ in range(15)]
invincible_powerups = [InvinciblePowerup() for _ in range(5)]
obstacles = [Obstacle() for _ in range(10)]
other_players = [Character(random.randint(0, SCREEN_WIDTH - 50), random.randint(0, SCREEN_HEIGHT - 50), GREEN) for _ in range(3)]
# 游戏中点
mid_point_x = SCREEN_WIDTH // 2
mid_point_y = SCREEN_HEIGHT // 2
# 游戏主循环
running = True
clock = pygame.time.Clock()
while running:
screen.fill(WHITE)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1: # 鼠标左键
player.jump()
# 更新虚拟摇杆
mouse_x, mouse_y = pygame.mouse.get_pos()
joystick.update(mouse_x, mouse_y)
player.move(joystick.dx * 5)
# 更新角色状态
player.apply_gravity()
player.update_invincible()
# 更新其他玩家状态
for other_player in other_players:
other_player.apply_gravity()
# 简单的AI,让其他玩家随机移动
other_player.move(random.randint(-2, 2))
if random.random() < 0.1:
other_player.jump()
# 更新障碍位置
for obstacle in obstacles:
obstacle.move()
if obstacle.x + obstacle.width < 0:
obstacles.remove(obstacle)
new_obstacle = Obstacle()
obstacles.append(new_obstacle)
# 检查玩家与障碍的碰撞
if not player.is_invincible and (
player.x < obstacle.x + obstacle.width
and player.x + player.width > obstacle.x
and player.y < obstacle.y + obstacle.height
and player.y + player.height > obstacle.y
):
running = False
# 检查其他玩家与障碍的碰撞
for other_player in other_players:
if not other_player.is_invincible and (
other_player.x < obstacle.x + obstacle.width
and other_player.x + other_player.width > obstacle.x
and other_player.y < obstacle.y + obstacle.height
and other_player.y + other_player.height > obstacle.y
):
other_players.remove(other_player)
# 检查玩家与金币的碰撞
for coin in coins:
if not coin.collected:
dx = player.x + player.width // 2 - coin.x
dy = player.y + player.height // 2 - coin.y
distance = (dx ** 2 + dy ** 2) ** 0.5
if distance < player.width // 2 + coin.radius:
coin.collected = True
player.score += 1
# 检查玩家与无敌道具的碰撞
for powerup in invincible_powerups:
if not powerup.collected:
dx = player.x + player.width // 2 - powerup.x
dy = player.y + player.height // 2 - powerup.y
distance = (dx ** 2 + dy ** 2) ** 0.5
if distance < player.width // 2 + powerup.radius:
powerup.collected = True
player.is_invincible = True
player.invincible_time = 100 # 无敌时间(帧)
# 检查玩家是否经过中点
if abs(player.x - mid_point_x) < player.width and abs(player.y - mid_point_y) < player.height:
player.score += 5 # 经过中点分数加成
# 绘制元素
player.draw()
joystick.draw()
for coin in coins:
if not coin.collected:
coin.draw()
for powerup in invincible_powerups:
if not powerup.collected:
powerup.draw()
for obstacle in obstacles:
obstacle.draw()
for other_player in other_players:
other_player.draw()
# 绘制分数
font = pygame.font.Font(None, 36)
score_text = font.render(f"Score: {player.score}", True, BLACK)
screen.blit(score_text, (10, 10))
# 绘制中点
pygame.draw.circle(screen, RED, (mid_point_x, mid_point_y), 10)
pygame.display.flip()
clock.tick(60)
pygame.quit()