2020年9月12日星期六

92 《零基礎入門學習Python》筆記 第092講:Pygame:飛機大戰3

當敵我兩機發生碰撞時,兩方應該是玉石俱焚的,現在我為每一個類增加撞擊時發生的慘烈畫面,比如:
敵人1:
敵人2:
敵人3:
我:
我們現在就來寫代碼:
首先為每一個類把這些圖片加進去:
  1. #myplane.py 部分代码
  2. import pygame
  3. class Myplane(pygame.sprite.Sprite):
  4. def __init__(self, bg_size):
  5. pygame.sprite.Sprite.__init__(self)
  6. self.image1 = pygame.image.load("images/me1.png").convert_alpha()
  7. self.image2 = pygame.image.load("images/me2.png").convert_alpha()
  8. #添加坠机图片
  9. self.destroy_images = []
  10. self.destroy_images.extend([\
  11. pygame.image.load("images/me_destroy_1.png").convert_alpha(), \
  12. pygame.image.load("images/me_destroy_2.png").convert_alpha(), \
  13. pygame.image.load("images/me_destroy_3.png").convert_alpha(), \
  14. pygame.image.load("images/me_destroy_4.png").convert_alpha() \
  15. ])
  16. self.rect = self.image1.get_rect()
  17. self.width, self.height = bg_size[0], bg_size[1]
  18. self.rect.left, self.rect.top = \
  19. (self.width - self.rect.width) // 2, \
  20. self.height - self.rect.height - 60 #减60,留给状态栏
  21. self.speed = 10
  1. #enemy.py
  2. import pygame
  3. from random import *
  4. class SmallEnemy(pygame.sprite.Sprite):
  5. def __init__(self, bg_size):
  6. pygame.sprite.Sprite.__init__(self)
  7. self.image = pygame.image.load("images/enemy1.png").convert_alpha()
  8. #添加坠机图片
  9. self.destroy_images = []
  10. self.destroy_images.extend([\
  11. pygame.image.load("images/enemy1_down1.png").convert_alpha(), \
  12. pygame.image.load("images/enemy1_down2.png").convert_alpha(), \
  13. pygame.image.load("images/enemy1_down3.png").convert_alpha(), \
  14. pygame.image.load("images/enemy1_down4.png").convert_alpha() \
  15. ])
  16. self.rect = self.image.get_rect()
  17. self.width, self.height = bg_size[0], bg_size[1]
  18. self.speed = 2
  19. self.rect.left, self.rect.top = \
  20. randint(0, self.width - self.rect.width), \
  21. randint(-5 * self.height, 0) #在页面外部上方5个屏幕高度范围内随机生成一个敌机
  22. def move(self):
  23. if self.rect.top < self.height:
  24. self.rect.top += self.speed
  25. else:
  26. self.reset()
  27. def reset(self):
  28. self.rect.left, self.rect.top = \
  29. randint(0, self.width - self.rect.width), \
  30. randint(-5 * self.height, 0)
  31. class MidEnemy(pygame.sprite.Sprite):
  32. def __init__(self, bg_size):
  33. pygame.sprite.Sprite.__init__(self)
  34. self.image = pygame.image.load("images/enemy2.png").convert_alpha()
  35. #添加坠机图片
  36. self.destroy_images = []
  37. self.destroy_images.extend([\
  38. pygame.image.load("images/enemy2_down1.png").convert_alpha(), \
  39. pygame.image.load("images/enemy2_down2.png").convert_alpha(), \
  40. pygame.image.load("images/enemy2_down3.png").convert_alpha(), \
  41. pygame.image.load("images/enemy2_down4.png").convert_alpha() \
  42. ])
  43. self.rect = self.image.get_rect()
  44. self.width, self.height = bg_size[0], bg_size[1]
  45. self.speed = 1
  46. self.rect.left, self.rect.top = \
  47. randint(0, self.width - self.rect.width), \
  48. randint(-10 * self.height, -self.height) #在页面外部上方1个到10个屏幕高度范围内随机生成一个敌机(1-10个,就保证了不会一开始出大一个大的)
  49. def move(self):
  50. if self.rect.top < self.height:
  51. self.rect.top += self.speed
  52. else:
  53. self.reset()
  54. def reset(self):
  55. self.rect.left, self.rect.top = \
  56. randint(0, self.width - self.rect.width), \
  57. randint(-10 * self.height, -self.height)
  58. class BigEnemy(pygame.sprite.Sprite):
  59. def __init__(self, bg_size):
  60. pygame.sprite.Sprite.__init__(self)
  61. #大型敌机有飞行特效,两张图片切换
  62. self.image1 = pygame.image.load("images/enemy3_n1.png").convert_alpha()
  63. self.image2 = pygame.image.load("images/enemy3_n2.png").convert_alpha()
  64. #添加坠机图片
  65. self.destroy_images = []
  66. self.destroy_images.extend([\
  67. pygame.image.load("images/enemy3_down1.png").convert_alpha(), \
  68. pygame.image.load("images/enemy3_down2.png").convert_alpha(), \
  69. pygame.image.load("images/enemy3_down3.png").convert_alpha(), \
  70. pygame.image.load("images/enemy3_down4.png").convert_alpha(), \
  71. pygame.image.load("images/enemy3_down5.png").convert_alpha(), \
  72. pygame.image.load("images/enemy3_down6.png").convert_alpha() \
  73. ])
  74. self.rect = self.image1.get_rect()
  75. self.width, self.height = bg_size[0], bg_size[1]
  76. self.speed = 1
  77. self.rect.left, self.rect.top = \
  78. randint(0, self.width - self.rect.width), \
  79. randint(-15 * self.height, -5 * self.height) #在页面外部上方5-15个屏幕高度范围内随机生成一个敌机
  80. def move(self):
  81. if self.rect.top < self.height:
  82. self.rect.top += self.speed
  83. else:
  84. self.reset()
  85. def reset(self):
  86. self.rect.left, self.rect.top = \
  87. randint(0, self.width - self.rect.width), \
  88. randint(-15 * self.height, -5 * self.height)
