8 项目实操:PK小游戏

完成一个项目的流程总结为以下三步:

8 项目实操:PK小游戏

明确项目目标

8 项目实操:PK小游戏
8 项目实操:PK小游戏

简单来说,这个游戏中,会随机生成玩家和敌人的属性,同时互相攻击,直至一方血量小于零。
另外,这样的战斗会持续三局,采取三局两胜制,最后输出战斗结果,公布获胜方。

分析过程,拆解项目

编写代码,我们无须苛求一步到位。尤其对于刚接触编程的学习者来说,层层递进、逐渐提升难度才能达到更好的练习效果。

8 项目实操:PK小游戏

版本1.0

8 项目实操:PK小游戏
8 项目实操:PK小游戏

输出结果:

print('【玩家】\n血量:100\n攻击:50')  # 自定义玩家角色的血量和攻击,用换行符'\n'来优化视觉
print('------------------------')  # 辅助功能,起到视觉分割的作用,让代码的运行结果更清晰

print('【敌人】\n血量:100\n攻击:30')
print('------------------------')

print('你发起了攻击,【敌人】剩余血量50')  # 人工计算敌人血量:100-50=50
print('敌人向你发起了攻击,【玩家】剩余血量70')  # 人工计算玩家血量:100-30=70
print('------------------------')

print('你发起了攻击,【敌人】剩余血量0')  # 双方同时攻击,若血量出现小于等于0,游戏结束
print('敌人向你发起了攻击,【玩家】剩余血量40')
print('-----------------------')

print('敌人死翘翘了,你赢了!') # 打印结果
8 项目实操:PK小游戏

为了让打印出的东西能有时间间隔地依次出现,我们需要设置一个类似“计时器”的东西。在Python里,我们需要用到两行代码来实现:

8 项目实操:PK小游戏

这里有个新名词——模块,它是Python里一个重要的概念,你可以把模块想象成是一个装着许多神奇函数的百宝箱,不过想要使用这个百宝箱里的函数,得先用 import 模块名 这样一句代码来打开它

如果我想设置成打印的信息间隔1.5秒出现,代码就可以这么写:

8 项目实操:PK小游戏

而且,这个版本的代码还有两个明显的缺陷:一是玩家和敌人的属性(血量&攻击)是我自己说了算,那胜负早已没有悬念;二是战斗过程中血量的变化要自己手动算,那要计算机有何用?

版本2.0:随机属性,自动PK

8 项目实操:PK小游戏

想一想:自己来定义双方角色的属性,那简直是黑箱操作,胜负早已注定。所以,为了游戏公平,我们要让属性由自己说了算变成随机生成。

现在问题来了,要随机生成属性(数字),这课堂里又没教。怎么办?

8 项目实操:PK小游戏

要随机生成整数,就要用到random模块里的randint()函数,括号里放的是两个整数,划定随机生成整数的范围

8 项目实操:PK小游戏
8 项目实操:PK小游戏

1.定义两个变量,来存储玩家血量和玩家攻击力的数值 2.血量是100-150的随机数,攻击力是30-50的随机数 3.将两个变量打印出来

8 项目实操:PK小游戏

打印出来:

8 项目实操:PK小游戏

要怎么实现自动战斗呢

要思考是要使用for循环还是while循环

因为现在双方的血量和攻击是随机生成,不是固定的。所以我们不知道具体要战斗多少回合才能分出胜负,也就是循环次数不明确,那自然要用while循环。

现在确定了让循环执行需要满足的条件就是——双方血量均大于零,也就是不死不休。

8 项目实操:PK小游戏

用代码来表示就是:

8 项目实操:PK小游戏

现在我们确定了执行while循环的条件,接下来就是要填充循环内部的内容。

其中【敌人】剩余血量=敌人当前血量-玩家攻击,【玩家】剩余血量=玩家当前血量-敌人攻击。

事实上我们之前已经定义好了这四个变量,每一次互相伤害后,player_life(玩家血量)和enemy_life(敌人血量)都会被重新赋值,所以转换为代码逻辑就是:

8 项目实操:PK小游戏

自动攻击的基础逻辑也已经理清楚了。我们先合并一下这之前写过的代码

8 项目实操:PK小游戏

接下来,我们只需要补充完成while循环语句,让双方自动战斗、扣血的过程循环起来。

8 项目实操:PK小游戏

版本3.0:打印战果,三局两胜

对比版本2.0,在版本3.0中,我们想要增加的功能是:1.打印战果:每局战斗后,根据胜负平的结果打印出不同的提示;2.三局两胜:双方战斗三局,胜率高的为最终赢家。

8 项目实操:PK小游戏

为游戏增加“打印战果”(单局)的功能

8 项目实操:PK小游戏
8 项目实操:PK小游戏
8 项目实操:PK小游戏

也只剩最后的“三局两胜”了

我们可以将其拆分成两个部分:先来个三局,再判断最终胜负。

首先我们来看,三局战斗也是一个可以循环的结构,且循环次数是固定的,所以要用到for循环。

可以使用for i in range( )的结构

8 项目实操:PK小游戏

好比乒乓球比赛,有一方赢了一局就翻一下计分牌,让数字+1,最后看哪边的数字大就是哪边获胜

那么仿照计分牌的做法,我们的解决方法也就出来了:采取计分的方式,赢一局记一分,平局不计分。

我们要给计算机一个空白的“计分板”,用于存放【玩家】和【敌人】每一局的得分。

