pygame实现飞机大战


Posted in Python onMarch 11, 2020

本文实例为大家分享了pygame实现飞机大战的具体代码,供大家参考,具体内容如下

运行效果图:

pygame实现飞机大战

pygame实现飞机大战

import pygame
import random
import time
import os
from os import path

WIDTH = 480
HEIGHT = 600
FPS = 60#每秒显示多少帧
POWERUP_TIME = 5000

COLOR = (255,174,200)
WHITE = (255,255,255)
BLACK = (0,0,0)
GREEN = (0,255,0)
BLUE = (0,0,255)
RED = (255,0,0)
YELLOW = (255,255,0)
#game_folder = os.path.dirname(__file__)
#img_folder = os.path.join(game_folder,'img')

pygame.init()
pygame.mixer.init()#声音的初始化
screen = pygame.display.set_mode((WIDTH,HEIGHT))#屏幕
pygame.display.set_caption("星际大战")#题目
clock = pygame.time.Clock()


snd_dir = path.join(path.dirname(__file__), 'snd')
img_dir = path.join(path.dirname(__file__), 'img')
background = pygame.image.load(path.join(img_dir, 'background.png'))
background_rect = background.get_rect()
player_img = pygame.image.load(path.join(img_dir,'playerShip1.png'))
player_mini_img = pygame.transform.scale(player_img, (25, 19))
player_mini_img.set_colorkey(BLACK)
#meteor_img = pygame.image.load(path.join(img_dir, "meteorBrown.png"))
bullet_img = pygame.image.load(path.join(img_dir, "laserRed.png"))
missile_img = pygame.image.load(path.join(img_dir, "missileRed.png"))
meteor_images = []
meteor_list =['monster11.png','monster22.png','monster33.png','monster44.png','monster55.png']
for img in meteor_list:
 meteor_images.append(pygame.image.load(path.join(img_dir, img)).convert())
powerup_images = {}
powerup_images['shield'] = pygame.image.load(path.join(img_dir, 'shield_gold.png')).convert()
powerup_images['gun'] = pygame.image.load(path.join(img_dir, 'bolt_gold.png')).convert()
powerup_images['star'] = pygame.image.load(path.join(img_dir, 'star_gold.png')).convert()
powerup_images['heart'] = pygame.image.load(path.join(img_dir, 'heart_gold.png')).convert()
shoot_sound = pygame.mixer.Sound(path.join(snd_dir, 'shoot_sound.wav'))
expl_sounds = []
for snd in ['rumble1.ogg', 'bomb.wav']:
 expl_sounds.append(pygame.mixer.Sound(path.join(snd_dir, snd)))
pygame.mixer.music.load(path.join(snd_dir, 'back_music.wav'))
pygame.mixer.music.set_volume(0.7)

#爆炸效果
explosion_anim = {}
explosion_anim['lg'] = []
explosion_anim['sm'] = []
explosion_anim['player'] = []
for i in range(4):
 filename = 'explosion0{}.png'.format(i)
 img = pygame.image.load(path.join(img_dir, filename)).convert()
 img.set_colorkey(WHITE)
 img_lg = pygame.transform.scale(img, (75, 75))
 explosion_anim['lg'].append(img_lg)
 img_sm = pygame.transform.scale(img, (32, 32))
 explosion_anim['sm'].append(img_sm) #玩家爆炸
 filename = 'explosion0{}.png'.format(i)
 img = pygame.image.load(path.join(img_dir, filename)).convert()
 img.set_colorkey(WHITE)
 explosion_anim['player'].append(img)

####################################### 类区 #######################################

