pygame编写的坦克游戏(四)

游戏最基础的东东:精灵动画

贴一段代码吧:

import random
import pygame
from const import *

class Block(pygame.sprite.DirtySprite):
    #精灵(赃精灵)
    def __init__(self, engine, who, type, pos, delay = 0, layer = LIST_BALKS):
        pygame.sprite.DirtySprite.__init__(self)
        self.engine = engine
        self.mode = 1 #-1销毁 0出生 1正常 2爆炸
        self.who = who #-1边界 0可击毁地图目标 1玩家1 2玩家2 3敌人
        self.type = type #类型,决定精灵显示样式
        self.scale = False #是否缩放(子弹爆炸效果和坦克爆炸效果用的同样的资源,坦克爆炸动画尺寸大一些)
        self.dir = DIR_UP  #方向(对运动目标有效)
        self.can_through = False #是否允许通过
        self.can_destory = True  #是否允许消灭(子弹可以击毁)
        self.destory_fire = 1 #击毁需要火力等级
        self.pos = pos #显示位置
        self.animation = True #贴图动画(玩家坦克2帧,不动时就不需动画效果了)
        self.frame_delay = delay #帧延时(多帧时有效)
        self.image_change(self.type, self.frame_delay)
        self.engine.add_sprite(self, layer)
        
    def get_rect(self):
        pt = [self.pos[0]+1, self.pos[1] + 1]
        return pygame.Rect(pt, (self.width-2, self.height-2))
    
    def image_change(self, type = -1, delay = 0):
        if type >=  0:
            self.type = type
        if delay > 0:
            self.frame_delay = delay
        self.frame_index = 0
        angle = DIR_CFG[self.dir]["angle"]
        self.frames = self.engine.get_frame(self.type, angle, self.scale)        
        self.frame_count = len(self.frames)
        self.image = self.frames[self.frame_index]
        self.width = self.image.get_width()
        self.height = self.image.get_height()
                
    def inc_counter(self, timer):
        #累计一定时间后进行帧切换
        if self.frame_delay > 0 and timer % self.frame_delay == self.frame_delay - 1:
            self.next_frmae()
    
    def next_frmae(self):
        if self.frame_count > 1:
            if self.frame_index + 1 == self.frame_count:
                self.frame_index = 0
            else:
                self.frame_index += 1
            if self.animation:
                self.image = self.frames[self.frame_index]
            
    def hit(self, bullet):
        if self.can_destory and bullet.level >=  self.destory_fire:
            self.die()
    
    def draw(self, screen):
        screen.blit(self.image, self.pos)
        
    def die(self):
        self.kill()
        del self

里面有个timer,由主程序的Clock.Tick()后进行累加,就是每帧累加一次,每关都从0开始

通过精灵Mode、FrameDelay来确定每帧显示的时间,一般的障碍物像砖头、钢板是没有动画的(只有一帧),河有动画(两帧)

玩家的坦克也有动画,但是不动时是允许显示动画的,所以后面要覆盖inc_counter方法,被击中效果也不一样所以也要覆盖hit、draw、die方法

再上几个障碍子类的代码:

class Brick(Block):
    #砖
    def __init__(self, engine, who, type, pos, delay, layer):
        Block.__init__(self, engine, who, type, pos, delay, layer)
        self.can_through = False
        
    def hit(self, bullet):
        if bullet.who !=  WHO_ENEMY:
            self.engine.play_sound(SND_BRICK)
        if bullet.level > 2:
            self.die()
        else:
            #击中不中位置,火力不同产生的销毁效果也不同
            type = BRICK_TAB[bullet.dir][self.type]
            if type == M_00:
                self.die()
            else:
                self.image_change(type)
        
class Ice(Block):
    #冰
    def __init__(self, engine, who, type, pos, delay, layer):
        Block.__init__(self, engine, who, type, pos, delay, layer)
        self.can_through = True
        self.can_destory = False
        
class River(Block):
    #河
    def __init__(self, engine, who, type, pos, delay, layer):
        Block.__init__(self, engine, who, type, pos, 30, layer)
        self.can_through = False
        self.can_destory = False
        
class Steel(Block):
    #钢板
    def __init__(self, engine, who, type, pos, delay, layer):
        Block.__init__(self, engine, who, type, pos, delay, layer)
        self.can_through = False
        
    def hit(self, bullet):
        if bullet.level > 2:
            self.die()
        else:
            if bullet.who !=  WHO_ENEMY:
                self.engine.play_sound(SND_STEEL)
        
class Base(Block):
    #基地
    def __init__(self, engine, who, type, pos, delay, layer):
        Block.__init__(self, engine, who, type, pos, delay, layer)
        self.can_through = False
        
    def hit(self, bullet):
        self.mode = -1
        self.can_through = True
        self.can_destory = False
        self.next_frmae()
        self.animation = False
        self.engine.game_over()
        self.engine.play_sound(SND_KILL)
    
class Food(Block):
    #宝物
    def __init__(self, engine):
        if engine.food !=  None:
            engine.food.die()
            engine.food = None
        foodtype = random.choice([P_STAR, P_CAPS, P_TIMR, P_BOMB, P_LIFE, P_SPAD]) #宝物类型
        pos = [32 + random.randint(1, 22) * 16, 32 + random.randint(1, 20) * 16]
        Block.__init__(self, engine, WHO_FOOD, foodtype, pos, 10, LIST_COVER)
        self.engine.play_sound(SND_SPECIAL)
        self.can_through = True
        self.duration = FOODS_DURATION           
        self.effect_time = self.engine.timer
        self.engine.food = self
        
    def get_rect(self):
        pt = [self.pos[0]+8, self.pos[1] + 8]
        return pygame.Rect(pt, (self.width-16, self.height-16))
    
    def eat(self, player):
        self.mode = -1
        pdict = self.engine.players[player.who]
        pdict["Score"] += 500
        self.engine.play_sound(SND_ADDLIFE if self.type == P_LIFE else SND_PROPS)
        if self.type == P_LIFE:
            pdict["Life"] += 1
        elif self.type == P_STAR:#等级提升            
            player.add_fire(1)
        elif self.type == P_CAPS:#无敌模式
            player.set_god()            
        elif self.type == P_BOMB:#杀死所有敌坦克列表
            self.engine.bomb_enemy()
        elif self.type == P_TIMR:#暂时敌人动画也要暂停
            self.engine.stop_enemy()
        elif self.type == P_SPAD:#加强老窝
            self.engine.protect_base()

        self.duration = SCORE_DURATION
        self.effect_time = self.engine.timer
        self.frame_delay = 0
        self.image_change(S_500)
        
    def inc_counter(self, timer):
        #累计一定时间后进行帧切换
        if timer - self.effect_time > self.duration:
            self.die()
        else:
            super().inc_counter(timer)
            
    def die(self):
        self.engine.food = None
        super().die()



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值