Automatic place char. into keyboard buffer?
Blitz3D Forums/Blitz3D Beginners Area/Automatic place char. into keyboard buffer?
| ||
Hi all, We could use keydown/keyhit to check if a key is pressed. If we want to create a automatic run demo and want blitz3D automatic place char. into keyboard buffer, how to do this? (eg. Blitz3D automatically "press" S to start demo. "press" X to exit, etc., instead of manually pressing S and X directly) Any ideas? Thanks in advance. Sammy :) |
| ||
I think it's a bit overkill trying to put chars into the keyboard buffer without keypresses. Why not simply set a constant to determine whether in demo mode or not. const Demo = true StartGame = ( keydown( S_Key ) or Demo ) EndGame = ( keydown( X_Key ) or Demo ) Stevie |
| ||
Hi Stevie G, Thank you for your reply. Here is the solution: http://www.blitzbasic.com/codearcs/codearcs.php?code=1227 Sammy :) |
| ||
Using a DLL for something which can be acheived with a simple workaround is OTT if you ask me. Whatever floats your boat though. |
| ||
Agreed, it's completely unnecessary, if you're having to manually input data into the keyboard buffer, you probably need to rethink the whole problem and start again from a different angle... |
| ||
Hi Stevie G and Jams, The virtual key is needed because I DON'T want to manually input data into the keyboard buffer. I don't type 'S' and 'X'. Let Blitz3D do it for me. The function is useful when you run a auto-play demo. eg. when you enter old doom game and leave it there, after a while, it will play automatically. Thanks Sammy :) |
| ||
That's not what i meant! Think of it like this.... pressing a key on the keyboard invokes some kind of response in your code (a function or whatever). Now you want to have that same response without a keypress.... so just call the function! |
| ||
sometimes it's useful when you want to control an external exe. Like clicking away a welcome message popup etc. |
| ||
The function is useful when you run a auto-play demo. eg. when you enter old doom game and leave it there, after a while, it will play automatically. I fail to see how this relies on writing virtual keypresses to the keyboard buffer. The doom demo started after a certain period of time ... it's that simple. I can see the relevance of using this DLL in Jfk's example above as you can not do this without an external library. However, for your usage I have to agree completely with Jams. Now you want to have that same response without a keypress.... so just call the function! Stevie |
| ||
>The virtual key is needed because I DON'T want >to manually input data into the keyboard buffer. >I don't type 'S' and 'X'. Let Blitz3D do it for me. The virtual key is not needed in that situation. You simply do as Stevie G suggested above. >The function is useful when you run a auto-play demo. >eg. when you enter old doom game and leave it there, >after a while, it will play automatically. You just use a timer and act on this timer in an IF...THEN structure. The reason people are all over you, is because you are using a complicated and unnessesary solution instead of a few lines of B3D code. Andy |
| ||
I think there are many misunderstandings in this thread. I guess Sammy was talking about a replay mode as seen in certain games. Replay or demo modes simply emulate keyhits and mouse action by "feeding" their Input Routines alternatively with data when in demo mode instead of user input. eg: if replay_mode=0 mxs#=mousexspeed()/4.0 turnentity camera,0,mxs#,0 mxs_array#(c)=mxs# c=c+1 else mxs#=mxs_array#(c) turnentity camera,0,mxs#,0 c=c+1 endif In the first case (play mode) the camera rotation is controlled by the mouse, additionally the rotation is stored in an array In the ELSE case (replay mode) the camera rotation is controlled by the array data, containing previously stored mouse actions. Every User Action can be stored this way. When recording and replaying, the same constant framerate should be used to keep things simple. If delta timing etc. is used and a constant framerate is not possible, a slightly more complicated solution is required, utilizing realtime sequencing. Furthermore the usage of random values (Rand and Rnd) can be tricky. In theory they can be used if they are initialized with the same seed everytime, but that's probably only theory :) For a fixed demomode sequence the array may be saved to a file that is loaded by default. |
| ||
Even with your example, there's still no need to shove the data into the keyboard buffer, it's completely unnecessary. I think it's a symptom of a poorly coded engine... if all your actions lie inside "if Keyhit(blah) then" blocks then this would seem like the obvious solution. Far better would be to bind keyhits to specific functions, then when you want to simulate a keyhit, just call that function... |
| ||
Hi all, Thank you for your reply. If I MANUALLY input data into the program, I would use "if keyhit(blah) then" blocks for data input. Sammy :) |
| ||
>If I MANUALLY input data into the program, >I would use "if keyhit(blah) then" blocks for data input. You are not understanding what people are saying to you. There is no difference whether is is MANUAL or AUTOMATIC. If you have a variable called demo, and you add something like what Stevie G suggested, then you get automatic demo mode without using a DLL. When you use a dll, you inherit a lot of properties. You become responsible to your customers for the dll and what it does to the customers system. Programming is not just about making the computer do what you want, but also to do it in a way which is simple and efficient both to you and to the user. You won't notice the difference now, and you propably don't understand why people are all over you for this, but using a DLL for something which can easilly be achieved with a few lines of code is silly, inefficient and a waste of your time. If you don't understand how to do the same in B3D without using a DLL, then just ask. I'm sure everyone here would be more than helpful in that case. Simple beats complex almost every time. I applaud your effort to learn B3D. Andy |
| ||
Hi all, Thank you for your reply and patience. Assuming the following configuration: W - move forward A - move left S - move backward D - move right Assuming you want your player to move in this way.. WWASSSDWWWWWWWWWWAAWWWWAAAASSWWDDD.... (2000 keystrokes) (forward, forward, left, backward, backward, backward, right, forward,...) This keystrokes are saved in a file. The pseduo code should be something like this: while not end of file reading a char. into letter$ select letter$ case "W" ; codes for moving forward case "A" ; codes for moving left case "S" ; codes for moving backward case "D" ; codes for moving right end select wend Later, you change your mind, you want this: SWSDDSSDASSSSSSSSSSDDDSSSWWWSSDDD........ (2000 keystrokes) (backward, forward, backward, right, right, ...) With virtual key, you do NOT need to change a single line of code. You just change the file content with keystrokes, then ok. It seems that with other method mentioned, I have to change large amount of codes to do the same thing. This is how I understand the use of virtual key. Thanks in advance. Sammy :) |
| ||
No you don't have to change the code at all. All you have to change is the file. In my Blood and Plunder Gauntlet Clone for the replay I did as the others have suggested: In 'record' mode store each action/button press in a 'type', at the end of the session save the data out to a file. Then when in demo mode it would read in the data into a 'type' then act on those actions in sequence during the demo. No code needs to be changed. You will have to change the data file's contents regardless of whether you use virtual key or generate the data file by playing the game yourself or simply changing them in a text file. |
| ||
Hi all, In that case, what is the use of virtual key? I am confused??!! Sammy :) |
| ||
There is no use in this situation, that's what we've been trying to tell you... Please study this example: If DemoMode = True Command$ = ReadCommandFromFile() ;Get the next command PushKeyboardBuffer( Command$ ) ;Put data into the keyboard buffer Endif If KeyDown( KEY_UP ) Player\Y = Player\Y -1 Endif ... A much better way to do it would be like this: If DemoMode = True Command$ = ReadCommandFromFile() ;Get the next command. Select Command$ Case "KEY_UP" : PlayerMoveUp() ;Interpret command. ... End Select else If KeyDown( KEY_UP ) PlayerMoveUp() ;interpret command. Endif ... endif Function PlayerMoveUp() Player\Y = Player\Y -1 End Function ... Another problem you'll run into if you want to use the keyboard buffer to automate the demo, is that the user can still press keys on the keyboard, and they'll still get put in the buffer along with all your data. |
| ||
Jams you forgot to say what function "pushkeybordbuffer()" does, and the first If KeyDown( KEY_UP ) Player\Y = Player\Y -1 Endif doesn't make sense since you have that function "PlayerMoveUp" unless I misunderstood something. However, it may be most simple if you add a second valid condition like if ((keydown(Key_UP)) and (demo=0)) or ((k(c)=KEY_UP) and (demo=1)) where k(c) is a value taken from a file or array. Plus: I totally agree, with your second point. Also consider that keydown cannot be replaced by "inserted virtual keyhits" and keydown allows multiple keys to be pressed simultanously. |
| ||
Oops, should have mentioned that 2 codeboxes are completely seperate. <Edited :) |
| ||
Hi all, Thanks a lot. If I have more questions, I would post again. Sammy :) |