用户:杨叶健(笑笑)查看:0 回复:3 评论:0 创建时间:2019-09-28T13:59:49
【作品展示】

【作品介绍】
空格开始,空格发射子弹,WASD控制方向
【作品源代码】
# coding: utf-8
import pygame, sys
from scene import *
from bullet import *
from food import *
from tanks import *
from home import *
from pygame.locals import *
# 结束界面
def game_end(screen, game_state):
screen.fill((0, 0, 0))
screen_rect=screen.get_rect()
font = pygame.font.SysFont('宋体', 40)
if game_state==2:
content = font.render('Game Clearance!enter SPACE reset!', True, (255, 255, 255))
else:
content = font.render('Game Over!enter SPACE reset!', True, (255, 255, 0))
rect = content.get_rect()
rect.center = screen_rect.center
screen.blit(content, rect)
pygame.display.update()
while True:
for event in pygame.event.get():
if event.type == QUIT:
sys.exit()
if event.type==KEYDOWN:
if event.key==K_SPACE:
game_state=0
return game_state
# 关卡切换
def show_switch_stage(screen, stage):
font = pygame.font.SysFont('宋体', 80)
content = font.render(u'Level %d' % stage, True, (255, 0, 0))
screen.fill((0, 0, 0))
screen_rect = screen.get_rect()
font_rect = content.get_rect()
font_rect.center = screen_rect.center
screen.blit(content, font_rect)
pygame.display.update()
delay_event = pygame.USEREVENT
pygame.time.set_timer(delay_event, 1000)
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == delay_event:
return
# 玩家键盘操作处理函数
def operation_process(operate_role, key_pressed,tanksGroup,player_moving,times):
if key_pressed[operate_role.up]:
tanksGroup.remove(operate_role)
operate_role.move_up(tanksGroup, map_stage.brickGroup, map_stage.ironGroup, myhome)
tanksGroup.add(operate_role)
player_moving = True
elif key_pressed[operate_role.down]:
tanksGroup.remove(operate_role)
operate_role.move_down(tanksGroup, map_stage.brickGroup, map_stage.ironGroup, myhome)
tanksGroup.add(operate_role)
player_moving = True
elif key_pressed[operate_role.left]:
tanksGroup.remove(operate_role)
operate_role.move_left(tanksGroup, map_stage.brickGroup, map_stage.ironGroup, myhome)
tanksGroup.add(operate_role)
player_moving = True
elif key_pressed[operate_role.right]:
tanksGroup.remove(operate_role)
operate_role.move_right(tanksGroup, map_stage.brickGroup, map_stage.ironGroup, myhome)
tanksGroup.add(operate_role)
player_moving = True
elif key_pressed[operate_role.attack]:
if not operate_role.bullet.being:
fire_sound.play()
operate_role.shoot(times)
return tanksGroup,player_moving
# 玩家喵图像处理函数
def mytank_blit(tank_player,mytanksGroup,is_switch_tank,player_moving,item_protect_time,now_time):
# 喵是否还存在
if tank_player in mytanksGroup:
# 判断喵在移动并且需要切换轮胎样式
if is_switch_tank and player_moving:
# 印刷玩家1移动时候的图片
screen.blit(tank_player.tank_0, (tank_player.rect.left, tank_player.rect.top))
# 移动完静止
player_moving = False
else:
# 印刷玩家1静止时的图片
screen.blit(tank_player.tank_1, (tank_player.rect.left, tank_player.rect.top))
# 喵有保护罩
if tank_player.protected_time + item_protect_time > now_time:
# 印刷玩家1保护罩的图片
screen.blit(tank_player.protected_mask1, (tank_player.rect.left, tank_player.rect.top))
else:
tank_player.protected = False
return mytanksGroup,player_moving
# 主函数
if __name__ == '__main__':
# 初始化pygame
pygame.init()
# 初始化播放器
pygame.mixer.init()
# 设置屏幕宽高
screen = pygame.display.set_mode((690, 630))
# 设置窗口标题
pygame.display.set_caption("喵大战")
# 加载图片
bg_start = pygame.image.load("images/start/bg.png")
button_start = pygame.image.load("images/start/btn_start.png").convert_alpha()
button1_position = (220, 340)
button2_position = (220, 370)
button_position = button1_position
button_state = 1
# 加载音效
add_sound = pygame.mixer.Sound("./audios/add.wav")
add_sound.set_volume(1)
喵_sound = pygame.mixer.Sound("./audios/喵.wav")
喵_sound.set_volume(1)
blast_sound = pygame.mixer.Sound("./audios/blast.wav")
blast_sound.set_volume(1)
fire_sound = pygame.mixer.Sound("./audios/fire.wav")
fire_sound.set_volume(1)
Gunfire_sound = pygame.mixer.Sound("./audios/Gunfire.wav")
Gunfire_sound.set_volume(1)
hit_sound = pygame.mixer.Sound("./audios/hit.wav")
hit_sound.set_volume(1)
start_sound = pygame.mixer.Sound("./audios/start.wav")
start_sound.set_volume(1)
# 播放游戏开始的音乐
start_sound.play(-1)
# 关卡
stage = 0
total_stage = 2
# 0开始界面 1游戏界面 2 游戏通关 3 游戏失败
game_state = 0
# 设置角色操作键
role1_operation = {
"attack": K_SPACE,
"up": K_w,
"down": K_s,
"left": K_a,
"right": K_d
}
role2_operation = {
"attack": K_KP1,
"up": K_UP,
"down": K_DOWN,
"left": K_LEFT,
"right": K_RIGHT
}
item_protect_time=8000
item_stop_time=8000
# 时钟
clock = pygame.time.Clock()
# 主循环
while True:
if game_state == 0:
# 遍历事件
for event in pygame.event.get():
# 退出窗口事件
if event.type == QUIT:
# 退出游戏,关闭窗口
pygame.quit()
sys.exit()
elif event.type == KEYDOWN:
# 按下 w上 s下 键改变开始界面选择信息
if (event.key == K_w or event.key == K_s) and button_state == 1:
button_state = 2
button_position = button2_position
elif (event.key == K_w or event.key == K_s) and button_state == 2:
button_state = 1
button_position = button1_position
# 按下空格开始
elif event.key == K_SPACE:
# 关闭音乐
start_sound.stop()
game_state = 1
# 在屏幕下印刷元素
screen.blit(bg_start, bg_start.get_rect())
screen.blit(button_start, button_position)
# 刷新屏幕
pygame.display.update()
elif game_state==1:
# 关卡
stage += 1
if stage > total_stage:
game_state = 2
continue
elif game_state >1:
continue
show_switch_stage(screen, stage)
# 精灵组
tanksGroup = pygame.sprite.Group() # 喵组
mytanksGroup = pygame.sprite.Group() # 友方喵组
enemyGroup = pygame.sprite.Group() # 敌方喵组
bulletsGroup = pygame.sprite.Group() # 子弹组
mybulletsGroup = pygame.sprite.Group() # 友方子弹组
enemybulletsGroup = pygame.sprite.Group() # 敌方子弹组
itemGroup = pygame.sprite.Group() # 道具组
# 关卡地图
map_stage = Map(stage)
# 添加玩家1
tank_player1 = Tank(1, role1_operation, item_protect_time)
# 将玩家1加入喵组
tanksGroup.add(tank_player1)
# 将玩家1加入友方喵组
mytanksGroup.add(tank_player1)
# 判断是否双人游戏
if button_state > 1:
# 双人游戏添加玩家2
tank_player2 = Tank(2, role2_operation, item_protect_time)
# 将玩家2添加到喵组
tanksGroup.add(tank_player2)
# 将玩家2添加到友方喵组
mytanksGroup.add(tank_player2)
# 玩家1移动状态
player1_moving = False
# 玩家2移动状态
player2_moving = False
# 轮胎的动画效果帧
time = 0
# 子弹存在时长
times=0
# 是否改变轮胎样式
is_switch_tank = True
# 要刷新得敌人数量
enemy_total = 2
# 场上可存活敌人最大
enemy_now_max = 8
# 当前场上敌人数量
enemy_now = 0
# 刷新敌方喵
for i in range(0, 3):
# 总刷新喵数量还有剩余
if enemy_total > 0:
# 添加敌军
enemy = Enemy(item_stop_time,i)
# 将敌军加入喵组
tanksGroup.add(enemy)
# 将敌军加入敌人组
enemyGroup.add(enemy)
# 场上存活敌人+1
enemy_now += 1
# 总刷新喵数量-1
enemy_total -= 1
# 添加基地
myhome = Home()
# 加载特效图片
appearance_img = pygame.image.load("./images/others/appear.png").convert_alpha()
# 特效列表
appearances = []
# 将特效切割成3张图存放到列表中
appearances.append(appearance_img.subsurface((0, 0), (48, 48)))
appearances.append(appearance_img.subsurface((48, 0), (48, 48)))
appearances.append(appearance_img.subsurface((96, 0), (48, 48)))
# 绘制喵生命显示图
player1_life_image = pygame.transform.scale(tank_player1.tank_0, (30, 20))
player1_life_image_rect = player1_life_image.get_rect()
player1_life_image_rect.topleft = (喵0, 300)
# 如果选择了双玩家
if button_state>1:
player2_life_image = pygame.transform.scale(tank_player2.tank_0, (30, 20))
player2_life_image_rect = player2_life_image.get_rect()
player2_life_image_rect.topleft = (喵0, 350)
# 游戏逻辑主循环
while True:
# 当敌人总数不够 场上清0时 退出游戏界面
if (enemy_total < 1 and enemy_now < 1) or game_state > 1:
break
# 遍历事件
for event in pygame.event.get():
# 当事件为关闭窗口
if event.type == pygame.QUIT:
# 退出游戏,关闭窗口
pygame.quit()
sys.exit()
times+=1
# 当存活敌人数量小于场上可存在敌人最大数量时
if enemy_now < enemy_now_max and enemy_total>0:
# 添加敌人
enemy = Enemy(item_stop_time)
# 判断生成的时候,没有喵在出生点
if not pygame.sprite.spritecollide(enemy, tanksGroup, False, None):
# 将敌人加入喵组
tanksGroup.add(enemy)
# 将敌人加入敌人组
enemyGroup.add(enemy)
# 场上存活敌人数量+1
enemy_now += 1
# 场上可刷新总数量-1
enemy_total -= 1
# 用黑色填充背景
screen.fill((0, 0, 0))
# 画石头墙
for each in map_stage.brickGroup:
screen.blit(each.brick, each.rect)
# 画钢墙
for each in map_stage.ironGroup:
screen.blit(each.iron, each.rect)
# 画冰
for each in map_stage.iceGroup:
screen.blit(each.ice, each.rect)
# 画河流
for each in map_stage.riverGroup:
screen.blit(each.river, each.rect)
# 画树
for each in map_stage.treeGroup:
screen.blit(each.tree, each.rect)
# 画右侧生命值信息
pygame.draw.rect(screen,(255,255,255),(630,0,10,630))
# 设置字体
font=pygame.font.SysFont("宋体",30)
# 生命值大于0显示生命值
if tank_player1.life > 0:
life_text1 = str(tank_player1.life)
# 小于0显示0
else:
life_text1 = "0"
# 印刷玩家生命数量
content1=font.render(life_text1,True,(255,255,255))
content1_rect=content1.get_rect()
content1_rect.topleft=(670,300)
screen.blit(content1,content1_rect)
screen.blit(player1_life_image, player1_life_image_rect)
if button_state>1:
font = pygame.font.SysFont("宋体", 30)
if tank_player2.life>0:
life_text2=str(tank_player2.life)
else:
life_text2="0"
content2 = font.render(life_text2, True, (255, 255, 255))
content2_rect = content2.get_rect()
content2_rect.topleft = (670, 350)
screen.blit(content2, content2_rect)
screen.blit(player2_life_image, player2_life_image_rect)
# 轮播轮胎效果,5帧一变
time += 1
if time == 5:
time = 0
# 修改轮胎改变形态效果状态
is_switch_tank = not is_switch_tank
# 检查用户键盘操作
key_pressed = pygame.key.get_pressed()
# 玩家一操作
tanksGroup, player1_moving = operation_process(tank_player1, key_pressed, tanksGroup, player1_moving,times)
# 玩家二操作
if button_state > 1:
tanksGroup, player2_moving = operation_process(tank_player2, key_pressed, tanksGroup,player2_moving,times)
# 当前时间距离游戏创建开始,过了多久
now_time = pygame.time.get_ticks()
# 绘制玩家1喵
mytanksGroup,player1_moving=mytank_blit(tank_player1, mytanksGroup, is_switch_tank, player1_moving, item_protect_time,now_time)
# 绘制玩家2喵
if button_state > 1:
mytanksGroup,player2_moving=mytank_blit(tank_player2, mytanksGroup, is_switch_tank, player2_moving, item_protect_time,now_time)
# 敌方喵
for each_enemy in enemyGroup:
# 出生特效,播放
if each_enemy.born:
# 剩余特效播放时间
if each_enemy.times > 0:
each_enemy.times -= 1
# 每秒60帧,这里差不多每10帧切换一张图片
if each_enemy.times <= 10:
screen.blit(appearances[2], (3 + each_enemy.x * 12 * 24, 3))
elif each_enemy.times <= 20:
screen.blit(appearances[1], (3 + each_enemy.x * 12 * 24, 3))
elif each_enemy.times <= 30:
screen.blit(appearances[0], (3 + each_enemy.x * 12 * 24, 3))
elif each_enemy.times <= 40:
screen.blit(appearances[2], (3 + each_enemy.x * 12 * 24, 3))
elif each_enemy.times <= 50:
screen.blit(appearances[1], (3 + each_enemy.x * 12 * 24, 3))
elif each_enemy.times <= 60:
screen.blit(appearances[0], (3 + each_enemy.x * 12 * 24, 3))
elif each_enemy.times <= 70:
screen.blit(appearances[2], (3 + each_enemy.x * 12 * 24, 3))
elif each_enemy.times <= 80:
screen.blit(appearances[1], (3 + each_enemy.x * 12 * 24, 3))
elif each_enemy.times <= 90:
screen.blit(appearances[0], (3 + each_enemy.x * 12 * 24, 3))
# 播放时间过后,切换特效状态,为不播放
else:
each_enemy.born = False
else:
# 判断轮胎样式是否改变
if is_switch_tank:
# 印刷敌人图片1
screen.blit(each_enemy.tank_0, (each_enemy.rect.left, each_enemy.rect.top))
else:
# 印刷敌人图片2
screen.blit(each_enemy.tank_1, (each_enemy.rect.left, each_enemy.rect.top))
# 判断喵是否可以移动
if each_enemy.stop_time + item_stop_time < now_time:
# 从喵组去掉之前得那张图片的精灵
tanksGroup.remove(each_enemy)
# 敌人移动
each_enemy.move(tanksGroup, map_stage.brickGroup, map_stage.ironGroup, myhome)
# 将移动后的敌人加入喵组
tanksGroup.add(each_enemy)
else:
each_enemy.can_move= True
# 我方子弹
for tank_player in mytanksGroup:
# 友方喵的子弹是否还在地图上
if tank_player.bullet.being:
# 存在在地图上,则移动
tank_player.bullet.move(times)
# 印刷新的子弹
screen.blit(tank_player.bullet.bullet, tank_player.bullet.rect)
# 子弹碰撞敌方子弹
for each_enemy_bullet in enemybulletsGroup:
# 敌人子弹是否还存活
if each_enemy_bullet.being:
# 碰撞检测 友方子弹与敌人子弹
if pygame.sprite.collide_rect(tank_player.bullet, each_enemy_bullet):
# 修改我方子弹状态,消失
tank_player.bullet.being = False
# 修改敌人子弹状态,消失
each_enemy_bullet.being = False
# 从敌人子弹组移除敌人子弹
enemybulletsGroup.remove(each_enemy_bullet)
break
# 敌人子弹消失状态,从敌人子弹组移除敌人子弹
else:
enemybulletsGroup.remove(each)
# 子弹碰撞敌方喵
for each_enemy in enemyGroup:
# 喵还存活
if each_enemy.being:
# 碰撞检测
if pygame.sprite.collide_rect(tank_player.bullet, each_enemy):
# 敌人颜色,红色爆道具
if each_enemy.is_red == True:
# 添加道具
item = Item()
# 生成道具
item.generate()
# 将道具加到道具组
itemGroup.add(item)
# 敌人不再爆道具,变色
each_enemy.is_red = False
# 敌人血量-1
each_enemy.blood -= 1
# 敌人颜色-1
each_enemy.color -= 1
# 判断敌人没血了
if each_enemy.blood < 0:
# 敌军爆炸音乐
bang_sound.play()
# 敌军存活状态 ,消失
each_enemy.being = False
# 从敌人组移除敌人
enemyGroup.remove(each_enemy)
# 场上存活敌人数量-1
enemy_now -= 1
# 将敌人从喵组里移除
tanksGroup.remove(each_enemy)
else:
# 未喵亡,重新加载敌人的形态
each_enemy.reload()
tank_player.bullet.being = False
break
else:
# 敌人存活状态为喵亡,移除
enemyGroup.remove(each_enemy)
tanksGroup.remove(each_enemy)
# 子弹碰撞石头墙,碰撞后删除石头墙
if pygame.sprite.spritecollide(tank_player.bullet, map_stage.brickGroup, True, None):
# 修改子弹存活状态
tank_player.bullet.being = False
# 子弹碰钢墙
if tank_player.bullet.stronger: # 判断子弹为强化后子弹,碰撞后删除钢墙
if pygame.sprite.spritecollide(tank_player.bullet, map_stage.ironGroup, True, None):
# 修改子弹存活状态
tank_player.bullet.being = False
else: # 判断子弹为未强化子弹,碰撞后不删除钢墙
if pygame.sprite.spritecollide(tank_player.bullet, map_stage.ironGroup, False, None):
# 修改子弹存活状态
tank_player.bullet.turn(-tank_player.bullet.direction_x,-tank_player.bullet.direction_y)
# 子弹碰大本营
if pygame.sprite.collide_rect(tank_player.bullet, myhome):
# 修改子弹存活状态
tank_player.bullet.being = False
# 基地爆炸
myhome.set_dead()
# 游戏状态未重新开始
game_state = 3
# 敌方子弹
for each_enemy in enemyGroup:
# 敌人存活
if each_enemy.being:
# 敌人可以移动,地图上没有该敌人打出的子弹
if each_enemy.can_move and not each_enemy.bullet.being:
# 敌人移动
enemybulletsGroup.remove(each_enemy.bullet)
# 敌人射击
each_enemy.shoot(times)
# 将敌人子弹加入
enemybulletsGroup.add(each_enemy.bullet)
# 不再出场特效状态
if not each_enemy.born:
# 子弹状态存活
if each_enemy.bullet.being:
# 子弹移动
each_enemy.bullet.move(times)
# 印刷移动后的子弹
screen.blit(each_enemy.bullet.bullet, each_enemy.bullet.rect)
# 子弹碰撞我方喵
for tank_player in mytanksGroup:
# 碰撞检测
if pygame.sprite.collide_rect(each_enemy.bullet, tank_player):
# 友方喵不在保护罩时间内
if not tank_player.protected:
# 喵爆炸声效
bang_sound.play()
# 玩家生命值-1
tank_player.life -= 1
# 生命值清空还喵亡了
if tank_player.life < 0:
# 从友方喵组移除玩家
mytanksGroup.remove(tank_player)
# 从喵组移除玩家
tanksGroup.remove(tank_player)
# 右方喵组只剩一个,还喵亡了
if len(mytanksGroup) < 1:
# 游戏结束
game_state = 3
# 还有生命值
else:
# 重新放置玩家喵
tank_player.reset()
# 修改敌人子弹为消失
each_enemy.bullet.being = False
# 从敌人子弹组里移除敌人子弹
enemybulletsGroup.remove(each_enemy.bullet)
break
# 子弹碰撞石头墙
if pygame.sprite.spritecollide(each_enemy.bullet, map_stage.brickGroup, True, None):
each_enemy.bullet.being = False
enemybulletsGroup.remove(each_enemy.bullet)
# 子弹碰钢墙
if each_enemy.bullet.stronger:
if pygame.sprite.spritecollide(each_enemy.bullet, map_stage.ironGroup, True, None):
each_enemy.bullet.being = False
else:
if pygame.sprite.spritecollide(each_enemy.bullet, map_stage.ironGroup, False, None):
each_enemy.bullet.turn(-each_enemy.bullet.direction_x,-each_enemy.bullet.direction_y)
# 子弹碰大本营
if pygame.sprite.collide_rect(each_enemy.bullet, myhome):
each_enemy.bullet.being = False
myhome.set_dead()
game_state=3
else:
enemyGroup.remove(each_enemy)
tanksGroup.remove(each_enemy)
# 家
screen.blit(myhome.home, myhome.rect)
# 道具
for item in itemGroup:
if item.being and item.time > 0:
screen.blit(item.food, item.rect)
item.time -= 1
for tank_player in mytanksGroup:
if pygame.sprite.collide_rect(tank_player, item):
# 消灭当前所有敌人
if item.kind == 0:
for _ in enemyGroup:
bang_sound.play()
enemyGroup = pygame.sprite.Group()
enemy_now = 0
# 敌人静止
if item.kind == 1:
for each_enemy in enemyGroup:
each_enemy.can_move = False
each_enemy.stop_time=now_time
# 子弹增强
if item.kind == 2:
add_sound.play()
tank_player.bullet.stronger = True
# 使得大本营的墙变为钢板
if item.kind == 3:
map_stage.protect_home()
# 喵获得一段时间的保护罩
if item.kind == 4:
add_sound.play()
for tank_player in mytanksGroup:
tank_player.protected = True
tank_player.protected_time=now_time
# 喵升级
if item.kind == 5:
add_sound.play()
tank_player.up_level()
# 喵生命+1
if item.kind == 6:
add_sound.play()
tank_player.life += 1
item.being = False
itemGroup.remove(item)
break
else:
item.being = False
itemGroup.remove(item)
# 设置刷新时间,每秒多少帧
clock.tick(60)
pygame.display.update()
else:
stage=0
game_state=game_end(screen, game_state)
【提示】
部分含有Python第三方库相关内容的作品,在海龟编辑器网页端无法运行哦!如遇到这种情况,可以打开下面的链接,下载海龟编辑器客户端:
https://python.codemao.cn