class Player(pygame.sprite.Sprite):
 def __init__(self):
  pygame.sprite.Sprite.__init__(self)
  #self.image = player_img
  self.image = pygame.Surface((50,40))#设置精灵大小
  self.image = pygame.transform.scale(player_img, (40, 39))#调整图片大小
  self.image.set_colorkey(BLACK)
  self.rect = self.image.get_rect()
  self.radius = 18
  #pygame.draw.circle(self.image, RED, self.rect.center, self.radius)
  self.rect.centerx=WIDTH/2
  self.rect.bottom = HEIGHT - 10
  self.speedx = 0
  self.shield = 100
  self.shoot_delay = 250 #发射子弹间隔ms
  self.last_shot = pygame.time.get_ticks()#跟踪最后一个子弹射击的时间
  self.lives = 3
  self.hidden = False
  self.hide_timer = pygame.time.get_ticks()
  self.power = 1
  self.power_time = pygame.time.get_ticks()

 def shoot(self):
  now = pygame.time.get_ticks()
  if now - self.last_shot > self.shoot_delay:#满足间隔时间
   self.last_shot = now
   if self.power == 1:
    bullet = Bullet(self.rect.centerx, self.rect.top)
    all_sprites.add(bullet)
    bullets.add(bullet)
    shoot_sound.play()
   if self.power == 2:
    bullet1 = Bullet(self.rect.left, self.rect.centery)
    bullet2 = Bullet(self.rect.right, self.rect.centery)
    all_sprites.add(bullet1)
    all_sprites.add(bullet2)
    bullets.add(bullet1)
    bullets.add(bullet2)
    shoot_sound.play()
   if self.power == 3:
    bullet1 = Bullet(self.rect.left, self.rect.centery)
    bullet2 = Bullet(self.rect.right, self.rect.centery)
    missile1 = Missile(self.rect.centerx, self.rect.top) # 导弹
    all_sprites.add(bullet1)
    all_sprites.add(bullet2)
    all_sprites.add(missile1)
    bullets.add(bullet1)
    bullets.add(bullet2)
    bullets.add(missile1)
    shoot_sound.play()
  # timeout for powerups
  if self.power >= 3 and pygame.time.get_ticks() - self.power_time > POWERUP_TIME:
   self.power -= 1
   self.power_time = pygame.time.get_ticks()

 def hide(self):
  # hide the player temporarily
  self.hidden = True
  self.hide_timer = pygame.time.get_ticks()
  self.rect.center = (WIDTH / 2, HEIGHT + 200)

 def powerup(self):
  self.power += 1
  self.power_time = pygame.time.get_ticks()

 def lifeup(self):
  if self.lives < 3:
   self.lives += 1
  elif self.lives == 3:
   self.lives = 3

 def update (self):
  self.speedx = 0
  keystste = pygame.key.get_pressed()
  if keystste[pygame.K_LEFT]:
   self.speedx = -8
  if keystste[pygame.K_RIGHT]:
   self.speedx = 8
  if keystste[pygame.K_SPACE]:
   self.shoot()
  self.rect.x += self.speedx
  if self.rect.right > WIDTH:
   self.rect.right = WIDTH
  if self.rect.left < 0:
   self.rect.left = 0
  # unhide if hidden
  if self.hidden and pygame.time.get_ticks() - self.hide_timer > 1000:
   self.hidden = False
   self.rect.centerx = WIDTH / 2
   self.rect.bottom = HEIGHT - 10


class Mob(pygame.sprite.Sprite):
 def __init__(self):
  pygame.sprite.Sprite.__init__(self)
  self.image_orig = random.choice(meteor_images)
  self.image_orig.set_colorkey(COLOR)
  self.image = self.image_orig.copy()
  self.rect = self.image.get_rect()
  #self.image = player_img
  #self.image = pygame.Surface((30,40))#设置精灵大小
  #self.image = pygame.transform.scale(meteor_img, (39, 39))
  self.radius = int(self.rect.width * .85 / 2)
  #pygame.draw.circle(self.image, RED, self.rect.center, self.radius)
  self.rect.x = random.randrange(WIDTH - self.rect.width)
  self.rect.y = random.randrange(-100, -40)
  self.speedy = random.randrange(1, 8)
  self.speedx = random.randrange(-3, 3)
  self.rot = 0
  self.rot_speed = random.randrange(-8, 8)#每次旋转度 数字是速度,正值是顺时针
  self.last_update = pygame.time.get_ticks()#自时钟启动以来已经过了多少毫秒

 def update(self):
  self.rotate()
  self.rect.x += self.speedx
  self.rect.y += self.speedy
  if self.rect.top > HEIGHT + 10 or self.rect.left < -25 or self.rect.right > WIDTH + 20:
   self.rect.x = random.randrange(WIDTH - self.rect.width)
   self.rect.y = random.randrange(-100, -40)
   self.speedy = random.randrange(1, 8)
   all_sprites.update()

 def rotate(self):
  now = pygame.time.get_ticks()
  if now - self.last_update > 50:
   self.last_update = now
   self.rot = (self.rot + self.rot_speed) % 360
   new_image = pygame.transform.rotate(self.image_orig, self.rot)
   #self.image = pygame.transform.rotate(self.image_orig, self.rot)#从原始图像上改
   #self.image = pygame.transform.rotate(self.image, self.rot_speed)
   old_center = self.rect.center
   self.image = new_image
   self.rect = self.image.get_rect()
   self.rect.center = old_center

