画面,配音效果非常不错的一个pygame射击小游戏,以下是部分代码预览:
""" pygame泡泡坦克大战.py 在游戏中用鼠标操作我方坦克射击彩色泡泡,打击敌方坦克,有三叉泡泡道具,连发道具,生命道具。
NPC坦克会时不时的瞄准我方坦克进行攻击,游戏可是有一定的难度哦,不过有了三叉和连发道具后就能所向披靡了。
本程序相对于前一个本版主要改动的内容为NPCTank增加了Shell属性,Tank的发射方法增加了Shell参数。各个类已经单独列为模块。
本程序的前身是李兴球先生用scratch2.0制作的泡泡坦克大战。
"""
__author__ = "李兴球"
__date__ = "2018年12月左右"
import os,math
import pygame
from pygame.locals import *
from random import randint,choice
from prop import Prop # 从道具模块导入道具类
from explosion import Explosion # 从爆炸模块导入爆炸类
from shell import Shell # 从炮弹模块导入炮弹类
from npctank import NPCTank # 从npctank导入NPCTank类,敌方AI坦克
from tank import Tank # 坦克模块导入Tank类,这是我方坦克
def collision_check():
global npc_dead_amounts
"玩家炮弹组和npc的碰撞检测"
sprite_dict = pygame.sprite.groupcollide(group_player_shell,group_npc,True,True) # 返回的是一个字典
if sprite_dict: # 返回的可能是这样:{<Shell sprite(in 0 groups)>: [<NPCTank sprite(in 0 groups)>, <NPCTank sprite(in 0 groups)>]} # 有可能一次击中多个npc
#print(sprite_dict)
npc_dead_amounts += len(sprite_dict.values()) # 统计阵亡的坦克数量
hitted_tank = list(sprite_dict.values())[0]
position = hitted_tank[0].rect.center
Explosion(explosion_images,position,group_explosion,screen,explosion_sound) # 生成爆炸效果实例对象
"玩家和npc的碰撞检测"
collided_npc_tank = pygame.sprite.spritecollideany(player,group_npc) # 返回被撞到的npc
if collided_npc_tank and not player.died(): # 注意防止连续碰撞
player.die()
collided_npc_tank.die()
npc_dead_amounts += 1 # 统计阵亡的坦克数量
group_npc.remove(collided_npc_tank)
position_npc = collided_npc_tank.rect.center
Explosion(explosion_images,position_npc,group_explosion,screen,explosion_sound)
position_player = player.rect.center
Explosion(explosion_images,position_player,group_explosion,screen,explosion_sound)
"玩家炮弹和npc炮弹碰撞检测,即我方炮弹可以抵销敌方炮弹"
sprite_dict2 = pygame.sprite.groupcollide(group_player_shell,group_npc_shell,True,True) # 返回的是一个字典
if sprite_dict2: #字典的key是炮弹,只是利用它取个坐标
shell = list(sprite_dict2.keys())[0]
Explosion(explosion_images,shell.rect.center,group_explosion,screen,explosion_sound)
"玩家和npc炮弹的碰撞检测"
hit_shell = pygame.sprite.spritecollideany(player,group_npc_shell) # 返回敌方的炮弹
if hit_shell and not player.died():
player.die()
hit_shell.die() # 使用die方法
position_shell = hit_shell.rect.center
Explosion(explosion_images,position_shell,group_explosion,screen,explosion_sound)
position_player = player.rect.center
Explosion(explosion_images,position_player,group_explosion,screen,explosion_sound)
def playmusic(music):
pygame.mixer.music.load(music)
pygame.mixer.music.play(-1,0)
def display_cover(cover_image):
"""显示封面的函数"""
clock = pygame.time.Clock()
continue_game = True
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
continue_game = False
running = False
break
if event.type == KEYDOWN:
if event.key == K_SPACE:
running = False
break
screen.blit(cover_image,(0,0))
pygame.display.update()
clock.tick(30)
return continue_game
def main():
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:running = False
if event.type == npc_produce_EVENT :
# 定时产生NPC,把Shell类也传进去了,做为npc的一个属性,在它的shoot方法中生成炮弹会使用到
NPCTank(npc_image,npc_shell_image,player,screen,group_npc,group_npc_shell,Shell)
if event.type == prop_produce_EVENT:
Prop(prop_images,group_prop,player,screen) # 定时产生道具
if event.type == MOUSEBUTTONUP:
if event.button == 1:
player.shoot(Shell) # 发射炮弹
if player.three_fire > 0: player.three_fire -= 1
if player.three_fire == 0 and player.shell_image != shell_image:
player.shell_image = shell_image
if player.continue_fire > 0 :
player.shoot(Shell)
player.continue_fire -= 1
if player.three_fire > 0: player.three_fire -= 1
if player.three_fire > 0 and player.shell_image != three_shell_image: # 更换为三叉泡泡弹
player.shell_image = three_shell_image
mousexy = pygame.mouse.get_pos()
player.forward(mousexy)
player.update()
group_player_shell.update() # 玩家发射的炮弹组
group_npc.update() # npc组
group_npc_shell.update() # npc炮弹组
group_prop.update() # 道具组更新
if player.invincible_time > 0: # 这个值大于0,说明玩家坦克已阵亡,让它减小直到为0
player.invincible_time -=1
if player.invincible_time == 0: # 等于0的时候才做碰撞检测
collision_check() # 碰撞检测
screen.fill((150,0,0)) # 重画背景色
player.draw() # 重画玩家的坦克
group_player_shell.draw(screen) # 重画所有玩家发射的炮弹
group_npc.draw(screen) # 重画所有npc
group_npc_shell.draw(screen) # 重画所有npc发射的炮弹
group_prop.draw(screen) # 重画所有道具
for bomb in group_explosion: # 这里不用group的draw方法,因为它要切换造型
bomb.draw()
pygame.display.set_caption("生命数:" + str(player.lives) + ",敌方坦克阵亡数:" + str(npc_dead_amounts))
pygame.display.update()
clock.tick(30)
if npc_dead_amounts > 100:
running = False
if npc_dead_amounts > 100:
finish(pygame.image.load(fisnish_image))
else:
pygame.quit()
def finish(image):
"""显示结尾图形"""
clock = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT or event.type == MOUSEBUTTONDOWN:
running = False
break
screen.blit(image,(0,0))
pygame.display.update()
clock.tick(30)
pygame.quit()
if __name__ == "__main__":
npc_dead_amounts = 0 # 敌方坦克阵亡数量
cover_image = os.getcwd() + os.sep + "images" + os.sep + "封面.png"
fisnish_image = os.getcwd() + os.sep + "images" + os.sep + "finish.png"
prop_images = [ "life.png","continuous_fire.png","three_fire.png"] # 道具图片表
prop_images = [ os.getcwd() + os.sep + "images" + os.sep + image for image in prop_images]
explosion_images = [ "explosion" + str(i) + ".png" for i in range(1,6)]
explosion_images = [ os.getcwd() + os.sep + "explosion" + os.sep + image for image in explosion_images]
npc_image = os.getcwd() + os.sep + "images" + os.sep + "绿坦克.png"
shell_image = os.getcwd() + os.sep + "images" + os.sep + "ball-c.png"
three_shell_image = os.getcwd() + os.sep + "images" + os.sep + "three_shell.png"
npc_shell_image = os.getcwd() + os.sep + "images" + os.sep + "ball-a.png"
player_image = os.getcwd() + os.sep + "images" + os.sep + "蓝坦克.png"
width,height = 960,720
game_title = "泡泡坦克大战"
pygame.init()
screen = pygame.display.set_mode((width,height))
pygame.display.set_caption(game_title)
shell_image = pygame.image.load(shell_image).convert_alpha() # 泡泡弹
three_shell_image = pygame.image.load(three_shell_image).convert_alpha() # 三叉泡泡弹
npc_shell_image = pygame.image.load(npc_shell_image).convert_alpha()
explosion_images = [pygame.image.load(image).convert_alpha() for image in explosion_images]
s = [ pygame.image.load(image).convert_alpha() for image in prop_images] # 道具图层表
prop_images = {}.fromkeys(['life','continue','three']) # 道具字典
prop_images['life'] = s[0]
prop_images['continue'] = s[1]
prop_images['three'] = s[2]
group_player_shell = pygame.sprite.Group() # 玩家炮弹组
group_npc_shell = pygame.sprite.Group() # NPC炮弹组
group_npc = pygame.sprite.Group() # NPC组
group_explosion = pygame.sprite.Group() # 爆炸效果组
group_prop = pygame.sprite.Group() # 道具组
player = Tank(player_image,shell_image,screen,group_player_shell)
clock = pygame.time.Clock()
npc_produce_EVENT = USEREVENT + 1 # npc自动产生事件
pygame.time.set_timer(npc_produce_EVENT,400) # 每隔400毫秒产生一个npc
prop_produce_EVENT = USEREVENT + 2 # 道具自动产生事件
pygame.time.set_timer(prop_produce_EVENT,10000) # 每秒生成一个,到了屏幕最下面会自动消失
explosion_sound = os.getcwd() + os.sep + "sound" + os.sep + "BOMB2.wav"
explosion_sound = pygame.mixer.Sound(explosion_sound)
"播放背景音乐"
bgmusic = os.getcwd() + os.sep + "sound" + os.sep + "Protozoa.wav"
playmusic(bgmusic)
"准备增加显示封面的函数"
if display_cover(pygame.image.load(cover_image)):
main()
else:
pygame.quit()
如需要下载完整源代码,请
需要浏览更多吗?
成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)
