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常用的日期时间处理方法示例
Feb 08 Python
编写简单的Python程序来判断文本的语种
Apr 07 Python
Python的pycurl包用法简介
Nov 13 Python
uwsgi+nginx部署Django项目操作示例
Dec 04 Python
python实现网页自动签到功能
Jan 21 Python
对Python协程之异步同步的区别详解
Feb 19 Python
python根据txt文本批量创建文件夹
Dec 08 Python
python 命令行传入参数实现解析
Aug 30 Python
如何在python中实现随机选择
Nov 02 Python
Python图片的横坐标汉字实例
Dec 04 Python
python使用openCV遍历文件夹里所有视频文件并保存成图片
Jan 14 Python
python3注册全局热键的实现
Mar 22 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
在Windows下编译适用于PHP 5.2.12及5.2.13的eAccelerator.dll(附下载)
2010/05/04 PHP
有关php运算符的知识大全
2011/11/03 PHP
8个PHP程序员常用的功能汇总
2014/12/18 PHP
深入讲解PHP的Yii框架中的属性(Property)
2016/03/18 PHP
通过代码实例解析PHP session工作原理
2020/12/11 PHP
jQuery根据纬度经度查看地图处理程序
2013/05/08 Javascript
从js向Action传中文参数出现乱码问题的解决方法
2013/12/29 Javascript
jQuery 回车事件enter使用示例
2014/02/18 Javascript
js的Boolean对象初始值示例
2014/03/04 Javascript
javascript中if和switch,==和===详解
2015/07/30 Javascript
原生js的数组除重复简单实例
2016/05/24 Javascript
JavaScript从0开始构思表情插件
2016/07/26 Javascript
nodejs个人博客开发第三步 载入页面
2017/04/12 NodeJs
node中koa中间件机制详解
2017/08/22 Javascript
vue实现登录页面的验证码以及验证过程解析(面向新手)
2019/08/02 Javascript
Vue页面跳转传递参数及接收方式
2020/09/09 Javascript
Windows系统配置python脚本开机启动的3种方法分享
2015/03/10 Python
学习Python3 Dlib19.7进行人脸面部识别
2018/01/24 Python
浅析python中的迭代与迭代对象
2018/10/08 Python
Python爬虫实现爬取百度百科词条功能实例
2019/04/05 Python
Python程序包的构建和发布过程示例详解
2019/06/09 Python
详解利用python+opencv识别图片中的圆形(霍夫变换)
2019/07/01 Python
python打印文件的前几行或最后几行教程
2020/02/13 Python
SpringBoot实现登录注册常见问题解决方案
2020/03/04 Python
使用纯 CSS 创作一个脉动 loader效果的源码
2018/09/28 HTML / CSS
美国第二大团购网站:LivingSocial
2016/07/24 全球购物
Tripadvisor新西兰:阅读评论,比较价格和酒店预订
2018/02/10 全球购物
捷克时尚网上商店:OTTO
2018/03/15 全球购物
anello泰国官方网站:日本流行包包品牌
2019/08/08 全球购物
智能室内花园:Click & Grow
2021/01/29 全球购物
体育老师的教学自我评价分享
2013/11/19 职场文书
执行总经理岗位职责
2014/02/03 职场文书
班级活动策划书
2014/02/06 职场文书
企业与个人合作经营协议书
2014/11/01 职场文书
2014年企业工会工作总结
2014/11/12 职场文书
详细了解java监听器和过滤器
2021/07/09 Java/Android