策划如何用vba调试游戏

发表于2016-01-30
评论6 3.7k浏览

前段时间公司准备制作一款以植物大战僵尸为题材,类似捕鱼的射击游戏,之前没有接手过类似项目,所以发表了一篇《捕鱼类游戏计算方式的设计思路》(http://www.gameres.com/463918.html 的文章来验证思路。

 

策划如何用VBA调试游戏数值

游戏截图


 

  根据这个思路,我准备EXCEL自带的VBA做一个数值模拟来调整数值。

 

  本人是初学VBA,草草地看了几页书之后就开始动手撰写代码了,做完之后发现还行,所以就发出来,希望能给大家带来一些帮助。

 

  我们策划不是专业程序员,也不会什么精妙的算法。但我们确实可以借助代码来帮助我们解决某些问题。

 

  1创建按钮

  首先,我们打开EXCEL,新建一个页面,选择开发工具”-“插入”-“按钮,随便在屏幕上画一个按钮,画完之后,会弹出制定宏

策划如何用VBA调试游戏数值

按钮建议放在G列之后

 

策划如何用VBA调试游戏数值

点击“新建”,即可打开代码窗口


 

  PS:可以右键点击按钮,选择“编辑文字”设定按钮的显示文字,或者右键选中,左键拖动按钮的位置和调整大小。

 

  2、打开代码窗口


  按钮创建好之后,也可以点击“开发工具”内的Visual Basic按钮打开代码窗口:

 

策划如何用VBA调试游戏数值

点击右上角的VisualBasic按钮打开代码界面


 

  代码窗口打开后,你会发现只有两句代码,今后的代码之后写在这两句中间,点击之前创建的按钮,就可以执行写的代码了。


 

策划如何用VBA调试游戏数值


  3、设置变量和常量
 

 

  首先我们以最基本的,豌豆射击普通僵尸的概率为例,豌豆攻击力是1,普通僵尸的生命值是10,则根据计算公式算出一颗豌豆杀死一只普通僵尸的概率为10%,也就是0.1

 

  我们以0.1的击杀概率,进行多次模拟,看看实际情况下,金币支出、金币收入数值的变化。


 

  那么,我们可以先定义金币支出、金币收入的变量:

 

SumExp= 1

SumInc= 0

 

策划如何用VBA调试游戏数值

 

 

  定义一个变量的方法很简单:

变量名 = 变量值

 

  后面绿色的字是注释,起说明作用,不写也可以。(单引号+ 注释内容)


 

  当然了,还有别的高大上定义变量的方法,例如:

 

Dim SumExpas string

 

  代码的意思是:

Dim 变量名 as 变量类型

 

  这种方法可以不用先写好变量值,可以定义好变量类型,本文不涉及这些,有兴趣的小伙伴可以自行度娘研究哈。


 

  我们定义好了两个变量SumExp(总金币支出)、SumInc(总金币收入),和他们的初始值10。但为什么总支出是1,而总收入0呢,因为后面的代码中,如果SumExp0的话,会发生除0错误,所以就从1开始。而且,大家可以这么想,我们模拟的情况是从打出第一炮之后开始的,此时金币已经扣1了,支出当然从1开始啦。


 

  有了这两个变量基本就够用了,但是还是建议再设置一个常量:击杀率。

 

Per= 0.1


 

  为什么要设置击杀率呢,原因就是方便修改,因为本来我们就是为了调试概率写的这个代码,这个击杀率应该会频繁地修改,后期代码复杂了,很多地方都需要引用击杀率,到时候一个个修改起来那感觉可是相当地酸爽,而且特别容易遗漏。

 

策划如何用VBA调试游戏数值


  4、设置自动循环
 

 

  设定好变量后,就正式撰写代码,设置自动循环,让VBA帮忙“掷骰子”了。

 

  让VBA自动干活,大家需要这段代码:

 

  For i =1 To 1000

  Next

策划如何用VBA调试游戏数值


 

  其中,这个i是啥玩意,大家先不用去管它,就当它是计数器,关键看后面的数值1000,表示让代码循环运行1000次,具体运行什么代码,写在这两句代码中间就可以了。


 

  这个数值1000可以改成任何你需要模拟的次数数值。数值太小,样本不够看不出趋势,数值太大,VBA可是会累“死”的哦,一般来说100050000就差不多了。

 

  5、VBA掷骰

 

  要让VBA掷骰子,需要在循环代码中加入这段代码:

 

1.        IfRnd < Per Then

2.         SumInc = SumInc + 1

3.        Else

4.        End If

复制代码


 

策划如何用VBA调试游戏数值


 

  这段代码的意思是:

 

   If  这个判断 Then

  对了运行我

   Else

   错了运行我

End If


 

  “这个判断”中的内容是:

Rnd< Per

 

  Per大家很熟,就是之前设定的变量击杀率,为0.1

 

  RndVBA内置的一个函数,效果是产生一个01之间的一个随机数(可度娘)


 

  如果Rnd产生出来小于0.1,那说明是击杀了,则Rnd < Per这句话是对的,所以应该运行“对了”那一块代码。

 

  如果Rnd产生出来大于或等于0.1,那说明是没击杀,则运行“错了”那一块的代码。


 

 

  这个判断,击杀了僵尸掉落金币,所以“对了”那一段代码就要把金币给加上去:

 

SumInc= SumInc + 1

 

  没有击杀僵尸什么事情也没有发生,所以“错了”这段代码为空,后面会用到。


  6、完成一个循环


 

  不管有没有击杀,每次豌豆打出去,总支出肯定是要加上去的,注意要加在掷骰代码外、循环代码内:

 

SumExp= SumExp + 1


 

策划如何用VBA调试游戏数值


 

  这个时候,一个完整的循环已经完成,VBA按照我们的医院,以0.1的几率,进行1000次判断。

每次判断都相当于豌豆进行一次攻击,判断中了,则将收入+1,如果不中,则不加。每次判断结束,不管中没中,支出一定要+1


 

  这个时候其实可以返回EXCEL界面,点击按钮让VBA运行了。但是点击后,EXCEL表格没有任何反应。实际上代码已经是运行了,但是没有把相关的数据打印出来,我们看不到而已。


7打印数据

 

由于每次循环,都产生了一次新的数值,需要每次都记录,所以需要在循环内,加入这两行代码:

1.      Sheet1.Cells(i,1).Value = SumExp

2.      Sheet1.Cells(i,2).Value = SumInc

复制代码



 

策划如何用VBA调试游戏数值


 

加入代码后,点击按钮运行。哇,发现EXCEL表格内有数值了:

 

策划如何用VBA调试游戏数值


 

那么,这两句代码的是什么意思呢?

 

Sheet1.Cells(i, 1).Value = SumExp

 

工作簿名字 . Cells函数(单元格坐标XY. 单元格值= 输入的值


 

单元格坐标Y,对应的就是EXCEL表的横坐标,1对应的就是A2就是B3就是C,以此类推。

 

单元格坐标X,大家看到了在第4章出现的i,在我们之前的循环体内,i表示的是计数器,从11000,当前循环到了哪一个,刚好可以作为单元格坐标的X

 

随着循环的推进,i不停地推进,也就依次将值写入单元格,相当方便。最终,循环进行了多少次,单元格也就被写了多少行,不信大家看:

 

策划如何用VBA调试游戏数值


  8打印数据的优化

 

大家发现,如果豌豆击杀了普通僵尸,掉落的可是10金币啊,怎么每次收入是+1呢。还有最好可以看一下收入减支出,看一下收益情况如何。


 

这时候我们就要对代码进行一下调整:

 

1 增加变量Gold

 

Gold = 10

 

2 调整打印的数值:

 

1.      Sheet1.Cells(i,1).Value = SumExp

2.      Sheet1.Cells(i,2).Value = SumInc * Gold

3.      Sheet1.Cells(i,3).Value = SumInc * Gold – SumExp

复制代码


 

策划如何用VBA调试游戏数值


 

  为什么要设置常量Gold呢,原因和Per一样——方便调试,因为僵尸掉落的金币数是我们需要频繁修改的,所以最好是设置成一个常量,方便每次更改,避免遗漏出错。


 

  新增的第3行代码和前面的基本一致,单元格坐标的Y表示在C列打印,方便查看。


 

策划如何用VBA调试游戏数值

点击运行后就是密密麻麻的数据了

 

 

  9折线图查看数据

 

  既然数据出来了,我们就可以使用EXCEL自带的折线图查看数据,对数据变化有一个宏观的了解。

 

策划如何用VBA调试游戏数值

直接选中AB两列所有单元格的数据(记得要点选AB,不能只选中单元格)


 

  选中数据后,选择功能标签插入,图表功能栏内选择二维折线图,选择第一种折线图。

 

策划如何用VBA调试游戏数值


 

策划如何用VBA调试游戏数值

平稳的蓝色折线表示支出

波动的红色折线表示收入

蓝色折线在上表示亏钱

红色折线在上表示赚钱


 

  另外,我们还可以插入一个单独的表格,查看纯收益情况。我们单独选中C列,插入折线图,得到:

 

策划如何用VBA调试游戏数值


 

  折线图创建好之后,就可以点击按钮查看效果了,可以多次点击,折线图会动态更新。


 

  我们使用的模型是:一次豌豆1金币,击杀一只普通僵尸掉落10金币,击杀率为10%(也就是0.1)。理论上的效果是10*0.1=1,相当于不赚也不亏,达到了收支平衡。


 

  但是,实际情况下,虽然收支能大致保持平衡,但收入折线的波动非常厉害,而且经常出现“一边倒”的情况。所以,根据之前我写的《捕鱼类游戏计算方式的设计思路》,我们可以加入调整击杀概率的方式。


  10查看击杀情况
 

  在击杀数据中,我们还想看一下,大概每隔多少次,豌豆可以击杀一次僵尸。

 

  所以我们在判断中,加入下面两条代码,当击杀发生时,记下1,没有击杀,记下0

 

1.      Sheet1.Cells(i, 4).Value = 1

2.      Sheet1.Cells(i, 4).Value = 0

复制代码


 

策划如何用VBA调试游戏数值


 

  点击按钮运行,在D列里面,列出了击杀的情况:

 

策划如何用VBA调试游戏数值


 

  但是,光是一串01,也是容易看眼花的,所以我们要使用条件格式,将1(击杀)的情况标记出来。


 

  选中D列整行,点击功能标签“开始”-“样式”-“条件格式”-“突出显示单元格规则”-“等于”,填入值为1,设置为“浅红填充色深红色文本”(也可以选中别的喜欢的颜色)。

 

策划如何用VBA调试游戏数值


 

  设置好之后,1这个数值被高亮了,就可以很明显地在数据表中看到击中的情况了。

策划如何用VBA调试游戏数值



  11引入悲情值
 

  豌豆攻击普通僵尸,以 0.1的概率,理论数值10次就可以击杀一次,但实际情况可能20次甚至30次都不会中一次,会给玩家带来很大的挫败感。

 

  所以我们要引入一个叫做悲情值的概念,降低击杀与被击杀间隔时间的离散程度,降低玩家由于连续未击中后的挫败感。


 

  悲情值的运作方式为:

 

  1 初始化悲情值=0

  2 当玩家攻击一次,未获得任何收益,则悲情值+1

  当玩家攻击一次,获得任何收益,则悲情值重置为0

  3 当悲情值到达某个值时,玩家下一次攻击的击杀率+100%(必定命中)


 

  在代码中,我们加入悲情值常量:

M =10

策划如何用VBA调试游戏数值


 

  在循环体中,加入相应的代码使其运作:

 

1.      For i = 1 To 1000 '模拟次数

2.         If Rnd < Per Then  '子弹击杀了怪物

3.         SumInc = SumInc + 1 '收入加起来

4.         Sheet1.Cells(i, 4).Value = 1

5.          N= M '重置悲情值

6.         Else  '子弹未击杀怪物

7.         Sheet1.Cells(i, 4).Value = 0

8.          N= N - 1

9.             If N <= 0 Then

10.         SumInc = SumInc + 1

11.         N = M '重置悲情值

12.         End If

13.  End If

复制代码


 

策划如何用VBA调试游戏数值

 

  PS:这里注意了,其实变量N才是悲情值,循环体中将M的值赋给N,让N代为执行悲情值的功能,因为N是循环体内的局部变量,所以不需要特别声明就可以用。(或者说将M的值赋给N的时候就已经声明了)


 

  循环体中新增的一个判断

 

1.             If N <= 0 Then

2.             SumInc = SumInc + 1

3.             N = M '重置悲情值

4.             End If

复制代码


 

  是用来执行悲情值的功能的,通过每次不命中减少N,当N减到0的时候,触发一定命中。无论是随机获得的命中,或者是悲情获得的命中,都需要再次重置悲情值。


 

  我们还可以加入一条代码,将悲情值的变化情况打印出来:

 

Sheet1.Cells(i,5).Value = N

 

策划如何用VBA调试游戏数值


 

  这样,在EXCEL表格界面E列,就可以看到悲情值的变化情况了。

 

  同样,我们根据第10章学的方式,将E列加一个条件格式,设置0为高亮(0表示此次触发了一定命中),这样我们就可以很容易地看到哪些是概率命中的,哪些是悲情命中的。

 

策划如何用VBA调试游戏数值

 

策划如何用VBA调试游戏数值

 


 

  但是,引入悲情值后发现,玩家的收益率直线上升。经过多次模拟,收入线基本没有低于过支出线,这和我们所要求的“收支平衡”相违背。

 

策划如何用VBA调试游戏数值

 


 

  要解决这个问题,有两种方法:

 

  1提高悲情值,原先设定的值是10,设为1520,收入线明显下降。但是过高调整悲情值,就违背我们设置这个值的初衷,导致它非常鸡肋。

 

  2动态调整击杀率,将“高走”趋势拉低,“低开”趋势拔高,达到一种动态的平衡。


  12动态调整击杀率
 

  要动态调整击杀率,首先我们要新增一个变量ap,加在Per上,来增加或减少击杀的几率。

 

策划如何用VBA调试游戏数值

 

  默认ap0,初始不调整击杀几率


 

  将ap加入到概率运算当中,使其生效:

 

策划如何用VBA调试游戏数值


 

  在循环体中加入代码,使其能“动态调整,收益高降概率,收益低提概率:

 

1.      Select Case(SumInc * Gold - SumExp) / SumExp

2.                 Case Is <= 0

3.                                      ap = ap + 0.01

4.                 Case Is > 0

5.                                      ap = ap - 0.01

6.      End Select

7.      Sheet1.Cells(i,6).Value = ap + Per

复制代码


 

策划如何用VBA调试游戏数值


 

  Select Case是比If判断更好用的一种判断方式,可以判断多个值,执行多行代码

 

1.      Select Case 需要检查的值

2.                 Case Is 1

3.                                      执行1代码

4.                 Case Is 2

5.                                      执行2代码

6.                 Case Is 3

7.                                      执行2代码

8.      ......

9.      End Select

复制代码


 

  如果大家希望对Select Case想更多的了解,可以度娘更深入学习。


 

  加入了ap后,收入线变得“老实”了,跑高了自动会拉下来,落低了自动会拉上去,纯收益值像是股票走势一样“上上下下”了,但总的趋势还是位置在0上。

 

策划如何用VBA调试游戏数值


 

  另外,代码中也将调整后的概率打印在了表格内的F列内,可以将F列导出折线图,查看概率的变化情况:

 

策划如何用VBA调试游戏数值


 

  不过,我只是提供了一种思路,毕竟游戏是需要有一些趣味性的。玩家打了好半天,还是那些金币,不多也不少,是很容易乏味的。这就需要小伙伴们开脑洞了,充分利用Select Case可以设置多个条件的优势,比如:在游戏初期先调高概率,让玩家获利颇多,然后拉紧钱袋降低概率,刺激玩家充值等等。挖坑这种事应该是大家都喜闻乐见了的吧。


  13 动态调整上下限
 

  在多次模拟后发现,动态调整值ap也会“失控”,一味地走高或走低,而且会变成负数。

 

  所以我们还需要加入apUpapDown变量值,来限制ap所能达到的最高几率和最低几率,让ap在正常的范围内上下波动:

 

apUp= 0.05

apDown= -0.05

策划如何用VBA调试游戏数值

 

  apUpapDown上下限制,建议幅度不要太大。也可以设定为只有上限无下限或无上限有下限,根据自己的需求制定。


 

  将apUpapDown加入代码,参与对ap的调整:

 

1.             Select Case ap

2.                 Case Is >= apUp

3.                                      ap = apUp

4.                 Case Is < apDown

5.                                      ap = apDown

6.             End Select

复制代码


 

策划如何用VBA调试游戏数值

 

  这段代码的意思就是:当ap高过上限时,将其设置为上限值,当ap低于下限时,将其设置为下限值。


 

  导入了上下限的代码之后,概率值的折线变化为:

 

策划如何用VBA调试游戏数值

 


 

  是不是规矩多了?而且纯收入的波动变得频繁且平稳,收入线和支出线如胶似漆地黏着,已经达到了理论上的数值平衡了。

 

策划如何用VBA调试游戏数值

 

  而且我将悲情值设置为15,也对曲线的影响也很小。每打15炮不击杀下次一定击杀,这种感觉还是可以的。

 

  14动态调整步长
 

  我们对概率的动态调整,是每一个循环都进行的,相当于每发射一次,概率就会变化一次。由于性能,或是玩家体验的考虑,我们会希望这个调整不是这么的频繁,可以每3炮调整一次,或者5炮调整一次,甚至是10炮后再调整。

 

  要实现这个功能,就需要增加一个动态调整的步长(或叫间隔)。


 

  比如,我们要设定每3炮调整一次,就这样调整。

 

  我们将动态调整的代码,嵌套到一个判断中去:

 

  If i Mod 3 = 0Then

 

  (这里放动态调整的整段代码)

 

  End If


 

策划如何用VBA调试游戏数值


 

  If 判断我们已经很熟悉了,但是这段:

iMod 3 = 0

  

  是什么意思呢?

 

  大家还记得,在循环体里面,i是计数器,表示从11000,当前轮到第几位了。

 

  ModVBA的内置函数,用于取得两个整数相除后结果的余数。聪明的小伙伴应该已经发现,哪些数字取余数是0啊?36913......3的倍数,遇到3的倍数就执行一次代码,不就实现了我们需要的每隔3次就调整一次的目的了吗。


 

  不过,这个调整步长在调试中会经常修改,最好是能把它拨出来作为常量,方便调整。

 

  定义一个常量:

 

策划如何用VBA调试游戏数值

 

  将代码修改为:

 

策划如何用VBA调试游戏数值


 

  好了,现在概率“抖动”地不是太厉害了,你也可以把apt值得改大一些,让它变得更“迟钝”。


  15结语
 

  我们已经搭建好了最基本的模型,小伙伴们就可以通过修改之前定义好的几个常量,写入各种数值进行调试了。

策划如何用VBA调试游戏数值


 

策划如何用VBA调试游戏数值


 

  希望这个教程能够帮助到大家,虽然这段短短的代码对于专业的程序员来说不算什么,但正所谓“策划写代码,神仙挡不住”。写的过程中,锻炼了我们的思维,联想到了更多的细节,另外这其中的成就感也是爆棚的。

 

  作为一个策划,仅仅完成这些数值的调整是不够的,我们所要做的其他工作更多。一个游戏需要成功,仅仅靠一个人写一段代码是完成不了的,需要项目组所有人共同发光发热,每个人提供的能量多一些,那整个团队的战斗力肯定会有非常明显的提升。

 

 

  祝大家早日实现自己的梦想!


 

  这次教程的全部VBA代码:

 

1.      Sub 按钮1_Click()

2.      SumExp = 1 '总支出

3.      SumInc = 0 '总收入

4.       

5.      Per = 0.1  '击杀率

6.       

7.      Gold = 10 '掉落金币

8.       

9.      M = 14 '悲情值

10.   

11.  ap = 0 '实时调整概率

12.  apUp = 0.05  '限制最高几率

13.  apDown = -0.05  '限制最低几率

14.   

15.  apt = 3 '概率调整步长

16.   

17.  For i = 1 To 1000 '模拟次数

18.      If Rnd < (Per + ap) Then  '子弹击杀了怪物

19.      SumInc = SumInc + 1 '收入加起来

20.      Sheet1.Cells(i, 4).Value = 1

21.      N = M '重置悲情值

22.      Else  '子弹未击杀怪物

23.      Sheet1.Cells(i, 4).Value = 0

24.      N = N - 1

25.      Sheet1.Cells(i, 5).Value = N '打印出悲情值

26.          If N <= 0 Then

27.          SumInc = SumInc + 1

28.          N = M '重置悲情值

29.          End If

30.      End If

31.      

32.  SumExp = SumExp + 1 '支出加起来

33.   

34.  Sheet1.Cells(i, 1).Value = SumExp '打印支出数值

35.  Sheet1.Cells(i, 2).Value = SumInc * Gold '打印收入数值

36.  Sheet1.Cells(i, 3).Value = SumInc * Gold - SumExp '打印纯收益数值

37.   

38.      If i Mod apt = 0 Then   '每隔apt炮调整一次概率

39.          Select Case (SumInc * Gold - SumExp) / SumExp   '根据收益调整几率

40.          

41.              Case Is <= 0

42.                                  ap = ap + 0.01 '收入过低,提高概率

43.              Case Is > 0

44.                                  ap = ap - 0.01 '收入过高,降低概率

45.          End Select

46.          Select Case ap      '调整概率不超过上下限

47.              Case Is >= apUp

48.                                  ap = apUp

49.              Case Is < apDown

50.                                  ap = apDown

51.          End Select

52.      End If

53.   

54.  Sheet1.Cells(i, 6).Value = ap + Per '打印概率的变化情况

55.   

56.  Next

57.  End Sub

复制代码

 

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引