接下來我們要為每一個類添加active 屬性,該屬性表示還活著,也就是說,當該屬性的值為True 時,我們就讓飛機顯示正常的飛行狀態,而當該屬性為False 時,表示該飛機已經遇難了,我們就要依次顯示墜機的畫面,顯示完之後,調用該類的resert() 方法。
self.active = True
接下來修改main 模塊的main() 函數,在繪製每一種飛機時,先檢測它的active 的值:
  1. #main.py 部分代码
  2. #中弹图片索引
  3. e1_destroy_index = 0
  4. e2_destroy_index = 0
  5. e3_destroy_index = 0
  6. me_destroy_index = 0
  7. (此处代码省略)
  8. #绘制大型敌机
  9. for each in big_enemies:
  10. if each.active: #检测是否还活着
  11. each.move()
  12. if switch_image:
  13. screen.blit(each.image1, each.rect)
  14. else:
  15. screen.blit(each.image2, each.rect)
  16. #即将出现在界面中,播放音效
  17. if each.rect.bottom > -50:
  18. enemy3_fly_sound.play()
  19. else:
  20. #坠机
  21. enemy3_down_sound.play() #音效
  22. if not(delay % 3):
  23. screen.blit(each.destroy_images[e3_destroy_index], each.rect)
  24. e3_destroy_index = (e3_destroy_index + 1) % 6
  25. if e3_destroy_index == 0:
  26. each.reset()
  27. (其他敌机和我方飞机代码类似。。。。。)
我們接著就要寫碰撞檢測代碼:
一旦我方飛機碰撞到敵機,導致的結果必將是敵我同歸於盡。
  1. #main.py 部分代码
  2. #检测我方飞机是否被撞
  3. enemies_down = pygame.sprite.spritecollide(me, enemies, False)
  4. if enemies_down:
  5. me.active = False
  6. for e in enemies_down:
  7. e.active = False
我們碰撞檢測使用 spritecollide() 方法:
碰撞和墜機是實現了,但是我們發現,兩個飛機還沒真正的接觸就已經撞上了,這是為什麼呢?
這是因為我們使用了普通的spritecollide() 方法,這個方法默認情況下是以圖片的矩形位置區域作為檢測的範圍,而我們飛機的矩形範圍遠大於自身,但是我們完全是可以做得更好的,我們可以做到完美的碰撞檢測,怎麼實現呢?
sprite 模塊裡有一個叫做collide_mask 的函數可以利用,這個函數要求檢測對象擁有一個mask 屬性,這個屬性就是用於指定檢測的範圍,關於mask,Pygame 還專門寫了一個mask 模塊,其中有一個叫做from_surface( ) 的函數,可以將Surface 對像中非透明的部分標記為mask 並返回。
首先,給每個類加上mask 屬性:
self.mask = pygame.mask.from_sueface(self.image) #将非透明部分标记为mask
然後在main 函數中修改碰撞檢測代碼,指定檢測方法為 pygame.sprite.collide_mask,即:
  1. #main.py
  2. #检测我方飞机是否被撞
  3. enemies_down = pygame.sprite.spritecollide(me, enemies, False, pygame.sprite.collide_mask)
  4. if enemies_down:
  5. me.active = False
  6. for e in enemies_down:
  7. e.active = False
