鱼C论坛

 找回密码
 立即注册
查看: 1868|回复: 13

[已解决]小甲鱼的飞机大战 中型机和大型机的血槽bug

[复制链接]
发表于 2020-3-20 18:27:03 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
一开始还是正常的越到后面会出现一些血槽为负的敌机
最佳答案
2020-3-20 19:01:29
  1. # -*- coding: utf-8 -*-
  2. # main.py
  3. import pygame
  4. import sys
  5. import traceback
  6. import myplane
  7. import enemy
  8. import bullet
  9. import supply

  10. from pygame.locals import *
  11. from random import *

  12. pygame.init()
  13. pygame.mixer.init()

  14. bg_size = width, height = 480, 700
  15. screen = pygame.display.set_mode(bg_size)
  16. pygame.display.set_caption("飞机大战")

  17. background = pygame.image.load("images/background.png").convert()

  18. BLACK = (0, 0, 0)
  19. WHITE = (255, 255, 255)
  20. GREEN = (0, 255, 0)
  21. RED = (255, 0, 0)

  22. # 载入游戏音乐
  23. pygame.mixer.music.load("sound/game_music.ogg")
  24. pygame.mixer.music.set_volume(0.2)
  25. bullet_sound = pygame.mixer.Sound("sound/bullet.wav")
  26. bullet_sound.set_volume(0.2)
  27. bomb_sound = pygame.mixer.Sound("sound/use_bomb.wav")
  28. bomb_sound.set_volume(0.2)
  29. supply_sound = pygame.mixer.Sound("sound/supply.wav")
  30. supply_sound.set_volume(0.2)
  31. get_bomb_sound = pygame.mixer.Sound("sound/get_bomb.wav")
  32. get_bomb_sound.set_volume(0.2)
  33. get_bullet_sound = pygame.mixer.Sound("sound/get_bullet.wav")
  34. get_bullet_sound.set_volume(0.2)
  35. upgrade_sound = pygame.mixer.Sound("sound/upgrade.wav")
  36. upgrade_sound.set_volume(0.2)
  37. enemy3_fly_sound = pygame.mixer.Sound("sound/enemy3_flying.wav")
  38. enemy3_fly_sound.set_volume(0.2)
  39. enemy1_down_sound = pygame.mixer.Sound("sound/enemy1_down.wav")
  40. enemy1_down_sound.set_volume(0.2)
  41. enemy2_down_sound = pygame.mixer.Sound("sound/enemy2_down.wav")
  42. enemy2_down_sound.set_volume(0.2)
  43. enemy3_down_sound = pygame.mixer.Sound("sound/enemy3_down.wav")
  44. enemy3_down_sound.set_volume(0.5)
  45. me_down_sound = pygame.mixer.Sound("sound/me_down.wav")
  46. me_down_sound.set_volume(0.2)


  47. def add_small_enemies(group1, group2, num):
  48.     for i in range(num):
  49.         e1 = enemy.SmallEnemy(bg_size)
  50.         group1.add(e1)
  51.         group2.add(e1)

  52. def add_mid_enemies(group1, group2, num):
  53.     for i in range(num):
  54.         e2 = enemy.MidEnemy(bg_size)
  55.         group1.add(e2)
  56.         group2.add(e2)

  57. def add_big_enemies(group1, group2, num):
  58.     for i in range(num):
  59.         e3 = enemy.BigEnemy(bg_size)
  60.         group1.add(e3)
  61.         group2.add(e3)

  62. def inc_speed(target, inc):
  63.     for each in target:
  64.         each.speed += inc

  65. def main():
  66.     pygame.mixer.music.play(-1)

  67.     # 生成我方飞机
  68.     me = myplane.MyPlane(bg_size)

  69.     enemies = pygame.sprite.Group()

  70.     # 生成敌方小型飞机
  71.     small_enemies = pygame.sprite.Group()
  72.     add_small_enemies(small_enemies, enemies, 15)

  73.     # 生成敌方中型飞机
  74.     mid_enemies = pygame.sprite.Group()
  75.     add_mid_enemies(mid_enemies, enemies, 4)

  76.     # 生成敌方大型飞机
  77.     big_enemies = pygame.sprite.Group()
  78.     add_big_enemies(big_enemies, enemies, 2)

  79.     # 生成普通子弹
  80.     bullet1 = []
  81.     bullet1_index = 0
  82.     BULLET1_NUM = 4
  83.     for i in range(BULLET1_NUM):
  84.         bullet1.append(bullet.Bullet1(me.rect.midtop))

  85.     # 生成超级子弹
  86.     bullet2 = []
  87.     bullet2_index = 0
  88.     BULLET2_NUM = 8
  89.     for i in range(BULLET2_NUM//2):
  90.         bullet2.append(bullet.Bullet2((me.rect.centerx-33, me.rect.centery)))
  91.         bullet2.append(bullet.Bullet2((me.rect.centerx+30, me.rect.centery)))

  92.     clock = pygame.time.Clock()

  93.     # 中弹图片索引
  94.     e1_destroy_index = 0
  95.     e2_destroy_index = 0
  96.     e3_destroy_index = 0
  97.     me_destroy_index = 0

  98.     # 统计得分
  99.     score = 0
  100.     score_font = pygame.font.Font("font/font.ttf", 36)

  101.     # 标志是否暂停游戏
  102.     paused = False
  103.     pause_nor_image = pygame.image.load("images/pause_nor.png").convert_alpha()
  104.     pause_pressed_image = pygame.image.load("images/pause_pressed.png").convert_alpha()
  105.     resume_nor_image = pygame.image.load("images/resume_nor.png").convert_alpha()
  106.     resume_pressed_image = pygame.image.load("images/resume_pressed.png").convert_alpha()
  107.     paused_rect = pause_nor_image.get_rect()
  108.     paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10
  109.     paused_image = pause_nor_image

  110.     # 设置难度级别
  111.     level = 1

  112.     # 全屏炸弹
  113.     bomb_image = pygame.image.load("images/bomb.png").convert_alpha()
  114.     bomb_rect = bomb_image.get_rect()
  115.     bomb_font = pygame.font.Font("font/font.ttf", 48)
  116.     bomb_num = 3

  117.     # 每30秒发放一个补给包
  118.     bullet_supply = supply.Bullet_Supply(bg_size)
  119.     bomb_supply = supply.Bomb_Supply(bg_size)
  120.     SUPPLY_TIME = USEREVENT
  121.     pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)

  122.     # 超级子弹定时器
  123.     DOUBLE_BULLET_TIME = USEREVENT + 1

  124.     # 标志是否使用超级子弹
  125.     is_double_bullet = False

  126.     # 解除我方无敌状态定时器
  127.     INVINCIBLE_TIME = USEREVENT + 2

  128.     # 生命数量
  129.     life_image = pygame.image.load("images/life.png").convert_alpha()
  130.     life_rect = life_image.get_rect()
  131.     life_num = 3

  132.     # 用于阻止重复打开记录文件
  133.     recorded = False

  134.     # 游戏结束画面
  135.     gameover_font = pygame.font.Font("font/font.TTF", 48)
  136.     again_image = pygame.image.load("images/again.png").convert_alpha()
  137.     again_rect = again_image.get_rect()
  138.     gameover_image = pygame.image.load("images/gameover.png").convert_alpha()
  139.     gameover_rect = gameover_image.get_rect()

  140.     # 用于切换图片
  141.     switch_image = True

  142.     # 用于延迟
  143.     delay = 100

  144.     running = True

  145.     while running:
  146.         for event in pygame.event.get():
  147.             if event.type == QUIT:
  148.                 pygame.quit()
  149.                 sys.exit()

  150.             elif event.type == MOUSEBUTTONDOWN:
  151.                 if event.button == 1 and paused_rect.collidepoint(event.pos):
  152.                     paused = not paused
  153.                     if paused:
  154.                         pygame.time.set_timer(SUPPLY_TIME, 0)
  155.                         pygame.mixer.music.pause()
  156.                         pygame.mixer.pause()
  157.                     else:
  158.                         pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)
  159.                         pygame.mixer.music.unpause()
  160.                         pygame.mixer.unpause()

  161.             elif event.type == MOUSEMOTION:
  162.                 if paused_rect.collidepoint(event.pos):
  163.                     if paused:
  164.                         paused_image = resume_pressed_image
  165.                     else:
  166.                         paused_image = pause_pressed_image
  167.                 else:
  168.                     if paused:
  169.                         paused_image = resume_nor_image
  170.                     else:
  171.                        paused_image = pause_nor_image

  172.             elif event.type == KEYDOWN:
  173.                 if event.key == K_SPACE:
  174.                     if bomb_num:
  175.                         bomb_num -= 1
  176.                         bomb_sound.play()
  177.                         for each in enemies:
  178.                             if each.rect.bottom > 0:
  179.                                 each.active = False

  180.             elif event.type == SUPPLY_TIME:
  181.                 supply_sound.play()
  182.                 if choice([True, False]):
  183.                     bomb_supply.reset()
  184.                 else:
  185.                     bullet_supply.reset()

  186.             elif event.type == DOUBLE_BULLET_TIME:
  187.                 is_double_bullet = False
  188.                 pygame.time.set_timer(DOUBLE_BULLET_TIME, 0)

  189.             elif event.type == INVINCIBLE_TIME:
  190.                 me.invincible = False
  191.                 pygame.time.set_timer(INVINCIBLE_TIME, 0)
  192.                         

  193.         # 根据用户的得分增加难度
  194.         if level == 1 and score > 50000:
  195.             level = 2
  196.             upgrade_sound.play()
  197.             # 增加3架小型敌机、2架中型敌机和1架大型敌机
  198.             add_small_enemies(small_enemies, enemies, 3)
  199.             add_mid_enemies(mid_enemies, enemies, 2)
  200.             add_big_enemies(big_enemies, enemies, 1)
  201.             # 提升小型敌机的速度
  202.             inc_speed(small_enemies, 1)
  203.         elif level == 2 and score > 300000:
  204.             level = 3
  205.             upgrade_sound.play()
  206.             # 增加5架小型敌机、3架中型敌机和2架大型敌机
  207.             add_small_enemies(small_enemies, enemies, 5)
  208.             add_mid_enemies(mid_enemies, enemies, 3)
  209.             add_big_enemies(big_enemies, enemies, 2)
  210.             # 提升小型敌机的速度
  211.             inc_speed(small_enemies, 1)
  212.             inc_speed(mid_enemies, 1)
  213.         elif level == 3 and score > 600000:
  214.             level = 4
  215.             upgrade_sound.play()
  216.             # 增加5架小型敌机、3架中型敌机和2架大型敌机
  217.             add_small_enemies(small_enemies, enemies, 5)
  218.             add_mid_enemies(mid_enemies, enemies, 3)
  219.             add_big_enemies(big_enemies, enemies, 2)
  220.             # 提升小型敌机的速度
  221.             inc_speed(small_enemies, 1)
  222.             inc_speed(mid_enemies, 1)
  223.         elif level == 4 and score > 1000000:
  224.             level = 5
  225.             upgrade_sound.play()
  226.             # 增加5架小型敌机、3架中型敌机和2架大型敌机
  227.             add_small_enemies(small_enemies, enemies, 5)
  228.             add_mid_enemies(mid_enemies, enemies, 3)
  229.             add_big_enemies(big_enemies, enemies, 2)
  230.             # 提升小型敌机的速度
  231.             inc_speed(small_enemies, 1)
  232.             inc_speed(mid_enemies, 1)
  233.             

  234.         screen.blit(background, (0, 0))
  235.                
  236.         if life_num and not paused:
  237.             # 检测用户的键盘操作
  238.             key_pressed = pygame.key.get_pressed()

  239.             if key_pressed[K_w] or key_pressed[K_UP]:
  240.                 me.moveUp()
  241.             if key_pressed[K_s] or key_pressed[K_DOWN]:
  242.                 me.moveDown()
  243.             if key_pressed[K_a] or key_pressed[K_LEFT]:
  244.                 me.moveLeft()
  245.             if key_pressed[K_d] or key_pressed[K_RIGHT]:
  246.                 me.moveRight()

  247.             # 绘制全屏炸弹补给并检测是否获得
  248.             if bomb_supply.active:
  249.                 bomb_supply.move()
  250.                 screen.blit(bomb_supply.image, bomb_supply.rect)
  251.                 if pygame.sprite.collide_mask(bomb_supply, me):
  252.                     get_bomb_sound.play()
  253.                     bomb_num += 1
  254.                     bomb_supply.active = False

  255.             # 绘制超级子弹补给并检测是否获得
  256.             if bullet_supply.active:
  257.                 bullet_supply.move()
  258.                 screen.blit(bullet_supply.image, bullet_supply.rect)
  259.                 if pygame.sprite.collide_mask(bullet_supply, me):
  260.                     get_bullet_sound.play()
  261.                     is_double_bullet = True
  262.                     pygame.time.set_timer(DOUBLE_BULLET_TIME, 18 * 1000)
  263.                     bullet_supply.active = False

  264.             # 发射子弹
  265.             if not(delay % 10):
  266.                 bullet_sound.play()
  267.                 if is_double_bullet:
  268.                     bullets = bullet2
  269.                     bullets[bullet2_index].reset((me.rect.centerx-33, me.rect.centery))
  270.                     bullets[bullet2_index+1].reset((me.rect.centerx+30, me.rect.centery))
  271.                     bullet2_index = (bullet2_index + 2) % BULLET2_NUM
  272.                 else:
  273.                     bullets = bullet1
  274.                     bullets[bullet1_index].reset(me.rect.midtop)
  275.                     bullet1_index = (bullet1_index + 1) % BULLET1_NUM

  276.                
  277.             # 检测子弹是否击中敌机
  278.             for b in bullets:
  279.                 if b.active:
  280.                     b.move()
  281.                     screen.blit(b.image, b.rect)
  282.                     enemy_hit = pygame.sprite.spritecollide(b, enemies, False, pygame.sprite.collide_mask)
  283.                     if enemy_hit:
  284.                         b.active = False
  285.                         for e in enemy_hit:
  286.                             if e in mid_enemies or e in big_enemies:
  287.                                 e.hit = True
  288.                                 e.energy -= 1
  289.                                 if e.energy == 0:
  290.                                     e.active = False
  291.                             else:
  292.                                 e.active = False
  293.             
  294.             # 绘制大型敌机
  295.             for each in big_enemies:
  296.                 if each.active:
  297.                     each.move()
  298.                     if each.hit:
  299.                         screen.blit(each.image_hit, each.rect)
  300.                         each.hit = False
  301.                     else:
  302.                         if switch_image:
  303.                             screen.blit(each.image1, each.rect)
  304.                         else:
  305.                             screen.blit(each.image2, each.rect)

  306.                     # 绘制血槽
  307.                     pygame.draw.line(screen, BLACK, \
  308.                                      (each.rect.left, each.rect.top - 5), \
  309.                                      (each.rect.right, each.rect.top - 5), \
  310.                                      2)
  311.                     # 当生命大于20%显示绿色,否则显示红色
  312.                     energy_remain = each.energy / enemy.BigEnemy.energy
  313.                     if energy_remain > 0.2:
  314.                         energy_color = GREEN
  315.                     else:
  316.                         energy_color = RED
  317.                     pygame.draw.line(screen, energy_color, \
  318.                                      (each.rect.left, each.rect.top - 5), \
  319.                                      (each.rect.left + each.rect.width * energy_remain, \
  320.                                       each.rect.top - 5), 2)
  321.                         
  322.                     # 即将出现在画面中,播放音效
  323.                     if each.rect.bottom == -50:
  324.                         enemy3_fly_sound.play(-1)
  325.                 else:
  326.                     # 毁灭
  327.                     if not(delay % 3):
  328.                         if e3_destroy_index == 0:
  329.                             enemy3_down_sound.play()
  330.                         screen.blit(each.destroy_images[e3_destroy_index], each.rect)
  331.                         e3_destroy_index = (e3_destroy_index + 1) % 6
  332.                         if e3_destroy_index == 0:
  333.                             enemy3_fly_sound.stop()
  334.                             score += 10000
  335.                             each.reset()

  336.             # 绘制中型敌机:
  337.             for each in mid_enemies:
  338.                 if each.active:
  339.                     each.move()

  340.                     if each.hit:
  341.                         screen.blit(each.image_hit, each.rect)
  342.                         each.hit = False
  343.                     else:
  344.                         screen.blit(each.image, each.rect)

  345.                     # 绘制血槽
  346.                     pygame.draw.line(screen, BLACK, \
  347.                                      (each.rect.left, each.rect.top - 5), \
  348.                                      (each.rect.right, each.rect.top - 5), \
  349.                                      2)
  350.                     # 当生命大于20%显示绿色,否则显示红色
  351.                     energy_remain = each.energy / enemy.MidEnemy.energy
  352.                     if energy_remain > 0.2:
  353.                         energy_color = GREEN
  354.                     else:
  355.                         energy_color = RED
  356.                     pygame.draw.line(screen, energy_color, \
  357.                                      (each.rect.left, each.rect.top - 5), \
  358.                                      (each.rect.left + each.rect.width * energy_remain, \
  359.                                       each.rect.top - 5), 2)
  360.                 else:
  361.                     # 毁灭
  362.                     if not(delay % 3):
  363.                         if e2_destroy_index == 0:
  364.                             enemy2_down_sound.play()
  365.                         screen.blit(each.destroy_images[e2_destroy_index], each.rect)
  366.                         e2_destroy_index = (e2_destroy_index + 1) % 4
  367.                         if e2_destroy_index == 0:
  368.                             score += 6000
  369.                             each.reset()

  370.             # 绘制小型敌机:
  371.             for each in small_enemies:
  372.                 if each.active:
  373.                     each.move()
  374.                     screen.blit(each.image, each.rect)
  375.                 else:
  376.                     # 毁灭
  377.                     if not(delay % 3):
  378.                         if e1_destroy_index == 0:
  379.                             enemy1_down_sound.play()
  380.                         screen.blit(each.destroy_images[e1_destroy_index], each.rect)
  381.                         e1_destroy_index = (e1_destroy_index + 1) % 4
  382.                         if e1_destroy_index == 0:
  383.                             score += 1000
  384.                             each.reset()

  385.             # 检测我方飞机是否被撞
  386.             enemies_down = pygame.sprite.spritecollide(me, enemies, False, pygame.sprite.collide_mask)
  387.             if enemies_down and not me.invincible:
  388.                 me.active = False
  389.                 for e in enemies_down:
  390.                     e.active = False
  391.             
  392.             # 绘制我方飞机
  393.             if me.active:
  394.                 if switch_image:
  395.                     screen.blit(me.image1, me.rect)
  396.                 else:
  397.                     screen.blit(me.image2, me.rect)
  398.             else:
  399.                 # 毁灭
  400.                 if not(delay % 3):
  401.                     if me_destroy_index == 0:
  402.                         me_down_sound.play()
  403.                     screen.blit(me.destroy_images[me_destroy_index], me.rect)
  404.                     me_destroy_index = (me_destroy_index + 1) % 4
  405.                     if me_destroy_index == 0:
  406.                         life_num -= 1
  407.                         me.reset()
  408.                         pygame.time.set_timer(INVINCIBLE_TIME, 3 * 1000)

  409.             # 绘制全屏炸弹数量
  410.             bomb_text = bomb_font.render(" X %d" % bomb_num, True, WHITE)
  411.             text_rect = bomb_text.get_rect()
  412.             screen.blit(bomb_image, (10, height - 10 - bomb_rect.height))
  413.             screen.blit(bomb_text, (20 + bomb_rect.width, height - 5 - text_rect.height))

  414.             # 绘制剩余生命数量
  415.             if life_num:
  416.                 for i in range(life_num):
  417.                     screen.blit(life_image, \
  418.                                 (width-10-(i+1)*life_rect.width, \
  419.                                  height-10-life_rect.height))

  420.             # 绘制得分
  421.             score_text = score_font.render("Score : %s" % str(score), True, WHITE)
  422.             screen.blit(score_text, (10, 5))

  423.         # 绘制游戏结束画面
  424.         elif life_num == 0:
  425.             # 背景音乐停止
  426.             pygame.mixer.music.stop()

  427.             # 停止全部音效
  428.             pygame.mixer.stop()

  429.             # 停止发放补给
  430.             pygame.time.set_timer(SUPPLY_TIME, 0)

  431.             if not recorded:
  432.                 recorded = True
  433.                 # 读取历史最高得分
  434.                 with open("record.txt", "r") as f:
  435.                     record_score = int(f.read())

  436.                 # 如果玩家得分高于历史最高得分,则存档
  437.                 if score > record_score:
  438.                     with open("record.txt", "w") as f:
  439.                         f.write(str(score))

  440.             # 绘制结束画面
  441.             record_score_text = score_font.render("Best : %d" % record_score, True, (255, 255, 255))
  442.             screen.blit(record_score_text, (50, 50))
  443.             
  444.             gameover_text1 = gameover_font.render("Your Score", True, (255, 255, 255))
  445.             gameover_text1_rect = gameover_text1.get_rect()
  446.             gameover_text1_rect.left, gameover_text1_rect.top = \
  447.                                  (width - gameover_text1_rect.width) // 2, height // 3
  448.             screen.blit(gameover_text1, gameover_text1_rect)
  449.             
  450.             gameover_text2 = gameover_font.render(str(score), True, (255, 255, 255))
  451.             gameover_text2_rect = gameover_text2.get_rect()
  452.             gameover_text2_rect.left, gameover_text2_rect.top = \
  453.                                  (width - gameover_text2_rect.width) // 2, \
  454.                                  gameover_text1_rect.bottom + 10
  455.             screen.blit(gameover_text2, gameover_text2_rect)

  456.             again_rect.left, again_rect.top = \
  457.                              (width - again_rect.width) // 2, \
  458.                              gameover_text2_rect.bottom + 50
  459.             screen.blit(again_image, again_rect)

  460.             gameover_rect.left, gameover_rect.top = \
  461.                                 (width - again_rect.width) // 2, \
  462.                                 again_rect.bottom + 10
  463.             screen.blit(gameover_image, gameover_rect)

  464.             # 检测用户的鼠标操作
  465.             # 如果用户按下鼠标左键
  466.             if pygame.mouse.get_pressed()[0]:
  467.                 # 获取鼠标坐标
  468.                 pos = pygame.mouse.get_pos()
  469.                 # 如果用户点击“重新开始”
  470.                 if again_rect.left < pos[0] < again_rect.right and \
  471.                    again_rect.top < pos[1] < again_rect.bottom:
  472.                     # 调用main函数,重新开始游戏
  473.                     main()
  474.                 # 如果用户点击“结束游戏”            
  475.                 elif gameover_rect.left < pos[0] < gameover_rect.right and \
  476.                      gameover_rect.top < pos[1] < gameover_rect.bottom:
  477.                     # 退出游戏
  478.                     pygame.quit()
  479.                     sys.exit()      

  480.         # 绘制暂停按钮
  481.         screen.blit(paused_image, paused_rect)

  482.         # 切换图片
  483.         if not(delay % 5):
  484.             switch_image = not switch_image

  485.         delay -= 1
  486.         if not delay:
  487.             delay = 100

  488.         pygame.display.flip()
  489.         clock.tick(60)
  490.         
  491. if __name__ == "__main__":
  492.     try:
  493.         main()
  494.     except SystemExit:
  495.         pass
  496.     except:
  497.         traceback.print_exc()
  498.         pygame.quit()
  499.         input()

