做一个“消灭病毒”


import pygame, time, random, sys, os
from pygame.locals import *
pygame.init()
# 创建窗口
can = pygame.display.set_mode((480, 660))
can.fill((255, 255, 255))
# 设置窗口标题
pygame.display.set_caption("消灭病毒") 
# 加载图片
bg0 = pygame.image.load("images/bg.png")  # 背景图片
bg1 = pygame.image.load("images/bg_1.png")  # 背景图片
bg2 = pygame.image.load("images/bg_4.png")  # 背景图片
bg3 = pygame.image.load("images/bg_3.png")  # 背景图片
blast = pygame.image.load("images/blast01.png")  # 爆炸图片
bullet0 = pygame.image.load("images/bullet.png")  # 子弹图片
bullet1 = pygame.image.load("images/bullet_2.png")  # 子弹图片
bullet2 = pygame.image.load("images/zhenguan.png")  # 子弹图片
bullet3 = pygame.image.load("images/yinghua.png")  # 子弹图片
diamond = pygame.image.load("images/diamond.png")  # 钻石图片
double_bullet = pygame.image.load("images/double_bullet.png")  # 多排子弹图片
gold_coin = pygame.image.load("images/gold_coin.png")  # 金币数量图片
blue = pygame.image.load("images/blue.png")  # 金币背景图片
gold = pygame.image.load("images/gold.png")  # 金币图片
logo = pygame.image.load("images/logo.png")  # logo图片
plane0 = pygame.image.load("images/plane.png")  # 飞机图片
plane1 = pygame.image.load("images/plane_4.png")  # 飞机图片
plane2 = pygame.image.load("images/plane_2.png")  # 飞机图片
plane3 = pygame.image.load("images/plane_3.png")  # 飞机图片                                   
virus_green = pygame.image.load("images/virus_green.png")  # 绿病毒图片
virus_red = pygame.image.load("images/virus_red.png")  # 红病毒图片
virus_yellow = pygame.image.load("images/virus_yellow.png")  # 黄病毒图片
class Canvas():
    def blit(self,img,*point):
        x = point[-1]
        y = point[0]
        can.blit(img,(x,y))
        if img == bg0 or img == bg1 or img == bg2 or img == bg3:
            can.blit(img,(GameVar.x2,GameVar.y2))
canvas = Canvas()
#事件控制方法
def handleEvent():
    for event in pygame.event.get():#循环遍历事件
        if event.type == QUIT or event.type == KEYDOWN and event.key == K_ESCAPE:
            pygame.quit()
            sys.exit()
        # 点击鼠标左键控制游戏开始到运行状态
        if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
            if  GameVar.state == 'START':
                GameVar.state = 'RUNNING' 
        if event.type == KEYDOWN and event.key == K_SPACE and GameVar.state == 'GAME_OVER':
            pygame.quit()
            os.system(sys.executable + ' virus.py')
            sys.exit()
        if event.type == pygame.MOUSEMOTION:
            # 运行状态下,控制飞机跟随鼠标移动
            if GameVar.state == 'RUNNING':
                GameVar.plane.x = event.pos[0] - GameVar.plane.width / 2
                GameVar.plane.y = event.pos[1] - GameVar.plane.height / 2
            # 鼠标移出移入事件控制运行和暂停状态切换
            if isMouseOut(event.pos[0], event.pos[1]):
                if  GameVar.state == 'RUNNING':
                    GameVar.state = 'PAUSE'
            if isMouseOver(event.pos[0], event.pos[1]):
                if  GameVar.state == 'PAUSE':
                    GameVar.state = 'RUNNING'  
                                          
# 判断时间间隔方法
def isActionTime(lastTime, interval):
    if lastTime == 0:
        return True
    currentTime = time.time()
    return currentTime - lastTime >= interval
    
# 写文字方法
def renderText(text, position, center, size):#(文字,坐标,坐标是否在中心,大小)
    # 设置字体样式和大小
    my_font = pygame.font.Font('images/msyh.ttf', size)
    text = my_font.render(text, True, (255, 255, 255))
    if center:
        textRect = text.get_rect()  # 获得要显示的文本的rect
        textRect.center = position  # 设置显示文本的坐标中心点
        can.blit(text, textRect)
    else:
        can.blit(text, position)
  
# 判断鼠标是否移出画布
def isMouseOut(x, y):
    if x >= 479 or x <= 0 or y >= 659 or y <= 0:
        return True

