Key Code For Canvas Games (Source Included)
BlitzMax Forums/BlitzMax Programming/Key Code For Canvas Games (Source Included)
| ||
Having decided to go with canvas-style graphics, it does open up many possibilities that cannot be done easily with standard graphics. However, you cannot use simple keydown() routines in there. No, you must write a monster routine that keeps track of which keys are down AND up as both messages are sent now through a polling system. Not as easy as I thought it would be. In any case, this program I wrote works perfectly, it additionally recognizes when you use SHIFT, CTRL, and ALT for your keystrokes. Further it has a little key repeat routine. Hold down the key and it will register only once, then again, then it will be held down until you let go. If you are holding down a key and jump out of the frame, it will intelligently wait until you return and clear the keyboard queue so a key is not 'stuck' as many Windows games today have this problem. Hope This Helps ! ' Get Keys using Canvas ' Written by David W (dw817) 12-14-15 ' GetDeskTopArea written by dan_upright Import MaxGui.Drivers Strict Extern "Win32" Function SystemParametersInfoA:Int(action:Int, param:Int, param2:Byte Ptr, winini:Int) EndExtern Global a,b,c,d,e,f,g,h,i,j,kk,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z Global aa$,bb$,cc$,dd$,ee$,ff$,gg$,hh$,ii$,jj$,k$,ll$,mm$ Global nn$,oo$,pp$,qq$,rr$,ss$,tt$,uu$,vv$,ww$,xx$,yy$,zzz$ Global key:Byte[256],lastkey,keytimer,mx,my,mk Global shiftkey,ctrlkey,altkey,arrowkey,numkey Global deskrect[4] GetDesktopArea(deskrect) Global window:TGadget Global mainview:tgadget window=CreateWindow("",deskrect[0],deskrect[1],deskrect[2],deskrect[3],,WINDOW_ACCEPTFILES) mainview=createcanvas(deskrect[0]-2,deskrect[1]-1,deskrect[2]+4,deskrect[3]+3,window,1) SetGraphics canvasgraphics(mainview) activategadget mainview Flip SetBlend solidblend SetScale 10,10 Repeat nano Cls If k$>"" DrawText k$,50,50 EndIf Until k$="es" zz Function zz() End EndFunction Function nano() Global ce,cd,cx,cy,i If lastkey>0 keytimer:+1 If keytimer<50 And keytimer<>25 key[lastkey]=0 Else key[lastkey]=1 EndIf EndIf If PollEvent() ce=CurrentEvent.id cd=CurrentEvent.data cx=EventX() cy=EventY() If ce=event_windowclose Or ce=event_appterminate zz ElseIf ce=event_keydown key[cd]=1 If cd<160 Or cd>165 lastkey=cd keytimer=0 EndIf ElseIf ce=event_keyup lastkey=0 key[cd]=0 ElseIf ce=event_mousemove mx=EventX() my=EventY() ElseIf ce=event_mousedown mk=cd ElseIf ce=event_mouseup mk=0 ElseIf ce=event_appsuspend Or ce=event_mouseleave mk=0 For i=0 To 255 key[i]=0 Next ce=0 Repeat If PollEvent() ce=CurrentEvent.id EndIf Flip Flip Until ce=event_mouseenter Or ce=event_appresume k$="" lastkey=0 keytimer=0 activategadget mainview Return EndIf EndIf shiftkey=0; ctrlkey=0; altkey=0; arrowkey=0; numkey=0 If key[160]+key[161] shiftkey=1 EndIf If key[162]+key[163] ctrlkey=1 EndIf If key[164]+key[165] altkey=1 EndIf k$="" For i=48 To 57 If key[i]=1And k$="" Then k$=k$+Chr$(i);numkey=1 Next For i=65 To 90 If key[i]=1And k$="" Then k$=k$+Chr$(32+i) Next If key[8] Then k$=k$+"bs" If key[9] Then k$=k$+"ta" If key[13] Then k$=k$+"cr" If key[27] Then k$=k$+"es" If key[32] Then k$=k$+" " If key[33] Then k$=k$+"pu" If key[34] Then k$=k$+"pd" If key[35] Then k$=k$+"en" If key[36] Then k$=k$+"ho" If key[37] Then k$=k$+"lf";arrowkey=1 If key[38] Then k$=k$+"up";arrowkey=1 If key[39] Then k$=k$+"rt";arrowkey=1 If key[40] Then k$=k$+"dn";arrowkey=1 If key[45] Then k$=k$+"in" If key[46] Then k$=k$+"de" If key[107] Then k$=k$+"n+" If key[109] Then k$=k$+"n-" If key[186] Then k$=k$+";" If key[187] Then k$=k$+"=" If key[188] Then k$=k$+"," If key[189] Then k$=k$+"-" If key[190] Then k$=k$+"." If key[191] Then k$=k$+"/" If key[192] Then k$=k$+"`" If key[219] Then k$=k$+"[" If key[220] Then k$=k$+"\" If key[221] Then k$=k$+"]" If key[222] Then k$=k$+"'" If shiftkey And k$>""Then k$="#"+k$ If ctrlkey And k$>""Then k$="^"+k$ If altkey And k$>""Then k$="@"+k$ If k$="^q"Or k$="es"Then zz Flip Flip EndFunction Function getdesktoparea(lprect:Int Ptr) systemparametersinfoa(spi_getworkarea,0,lprect,0) End Function Questions, comments, compliments, or kerosene, take your pick and lemme know ! :) |
| ||
If you call EnablePolledInput(), the KeyUp/KeyDown functions should work. https://github.com/blitz-research/blitzmax/blob/master/mod/brl.mod/polledinput.mod/polledinput.bmx#L87 Also, no need to invoke SystemParametersInfo. Use DesktopWidth() and DesktopHeight(). |
| ||
For PolledInput to work really lightweight with MaxGUI you need to change the "autoPoll" private global to False. Then rebuild this brl.polledinput module. Then you can call EnablePolledInput() or EnablePolledInput( canvas ) (the latter only processes input events when they come from the canvas gadget). Then you can use KeyDown and KeyHit inside some polled updating code, usually hooked to a timer set to some frequency like 30 FPS. Besides animations and AI, you'll also process user input there. Just remember to add a PollSystem call to this main updating function before using KeyDown or KeyHit, so any pending input events are processed. EDIT: Example of all this below, in post #5. |
| ||
Kfprimm: * Tried the code of "polledinput." Doesn't seem to be getting what I want. Could you please post a working example of a held key that vanishes using canvas screen ? The desktopwidth() and company are used because I want to know the exact size of the screen minus the taskbar. If this can be done minus a library, I'm all for it. Kryzon: * I'm getting some screwy timing when I try enablepolledinput() and hold down a key for a few seconds. When I let go of the key, a message appears it was released a quarter of a second later. I'll need to stick to my code above which does handle all instances if there isn't a simpler solution out there. Or can you post an example program to demonstrate where it works in all instances, key tapped, or held ? |
| ||
Run this program and press the SPACE key. And note the module modifications at the top. |
| ||
Okay, before we go too far, Kryzon, you are using: D3D9Max2DDriver() Does this have any advantage over graphics 1024,768 or CreateCanvas ? I am using CreateCanvas because in my program I want to be able to drag an image from off of the Internet Window (using CreateHTMLView) and read it in my program. What precisely is the difference between all 3, and does D3D9Max have any advantage over any other graphic mode ? Is it faster in terms of lockimage, better, more compatible to graphic cards ? Explain. |
| ||
Do you mean, explain please? You need to get acquainted with the Max2D module and its drivers. CreateCanvas is like a call to Graphics, but instead of creating a window as a display, it creates a panel gadget as a display. You can fit this panel inside other windows and panels. If your program is running on Windows, the Direct3D 9 renderer is more likely to have a better performance. |
| ||
Sorry, please. :7 I was getting so wordsworthy in there. I guess I need to clarify something. BlitzMAX and the command FLIP create smooth graphics that use little CPU. The last time I tried BlitzBasic it staggered all over the place, no smooth motions, and pegged my CPU at 50% for what appeared to be simple animations. Is this still the case please, Kryzon - or should I abandon BlitzMAX ? |
| ||
I think it's more important to know why it staggers. In the end it's all instructions given to the machine, and if something is staggering then the instructions are causing or telling the machine to do so. If you're not interested in the internals maybe you should get a higher level engine -- that is, something that expects you to program game behaviour, rather than lower-level things like frame rate control, rendering etc. I don't mean this in a condescending way; some people prefer some tools etc. I myself only use BlitzMax to make quick utilities for me. Depending on the circumstances the Flip function in BlitzMax does some frame rate control, releasing free time to the CPU. I know this because I looked at the module source code; anyone can do it too. This isn't exclusive to BlitzMax, you can do this Flip behaviour with other game engines, even Blitz3D. |
| ||
Does Blitz3D internalize files too as BlitzMAX does ? I can currently use in BlitzMAX:global ib$="system\" ?Not debug ib$="incbin::" Incbin "media\bgm\$Good Night 1.ogg" Incbin "media\bgm\$Item 1.ogg" Incbin "media\bgm\Adventure 1.ogg" Incbin "media\bgm\Editor.ogg" Incbin "media\bgm\Village 1.ogg" Incbin "media\data\edit.var" Incbin "media\data\Home.var" Incbin "media\data\newgame.var" Incbin "media\fog\001-Fog01.jpg" Incbin "media\fog\003-Shade01.jpg" Incbin "media\font\Def_20.ttf" Incbin "media\font\Game_26.ttf" Incbin "media\font\Title_26.ttf" Incbin "media\sfx\001-System01.ogg" Incbin "media\sfx\002-System02.ogg" Incbin "media\sky\003-StarlitSky01.jpg" Incbin "media\sky\004-CloudySky01.jpg" Incbin "media\sys\Cbbgs_256x64x44.png" Incbin "media\sys\Circle.png" Incbin "media\sys\Critters_64x64x176.png" Incbin "media\sys\Energy_128x128x4.png" Incbin "media\sys\Faces_64x64x176.png" Incbin "media\sys\Frame.png" Incbin "media\sys\Glow_200x200x15.png" Incbin "media\sys\IconSet_24x24x256.png" Incbin "media\sys\Pick The Tile.png" Incbin "media\sys\Pick Tile Set.png" Incbin "media\sys\Sprites_32x32x512.png" Incbin "media\sys\SysFont_8x8x512.png" Incbin "media\sys\SysIcons_32x32x64.png" Incbin "media\sys\Tile Cursor.png" Incbin "media\sys\Tile Grid.png" Incbin "media\sys\Tiles_32x32x736.png" Incbin "media\sys\Torchlit Editor.png" Incbin "media\sys\Torchlit.png" Incbin "media\sys\Vector.png" Incbin "media\sys\View Port.png" ? And depending upon whether or not I am running in debug or final release, I can read these files internally, graphic, text, and audio, effectively protecting and hiding them. And does Blitz3D allow you to read and write individual pixels ? I do quite a bit of that in my work. I admit I am at a complete loss of understanding 3D graphics. I wrote THIS: Strict Global i,Global img:TImage=LoadImage("dogs.jpg") Graphics 1024,768 For i=0 To 383 SetScale .5+i/1024.0,1 SetViewport 0,192+i,1024,1 DrawImage img,384-i/4.0,192 Next Flip WaitKey Find test image HERE: https://lh4.ggpht.com/pYJ0w6Sy2wzZjuSSTAtCl5TtnQwT1PkUIckiIlYUequ-y61822Yf0PS6wei3k_bG68Q=h900 As a crude way of tilting an image. It works but the scaling looks off. I'd love it if I could really write a true 3D dungeon with custom images for walls that stays on a tight grid like a tiled RPG instead of all the loose movement I've seen in other 3D dungeon example programs. But I wouldn't want to be locked down to a programming language where everything is polygonal and I have no other options. I need my pixels, scaling with blur, Truetype Fonts, and CreateHTMLView. It seems if I adopt one programming language over another, I sacrifice the abilities I am familiar with, Kryzon. Please comment. Which do you think is the best of all of these worlds, Kryzon ? |