复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-3-20 18:30:06 | 显示全部楼层
???
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-3-20 18:40:18 | 显示全部楼层
emmmmmm………………代码发一下呗
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-20 18:53:20 | 显示全部楼层
乘号 发表于 2020-3-20 18:40
emmmmmm………………代码发一下呗

ok
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-20 18:55:15 | 显示全部楼层
main函数:





from random import choice

import pygame
import sys
import traceback
import myplane
import enemy
import bullet
import supply
from pygame.locals import *

pygame.init()
pygame.mixer.init()

bg_size = width, height = 480, 700
screen = pygame.display.set_mode(bg_size)
pygame.display.set_caption("打飞机 ------ denngyu Demo")

background = pygame.image.load("images/background.png").convert()

WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
RED = (255, 0, 0)

#载入游戏音乐
pygame.mixer.music.load("sound/game_music.ogg")
pygame.mixer.music.set_volume(0.2)
bullet_sound = pygame.mixer.Sound("sound/bullet.wav")
bullet_sound.set_volume(0.2)
bomb_sound = pygame.mixer.Sound("sound/use_bomb.wav")
bomb_sound.set_volume(0.2)
supply_sound = pygame.mixer.Sound("sound/supply.wav")
supply_sound.set_volume(0.2)
get_bomb_sound = pygame.mixer.Sound("sound/get_bomb.wav")
get_bomb_sound.set_volume(0.2)
get_bullet_sound = pygame.mixer.Sound("sound/get_bullet.wav")
get_bullet_sound.set_volume(0.2)
upgrade_sound = pygame.mixer.Sound("sound/upgrade.wav")
upgrade_sound.set_volume(0.2)
enemy3_fly_sound = pygame.mixer.Sound("sound/enemy3_flying.wav")
enemy3_fly_sound.set_volume(0.2)
enemy1_down_sound = pygame.mixer.Sound("sound/enemy1_down.wav")
enemy1_down_sound.set_volume(0.2)
enemy2_down_sound = pygame.mixer.Sound("sound/enemy2_down.wav")
enemy2_down_sound.set_volume(0.2)
enemy3_down_sound = pygame.mixer.Sound("sound/enemy3_down.wav")
enemy3_down_sound.set_volume(0.5)
me_down_sound = pygame.mixer.Sound("sound/me_down.wav")
me_down_sound.set_volume(0.2)