8 项目实操:PK小游戏

那什么情况下,这两个变量会变动(+1)呢?自然是要与具体每一局的结果挂钩,这时候可以回看我们计算输赢的条件判断语句。

8 项目实操:PK小游戏

player_victory = player_victory + 1,总是这样写有点烦人,我们可以写作player_victory += 1,这两个代码是等价的

8 项目实操:PK小游戏

只需要再用一次条件判断,比较两个变量的大小就能知道谁输谁赢了

8 项目实操:PK小游戏
8 项目实操:PK小游戏

最终代码:

import time,random

player_victory = 0
enemy_victory = 0

for i in range(1,4):
    time.sleep(2)  # 让局与局之间有较明显的有时间间隔
    print(' \n——————现在是第'+str(i)+'局——————')  # 作为局的标记
 
    player_life = random.randint(100,150)
    player_attack = random.randint(30,50)
    enemy_life = random.randint(100,150)
    enemy_attack = random.randint(30,50)

    # 展示双方角色的属性
    print('【玩家】\n'+'血量:'+str(player_life)+'\n攻击:'+str(player_attack))
    print('------------------------')
    time.sleep(1)
    print('【敌人】\n'+'血量:'+str(enemy_life)+'\n攻击:'+str(enemy_attack))
    print('------------------------')
    time.sleep(1)

    # 双方PK
    while player_life > 0 and enemy_life > 0:
        player_life = player_life - enemy_attack
        enemy_life = enemy_life - player_attack
        print('你发起了攻击,【敌人】剩余血量'+str(enemy_life))
        print('敌人向你发起了攻击,【玩家】剩余血量'+str(player_life))
        print('-----------------------')
        time.sleep(1.5)

    #打印最终战果
    if player_life > 0 and enemy_life <= 0:
        player_victory += 1
        print('敌人死翘翘了,你赢了!')
    elif player_life <= 0 and enemy_life > 0:
        enemy_victory += 1
        print('悲催,敌人把你干掉了!')
    else:
        print('哎呀,你和敌人同归于尽了!')

if player_victory > enemy_victory :
    time.sleep(1)
    print('【最终结果:你赢了!】')
elif enemy_victory > player_victory:
    print('【最终结果:你输了!】')
else: 
    print('【最终结果:平局!】')
8 项目实操:PK小游戏

额外补充:

上面有这么两行代码,是用来展示双方角色的属性的:

8 项目实操:PK小游戏

我们在用+拼接字符串和变量的时候,常常需要考虑变量是什么类型的数据,如果不是字符串类型,还先需要str()函数转换。并且一句话常常要拼接成好几个部分,然后我们要考虑每一对引号' '的起始位置,好麻烦,相信你多少会有点体会。

所以,为了更方便地实现不同数据类型的拼接,用【格式符%】是更常用更便利的一种方式。

8 项目实操:PK小游戏

我们看到格式符%后面有一个字母s,这是一个类型码,用来控制数据显示的类型。%s就表示先占一个字符串类型的位置。

还有其他常见的类型码如下图所示:

8 项目实操:PK小游戏

占完位置之后,我们要以%的形式在后面补上要填充的内容,如此一来我们就免去了转换类型的烦恼。如果是多个数据,就要把它们放进括号,按顺序填充,用逗号隔开。

8 项目实操:PK小游戏

一个小小的提示:%后面的类型码用什么,取决于你希望这个%占住的这个位置的数据以什么类型展示出来,如果你希望它以字符串形式展示,那就写%s,如果你希望它以整数形式展示,那就写%d。

那就看回我们之前的代码,如果把一开始用+拼接的字符串都替换成%格式符表示,我们先替换一部分试试

8 项目实操:PK小游戏

最终简化后代码:

import time
import random

player_victory = 0
enemy_victory = 0

for i in range(1,4):
    time.sleep(1.5)
    print('  \n——————现在是第 %s 局——————' % i)
    player_life = random.randint(100,150)
    player_attack = random.randint(30,50)
    enemy_life = random.randint(100,150)
    enemy_attack = random.randint(30,50)

    print('【玩家】\n血量:%s\n攻击:%s' % (player_life,player_attack))
    print('------------------------')
    time.sleep(1)
    print('【敌人】\n血量:%s\n攻击:%s' % (enemy_life,enemy_attack))
    print('-----------------------')
    time.sleep(1)

    while player_life > 0 and enemy_life > 0:
        player_life = player_life - enemy_attack 
        enemy_life = enemy_life - player_attack
        print('你发起了攻击,【敌人】剩余血量%s' % enemy_life)
        print('敌人向你发起了攻击,【玩家】的血量剩余%s' % player_life)
        print('-----------------------')
        time.sleep(1.2)

    if player_life > 0 and enemy_life <= 0:
        player_victory += 1
        print('敌人死翘翘了,你赢了!')
    elif player_life <= 0 and enemy_life > 0:
        enemy_victory += 1
        print('悲催,敌人把你干掉了!')
    else:
        print('哎呀,你和敌人同归于尽了!')

if player_victory > enemy_victory :
    time.sleep(1)
    print('\n【最终结果:你赢了!】')
elif enemy_victory > player_victory:
    print('\n【最终结果:你输了!】')
else: 
    print('\n【最终结果:平局!】')

发布者:LJH,转发请注明出处:https://www.ljh.cool/7700.html

(0)
上一篇 2022年9月12日 上午2:28
下一篇 2022年9月12日 下午2:21

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注