class Bullet(pygame.sprite.Sprite):
 def __init__(self, x, y):
  pygame.sprite.Sprite.__init__(self)
  self.image = pygame.Surface((10, 20))
  self.image = pygame.transform.scale(bullet_img, (15, 40))
  self.image.set_colorkey(BLACK)
  self.rect = self.image.get_rect()
  self.rect.bottom = y
  self.rect.centerx = x
  self.speedy = -10

 def update(self):
  self.rect.y += self.speedy
  # kill if it moves off the top of the screen
  if self.rect.bottom < 0:
   self.kill()

#创建导弹类#
class Missile(pygame.sprite.Sprite):
 def __init__(self, x, y):
  pygame.sprite.Sprite.__init__(self)
  self.image = missile_img
  self.image.set_colorkey(BLACK)
  self.rect = self.image.get_rect()
  self.rect.bottom = y
  self.rect.centerx = x
  self.speedy = -10

 def update(self):
  self.rect.y += self.speedy
  if self.rect.bottom < 0:
   self.kill()


class Explosion(pygame.sprite.Sprite):
 def __init__(self, center, size):
  pygame.sprite.Sprite.__init__(self)
  self.size = size
  self.image = explosion_anim[self.size][0]
  self.rect = self.image.get_rect()
  self.rect.center = center
  self.frame = 0
  self.last_update = pygame.time.get_ticks()
  self.frame_rate = 50 #frame_rate属性:控制如何快速运行动画

 def update(self):  #描画爆炸效果(前提是Explosion对象被创建)
  now = pygame.time.get_ticks()
  if now - self.last_update > self.frame_rate:
   self.last_update = now
   self.frame += 1
   if self.frame == len(explosion_anim[self.size]):
    self.kill()
   else:
    center = self.rect.center
    self.image = explosion_anim[self.size][self.frame]
    self.rect = self.image.get_rect()
    self.rect.center = center

#玩家buf
class Pow(pygame.sprite.Sprite):
 def __init__(self, center):
  pygame.sprite.Sprite.__init__(self)
  self.type = random.choice(['shield', 'gun','star','heart'])
  self.image = powerup_images[self.type]
  self.image.set_colorkey(BLACK)
  self.rect = self.image.get_rect()
  self.rect.center = center
  self.speedy = 2

 def update(self):
  self.rect.y += self.speedy
  # kill if it moves off the bottom of the screen
  if self.rect.top > HEIGHT:
   self.kill()


#######################################函数区#######################################

#画分数框
font_name = pygame.font.match_font('arial')
def draw_text(surf, text, size, x, y):
 font = pygame.font.Font(font_name, size)
 text_surface = font.render(text, True, WHITE)
 text_rect = text_surface.get_rect()
 text_rect.midtop = (x, y)
 surf.blit(text_surface, text_rect)

#画血条
def draw_shield_bar(surf, x, y, pct): #pct填充参数(shield血量)
 if pct < 0:
  pct = 0
 BAR_LENGTH = 100
 BAR_HEIGHT = 10
 fill = (pct / 100) * BAR_LENGTH
 outline_rect = pygame.Rect(x, y, BAR_LENGTH, BAR_HEIGHT)
 fill_rect = pygame.Rect(x, y, fill, BAR_HEIGHT)
 pygame.draw.rect(surf, COLOR, fill_rect)
 pygame.draw.rect(surf, WHITE, outline_rect, 2)

#产生新怪物
def newmob():
 m = Mob()
 all_sprites.add(m)
 mobs.add(m)

#显示生命
def draw_lives(surf, x, y, lives, img):
 for i in range(lives):
  img_rect = img.get_rect()
  img_rect.x = x + 30 * i
  img_rect.y = y
  surf.blit(img, img_rect)

