python兔子和獾_pygame兔子与獾升级版

兔子与獾本是国外12岁小孩用pygame写的游戏,这里我做了一些修改,加强了可玩性和娱乐性

游戏介绍

先介绍以下游戏背景。

最近有一种游戏非常火爆,叫做“养鲲游戏”,其实就是一些也有广告,游戏本身并没有这些鲲的存在。广告效果是这样的,画风还不错,决定用这个素材做一下。

具有灰暗画风的还是作为反派吧,现在需要一个可爱画风又有正义感的正面人物。于是我想到了我所处的城市——无锡,无锡有名的当然是“太湖神鼋啊”,于是英雄也有了。而英雄的素材,一定要经典,让人印象深刻,还不能过于浮夸。于是我就想到了他

请忽略上面的马里奥,其实他们是好朋友。

--------------------以上是游戏背景--------------------

下面介绍以下游戏的玩法。

wasd上下左右,鼠标射击,击杀20个敌人后屏幕上会随机出现双箭的标志,走过去可以升级武器,伤害加倍,判定范围加倍。 每击杀30敌人,屏幕左上角会出现手握雷电的标志,按下f键,会自动杀死两个左右的敌人,技能数量可以积累。前期的怪都会很小,后期的怪会变大,血量也比小怪厚很多,另外增设了一个boss的角色。但是这样的游戏还是太老套,对于玩家来说打赢游戏还是轻而易举的。所以添加了个不确定因素,在地图中随机存放了三个地雷,在移动、捡装备过程中也可能就会gameover。

1.首先我们定义鲲类 放在badguy.py里

import pygame

from pygame.locals import *

from random import randint

class Badguy(pygame.sprite.Sprite): # 继承pygame的Sprite类

def __init__(self, initial_position, filename="resources/images/01.png", speed=1, health=1, scale=1):

pygame.sprite.Sprite.__init__(self)

self.scale = scale

self.image = pygame.image.load(filename)

if self.scale == 2: # 对于图片素材2倍扩展

self.image = pygame.transform.scale2x(pygame.image.load(filename))

if self.scale == 3:

self.image = pygame.transform.scale(pygame.image.load(filename), (3*64, 3*29))

self.rect = self.image.get_rect()

self.rect.topleft = initial_position

self.speed = speed

self.health = health # 生命值

def move(self):  # 让鲲移动

self.rect.left = self.rect.left - self.speed

2.因为捡到武器之后会得到双箭,所以要对武器进行抽象,定义武器类weapon.py

import pygame

class Weapon(pygame.sprite.Sprite):

def __init__(self, filename="resources/images/bullet.png", hit=1, vex=[], channel=1):

pygame.sprite.Sprite.__init__(self)

self.image = pygame.image.load(filename)

self.rect = self.image.get_rect()

self.hit = hit # 伤害值

self.vex = vex # 发射角度[x,y]

self.channel = channel # 默认为单箭,升级后channel=2

3.还要定义个地雷类,还要设定踩到雷之后触发雷的爆炸效果

import pygame

class Mine(pygame.sprite.Sprite):

def __init__(self, initial_position, filename="resources/images/bomb.png"):

pygame.sprite.Sprite.__init__(self)

self.image = pygame.transform.scale2x(pygame.image.load(filename))