好了,這就是完美的碰撞檢測了,在大部分情況下編寫遊戲開發,基本上都是使用這種碰撞檢測。
現在,有人就可能已經發現了,剛才我們的代碼實際上是存在很明顯的Bug,導致部分音效無法正常播放,
大家知道是為什麼嗎?可以看一下這裡的代碼:
  1. #绘制大型敌机
  2. for each in big_enemies:
  3. if each.active: #检测是否还活着
  4. each.move()
  5. if switch_image:
  6. screen.blit(each.image1, each.rect)
  7. else:
  8. screen.blit(each.image2, each.rect)
  9. #即将出现在界面中,播放音效
  10. if each.rect.bottom > -50:
  11. enemy3_fly_sound.play()
  12. else:
  13. #坠机
  14. enemy3_down_sound.play() #音效
  15. if not(delay % 3):
  16. screen.blit(each.destroy_images[e3_destroy_index], each.rect)
  17. e3_destroy_index = (e3_destroy_index + 1) % 6
  18. if e3_destroy_index == 0:
  19. each.reset()
大家看看,不管是我們的飛機,還是敵機,它們是怎麼墜機的,首先,我們檢測active,如果為False 的話,就播放音效,然後畫一張墜機圖,這樣就一幀過去了,然後第二幀,又播放音效,畫圖的進不去,然後第三幀,播放音效,然後畫下面的一張墜機圖。
大家發現問題沒有,你要畫它墜機的圖片,需要好多幀,但是這裡你重複的播放了好多次它墜機的音效,一個飛機墜機只需要播放一次音效即可,你要播放很多次,導致的結果就是你把所有音效的通道都佔滿了,因為Pygame 默認只有8條音效的通道。
我們現在要做的就是讓它只播放一次。修改如下:
  1. #绘制大型敌机
  2. for each in big_enemies:
  3. if each.active: #检测是否还活着
  4. each.move()
  5. if switch_image:
  6. screen.blit(each.image1, each.rect)
  7. else:
  8. screen.blit(each.image2, each.rect)
  9. #即将出现在界面中,播放音效
  10. if each.rect.bottom > -50:
  11. enemy3_fly_sound.play()
  12. else:
  13. #坠机
  14. if not(delay % 3):
  15. if e3_destroy_index == 0:
  16. enemy3_down_sound.play() #音效
  17. screen.blit(each.destroy_images[e3_destroy_index], each.rect)
  18. e3_destroy_index = (e3_destroy_index + 1) % 6
  19. if e3_destroy_index == 0:
  20. each.reset()