# 判断鼠标是否移入画布
def isMouseOver(x, y):
    if x > 0 and x < 479 and y > 0 and y < 659:
        return True
        
# 定义Sky类
class Sky():
    def __init__(self):
        self.width = 480
        self.height = 660
        self.x1 = 0
        self.y1 = 0
        self.x2 = 0
        self.y2 = -self.height
    def paint(self):
        canvas.blit(bg0, (self.x1, self.y1))
    def step(self):
        self.y1 = self.y1 + 0.5
        GameVar.y2 = GameVar.y2 + 0.5
        if self.y1 > self.height:
            self.y1 = -self.height
        if GameVar.y2 > self.height:
            GameVar.y2 = -self.height
            
# 定义父类FlyingObject
class FlyingObject():
    def __init__(self, x, y, width, height, life, img):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.life = life
        self.img = img
        self.lastTime = 0
        self.interval = 0.01
        self.canDelete = False
    # 碰撞检测方法
    def hit(self, object):
        o = object
        return o.x > self.x - o.width and o.x < self.x + self.width and o.y > self.y - o.height and o.y < self.y + self.height
    # 对象之间碰撞后的处理
    def bang(self, bangsign,component):
        # 病毒或双排子弹和飞机碰撞之后的处理
        if bangsign:
            self.canDelete = True
            if bangsign == 2:
                self.life -= 1
            if bangsign == 3:
               GameVar.canDouble = True
               GameVar.doubleTime += 30
        # 病毒和子弹碰撞之后的处理
        else:   
            if hasattr(self, 'coin'):#判断为病毒          
                self.life -= component.life
            if not hasattr(self, 'coin'):#判断为子弹
                self.life -= self.life    
            if self.life <= 0:
                self.canDelete = True
                if not hasattr(self, 'coin'):#判断为子弹
                    can.blit(blast, (self.x, self.y - 50))                 
                if hasattr(self, 'coin'):#判断为病毒
                    GameVar.coin += self.coin      
    # 越界处理
    def outOfBounds(self):
        return self.y > 660
    
# 定义Bullet类
class Bullet(FlyingObject):
    def __init__(self, x, y, width, height, life, img):
        FlyingObject.__init__(self, x, y, width, height, life, img)
    def paint(self):
        canvas.blit(bullet0,(self.x,self.y))
    # 重写step方法
    def step(self):        
        self.y = self.y - 9
    # 重写判断是否越界的方法
    def outOfBounds(self):
        return self.y < -self.height
    def setPower(self,life):
        self.life  = life
      
# 定义Virus类
class Virus(FlyingObject):
    def __init__(self, x, y, width, height, type, life, coin, img, perX, perY, size, degree, perDegree):
        FlyingObject.__init__(self, x, y, width, height, life, img)
        self.x = random.randint(0, 480 - self.width)
        self.y = -self.height
        self.perX = perX
        self.perY = perY
        self.size = size
        self.type = type
        self.coin = coin 
        self.degree = degree
        self.perDegree = perDegree
    def setLife(self,life):
        self.life  = life
    def paint(self):
        if self.degree == 360:
            self.perDegree = -5
        elif self.degree == 0:
            self.perDegree = 5
        self.degree += self.perDegree
        orig_rect = self.img.get_rect()
        rot_image = pygame.transform.rotate(self.img, self.degree)
        rot_rect = orig_rect.copy()
        rot_rect.center = rot_image.get_rect().center
        rot_image = rot_image.subsurface(rot_rect).copy()
        can.blit(rot_image, (self.x, self.y))  
        renderText(str(self.life), (self.x + (self.width / 2), self.y + (self.height / 2)), True, self.size)
    def step(self):
        # 判断是否到了移动的时间间隔
        if not isActionTime(self.lastTime, self.interval):
            return
        self.lastTime = time.time()
        # 控制移动速度
        self.y = self.y + self.perY
        self.x = self.x + self.perX
        if self.x < 0 or self.x > 480 - self.width:
            self.perX = -self.perX
     
