Scrolling Game Development Kit Forum

SGDK Version 1 => Script => Topic started by: dutch_619 on 2007-02-20, 08:47:44 PM

Title: Keyboard input and Do loops
Post by: dutch_619 on 2007-02-20, 08:47:44 PM
I have two questions. The first is pretty easy

To begin I wanted to set the script to fire 4 bullets for every key press. I nested a loop,( i=4 while i >= 0 do, etc. but I think there's an easier way to do this. I get an odd error on occasion while loading the game and I think the script is the culprit. I think If I have the runtime component sleep before running It would run smoother and disregard any spurious input while loading. It would be simpler to use the extant counter in the script and dump my added on bits.

My next question involves grabbing the keyboard inputs for the playable sprite. I am using the BMDX to do this now, but the trouble is it grabs all playable sprites, even in instances I want the thing to be inert. I was hoping to grab the keyboard inputs without having to define collisions and solidity in the script. Any suggestions?

Thanks.
Title: Re: Keyboard input and Do loops
Post by: bluemonkmn on 2007-02-20, 09:15:32 PM
I don't understand your questions -- BMDXCtls doesn't know anything about sprites so I don't know what you mean by BMDXCtls "grabbing sprites".  And if you want to perform a loop more simply, use a For loop (For I = 1 to 4), but this isn't much simpler that using a while loop and a variable, and probably wouldn't have any effect on whatever error you're getting.  I can't guess what the problem is without knowing the error.
Title: Re: Keyboard input and Do loops
Post by: dutch_619 on 2007-02-20, 10:10:22 PM
I believe I have a handle on the first error, so that one can be disregarded.

The problem I have is that in order to make the playable sprite act the way I want I'm using events from the display object. I'm having trouble specifying the sprite I want to be affected by this. For the load screen I use an inert sprite and special functions to move it and interact with it. When using the aforementioned display events it will move the inert menu sprite as well as the playable sprite.

What I am attempting to do is to give the playable sprite a steady default speed in the direction it is facing. I then want to use the up and down keys to affect velocity, so that it moves faster while the up key is held and slower while the down is held. I am currently scrabbling for an simple way to do this. I have a few ideas but I would like to avoid the complexities I see in my ideas.
Title: Re: Keyboard input and Do loops
Post by: bluemonkmn on 2007-02-21, 07:26:36 AM
It sounds like you need help distinguishing when to affect the sprite or which sprite to affect.  What part of that are you having trouble with?  Can you just check the sprite definition name associated with the sprite to see if it's one that you want to affect?
Title: Re: Keyboard input and Do loops
Post by: dutch_619 on 2007-02-21, 11:53:11 PM
Hmm... I want to affect the playable sprite in all the various maps except the menu and credits map. I'd like to avoid having redundant pieces of code for the same sprite in various guises on different maps. The effect I want to have is, as before, to set the sprite to move at a set speed forward in whichever direction it is pointing. Then I'd like to use the up/down keys to either increase or decrease its speed. I can get this to work by having the up and down keys remapped in the gdp. file, then setting the up key to work when an arbitrarily picked key is not pressed. I then use the up and down keys to change to a new sprite thats either faster or slower. This is a very ugly way of doing so.

I have also tried setting the sprite to inert and doing the same thing with scripting and sinking keypresses to increase or decrease the sprites maximum speed.

I finally tried editing the source code to do this as well, but it leads to the unpleasant prospect of having a project that no one else can edit as it has to be deployed with an installer.

What I really could use at this point is an easier way to do these things. I am fortunately quickly becoming acquainted with VB which is an un-looked for boon. I do dislike how variables are used in VB. It seems untidy.
Title: Re: Keyboard input and Do loops
Post by: bluemonkmn on 2007-02-22, 06:41:05 AM
1) You don't need to sink events of the display to trap player input.  You can use the Player_OnControllerMoved event and/or bits from ProjectObj.GamePlayer.CtlActions  (I think the scripting reference in the help file documents the values of different bits that can be in this property as "Enum eActionBits").