現在再來測試一下就好多了,當然,如果你嫌默認的8個音效通道太少的話,可以使用mixer模塊的set_ num _channels()方法來設置通道數多一點。
下面貼出這節課實現的3個模塊的完整代碼:
  1. #main.py
  2. import pygame
  3. import sys
  4. import traceback #为了更好地退出
  5. import myplane
  6. import enemy
  7. from pygame.locals import *
  8. pygame.init()
  9. pygame.mixer.init() #混音器初始化
  10. bg_size = width, height = 480, 700
  11. screen = pygame.display.set_mode(bg_size)
  12. pygame.display.set_caption("飞机大战 -- Python Demo")
  13. background = pygame.image.load("images/background.png").convert()
  14. # 载入游戏音乐
  15. pygame.mixer.music.load("sound/game_music.ogg")
  16. pygame.mixer.music.set_volume(0.2)
  17. bullet_sound = pygame.mixer.Sound("sound/bullet.wav")
  18. bullet_sound.set_volume(0.2)
  19. bomb_sound = pygame.mixer.Sound("sound/use_bomb.wav")
  20. bomb_sound.set_volume(0.2)
  21. supply_sound = pygame.mixer.Sound("sound/supply.wav")
  22. supply_sound.set_volume(0.2)
  23. get_bomb_sound = pygame.mixer.Sound("sound/get_bomb.wav")
  24. get_bomb_sound.set_volume(0.2)
  25. get_bullet_sound = pygame.mixer.Sound("sound/get_bullet.wav")
  26. get_bullet_sound.set_volume(0.2)
  27. upgrade_sound = pygame.mixer.Sound("sound/upgrade.wav")
  28. upgrade_sound.set_volume(0.2)
  29. enemy3_fly_sound = pygame.mixer.Sound("sound/enemy3_flying.wav")
  30. enemy3_fly_sound.set_volume(0.5)
  31. enemy1_down_sound = pygame.mixer.Sound("sound/enemy1_down.wav")
  32. enemy1_down_sound.set_volume(0.2)
  33. enemy2_down_sound = pygame.mixer.Sound("sound/enemy2_down.wav")
  34. enemy2_down_sound.set_volume(0.2)
  35. enemy3_down_sound = pygame.mixer.Sound("sound/enemy3_down.wav")
  36. enemy3_down_sound.set_volume(0.5)
  37. me_down_sound = pygame.mixer.Sound("sound/me_down.wav")
  38. me_down_sound.set_volume(0.2)
  39. def add_small_enemies(group1, group2, num):
  40. for i in range(num):
  41. e1 = enemy.SmallEnemy(bg_size)
  42. group1.add(e1)
  43. group2.add(e1)
  44. def add_mid_enemies(group1, group2, num):
  45. for i in range(num):
  46. e2 = enemy.MidEnemy(bg_size)
  47. group1.add(e2)
  48. group2.add(e2)
  49. def add_big_enemies(group1, group2, num):
  50. for i in range(num):
  51. e3 = enemy.BigEnemy(bg_size)
  52. group1.add(e3)
  53. group2.add(e3)
  54. def main():
  55. pygame.mixer.music.play(-1)
  56. # 生成我方飞机
  57. me = myplane.Myplane(bg_size)
  58. #生成敌方飞机
  59. enemies = pygame.sprite.Group()
  60. # 生成敌方小型飞机
  61. small_enemies = pygame.sprite.Group()
  62. add_small_enemies(small_enemies, enemies, 15)
  63. # 生成敌方中型飞机
  64. mid_enemies = pygame.sprite.Group()
  65. add_mid_enemies(mid_enemies, enemies, 4)
  66. # 生成敌方大型飞机
  67. big_enemies = pygame.sprite.Group()
  68. add_big_enemies(big_enemies, enemies, 2)
  69. #中弹图片索引
  70. e1_destroy_index = 0
  71. e2_destroy_index = 0
  72. e3_destroy_index = 0
  73. me_destroy_index = 0
  74. clock = pygame.time.Clock()
  75. #用于切换图片
  76. switch_image = True
  77. #用于延迟
  78. delay = 100
  79. running = True
  80. while running:
  81. for event in pygame.event.get():
  82. if event.type == QUIT:
  83. pygame.quit()
  84. sys.exit()
  85. #检测用户的键盘操作
  86. key_pressed = pygame.key.get_pressed()
  87. if key_pressed[K_w] or key_pressed[K_UP]:
  88. me.moveUp()
  89. if key_pressed[K_s] or key_pressed[K_DOWN]:
  90. me.moveDown()
  91. if key_pressed[K_a] or key_pressed[K_LEFT]:
  92. me.moveLeft()
  93. if key_pressed[K_d] or key_pressed[K_RIGHT]:
  94. me.moveRight()
  95. screen.blit(background, (0, 0))
  96. #绘制大型敌机
  97. for each in big_enemies:
  98. if each.active: #检测是否还活着
  99. each.move()
  100. if switch_image:
  101. screen.blit(each.image1, each.rect)
  102. else:
  103. screen.blit(each.image2, each.rect)
  104. #即将出现在界面中,播放音效
  105. if each.rect.bottom == -50:
  106. enemy3_fly_sound.play(-1) #循环播放
  107. else:
  108. #坠机
  109. if not(delay % 3):
  110. if e3_destroy_index == 0:
  111. enemy3_down_sound.play()
  112. screen.blit(each.destroy_images[e3_destroy_index], each.rect)
  113. e3_destroy_index = (e3_destroy_index + 1) % 6
  114. if e3_destroy_index == 0:
  115. enemy3_fly_sound.stop() #循环音效停止播放
  116. each.reset()
  117. #绘制中型敌机
  118. for each in mid_enemies:
  119. if each.active: #检测是否还活着
  120. each.move()
  121. screen.blit(each.image, each.rect)
  122. else:
  123. #坠机
  124. if not(delay % 3):
  125. if e2_destroy_index == 0:
  126. enemy2_down_sound.play() #音效
  127. screen.blit(each.destroy_images[e2_destroy_index], each.rect)
  128. e2_destroy_index = (e2_destroy_index + 1) % 4
  129. if e2_destroy_index == 0:
  130. each.reset()
  131. #绘制小型敌机
  132. for each in small_enemies:
  133. if each.active: #检测是否还活着
  134. each.move()
  135. screen.blit(each.image, each.rect)
  136. else:
  137. #坠机
  138. if not(delay % 3):
  139. if e1_destroy_index == 0:
  140. enemy1_down_sound.play() #音效
  141. screen.blit(each.destroy_images[e1_destroy_index], each.rect)
  142. e1_destroy_index = (e1_destroy_index + 1) % 4
  143. if e1_destroy_index == 0:
  144. each.reset()
  145. #检测我方飞机是否被撞
  146. enemies_down = pygame.sprite.spritecollide(me, enemies, False, pygame.sprite.collide_mask)
  147. if enemies_down:
  148. #me.active = False
  149. for e in enemies_down:
  150. e.active = False
  151. #绘制我方飞机
  152. if me.active: #检测是否还活着
  153. if switch_image:
  154. screen.blit(me.image1, me.rect)
  155. else:
  156. screen.blit(me.image2, me.rect)
  157. else:
  158. #坠机
  159. if not(delay % 3):
  160. if me_destroy_index == 0:
  161. me_down_sound.play()
  162. screen.blit(me.destroy_images[me_destroy_index], me.rect)
  163. me_destroy_index = (me_destroy_index + 1) % 4
  164. if me_destroy_index == 0:
  165. print("game over")
  166. running = False
  167. #切换图片
  168. if not(delay % 5): #5帧切换一次,一秒就只切换12次
  169. switch_image = not switch_image
  170. delay -= 1
  171. if not delay:
  172. delay = 100
  173. pygame.display.flip()
  174. clock.tick(60)
  175. if __name__ == "__main__":
  176. try:
  177. main()
  178. except SystemExit:
  179. pass
  180. except:
  181. traceback.print_exc()
  182. pygame.quit()
  183. input()
  1. #myplane.py
  2. import pygame
  3. class Myplane(pygame.sprite.Sprite):
  4. def __init__(self, bg_size):
  5. pygame.sprite.Sprite.__init__(self)
  6. self.image1 = pygame.image.load("images/me1.png").convert_alpha()
  7. self.image2 = pygame.image.load("images/me2.png").convert_alpha()
  8. #添加坠机图片
  9. self.destroy_images = []
  10. self.destroy_images.extend([\
  11. pygame.image.load("images/me_destroy_1.png").convert_alpha(), \
  12. pygame.image.load("images/me_destroy_2.png").convert_alpha(), \
  13. pygame.image.load("images/me_destroy_3.png").convert_alpha(), \
  14. pygame.image.load("images/me_destroy_4.png").convert_alpha() \
  15. ])
  16. self.rect = self.image1.get_rect()
  17. self.width, self.height = bg_size[0], bg_size[1]
  18. self.rect.left, self.rect.top = \
  19. (self.width - self.rect.width) // 2, \
  20. self.height - self.rect.height - 60 #减60,留给状态栏
  21. self.speed = 10
  22. self.active = True
  23. self.mask = pygame.mask.from_surface(self.image1) #将非透明部分标记为mask
  24. def moveUp(self):
  25. if self.rect.top > 0:
  26. self.rect.top -= self.speed
  27. else:
  28. self.rect.top = 0
  29. def moveDown(self):
  30. if self.rect.bottom < self.height - 60:
  31. self.rect.top += self.speed
  32. else:
  33. self.rect.bottom = self.height - 60
  34. def moveLeft(self):
  35. if self.rect.left > 0:
  36. self.rect.left -= self.speed
  37. else:
  38. self.rect.left = 0
  39. def moveRight(self):
  40. if self.rect.right < self.width:
  41. self.rect.left += self.speed
  42. else:
  43. self.rect.right = self.width
  1. #enemy.py
  2. import pygame
  3. from random import *
  4. class SmallEnemy(pygame.sprite.Sprite):
  5. def __init__(self, bg_size):
  6. pygame.sprite.Sprite.__init__(self)
  7. self.image = pygame.image.load("images/enemy1.png").convert_alpha()
  8. #添加坠机图片
  9. self.destroy_images = []
  10. self.destroy_images.extend([\
  11. pygame.image.load("images/enemy1_down1.png").convert_alpha(), \
  12. pygame.image.load("images/enemy1_down2.png").convert_alpha(), \
  13. pygame.image.load("images/enemy1_down3.png").convert_alpha(), \
  14. pygame.image.load("images/enemy1_down4.png").convert_alpha() \
  15. ])
  16. self.rect = self.image.get_rect()
  17. self.width, self.height = bg_size[0], bg_size[1]
  18. self.speed = 2
  19. self.active = True
  20. self.rect.left, self.rect.top = \
  21. randint(0, self.width - self.rect.width), \
  22. randint(-5 * self.height, 0) #在页面外部上方5个屏幕高度范围内随机生成一个敌机
  23. self.mask = pygame.mask.from_surface(self.image) #将非透明部分标记为mask
  24. def move(self):
  25. if self.rect.top < self.height:
  26. self.rect.top += self.speed
  27. else:
  28. self.reset()
  29. def reset(self):
  30. self.active = True
  31. self.rect.left, self.rect.top = \
  32. randint(0, self.width - self.rect.width), \
  33. randint(-5 * self.height, 0)
  34. class MidEnemy(pygame.sprite.Sprite):
  35. def __init__(self, bg_size):
  36. pygame.sprite.Sprite.__init__(self)
  37. self.image = pygame.image.load("images/enemy2.png").convert_alpha()
  38. #添加坠机图片
  39. self.destroy_images = []
  40. self.destroy_images.extend([\
  41. pygame.image.load("images/enemy2_down1.png").convert_alpha(), \
  42. pygame.image.load("images/enemy2_down2.png").convert_alpha(), \
  43. pygame.image.load("images/enemy2_down3.png").convert_alpha(), \
  44. pygame.image.load("images/enemy2_down4.png").convert_alpha() \
  45. ])
  46. self.rect = self.image.get_rect()
  47. self.width, self.height = bg_size[0], bg_size[1]
  48. self.speed = 1
  49. self.active = True
  50. self.rect.left, self.rect.top = \
  51. randint(0, self.width - self.rect.width), \
  52. randint(-10 * self.height, -self.height) #在页面外部上方1个到10个屏幕高度范围内随机生成一个敌机(1-10个,就保证了不会一开始出大一个大的)
  53. self.mask = pygame.mask.from_surface(self.image) #将非透明部分标记为mask
  54. def move(self):
  55. if self.rect.top < self.height:
  56. self.rect.top += self.speed
  57. else:
  58. self.reset()
  59. def reset(self):
  60. self.active = True
  61. self.rect.left, self.rect.top = \
  62. randint(0, self.width - self.rect.width), \
  63. randint(-10 * self.height, -self.height)
  64. class BigEnemy(pygame.sprite.Sprite):
  65. def __init__(self, bg_size):
  66. pygame.sprite.Sprite.__init__(self)
  67. #大型敌机有飞行特效,两张图片切换
  68. self.image1 = pygame.image.load("images/enemy3_n1.png").convert_alpha()
  69. self.image2 = pygame.image.load("images/enemy3_n2.png").convert_alpha()
  70. #添加坠机图片
  71. self.destroy_images = []
  72. self.destroy_images.extend([\
  73. pygame.image.load("images/enemy3_down1.png").convert_alpha(), \
  74. pygame.image.load("images/enemy3_down2.png").convert_alpha(), \
  75. pygame.image.load("images/enemy3_down3.png").convert_alpha(), \
  76. pygame.image.load("images/enemy3_down4.png").convert_alpha(), \
  77. pygame.image.load("images/enemy3_down5.png").convert_alpha(), \
  78. pygame.image.load("images/enemy3_down6.png").convert_alpha() \
  79. ])
  80. self.rect = self.image1.get_rect()
  81. self.width, self.height = bg_size[0], bg_size[1]
  82. self.speed = 1
  83. self.active = True
  84. self.rect.left, self.rect.top = \
  85. randint(0, self.width - self.rect.width), \
  86. randint(-15 * self.height, -5 * self.height) #在页面外部上方5-15个屏幕高度范围内随机生成一个敌机
  87. self.mask = pygame.mask.from_surface(self.image1) #将非透明部分标记为mask
  88. def move(self):
  89. if self.rect.top < self.height:
  90. self.rect.top += self.speed
  91. else:
  92. self.reset()
  93. def reset(self):
  94. self.active = True
  95. self.rect.left, self.rect.top = \
  96. randint(0, self.width - self.rect.width), \
  97. randint(-15 * self.height, -5 * self.height)
(未完待續)

0 留言:

發佈留言