zoukankan      html  css  js  c++  java
  • 十三、坦克大战

    #类
    import pygame,time, random
    from pygame.sprite import Sprite
    SCREEN_WIDTH =800
    SCREEN_HEIGHT =600
    TEXT_COLOR = (0, 0, 0)
    BG_COLOR =pygame.Color(255, 0, 0)
    class BaseItem(Sprite):
    def __init__(self, color, width, height):
    # Call the parent class (Sprite) constructor
    pygame.sprite.Sprite.__init__(self)
    class MainGame():
    window = None
    my_tank = None
    enemyTankList = []
    enemyTankCount = 5
    myBulletList = []
    emeryBulletList =[]
    explodeList = []
    wallList = []
    def __init__(self):
    pass
    #开始游戏
    def startGame(self):
    # 加载主窗口
    pygame.display.init()
    # 显示窗口大小,并且显示
    MainGame.window = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT]) #返回一个窗口对象,surface对象
    # 创建我方坦克
    self.createMytank()
    self.createEmeryTank()
    self.createWall()
    pygame.display.set_caption('坦克大战')
    while True:
    time.sleep(0.02)
    MainGame.window.fill(BG_COLOR)
    self.getEvent()
    self.biltcreateWall()
    #左上角显示
    MainGame.window.blit(self.getTextSuface('Esc重生,espace射击,↑↓← →进行移动,当前坦克数量%d' %len(MainGame.enemyTankList)), (10, 10))
    # 显示我方坦克
    if MainGame.my_tank and MainGame.my_tank.live:
    MainGame.my_tank.displayTank()
    else:
    del MainGame.my_tank
    MainGame.my_tank = None
    #显示我方子弹
    self.CreateBullet()
    # 显示敌方坦克
    self.blitEmeryTank()
    # 展示敌方坦克子弹列表
    self.blitEmeryBulletList()
    # 坦克移动
    self.blitexplodeList()
    if MainGame.my_tank and MainGame.my_tank.live:
    if not MainGame.my_tank.stop:
    MainGame.my_tank.moveTank()
    MainGame.my_tank.bitWall()
    MainGame.my_tank.mytank_hit_emerytank()
    pygame.display.update()
    def blitEmeryTank(self):
    for emerytank in MainGame.enemyTankList:
    if emerytank.live:
    emerytank.displayTank()
    emerytank.randMove()
    emerytank.bitWall()
    emerybullet = emerytank.shot()
    if MainGame.my_tank and MainGame.my_tank.live:
    emerytank.emery_hit_mytank()
    if emerybullet:
    MainGame.emeryBulletList.append(emerybullet)
    else:
    MainGame.enemyTankList.remove(emerytank)

    def blitEmeryBulletList(self):
    for emeryBullet in MainGame.emeryBulletList:
    if emeryBullet.live:
    emeryBullet.disployBullet()
    emeryBullet.moveBullet()
    emeryBullet.emeryBullet_hit_myTank()
    emeryBullet.BullethitWall()
    else:
    MainGame.emeryBulletList.remove(emeryBullet)

    def CreateBullet(self):
    for myBullet in MainGame.myBulletList:
    if myBullet.live:
    myBullet.disployBullet()
    myBullet.moveBullet()
    myBullet.myBullet_hit_emeryTank()
    myBullet.BullethitWall()
    else:
    self.myBulletList.remove(myBullet)
    def blitexplodeList(self):
    for explode in MainGame.explodeList:
    if explode.live:
    explode.displayExplode()
    else:
    MainGame.explodeList.remove(explode)

    def createMytank(self):
    MainGame.my_tank = myTank(SCREEN_WIDTH/2, SCREEN_HEIGHT/2)
    music = Music("img/start.wav")
    music.play()
    #初始化敌方坦克,添加到列表中
    def createEmeryTank(self):
    top = random.randint(50, SCREEN_HEIGHT-100)
    for i in range(MainGame.enemyTankCount):
    left = random.randint(0, SCREEN_WIDTH-100)
    speed = random.randint(1, 4)
    enemy = EmeryTank(left, top, speed)
    MainGame.enemyTankList.append(enemy)

    def createWall(self):
    top = 200
    for i in range(6):
    wall = Wall(142*i,top)
    MainGame.wallList.append(wall)
    def biltcreateWall(self):
    for wall in MainGame.wallList:
    if wall.live:
    wall.disployWall()
    else:
    MainGame.wallList.remove(wall)
    #结束游戏
    def endGame(self):
    print("你好呀,再见")
    exit()
    #左上角文字描述
    def getTextSuface(self,text):
    #初始化字体模块
    pygame.font.init()
    #查看所有字体
    #print(pygame.font.get_fonts())
    #获取字体类型对象
    font=pygame.font.SysFont('kaiti', 18)
    #绘制文字信息
    sextSurFace=font.render(text, True, TEXT_COLOR)
    return sextSurFace

    #添加事件,点击关闭,关闭窗口;按下键盘的时候,判断键盘按下的是什么键
    def getEvent(self):
    #获取所有事件
    eventList = pygame.event.get()
    #遍历事件
    for event in eventList:
    #判断按下的键是关闭还是键盘按下
    if event.type == pygame.QUIT:
    self.endGame()
    #如果是键盘的按键
    if event.type == pygame.KEYDOWN:
    if not MainGame.my_tank:
    if event.key == pygame.K_ESCAPE:
    self.createMytank()
    if MainGame.my_tank and MainGame.my_tank.live:
    if event.key == pygame.K_LEFT:
    MainGame.my_tank.direction = 'L'
    self.my_tank.stop = False
    # MainGame.my_tank.moveTank()
    print('按下左键,坦克向左移动')
    elif event.key == pygame.K_RIGHT:
    MainGame.my_tank.direction = 'R'
    self.my_tank.stop = False
    # MainGame.my_tank.moveTank()
    print('按下右键,坦克向右移动')
    elif event.key == pygame.K_UP:
    MainGame.my_tank.direction = 'U'
    self.my_tank.stop = False
    # MainGame.my_tank.moveTank()
    print('按下上键,坦克向上移动')
    elif event.key == pygame.K_DOWN:
    MainGame.my_tank.direction = 'D'
    self.my_tank.stop = False
    # MainGame.my_tank.moveTank()
    print('按下下键,坦克向下移动')
    elif event.key == pygame.K_SPACE:
    if len(self.myBulletList) < 3:
    print('发射子弹')
    myBullet = Bullet(MainGame.my_tank)
    self.myBulletList.append(myBullet)
    music = Music("img/fire.wav")
    music.play()


    if event.type == pygame.KEYUP:
    if event.key == pygame.K_UP or event.key == pygame.K_DOWN or event.key == pygame.K_RIGHT or event.key == pygame.K_LEFT:
    if MainGame.my_tank and MainGame.my_tank.live:
    self.my_tank.stop = True


    class Tank(BaseItem):
    def __init__(self, left, top):
    self.images = {
    'U': pygame.image.load('img/p1tankU.gif'),
    'R': pygame.image.load('img/p1tankR.gif'),
    'L': pygame.image.load('img/p1tankL.gif'),
    'D': pygame.image.load('img/p1tankD.gif')
    }
    #方向
    self.direction = 'L'
    #根据当前图片的方向,获取图片
    self.image = self.images[self.direction]
    #获取图片的区域
    self.rect = self.image.get_rect()
    #设置区域的left,top
    self.rect.left = left
    self.rect.top = top
    #速度
    self.speed = 5
    # 移动开关
    self.stop = True
    # 增加坦克存活开关
    self.live = True
    #增加原来的坐标
    self.oldleft = self.rect.left
    self.oldtop = self.rect.top
    #移动
    def moveTank(self):
    self.oldtop = self.rect.top
    self.oldleft = self.rect.left
    if self.direction == 'U' and self.rect.top>0:
    self.rect.top -= self.speed
    elif self.direction == 'L'and self.rect.left>0:
    self.rect.left -=self.speed
    elif self.direction == 'R'and self.rect.left+self.rect.height<SCREEN_WIDTH:
    self.rect.left +=self.speed
    elif self.direction == 'D'and self.rect.top+self.rect.height<SCREEN_HEIGHT:
    self.rect.top += self.speed
    #射击
    def shot(self):
    return Bullet(self)
    def bitWall(self):
    for wall in MainGame.wallList:
    if pygame.sprite.collide_rect(self, wall):
    self.stay()
    def stay(self):
    self.rect.left = self.oldleft
    self.rect.top = self.oldtop
    #显示
    def displayTank(self):
    # 获取展示的对象
    self.image = self.images[self.direction]
    # 调用blit方法展示
    MainGame.window.blit(self.image, self.rect)
    class myTank(Tank):
    def __init__(self,left,top):
    super(myTank, self).__init__(left,top)
    def mytank_hit_emerytank(self):
    for emery in MainGame.enemyTankList:
    if pygame.sprite.collide_rect(self,emery):
    self.stay()

    class EmeryTank(Tank):

    def __init__(self, left, top, speed):
    super(EmeryTank, self).__init__(left,top)
    # 加载图片集
    self.images = {
    'U': pygame.image.load('img/enemy1U.gif'),
    'D': pygame.image.load('img/enemy1D.gif'),
    'L': pygame.image.load('img/enemy1L.gif'),
    'R': pygame.image.load('img/enemy1R.gif')
    }
    #坦克的方向
    self.direction = self.directionRandom()
    #敌方坦克的图片
    self.image = self.images[self.direction]
    #获取区域
    self.rect = self.image.get_rect()
    #设置坦克的区域
    self.rect.left = left
    self.rect.top = top
    #速度
    self.speed = speed
    #移动开关
    self.stop = True
    self.step = 60

    def directionRandom(self):
    randomNum = random.randint(1, 4)
    if randomNum == 1:
    return 'U'
    elif randomNum == 2:
    return 'L'
    elif randomNum == 3:
    return 'R'
    elif randomNum == 4:
    return 'D'
    def randMove(self):
    if self.step <=0:
    self.direction = self.directionRandom()
    self.step = 60
    else:
    self.moveTank()
    self.step -= 1

    def shot(self):
    n = random.randint(1, 100)
    if n < 5:
    return Bullet(self)
    def emery_hit_mytank(self):
    if pygame.sprite.collide_rect(self,MainGame.my_tank):
    self.stay()

    class Wall():
    def __init__(self,left,top):
    self.image = pygame.image.load("img/steels.gif")
    self.rect = self.image.get_rect()
    self.rect.left = left
    self.rect.top = top
    self.live = True
    #续命时间
    self.hg =3
    #展示墙壁
    def disployWall(self):
    MainGame.window.blit(self.image, self.rect)

    class Bullet(BaseItem):
    def __init__(self, tank):
    self.image = pygame.image.load('img/enemymissile.gif')
    self.direction = tank.direction
    #子弹的区域
    self.rect = self.image.get_rect()
    #子弹的top left
    if self.direction == 'U':
    self.rect.left = tank.rect.left + tank.rect.width / 2 - self.rect.width / 2
    self.rect.top = tank.rect.top - self.rect.height
    elif self.direction == 'D':
    self.rect.left = tank.rect.left + tank.rect.width / 2 - self.rect.width / 2
    self.rect.top = tank.rect.top + tank.rect.height
    elif self.direction == 'L':
    self.rect.left = tank.rect.left - self.rect.width / 2 - self.rect.width / 2
    self.rect.top = tank.rect.top + tank.rect.width / 2 - self.rect.width / 2
    elif self.direction == 'R':
    self.rect.left = tank.rect.left + tank.rect.width
    self.rect.top = tank.rect.top + tank.rect.width / 2 - self.rect.width / 2
    self.speed = 6
    #子弹展示的开关
    self.live = True
    #子弹移动
    def moveBullet(self):
    if self.direction == 'U':
    if self.rect.top >0:
    self.rect.top -= self.speed
    else:
    self.live = False
    elif self.direction == 'D':
    if self.rect.top + self.rect.width < SCREEN_HEIGHT:
    self.rect.top +=self.speed
    else:
    self.live = False
    elif self.direction == 'L':
    if self.rect.left>0:
    self.rect.left -=self.speed
    else:
    self.live = False
    elif self.direction == 'R':
    if self.rect.left +self.rect.width <SCREEN_WIDTH:
    self.rect.left +=self.speed
    else:
    self.live = False
    #展示子弹
    def disployBullet(self):
    # 将图片surface加载到窗口
    MainGame.window.blit(self.image, self.rect)
    def myBullet_hit_emeryTank(self):
    for emerytank in MainGame.enemyTankList:
    if pygame.sprite.collide_rect(emerytank, self):
    emerytank.live = False
    self.live = False
    explode = Explode(emerytank)
    MainGame.explodeList.append(explode)
    def emeryBullet_hit_myTank(self):
    if MainGame.my_tank and MainGame.my_tank.live:
    if pygame.sprite.collide_rect(MainGame.my_tank, self):
    MainGame.my_tank.live = False
    self.live = False
    explode = Explode(MainGame.my_tank)
    MainGame.explodeList.append(explode)
    def BullethitWall(self):
    for wall in MainGame.wallList:
    if pygame.sprite.collide_rect(wall, self):
    self.live = False
    wall.hg -= 1
    if wall.hg < 0:
    wall.live = False
    music = Music("img/hit.wav")
    music.play()
    class Explode():
    def __init__(self,Tank):
    self.rect = Tank.rect
    self.images = [
    pygame.image.load("img/blast0.gif"),
    pygame.image.load("img/blast1.gif"),
    pygame.image.load("img/blast2.gif"),
    pygame.image.load("img/blast3.gif"),
    pygame.image.load("img/blast4.gif"),
    ]
    self.step = 0
    # self.image = self.images[self.step]
    #判断是否活着
    self.live = True
    #展示爆炸效果
    def displayExplode(self):
    if self.step < len(self.images):
    self.image = self.images[self.step]
    self.step += 1
    MainGame.window.blit(self.image, self.rect)
    else:
    self.live = False
    self.step = 0
    class Music():
    def __init__(self, filename):
    self.filename = filename
    pygame.mixer.init()
    pygame.mixer.music.load(self.filename)
    #播放方法
    def play(self):
    pygame.mixer.music.play()

    if __name__ =='__main__':
    MainGame().startGame()

  • 相关阅读:
    kafka消费者如何才能从头开始消费某个topic的全量数据
    kafka消费者客户端启动之后消费不到消息的原因分析
    JMeter测试工具中的参数化使用[函数助手]
    在IDEA中使用gradle配置打可执行jar包[可执行jar与其所依赖的jar分离]
    一次tomcat配置参数调优Jmeter压力测试记录前后对比
    IntelliJ IDEA 14.1.4导入项目启动报错:Error during artifact deployment.[组件部署期间出错]
    BZOJ2861 : 双向边定向为单向边
    BZOJ4313 : 三维积木
    BZOJ4714 : 旋转排列
    BZOJ1395 : [Baltic2005]Trip
  • 原文地址:https://www.cnblogs.com/dangjingwei/p/12313957.html
Copyright © 2011-2022 走看看