# 定义Plane类
class Plane(FlyingObject):
    def __init__(self, x, y, width, height, life, img):
        FlyingObject.__init__(self, x, y, width, height, life, img)
        self.width = 100
        self.height = 120
        self.x = 190
        self.y = 495
        # 射击时间间隔
        self.shootLastTime = 0
        self.shootInterval = 0.14
    def paint(self):
        canvas.blit(plane0, (self.x, self.y))
    def shoot(self):
        if not isActionTime(self.shootLastTime, self.shootInterval):
            return
        self.shootLastTime = time.time()
        if GameVar.canDouble == True:
            plane01 = Bullet(self.x + self.width / 2, self.y - 25, 10, 29, 1, bullet0)
            plane01.setPower(1)
            GameVar.bullets.append(plane01)
            plane02 = Bullet(self.x + self.width / 2 - 10, self.y - 25, 10, 29, 1, bullet0)
            plane02.setPower(1)
            GameVar.bullets.append(plane02)
            GameVar.doubleTime = GameVar.doubleTime - 1
            if GameVar.doubleTime == 0:
                GameVar.canDouble = False
        else:
            plane03 = Bullet(self.x + self.width / 2 - 5, self.y - 25, 10, 29, 1, bullet0)
            plane03.setPower(1)
            GameVar.bullets.append(plane03)
            
# 定义Double类
class Double(FlyingObject):
    def __init__(self, x, y, width, height, life, img, perX, perY):
        FlyingObject.__init__(self, x, y, width, height, life, img)
        self.x = random.randint(0, 480 - self.width)
        self.y = -self.height
        self.perX = perX
        self.perY = perY
    def paint(self):
        can.blit(self.img, (self.x, self.y))
    def step(self):
        if not isActionTime(self.lastTime, self.interval):
            return
        self.lastTime = time.time()
        # 控制移动速度
        self.y += self.perY
        self.x += self.perX
        if self.x < 0:
            self.perX = 2
        if self.x > 480 - self.width:
            self.perX = -2
        
def objectEnter():
    # 控制产生病毒的间隔
    if not isActionTime(GameVar.lastTime, GameVar.interval):
        return
    GameVar.lastTime = time.time()
    # 随机生成坐标
    x = random.randint(0, 480 - 50)
    x1 = random.randint(0, 480 - 60)
    x2 = random.randint(0, 480 - 140)
    x3 = random.randint(0, 480 - 50)
    perX = random.randint(-2, 4) # x变化幅度
    perY = random.randint(2, 3) # y的变化幅度
    n = random.randint(0, 9)  # 根据随机整数的值生成不同的病毒
    m = random.randint(0, 15)  # 随机生成双排子弹
    if n <= 6:
        yellowVirus = Virus(x, 0, 50, 50, 1, 8, GameVar.yellowVirusCoin, virus_yellow, perX, perY, 20, 0, 1)
        yellowVirus.setLife(8)
        GameVar.viruses.append(yellowVirus)
    elif n == 8 or n == 7:
        redVirus = Virus(x1, 0, 68, 68, 2, 18, 50, virus_red,perX, perY, 25, 0, 1)
        redVirus.setLife(18)
        GameVar.viruses.append(redVirus)
    elif n == 9:
        if len(GameVar.viruses) == 0 or GameVar.viruses[0].type != 3:
            greenVirus = Virus(x2, 0, 150, 150, 3, 88, 100, virus_green,perX, 0.5, 55, 0, 1)
            greenVirus.setLife(88)
            GameVar.viruses.insert(0, greenVirus)
    if m == 10:
        GameVar.doubleBullets.append(Double(x3, 0, 50, 50, 1, double_bullet, perX, perY))    
# 画出游戏中的对象
def paintObject():    
    # 控制对象绘制的时间间隔
    if not isActionTime(GameVar.paintLastTime, GameVar.paintInterval):
        return
    GameVar.paintLastTime = time.time()
    GameVar.sky.paint()
    for Virus in GameVar.viruses:
        Virus.paint()
    for doubleBullet in GameVar.doubleBullets:
        doubleBullet.paint()
    GameVar.plane.paint()
    for bullet in GameVar.bullets:
        bullet.paint()
    # 画出并写出金币数和战力值
    can.blit(gold_coin, (15, 15))
    can.blit(diamond, (377, 15))
    renderText(str(GameVar.coin), (50, 15), False, 20)
    renderText(str(GameVar.planes), (420, 15), False, 20)
    
# 游戏中对象移动的方法
def objectStep():
    GameVar.sky.step()
    for Virus in GameVar.viruses:
        Virus.step()
    for doubleBullet in GameVar.doubleBullets:
        doubleBullet.step()
    for bullet in GameVar.bullets:
        bullet.step()
    