def show_go_screen():
 screen.blit(background, background_rect)
 draw_text(screen, "SHMUP!", 64, WIDTH / 2, HEIGHT / 4)
 draw_text(screen, "Arrow keys move, Space to fire", 22, WIDTH / 2, HEIGHT / 2)
 draw_text(screen, "Heart can add a life. Stars can clear all monsters.", 16, WIDTH / 2, HEIGHT * 4 / 5)
 draw_text(screen, "Shield can add blood. Space to fire. Lightning can strengthen bullets.", 16, WIDTH / 2, HEIGHT * 5 / 6)
 draw_text(screen, "Press a key to begin", 18, WIDTH / 2, HEIGHT * 2 / 3)

 pygame.display.flip()
 waiting = True
 while waiting:
  clock.tick(FPS)
  for event in pygame.event.get():
   if event.type == pygame.QUIT:
    pygame.quit()
   if event.type == pygame.KEYUP:
    waiting = False

all_sprites = pygame.sprite.Group()
bullets = pygame.sprite.Group() #碰撞检测组 子弹组
mobs = pygame.sprite.Group()
powerups = pygame.sprite.Group()
player = Player()
all_sprites.add(player)
for i in range(8):    #创建障碍物
 newmob()


score = 0
count = 0#用于循环计算FPS
start =time.time()
pygame.mixer.music.play(loops=-1) #背景音乐


game_over = True
running = True
while running:
 if game_over:
  show_go_screen()
  game_over = False
  all_sprites = pygame.sprite.Group()
  mobs = pygame.sprite.Group()
  bullets = pygame.sprite.Group()
  powerups = pygame.sprite.Group()
  player = Player()
  all_sprites.add(player)
  for i in range(8):
   newmob()
  score = 0

 clock.tick(FPS)#保持正确的时间运行
 for event in pygame.event.get():
  # check for closing window
  if event.type == pygame.QUIT:
   running = False
  #elif event.type == pygame.KEYDOWN:
   # if event.key == pygame.K_SPACE:
   #  player.shoot()
 # Update
 all_sprites.update()

 # 检查障碍物与玩家碰撞
 #hits = pygame.sprite.spritecollide(player, mobs, False)#碰撞检测,true碰撞后会消失
 hits = pygame.sprite.spritecollide(player, mobs, True, pygame.sprite.collide_circle)
 for hit in hits:
  player.shield -= hit.radius * 2
  expl = Explosion(hit.rect.center, 'sm')
  all_sprites.add(expl)
  newmob()

  if player.shield <= 0:
   death_explosion = Explosion(player.rect.center, 'lg')
   all_sprites.add(death_explosion)
   random.choice(expl_sounds).play()
   player.hide()
   player.lives -= 1
   player.shield = 100
  #player.kill()
   # if the player died and the explosion has finished playing
 if player.lives == 0 and not death_explosion.alive():
  game_over = True
  #running = False
  #if hits: running = False

  #draw
  screen.fill(BLACK)
  screen.blit(background, background_rect)
  all_sprites.draw(screen)
  draw_text(screen, str(score), 18, WIDTH / 2, 10)

 #all_sprites.update()

 # 检查子弹击中障碍物
 hits = pygame.sprite.groupcollide(mobs, bullets, True, True)
 for hit in hits:
  score += 50 - hit.radius
  random.choice(expl_sounds).play()
  expl = Explosion(hit.rect.center, 'lg')
  all_sprites.add(expl)
  if random.random() > 0.9:#10%的几率奖励
   pow = Pow(hit.rect.center)
   all_sprites.add(pow)
   powerups.add(pow)
  newmob()

 # 检查玩家击中powerup(盾牌或能量)
 hits = pygame.sprite.spritecollide(player, powerups, True)
 for hit in hits:
  #加血
  if hit.type == 'shield':
   player.shield += random.randrange(10, 30)
   if player.shield >= 100:
    player.shield = 100
  #子弹增强
  if hit.type == 'gun':
   player.powerup()
  #清楚屏内所有怪物
  if hit.type == 'star':
   mob_ctr = 0
   for mob in mobs.sprites():
    mob.kill()
    mob_ctr += 1
   for i in range(mob_ctr):
    newmob()
  #生命加 1
  if hit.type == 'heart':
   player.lifeup()
   #print(player.lives)
   draw_lives(screen, WIDTH - 100, 5, player.lives,player_mini_img)
   pygame.display.flip()
 #显示
 #背景填充
 screen.fill(BLACK)
 screen.blit(background, background_rect)
 all_sprites.draw(screen)
 draw_text(screen, str(score), 27, WIDTH / 2, 10)
 draw_shield_bar(screen, 5, 5, player.shield)
 draw_lives(screen, WIDTH - 100, 5, player.lives,player_mini_img)#画生命
 #all_sprites.draw(screen)
 pygame.display.flip()#完成后翻面白板,屏幕显示

