笔者最近学了一点pygame,献丑了。
代码附上,大佬勿喷!
import random
import time
import pygame
WIDTH = 410
HEIGHT = 750
ENEMY_BORN = pygame.USEREVENT + 1
BULLET_BORN = pygame.USEREVENT + 10
ENEMY_BULLET_BORN = pygame.USEREVENT + 100
REWARD_BORN = pygame.USEREVENT + 1000
class AudioManage:
# @staticmethod
# def play_bg_music():
# pygame.mixer.music.load("../素材/素材1/game.mp3")
# # pygame.mixer.music.set_volume(0.1)#设置声音大小
# pygame.mixer.music.play(loops=True)
@staticmethod
def bg_music():
pygame.mixer.music.load("../素材/素材1/bg.wav")
pygame.mixer.music.play(loops=True)
@staticmethod
def play_sound(name):
sound_play = pygame.mixer.Sound(f"../素材/素材1/{name}")
sound_play.play()
@staticmethod
def end_sound(name):
sound_end = pygame.mixer.Sound(f"../素材/素材1/{name}")
sound_end.play()
@staticmethod
def bullet_sound(name):
sound_bullet = pygame.mixer.Sound(f"../素材/素材1/{name}")
sound_bullet.play()
@staticmethod
def gui_sound(name):
sound_gui = pygame.mixer.Sound(f"../素材/素材1/{name}")
sound_gui.play()
@staticmethod
def bianshen_sound(name):
sound_bianshen = pygame.mixer.Sound(f"../素材/素材1/{name}")
sound_bianshen.play()
@staticmethod
def attack_sound(name):
sound_attack = pygame.mixer.Sound(f"../素材/素材1/{name}")
sound_attack.play()
@staticmethod
def add_life_sound(name):
sound_add_life = pygame.mixer.Sound(f"../素材/素材1/{name}")
sound_add_life.play()
@staticmethod
def get_sound(name):
sound_get = pygame.mixer.ound(f"../素材/素材1/{name}")
sound_get.play()
@staticmethod
def enemy_hurt_sound(name):
sound_enemy_hurt = pygame.mixer.Sound(f"../素材/素材1/{name}")
sound_enemy_hurt.play()
@staticmethod
def success_sound(name):
success_get = pygame.mixer.Sound(f"../素材/素材1/{name}")
success_get.play()
class BaseSprite(pygame.sprite.Sprite):
def __init__(self, image_name):
super().__init__()
self.image = pygame.image.load(image_name).convert_alpha()
self.rect = self.image.get_rect()
class EnemySprite(BaseSprite):
def __init__(self, image_name, start_x, destroy_images, gm, speed=7, hp=3):
super().__init__(image_name)
self.rect.left = start_x
self.speed = speed
self.gm = gm
self.max_hp = self.hp = hp
self.rect.top = 0
self.current_index = 0
self.destroy_images = [pygame.image.load(destroy_image) for destroy_image in destroy_images]
def hurt(self):
if self.gm.bullet_manage.bullet_type == 1:
self.hp -= 1
elif self.gm.bullet_manage.bullet_type == "u":
self.hp -= 3
elif self.gm.bullet_manage.bullet_type == "i":
self.hp -= 3
def update(self):
pygame.draw.rect(self.image, "red", (0, 0, self.rect.width, 5))
pygame.draw.rect(self.image, "green", (0, 0, self.rect.width * self.hp / self.max_hp, 5))
self.rect.top += self.speed
if self.rect.top > HEIGHT:
self.kill()
if self.hp <= 0:
self.image = self.destroy_images[self.current_index // 5]
self.current_index += 1
if self.current_index == len(self.destroy_images) * 5:
self.kill()
class EnemyManage:
def __init__(self, gm):
self.gm = gm
self.enemy_group = pygame.sprite.Group()
def born(self):
image_name = random.choice(
["../素材/素材1/guai1.png", "../素材/素材1/guai2.png", "../素材/素材1/guai3.png",
"../素材/素材1/guai4.png"])
start_x = random.randint(0, WIDTH - 100)
self.enemy = EnemySprite(image_name, start_x,
["../素材/素材1/enemy_baozha1.png", "../素材/素材1/enemy_baozha2.png"], self.gm)
self.enemy.add(self.enemy_group)
def clear(self):
self.enemy_group.empty()
def update(self):
self.enemy_group.draw(self.gm.screen)
self.enemy_group.update()
class RewardSprite(BaseSprite):
def __init__(self, image_name, start_x, gm, speed=7):
self.image_name = image_name
super().__init__(image_name)
self.rect.left = start_x
self.speed = speed
self.gm = gm
self.rect.top = 0
self.is_use()
def is_use(self):
if self.image_name == "../素材/素材1/life.png":
self.use = "add_life"
if self.image_name == "../素材/素材1/zidan2_reward.png":
self.use = "zidan2_reward"
if self.image_name == "../素材/素材1/zidan3_reward.png":
self.use = "zidan3_reward"
def update(self):
self.rect.top += self.speed
if self.rect.top > HEIGHT:
self.kill()
class RewardManage:
def __init__(self, gm):
self.gm = gm
self.reward_group = pygame.sprite.Group()
def born(self):
image_name = random.choice(
["../素材/素材1/life.png", "../素材/素材1/zidan2_reward.png", "../素材/素材1/zidan3_reward.png"])
start_x = random.randint(0, WIDTH - 50)
self.reward = RewardSprite(image_name, start_x, self.gm)
self.reward.add(self.reward_group)
def clear(self):
self.reward_group.empty()
def update(self):
self.reward_group.draw(self.gm.screen)
self.reward_group.update()
class EnemyBulletSprite(BaseSprite):
def __init__(self, image_name, enemy_pos, bullet_speed=15):
super().__init__(image_name)
self.rect.center = enemy_pos
self.bullet_speed = bullet_speed
def update(self):
self.rect.bottom += self.bullet_speed
if self.rect.bottom > HEIGHT:
self.kill()
class EnemyBulletManage:
def __init__(self, gm):
self.gm = gm
self.enemy_bullet_group = pygame.sprite.Group()
self.last_enemy_bullet_time = pygame.time.get_ticks()
def born(self):
current_time = pygame.time.get_ticks()
if current_time - self.last_enemy_bullet_time > 1500: # 每隔 1 秒生成一个敌人子弹
for enemy in self.gm.enemy_manage.enemy_group:
enemy_bullet = EnemyBulletSprite("../素材/素材1/enemy_zidan.png", enemy.rect.center)
self.enemy_bullet_group.add(enemy_bullet)
self.last_enemy_bullet_time = current_time
def clear(self):
self.enemy_bullet_group.empty()
def update(self):
self.enemy_bullet_group.draw(self.gm.screen)
self.enemy_bullet_group.update()
class PlayerSprite(BaseSprite):
def __init__(self, image_name, change_images, player_speed=10):
super().__init__(image_name)
self.rect.center = (WIDTH / 2, HEIGHT - 150)
self.player_speed = player_speed
self.current_index = 0
self.change_images = [pygame.image.load(change_image) for change_image in change_images]
self.animation_speed = 5
def update(self):
key_pressed = pygame.key.get_pressed()
if key_pressed[pygame.K_SPACE]:
self.current_index += self.animation_speed
if self.current_index >= len(self.change_images) * self.animation_speed:
self.current_index = 0
else:
self.current_index = 0
self.image = self.change_images[self.current_index // self.animation_speed]
if key_pressed[pygame.K_LEFT] or key_pressed[pygame.K_a]:
self.rect.left -= self.player_speed
if self.rect.left < 0:
self.rect.left = 0
if key_pressed[pygame.K_RIGHT] or key_pressed[pygame.K_d]:
self.rect.right += self.player_speed
if self.rect.right > WIDTH:
self.rect.right = WIDTH
if key_pressed[pygame.K_UP] or key_pressed[pygame.K_w]:
self.rect.top -= self.player_speed
if self.rect.top < 0:
self.rect.top = 0
if key_pressed[pygame.K_DOWN] or key_pressed[pygame.K_s]:
self.rect.bottom += self.player_speed
if self.rect.bottom > HEIGHT:
self.rect.bottom = HEIGHT
class PlayerManage:
def __init__(self, gm):
self.gm = gm
self.player_group = pygame.sprite.Group()
def born(self):
# if self.gm.bullet_manage.bullet_type == "1":
self.player = PlayerSprite("../素材/素材1/wukong1.png",
[f"../素材/素材1/wukong{i}.png" for i in range(1, 6)])
self.player_group.add(self.player)
# if self.gm.bullet_manage.bullet_type == "u":
# self.player = PlayerSprite("../素材/素材1/11111.png",
# [f"../素材/素材1/11111.png"])
# self.player_group.add(self.player)
def die(self):
self.player.kill()
def update(self):
self.player_group.draw(self.gm.screen)
self.player_group.update()
class BulletSprite(BaseSprite):
def __init__(self, image_name, bullet_speed=30):
super().__init__(image_name)
self.bullet_speed = bullet_speed
self.rect = self.image.get_rect()
def update(self):
self.rect.top -= self.bullet_speed
if self.rect.top < 0:
self.kill()
class BulletManage:
def __init__(self, gm):
self.gm = gm
self.bullet_group = pygame.sprite.Group()
self.last_bullet_time = pygame.time.get_ticks()
self.bullets = pygame.sprite.Group()
self.bullet_type = 1
self.bullet_type2_num = 10
self.bullet_group = pygame.sprite.Group()
self.bullet_type3_time = 3
self.current_index = 0
def change_bullet_type(self, bullet_type):
self.bullet_type = bullet_type
if bullet_type == "u":
self.bullet_type2_num = 10
if bullet_type == "i":
self.bullet_type3_time = 3
def born(self):
if self.bullet_type == 1:
current_time = pygame.time.get_ticks()
if current_time - self.last_bullet_time > 150:
self.bullet = BulletSprite("../素材/素材1/zidan.png")
self.bullet.rect.center = self.gm.player_manage.player.rect.center
self.bullet.add(self.bullet_group)
self.last_bullet_time = current_time
elif self.bullet_type == "u":
current_time = pygame.time.get_ticks()
if current_time - self.last_bullet_time > 150:
AudioManage.bianshen_sound("bianshen.mp3")
# self.gm.player = PlayerSprite("../素材/素材1/11111.png", ["../素材/素材1/11111.png"])
# self.gm.player.rect.center = self.gm.player_manage.player.rect.center
# self.gm.player.add(self.gm.player_group)
self.bullet = BulletSprite("../素材/素材1/zidan2.png")
self.bullet.rect.center = self.gm.player_manage.player.rect.center
self.bullet.add(self.bullet_group)
self.last_bullet_time = current_time
self.bullet_type2_num -= 1
if self.bullet_type2_num == 0:
self.change_bullet_type(1)
elif self.bullet_type == "i":
if self.bullet_type3_time >= 0:
self.bullet = BulletSprite("../素材/素材1/zidan3.png")
AudioManage.gui_sound("gui.mp3")
self.bullet.rect.center = (
self.gm.player_manage.player.rect.centerx, self.gm.player_manage.player.rect.centery - 310)
self.bullet.add(self.bullet_group)
if self.bullet_type3_time <= 0:
self.change_bullet_type(1)
def clear(self):
self.bullet_group.empty()
def update(self):
self.bullet_type3_time -= 1 / 30
self.bullet_group.draw(self.gm.screen)
self.bullet_group.update()
class BgSprite(BaseSprite):
def __init__(self, image_name, start_y, speed=5):
super().__init__(image_name)
self.rect.top = start_y
self.speed = speed
def update(self):
self.rect.top += self.speed
if self.rect.top >= HEIGHT:
self.rect.top = -HEIGHT
class BgManage:
def __init__(self, gm):
self.gm = gm
self.ready_group = pygame.sprite.Group()
self.bg0 = BgSprite("../素材/素材1/bgnight.jpg", 0, 0)
self.bg0.add(self.ready_group)
self.gaming_group = pygame.sprite.Group()
self.bg1 = BgSprite("../素材/素材1/bgnight.jpg", 0, 5)
self.bg1.add(self.gaming_group)
self.bg2 = BgSprite("../素材/素材1/bgnight.jpg", -HEIGHT, 5)
self.bg2.add(self.gaming_group)
self.end_group = pygame.sprite.Group()
self.bg3 = BgSprite("../素材/素材1/bgnight.jpg", 0, 0)
self.bg3.add(self.end_group)
self.next_group = pygame.sprite.Group()
self.bg4 = BgSprite("../素材/素材1/success.jpg", 0, 0)
self.bg4.add(self.next_group)
def update(self):
if self.gm.game_state == "ready":
self.ready_group.draw(self.gm.screen)
self.ready_group.update()
elif self.gm.game_state == "gaming":
self.gaming_group.draw(self.gm.screen)
self.gaming_group.update()
elif self.gm.game_state == "next":
self.next_group.draw(self.gm.screen)
self.next_group.update()
elif self.gm.game_state == "end":
self.end_group.draw(self.gm.screen)
self.end_group.update()
class UISprite(BaseSprite):
def __init__(self, image_name, center):
super().__init__(image_name)
self.rect.center = center
def is_collide(self):
mouse_pos = pygame.mouse.get_pos()
if self.rect.collidepoint(mouse_pos):
return True
class GIFSprite(BaseSprite):
def __init__(self, image_names):
super().__init__(image_names[0])
self.rect.center = (80, 80)
self.images = [pygame.image.load(image_name) for image_name in image_names]
self.current_index = 0
def update(self):
self.current_index += 1
if self.current_index == len(self.images) * 2:
self.current_index = 0
self.image = self.images[self.current_index // 2]
self.image = pygame.transform.scale(self.image, (80, 80))
class UIManage:
def __init__(self, gm, life_number=3):
self.gm = gm
self.ready_group = pygame.sprite.Group()
self.start_btn1 = UISprite("../素材/素材1/choice1.png", (WIDTH / 2 - 100, HEIGHT / 2 + 80))
self.start_btn1.add(self.ready_group)
self.start_btn2 = UISprite("../素材/素材1/choice2.png", (WIDTH / 2, HEIGHT / 2 + 80))
self.start_btn2.add(self.ready_group)
self.start_btn3 = UISprite("../素材/素材1/choice3.png", (WIDTH / 2 + 100, HEIGHT / 2 + 80))
self.start_btn3.add(self.ready_group)
self.life_number = life_number
self.feng_group = pygame.sprite.Group()
self.feng = UISprite("../素材/素材1/title.jpg", (WIDTH / 2, HEIGHT / 2 - 180))
self.feng.add(self.feng_group)
self.gaming_group = pygame.sprite.Group()
self.head_img = GIFSprite([f"../素材/素材1/{i}.png" for i in range(1, 73)])
self.head_img.image = pygame.transform.scale(self.head_img.image, (80, 80))
self.bullet_img = BulletSprite("../素材/飞机大战/zidan.png")
self.bullet_img.add(self.gaming_group)
self.head_img.add(self.gaming_group)
self.font = pygame.font.Font("../素材/font/simhei.ttf", size=30)
self.life_label = self.font.render(f"X{self.life_number}", True, "red")
self.score_value = 0
self.font = pygame.font.Font("../素材/font/simhei.ttf", size=30)
self.score_label = self.font.render(f"Score:{self.score_value}", True, "red")
self.next_group = pygame.sprite.Group()
self.next_btn = UISprite("../素材/素材1/continue.jpg", (WIDTH / 2, HEIGHT - 170))
self.next_btn.add(self.next_group)
self.end_group = pygame.sprite.Group()
self.restart_btn = UISprite("../素材/赛车/end.png", (WIDTH / 2, HEIGHT - 400))
self.restart_btn.add(self.end_group)
def down_life(self):
self.life_number -= 1
self.life_label = self.font.render(f"X{self.life_number}", True, "red")
def add_life(self):
self.life_number += 1
self.life_label = self.font.render(f"X{self.life_number}", True, "red")
def add_score(self):
self.score_value += 1
self.score_label = self.font.render(f"Score:{self.score_value}", False, "red")
def update(self):
if self.gm.game_state == "ready":
self.feng_group.draw(self.gm.screen)
self.ready_group.draw(self.gm.screen)
self.ready_group.update()
self.life_number = 3
elif self.gm.game_state == "gaming":
self.gaming_group.draw(self.gm.screen)
self.gaming_group.update()
self.gm.screen.blit(self.score_label, (250, 60))
self.gm.screen.blit(self.life_label, (120, 60))
elif self.gm.game_state == "next":
self.next_group.draw(self.gm.screen)
self.next_group.update()
self.score_value = 0
self.life_number = 3
elif self.gm.game_state == "end":
self.end_group.draw(self.gm.screen)
self.end_group.update()
self.gm.screen.blit(self.score_label, (WIDTH / 2 - 55, HEIGHT / 2 - 100))
def check_click(self):
if self.gm.game_state == "ready":
if self.start_btn1.is_collide():
self.gm.game_state = "gaming"
self.gm.player_manage.born()
pygame.time.set_timer(ENEMY_BORN, 2000)
pygame.time.set_timer(REWARD_BORN, 4000)
if self.start_btn2.is_collide():
self.gm.game_state = "gaming"
self.gm.player_manage.born()
pygame.time.set_timer(ENEMY_BORN, 1500)
pygame.time.set_timer(REWARD_BORN, 6000)
if self.start_btn3.is_collide():
self.gm.game_state = "gaming"
self.gm.player_manage.born()
pygame.time.set_timer(ENEMY_BORN, 1000)
pygame.time.set_timer(REWARD_BORN, 8000)
elif self.gm.game_state == "gaming":
self.gm.player_manage.born()
elif self.gm.game_state == "end":
if self.restart_btn.is_collide():
self.gm.game_state = "ready"
elif self.next_btn.is_collide():
self.gm.game_state = "ready"
class GameManage:
def __init__(self):
pygame.init()
pygame.display.set_caption("悟空打怪")
self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
self.clock = pygame.time.Clock()
AudioManage.bg_music()
self.game_state = "ready"
self.ui_manage = UIManage(self)
self.bg_manage = BgManage(self)
self.enemy_manage = EnemyManage(self)
self.player_manage = PlayerManage(self)
self.player_group = pygame.sprite.Group()
self.bullet_manage = BulletManage(self)
self.enemy_bullet_manage = EnemyBulletManage(self)
self.reward_manage = RewardManage(self)
self.ui_manage.score_value = 0
self.bullet_manage.clear()
self.enemy_manage.clear()
self.enemy_bullet_manage.clear()
def check_event(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
if event.type == pygame.KEYUP:
if event.key == pygame.K_SPACE:
self.bullet_manage.born()
AudioManage.bullet_sound("bullet.mp3")
if event.type == pygame.KEYUP:
if self.game_state == "gaming":
if event.key == pygame.K_u:
self.bullet_manage.change_bullet_type("u")
if event.key == pygame.K_i:
self.bullet_manage.change_bullet_type("i")
if event.type == pygame.MOUSEBUTTONUP:
self.ui_manage.check_click()
if event.type == ENEMY_BORN:
self.enemy_manage.born()
if event.type == REWARD_BORN:
self.reward_manage.born()
def update_draw(self):
self.screen.fill("grey")
self.bg_manage.update()
self.ui_manage.update()
if self.game_state == "gaming":
self.enemy_manage.update()
self.player_manage.update()
self.bullet_manage.update()
self.enemy_bullet_manage.update()
self.enemy_bullet_manage.born()
self.reward_manage.update()
# 控制激光一直发射
if self.bullet_manage.bullet_type == "i":
self.bullet_manage.born()
if self.ui_manage.score_value == 10:
self.game_state = "next"
pygame.time.set_timer(ENEMY_BORN, 0)
pygame.time.set_timer(REWARD_BORN, 0)
AudioManage.success_sound("success.mp3")
self.ui_manage.score_value = 0
self.ui_manage.score_label = self.ui_manage.font.render(f"Score:{self.ui_manage.score_value}", True,
"red")
self.ui_manage.life_value = 3
self.ui_manage.life_label = self.ui_manage.font.render(f"X{self.ui_manage.life_value}", True,
"red")
self.bullet_manage.clear()
self.player_manage.die()
self.enemy_manage.clear()
self.enemy_bullet_manage.clear()
if self.game_state == "end":
pygame.time.set_timer(ENEMY_BORN, 0)
pygame.time.set_timer(REWARD_BORN, 0)
self.ui_manage.score_value = 0
self.ui_manage.score_label = self.ui_manage.font.render(f"Score:{self.ui_manage.score_value}", True, "red")
self.ui_manage.life_value = 3
self.ui_manage.life_label = self.ui_manage.font.render(f"X{self.ui_manage.life_value}", True,
"red")
pygame.display.flip()
def check_collide(self):
# 检测玩家与奖励道具的碰撞
s1 = pygame.sprite.spritecollide(self.player_manage.player, self.reward_manage.reward_group, False)
if s1:
for s11 in s1:
if s11.use == "add_life":
self.ui_manage.add_life()
AudioManage.play_sound("add_life.mp3")
s11.kill()
if s11.use == "zidan2_reward":
AudioManage.play_sound("get.mp3")
self.bullet_manage.change_bullet_type("u")
s11.kill()
if s11.use == "zidan3_reward":
AudioManage.play_sound("get.mp3")
self.bullet_manage.change_bullet_type("i")
s11.kill()
# 检测敌人子弹与玩家的碰撞
collided_enemy_bullet = pygame.sprite.spritecollide(self.player_manage.player,
self.enemy_bullet_manage.enemy_bullet_group, True)
if collided_enemy_bullet:
self.ui_manage.down_life()
AudioManage.play_sound("hurt.mp3")
if self.ui_manage.life_number <= 0:
self.game_state = "end"
self.player_manage.die()
self.enemy_manage.clear()
self.bullet_manage.clear()
AudioManage.end_sound("end.mp3")
pygame.time.set_timer(ENEMY_BORN, 0)
# 检测玩家子弹与敌人的碰撞
if self.bullet_manage.bullet_type == 1 or self.bullet_manage.bullet_type == "u":
d = pygame.sprite.groupcollide(self.bullet_manage.bullet_group, self.enemy_manage.enemy_group, True, False)
if d:
for enemy_s in d.values():
for enemy in enemy_s:
if enemy.hp > 0:
AudioManage.enemy_hurt_sound("enemy_hurt.mp3")
enemy.hurt()
if enemy.hp <= 0:
self.ui_manage.add_score()
AudioManage.attack_sound("baozha.mp3")
if self.bullet_manage.bullet_type == "i":
d = pygame.sprite.groupcollide(self.bullet_manage.bullet_group, self.enemy_manage.enemy_group, False, True)
if d:
for enemy_s in d.values():
for enemy in enemy_s:
if enemy.hp > 0:
enemy.hurt()
if enemy.hp <= 0:
self.ui_manage.add_score()
AudioManage.attack_sound("baozha.mp3")
# 检测玩家与敌人的碰撞
r = pygame.sprite.spritecollide(self.player_manage.player, self.enemy_manage.enemy_group, True)
if r:
self.ui_manage.down_life()
AudioManage.play_sound("hurt.mp3")
if self.ui_manage.life_number <= 0:
self.game_state = "end"
self.player_manage.die()
self.enemy_manage.clear()
self.bullet_manage.clear()
AudioManage.end_sound("end.mp3")
pygame.time.set_timer(ENEMY_BORN, 0)
pygame.time.set_timer(REWARD_BORN, 0)
def run(self):
while True:
self.check_event()
self.update_draw()
self.clock.tick(30)
if self.game_state == "gaming":
self.check_collide()
mg = GameManage()
mg.run()