利用python3 的pygame模块实现塔防游戏
利用python3的pygame模块基本实现塔防游戏的基本功能,包括血量和分数显示,bgm,防御塔建造,防御塔攻击范围内的敌军,暂停和加速功能。由于实在没有素材,用的都是自己截图P的,所以美化不好。但基本保证功能,其中有一个BUG,但不影响游戏效果。
1.运行主类
"""主程序"""
frompygame.localsimport*
fromTowerDefend.enemyimport*
fromTowerDefend.towerposSetimport*
fromTowerDefend.towerimport*
importpygame
defrun():
"""运行函数"""
pygame.init()
size=width,height=1200,600
screen=pygame.display.set_mode(size)
background_img=pygame.image.load(r'image/background.png').convert_alpha()
background_img=pygame.transform.scale(background_img,(width,height))
#创建分数和血量
health_count=5
score_count=0
score=pygame.font.Font('font/score_health.ttf',30)
health=pygame.font.Font('font/score_health.ttf',30)
#创建背景音乐
bg_music=pygame.mixer.music
bg_music.load('media/bg.mp3')
bg_music.set_volume(2)
#创建敌军类
enemies=pygame.sprite.Group()
ENEMY_NUM=5
position=[[258,600],[258,670],[258,740],[258,810],[258,880]]
foriinrange(ENEMY_NUM):
enemies.add(Enemy(position[i]))
#创建炮塔
towers=pygame.sprite.Group()
#加载暂停键
pause_img=pygame.image.load('image/pause.png').convert_alpha()
pause_rect=pause_img.get_rect()
pause_rect.left,pause_rect.top=1145,0
#加载血量和金币显示
health_money_img=pygame.image.load('image/health_money.png').convert_alpha()
health_money_rect=health_money_img.get_rect()
health_money_rect.left,health_money_rect.top=0,0
#加载加速键
speed_img=pygame.image.load('image/speed.png').convert_alpha()
speed_rect=speed_img.get_rect()
speed_rect.left,speed_rect.top=1090,0
#设置炮塔位置
towers_pos=pygame.sprite.Group()
position_list=[[225,495],[264,428],[312,428],[362,428],[410,428],[460,428],[508,428],[561,428],
[561,373],[377,373]]
foriinrange(len(position_list)):
towers_pos.add(Position(position_list[i]))
#设置循环条件
running=True
clock=pygame.time.Clock()
paused=False
#播放音乐
ifnotbg_music.get_busy():
bg_music.play(-1)
whilerunning:
clock.tick(100)
foreventinpygame.event.get():
ifevent.type==QUIT:
running=False
ifevent.type==MOUSEBUTTONDOWN:
ifevent.button==1:
ifspeed_rect.collidepoint(event.pos):
foreachinenemies:
each.accelerate*=2
ifpause_rect.collidepoint(event.pos):
paused=notpaused
foreachintowers_pos:
ifeach.rect.collidepoint(event.pos):
tower=Tower([each.rect.left,each.rect.top])
towers.add(tower)
towers_pos.remove(each)
ifnotpaused:
forenemyinenemies:
ifenemy.active:
enemy.move()
else:
ifenemy.rect.top<=180:
health_count-=1
ifenemy.rect.top>180:
score_count+=20
enemies.remove(enemy)
#绘制界面设置
screen.blit(background_img,(0,0))
screen.blit(health.render(str(health_count),True,(255,255,255)),(60,0.3))
screen.blit(score.render(str(score_count),True,(255,255,255)),(130,0.5))
screen.blit(health_money_img,health_money_rect)
screen.blit(pause_img,pause_rect)
screen.blit(speed_img,speed_rect)
#绘制炮塔
foreachintowers:
each.draw(screen,enemies)
each.hit(enemies)
#绘制炮塔位置
towers_pos.draw(screen)
#敌军若存活则绘制其和血量
forenemyinenemies:
ifenemy.active:
screen.blit(enemy.img,enemy.rect)
enemy.drawhealth(screen)
pygame.display.flip()
pygame.quit()
if__name__=="__main__":
run()
2.炮塔类
"""TOWER"""
importpygame
importmath
classTower(pygame.sprite.Sprite):
"""tower"""
def__init__(self,pos):
pygame.sprite.Sprite.__init__(self)
self.img0=pygame.image.load('image/tower0.png')
self.img1=pygame.image.load('image/tower1.png')
self.img2=pygame.image.load('image/tower2.png')
self.rect=self.img0.get_rect()
self.rect.left,self.rect.top=pos
self.count=1
defdraw(self,screen,enemies):
"""绘制"""
ifself.count>90:
self.count=1
if1<=self.count<30:
screen.blit(self.img0,self.rect)
elif30<=self.count<60:
screen.blit(self.img1,self.rect)
else:
screen.blit(self.img2,self.rect)
forenemyinenemies:
distance=math.sqrt(
math.pow((self.rect.left-enemy.rect.left),2)+math.pow((self.rect.top-enemy.rect.top),2))
ifdistance<50andenemy.activeisTrue:
self.count+=1
defhit(self,enemies):
"""攻击"""
forenemyinenemies:
distance=math.sqrt(
math.pow((self.rect.left-enemy.rect.left),2)+math.pow((self.rect.top-enemy.rect.top),2))
ifdistance<50:
enemy.health-=1
ifenemy.health==0:
enemy.active=False
3.敌军类
importpygame classEnemy(pygame.sprite.Sprite): """小兵类""" def__init__(self,position): pygame.sprite.Sprite.__init__(self) self.img=pygame.image.load(r'image/enemy.png').convert_alpha() self.rect=self.img.get_rect() self.init_pos=position self.rect.left,self.rect.top=self.init_pos self.accelerate=1 self.speed=[0,-self.accelerate] self.active=True self.health=500 #竖直 self.status='UP' defmove(self): """移动""" self.rect=self.rect.move(self.speed) ifself.rect.top<=448andself.rect.left==258: self.rect.top=448 self.status='R' self.img=pygame.transform.rotate(self.img,270) self.speed=[self.accelerate,0] ifself.rect.top==448andself.rect.left>=597: self.rect.left=597 self.status='UP' self.img=pygame.transform.rotate(self.img,90) self.speed=[0,-self.accelerate] if320self.rect.left>=746: self.rect.left=746 self.status='DW' self.img=pygame.transform.rotate(self.img,270) self.speed=[0,self.accelerate] ifself.rect.top>=330andself.rect.left==746: self.rect.top=330 self.status='R' self.img=pygame.transform.rotate(self.img,90) self.speed=[self.accelerate,0] ifself.rect.top==330andself.rect.left>=930: self.rect.left=930 self.status='UP' self.img=pygame.transform.rotate(self.img,90) self.speed=[0,-self.accelerate] ifself.rect.top<180: self.active=False defdrawhealth(self,screen): """绘制血量""" BLACK=(0,0,0) RED=(255,0,0) GREEN=(0,255,0) health_percentage=float(self.health)/500 ifself.status=='UP': start=self.rect.left+8 pygame.draw.line(screen,BLACK,(start,self.rect.top-3), (start+32,self.rect.top-3),4) ifhealth_percentage>0.5: pygame.draw.line(screen,GREEN,(start,self.rect.top-3), (start+32*health_percentage,self.rect.top-3),4) else: pygame.draw.line(screen,RED,(start,self.rect.top-3), (start+32*health_percentage,self.rect.top-3),4) elifself.status=='DW': start=self.rect.left+8 pygame.draw.line(screen,BLACK,(start,self.rect.bottom+3), (start+32,self.rect.bottom+3),4) ifhealth_percentage>0.5: pygame.draw.line(screen,GREEN,(start,self.rect.bottom+3), (start+32*health_percentage,self.rect.bottom+3),4) else: pygame.draw.line(screen,RED,(start,self.rect.bottom+3), (start+32*health_percentage,self.rect.bottom+3),4) elifself.status=='R': start=self.rect.bottom-8 pygame.draw.line(screen,BLACK,(self.rect.right+3,start), (self.rect.right+3,start-32),4) ifhealth_percentage>0.5: pygame.draw.line(screen,GREEN,(self.rect.right+3,start), (self.rect.right+3,start-32*health_percentage),4) else: pygame.draw.line(screen,RED,(self.rect.right+3,start), (self.rect.right+3,start-32*health_percentage),4) else: start=self.rect.bottom-8 pygame.draw.line(screen,BLACK,(self.rect.left-3,start), (self.rect.left-3,start-30),4) ifhealth_percentage>0.5: pygame.draw.line(screen,GREEN,(self.rect.left-3,start), (self.rect.left-3,start-30*health_percentage),4) else: pygame.draw.line(screen,RED,(self.rect.left-3,start), (self.rect.left-3,start-30*health_percentage),4) defreset(self): """resettheposition""" self.rect.left,self.rect.top=self.init_pos
4.炮塔建造位置类
"""初始化炮塔可占据的位置"""
importpygame
classPosition(pygame.sprite.Sprite):
"""pos"""
def__init__(self,pos):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.image.load('image/pt.png')
self.rect=self.image.get_rect()
self.rect.left,self.rect.top=pos
5.说明
本游戏通过鼠标左键点击炮塔可以建造的位置俩建造炮塔。
6.效果图
可以看到图确实不好看,但美术功底不够,所以不怎么好看。当然需要素材的也可以给你。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。