self.tempImg = pygame.transform.scale(self.image, (172//5, 34))

self.rect = self.tempImg.get_rect()

self.rect.topleft = initial_position

self.size = self.image.get_size()

self.show_size_x, self.show_size_y = (self.size[0] // 5, self.size[1])

self.frame_no = 0

def show(self):

# 通过帧的切换实现雷的爆炸效果

self.frame_no += 1

self.frame_no %= 5

pygame.time.delay(100)

# screen.blit(self.image, (0, 0), (self.frame_no * self.show_size_x, 0, self.show_size_x, self.show_size_y))

4.最后,game.py用while循环实现游戏的运行。(没有实现界面与逻辑分离也没有多线程处理)

from sys import exit

import pygame

from pygame.locals import *

import math

import random

from badguy import Badguy

from weapon import Weapon

from mine import Mine

# 2

# 初始化pygame,创建了一个窗口

pygame.init()

width, height = 900, 480

screen = pygame.display.set_mode((width, height))

pygame.display.set_caption("太湖神鼋VS巨型腐鲲")

keys = [False, False, False, False]

playerpos = [100, screen.get_rect().centery]

killNum = 0

arrows = []

# 定义一个定时器,使得游戏里可以经过一段时间后就新建一只鲲

badtimer = 90

badtimer1 = 0

# 定义游戏时间

playTime = 600000

#定义武器数量

WeaponGroup = pygame.sprite.Group()

isDoubleArrow = False

# 生成双箭武器

doubleArrow = pygame.image.load("resources/images/bulletDouble.png")

doubleArrowX, doubleArrowY = random.randint(200, width//2), random.randint(20, height-20)

doubleArrowRect = pygame.Rect(doubleArrow.get_rect())

doubleArrowRect.top = doubleArrowY

doubleArrowRect.left = doubleArrowX

rada = 0

popTime = 0 # 定义一次消灭敌人的个数,否则会因为快速循环删除很多敌人

# badguys 记录badguy的位置坐标的列表

badguy1 = Badguy((900, 100)) # 先实例化一个鲲,加入到BadguyGroup中

BadguyGroup = pygame.sprite.Group()

BadguyGroup.add(badguy1)

badNum = 0

Badspeed = 1

BadMidBoss = 5

BadBigBoss = 1

hasKilledBigBoss = False

BossHasReached = False

healthvalue = 194

pygame.mixer.init()

isOutofWindow = False

# 3

# 加载本地图片

player = pygame.image.load("resources/images/turtle.png")

grass = pygame.image.load("resources/images/grass.png")

castle = pygame.image.load("resources/images/castle.png")

arrow = pygame.image.load("resources/images/bullet.png")

# 加载武器图片

radaImg = pygame.image.load("resources/images/rada.png")

# 加载鲲图片

badguyimg1 = pygame.image.load("resources/images/01.png")

badguyimg = badguyimg1

# 加载健康图片

healthbar = pygame.image.load("resources/images/healthbar.png")

health = pygame.image.load("resources/images/health.png")

# 加载输赢图片

gameover = pygame.image.load("resources/images/gameover.png")

youwin = pygame.image.load("resources/images/youwin.png")

# 加载声音

hit = pygame.mixer.Sound("resources/audio/explode.wav")

enemy = pygame.mixer.Sound("resources/audio/enemy.wav")

shoot = pygame.mixer.Sound("resources/audio/shoot.wav")

bomb = pygame.mixer.Sound("resources/audio/bomb.wav")

thunder = pygame.mixer.Sound("resources/audio/thunder.wav")

gain = pygame.mixer.Sound("resources/audio/gain.wav")

warning = pygame.mixer.Sound("resources/audio/warning.wav")

fail = pygame.mixer.Sound("resources/audio/fail.wav")

success = pygame.mixer.Sound("resources/audio/success.wav")

# 调节声音大小

hit.set_volume(0.1)

enemy.set_volume(0.1)

shoot.set_volume(0.03)

bomb.set_volume(0.2)

warning.set_volume(0.2)

thunder.set_volume(0.08)

gain.set_volume(0.2)

success.set_volume(0.4)

fail.set_volume(0.4)

pygame.mixer.music.load('resources/audio/moonlight.wav')

pygame.mixer.music.play(-1, 0.0)

pygame.mixer.music.set_volume(0.15)

# 生成地雷

hasSteppedMine = False

minesPositions = [[random.randint(200, width-20), random.randint(20, height-20)] for i in range(3)]

MineGroup = pygame.sprite.Group()

for mineposition in minesPositions:

mine = Mine(mineposition)

MineGroup.add(mine)

# print(minesPositions)

time = 10

# 4

# 进入循环

running = 1

exitcode = 0

while running:

if popTime > 0:

print(popTime)

badtimer -= 1

badspeed = Badspeed # 重新初始化坏蛋速度

# 5 设置黑色背景

screen.fill(0)

# 6

# 循环画上背景

for x in range(width // grass.get_width() + 1):

for y in range(height // grass.get_height() + 1):

screen.blit(grass, (x * 100, y * 100))

# 画上四个城堡

screen.blit(castle, (0, 30))

screen.blit(castle, (0, 135))

screen.blit(castle, (0, 240))

screen.blit(castle, (0, 345))

# 画上小兔子

# 玩家旋转兔子

position = pygame.mouse.get_pos()

angle = math.atan2(position[1] - (playerpos[1] + 32), position[0] - (playerpos[0] + 26))

playerrot = pygame.transform.rotate(player, 360 - angle * 57.29)

playerpos1 = (playerpos[0] - playerrot.get_rect().width // 2, playerpos[1] - playerrot.get_rect().height // 2)

screen.blit(playerrot, playerpos1)

playerrect = pygame.Rect(player.get_rect())

playerrect.top = playerpos1[1]

playerrect.left = playerpos1[0]

# 双箭武器升级

if killNum >= 20 and not isDoubleArrow:

screen.blit(doubleArrow, (doubleArrowX, doubleArrowY))

if doubleArrowRect.colliderect(playerrect):

gain.play()

isDoubleArrow = True

# 触碰雷区

for mine in MineGroup.sprites():

if mine.rect.colliderect(playerrect):

hasSteppedMine = True

bomb.play()

break

if hasSteppedMine:

while time > 0:

for mine in MineGroup.sprites():

mine.show()

screen.blit(mine.image, mine.rect, (mine.frame_no * mine.show_size_x, 0, mine.show_size_x, mine.show_size_y))

pygame.display.update(mine.rect)

time -= 1

# 画出箭头

for bullet in WeaponGroup.sprites():

index = 0

velx = math.cos(bullet.vex[0]) * 10

vely = math.sin(bullet.vex[0]) * 10

bullet.vex[1] += velx

bullet.vex[2] += vely

if bullet.vex[1] < -64 or bullet.vex[1] > 900 or bullet.vex[2] < -64 or bullet.vex[2] > 480:

WeaponGroup.remove(bullet)

index += 1

for projectile in WeaponGroup.sprites():

arrow1 = pygame.transform.rotate(bullet.image, 360 - projectile.vex[0] * 57.29)

screen.blit(arrow1, (projectile.vex[1], projectile.vex[2]))

# 画上鲲

if badtimer == 0:

if BadBigBoss > 0:

n = random.randint(0, 30)

if n == 2 or n == 3:

badspeed = n

badguy = Badguy([900, random.randint(50, 430)], speed=badspeed)

BadguyGroup.add(badguy)

badNum += 1

if killNum > 80 and BadMidBoss > 0: # 杀死50个敌人 会出现5个中boss

MidBoss = Badguy([900, random.randint(50, 430)], speed=0.8, health=50, scale=2)

BadguyGroup.add(MidBoss)

BadMidBoss -= 1

badNum += 1

if killNum > 120 and BadBigBoss > 0: # 杀死80个敌人 会出现1个大boss

BigBoss = Badguy([900, random.randint(50, 400)], speed=0.5, health=200, scale=3)

BadguyGroup.add(BigBoss)

BadBigBoss -= 1

badNum += 1

warning.play()

# 加载boss血条

bosshealthbar = pygame.transform.scale(healthbar, (400, 30))

bosshealth = pygame.transform.scale(health, (4, 25))

badtimer = 100 - (badtimer1 * 2)

if badtimer1 >= 35:

badtimer1 = 35

else:

badtimer1 += 2

try:

if BigBoss in BadguyGroup.sprites():

screen.blit(bosshealthbar, (200, 60))

for health1 in range(BigBoss.health*2):

screen.blit(bosshealth, (health1 + 198, 62))

except:

pass

index = 0

for badguy in BadguyGroup.sprites():

if badguy.rect.left < -64:

BadguyGroup.remove(badguy)

badguy.move()

# print(badguy.rect.left, badguy.rect.top)

# 鲲冲过来并且在碰到城堡的时候会消失。尽管你看不到,鲲实际上会降低你的健康值。

badrect = pygame.Rect(badguyimg.get_rect())

badrect.top = badguy.rect.top

badrect.left = badguy.rect.left

if badrect.left < 64:

hit.play()

hitvalue = random.randint(1 * int((badguy.speed**2 + 1)), 3 * int((badguy.speed**2+1))) * badguy.health

healthvalue -= hitvalue

print(hitvalue)

BadguyGroup.remove(badguy)

try:

if badguy is BigBoss:

BossHasReached = True

except:

pass

# 检查箭头

index1 = 0

for bullet in WeaponGroup.sprites():

bullrect = pygame.Rect(bullet.image.get_rect())

bullrect.left = bullet.vex[1]

bullrect.top = bullet.vex[2]

# 检测箭头是否与坏蛋相交

if badrect.colliderect(bullrect):

badguy.health -= bullet.hit

if badguy.health <= 0:

enemy.play()

killNum += 1

try:

if badguy == BigBoss:

hasKilledBigBoss = True

break

except:

pass

if killNum > 0 and killNum % 30 == 0: # 杀死20个敌人获得一个雷达武器

rada += 1

popTime += 2

try:

BadguyGroup.remove(badguy)

except:

pass

try:

WeaponGroup.remove(bullet)

except:

pass

index1 += 1

index += 1

screen.blit(badguy.image, badguy.rect)

# 添加时钟用来计时

font = pygame.font.Font('resources/simsun.ttc', 18)

survivedtext = font.render("倒计时:" + str((playTime - pygame.time.get_ticks()) // 60000) + "分" + str((playTime - pygame.time.get_ticks()) // 1000 % 60).zfill(

2), True, (0, 0, 0))

textRect = survivedtext.get_rect()

textRect.topright = [width-30, 5]

screen.blit(survivedtext, textRect)

# 显示已杀死的敌人

font = pygame.font.Font('resources/simsun.ttc', 20)

killedtext = font.render(u"您已击杀" + str(killNum) + u"个敌人" .zfill(

2), True, (0, 0, 0))

textRect = killedtext.get_rect()

textRect.topright = [2*width//3, 5]

screen.blit(killedtext, textRect)

# 添加生命值显示

screen.blit(healthbar, (5, 5))

for health1 in range(healthvalue):

screen.blit(health, (health1 + 8, 8))

if rada > 0:

screen.blit(radaImg, (200, 3))

# 7

# 刷新屏幕

pygame.display.flip()

# 8设置游戏退出条件

for event in pygame.event.get():

if event.type == QUIT:

exit()

# 定义玩家wasd四个按键用来控制方向

if playerpos[0] > width - 10 or playerpos[0] < 10 or playerpos[1] < 10 or playerpos[1] > height-10:

isOutofWindow = True

if event.type == pygame.KEYDOWN and not isOutofWindow:

if event.key == K_w:

keys[0] = True

elif event.key == K_a:

keys[1] = True

elif event.key == K_s:

keys[2] = True

elif event.key == K_d:

keys[3] = True

if keys[0] and playerpos[1] > 10:

playerpos[1] -= 10

elif keys[2] and playerpos[1] < height - 10:

playerpos[1] += 10

elif keys[1] and playerpos[0] > 10:

playerpos[0] -= 10

elif keys[3] and playerpos[0] < width - 10:

playerpos[0] += 10

if event.type == pygame.KEYUP:

if event.key == pygame.K_w:

keys[0] = False

elif event.key == pygame.K_a:

keys[1] = False

elif event.key == pygame.K_s:

keys[2] = False

elif event.key == pygame.K_d:

keys[3] = False

# 雷达武器 一次消灭2个敌人,

if event.type == pygame.KEYDOWN:

if event.key == K_f and rada > 0:

rada -= 1

indx_1 = random.randint(0, len(BadguyGroup.sprites()))

indx_2 = random.randint(0, len(BadguyGroup.sprites()))

if event.type == pygame.KEYUP:

if event.key == K_f and popTime > 0:

try:

thunder.play()

popTime -= 2

BadguyGroup.sprites()[indx_1].health -= 1

BadguyGroup.sprites()[indx_2].health -= 1

if BadguyGroup.sprites()[indx_1].health <= 0:

BadguyGroup.remove(BadguyGroup.sprites()[indx_1])

killNum += 1

if BadguyGroup.sprites()[indx_2].health <= 0:

BadguyGroup.remove(BadguyGroup.sprites()[indx_2])

killNum += 1

except:

pass

# 跟踪箭头

if event.type == pygame.MOUSEBUTTONDOWN:

shoot.play()

position = pygame.mouse.get_pos()

vex = [math.atan2(position[1] - (playerpos1[1] + 32),

position[0] - (playerpos1[0] + 26)),

playerpos1[0] + 32,

playerpos1[1] + 32

]

# 装填武器

if killNum < 20 or not isDoubleArrow:

bullet = Weapon(vex=vex)

elif isDoubleArrow: # 双箭

bullet = Weapon(filename="resources/images/bulletDouble.png", vex=vex, hit=2, channel=2)

WeaponGroup.add(bullet)

# 检查输赢

if pygame.time.get_ticks() >= playTime or killNum >= 200 or hasKilledBigBoss:

running = 0

exitcode = 1

if healthvalue <= 0 or BossHasReached or hasSteppedMine:

running = 0

exitcode = 0

# 输赢显示

if exitcode == 0:

pygame.time.wait(500)

fail.play()

pygame.font.init()

font = pygame.font.Font("resources/simsun.ttc", 36)  #设定中文字体

text = font.render(u"您击杀了: " + str(killNum) + u"敌人", True, (255, 0, 0))

textRect = text.get_rect()

gameover = pygame.transform.scale(gameover, (width, height))

textRect.centerx = screen.get_rect().centerx

textRect.centery = screen.get_rect().centery + 40

screen.blit(gameover, (0, 0))

screen.blit(text, textRect)

else:

pygame.time.wait(500)

success.play()

pygame.font.init()

font = pygame.font.Font('resources/simsun.ttc', 36)

text = font.render(u"您击杀了: " + str(killNum) + u"敌人", True, (0, 255, 0))

textRect = text.get_rect()

youwin = pygame.transform.scale(youwin, (width, height))

textRect.centerx = screen.get_rect().centerx

textRect.centery = screen.get_rect().centery + 50

screen.blit(youwin, (0, 0))

screen.blit(text, textRect)

if hasKilledBigBoss:

text1 = font.render("您已击杀巨型腐鲲! ", True, (0, 255, 0))

textRect1 = text1.get_rect()

textRect1.centerx = screen.get_rect().centerx

textRect1.centery = screen.get_rect().centery + 20

screen.blit(text1, textRect1)

while 1:

for event in pygame.event.get():

if event.type == pygame.QUIT:

pygame.quit()

exit()

pygame.display.flip()闪电侠的右手/兔子和獾​gitee.com

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值