Author Topic: Basics of Visual Basic  (Read 9319 times)

eric22222

  • Fanatic
  • ***
  • Posts: 177
    • View Profile
    • Eric Online
    • Email
Basics of Visual Basic
« on: 2006-07-08, 04:09:16 AM »
Hello, all! Seems Malaysia has more internet than I expected it would. Anyway, I've had more free time than I expected I would and want to put in some effort to learning VBScript. I pulled up the scripting, um, docutorial, and tried reading through. I'm lost. I'll definately need a little help on this.

So the script is sort of applied to the whole game whenever an "event" meets certain criteria, right? Like, a special function is activated, or the player interacts with a type of tile.

I'm also a bit confused on the whole "sub"/"subroutine" thing if anyone can clear up what that does...

Here's the example framework:

Code: [Select]
Sub Player_OnControllerMove(OldActions, NewActions)
   'Your code here.
End Sub

HostObj.SinkObjectEvents ProjectObj.GamePlayer, "Player"
HostObj.ConnectEventsNow()
ProjectObj.GamePlayer.Play 16

So I think the OldActions/NewActions parts are replaced with 8 bits, each one representing a button (up, left, etc). I'm not sure what kind of stuff would be code, but I think I get that "End Sub" closes out whatever a "Sub" is. The rest of it completely throws me for a loop... Except the last line. I think I get that it starts the game.

Don't think I'm not reading through all the info. It just isn't making since to me yet...

bluemonkmn

  • SGDK Author
  • Administrator
  • Fanatic
  • *****
  • Posts: 2761
    • ICQ Messenger - 2678251
    • MSN Messenger - BlueMonkMN@gmail.com
    • View Profile
    • http://sgdk2.sf.net/
    • Email
Re: Basics of Visual Basic
« Reply #1 on: 2006-07-08, 07:08:14 AM »
You should probably also look at some example code.  Have you looked at the code included in the docutorial yet (the script for GoldYoink)?

Since a computer represents everything in bits, 8 bits just means a number between 0 and 255 (inclusive).  The example code you posted could be copied and pasted exactly as you showed into a script file and it would work.  It wouldn't do anything besides play the game, but it would work.  That's because OldActions and NewActions are variable names that will receive the numbers.  So you could add code after the "Your code here" comment line that does something with these variables.  Surely there's some example code that demonstrates this, and I think the Docutorial walks through some details too.  But OldActions and NewActions are just variables whose values are supplied by GameDev to tell the script what the state of the controller was before and what it is now by packing 8 bits of information into each of the two variables.  255 represents 8 bits that are all turned on amd 0 represents no bits turned on.  4 represents the third bit turned on.  5 represents the first and third bit turned on.  But really all you have to understand is how you extract information from those numbers using "And" and the constants the define which bits are associated with which controller buttons/positions.

I think the scripting wizard "record and playback" feature will generate script that demonstrates how you can use the ControllerMove event (and record the movement for playback later).

eric22222

  • Fanatic
  • ***
  • Posts: 177
    • View Profile
    • Eric Online
    • Email
Re: Basics of Visual Basic
« Reply #2 on: 2006-07-08, 08:03:53 AM »
Okay... so if I wanted to remake part of my game where touching a tile in the category "red" activates the function "swap_to_red", it would look something like this?

Code: [Select]
Sub Player_OnAfterMoveSprites()
   If --something that checks if the player touched a tile in category in "red"-- Then
      ProjectObj.GamePlayer.ActivateFunction ProjectObj.Maps("Map1").Specials("Swap_to_red")
   End If
End Sub

HostObj.SinkObjectEvents ProjectObj.GamePlayer, "Player"
HostObj.ConnectEventsNow()
ProjectObj.GamePlayer.Play 16

I'm just piecing this together from the code of the tutorial project and the scripting reference, so I'm not sure on much... I found a few parts of the list that look like they would complete the code (Touch, OnTouchTile, and OnTileInteraction), though I'm not sure how I fit them to this.

Oh, and what does "Dim" mean? I think once I learn the basic vocabulary and syntax, I should have a good foothold in the learning curve. Maybe then I'll know what's going on.  ???