2) Can you keep your same code, but just add a condition to skip it when you're on the menu?  For example:
Code: [Select]
If ProjectObj.GamePlayer.rMap.Name = "Menu" Then Exit Sub
Title: Re: Keyboard input and Do loops
Post by: dutch_619 on 2007-02-22, 08:45:23 PM
I think I see how to do this in C script, but not in VB. Like so I assume for C...

Void getinput()
{

    if (key[KEY_ESC])      gameover = 1;
    if (key[KEY_UP])        forward(1);
    if (key[KEY_RIGHT])   turnright(1);
    if (key[KEY_LEFT])     turnleft(1);
    if (key[KEY_DOWN])   backward(1);
}

void forward(int num)
{
    if (key_count[num]++ > key_delay[num])
    {
        key_count[num] = 0;

        player[num]->xspeed++;
        if (player[num]->xspeed > MAXSPEED)
            player[num]->xspeed = MAXSPEED;
    }
}

etc. etc. etc.
Title: Re: Keyboard input and Do loops
Post by: bluemonkmn on 2007-02-23, 06:17:09 AM
Do you just want me to translate that into VB script?
Code: [Select]
Sub getinput()
   If key(KEY_ESC) Then gameover = 1
   If key(KEY_UP) Then forward 1
   If key(KEY_RIGHT) Then turnright 1
   If key(KEY_LEFT) Then turnleft 1
   If key(KEY_DOWN) Then backward 1
End Sub

Sub forward(num)
   If key_count(num) > key_delay(num) Then
      key_count(num) = 0
      player(num).xspeed = player(num).xspeed + 1
      If player(num).xspeed > MAXSPEED Then
         player(num).xspeed = MAXSPEED
      End If
   Else
      key_count(num) = key_count(num) + 1
   End If
End Sub
Title: Re: Keyboard input and Do loops
Post by: dutch_619 on 2007-02-23, 09:11:21 PM
Thats not too different from C code. I guess I just need to know how to reference my sprite from the code. I'd like to pull as much info from the sprite definition as I can, rather than coding it into the script.

I think it's something like this

.....shooting script......

Sub Player_OnPlayInit()
   HostObj.StartScript=1
End Sub

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

#Split ========== Gameplay script (Number 1) ========


Option Explicit


Dim oPlayer

Set oPlayer = NewGameDevObj("Player")
Sub Player_OnPlayInit

 
Sub getinput()
   If key(KEY_UP) Then forward 1
   If key(KEY_RIGHT) Then turnright 1
   If key(KEY_LEFT) Then turnleft 1
   If key(KEY_DOWN) Then backward 1
End Sub

Sub forward(num)
   If key_count(num) > key_delay(num) Then
      key_count(num) = 0
      player(num).xspeed = player(num).xspeed + 1
      If player(num).xspeed > MAXSPEED Then
         player(num).xspeed = MAXSPEED
      End If
   Else
      key_count(num) = key_count(num) + 1
   End If
End Sub

Sub turnright(num)
   If key_count(num) > key_delay(num) Then
      key_count(num) = 0
      player(num).yspeed = player(num).yspeed + 1
      If player(num).yspeed > MAXSPEED Then
         player(num).yspeed = MAXSPEED
      End If
   Else
      key_count(num) = key_count(num) + 1
   End If
End Sub

Sub turnleft(num)
   If key_count(num) > key_delay(num) Then
      key_count(num) = 0
      player(num).yspeed = player(num).yspeed + 1
      If player(num).yspeed > MAXSPEED Then
         player(num).yspeed = MAXSPEED
      End If
   Else
      key_count(num) = key_count(num) + 1
   End If
End Sub     

Sub backward(num)
   If key_count(num) > key_delay(num) Then
      key_count(num) = 0
      player(num).xspeed = player(num).xspeed + 1
      If player(num).xspeed > MAXSPEED Then
         player(num).xspeed = MAXSPEED
      End If
   Else
      key_count(num) = key_count(num) + 1
   End If
End Sub



HostObj.SinkObjectEvents ProjectObj.GamePlayer, "Player"
HostObj.SinkObjectEvents CurrentDisplay, "Display"

HostObj.ConnectEventsNow()




