VB 版 (精华区)

发信人: aaaz (我最笨了), 信区: VB
标  题: QB角色扮演游戏四天写作课程(5)
发信站: 哈工大紫丁香 (2000年07月27日09:40:11 星期四), 转信

发信人: netwolf (小狼), 信区: GAME_Designer
标  题: QB角色扮演游戏四天写作课程(5)
发信站: BBS 水木清华站 (Thu Jul 24 17:43:18 1997)

第四天

今天让我们来替迷宫内增加一些有用的物品,像是食物、武器等装备。 为求游戏整
体的平衡,我们同时也在迷宫内增加一些陷阱:

CLS
RANDOMIZE TIMER                                 :REM  <--- new
DIM monster(10, 10)
FOR count1 = 1 TO 10
 FOR count2 = 1 TO 10
  monster(count1, count2) = INT(RND * 11)
 NEXT count2
NEXT count1
NEXT count1

DIM item(10, 10)                                :REM  <--- new
FOR count1 = 1 TO 10                            :REM    |
 FOR count2 = 1 TO 10                           :REM    |
  IF RND < .2 THEN                              :REM    |
   item(count1, count2) = INT(RND * 9) + 1      :REM    |
  ELSE                                          :REM    |
   item(count1, count2) = 0                     :REM    |
  END IF                                        :REM    |
 NEXT count2                                    :REM    |
NEXT count1                                     :REM   _|

row = 5
column = 5
moveErr$ = "You cannot move in that direction!"
pressKey$ = "Press any key to continue."
exitRow = INT(RND * 10) + 1
exitColumn = INT(RND * 10) + 1
gold = 0
health = 20
weapon = 1


DIM monster$(10)
RESTORE monsterData
FOR count = 1 TO 10
 READ monster$(count)
NEXT count

DIM item$(9)                                    :REM  <--- new
RESTORE itemData                                :REM    |
FOR count = 1 TO 9                              :REM    |
 READ item$(count)                              :REM    |
NEXT count                                      :REM   _|

LOCATE 14, 1
PRINT "Commands:   n - north"
PRINT "            s - south"
PRINT "            e - east"
PRINT "            w - west"
PRINT "            a - attack"
PRINT "            t - take item"               :REM  <--- new
PRINT "            x - use exit"
PRINT
PRINT "            q - quit"

LOCATE 14, 40                                           :REM  <--- new
PRINT CHR$(201); STRING$(10, CHR$(205)); CHR$(187)      :REM    |
LOCATE 15, 40                                           :REM    |
PRINT CHR$(186); SPACE$(10); CHR$(186)                  :REM    |
LOCATE 16, 40                                           :REM    |
PRINT CHR$(200); STRING$(10, CHR$(205)); CHR$(188)      :REM    |
LOCATE 17, 44                                           :REM    |
PRINT "ITEM"                                            :REM   _|

