Python飞机大战小游戏

Python飞机大战小游戏
#!/usr/bin/env python
# @Time    : 2018/3/31 15:21
# @Author  : KiritoLiu
# @Contact : kiritoliuyhsky@gmail.com
# @Site    : 
# @File    : 《飞机大战》游戏.py
# @Software: PyCharm
import pygame
from pygame.locals import *
import time
import random
import sys
import threading

bg_image = "./images/bg2.png"
hero_image = "./images/me.png"
enemy_images = ("./images/e0.png", "./images/e1.png", "./images/e2.png")
bullet_image = "./images/pd.png"
explosion_images = ("./images/exp0.png", "./images/exp1.png", "./images/exp2.png")
gameover_image = "./images/gameover.png"
quit_image = "./images/quit.png"
restart_image = "./images/restart.png"

############################################


class MoveObject:
    '''
    移动物体的父类
    1.位置 2.速度 3.图像 4.子弹列表 5.位置刷新 6.存活状态
    '''
    def __init__(self, screen_temp, x, y):
        self.x = x
        self.y = y
        self.screen = screen_temp
        self.bullet_list = []
        self.aliving = True

    def itimage(self, image):
        self.image = pygame.image.load(image)

    def speed_x(self, speedx):
        self.speedx = speedx

    def speed_y(self, speedy):
        self.speedy = speedy

    def display(self):
        if self.aliving:
            self.screen.blit(self.image, (self.x, self.y))

    def move_x(self):
        if self.aliving:
            self.x += self.speedx

    def move_y(self):
        if self.aliving:
            self.y += self.speedy

    def fire(self, bullet):
        if self.aliving:
            self.bullet_list.append(bullet)

    def setaliving(self, aliving):
        self.aliving = aliving

class Bullet(MoveObject):
    '''
    子弹,只能纵向移动,且敌我皆可发射子弹
    '''

    def __init__(self, screen_temp, x, y, speedy):
        MoveObject.__init__(self, screen_temp, x, y)
        self.speed_y(speedy)
        self.itimage("./images/pd.png")

    def move_y(self):
        MoveObject.move_y(self)
        if self.y < -10 or self.y > 570:
            return True

class HeroPlane(MoveObject):
    '''
    玩家飞机
    移动方向:前 后 左 右
    子弹:设置开火
    '''
    def __init__(self, screen_temp):
        MoveObject.__init__(self, screen_temp, 200, 400)
        self.itimage(hero_image)

    def display(self):
        MoveObject.display(self)
        for b in self.bullet_list:
            b.display()
            if b.move_y():
                self.bullet_list.remove(b)

    def moveleft(self):
        self.speed_x(-8)
        self.move_x()
        if self.x <= 0:
            self.x = 0

    def moveright(self):
        self.speed_x(8)
        self.move_x()
        if self.x >= 406:
            self.x = 406

    def moveup(self):
        self.speed_y(-8)
        self.move_y()
        if self.y <= 0:
            self.y =0

    def movedown(self):
        self.speed_y(8)
        self.move_y()
        if self.y >= 492:
            self.y = 492

    def fire(self):
        MoveObject.fire(self, Bullet(self.screen, self.x+53, self.y-9, -10))

    def restart(self):
        self.x = 200
        self.y = 400
        self.setaliving(True)
        self.bullet_list.clear()

class Enemy(MoveObject):
    '''
    敌机 三种 只能向下 间断性开火(发射子弹的时间间隔)
    判断英雄子弹与敌机撞击
    判断敌我飞机碰撞
    '''
    def __init__(self, screen_temp):
        MoveObject.__init__(self, screen_temp, random.randint(0, 396), -75)
        self.itimage(enemy_images[random.randint(0, 2)])
        self.speed_y(random.randint(4, 6))

    def display(self):
        MoveObject.display(self)
        for b in self.bullet_list:
            b.display()
            if b.move_y():
                self.bullet_list.remove(b)

    def move_y(self, hero):
        try:
            MoveObject.move_y(self)
        except:
            pass
        #玩家飞机碰撞热区的判定
        heroleft = hero.x + 10
        heroright = hero.x + hero.image.get_width() - 10
        herotop = hero.y + 10
        herobottom = hero.y + hero.image.get_height() - 30
        #敌机碰撞热区的判定
        enemyleft = self.x + 5
        enemyright = self.x + self.image.get_width() - 5
        enemytop = self.y + 5
        enemybottom = self.y + self.image.get_height() - 25

        if enemytop > 570:
            return 1
        for bo in hero.bullet_list:
            if bo.x > enemyleft and bo.x < enemyright and bo.y > self.y + 20 and bo.y < self.y + 60:
                hero.bullet_list.remove(bo)
                return 2
        if hero.aliving:
            for bo in self.bullet_list:
                if bo.x > heroleft + 12 and bo.x < heroright - 12 and bo.y > herotop + 20 and bo.y < herobottom + 60:
                    self.bullet_list.remove(bo)
                    return 3
            if (heroleft <= enemyleft <= heroright or heroleft <= enemyright <= heroright) and (herotop <= enemytop <= herobottom or herotop <= enemybottom <= herobottom):
                return 4

    def fire(self):
        MoveObject.fire(self, Bullet(self.screen, self.x + self.image.get_width() / 2, self.y + self.image.get_height(), 10))

    def setfire(self, hasbullet, interval):
        self.hasbullet = hasbullet
        self.interval = interval