# 检测对象之间发生碰撞的方法
def checkHit():
    # 检测每个病毒是否与飞机发生碰撞
    for Virus in GameVar.viruses:
        if GameVar.plane.hit(Virus):
            Virus.bang(1,GameVar.plane)
            GameVar.plane.bang(2,Virus)
        # 检测每颗子弹是否与病毒发生碰撞
        for bullet in GameVar.bullets:
            if Virus.hit(bullet):
                Virus.bang(0,bullet)
                bullet.bang(0,Virus)
    # 检测飞机是否与双排子弹碰撞
    for doubleBullet in GameVar.doubleBullets:
        if GameVar.plane.hit(doubleBullet):
            doubleBullet.bang(3,GameVar.plane)

#删除对象
def deleteObject():
    for Virus in GameVar.viruses:
        if Virus.canDelete or Virus.outOfBounds():
            GameVar.viruses.remove(Virus)
    for bullet in GameVar.bullets:
        if bullet.canDelete or bullet.outOfBounds():
            GameVar.bullets.remove(bullet)
    for doubleBullet in GameVar.doubleBullets:
        if doubleBullet.canDelete or doubleBullet.outOfBounds():
            GameVar.doubleBullets.remove(doubleBullet)
    if GameVar.plane.canDelete == True:
        GameVar.planes -= 1
        if GameVar.planes <= 0:
            GameVar.state = 'GAME_OVER'
        else:
            GameVar.plane = Plane(0, 0, 100, 120, 1, plane0)
    
# 创建游戏变量
class GameVar():
    sky = None
    plane = None
    viruses = []
    bullets = []
    doubleBullets = []
    canDouble = False
    doubleTime = 0   #双排子弹时间
    startText = 240  # 文字初始坐标
    overText = 240
    lastTime = 0
    interval = 2
    paintLastTime = 0
    paintInterval = 0
    coin = 0
    planes = 3
    state = 'START'
    scale = 22  #设置呼吸金币大小
    moveText = 1 # 游戏开始和结束文字动画控制
    moveImage = 1 #游戏开始和结束图片动画控制
    x2 = 0
    y2 = -660
    yellowVirusCoin = 10
    
# 创建sky对象
GameVar.sky = Sky()
# 创建飞机对象
GameVar.plane = Plane(0, 0, 100, 120, 1, plane0)

# 游戏状态控制
def contralState():
    if  GameVar.state == 'START':
        GameVar.sky.paint()
        GameVar.startText += GameVar.moveText
        renderText('移 动 消 灭 病 毒', (GameVar.startText, 380), True, 25)
        if GameVar.startText == 250:
            GameVar.moveText = -1
        if GameVar.startText == 230:
            GameVar.moveText = 1   
        can.blit(logo, (50, 100))
        GameVar.plane.paint()
        GameVar.plane.y += GameVar.moveImage
        if GameVar.plane.y == 495:
            GameVar.moveImage = 1
        if GameVar.plane.y == 515:
            GameVar.moveImage = -1
        pygame.display.update() 
    elif GameVar.state == 'RUNNING':
        objectEnter()
        paintObject()
        objectStep()
        GameVar.plane.shoot()
        checkHit()
        deleteObject()
    elif GameVar.state == 'PAUSE':
        paintObject()
    elif GameVar.state == 'GAME_OVER':
        GameVar.sky.paint()
        can.blit(logo, (50, 100))
        can.blit(blue, (130, 410))
        renderText('你 赚 到 了 :', (GameVar.overText, 350), True, 25)
        GameVar.overText += GameVar.moveText
        if GameVar.overText == 250:
            GameVar.moveText = -1
        if GameVar.overText == 230:
            GameVar.moveText = 1
        renderText('x   ' + str(GameVar.coin), (265, 440), True, 25)
        # 添加呼吸金币
        rotatedSurf = pygame.transform.scale(gold, (GameVar.scale, GameVar.scale))
        rot_rect = rotatedSurf.get_rect()
        rot_rect.center = (190, 442)
        can.blit(rotatedSurf, rot_rect)
        if GameVar.scale == 20:
            GameVar.moveImage = 1
        elif GameVar.scale == 35:
            GameVar.moveImage = -1
        GameVar.scale += GameVar.moveImage
       
while True:
    # 游戏状态控制
    contralState()
    # 更新屏幕内容
    pygame.display.update()
    # 监听有没有按下退出按钮
    handleEvent()
    # 等待0.01秒后再进行下一次循环
    time.sleep(0.01)

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值