pygame-飞机大战

学写一个飞机大战游戏,功能有些简单。参考:http://res.crossincode.com/wechat/pygame.html

注释写的有点多,方便自己看,随时修改。。。。

#!/usr/bin/env python3
# encoding: utf-8

import pygame
from sys import exit
import random
import math

# 打飞机小游戏

# 定义bullet(子弹)
class Bullet:
    '''
    bullet(子弹)类包含x,y属性, 左侧子弹初始化,右侧子弹初始化,子弹移动方法
    '''
    def __init__(self):
        self.x = 0
        self.y = -1
        self.image = pygame.image.load(r'C:\Users\Administrator\Desktop\pygame-plane\bullet.png').convert_alpha() # 加载子弹图片
        self.active = False
    
    def move(self): # 子弹移动
        if self.active:
            self.y -= 2
        if self.y<0:
            self.active = False

    def restart_center(self): # 中间子弹
        self.x = x 
        self.y = y
        self.active = True

    def restart_left(self): # 左侧机翼子弹
        self.x = x + 25
        self.y = y
        self.active = True
        
    def restart_right(self): # 右侧机翼侧子弹
        self.x = x - 25
        self.y = y
        self.active = True

    
# 定义Enemy(敌机)          
class Enemy:
    '''
    设置敌机的初始化位置,移动方法。
    '''
    def restart(self): 
        self.x = random.randint(31,419)    # 根据窗口大小,敌机尺寸 随机设置敌机出现的横坐标位置(不要超出窗口)
        self.y = random.randint(-200,-120) # 随机设置敌机出现的纵坐标位置
        self.speed = random.random()+0.4   # 设置子弹移动速度
        
    def __init__(self):
        #初始化(未经初始化,属性不能直接使用)
        self.restart()
        self.image = pygame.image.load(r'C:\Users\Administrator\Desktop\pygame-plane\enemy.png').convert_alpha() # 加载敌机图片

    def move(self):
        if self.y > 600:  
            self.restart()
        else:
            self.y += self.speed


# 定义Plane(飞机)
class Plane:
    def restart(self):
        self.x = 450
        self.y = 300

    def __init__(self):
        self.restart()
        self.image = pygame.image.load(r'C:\Users\Administrator\Desktop\pygame-plane\plane.png').convert_alpha()

    def move(self):
        self.x = x - self.image.get_width()/2 
        self.y = y - self.image.get_height()/2
        screen.blit(self.image,(self.x,self.y)) # 将飞机图片绘制到窗口,(x,y)位置表示图片左上角


# 子弹与敌机碰撞检测
'''
忽略bullet本身面积,当做一个坐标(x,y)与敌机碰撞检测。
'''
def checkhit(bullet,enemy):
    if ( bullet.x > enemy.x  and  bullet.x < enemy.x + enemy.image.get_width()) and (
        bullet.y > enemy.y  and  bullet.y < enemy.y + enemy.image.get_height()):
        enemy.restart()
        bullet.active = False
        return True
    return False


# 飞机(plane)与敌机碰撞检测
'''
两个矩形相交的条件:两个矩形的重心距离在X和Y轴上都小于两个矩形长或宽的一半之和,分两次判断一下就行了。
如果一旦有重合就算是碰撞,会让游戏看上去有些奇怪:有时候你觉得并没有撞上,而实际已经有了重合,游戏就失败了。为了避免这一现象,在检测的长度上打点折扣(0.7)
'''
def checkCrash(plane,enemy):
    if ( math.sqrt((x - (enemy.x + enemy.image.get_width()/2))**2) < 0.7*(plane.image.get_width()/2 + enemy.image.get_width()/2) ) and (
        math.sqrt((y - (enemy.y + enemy.image.get_height()/2))**2) < 0.7*(plane.image.get_height()/2 + enemy.image.get_height()/2) ):
        return True
    return False
    
pygame.init() # 初始化
screen = pygame.display.set_mode((450,700),0,0) # 绘制窗口(像素大小与背景图片一样)。_mod(resolution=(0,0), flags=0, depth=0)
pygame.display.set_caption('小游戏') # 设置窗口标题
img_background = pygame.image.load(r'C:\Users\Administrator\Desktop\pygame-plane\back.jpg').convert() # 加载背景图片
plane = Plane()    # 设置飞机
bullets_left = []  # 左侧机翼子弹,添加5颗子弹
bullets_right = [] # 右侧机翼子弹,添加5颗子弹
bullets_center = []# 中间子弹列表,添加5颗子弹
for i in range(5):
    bullets_left.append(Bullet())
    bullets_right.append(Bullet())
    bullets_center.append(Bullet())