Title: Re: Keyboard input and Do loops
Post by: bluemonkmn on 2007-02-24, 08:11:45 AM
1) You can access the sprite that the project defines as the current player sprite for the current map with: ProjectObj.GamePlayer.PlayerSprite.  The properties and methods of PlayerSprite are listed under the definition "Sprite Object" in the scripting reference.  From there you can also access the sprite's definition (which includes the name) and template.  DX and DY are the speed of the sprite and are right on the Sprite Object.

2)  If you want to enumerate other sprites on the player sprite's layer, you can use:
Code: [Select]
Dim Idx, Player2
Set Player2 = Nothing
With ProjectObj.GamePlayer.PlayerSprite.rDef.rLayer
   For Idx = 0 To .SpriteCount - 1
      If .Sprite(Idx).rDef.Name = "Player2" Then Set Player2 = .Sprite(Idx)
   Next
End With
That example shows how you could look through all the sprites in the layer to find one whose definition is named "Player2".  If it finds one, it stored it in a variable called Player2 which you can then use directly.  If you want to check if any Player2 sprite was found, you can use:
If Player2 Is Nothing Then ' Player 2 doesn't exist

3) You don't need to maintain a key() array to track what keys the player is pressing.  The player object does that for you.  If you want to see if the default player is pressing up:
If (ProjectObj.GamePlayer.CtlActions And 1) <> 0 Then ' Player is pressing up
Did you see the 2-player demo project?
Title: Re: Keyboard input and Do loops
Post by: dutch_619 on 2007-02-24, 06:42:42 PM
I've been using the "GoldYoink" and the 2 player demo as references for how SGDK handles Vb scripting. I keep trying to do things as I would in C++ and it tends to louse things up.

The up side is that I now have a semi-functional script for my game. As soon as I add some functionality and another level or two I think I'll be done. Thanks for the help, it's been appreciated.
Title: Re: Keyboard input and Do loops
Post by: dutch_619 on 2007-03-13, 08:02:47 AM
Still having problems with my script.

Here's what I'm trying at present

Code: [Select]
Sub Player_OnControllerMove(OldActions, NewActions)
If (Not OldActions) And NewActions And ACTION_UP Then DoSpriteAccelerate
                If (Not OldActions) And NewActions And ACTION_DOWN  Then DoSpriteDeccelerate
                If Not (Not OldActions) And (Not NewActions) And ACTION_DOWN Then DoSpriteSteady
                If Not (Not OldActions) And (Not NewActions) And ACTION_UP Then DoSpriteSteady

End Sub

Sub DoSpriteAccelerate
Dim DX, DY, oPlayerSprite
Set oPlayerSprite = ProjectObj.GamePlayer.PlayerSprite
 With ProjectObj.GamePlayer.PlayerSprite
oPlayerSprite.X =.X + (.Width -oPlayerSprite.Width)/2
oPlayerSprite.Y =.Y + (.Width -oPlayerSprite.Width)/2
   GetStateDeltas DX, DY
oPlayerSprite.DX = (DX * oPlayerSprite.rDef.Template.MoveSpeed) * 1.2
oPlayerSprite.DY = (DY * oPlayerSprite.rDef.Template.MoveSpeed) * 1.2
If oPlayerSprite.rDef.Template.StateCount = 36 Then oPlayerSprite.CurState = RectToPolarState(DX, DY)
 End With
End Sub


Sub DoSpriteDeccelerate
Dim DX, DY, oPlayerSprite
Set oPlayerSprite = ProjectObj.GamePlayer.PlayerSprite
 With ProjectObj.GamePlayer.PlayerSprite
oPlayerSprite.X =.X + (.Width -oPlayerSprite.Width)/2
oPlayerSprite.Y =.Y + (.Width -oPlayerSprite.Width)/2
   GetStateDeltas DX, DY
oPlayerSprite.DX = (DX * oPlayerSprite.rDef.Template.MoveSpeed) * .8
oPlayerSprite.DY = (DY * oPlayerSprite.rDef.Template.MoveSpeed) * .8
If oPlayerSprite.rDef.Template.StateCount = 36 Then oPlayerSprite.CurState = RectToPolarState(DX, DY)
 End With
End Sub