DO
 LOCATE 1, 1
 PRINT "Your position:"; row; column
 LOCATE 1, 25
 PRINT "Gold:"; gold; "  Health:"; health; "  Weapon:"; weapon  :REM <--changed
  IF ((row = exitRow) AND (column = exitColumn)) THEN
  LOCATE 2, 1
  PRINT "You are at the exit!"
 ELSE
  LOCATE 2, 1
  PRINT SPACE$(79)
 END IF
 END IF
 LOCATE 3, 1
 PRINT "Monster: ";
 monsterType = monster(row, column)
 IF monsterType = 0 THEN
  PRINT "nothing   "
 ELSE
  monsterName$ = MID$(monster$(monsterType), 1, 10)
  PRINT monsterName$
  monsterAttack = VAL(MID$(monster$(monsterType), 11, 1))
  MonsterHealth = VAL(MID$(monster$(monsterType), 12, 1))
  MonsterGold = monsterType * INT(RND * 6)
 END IF

 itemType (or edit) = item(row, column)                 :REM  <--- new
 IF itemType (or edit) = 0 THEN                         :REM    |
  LOCATE 15, 41                                         :REM    |
  PRINT "nothing   "                                    :REM    |
 ELSE                                                   :REM    |
  itemName$ = LEFT$(item$(itemType (or edit)), 10)      :REM    |
  itemClass$ = MID$(item$(itemType (or edit)), 11, 1)   :REM    |
  itemValue = VAL(RIGHT$(item$(itemType (or edit)), 1)) :REM    |
  LOCATE 15, 41                                         :REM    |
  PRINT itemName$                                       :REM    |
  IF itemClass$ = "T" THEN                              :REM    |
   LOCATE 10, 1                                         :REM    |
   PRINT "The "; RTRIM$(itemName$); " damages you for "; itemValue; " points!"
   health = health - itemValue                          :REM    |
   item(row, column) = 0                                :REM    |
   itemType (or edit) = 0                               :REM    |
   IF health <= 0 THEN                                  :REM    |
    PRINT "You die!"                                    :REM    |
    PRINT "Game over!"                                  :REM    |
    END                                                 :REM    |
   END IF                                               :REM    |
  END IF                                                :REM    |
 END IF                                                 :REM   _|

 LOCATE 8, 1
 INPUT "What now"; reply$
 LOCATE 10, 1
 PRINT SPACE$(79)
 PRINT SPACE$(79)
 PRINT SPACE$(79)


 SELECT CASE reply$
        CASE IS = "n"
         IF row = 1 THEN
          LOCATE 10, 1
          PRINT moveErr$
         ELSE
          row = row - 1
          LOCATE 10, 1
          PRINT "You go north."
         END IF
        CASE IS = "s"
         IF row = 10 THEN
          LOCATE 10, 1
          PRINT moveErr$
         ELSE
          row = row + 1
          LOCATE 10, 1
          PRINT "You go south."
         END IF
        CASE IS = "w"
         IF column = 1 THEN
          LOCATE 10, 1
          PRINT moveErr$
         ELSE
          column = column - 1
          LOCATE 10, 1
          PRINT "You go west."
         END IF
        CASE IS = "e"
         IF column = 10 THEN
          LOCATE 10, 1
          PRINT moveErr$
         ELSE
          column = column + 1
          LOCATE 10, 1
          PRINT "You go east."
         END IF
        CASE IS = "x"
         IF ((row = exitRow) AND (column = exitColumn)) THEN
          IF gold < 100 THEN
           LOCATE 10, 1
           PRINT "You dont have enough gold!"
          ELSE
           LOCATE 10, 1
           LOCATE 10, 1
           PRINT "You have escaped! Well done!"
           END
          END IF
         END IF
        CASE IS = "a"
         IF monsterType = 0 THEN
          LOCATE 10, 1
          PRINT "There's nothing to attack!"
         ELSE
          DO WHILE ((MonsterHealth > 0) AND (health > 0))
           LOCATE 10, 1
           PRINT SPACE$(79)
           PRINT SPACE$(79)
           PRINT SPACE$(79)
           LOCATE 10, 1
           attack = weapon + INT(RND * 9)
           SELECT CASE attack
                  CASE IS = monsterAttack
                   PRINT "No one wins this round."
                  CASE IS > monsterAttack
                                                              :REM  <-- changed
                   PRINT "You deal the "; RTRIM$(monsterName$); " a blow!"
                                                              :REM   _____|
                   MonsterHealth = MonsterHealth - 1
                  CASE IS < monsterAttack
                   PRINT "You have been wounded!"
                   health = health - 1
           END SELECT
           PRINT pressKey$
           SLEEP
          LOOP
          LOCATE 10, 1
          IF health > 0 THEN
           PRINT "You won the fight!"; SPACE$(20)
           PRINT "You found "; MonsterGold; " pieces of gold!"
           gold = gold + MonsterGold
           monsterType = 0
           monster(row, column) = 0
           PRINT pressKey$
           SLEEP
          ELSE
                                                              :REM  <-- changed
           PRINT "The "; RTRIM$(monsterName$); " killed you!"; SPACE$(20)
                                                              :REM   _____|
                                                              :REM   _____|
           PRINT "Game over!"; SPACE$(20)
           END
          END IF
         END IF
        CASE IS = "t"                                               :REM <--new
         IF itemType (or edit) = 0 THEN                             :REM   |
          LOCATE 10, 1                                              :REM   |
          PRINT "Nothing to take!"                                  :REM   |
          PRINT pressKey$                                           :REM   |
          SLEEP                                                     :REM   |
         ELSE                                                       :REM   |
          SELECT CASE itemClass$                                    :REM   |
                CASE IS = "F"                                       :REM   |
                 LOCATE 10, 1                                       :REM   |
                 PRINT "You eat the "; RTRIM$(itemName$); "."       :REM   |
                 IF health = 20 THEN                                :REM   |
                  PRINT "You had no wounds, so the food is wasted." :REM   |
                 ELSE                                               :REM   |
                  health = health + itemValue                       :REM   |
                  PRINT "You gain "; itemValue; " health points."   :REM   |
                 END IF                                             :REM   |
                CASE IS = "W"                                       :REM   |
                 LOCATE 10, 1                                       :REM   |
                 IF weapon >= itemValue THEN                        :REM   |
                  PRINT "You have a similar or better weapon."      :REM   |
                 ELSE                                               :REM   |
                  PRINT "You pick up a "; RTRIM$(itemName$); " !"   :REM   |
                  weapon = itemValue                                :REM   |
                  PRINT "Your weapon rating is now "; weapon; "."   :REM   |
                 END IF                                             :REM   |
          END SELECT                                                :REM   |
          PRINT pressKey$                                           :REM   |
          SLEEP                                                     :REM   |
          item(row, column) = 0                                     :REM   |
          itemType (or edit) = 0                                    :REM   |
         END IF                                                     :REM  _|
        CASE IS = "q"
         LOCATE 10, 1
         PRINT "Bye!"
         END
 END SELECT