def add_small_enemies(grop1,grop2,num):
    for i in range(num):
        e1 = enemy.SmallEnemy(bg_size)
        grop1.add(e1)
        grop2.add(e1)

def add_mid_enemies(grop1,grop2,num):
    for i in range(num):
        e2 = enemy.MidEnemy(bg_size)
        grop1.add(e2)
        grop2.add(e2)


def add_big_enemies(grop1,grop2,num):
    for i in range(num):
        e3 = enemy.BigEnemy(bg_size)
        grop1.add(e3)
        grop2.add(e3)

def inc_speed(target, inc):
    for each in target:
        each.speed += inc

def main():
    pygame.mixer.music.play(-1)


    # 生成我方飞机
    me = myplane.MyPlane(bg_size)

    # 敌方飞机集合
    enemies = pygame.sprite.Group()

    # 生成敌方小飞机
    small_enemies = pygame.sprite.Group()
    add_small_enemies(small_enemies,enemies,15)

    # 生成敌方中飞机
    mid_enemies = pygame.sprite.Group()
    add_mid_enemies(mid_enemies, enemies, 4)

    # 生成敌方大飞机
    big_enemies = pygame.sprite.Group()
    add_big_enemies(big_enemies, enemies, 2)

    #生产超级子弹
    bullet2 = []
    bullet2_index = 0
    BULLET2_NUM = 8
    for i in range(BULLET2_NUM//2):
        bullet2.append(bullet.Bullet2((me.rect.centerx - 33, me.rect.centery)))
        bullet2.append(bullet.Bullet2((me.rect.centerx + 30, me.rect.centery)))

    #生成普通子弹
    bullet1 = []
    bullet1_index = 0
    BULLET1_NUM = 4
    for i in range(BULLET1_NUM):
        bullet1.append(bullet.Bullet1(me.rect.midtop))

    clock = pygame.time.Clock()

    #中弹图片索引
    e1_destory_index = 0
    e2_destory_index = 0
    e3_destory_index = 0
    me_destroy_index = 0

    # 统计得分
    score = 0
    score_font = pygame.font.Font("font/font.ttf",36)

    # 表志是否暂停游戏
    paused = False
    pause_nor_image = pygame.image.load("images/pause_nor.png").convert_alpha()
    pause_pressed_image = pygame.image.load("images/pause_pressed.png").convert_alpha()
    resume_nor_image = pygame.image.load("images/resume_nor.png").convert_alpha()
    resume_pressed_image = pygame.image.load("images/resume_pressed.png").convert_alpha()
    paused_rect = pause_nor_image.get_rect()
    paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10
    paused_image = pause_nor_image

    #设置难度级别
    level = 1

    #全屏炸弹
    bomb_image = pygame.image.load("images/bomb.png").convert_alpha()
    bomb_rect = bomb_image.get_rect()
    bomb_font = pygame.font.Font("font/font.ttf",48)
    bomb_num = 3

    #每三十秒出发补给
    bullet_supply = supply.Bullet_Supply(bg_size)
    bomb_supply = supply.Bomb_Supply(bg_size)
    SUPPLY_TIME = USEREVENT
    pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)

    #超级子弹定时器
    DOUBLE_BULLET_TIME = USEREVENT + 1

    #标志是否使用子弹
    is_double_bullet = False

    #解除无敌计时器
    INVINCIBLE_TIME = USEREVENT + 2

    #生命值
    life_image = pygame.image.load("images/life.png").convert_alpha()
    life_rect = life_image.get_rect()
    life_num = 3

    #游戏结束画面
    gameover_font = pygame.font.Font("font/font.ttf",48)
    again_image = pygame.image.load("images/again.png").convert_alpha()
    again_rect = again_image.get_rect()
    gameover_image = pygame.image.load("images/gameover.png").convert_alpha()
    gameover_rect = gameover_image.get_rect()


    #用于阻止重复打开记录文件
    recorded = False

    #用于切换图片
    swich_image = True

    #用于延时
    delay = 100



    running = True

    while running:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()

            elif event.type == MOUSEBUTTONDOWN:
                if event.button == 1 and paused_rect.collidepoint(event.pos):
                    paused = not paused
                    if paused:
                        pygame.time.set_timer(SUPPLY_TIME, 0)
                        pygame.mixer.music.pause()
                        pygame.mixer.pause()
                    else:
                        pygame.time.set_timer(SUPPLY_TIME, 30*1000)
                        pygame.mixer.music.unpause()
                        pygame.mixer.unpause()

            elif event.type == MOUSEMOTION:
                if paused_rect.collidepoint(event.pos):
                    if paused:
                        paused_image = resume_pressed_image
                    else:
                        paused_image = pause_pressed_image
                else:
                    if paused:
                        paused_image = resume_nor_image
                    else:
                        paused_image = pause_nor_image

            elif event.type == KEYDOWN:
                if event.key == K_SPACE:
                    if bomb_num:
                        bomb_num -= 1
                        bomb_sound.play()
                        for each in enemies:
                            if each.rect.bottom > 0:
                                each.active = False


            elif event.type == SUPPLY_TIME:
                supply_sound.play()
                if choice([True, False]):
                    bomb_supply.reset()
                else:
                    bullet_supply.reset()

            elif event.type == DOUBLE_BULLET_TIME:
                is_double_bullet = False
                pygame.time.set_timer(DOUBLE_BULLET_TIME, 0)

            elif event.type == INVINCIBLE_TIME:
                me.invincible = False
                pygame.time.set_timer(INVINCIBLE_TIME, 0)

        #根据得分增加难度
        if level == 1 and score > 50000:
            level = 2
            upgrade_sound.play()
            #增加3小,两中,一大
            add_small_enemies(small_enemies, enemies, 3)
            add_mid_enemies(mid_enemies, enemies, 2)
            add_big_enemies(big_enemies,enemies,1)
            # 提升小机速度
            inc_speed(small_enemies,1)
        elif level == 2 and score > 300000:
            level = 3
            upgrade_sound.play()
            #增加5小,3中,2大
            add_small_enemies(small_enemies, enemies, 5)
            add_mid_enemies(mid_enemies, enemies, 3)
            add_big_enemies(big_enemies,enemies,2)
            # 提升小机速度
            inc_speed(small_enemies,1)
            inc_speed(mid_enemies, 1)
        elif level == 3 and score > 600000:
            level = 4
            upgrade_sound.play()
            #增加5小,3中,2大
            add_small_enemies(small_enemies, enemies, 5)
            add_mid_enemies(mid_enemies, enemies, 3)
            add_big_enemies(big_enemies,enemies,2)
            # 提升小机速度
            inc_speed(small_enemies,1)
            inc_speed(mid_enemies, 1)
        elif level == 4 and score > 1000000:
            level = 5
            upgrade_sound.play()
            #增加5小,3中,2大
            add_small_enemies(small_enemies, enemies, 5)
            add_mid_enemies(mid_enemies, enemies, 3)
            add_big_enemies(big_enemies,enemies,2)
            # 提升小机速度
            inc_speed(small_enemies,1)
            inc_speed(mid_enemies, 1)



        screen.blit(background, (0, 0))

        if life_num and not paused:
             #检测用户键盘操作
            key_pressed = pygame.key.get_pressed()

            if key_pressed[K_w] or key_pressed[K_UP]:
                me.moveUp()
            if key_pressed[K_s] or key_pressed[K_DOWN]:
                me.moveDown()
            if key_pressed[K_a] or key_pressed[K_LEFT]:
                me.moveLeft()
            if key_pressed[K_d] or key_pressed[K_RIGHT]:
                me.moveRight()

            #绘制炸弹补给并检测是否得到
            if bomb_supply.active:
                bomb_supply.move()
                screen.blit(bomb_supply.image,bomb_supply.rect)
                if pygame.sprite.collide_mask(bomb_supply, me):
                    get_bomb_sound.play()
                    if bomb_num < 3:
                        bomb_num += 1
                    bomb_supply.active = False

             # 绘制子弹补给并检测是否得到
            if bullet_supply.active:
                 bullet_supply.move()
                 screen.blit(bullet_supply.image, bullet_supply.rect)
                 if pygame.sprite.collide_mask(bullet_supply, me):
                     get_bullet_sound.play()
                     is_double_bullet = True
                     pygame.time.set_timer(DOUBLE_BULLET_TIME, 18 * 1000)
                     bullet_supply.active = False

            #发射子弹
            if not(delay % 10):
                bullet_sound.play()
                if is_double_bullet:
                    bullets = bullet2
                    bullets[bullet2_index].reset((me.rect.centerx-33, me.rect.centery))
                    bullets[bullet2_index+1].reset((me.rect.centerx + 30, me.rect.centery))
                    bullet2_index = (bullet2_index + 2) % BULLET2_NUM
                else:
                    bullets = bullet1
                    bullets[bullet1_index].reset(me.rect.midtop)
                    bullet1_index = (bullet1_index + 1) % BULLET1_NUM

            #检测子弹是否中机
            for b in bullets:
                if b.active:
                    b.move()
                    screen.blit(b.image, b.rect)
                    enemy_hit = pygame.sprite.spritecollide(b,enemies, False, pygame.sprite.collide_mask)
                    if enemy_hit:
                        b.active = False
                        for e in enemy_hit:
                            if e in mid_enemies or e in big_enemies:
                                e.hit = True
                                e.energy -= 1
                                if e.energy <= 0:
                                    e.active = False
                            else:
                                e.active = False
            #绘制大型机
            for each in big_enemies:
                if each.active:
                    each.move()
                    if each.hit:
                        #绘制被打特效
                        screen.blit(each.image_hit,each.rect)
                        each.hit = False
                    else:
                        if swich_image:
                            screen.blit(each.image1, each.rect)
                        else:
                            screen.blit(each.image2, each.rect)

                    # 绘制血槽
                    pygame.draw.line(screen, BLACK, \
                                     (each.rect.left,each.rect.top - 5), \
                                     (each.rect.right, each.rect.top - 5),\
                                     2)
                    #当生命大于20%绿色,否则红色
                    enemy_remain = each.energy / enemy.BigEnemy.energy
                    if enemy_remain > 0.2:
                        energy_color = GREEN
                    else:
                        energy_color = RED
                    pygame.draw.line(screen, energy_color, \
                                     (each.rect.left,each.rect.top - 5),\
                                     (each.rect.left + each.rect.width * enemy_remain ,\
                                     each.rect.top - 5), \
                                     2)

                    #即将出现时,播放音效
                    if each.rect.bottom == -50:
                        enemy3_fly_sound.play(-1)
                else:
                    #毁灭
                    if not(delay % 3):
                        if e3_destory_index == 0:
                            enemy3_down_sound.play()
                        screen.blit(each.destroy_images[e3_destory_index], each.rect)
                        e3_destory_index = (e3_destory_index + 1) % 6
                        if e3_destory_index == 0:
                            enemy3_fly_sound.stop()
                            score += 10000
                            each.reset()


            #绘制中型机:
            for each in mid_enemies:
                if each.active:
                    each.move()

                    if each.hit:
                        screen.blit(each.image_hit, each.rect)
                        each.hit = False
                    else:
                        screen.blit(each.image,each.rect)

                    # 绘制血槽
                    pygame.draw.line(screen, BLACK, \
                            (each.rect.left, each.rect.top - 5), \
                            (each.rect.right, each.rect.top - 5), \
                            2)
                    # 当生命大于20%绿色,否则红色
                    energy_remain = each.energy / enemy.MidEnemy.energy
                    if energy_remain > 0.2:
                        energy_color = GREEN
                    else:
                        energy_color = RED
                    pygame.draw.line(screen, energy_color, \
                                     (each.rect.left, each.rect.top - 5), \
                                     (each.rect.left + each.rect.width * energy_remain, \
                                      each.rect.top - 5), 2)

                else:
                    #毁灭

                    if not(delay % 3):
                        if e2_destory_index == 0:
                            enemy2_down_sound.play()
                        screen.blit(each.destroy_images[e2_destory_index], each.rect)
                        e2_destory_index = (e2_destory_index + 1) % 4
                        if e2_destory_index == 0:
                            score += 6000
                            each.reset()

            #绘制小型机
            for each in small_enemies:
                if each.active:
                    each.move()
                    screen.blit(each.image, each.rect)
                else:
                    #毁灭
                    if not(delay % 3):
                        if e1_destory_index == 0:
                            enemy1_down_sound.play()
                        screen.blit(each.destroy_images[e1_destory_index], each.rect)
                        e1_destory_index = (e1_destory_index + 1) % 4
                        if e1_destory_index == 0:
                            score += 1000
                            each.reset()

            #检测我方飞机是否被撞
            enemies_down = pygame.sprite.spritecollide(me, enemies, False, pygame.sprite.collide_mask)
            if enemies_down and not me.invincible:
                me.active = False
                for e in enemies_down:
                    e.active = False

            #绘制我方飞机
            swich_image = not swich_image
            if me.active:
                if swich_image:
                    screen.blit(me.image1, me.rect)
                else:
                    screen.blit(me.image2, me.rect)
            else:
                # 毁灭
                if not (delay % 3):
                    if me_destroy_index == 0:
                        me_down_sound.play()
                    screen.blit(me.destroy_images[me_destroy_index], me.rect)
                    me_destroy_index = (me_destroy_index + 1) % 4
                    if me_destroy_index == 0:
                        life_num -= 1
                        #重生
                        me.reset()
                        pygame.time.set_timer(INVINCIBLE_TIME, 3 * 1000)

            # 绘制炸弹数量
            bomb_text = bomb_font.render("x %d" % bomb_num,True, WHITE)
            text_rect = bomb_text.get_rect()
            screen.blit(bomb_image,(10, height - 10 - bomb_rect.height))
            screen.blit(bomb_text, (20 + bomb_rect.width, height - 5 -text_rect.height))

            #绘制剩余生命数量
            if life_num:
                for i in range(life_num):
                    screen.blit(life_image, \
                                (width-10-(i+1)*life_rect.width, \
                                 height-10-life_rect.height))

            # 绘制得分
            score_text = score_font.render("Score : %s" % str(score), True, WHITE)
            screen.blit(score_text, (10, 5))

        #绘制游戏结束
        elif life_num == 0:
            # 背景音乐停止
            pygame.mixer.music.stop()

            # 停止全部音效
            pygame.mixer.stop()

            #停止补给
            pygame.time.set_timer(SUPPLY_TIME, 0)

            if not recorded:
                #读取历史最好的得分
                with open ("record.txt","r") as f:
                    record_score = int (f.read())
                #更新历史最高分
                if score > record_score:
                    with open("record.txt","w") as f:
                        f.write(str(score))

            #绘制结束界面
            record_score_text = score_font.render("Best:%d"%record_score, True,(255,255,255))
            screen.blit(record_score_text, (50,50))

            gameover_text1 = gameover_font.render("Your Score", True, (255, 255, 255))
            gameover_text1_rect = gameover_text1.get_rect()
            gameover_text1_rect.left, gameover_text1_rect.top = \
                (width - gameover_text1_rect.width) // 2, height // 3
            screen.blit(gameover_text1, gameover_text1_rect)

            gameover_text2 = gameover_font.render(str(score), True, (255, 255, 255))
            gameover_text2_rect = gameover_text2.get_rect()
            gameover_text2_rect.left, gameover_text2_rect.top = \
                (width - gameover_text2_rect.width) // 2, \
                gameover_text1_rect.bottom + 10
            screen.blit(gameover_text2, gameover_text2_rect)

            again_rect.left, again_rect.top = \
                (width - again_rect.width) // 2, \
                gameover_text2_rect.bottom + 50
            screen.blit(again_image, again_rect)

            gameover_rect.left, gameover_rect.top = \
                (width - again_rect.width) // 2, \
                again_rect.bottom + 10
            screen.blit(gameover_image, gameover_rect)

            # 检测用户的鼠标操作
            # 如果用户按下鼠标左键
            if pygame.mouse.get_pressed()[0]:
                # 获取鼠标坐标
                pos = pygame.mouse.get_pos()
                # 如果用户点击“重新开始”
                if again_rect.left < pos[0] < again_rect.right and \
                        again_rect.top < pos[1] < again_rect.bottom:
                    # 调用main函数,重新开始游戏
                    main()
                # 如果用户点击“结束游戏”
                elif gameover_rect.left < pos[0] < gameover_rect.right and \
                        gameover_rect.top < pos[1] < gameover_rect.bottom:
                    # 退出游戏
                    pygame.quit()
                    sys.exit()



        # 绘制暂停按钮
        screen.blit(paused_image, paused_rect)

        #切换图
        if not(delay % 5):
            swich_image = not swich_image

        delay -= 1
        if not delay:
            delay = 100

        pygame.display.flip()
        clock.tick(60)