Sub DoSpriteSteady
Dim DX, DY, oPlayerSprite 
Set oPlayerSprite = ProjectObj.GamePlayer.PlayerSprite
 With ProjectObj.GamePlayer.PlayerSprite
'oPlayerSprite.X =.X + (.Width -oPlayerSprite.Width)/2
'oPlayerSprite.Y =.Y + (.Width -oPlayerSprite.Width)/2
   GetStateDeltas DX, DY
oPlayerSprite.DX = (DX * oPlayerSprite.rDef.Template.MoveSpeed)
oPlayerSprite.DY = (DY * oPlayerSprite.rDef.Template.MoveSpeed)
If oPlayerSprite.rDef.Template.StateCount = 36 Then oPlayerSprite.CurState = RectToPolarState(DX, DY)
 End With
End Sub


Function GetStateDeltas(DX, DY)
With ProjectObj.GamePlayer.PlayerSprite
Select Case .rDef.Template.StateType
Case STATE_SINGLE
If Abs(DX) + Abs(DY) > 1 Then
DX = .DX / (Abs(.DX) + Abs(.DY))
DY = .DY / (Abs(.DX) + Abs(.DY))
Else
If Abs(DX) + Abs(DY) < 1 Then DX = 0 : DY = -1
End If
Case STATE_LEFT_RIGHT
DY = 0
If (.CurState Mod 2) = 0 Then DX = -1 Else DX = 1
Case STATE_8_DIRECTION
Select Case (.CurState Mod 8)
Case 0 : DX = 0 : DY = -1
Case 1 : DX = 1 : DY = -1
Case 2 : DX = 1 : DY = 0
Case 3 : DX = 1 : DY = 1
Case 4 : DX = 0 : DY = 1
Case 5 : DX = -1 : DY = 1
Case 6 : DX = -1 : DY = 0
Case 7 : DX = -1 : DY = -1
End Select
Case Else
DX = Cos((.CurState Mod 36) * 3.14159 / 18)
DY = -Sin((.CurState Mod 36) * 3.14159 / 18)
End Select
End With
End Function


Function RectToPolarState(X, Y)
Dim Angle, Pi
Pi = 3.14159
If X <> 0 Then
Angle = Atn(-Y / X)
Else
Angle = -(Pi / 2) * Sgn(Y)
End If
If X < 0 Then
Angle = Pi + Angle
ElseIf Y > 0 Then
Angle = Pi * 2 + Angle
End If
RectToPolarState = ((Angle * 18) / Pi) Mod 36
End Function





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






Unfortunately I can't think of an easy way to adjust the direction of the sprite. I think maybe call a Function with an added value to the angle variable in a custom based off of the Function used in the script wizard. I know this a terribly ugly way to code this, but I still have trouble with how Gamedev interacts with the sprite definitions.
Title: Re: Keyboard input and Do loops
Post by: dutch_619 on 2007-03-13, 04:55:57 PM
I added this to handle the key config, and it works, but the player sprite is inert so it doesn't know how to handle the keyleft or keyright keypresses.

Code: [Select]
Sub Player_OnPlayInit
   With ProjectObj.GamePlayer
KeyUp = 38
KeyLeft = 37
KeyRight = 39
KeyDown = 40
KeyBtn1 = 17
KeyBtn2 = 32
KeyBtn3 = 16
KeyBtn4 = 13
End With
End Sub



Hmm, maybe I should just call a special function that changes the sprite templates maxspeed when keyup or keydown are pressed. Then I can leave the sprite controlled by the input device.

I still need to add some code that calls the template modifying code only when the sprite is one of a certain group of names.
Title: Re: Keyboard input and Do loops
Post by: bluemonkmn on 2007-03-13, 05:03:18 PM
All you need to do to set the direction of the sprite is set the CurState property to a number from 0 to 35.  The number represents the angle in degrees divided by 10.  So if you want the sprite to point right, set CurState to 0.  If you want it to point up, set it to 9, etc.
Title: Re: Keyboard input and Do loops
Post by: dutch_619 on 2007-03-13, 05:16:41 PM
Hmm so I pull the sprite state and increment or decrement it.