pygame.quit()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python获取豆瓣电影简介代码分享
Jan 16 Python
Python 序列的方法总结
Oct 18 Python
Python字符串处理实现单词反转
Jun 14 Python
python环形单链表的约瑟夫问题详解
Sep 27 Python
python list格式数据excel导出方法
Oct 31 Python
如何基于Python批量下载音乐
Nov 11 Python
python3实现在二叉树中找出和为某一值的所有路径(推荐)
Dec 26 Python
python轮询机制控制led实例
May 03 Python
如何理解Python中的变量
Jun 01 Python
Keras load_model 导入错误的解决方式
Jun 09 Python
通过自学python能找到工作吗
Jun 21 Python
详解python中[-1]、[:-1]、[::-1]、[n::-1]使用方法
Apr 25 Python
Django框架models使用group by详解
Mar 11 #Python
python检查目录文件权限并修改目录文件权限的操作
Mar 11 #Python
python 链接sqlserver 写接口实例
Mar 11 #Python
浅谈Python中range与Numpy中arange的比较
Mar 11 #Python
python读取当前目录下的CSV文件数据
Mar 11 #Python
python闭包、深浅拷贝、垃圾回收、with语句知识点汇总
Mar 11 #Python
在Python中用GDAL实现矢量对栅格的切割实例
Mar 11 #Python
You might like
php+dojo 的数据库保存拖动布局的一个方法dojo 这里下载
2007/03/07 PHP
PHP程序员最常犯的11个MySQL错误小结
2010/11/20 PHP
php 广告调用类代码(支持Flash调用)
2011/08/11 PHP
使用php显示搜索引擎来的关键词
2014/02/13 PHP
javascript textContent与innerText的异同分析
2010/10/22 Javascript
js实现拉伸拖动iframe的具体代码
2013/08/03 Javascript
如何创建一个JavaScript弹出DIV窗口层的效果
2013/09/25 Javascript
JS截取字符串常用方法详细整理
2013/10/28 Javascript
基于NodeJS的前后端分离的思考与实践(六)Nginx + Node.js + Java 的软件栈部署实践
2014/09/26 NodeJs
jQuery+CSS实现滑动的标签分栏切换效果
2015/12/17 Javascript
JavaScript的Vue.js库入门学习教程
2016/05/23 Javascript
利用jquery获取select下拉框的值
2016/11/23 Javascript
基于JavaScript实现Tab选项卡切换效果
2016/11/24 Javascript
JS闭包可被利用的常见场景小结
2017/04/09 Javascript
AngulaJS路由 ui-router 传参实例
2017/04/28 Javascript
JavaScript实现的可变动态数字键盘控件方式实例代码
2017/07/15 Javascript
详解使用angularjs的ng-options时如何设置默认值(初始值)
2017/07/18 Javascript
Angularjs上传图片实例详解
2017/08/06 Javascript
移动端H5页面返回并刷新页面(BFcache)的方法
2018/11/06 Javascript
详解为什么Vue中的v-if和v-for不建议一起用
2021/01/13 Vue.js
[01:30]DOTA2上海特锦赛现场采访 Loda倾情献唱
2016/03/25 DOTA
[51:10]VP vs VGJ.S 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
python 计算两个日期相差多少个月实例代码
2017/05/24 Python
Python无损音乐搜索引擎实现代码
2018/02/02 Python
Python Pandas找到缺失值的位置方法
2018/04/12 Python
Python统计python文件中代码,注释及空白对应的行数示例【测试可用】
2018/07/25 Python
Python学习笔记之错误和异常及访问错误消息详解
2019/08/08 Python
如何理解transaction事务的概念
2015/05/27 面试题
教育科研先进个人材料
2014/01/26 职场文书
师德师风个人整改措施
2014/10/27 职场文书
2015教师年度思想工作总结
2015/04/30 职场文书
张丽莉观后感
2015/06/16 职场文书
小学班级管理心得体会
2016/01/07 职场文书
2019年工作总结范文
2019/05/21 职场文书
经典人生语录分享:不畏将来,不念过去,笑对当下
2019/12/12 职场文书
如何理解及使用Python闭包
2021/06/01 Python