count = len(bullets_left)
index = 0
interval = 0 # 表示循环次数(重新接受新的坐标值,发射下一颗子弹)
enemies = [] # 创建Enemy(敌机)列表,添加2个敌机
for i in range(4):
    enemies.append(Enemy())
    
score = 0  # 设置分数 
gameover = False # 设置游戏结束的条件(飞机与敌机碰撞后,plane/enemy/bullets循环停止)


#循环主体
while True:
    for event in pygame.event.get():  # 事件列表
        if event.type == pygame.QUIT: # 判断是否触发了关闭事件(pygame.QUIT,是一个整数)
            print('关闭了屏幕') 
            pygame.quit() # 关闭窗口(pygame库停止工作)
            exit()
        if gameover and event.type == pygame.MOUSEBUTTONUP: # 点击鼠标,游戏重启
            plane.restart()
            for e in enemies:
                e.restart()
            for b in bullets_left:
                b.active = False
            for b in bullets_right:
                b.active = False
            for b in bullets_center:
                b.active = False
            score = 0
            gameover = False
    screen.blit(img_background,(0,0)) # 将背景图片绘制到窗口,(x,y)位置表示窗口左上角
    x,y = pygame.mouse.get_pos()      # 获取鼠标坐标位置(x,y均为整数)
    if not gameover:
        interval -= 1
        if interval < 0:
            if score < 10:
                bullets_center[index].restart_center()     
            elif 10 <= score <= 11:
                bullets_left[index].restart_left()
                bullets_right[index].restart_right()
            else:
                gameover = True
                my_font = pygame.font.Font(r'C:\Windows\Fonts\STZHONGS.TTF',20)
                text_score = my_font.render(u'您的得分: %d' % score, True, (144, 238, 144),(0,0,0))
                screen.blit(text_score,(0,0))
                text_end = my_font.render(u'通关成功,游戏结束!', True, (0, 0, 0))
                screen.blit(text_end,(100,400))
                pygame.display.update() # 刷新绘制窗口
                break
            interval = 100
            index = (index +1) % count

        for b in bullets_center:  # 判断飞机中间子弹是否初始化并发射,检查子弹与敌机是否碰撞
            if b.active:
                for e in enemies:
                    if checkhit(b,e): # 中间子弹与敌机碰撞检查
                        score += 1
                b.move()
                screen.blit(b.image,(b.x,b.y))
                
        for b in bullets_left:  # 判断飞机左侧子弹是否初始化并发射,检查子弹与敌机是否碰撞
            if b.active:
                for e in enemies:
                    if checkhit(b,e): # 左侧子弹与敌机碰撞检查
                        score += 1
                b.move()
                screen.blit(b.image,(b.x,b.y))
                
        for i in bullets_right: # 判断飞机右侧子弹是否初始化并发射,检查子弹与敌机是否碰撞
            if i.active:
                for e in enemies:   
                    if checkhit(i,e): # 右侧子弹与敌机碰撞检查
                        score += 1
                i.move()
                screen.blit(i.image,(i.x,i.y))
        
        for e in enemies: 
            if checkCrash(plane,e): # 飞机与敌机碰撞检测(游戏结束)
                gameover = True
            e.move()    # 调用敌机向下移动 
            screen.blit(e.image,(e.x,e.y)) # 将敌机绘制在窗口
        plane.move()     
    else:
        my_font = pygame.font.Font(r'C:\Windows\Fonts\STZHONGS.TTF',20) # 创建font对象,(‘C:\Windows\Fonts\STZHONGS.TTF’)是字体样式,也可以用None表示使用默认字体,20是字号
        my_font.set_italic(True) # 斜体
        text_score = my_font.render(u'您的得分: %d  ' % score, True, (144, 238, 144),(0,0,0)) # 文字只支持单行,多行的话,建立多个对象。注:my_font.render()的参数分别是:字体,布尔值[字体平滑/锯齿],字体颜色,字体背景颜色[可选]
        screen.blit(text_score,(0,0))
        text_end = my_font.render(u'——点击鼠标重新游戏——', True, (0, 0, 0))
        screen.blit(text_end,(100,400))
    pygame.display.update() # 刷新绘制窗口

猜你喜欢

转载自blog.csdn.net/kun_dl/article/details/81215081