something like this
Code: [Select]
Sub DoSpriteTurnLeft
Dim oPlayerSprite, nStateInt
Set oPlayerSprite = ProjectObj.GamePlayer.PlayerSprite
With ProjectObj.GamePlayer.PlayerSprite
     Let oPlayerSprite.CurState = nStateInt
          If nStateInt = 0 Then
               Set PlayerSprite.CurState = 35
          If nStateInt > 0 Then
               Set PlayerSprite.CurState = nStateInt - 1
End With
End Sub


Sub DoSpriteTurnRight
Dim oPlayerSprite, nStateInt
Set oPlayerSprite = ProjectObj.GamePlayer.PlayerSprite
With ProjectObj.GamePlayer.PlayerSprite
     Let oPlayerSprite.CurState = nStateInt
          If nStateInt = 35 Then
               Set PlayerSprite.CurState = 0
          If nStateInt < 35 Then
               Set PlayerSprite.CurState = nStateInt + 1
End With
End Sub
End Sub
Title: Re: Keyboard input and Do loops
Post by: dutch_619 on 2007-03-13, 11:16:46 PM
Not working. I get an error message saying "Object oPlayerSprite required" and the line it fails at. I defined oPlayerSprite in the sub, and referenced it to  ProjectObj.GamePlayer.PlayerSprite which means it should be pulling the state of the active playable sprite, no?

I could probably do away with the nStateInt variable and change the current state directly I suppose. I don't think thats the problem however.

Any ideas?

I must admit to having fun with this. It's always nice to take out a new toy and dirty it up a bit.
Title: Re: Keyboard input and Do loops
Post by: bluemonkmn on 2007-03-14, 05:21:25 AM
Kinda (not quite right), but that code can be significantly simplified too.  Here's how I'd try it:
Code: [Select]
Sub DoSpriteTurnLeft
With ProjectObj.GamePlayer.PlayerSprite
     .CurState = (.CurState + 1) Mod 36
End With
End Sub

Sub DoSpriteTurnRight
With ProjectObj.GamePlayer.PlayerSprite
     .CurState = (.CurState + 35) Mod 36
End With
End Sub
Title: Re: Keyboard input and Do loops
Post by: dutch_619 on 2007-03-14, 03:42:36 PM
Here's the problem I guess
Quote
Mod 36

I thought it was the modulus operator for the function. This avoids the divide by zero error I was trying to avoid by only having it increment if it was 34 or less as well.

Is the .CurState an extension of the ProjectObj.GamePlayer.PlayerSprite object?

I had to add a bit to change the DX and DY of the sprite when the state changes. Tha code looks like this
Code: [Select]
Sub DoSpriteLeft
Dim DX, DY, oPlayerSprite
Set oPlayerSprite = ProjectObj.GamePlayer.PlayerSprite
 With ProjectObj.GamePlayer.PlayerSprite
  .CurState = (.CurState + 1) Mod 36 'line 60
GetStateDeltas DX, DY
oPlayerSprite.DX = (DX * oPlayerSprite.rDef.Template.MoveSpeed)
oPlayerSprite.DY = (DY * oPlayerSprite.rDef.Template.MoveSpeed)
If oPlayerSprite.rDef.Template.StateCount = 36 Then oPlayerSprite.CurState = RectToPolarState(DX, DY)
   End With
End Sub

Sub DoSpriteRight
Dim DX, DY, oPlayerSprite
Set oPlayerSprite = ProjectObj.GamePlayer.PlayerSprite
 With ProjectObj.GamePlayer.PlayerSprite
     .CurState = (.CurState +35) Mod 36
GetStateDeltas DX, DY
oPlayerSprite.DX = (DX * oPlayerSprite.rDef.Template.MoveSpeed)
oPlayerSprite.DY = (DY * oPlayerSprite.rDef.Template.MoveSpeed)
If oPlayerSprite.rDef.Template.StateCount = 36 Then oPlayerSprite.CurState = RectToPolarState(DX, DY)
    End With
End Sub

The trouble is every time it crosses state 0 I get a "subscript out of range error"

