home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Game Programming for Teens / VBGPFT.cdr / sources / chapter17 / CelticCrusader2 / Characters.bas < prev    next >
Encoding:
BASIC Source File  |  2004-10-25  |  10.3 KB  |  375 lines

  1. Attribute VB_Name = "Characters"
  2. '---------------------------------------------------------------
  3. ' Visual Basic Game Programming for Teens
  4. ' Characters.bas File
  5. '---------------------------------------------------------------
  6.  
  7. Option Explicit
  8. Option Base 0
  9.  
  10. 'main character class data type
  11. Public Type TCHARACTER
  12.     name As String * 20
  13.     classtype As String * 20
  14.     experience As Integer
  15.     level As Integer
  16.     strength As Integer
  17.     dexterity As Integer
  18.     intellect  As Integer
  19.     charisma As Integer
  20.     stamina As Integer
  21.     fillerstr As String * 80
  22.     fillerint(10) As Integer
  23. End Type
  24.  
  25. 'keeps track of NPC state
  26. Public Enum NPCSTATES
  27.     NPC_STOPPED = 0
  28.     NPC_WALKING = 1
  29.     NPC_PAUSED = 2
  30.     NPC_TALKING = 3
  31. End Enum
  32.  
  33. 'keeps track of each character
  34. Public Type TNPC
  35.     name As String
  36.     state As NPCSTATES
  37.     startpos As point
  38.     curpos As point
  39.     destpos As point
  40.     classindex As Integer
  41.     SpeedDelay As Integer
  42.     SpeedCount As Integer
  43.     Facing As Integer
  44. End Type
  45.  
  46. 'generic data for the character classes
  47. 'images and data are shared by the NPCs
  48. Const NUMCHARS As Long = 1
  49. Dim charImages(NUMCHARS) As Direct3DTexture8
  50. Dim charClasses(NUMCHARS) As TCHARACTER
  51.  
  52. 'unique data for each individual NPC
  53. Const NUMNPCS As Long = 10
  54. Dim charStates(NUMNPCS) As TNPC
  55. Dim charSprites(NUMNPCS) As TSPRITE
  56.  
  57. 'main player character
  58. Public Player As TCHARACTER
  59.  
  60.  
  61. Public Sub InitCharacters()
  62.     Dim p As point
  63.     Dim n As Long
  64.     
  65.     'set up all the base character classes, sprites, and images
  66.     'so far we're only using a single type of character--Viking Warrior
  67.     charClasses(0) = LoadCharacterBinaryFile(App.Path & "\warrior.dat")
  68.     Set charImages(0) = LoadTexture(d3ddev, App.Path & "\viking_walking.bmp")
  69.     
  70.     'now create the individual characters used in the game
  71.     'all of these will share the base data above
  72.     For n = 0 To NUMNPCS - 1
  73.         
  74.         'initialize sprite data
  75.         InitSprite d3ddev, charSprites(n)
  76.         With charSprites(n)
  77.             .FramesPerRow = 8
  78.             .FrameCount = 8
  79.             .AnimDelay = 2
  80.             .width = 96
  81.             .height = 96
  82.         End With
  83.             
  84.         'start NPCs at the player's location
  85.         '(to test NPC movement at this stage)
  86.         p.x = PLAYERSTARTX * TILEWIDTH
  87.         p.y = PLAYERSTARTY * TILEHEIGHT
  88.         
  89.         'customize the Viking character
  90.         With charStates(n)
  91.             
  92.             'this is the key! points to the base image/sprite/data
  93.             .classindex = 0
  94.             
  95.             .name = "Viking"
  96.             .startpos = p
  97.             .curpos = p
  98.             .SpeedDelay = 1
  99.             .SpeedCount = 0
  100.             .state = NPC_WALKING
  101.             SetRandomDestination n
  102.  
  103.         End With
  104.     Next n
  105.     
  106. End Sub
  107.  
  108. Public Sub SetRandomDestination(ByVal num As Long)
  109.     With charStates(num)
  110.     
  111.         'set random X near the starting position
  112.         '(the NPC will never wander away from his "home")
  113.         .destpos.x = .startpos.x + Random(600)
  114.         If .destpos.x > GAMEWORLDWIDTH Then
  115.             .destpos.x = GAMEWORLDWIDTH - 1
  116.         End If
  117.         
  118.         'set random Y near the starting position
  119.         .destpos.y = .startpos.y + Random(600)
  120.         If .destpos.y > GAMEWORLDHEIGHT Then
  121.             .destpos.y = GAMEWORLDHEIGHT - 1
  122.         End If
  123.     End With
  124. End Sub
  125.  
  126. Public Sub MoveNPC(ByVal num As Long)
  127.     'moves a single NPC
  128.     With charStates(num)
  129.     
  130.         'update movement rate--exit if not there yet
  131.         .SpeedCount = .SpeedCount + 1
  132.         If .SpeedCount < .SpeedDelay Then Exit Sub
  133.             
  134.         'okay, time to move, reset move counter
  135.         .SpeedCount = 0
  136.         
  137.         'check to see if destination reached
  138.         If .curpos.x = .destpos.x And .curpos.y = .destpos.y Then
  139.             'yes! set a new destination then exit
  140.             .state = NPC_STOPPED
  141.             Exit Sub
  142.         Else
  143.             .state = NPC_WALKING
  144.         End If
  145.  
  146.         'time to set the NPC's "facing" direction
  147.         'and update the X,Y position
  148.         If .curpos.x < .destpos.x Then
  149.             
  150.             'needs to walk westward
  151.             .curpos.x = .curpos.x + 1
  152.             
  153.             If .curpos.y < .destpos.y Then
  154.                 'facing SE
  155.                 .curpos.y = .curpos.y + 1
  156.                 .Facing = 3
  157.             ElseIf .curpos.y > .destpos.y Then
  158.                 'facing NE
  159.                 .curpos.y = .curpos.y - 1
  160.                 .Facing = 1
  161.             Else
  162.                 'facing EAST
  163.                 .Facing = 2
  164.             End If
  165.         
  166.         ElseIf .curpos.x > .destpos.x Then
  167.             
  168.             'needs to walk eastward
  169.             .curpos.x = .curpos.x - 1
  170.             
  171.             If .curpos.y < .destpos.y Then
  172.                 'facing SW
  173.                 .curpos.y = .curpos.y + 1
  174.                 .Facing = 5
  175.             ElseIf .curpos.y > .destpos.y Then
  176.                 'facing NW
  177.                 .curpos.y = .curpos.y - 1
  178.                 .Facing = 7
  179.             Else
  180.                 'facing WEST
  181.                 .Facing = 6
  182.             End If
  183.             
  184.         Else 'must be facing due NORTH or SOUTH
  185.             
  186.             If .curpos.y < .destpos.y Then
  187.                 'facing SOUTH
  188.                 .curpos.y = .curpos.y + 1
  189.                 .Facing = 4
  190.             ElseIf .curpos.y > .destpos.y Then
  191.                 'facint NORTH
  192.                 .curpos.y = .curpos.y - 1
  193.                 .Facing = 0
  194.             End If
  195.         
  196.         End If
  197.     
  198.     End With
  199. End Sub
  200.  
  201. Public Sub DrawNPC(ByVal num As Long)
  202.     Dim r As RECT
  203.     Dim classindex As Long
  204.     
  205.     'grab a shortcut to these long variable names
  206.     r.Left = charStates(num).curpos.x
  207.     r.Top = charStates(num).curpos.y
  208.     r.Right = r.Left + charSprites(num).width
  209.     r.bottom = r.Top + charSprites(num).height
  210.     
  211.     'remember, images/data are referred to using the NPC's classindex!
  212.     'the sprite and state arrays are for every single unique NPC,
  213.     'but the bitmap image and class data are shared by all NPCs
  214.     classindex = charStates(num).classindex
  215.     
  216.     'now check to see if the sprite is within the scrolling viewport
  217.     'sprite's position is actually global, so this determines if it's visible
  218.     If r.Left > ScrollX - 1 And r.Right < ScrollX + SCREENWIDTH + 1 And _
  219.        r.Top > ScrollY - 1 And r.bottom < ScrollY + SCREENHEIGHT + 1 Then
  220.     
  221.         'update animation frame if walking
  222.         AnimateSprite charSprites(num)
  223.         
  224.         'draw the sprite--remember, it's using the shared image (texture)
  225.         charSprites(num).x = charStates(num).curpos.x - ScrollX
  226.         charSprites(num).y = charStates(num).curpos.y - ScrollY
  227.         charSprites(num).AnimSeq = charStates(num).Facing
  228.         DrawSprite charImages(classindex), charSprites(num), C_WHITE
  229.     
  230.     End If
  231.  
  232. End Sub
  233.  
  234. Public Sub MoveNPCs()
  235.     Dim n As Long
  236.     
  237.     'loop through all of the NPCs and move them
  238.     For n = 0 To NUMNPCS - 1
  239.         
  240.         Select Case charStates(n).state
  241.             Case NPC_TALKING
  242.                 FacePlayer n
  243.             
  244.             Case NPC_PAUSED
  245.                 SetRandomDestination n
  246.             
  247.             Case NPC_WALKING
  248.                 MoveNPC n
  249.                 
  250.             Case NPC_STOPPED
  251.                 SetRandomDestination n
  252.             
  253.         End Select
  254.     Next n
  255. End Sub
  256.  
  257. Public Sub CheckNPCCollisions()
  258.     Dim n As Long
  259.     
  260.     'check all NPCs for collisions
  261.     For n = 0 To NUMNPCS - 1
  262.     
  263.         If Collision(charSprites(n), heroSpr) Then
  264.             charStates(n).state = NPC_TALKING
  265.         End If
  266.         
  267.     Next n
  268.  
  269. End Sub
  270.  
  271. Public Sub TalkToPlayer(ByVal num As Long)
  272.     Dim x As Long
  273.     Dim y As Long
  274.     
  275.     x = charSprites(num).x + charSprites(num).width / 4
  276.     y = charSprites(num).y
  277.     PrintText fontImg, fontSpr, x, y, C_WHITE, "Hello"
  278.  
  279. End Sub
  280.  
  281. Public Sub FacePlayer(ByVal num As Long)
  282.     Dim a As point
  283.     Dim b As point
  284.     
  285.     a.x = heroSpr.x + heroSpr.width / 2
  286.     a.y = heroSpr.y + heroSpr.height / 2
  287.     
  288.     b.x = charSprites(num).x + charSprites(num).width / 2
  289.     b.y = charSprites(num).y + charSprites(num).height / 2
  290.     
  291.     With charStates(num)
  292.         
  293.         If b.x < a.x - 5 Then
  294.             If b.y < a.y - 5 Then
  295.                 .Facing = 3
  296.             ElseIf b.y > a.y + 5 Then
  297.                 .Facing = 1
  298.             Else
  299.                 .Facing = 2
  300.             End If
  301.         
  302.         ElseIf b.x > a.x + 5 Then
  303.             If b.y < a.y - 5 Then
  304.                 .Facing = 5
  305.             ElseIf b.y > a.y + 5 Then
  306.                 .Facing = 7
  307.             Else
  308.                 .Facing = 6
  309.             End If
  310.             
  311.         Else
  312.             If b.y < a.y - 5 Then
  313.                 .Facing = 4
  314.             ElseIf b.y > a.y + 5 Then
  315.                 .Facing = 0
  316.             End If
  317.         End If
  318.     
  319.     End With
  320. End Sub
  321.  
  322. Public Sub DrawNPCs()
  323.     Dim n As Long
  324.     
  325.     'loop through all of the NPCs and draw them
  326.     For n = 0 To NUMNPCS - 1
  327.         
  328.         Select Case charStates(n).state
  329.             Case NPC_TALKING
  330.                 DrawNPC n
  331.                 charStates(n).state = NPC_WALKING
  332.                 
  333.                 If diState.key(KEY_SPACE) > 0 Then
  334.                     TalkToPlayer n
  335.                 End If
  336.             
  337.             Case NPC_PAUSED
  338.                 DrawNPC n
  339.                 charStates(n).state = NPC_WALKING
  340.             
  341.             Case NPC_WALKING
  342.                 DrawNPC n
  343.                 
  344.             Case NPC_STOPPED
  345.                 DrawNPC n
  346.                 charStates(n).state = NPC_WALKING
  347.                     
  348.         End Select
  349.     
  350.     Next n
  351. End Sub
  352.  
  353. Public Function LoadCharacterBinaryFile(ByVal filename As String) As TCHARACTER
  354.     Dim filenum As Integer
  355.     Dim dude As TCHARACTER
  356.     
  357.     filenum = FreeFile()
  358.     Open filename For Binary As filenum Len = Len(dude)
  359.     Get filenum, , dude
  360.     Close filenum
  361.     
  362.     LoadCharacterBinaryFile = dude
  363. End Function
  364.  
  365. Public Sub SaveCharacterBinaryFile(ByVal filename As String, ByRef dude As TCHARACTER)
  366.     Dim filenum As Integer
  367.     
  368.     filenum = FreeFile()
  369.     Open filename For Binary As filenum Len = Len(dude)
  370.     Put filenum, , dude
  371.     Close filenum
  372. End Sub
  373.  
  374.  
  375.