利用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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。