I guess It is incrementing outside of the range, but as before, doesn't the mod operator set the max value to 35? It should then roll back through the range, right?
Title: Re: Keyboard input and Do loops
Post by: bluemonkmn on 2007-03-14, 05:58:50 PM
1. Why are you checking "If oPlayerSprite.rDef.Template.StateCount = 36" -- isn't it always 36?  This code doesn't work if you're not using it on a 36-state rotating sprite.

2. Yes, when you have code between a "With" and an "End With" anything beginning with a "." is an extension to the With expression.  Therefore you don't need oPlayerSprite.  You can simply check "If .rDef.Template.StateCount = 36", and set ".CurState = RectToPolarState(DX, DY)"

3) Yes, Mod is the modulus operator, so the result should always be from 0 to 35.  Perhaps the code ran on a sprite with less than 36 states?
Title: Re: Keyboard input and Do loops
Post by: dutch_619 on 2007-03-15, 07:33:16 AM
Quote
2. Yes, when you have code between a "With" and an "End With" anything beginning with a "." is an extension to the With expression.  Therefore you don't need oPlayerSprite.  You can simply check "If .rDef.Template.StateCount = 36", and set ".CurState = RectToPolarState(DX, DY)"

Everything became much clearer quite suddenly! Between the VBScript help files on MSDN and what I know of database programming I'm finally making some progress here. Plus finally getting how the objects and variables are tree-ed (sic) helps too.

I still have trouble with the capturing key-presses. I'm trying to set it up so that the sub runs while the key is pressed and only while the key is pressed (regardless of the other keys states). I want it to run another sub (Sub DoSpriteSteady) while neither the up or down key is pressed. I can get the first part to work, but I seem to have difficulting XOr-ing the subs.

Plus, I still get a subscript out of range when I rotate the sprite past 180 degrees. I'm wondering if maybe it due to the way the sprite is set up. I have a 36 state player sprite, I started the sprite facing left, then clicked the "36 state button" and the error always occurs while the sprite moves through the left facing state. That should be state 18 (?) starting from zero, so it should be within the boundary of the array.

Anyway, here's what I have at present (minus the additions for checking to see if a key is held down)


Code: [Select]
Sub Player_OnControllerMove(OldActions, NewActions)
If ProjectObj.GamePlayer.rMap.Name = "RB1-1" Then
If (Not OldActions) And NewActions And ACTION_UP Then DoSpriteAccelerate
If (Not OldActions) And NewActions And ACTION_DOWN  Then DoSpriteDeccelerate
If (Not OldActions) And NewActions And ACTION_LEFT Then DoSpriteLeft
If (Not OldActions) And NewActions And ACTION_RIGHT Then DoSpriteRight
        End If
End Sub

 
Sub DoSpriteAccelerate
Dim DX, DY
 With ProjectObj.GamePlayer.PlayerSprite
  .rDef.Template.MoveSpeed = 15
.X =.X + (.Width -.Width)/2
.Y =.Y + (.Width -.Width)/2
GetStateDeltas DX, DY
.DX = (DX * .rDef.Template.MoveSpeed)
.DY = (DY * .rDef.Template.MoveSpeed)
.CurState = RectToPolarState(DX, DY)
 End With
End Sub

'Sub DoSpriteSteady
'Dim DX, DY
' With ProjectObj.GamePlayer.PlayerSprite
' .rDef.Template.MoveSpeed = 11
' .X =.X + (.Width -.Width)/2
' .Y =.Y + (.Width -.Width)/2
' GetStateDeltas DX, DY
' .DX = (DX * .rDef.Template.MoveSpeed)
' .DY = (DY * .rDef.Template.MoveSpeed)
' .CurState = RectToPolarState(DX, DY)
' End With
'End Sub

Sub DoSpriteDeccelerate
Dim DX, DY
With ProjectObj.GamePlayer.PlayerSprite
.rDef.Template.MoveSpeed = 8
.X =.X + (.Width -.Width)/2
.Y =.Y + (.Width -.Width)/2
GetStateDeltas DX, DY
.DX = (DX * .rDef.Template.MoveSpeed)
.DY = (DY * .rDef.Template.MoveSpeed)
.CurState = RectToPolarState(DX, DY)
End With
End Sub