bluemonkmn

  • SGDK Author
  • Administrator
  • Fanatic
  • *****
  • Posts: 2761
    • ICQ Messenger - 2678251
    • MSN Messenger - BlueMonkMN@gmail.com
    • View Profile
    • http://sgdk2.sf.net/
    • Email
Re: Basics of Visual Basic
« Reply #3 on: 2006-07-08, 07:32:50 PM »
1) If you want to activate a function when a tile is touched, you should put the code in the OnTileInteractionEvent instead of in the OnAfterMoveSprites event.

2) Dim "declares" the existence of a variable in a particular "scope".  If the "Dim" for a variable is within a function, then that variable is only accessible within that function (if you "Dim" and use the same variable name in another function, it will be an independent value).  If you Dim the variable at the top of the script (not inside a Function/Sub) then you can use that variable anywhere in the code (as long as you don't Dim another copy inside the function).

eric22222

  • Fanatic
  • ***
  • Posts: 177
    • View Profile
    • Eric Online
    • Email
Re: Basics of Visual Basic
« Reply #4 on: 2006-07-09, 06:27:31 AM »
Okay, I think I'm picking up on this... Dim says "this variable will be used in this area." I think I'm starting to see what's going on. I'll hopefully be able to look at a bunch of code now and pick up on some stuff. If I have anymore questions, I'll put 'em here. Thanks!  ;D

Edit: Almost forgot...
Can I define any combination of letters as a variable? Like, something that's self-explanatory enough for me to remember what refers to what?
Secondly, what does putting a number in parentheses after a variable do? Is that to define an initial value?
Thirdly: this is probably extremely obvious to you scripters, but I'm gonna need to humble myself and ask: does capitalization matter in script?
Thanks! (again!)
« Last Edit: 2006-07-09, 06:36:52 AM by eric22222 »

bluemonkmn

  • SGDK Author
  • Administrator
  • Fanatic
  • *****
  • Posts: 2761
    • ICQ Messenger - 2678251
    • MSN Messenger - BlueMonkMN@gmail.com
    • View Profile
    • http://sgdk2.sf.net/
    • Email
Re: Basics of Visual Basic
« Reply #5 on: 2006-07-09, 07:44:27 AM »
1) Microsoft's official documentation on variable declaration rules for VBScript is available in this page in their MSDN documentation.

2) Parentheses are used with variables when the variable represents an array (multiple values indexed by number stored in one variable).  VBScript Arrays are described on the same page in MSDN.

3) VBScript is not case-sensitive.  "MyVar" will refer to the same variable as "myvar".

durnurd

  • Lead Lemming
  • Expert
  • Fanatic
  • *****
  • Posts: 1234
  • Games completed so far: 0
    • MSN Messenger - durnurd@hotmail.com
    • View Profile
    • Find My Ed
Re: Basics of Visual Basic
« Reply #6 on: 2006-07-09, 10:12:20 AM »
One addendum is that when comparing litteral strings, capitalization does matter.  For example:

Code: [Select]
"Test1" = "tEsT1"
will return false.
Edward Dassmesser

eric22222

  • Fanatic
  • ***
  • Posts: 177
    • View Profile
    • Eric Online
    • Email
Re: Basics of Visual Basic
« Reply #7 on: 2006-07-09, 11:47:53 PM »
Okay, I'm trying do some pretty simple stuff in a test project. Looking at all the sample script I had, I decided I'd try to activate a function whenever the player walks up to a wall on its left. Here's what I've pieced together:

Code: [Select]
Sub Player_OnControllerMove(OldActions, NewActions)
Dim Lyr, Spr, Def
Set Lyr = ProjectObj.Maps("Map1").MapLayer("Test")
Set Spr = Lyr.Sprite(0)
Set Def = Spr.rDef
If Def.SolidTest(Spr.X-1,Spr.Y+31) Then
ProjectObj.GamePlayer.ActivateFunction ProjectObj.Maps("Map1").Specials("Move up")
End If
End Sub

HostObj.SinkObjectEvents ProjectObj.GamePlayer, "Player"
HostObj.ConnectEventsNow()
ProjectObj.GamePlayer.Play 16

