Author Topic: Keyboard input and Do loops  (Read 10437 times)

dutch_619

  • Regular
  • **
  • Posts: 90
    • View Profile
    • Email
Re: Keyboard input and Do loops
« Reply #15 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.

bluemonkmn

  • SGDK Author
  • Administrator
  • Fanatic
  • *****
  • Posts: 2761
    • ICQ Messenger - 2678251
    • MSN Messenger - BlueMonkMN@gmail.com
    • View Profile
    • http://sgdk2.sf.net/
    • Email
Re: Keyboard input and Do loops
« Reply #16 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

dutch_619

  • Regular
  • **
  • Posts: 90
    • View Profile
    • Email
Re: Keyboard input and Do loops
« Reply #17 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?
« Last Edit: 2007-03-14, 04:28:29 PM by dutch_619 »

bluemonkmn

  • SGDK Author
  • Administrator
  • Fanatic
  • *****
  • Posts: 2761
    • ICQ Messenger - 2678251
    • MSN Messenger - BlueMonkMN@gmail.com
    • View Profile
    • http://sgdk2.sf.net/
    • Email
Re: Keyboard input and Do loops
« Reply #18 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?

dutch_619

  • Regular
  • **
  • Posts: 90
    • View Profile
    • Email
Re: Keyboard input and Do loops
« Reply #19 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!

bluemonkmn

  • SGDK Author
  • Administrator
  • Fanatic
  • *****
  • Posts: 2761
    • ICQ Messenger - 2678251
    • MSN Messenger - BlueMonkMN@gmail.com
    • View Profile
    • http://sgdk2.sf.net/
    • Email
Re: Keyboard input and Do loops
« Reply #20 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).

dutch_619

  • Regular
  • **
  • Posts: 90
    • View Profile
    • Email
Re: Keyboard input and Do loops
« Reply #21 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.

bluemonkmn

  • SGDK Author
  • Administrator
  • Fanatic
  • *****
  • Posts: 2761
    • ICQ Messenger - 2678251
    • MSN Messenger - BlueMonkMN@gmail.com
    • View Profile
    • http://sgdk2.sf.net/
    • Email
Re: Keyboard input and Do loops
« Reply #22 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.  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.