Sub DoSpriteLeft
Dim DX, DY
  With ProjectObj.GamePlayer.PlayerSprite
  .CurState = (.CurState + 1) Mod 36 'line 60
GetStateDeltas DX, DY
.DX = (DX * .rDef.Template.MoveSpeed)
.DY = (DY * .rDef.Template.MoveSpeed)
.CurState = RectToPolarState(DX, DY)
End With
End Sub

Sub DoSpriteRight
Dim DX, DY
  With ProjectObj.GamePlayer.PlayerSprite
.CurState = (.CurState +35) Mod 36
GetStateDeltas DX, DY
.DX = (DX * .rDef.Template.MoveSpeed)
.DY = (DY * .rDef.Template.MoveSpeed)
.CurState = RectToPolarState(DX, DY)
  End With
End Sub

Function GetStateDeltas(DX, DY)
With ProjectObj.GamePlayer.PlayerSprite
Select Case .rDef.Template.StateType
Case STATE_SINGLE
If Abs(DX) + Abs(DY) > 1 Then
DX = .DX / (Abs(.DX) + Abs(.DY))
DY = .DY / (Abs(.DX) + Abs(.DY))
Else
If Abs(DX) + Abs(DY) < 1 Then DX = 0 : DY = -1
End If
Case STATE_LEFT_RIGHT
DY = 0
If (.CurState Mod 2) = 0 Then DX = -1 Else DX = 1
Case STATE_8_DIRECTION
Select Case (.CurState Mod 8)
Case 0 : DX = 0 : DY = -1
Case 1 : DX = 1 : DY = -1
Case 2 : DX = 1 : DY = 0
Case 3 : DX = 1 : DY = 1
Case 4 : DX = 0 : DY = 1
Case 5 : DX = -1 : DY = 1
Case 6 : DX = -1 : DY = 0
Case 7 : DX = -1 : DY = -1
End Select
Case Else
DX = Cos((.CurState Mod 36) * 3.14159 / 18)
DY = -Sin((.CurState Mod 36) * 3.14159 / 18)
End Select
End With
End Function

Function RectToPolarState(X, Y)
Dim Angle, Pi
Pi = 3.14159
If X <> 0 Then
Angle = Atn(-Y / X)
Else
Angle = -(Pi / 2) * Sgn(Y)
End If
If X < 0 Then
Angle = Pi + Angle
ElseIf Y > 0 Then
Angle = Pi * 2 + Angle
End If
RectToPolarState = ((Angle * 18) / Pi) Mod 36
End Function


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


If I haven't said so before, thanks for all the help!
Title: Re: Keyboard input and Do loops
Post by: bluemonkmn on 2007-03-15, 09:41:46 AM
Check your sprite definition.  If you started it facing left, you probably only got half the states because left is half way through the whole rotation cycle.  It should start facing right.  So it maybe didn't create any states for facing up (from facing right, through facing up to facing left).
Title: Re: Keyboard input and Do loops
Post by: dutch_619 on 2007-03-15, 05:29:58 PM
The sprite was of a "simple" type and It was set to delete when off map. Once I changed it to inert and "auto-delete = never" the "subscript out of range" fail disappeared. I don't exactly see why either of those would cause it to crash, but.... as long as it works I guess.

The problem I had with key-presses was linked to the sprites inertia settings. It seemed it was actually working as intended, but the speed change was too slow to notice.

As an aside, I don't suppose you would care to put this script on the examples page (with comments added to the code) for the next person who cares to do something of this sort? It is hard to find code snippets in the forums at times.

Additionally, a bit of advice to others, constant backups are your friends! Not weekly, or daily backups; but after any major change! It may eat up disk space, but magnetic memory is cheap, use the space.
Title: Re: Keyboard input and Do loops
Post by: bluemonkmn on 2007-03-16, 04:59:01 AM
You should be able to submit new documentation with the "Submit new documentation" link at http://sourceforge.net/docman/?group_id=9970 (http://sourceforge.net/docman/?group_id=9970).  I don't know if anyone has tried this yet, but I'm willing to post your document if you want to submit one.  Let me know if/when you submit something -- I'm not sure how/if SourceForge would notify me.