def run(enemy):
    '''
    敌机各自开火的线程
    '''
    while True:
        try:
            enemy.fire()
            time.sleep(enemy.interval)
        except Exception:
            print(Exception)

def explosion(MoveObject, screen):
    '''
    显示击中或撞击之后的爆炸效果
    '''

    centrex = MoveObject.x + MoveObject.image.get_width() / 2
    centrey = MoveObject.y + MoveObject.image.get_height() / 2
    for i in [0] * 50 + [1] * 50 + [2] * 50:
        image = pygame.image.load(explosion_images[i])
        screen.blit(image, (centrex, centrey))
        pygame.display.update()

def key_control(hero_temp):
    '''键盘控制方法'''

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            quit()

    if not hero_temp.aliving:
        # 玩家已经被击毁则不响应键盘按键
        return False

    pressed_keys = pygame.key.get_pressed()

    if pressed_keys[K_LEFT] or pressed_keys[K_a]:
        hero_temp.moveleft()
    elif pressed_keys[K_RIGHT] or pressed_keys[K_d]:
        hero_temp.moveright()
    if pressed_keys[K_UP] or pressed_keys[K_w]:
        hero_temp.moveup()
    elif pressed_keys[K_DOWN] or pressed_keys[K_s]:
        hero_temp.movedown()
    if pressed_keys[K_SPACE]:
        hero_temp.fire()
        return True

class Button(object):
    '''
    按钮类,用来做结束游戏和重新开始按钮
    '''

    def __init__(self, image, position):
        self.image = pygame.image.load(image).convert_alpha()
        self.position = position

    def isover(self):
        point_x, point_y = pygame.mouse.get_pos()
        x, y = self.position
        w, h = self.image.get_size()
        x -= w / 2
        y -= h / 2

        in_x = x < point_x < x + w
        in_y = y < point_y < y + h
        return in_x and in_y

    def render(self, surface):
        x, y = self.position
        w, h = self.image.get_size()
        x -= w / 2
        y -= h / 2
        surface.blit(self.image, (x, y))


#############################################

def main():
    '''
    游戏主程序
    '''
    pygame.init()
    # 初始化pygame
    pygame.mixer.init()
    # 初始化misxer
    screen = pygame.display.set_mode((512, 568), 0, 0)
    # 创建游戏窗口

    background = pygame.image.load(bg_image)

    game_over = False
    font = pygame.font.SysFont('arial', 40)
    gameover = Button(gameover_image, (250, 200))
    quitbutton = Button(quit_image, (180, 300))
    restartbutton = Button(restart_image, (300, 300))

    enemy_list = []
    myscore = 0
    hero = HeroPlane(screen)

    m = -968
    while True:
        screen.blit(background, (0, m))
        m += 2
        if m >= -200:
            m = -968
        # 背景循环滚动

        if game_over:
            # 显示game over,quit,restart
            gameover.render(screen)
            quitbutton.render(screen)
            restartbutton.render(screen)
            pygame.mouse.set_visible(True)

            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.quit()
                    quit()
                elif event.type == MOUSEBUTTONDOWN and event.button == 1:
                    if quitbutton.isover():
                        pygame.quit()
                        quit()
                    elif restartbutton.isover():
                        game_over = False
                        myscore = 0
                        hero.restart()

        else:
            hero.display()
            if key_control(hero):
                pass

            if len(enemy_list) < 15:
                r = random.randint(1, min(100, 25 * (len(enemy_list) + 1)))
                if r == 12:
                    newenemy = Enemy(screen)
                    newenemy.setfire(random.choice([0, 1]), random.choice([0.5, 1, 2]))
                    enemy_list.append(newenemy)
                    if newenemy.hasbullet:
                        t = threading.Thread(target=run, args=(newenemy,))
                        t.start()

            for e in enemy_list:
                e.display()
                result = e.move_y(hero)
                if result == 1:
                    enemy_list.remove(e)
                elif result == 2:
                    explosion(e, screen)
                    enemy_list.remove(e)
                    myscore += 100
                elif result == 3:
                    hero.setaliving(False)
                    hero.display()
                    game_over = True
                    explosion(hero, screen)
                elif result == 4:
                    explosion(e, screen)
                    enemy_list.remove(e)
                    myscore += 50
                    hero.setaliving(False)
                    hero.display()
                    game_over = True
                    explosion(hero, screen)

        score = font.render(str(myscore), 1, (237, 140, 21))
        screen.blit(score, (400, 20))
        pygame.display.update()
        time.sleep(0.03)

#判断当前否是主程序,并调用主程序
if __name__ == '__main__':
    main()
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值