LOOP


monsterData:
DATA "blind bat 21"
DATA "rat       11"
DATA "snake     31"
DATA "goblin    23"
DATA "troll     44"
DATA "bear      55"
DATA "lion      54"
DATA "sabretooth65"
DATA "elephant  78"
DATA "dragon    98"

itemData:                               :REM  <--- new
DATA "apple     F1"                     :REM    |
DATA "bread     F2"                     :REM    |
DATA "chicken   F3"                     :REM    |
DATA "dagger    W2"                     :REM    |
DATA "sword     W3"                     :REM    |
DATA "halberd   W4"                     :REM    |
DATA "smoke     T1"                     :REM    |
DATA "noose trapT2"                     :REM    |
DATA "pit trap  T3"                     :REM   _|

Starting from the top:

你或许已经注意到, 虽然 RND 宣称能够产生『乱数』效果,可是产生的乱数序怎麽
每次都相同?因为 QB 产生乱数的方式,是以一基底值(称之为乱数『种子』)作为
产生乱数的依据。由於我们在程式过程未设定该基底值,才会有每次乱数序皆相同的
现象。 RANDOMIZE 正是用来重新设定该数值的命令,而 TIMER 则代表著从子夜起到
目前所经过的秒数。 所以我们只要巧妙的利用 RANDOMIZE TIMER 这道命令,就可以
在每次执行时,产生不同的乱数。

物品的设置与邪恶怪物的安排相同, 我们是以 item(10,10) 的阵列来储存,如此可
让每个房间都能存有一件物品。我们设定房间内出现物品的机率为百分之二十( RND
< 0.2 ),而物品的编号则从 1 到 9。物品名称则存放在 item$ 阵列之中。

CHR$ 是将数值转换成对应的 ASCII 字元。 举例来说,我们可以用 PRINT CHR$(65)
来替代 PRINT "A"。65 则是 "A" 字元在 ASCII 字元表中的序码。

透过 CHR$ 我们可以使用一些有趣的字元,这可以使画面显得更丰富。在 QBasic 中
, 只要按下 SHIFT-F1,选择 "Contents" 与 "ASCII charater codes" 後就可以浏
览 ASCII 字元集。 瞧瞧 ASCII 数值为 2 所对应的字元,是不是有点像 PACMAN 呢



每个物品都有自己的名称、类别与数值。 类别用以区分它究竟属於食物( "F" )、
武器( "W" )还是陷阱( "T" )。而数值的定义则依类别的不同而有所差别。以下
是不同类别,其数值所代表的意义:

类别: 食物             数值: 主角可获得的生命点数
      武器                   主角可获得的 " 武器 " 属性
      陷阱                   主角触及时,将损失的生命点数

LEFT$(a$, 10) 与 MID$(a$,1,10) 的执行结果完全相同。换句话说,前者只是固定
从字串开头作为启始位置。 而 RIGHT$("ABCDE", 3) 将会传回 "CDE",也就是自整
个字串右边第三个字元开始算起复制字串。

其实 MID$ 可以完全取代 LEFT$ 与 RIGHT$, 不过使用後两者应该可以节省一点时
间。

当主角走进一间有陷阱的房间内,会立即减损一部份的生命力。 陷阱一旦被触发就
失去效用,     换句话说,     它只会造成一次伤害。     (解除方式为将阵列
item(row,column) 的值设定为 0 )

RTRIM$("ABC ") 会传回 "ABC"。 换句话说,RTRIM$ 会消除右边的所有空白字原部
份。LTRIM$ 用法类似,只不过它是从字串左方开始消除空白字元。

在取得物品方面,我们另外加入了一些有趣的检查。 假如主角在拾获一份食物时毫
发无伤( health=20 ),那麽取得这份食物无疑是一种浪费。另外假使主角试著舍
取一把不比目前手中为佳的武器时,程式也会于以制止。

OK,我们的 RPG 计画至今已终於完工了。

--
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 203.93.18.173]

--
※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: 202.118.226.221]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:209.117毫秒