The function is just a relative teleport (up 5 pixels). Nothing really happens, but the game does run. So what am I missing here?

Also, I've deduced that Sprite(0) refers to the first sprite in the list, but is there a way to refer to the player sprite? I saw PlayerSprite in the reference, but it says I have to call InitPlayerSprite first.

durnurd

  • Lead Lemming
  • Expert
  • Fanatic
  • *****
  • Posts: 1234
  • Games completed so far: 0
    • MSN Messenger - durnurd@hotmail.com
    • View Profile
    • Find My Ed
Re: Basics of Visual Basic
« Reply #8 on: 2006-07-10, 06:53:10 AM »
As long as the game is being run at the time the call is made, you don't have to worry about InitPlayerSprite.  You can just use ProjectObj.GamePlayer.PlayerSprite

Perhaps it would be a good idea to tell us exactly what you think each step is doing so we know what's going on.  And, of course, you should test the "Move Up" special function to make sure it works from within the game normally (i.e. without script).
Edward Dassmesser

eric22222

  • Fanatic
  • ***
  • Posts: 177
    • View Profile
    • Eric Online
    • Email
Re: Basics of Visual Basic
« Reply #9 on: 2006-07-10, 08:07:20 AM »
Yes, "Move Up" works as it should without script. So here's my take on what this whole thing is doing:
Code: [Select]
Sub Player_OnControllerMove(OldActions, NewActions)This is what starts this section of code, running through it after the controller's position moves.
Code: [Select]
Dim Lyr, Spr, DefThis sets "Lyr", "Spr", and "Def" and variables.
Code: [Select]
Set Lyr = ProjectObj.Maps("Map1").MapLayer("Test")
Set Spr = Lyr.Sprite(0)
Set Def = Spr.rDef
This section defines "Lyr" as, well, the only layer I have in this project. The second line defines "Spr" as the first sprite on that layer, and the third line defines "Def" as "Spr.rDef", which is referencing the player sprite's sprite definition.
Code: [Select]
If Def.SolidTest(Spr.X-1,Spr.Y+31) ThenThis part was a bit counter-intuitive. I know it's testing for solidity at the point one pixel left of the bottom-left corner, but I would've thought it would need something like "If Def.SolidTest(...) = True Then". But this is how I saw it in the tutorial project's script, so I followed suit.
Code: [Select]
ProjectObj.GamePlayer.ActivateFunction ProjectObj.Maps("Map1").Specials("Move up")This part activates the function "Move Up" in Map1. That's just followed by the "Ends" and the three lines that I can only assume is needed in every code.
Code: [Select]
HostObj.SinkObjectEvents ProjectObj.GamePlayer, "Player"
HostObj.ConnectEventsNow()
ProjectObj.GamePlayer.Play 16
I'm not sure on the first one, the second one kind of puts it all together, and the third one starts the game. So... how'd I do?

Extra credit: Could I leave out all the Dim and Set parts if I changed the SolidTest line to:
Code: [Select]
If ProjectObj.GamePlayer.PlayerSprite.rDef.SolidTest(Spr.X-1,Spr.Y+31) Then

bluemonkmn

  • SGDK Author
  • Administrator
  • Fanatic
  • *****
  • Posts: 2761
    • ICQ Messenger - 2678251
    • MSN Messenger - BlueMonkMN@gmail.com
    • View Profile
    • http://sgdk2.sf.net/
    • Email
Re: Basics of Visual Basic
« Reply #10 on: 2006-07-10, 08:16:48 PM »
I tried your script and it works on my test project.  Perhaps you didn't get the script hooked up to the project.  Also, it only activates when I'm up against a wall *and* I push or release a key (because it only activates when OnControllerMove fires).  Can you do something to verify that the script is running at all?  For example, add this line above the SinkObjectEvents line:

MsgBox "Test"

To answer your other question, yes you can eliminate a lot of the code by performing more work on a single line like that.  But your sample code still shows references to the Spr variable so you didn't entirely eliminate all the variable references there.