if __name__ == "__main__":
    try:
        main()
    except SystemExit:
        pass
    except:
        traceback.print_exc()
        pygame,quit()
        input()
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-20 18:56:00 | 显示全部楼层
敌机:

import pygame
from random import *

class SmallEnemy(pygame.sprite.Sprite):
    def __init__(self, bg_size):
        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.image.load("images/enemy1.png").convert_alpha()
        self.destroy_images = []
        self.destroy_images.extend([\
            pygame.image.load("images/enemy1_down1.png").convert_alpha(), \
            pygame.image.load("images/enemy1_down2.png").convert_alpha(), \
            pygame.image.load("images/enemy1_down3.png").convert_alpha(), \
            pygame.image.load("images/enemy1_down4.png").convert_alpha()\
            ])
        self.rect = self.image.get_rect()
        self.width,self.height = bg_size[0], bg_size[1]
        self.speed = 2
        self.active = True
        self.rect.left,self.rect.top = \
                        randint(0, self.width - self.rect.width), \
                        randint(-5 * self.height, 0)
        self.mask = pygame.mask.from_surface(self.image)

    def move(self):
        if self.rect.top < self.height:
            self.rect.top += self.speed
        else:
            self.reset()

    def reset(self):
        self.active = True
        self.rect.left, self.rect.top = \
                        randint(0, self.width - self.rect.width), \
                        randint(-5 * self.height, 0)

