import pygame |
import sys |
import traceback |
from pygame. locals import * |
import myplane |
import enemy |
import bullet |
import supply |
import random |
pygame.init() |
bg_size = width, height = 400 , 700 |
screen = pygame.display.set_mode(bg_size) |
pygame.display.set_caption( "飞机大战" ) |
background = pygame.image.load( "images/background.png" ).convert() |
BLACK = ( 0 , 0 , 0 ) |
GREEN = ( 0 , 255 , 0 ) |
RED = ( 255 , 0 , 0 ) |
WHITE = ( 255 , 255 , 255 ) |
#载入游戏音乐 |
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(group1, group2, num): |
for i in range (num): |
e1 = enemy.SmallEnemy(bg_size) |
group1.add(e1) |
group2.add(e1) |
def add_mid_enemies(group1, group2, num): |
for i in range (num): |
e1 = enemy.MidEnemy(bg_size) |
group1.add(e1) |
group2.add(e1) |
def add_big_enemies(group1, group2, num): |
for i in range (num): |
e1 = enemy.BigEnemy(bg_size) |
group1.add(e1) |
group2.add(e1) |
def inc_speed(target, inc): |
for each in target: |
each.speed + = inc |
def main(): |
pygame.mixer.music.play( - 1 ) |
|
clock = pygame.time.Clock() |
# 中弹图片索引 |
e1_destroy_index = 0 |
e2_destroy_index = 0 |
e3_destroy_index = 0 |
me_destroy_index = 0 |
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, 5 ) |
big_enemies = pygame.sprite.Group() |
add_big_enemies(big_enemies, enemies, 1 ) |
running = True |
switch_image = True |
delay = 100 |
score = 0 |
score_font = pygame.font.Font( "font/font.ttf" , 36 ) |
|
bullets = [] |
# 生成普通子弹 |
bullet1 = [] |
bullet1_index = 0 |
BULLET1_NUM = 5 |
for i in range (BULLET1_NUM): |
bullet1.append(bullet.Bullet1(me.rect.midtop)) |
# 生命数量 |
life_image = pygame.image.load( "images/life.png" ).convert_alpha() |
life_rect = life_image.get_rect() |
life_num = 10 |
# 游戏结束画面 |
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() |
DOUBLE_BULLET_TIME = USEREVENT + 1 |
# 解除我方飞机无敌状态 |
INVINCEBLE_TIME = USEREVENT + 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))) |
# 标记是否使用超级子弹 |
is_double_bullet = False |
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 |
# 每30秒发放一个补给包 |
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 ) |
# 阻止重复读取成绩记录文件 |
recorded = False |
# 标志是否暂停游戏 |
paused = False |
paused_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 = paused_nor_image.get_rect() |
paused_rect.left, paused_rect.top = width - paused_rect.width - 10 , 10 |
paused_image = paused_nor_image |
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() |
paused_image = resume_pressed_image |
else : |
pygame.time.set_timer(SUPPLY_TIME, 30 * 1000 ) |
pygame.mixer.music.unpause() |
pygame.mixer.unpause() |
paused_image = pause_pressed_image |
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 = paused_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 random.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 = = INVINCEBLE_TIME: |
me.invincible = False |
pygame.time.set_timer(INVINCEBLE_TIME, 0 ) |
# 根据用户的得分增加难度 |
if level = = 1 and score > 50000 : |
level = 2 |
upgrade_sound.play() |
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() |
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 > 300000 : |
level = 4 |
upgrade_sound.play() |
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() |
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: |
# 绘制全屏炸弹补给并检测是否获得 |
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 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 + 33 , 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 |
|
# 绘制全屏炸弹补给并检测是否获得 |
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 |
# 绘制大型敌机 |
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 switch_image: |
screen.blit(each.image1, each.rect) |
else : |
screen.blit(each.image2, each.rect) |
if each.rect.bottom = = - 50 : |
enemy3_fly_sound.play( - 1 ) |
# 绘制血槽 |
pygame.draw.line(screen, BLACK, \ |
(each.rect.left, each.rect.top - 5 ),\ |
(each.rect.right, each.rect.top - 5 ), \ |
2 ) |
|
energy_remain = each.energy / enemy.BigEnemy.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 e3_destroy_index = = 0 : |
enemy3_down_sound.play() |
screen.blit(each.destroy_images[e3_destroy_index], each.rect) |
e3_destroy_index = (e3_destroy_index + 1 ) % 6 |
if e3_destroy_index = = 0 : |
me_down_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.image1, each.rect) |
# 绘制血槽 |
pygame.draw.line(screen, BLACK, \ |
(each.rect.left, each.rect.top - 5 ),\ |
(each.rect.right, each.rect.top - 5 ), \ |
2 ) |
|
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_destroy_index = = 0 : |
enemy2_down_sound.play() |
screen.blit(each.destroy_images[e2_destroy_index], each.rect) |
e2_destroy_index = (e2_destroy_index + 1 ) % 4 |
if e2_destroy_index = = 0 : |
score + = 5000 |
each.reset() |
# 绘制小型敌机 |
for each in small_enemies: |
if each.active: |
each.move() |
screen.blit(each.image1, each.rect) |
else : |
if not (delay % 3 ): |
if e1_destroy_index = = 0 : |
enemy1_down_sound.play() |
screen.blit(each.destroy_images[e1_destroy_index], each.rect) |
e1_destroy_index = (e1_destroy_index + 1 ) % 4 |
if e1_destroy_index = = 0 : |
score + = 1000 |
each.reset() |
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() |
# 检测我方飞机是否被撞 |
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 |
# 绘制我方飞机 |
if me.active: |
if switch_image: |
screen.blit(me.image1, me.rect) |
else : |
screen.blit(me.image2, me.rect) |
else : |
me_down_sound.play() |
if not (delay % 3 ): |
screen.blit(each.destroy_images[me_destroy_index], each.rect) |
me_destroy_index = (me_destroy_index + 1 ) % 4 |
# 剩余生命数量 |
if me_destroy_index = = 0 : |
life_num - = 1 |
me.reset() |
pygame.time.set_timer(INVINCEBLE_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( str ( "Score: %s" % 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: |
recorded = True |
# 读取历史最高分 |
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 ,WHITE) |
screen.blit(record_score_text, ( 50 , 50 )) |
|
gameover_text1 = gameover_font.render( "Your Score: " , True , WHITE) |
gameover_text1_rect = gameover_text1.get_rect() |
gameover_text1_rect.left, gameover_text1_rect.top = \ |
(width - gameover_text1_rect.width) / / 2 , height / / 2 |
screen.blit(gameover_text1, gameover_text1_rect) |
|
gameover_text2 = gameover_font.render( str (score), True , WHITE) |
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() |
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 ): |
switch_image = not switch_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 () |
|
初级程序员
by: 毛宗泉 发表于:2021-10-17 12:44:06 顶(1) | 踩(0) 回复
1
1
回复评论