eric22222

  • Fanatic
  • ***
  • Posts: 177
    • View Profile
    • Eric Online
    • Email
Re: Basics of Visual Basic
« Reply #11 on: 2006-07-10, 09:11:38 PM »
Oh... Right... I need to make sure the script is running with the project... My mistake  :-[.

And I see what you mean about the Spr thing, that I missed some. Ok, thanks again guys!

durnurd

  • Lead Lemming
  • Expert
  • Fanatic
  • *****
  • Posts: 1234
  • Games completed so far: 0
    • MSN Messenger - durnurd@hotmail.com
    • View Profile
    • Find My Ed
Re: Basics of Visual Basic
« Reply #12 on: 2006-07-11, 07:07:18 AM »
A quick note on the "counter-intuitive" line:

an "if" statement controls the flow of a program by only executing the code inside the block when a condition evaluates to true.  For example:

Code: [Select]
if true then
   'do Something
end if

will always execute, since true always evaluates to true.  So whatever your expression is, if it evaluates to true, the code inside the block will run when it reaches that point in the program.  So saying "if (statement) = true" is equivalent to saying "if true = true" or "if false = true" which, if you know your boolean logic, is equivalent to "if true AND true" or "if false AND true" which then re-evaluates back to "if true" and "if false", the same as the original, without checking to see if it's true: "if (statement)"
Edward Dassmesser

eric22222

  • Fanatic
  • ***
  • Posts: 177
    • View Profile
    • Eric Online
    • Email
Re: Basics of Visual Basic
« Reply #13 on: 2006-07-17, 06:56:06 AM »
Now that the basics are about covered, I'm moving into doing actually useful things. The still-untitled game that Adam and I are working on is going to have a whole bunch of moves that can be done (think Super Mario 64 or Banjo-Kazooie). I think a good use of script would be to clean up all those special functions we've used just to get a spear to be thrown through the air. Here's what we're going for: you press whatever button we decide on, the spear is tossed in the direction you're facing (high non-100 inertia from a 45-degree vector), the spear hits the ground and changes to spear_in_ground upon touching the ground tiles.

The main hurdle we had there was detecting when the spear had come in contact with the ground since only player interactions are supported without scripting (As far as I know). Our clever workaround was to actually swap the player to the spear. The original player was still controlled by the arrow keys, but the camera centered on the spear. It was actually pretty cool, but would be awful if you threw it down a pit and couldn't see the character anymore.

With a bit of script, I'm sure this could be alot easier. So... first question.

Code: [Select]
Sub DoFireButton0()
   With ProjectObj.GamePlayer.PlayerSprite
      Select Case .rDef.Template.StateType
      Case STATE_LEFT_RIGHT
         If (.CurState Mod 2) = 0 Then
            ProjectObj.GamePlayer.ActivateFunction ProjectObj.Maps("MyMapName").Specials("Throw_spear_left")
         Else
            ProjectObj.GamePlayer.ActivateFunction ProjectObj.Maps("MyMapName").Specials("Throw_spear_right")
         End If
      End Select
   End With
End Sub

I've modified part of the shooting script. I'm hoping I changed all the necessary info. Of course, this is only step one. Eventually, I'll be able to get the entire spear toss in script (hopefully). Maybe if I were to replace the lines that cause the functions with the acutal meat of the function (just make it create the sprite).

So is this right so far? Just to see which way the player is facing (it is a left/right state sprite).

durnurd

  • Lead Lemming
  • Expert
  • Fanatic
  • *****
  • Posts: 1234
  • Games completed so far: 0
    • MSN Messenger - durnurd@hotmail.com
    • View Profile
    • Find My Ed
Re: Basics of Visual Basic
« Reply #14 on: 2006-07-17, 05:09:27 PM »
using script, you can use two functions to find when a sprite has hit solid:

Code: [Select]
Sub Player_OnBeforeMoveSprites()
   Sprite.ReactToSolid
   If Sprite.bHitSolid Then
      'Do something
   End If
End Sub

Where Sprite is the sprite you want to check.  It might also be easier to create the sprites in the script so you can keep track of them rather than calling a special function to do it.
Edward Dassmesser