class MidEnemy(pygame.sprite.Sprite):
    energy = 8
    def __init__(self, bg_size):
        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.image.load("images/enemy2.png").convert_alpha()
        self.image_hit = pygame.image.load("images/enemy2_hit.png").convert_alpha()
        self.destroy_images = []
        self.destroy_images.extend([ \
            pygame.image.load("images/enemy2_down1.png").convert_alpha(), \
            pygame.image.load("images/enemy2_down2.png").convert_alpha(), \
            pygame.image.load("images/enemy2_down3.png").convert_alpha(), \
            pygame.image.load("images/enemy2_down4.png").convert_alpha() \
            ])
        self.rect = self.image.get_rect()
        self.width,self.height = bg_size[0], bg_size[1]
        self.speed = 1
        self.active = True
        self.rect.left,self.rect.top = \
                        randint(0, self.width - self.rect.width), \
                        randint(-10 * self.height, -self.height)
        self.mask = pygame.mask.from_surface(self.image)
        self.ennergy = MidEnemy.energy
        self.hit = False

    def move(self):
        if self.rect.top < self.height:
            self.rect.top += self.speed
        else:
            self.reset()

    def reset(self):
        self.active = True
        self.ennergy = MidEnemy.energy
        self.rect.left, self.rect.top = \
                        randint(0, self.width - self.rect.width), \
                        randint(-10 * self.height, -self.height)

