import pygame import random import os FPS = 60 WIDTH = 500 HEIGHT = 600 BLACK = (0, 0, 0) WHITE = (255, 255, 255) GREEN = (0, 255, 0) RED = (255, 0, 0) YELLOW = (255, 255, 0) # 游戏初始化及创建视窗 pygame.init() pygame.mixer.init() screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("planeshoot") clock = pygame.time.Clock() # 载入图片 background_img = pygame.image.load(os.path.join("img", "background.png")).convert() player_img = pygame.image.load(os.path.join("img", "player.png")).convert() player_mini_img = pygame.transform.scale(player_img, (25, 19)) player_mini_img.set_colorkey(BLACK) pygame.display.set_icon(player_mini_img) enemy_img = pygame.image.load(os.path.join("img", "player.png")).convert() bullet_img = pygame.image.load(os.path.join("img", "bullet.png")).convert() rock_imgs = [] for i in range(7): rock_imgs.append(pygame.image.load(os.path.join("img", f"rock{i}.png")).convert()) expl_anim = {} expl_anim['lg'] = [] expl_anim['sm'] = [] expl_anim['player'] = [] for i in range(9): expl_img = pygame.image.load(os.path.join("img", f"expl{i}.png")).convert() expl_img.set_colorkey(BLACK) expl_anim['lg'].append(pygame.transform.scale(expl_img, (75, 75))) expl_anim['sm'].append(pygame.transform.scale(expl_img, (30, 30))) player_expl_img = pygame.image.load(os.path.join("img", f"player_expl{i}.png")).convert() player_expl_img.set_colorkey(BLACK) expl_anim['player'].append(player_expl_img) power_imgs = {} power_imgs['shield'] = pygame.image.load(os.path.join("img", "shield.png")).convert() power_imgs['gun'] = pygame.image.load(os.path.join("img", "gun.png")).convert() power_imgs['body'] = pygame.image.load(os.path.join("img", "p2341.png")).convert() score=0 score1=0 score2=0 plant_lives=0 plant2_lives=0 plant_healths=0 plant2_healths=0 load_s=False # 载入音乐及音效 shoot_sound = pygame.mixer.Sound(os.path.join("sound", "shoot.wav")) gun_sound = pygame.mixer.Sound(os.path.join("sound", "pow1.wav")) shield_sound = pygame.mixer.Sound(os.path.join("sound", "pow0.wav")) die_sound = pygame.mixer.Sound(os.path.join("sound", "rumble.ogg")) expl_sounds = [ pygame.mixer.Sound(os.path.join("sound", "expl0.wav")), pygame.mixer.Sound(os.path.join("sound", "expl1.wav")) ] pygame.mixer.music.load(os.path.join("sound", "background.ogg")) pygame.mixer.music.set_volume(0.4) font_name = os.path.join("font.ttf") def draw_text(surf, text, size, x, y): font = pygame.font.Font(font_name, size) text_surface = font.render(text, True, WHITE) text_rect = text_surface.get_rect() text_rect.centerx = x text_rect.top = y surf.blit(text_surface, text_rect) def new_rock(): r = Rock() all_sprites.add(r) rocks.add(r) def draw_health(surf, hp, x, y): if hp <=0: hp = 0 BAR_LENGTH = 100 BAR_HEIGHT = 10 fill = (hp/100)*BAR_LENGTH outline_rect = pygame.Rect(x, y, BAR_LENGTH, BAR_HEIGHT) fill_rect = pygame.Rect(x, y, fill, BAR_HEIGHT) pygame.draw.rect(surf, GREEN, fill_rect) pygame.draw.rect(surf, WHITE, outline_rect, 2) def draw_lives(surf, lives, img, x, y): for i in range(lives): img_rect = img.get_rect() img_rect.x = x + 32*i img_rect.y = y surf.blit(img, img_rect) def draw_init2(): screen.blit(background_img, (0,0)) draw_text(screen, '按p重新开始', 64, WIDTH/2, HEIGHT/4) draw_text(screen, '按l结束', 64, WIDTH / 2, HEIGHT / 4+80) draw_text(screen, 'YOUR SCORE:'+str(score), 32, WIDTH / 2-50, HEIGHT / 4-50) draw_text(screen, 'PLAYER1 SCORE:' + str(score1), 20, WIDTH/2 , HEIGHT - 100) draw_text(screen, 'PLAYER2 SCORE:' + str(score2), 20, WIDTH/2-0 , HEIGHT - 50) pygame.display.update() waiting = True while waiting: clock.tick(FPS) # 取得輸入 for event in pygame.event.get(): if event.type == pygame.QUIT: waiting = False return True if event.type == pygame.KEYDOWN: if event.key==pygame.K_p: waiting = False return False elif event.key==pygame.K_l: waiting = False return True def draw_init(): global score global score1 global score2 global plant_lives global plant2_lives global plant_healths global plant2_healths global load_s screen.blit(background_img, (0,0)) draw_text(screen, '飞机大战!', 64, WIDTH/2, HEIGHT/4) draw_text(screen, '移动飞船 空白键射击', 22, WIDTH/2, HEIGHT/2) draw_text(screen, '按O读档', 30, WIDTH / 2, HEIGHT / 2+60) draw_text(screen, '按空格开始游戏!', 18, WIDTH/2, HEIGHT*3/4) draw_text(screen, '按L结束游戏!', 18, WIDTH / 2, HEIGHT * 3 / 4+30) pygame.display.update() waiting = True while waiting: clock.tick(FPS) # 取得輸入 for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() return True if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: waiting = False return False elif event.key == pygame.K_l: pygame.quit() return True elif event.key==pygame.K_o: with open("file.txt", "r") as fp: s = fp.readlines() s = [int(line.strip()) for line in s] score=s[0] score1=s[1] score2=s[2] plant_lives=s[3] plant2_lives=s[4] plant_healths=s[5] plant2_healths =s[6] load_s=True waiting = False return False class Player2(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.image = pygame.transform.scale(player_img, (50, 38)) self.image.set_colorkey(BLACK) self.rect = self.image.get_rect() self.radius = 20 # pygame.draw.circle(self.image, RED, self.rect.center, self.radius) self.rect.centerx = WIDTH self.rect.bottom = HEIGHT - 10 self.speedx = 8 self.health = 100 self.lives = 3 self.hidden = False self.hide_time = 0 self.gun = 1 self.gun11=1 self.gun_time = 0 self.gun11_time=0 self.hide21=False def update(self): now = pygame.time.get_ticks() if self.gun == 2 and now - self.gun_time > 5000: self.gun = 1 self.gun_time = now now = pygame.time.get_ticks() if self.gun11 == 2 and now - self.gun11_time > 5000: self.gun11 = 1 self.gun11_time = now if self.hidden and now - self.hide_time > 1000: self.hidden = False self.rect.centerx = WIDTH / 2 self.rect.bottom = HEIGHT - 10 if self.hide21: self.rect.x=WIDTH+500 self.rect.y=HEIGHT+500 self.kill() key_pressed = pygame.key.get_pressed() if key_pressed[pygame.K_d]: self.rect.x += self.speedx if key_pressed[pygame.K_a]: self.rect.x -= self.speedx if self.rect.right > WIDTH: self.rect.right = WIDTH if self.rect.left < 0: self.rect.left = 0 if key_pressed[pygame.K_w]: self.rect.y-=self.speedx if self.rect.y < 0: self.rect.y = 0 if key_pressed[pygame.K_s]: self.rect.y +=self.speedx if self.rect.bottom > HEIGHT: self.rect.bottom = HEIGHT def shoot(self): if not(self.hidden): if self.gun == 1: bullet = Bullet(self.rect.centerx, self.rect.top) all_sprites.add(bullet) bullets2.add(bullet) shoot_sound.play() elif self.gun ==2: bullet1 = Bullet(self.rect.left, self.rect.centery) bullet2 = Bullet(self.rect.right, self.rect.centery) all_sprites.add(bullet1) all_sprites.add(bullet2) bullets2.add(bullet1) bullets2.add(bullet2) shoot_sound.play() def hide(self): self.hidden = True self.hide_time = pygame.time.get_ticks() self.rect.center = (WIDTH/2, HEIGHT+500) def hide2(self): self.hide21=True def gunup(self): self.gun = 2 self.gun_time = pygame.time.get_ticks() def gunup1(self): self.gun11 = 2 self.gun11_time = pygame.time.get_ticks() class Player(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.image = pygame.transform.scale(player_img, (50, 38)) self.image.set_colorkey(BLACK) self.rect = self.image.get_rect() self.radius = 20 # pygame.draw.circle(self.image, RED, self.rect.center, self.radius) self.rect.centerx = WIDTH / 2 self.rect.bottom = HEIGHT - 10 self.speedx = 8 self.health = 100 self.lives = 3 self.hidden = False self.hide21=False self.hide_time = 0 self.gun = 1 self.gun11=1 self.gun_time = 0 self.gun11_time = 0 def update(self): now = pygame.time.get_ticks() if self.gun == 2 and now - self.gun_time > 5000: self.gun = 1 self.gun_time = now now = pygame.time.get_ticks() if self.gun11 == 2 and now - self.gun_time > 5000: self.gun11 = 1 self.gun11_time = now if self.hidden and now - self.hide_time > 1000: self.hidden = False self.rect.centerx = WIDTH / 2 self.rect.bottom = HEIGHT - 10 if self.hide21: self.rect.x=WIDTH+1100 self.rect.y=HEIGHT+1100 self.kill() key_pressed = pygame.key.get_pressed() if key_pressed[pygame.K_RIGHT]: self.rect.x += self.speedx if key_pressed[pygame.K_LEFT]: self.rect.x -= self.speedx if self.rect.right > WIDTH: self.rect.right = WIDTH if self.rect.left < 0: self.rect.left = 0 if key_pressed[pygame.K_DOWN]: self.rect.y+=self.speedx if self.rect.bottom > HEIGHT: self.rect.bottom = HEIGHT if key_pressed[pygame.K_UP]: self.rect.y-=self.speedx if self.rect.y < 0: self.rect.y = 0 def shoot(self): if not(self.hidden): if self.gun == 1: bullet = Bullet(self.rect.centerx, self.rect.top) all_sprites.add(bullet ) bullets1.add(bullet) shoot_sound.play() elif self.gun ==2: bullet1 = Bullet(self.rect.left, self.rect.centery) bullet2 = Bullet(self.rect.right, self.rect.centery) all_sprites.add(bullet1) all_sprites.add(bullet2) bullets1.add(bullet1) bullets1.add(bullet2) shoot_sound.play() def hide(self): self.hidden = True self.hide_time = pygame.time.get_ticks() self.rect.center = (WIDTH/2, HEIGHT+500) def hide2(self): self.hide21=True def gunup(self): self.gun = 2 self.gun_time = pygame.time.get_ticks() def gunup1(self): self.gun11 = 2 self.gun11_time = pygame.time.get_ticks() class enemy(pygame.sprite.Sprite): def __init__(self, x=0, y=0): self.x = x self.y = y self.screen = screen self.fangxiang = 'right' self.name = 'enemyer' self.bullet = [] def draw(self): self.screen.blit(self.image, (self.x, self.y)) for temp in self.bullet: temp.draw() def move(self): if self.fangxiang == 'right': self.x += 2 elif self.fangxiang == 'left': self.x -= 2 if self.x > 460: self.fangxiang = 'left' elif self.x <= 0: self.fangxiang = 'right' # print(self.x) randomNum = random.randint(1, 100) if randomNum in [50, 70]: self.bullet.append(Bullet(self.name, self.x + 30, self.y + 24)) class Rock(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.image_ori = random.choice(rock_imgs) self.image_ori.set_colorkey(BLACK) self.image = self.image_ori.copy() self.rect = self.image.get_rect() self.radius = int(self.rect.width * 0.85 / 2) # pygame.draw.circle(self.image, RED, self.rect.center, self.radius) self.rect.x = random.randrange(0, WIDTH - self.rect.width) self.rect.y = random.randrange(-180, -100) self.speedy = random.randrange(2, 5) self.speedx = random.randrange(-3, 3) self.total_degree = 0 self.rot_degree = random.randrange(-3, 3) def rotate(self): self.total_degree += self.rot_degree self.total_degree = self.total_degree % 360 self.image = pygame.transform.rotate(self.image_ori, self.total_degree) center = self.rect.center self.rect = self.image.get_rect() self.rect.center = center def update(self): self.rotate() self.rect.y += self.speedy self.rect.x += self.speedx if self.rect.top > HEIGHT or self.rect.left > WIDTH or self.rect.right < 0: self.rect.x = random.randrange(0, WIDTH - self.rect.width) self.rect.y = random.randrange(-100, -40) self.speedy = random.randrange(2, 10) self.speedx = random.randrange(-3, 3) class Bullet(pygame.sprite.Sprite): def __init__(self, x, y): pygame.sprite.Sprite.__init__(self) self.image = bullet_img self.image.set_colorkey(BLACK) self.rect = self.image.get_rect() self.rect.centerx = x self.rect.bottom = y self.speedy = -10 def update(self): self.rect.y += self.speedy if self.rect.bottom < 0: self.kill() class Explosion(pygame.sprite.Sprite): def __init__(self, center, size): pygame.sprite.Sprite.__init__(self) self.size = size self.image = expl_anim[self.size][0] self.rect = self.image.get_rect() self.rect.center = center self.frame = 0 self.last_update = pygame.time.get_ticks() self.frame_rate = 50 def update(self): now = pygame.time.get_ticks() if now - self.last_update > self.frame_rate: self.last_update = now self.frame += 1 if self.frame == len(expl_anim[self.size]): self.kill() else: self.image = expl_anim[self.size][self.frame] center = self.rect.center self.rect = self.image.get_rect() self.rect.center = center class Power(pygame.sprite.Sprite): def __init__(self, center): pygame.sprite.Sprite.__init__(self) self.type = random.choice(['shield', 'gun','body']) self.image = power_imgs[self.type] self.image.set_colorkey(BLACK) self.rect = self.image.get_rect() self.rect.center = center self.speedy = 3 def update(self): self.rect.y += self.speedy if self.rect.top > HEIGHT: self.kill() pygame.mixer.music.play(-1) # 游戏回圈 show_init = True running = True while running: if show_init: close = draw_init() if close: with open("file.txt", "w") as fp: fp.write(str(int(score))) fp.write('\n') fp.write(str(int(score1))) fp.write('\n') fp.write(str(int(score2))) fp.write('\n') fp.write(str(player.lives)) fp.write('\n') fp.write(str(player2.lives)) fp.write('\n') fp.write(str(int(player.health))) fp.write('\n') fp.write(str(int(player2.health))) break show_init = False all_sprites = pygame.sprite.Group() rocks = pygame.sprite.Group() bullets1 = pygame.sprite.Group() bullets2 = pygame.sprite.Group() powers = pygame.sprite.Group() player = Player() player2 = Player2() if load_s: player.lives=plant_lives player.health=plant_healths player2.lives = plant2_lives player2.health = plant2_healths load_s=False all_sprites.add(player) all_sprites.add(player2) for i in range(8): new_rock() clock.tick(FPS) # 取得输入 for event in pygame.event.get(): if event.type == pygame.QUIT: with open("file.txt", "w") as fp: fp.write(str(score)) fp.write('\n') fp.write(str(score1)) fp.write('\n') fp.write(str(score2)) fp.write('\n') fp.write(str(player.lives)) fp.write('\n') fp.write(str(player2.lives)) fp.write('\n') fp.write(str(int(player.health))) fp.write('\n') fp.write(str(int(player2.health))) running = False elif event.type == pygame.KEYDOWN: if event.key ==pygame.K_SPACE: player.shoot() if event.key == pygame.K_q: player2.shoot() # 更新游戏 all_sprites.update() # 判断石头、子弹碰撞 hits = pygame.sprite.groupcollide(rocks, bullets1, True, True) for hit in hits: random.choice(expl_sounds).play() score += hit.radius score1+=hit.radius expl = Explosion(hit.rect.center, 'lg') all_sprites.add(expl) if random.random() > 0.9: pow = Power(hit.rect.center) all_sprites.add(pow) powers.add(pow) new_rock() hits = pygame.sprite.groupcollide(rocks, bullets2, True, True) for hit in hits: random.choice(expl_sounds).play() score += hit.radius score2+=hit.radius expl = Explosion(hit.rect.center, 'lg') all_sprites.add(expl) if random.random() > 0.9: pow1 = Power(hit.rect.center) all_sprites.add(pow1) powers.add(pow1) new_rock() # 判断石头、飞机碰撞 hits = pygame.sprite.spritecollide(player, rocks, True, pygame.sprite.collide_circle) for hit in hits: new_rock() player.health -= hit.radius * 2 expl = Explosion(hit.rect.center, 'sm') all_sprites.add(expl) if player.health <= 0: player.gun=1 death_expl = Explosion(player.rect.center, 'player') all_sprites.add(death_expl) die_sound.play() player.lives -= 1 if player.lives<=0: player.hide2() player.health = 100 player.hide() hits = pygame.sprite.spritecollide(player2, rocks, True, pygame.sprite.collide_circle) for hit in hits: new_rock() player2.health -= hit.radius * 2 expl = Explosion(hit.rect.center, 'sm') all_sprites.add(expl) if player2.health <= 0: player2.gun = 1 death_expl = Explosion(player2.rect.center, 'player') all_sprites.add(death_expl) die_sound.play() player2.lives -= 1 if player2.lives<=0: player2.hide2() player2.health = 100 player2.hide() # 判断道具、飞机碰撞 hits = pygame.sprite.spritecollide(player, powers, True) for hit in hits: if hit.type == 'body': player.health += 20 if player.health > 100: player.health = 100 shield_sound.play() elif hit.type == 'shield': player.gunup() gun_sound.play() elif hit.type == 'gun': player.gunup1() player.speedx+=4 # player.gunup1() hits = pygame.sprite.spritecollide(player2, powers, True) for hit in hits: if hit.type == 'body': player2.health += 20 if player2.health > 100: player2.health = 100 shield_sound.play() elif hit.type == 'shield': player2.gunup() gun_sound.play() elif hit.type == 'gun': player2.gunup1() player2.speedx+=4 if player.lives==0 and player2.lives == 0 :#and not(death_expl.alive()): #close2=draw_init2() with open("file.txt", "w") as fp: fp.write(str(score)) fp.write('\n') fp.write(str(score1)) fp.write('\n') fp.write(str(score2)) close2 = draw_init2() if not(close2): close=False show_init = True else: break # 画面显示 screen.fill(BLACK) screen.blit(background_img, (0,0)) all_sprites.draw(screen) draw_text(screen, str(score), 18, WIDTH/2, 10) if player.lives>0: draw_health(screen, player.health, 5, 15) if player2.lives > 0: draw_health(screen, player2.health, 5, 30) draw_lives(screen, player.lives, player_mini_img, WIDTH - 100, 15) draw_lives(screen, player2.lives, player_mini_img, WIDTH - 100, 40) pygame.display.update() pygame.quit()