class BigEnemy(pygame.sprite.Sprite):
    energy = 20

    def __init__(self,bg_size):
        pygame.sprite.Sprite.__init__(self)

        self.image1 = pygame.image.load("images/enemy3_n1.png").convert_alpha()
        self.image2 = pygame.image.load("images/enemy3_n2.png").convert_alpha()
        self.image_hit = pygame.image.load("images/enemy3_hit.png").convert_alpha()
        self.destroy_images = []
        self.destroy_images.extend([ \
            pygame.image.load("images/enemy3_down1.png").convert_alpha(), \
            pygame.image.load("images/enemy3_down2.png").convert_alpha(), \
            pygame.image.load("images/enemy3_down3.png").convert_alpha(), \
            pygame.image.load("images/enemy3_down4.png").convert_alpha(), \
            pygame.image.load("images/enemy3_down5.png").convert_alpha(), \
            pygame.image.load("images/enemy3_down6.png").convert_alpha() \
            ])
        self.rect = self.image1.get_rect()
        self.width,self.height = bg_size[0], bg_size[1]
        self.speed = 1
        self.active = True
        self.rect.left,self.rect.top = \
                        randint(0, self.width - self.rect.width), \
                        randint(-15 * self.height, -5 * self.height)
        self.mask = pygame.mask.from_surface(self.image1)
        self.ennergy = BigEnemy.energy
        self.hit = False

    def move(self):
        if self.rect.top < self.height:
            self.rect.top += self.speed
        else:
            self.reset()

    def reset(self):
        self.active = True
        self.ennergy = BigEnemy.energy
        self.rect.left, self.rect.top = \
                        randint(0, self.width - self.rect.width), \
                        randint(-10 * self.height, -self.height)

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-20 19:01:29 | 显示全部楼层    本楼为最佳答案   
  1. # -*- coding: utf-8 -*-
  2. # main.py
  3. import pygame
  4. import sys
  5. import traceback
  6. import myplane
  7. import enemy
  8. import bullet
  9. import supply

  10. from pygame.locals import *
  11. from random import *

  12. pygame.init()
  13. pygame.mixer.init()

  14. bg_size = width, height = 480, 700
  15. screen = pygame.display.set_mode(bg_size)
  16. pygame.display.set_caption("飞机大战")

  17. background = pygame.image.load("images/background.png").convert()

  18. BLACK = (0, 0, 0)
  19. WHITE = (255, 255, 255)
  20. GREEN = (0, 255, 0)
  21. RED = (255, 0, 0)

  22. # 载入游戏音乐
  23. pygame.mixer.music.load("sound/game_music.ogg")
  24. pygame.mixer.music.set_volume(0.2)
  25. bullet_sound = pygame.mixer.Sound("sound/bullet.wav")
  26. bullet_sound.set_volume(0.2)
  27. bomb_sound = pygame.mixer.Sound("sound/use_bomb.wav")
  28. bomb_sound.set_volume(0.2)
  29. supply_sound = pygame.mixer.Sound("sound/supply.wav")
  30. supply_sound.set_volume(0.2)
  31. get_bomb_sound = pygame.mixer.Sound("sound/get_bomb.wav")
  32. get_bomb_sound.set_volume(0.2)
  33. get_bullet_sound = pygame.mixer.Sound("sound/get_bullet.wav")
  34. get_bullet_sound.set_volume(0.2)
  35. upgrade_sound = pygame.mixer.Sound("sound/upgrade.wav")
  36. upgrade_sound.set_volume(0.2)
  37. enemy3_fly_sound = pygame.mixer.Sound("sound/enemy3_flying.wav")
  38. enemy3_fly_sound.set_volume(0.2)
  39. enemy1_down_sound = pygame.mixer.Sound("sound/enemy1_down.wav")
  40. enemy1_down_sound.set_volume(0.2)
  41. enemy2_down_sound = pygame.mixer.Sound("sound/enemy2_down.wav")
  42. enemy2_down_sound.set_volume(0.2)
  43. enemy3_down_sound = pygame.mixer.Sound("sound/enemy3_down.wav")
  44. enemy3_down_sound.set_volume(0.5)
  45. me_down_sound = pygame.mixer.Sound("sound/me_down.wav")
  46. me_down_sound.set_volume(0.2)


  47. def add_small_enemies(group1, group2, num):
  48.     for i in range(num):
  49.         e1 = enemy.SmallEnemy(bg_size)
  50.         group1.add(e1)
  51.         group2.add(e1)

  52. def add_mid_enemies(group1, group2, num):
  53.     for i in range(num):
  54.         e2 = enemy.MidEnemy(bg_size)
  55.         group1.add(e2)
  56.         group2.add(e2)

  57. def add_big_enemies(group1, group2, num):
  58.     for i in range(num):
  59.         e3 = enemy.BigEnemy(bg_size)
  60.         group1.add(e3)
  61.         group2.add(e3)

  62. def inc_speed(target, inc):
  63.     for each in target:
  64.         each.speed += inc

  65. def main():
  66.     pygame.mixer.music.play(-1)

  67.     # 生成我方飞机
  68.     me = myplane.MyPlane(bg_size)

  69.     enemies = pygame.sprite.Group()

  70.     # 生成敌方小型飞机
  71.     small_enemies = pygame.sprite.Group()
  72.     add_small_enemies(small_enemies, enemies, 15)

  73.     # 生成敌方中型飞机
  74.     mid_enemies = pygame.sprite.Group()
  75.     add_mid_enemies(mid_enemies, enemies, 4)

  76.     # 生成敌方大型飞机
  77.     big_enemies = pygame.sprite.Group()
  78.     add_big_enemies(big_enemies, enemies, 2)

  79.     # 生成普通子弹
  80.     bullet1 = []
  81.     bullet1_index = 0
  82.     BULLET1_NUM = 4
  83.     for i in range(BULLET1_NUM):
  84.         bullet1.append(bullet.Bullet1(me.rect.midtop))

  85.     # 生成超级子弹
  86.     bullet2 = []
  87.     bullet2_index = 0
  88.     BULLET2_NUM = 8
  89.     for i in range(BULLET2_NUM//2):
  90.         bullet2.append(bullet.Bullet2((me.rect.centerx-33, me.rect.centery)))
  91.         bullet2.append(bullet.Bullet2((me.rect.centerx+30, me.rect.centery)))

  92.     clock = pygame.time.Clock()

  93.     # 中弹图片索引
  94.     e1_destroy_index = 0
  95.     e2_destroy_index = 0
  96.     e3_destroy_index = 0
  97.     me_destroy_index = 0

  98.     # 统计得分
  99.     score = 0
  100.     score_font = pygame.font.Font("font/font.ttf", 36)

  101.     # 标志是否暂停游戏
  102.     paused = False
  103.     pause_nor_image = pygame.image.load("images/pause_nor.png").convert_alpha()
  104.     pause_pressed_image = pygame.image.load("images/pause_pressed.png").convert_alpha()
  105.     resume_nor_image = pygame.image.load("images/resume_nor.png").convert_alpha()
  106.     resume_pressed_image = pygame.image.load("images/resume_pressed.png").convert_alpha()
  107.     paused_rect = pause_nor_image.get_rect()
  108.     paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10
  109.     paused_image = pause_nor_image

  110.     # 设置难度级别
  111.     level = 1

  112.     # 全屏炸弹
  113.     bomb_image = pygame.image.load("images/bomb.png").convert_alpha()
  114.     bomb_rect = bomb_image.get_rect()
  115.     bomb_font = pygame.font.Font("font/font.ttf", 48)
  116.     bomb_num = 3

  117.     # 每30秒发放一个补给包
  118.     bullet_supply = supply.Bullet_Supply(bg_size)
  119.     bomb_supply = supply.Bomb_Supply(bg_size)
  120.     SUPPLY_TIME = USEREVENT
  121.     pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)

  122.     # 超级子弹定时器
  123.     DOUBLE_BULLET_TIME = USEREVENT + 1

  124.     # 标志是否使用超级子弹
  125.     is_double_bullet = False

  126.     # 解除我方无敌状态定时器
  127.     INVINCIBLE_TIME = USEREVENT + 2

  128.     # 生命数量
  129.     life_image = pygame.image.load("images/life.png").convert_alpha()
  130.     life_rect = life_image.get_rect()
  131.     life_num = 3

  132.     # 用于阻止重复打开记录文件
  133.     recorded = False

  134.     # 游戏结束画面
  135.     gameover_font = pygame.font.Font("font/font.TTF", 48)
  136.     again_image = pygame.image.load("images/again.png").convert_alpha()
  137.     again_rect = again_image.get_rect()
  138.     gameover_image = pygame.image.load("images/gameover.png").convert_alpha()
  139.     gameover_rect = gameover_image.get_rect()

  140.     # 用于切换图片
  141.     switch_image = True

  142.     # 用于延迟
  143.     delay = 100

  144.     running = True

  145.     while running:
  146.         for event in pygame.event.get():
  147.             if event.type == QUIT:
  148.                 pygame.quit()
  149.                 sys.exit()

  150.             elif event.type == MOUSEBUTTONDOWN:
  151.                 if event.button == 1 and paused_rect.collidepoint(event.pos):
  152.                     paused = not paused
  153.                     if paused:
  154.                         pygame.time.set_timer(SUPPLY_TIME, 0)
  155.                         pygame.mixer.music.pause()
  156.                         pygame.mixer.pause()
  157.                     else:
  158.                         pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)
  159.                         pygame.mixer.music.unpause()
  160.                         pygame.mixer.unpause()

  161.             elif event.type == MOUSEMOTION:
  162.                 if paused_rect.collidepoint(event.pos):
  163.                     if paused:
  164.                         paused_image = resume_pressed_image
  165.                     else:
  166.                         paused_image = pause_pressed_image
  167.                 else:
  168.                     if paused:
  169.                         paused_image = resume_nor_image
  170.                     else:
  171.                        paused_image = pause_nor_image

  172.             elif event.type == KEYDOWN:
  173.                 if event.key == K_SPACE:
  174.                     if bomb_num:
  175.                         bomb_num -= 1
  176.                         bomb_sound.play()
  177.                         for each in enemies:
  178.                             if each.rect.bottom > 0:
  179.                                 each.active = False

  180.             elif event.type == SUPPLY_TIME:
  181.                 supply_sound.play()
  182.                 if choice([True, False]):
  183.                     bomb_supply.reset()
  184.                 else:
  185.                     bullet_supply.reset()

  186.             elif event.type == DOUBLE_BULLET_TIME:
  187.                 is_double_bullet = False
  188.                 pygame.time.set_timer(DOUBLE_BULLET_TIME, 0)

  189.             elif event.type == INVINCIBLE_TIME:
  190.                 me.invincible = False
  191.                 pygame.time.set_timer(INVINCIBLE_TIME, 0)
  192.                         

  193.         # 根据用户的得分增加难度
  194.         if level == 1 and score > 50000:
  195.             level = 2
  196.             upgrade_sound.play()
  197.             # 增加3架小型敌机、2架中型敌机和1架大型敌机
  198.             add_small_enemies(small_enemies, enemies, 3)
  199.             add_mid_enemies(mid_enemies, enemies, 2)
  200.             add_big_enemies(big_enemies, enemies, 1)
  201.             # 提升小型敌机的速度
  202.             inc_speed(small_enemies, 1)
  203.         elif level == 2 and score > 300000:
  204.             level = 3
  205.             upgrade_sound.play()
  206.             # 增加5架小型敌机、3架中型敌机和2架大型敌机
  207.             add_small_enemies(small_enemies, enemies, 5)
  208.             add_mid_enemies(mid_enemies, enemies, 3)
  209.             add_big_enemies(big_enemies, enemies, 2)
  210.             # 提升小型敌机的速度
  211.             inc_speed(small_enemies, 1)
  212.             inc_speed(mid_enemies, 1)
  213.         elif level == 3 and score > 600000:
  214.             level = 4
  215.             upgrade_sound.play()
  216.             # 增加5架小型敌机、3架中型敌机和2架大型敌机
  217.             add_small_enemies(small_enemies, enemies, 5)
  218.             add_mid_enemies(mid_enemies, enemies, 3)
  219.             add_big_enemies(big_enemies, enemies, 2)
  220.             # 提升小型敌机的速度
  221.             inc_speed(small_enemies, 1)
  222.             inc_speed(mid_enemies, 1)
  223.         elif level == 4 and score > 1000000:
  224.             level = 5
  225.             upgrade_sound.play()
  226.             # 增加5架小型敌机、3架中型敌机和2架大型敌机
  227.             add_small_enemies(small_enemies, enemies, 5)
  228.             add_mid_enemies(mid_enemies, enemies, 3)
  229.             add_big_enemies(big_enemies, enemies, 2)
  230.             # 提升小型敌机的速度
  231.             inc_speed(small_enemies, 1)
  232.             inc_speed(mid_enemies, 1)
  233.             

  234.         screen.blit(background, (0, 0))
  235.                
  236.         if life_num and not paused:
  237.             # 检测用户的键盘操作
  238.             key_pressed = pygame.key.get_pressed()

  239.             if key_pressed[K_w] or key_pressed[K_UP]:
  240.                 me.moveUp()
  241.             if key_pressed[K_s] or key_pressed[K_DOWN]:
  242.                 me.moveDown()
  243.             if key_pressed[K_a] or key_pressed[K_LEFT]:
  244.                 me.moveLeft()
  245.             if key_pressed[K_d] or key_pressed[K_RIGHT]:
  246.                 me.moveRight()

  247.             # 绘制全屏炸弹补给并检测是否获得
  248.             if bomb_supply.active:
  249.                 bomb_supply.move()
  250.                 screen.blit(bomb_supply.image, bomb_supply.rect)
  251.                 if pygame.sprite.collide_mask(bomb_supply, me):
  252.                     get_bomb_sound.play()
  253.                     bomb_num += 1
  254.                     bomb_supply.active = False

  255.             # 绘制超级子弹补给并检测是否获得
  256.             if bullet_supply.active:
  257.                 bullet_supply.move()
  258.                 screen.blit(bullet_supply.image, bullet_supply.rect)
  259.                 if pygame.sprite.collide_mask(bullet_supply, me):
  260.                     get_bullet_sound.play()
  261.                     is_double_bullet = True
  262.                     pygame.time.set_timer(DOUBLE_BULLET_TIME, 18 * 1000)
  263.                     bullet_supply.active = False

  264.             # 发射子弹
  265.             if not(delay % 10):
  266.                 bullet_sound.play()
  267.                 if is_double_bullet:
  268.                     bullets = bullet2
  269.                     bullets[bullet2_index].reset((me.rect.centerx-33, me.rect.centery))
  270.                     bullets[bullet2_index+1].reset((me.rect.centerx+30, me.rect.centery))
  271.                     bullet2_index = (bullet2_index + 2) % BULLET2_NUM
  272.                 else:
  273.                     bullets = bullet1
  274.                     bullets[bullet1_index].reset(me.rect.midtop)
  275.                     bullet1_index = (bullet1_index + 1) % BULLET1_NUM

  276.                
  277.             # 检测子弹是否击中敌机
  278.             for b in bullets:
  279.                 if b.active:
  280.                     b.move()
  281.                     screen.blit(b.image, b.rect)
  282.                     enemy_hit = pygame.sprite.spritecollide(b, enemies, False, pygame.sprite.collide_mask)
  283.                     if enemy_hit:
  284.                         b.active = False
  285.                         for e in enemy_hit:
  286.                             if e in mid_enemies or e in big_enemies:
  287.                                 e.hit = True
  288.                                 e.energy -= 1
  289.                                 if e.energy == 0:
  290.                                     e.active = False
  291.                             else:
  292.                                 e.active = False
  293.             
  294.             # 绘制大型敌机
  295.             for each in big_enemies:
  296.                 if each.active:
  297.                     each.move()
  298.                     if each.hit:
  299.                         screen.blit(each.image_hit, each.rect)
  300.                         each.hit = False
  301.                     else:
  302.                         if switch_image:
  303.                             screen.blit(each.image1, each.rect)
  304.                         else:
  305.                             screen.blit(each.image2, each.rect)

  306.                     # 绘制血槽
  307.                     pygame.draw.line(screen, BLACK, \
  308.                                      (each.rect.left, each.rect.top - 5), \
  309.                                      (each.rect.right, each.rect.top - 5), \
  310.                                      2)
  311.                     # 当生命大于20%显示绿色,否则显示红色
  312.                     energy_remain = each.energy / enemy.BigEnemy.energy
  313.                     if energy_remain > 0.2:
  314.                         energy_color = GREEN
  315.                     else:
  316.                         energy_color = RED
  317.                     pygame.draw.line(screen, energy_color, \
  318.                                      (each.rect.left, each.rect.top - 5), \
  319.                                      (each.rect.left + each.rect.width * energy_remain, \
  320.                                       each.rect.top - 5), 2)
  321.                         
  322.                     # 即将出现在画面中,播放音效
  323.                     if each.rect.bottom == -50:
  324.                         enemy3_fly_sound.play(-1)
  325.                 else:
  326.                     # 毁灭
  327.                     if not(delay % 3):
  328.                         if e3_destroy_index == 0:
  329.                             enemy3_down_sound.play()
  330.                         screen.blit(each.destroy_images[e3_destroy_index], each.rect)
  331.                         e3_destroy_index = (e3_destroy_index + 1) % 6
  332.                         if e3_destroy_index == 0:
  333.                             enemy3_fly_sound.stop()
  334.                             score += 10000
  335.                             each.reset()

  336.             # 绘制中型敌机:
  337.             for each in mid_enemies:
  338.                 if each.active:
  339.                     each.move()

  340.                     if each.hit:
  341.                         screen.blit(each.image_hit, each.rect)
  342.                         each.hit = False
  343.                     else:
  344.                         screen.blit(each.image, each.rect)

  345.                     # 绘制血槽
  346.                     pygame.draw.line(screen, BLACK, \
  347.                                      (each.rect.left, each.rect.top - 5), \
  348.                                      (each.rect.right, each.rect.top - 5), \
  349.                                      2)
  350.                     # 当生命大于20%显示绿色,否则显示红色
  351.                     energy_remain = each.energy / enemy.MidEnemy.energy
  352.                     if energy_remain > 0.2:
  353.                         energy_color = GREEN
  354.                     else:
  355.                         energy_color = RED
  356.                     pygame.draw.line(screen, energy_color, \
  357.                                      (each.rect.left, each.rect.top - 5), \
  358.                                      (each.rect.left + each.rect.width * energy_remain, \
  359.                                       each.rect.top - 5), 2)
  360.                 else:
  361.                     # 毁灭
  362.                     if not(delay % 3):
  363.                         if e2_destroy_index == 0:
  364.                             enemy2_down_sound.play()
  365.                         screen.blit(each.destroy_images[e2_destroy_index], each.rect)
  366.                         e2_destroy_index = (e2_destroy_index + 1) % 4
  367.                         if e2_destroy_index == 0:
  368.                             score += 6000
  369.                             each.reset()

  370.             # 绘制小型敌机:
  371.             for each in small_enemies:
  372.                 if each.active:
  373.                     each.move()
  374.                     screen.blit(each.image, each.rect)
  375.                 else:
  376.                     # 毁灭
  377.                     if not(delay % 3):
  378.                         if e1_destroy_index == 0:
  379.                             enemy1_down_sound.play()
  380.                         screen.blit(each.destroy_images[e1_destroy_index], each.rect)
  381.                         e1_destroy_index = (e1_destroy_index + 1) % 4
  382.                         if e1_destroy_index == 0:
  383.                             score += 1000
  384.                             each.reset()

  385.             # 检测我方飞机是否被撞
  386.             enemies_down = pygame.sprite.spritecollide(me, enemies, False, pygame.sprite.collide_mask)
  387.             if enemies_down and not me.invincible:
  388.                 me.active = False
  389.                 for e in enemies_down:
  390.                     e.active = False
  391.             
  392.             # 绘制我方飞机
  393.             if me.active:
  394.                 if switch_image:
  395.                     screen.blit(me.image1, me.rect)
  396.                 else:
  397.                     screen.blit(me.image2, me.rect)
  398.             else:
  399.                 # 毁灭
  400.                 if not(delay % 3):
  401.                     if me_destroy_index == 0:
  402.                         me_down_sound.play()
  403.                     screen.blit(me.destroy_images[me_destroy_index], me.rect)
  404.                     me_destroy_index = (me_destroy_index + 1) % 4
  405.                     if me_destroy_index == 0:
  406.                         life_num -= 1
  407.                         me.reset()
  408.                         pygame.time.set_timer(INVINCIBLE_TIME, 3 * 1000)

  409.             # 绘制全屏炸弹数量
  410.             bomb_text = bomb_font.render(" X %d" % bomb_num, True, WHITE)
  411.             text_rect = bomb_text.get_rect()
  412.             screen.blit(bomb_image, (10, height - 10 - bomb_rect.height))
  413.             screen.blit(bomb_text, (20 + bomb_rect.width, height - 5 - text_rect.height))

  414.             # 绘制剩余生命数量
  415.             if life_num:
  416.                 for i in range(life_num):
  417.                     screen.blit(life_image, \
  418.                                 (width-10-(i+1)*life_rect.width, \
  419.                                  height-10-life_rect.height))

  420.             # 绘制得分
  421.             score_text = score_font.render("Score : %s" % str(score), True, WHITE)
  422.             screen.blit(score_text, (10, 5))

  423.         # 绘制游戏结束画面
  424.         elif life_num == 0:
  425.             # 背景音乐停止
  426.             pygame.mixer.music.stop()

  427.             # 停止全部音效
  428.             pygame.mixer.stop()

  429.             # 停止发放补给
  430.             pygame.time.set_timer(SUPPLY_TIME, 0)

  431.             if not recorded:
  432.                 recorded = True
  433.                 # 读取历史最高得分
  434.                 with open("record.txt", "r") as f:
  435.                     record_score = int(f.read())

  436.                 # 如果玩家得分高于历史最高得分,则存档
  437.                 if score > record_score:
  438.                     with open("record.txt", "w") as f:
  439.                         f.write(str(score))

  440.             # 绘制结束画面
  441.             record_score_text = score_font.render("Best : %d" % record_score, True, (255, 255, 255))
  442.             screen.blit(record_score_text, (50, 50))
  443.             
  444.             gameover_text1 = gameover_font.render("Your Score", True, (255, 255, 255))
  445.             gameover_text1_rect = gameover_text1.get_rect()
  446.             gameover_text1_rect.left, gameover_text1_rect.top = \
  447.                                  (width - gameover_text1_rect.width) // 2, height // 3
  448.             screen.blit(gameover_text1, gameover_text1_rect)
  449.             
  450.             gameover_text2 = gameover_font.render(str(score), True, (255, 255, 255))
  451.             gameover_text2_rect = gameover_text2.get_rect()
  452.             gameover_text2_rect.left, gameover_text2_rect.top = \
  453.                                  (width - gameover_text2_rect.width) // 2, \
  454.                                  gameover_text1_rect.bottom + 10
  455.             screen.blit(gameover_text2, gameover_text2_rect)

  456.             again_rect.left, again_rect.top = \
  457.                              (width - again_rect.width) // 2, \
  458.                              gameover_text2_rect.bottom + 50
  459.             screen.blit(again_image, again_rect)

  460.             gameover_rect.left, gameover_rect.top = \
  461.                                 (width - again_rect.width) // 2, \
  462.                                 again_rect.bottom + 10
  463.             screen.blit(gameover_image, gameover_rect)

  464.             # 检测用户的鼠标操作
  465.             # 如果用户按下鼠标左键
  466.             if pygame.mouse.get_pressed()[0]:
  467.                 # 获取鼠标坐标
  468.                 pos = pygame.mouse.get_pos()
  469.                 # 如果用户点击“重新开始”
  470.                 if again_rect.left < pos[0] < again_rect.right and \
  471.                    again_rect.top < pos[1] < again_rect.bottom:
  472.                     # 调用main函数,重新开始游戏
  473.                     main()
  474.                 # 如果用户点击“结束游戏”            
  475.                 elif gameover_rect.left < pos[0] < gameover_rect.right and \
  476.                      gameover_rect.top < pos[1] < gameover_rect.bottom:
  477.                     # 退出游戏
  478.                     pygame.quit()
  479.                     sys.exit()      

  480.         # 绘制暂停按钮
  481.         screen.blit(paused_image, paused_rect)

  482.         # 切换图片
  483.         if not(delay % 5):
  484.             switch_image = not switch_image

  485.         delay -= 1
  486.         if not delay:
  487.             delay = 100

  488.         pygame.display.flip()
  489.         clock.tick(60)
  490.         
  491. if __name__ == "__main__":
  492.     try:
  493.         main()
  494.     except SystemExit:
  495.         pass
  496.     except:
  497.         traceback.print_exc()
  498.         pygame.quit()
  499.         input()

复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-20 19:04:19 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-20 19:11:14 | 显示全部楼层

用你发的那个吗
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-20 19:17:04 | 显示全部楼层
denngyu 发表于 2020-3-20 19:11
用你发的那个吗

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-20 19:17:30 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-20 19:28:31 | 显示全部楼层
吼吼,人生第三次最佳答案
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-20 19:37:01 | 显示全部楼层
乘号 发表于 2020-3-20 19:28
吼吼,人生第三次最佳答案

你是不是只贴了源码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-20 19:39:55 | 显示全部楼层
denngyu 发表于 2020-3-20 19:37
你是不是只贴了源码

你给我设的最佳答案啊
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-8 18:32

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表