Transferred from: http://aigo.iteye.com/blog/2272698
Code or reference from Epic's Official Tower Defense Project: Strategygame
Look at the C + + API, the ready-made API seems to only support the single touch detection, the use of the following:
Registered:
// Support Touch devices This, &atd_mobileplayercontroller::movetotouchlocation); Inputcomponentthis, &atd_mobileplayercontroller::movetotouchlocation);
Trigger callback:
voidAtd_mobileplayercontroller::movetotouchlocation (ConstEtouchindex::type Fingerindex,ConstFvector location) {fvector2d screenspacelocation (location); //Trace to see what's under the touch locationFhitresult Hitresult; Gethitresultatscreenposition (Screenspacelocation, Currentclicktracechannel,true, Hitresult); if(hitresult.bblockinghit) {//We hit something, move theresetnewmovedestination (Hitresult.impactpoint); } }
If you want to achieve multi-touch detection, such as the implementation of two finger pinch to zoom the screen, Strategygame project implemented a set of algorithms to achieve multi-point screen detection, as follows:
StrategyPlayerController.h
1, first rewrite Strategyplayercontroller's Processplayerinput () and setupinputcomponent () functions
protected : /* * /virtualvoid processplayerinput (constfloat Constbooloverride; Virtual void override;
Bind the event in the Setupinputcomponent () function (the event mechanism is also written by itself), where bind_1p_action and bind_2p_action are their own defined macros:
voidastrategyplayercontroller::setupinputcomponent () {super::setupinputcomponent (); Inputhandler= Newobject<ustrategyinput> ( This); Bind_1p_action (Inputhandler, Egamekey::tap, ie_pressed,&astrategyplayercontroller::ontappressed); Bind_1p_action (Inputhandler, Egamekey::hold, ie_pressed,&astrategyplayercontroller::onholdpressed); Bind_1p_action (Inputhandler, Egamekey::hold, ie_released,&astrategyplayercontroller::onholdreleased); Bind_1p_action (Inputhandler, Egamekey::swipe, ie_pressed,&astrategyplayercontroller::onswipestarted); Bind_1p_action (Inputhandler, Egamekey::swipe, Ie_repeat,&astrategyplayercontroller::onswipeupdate); Bind_1p_action (Inputhandler, Egamekey::swipe, ie_released,&astrategyplayercontroller::onswipereleased); Bind_2p_action (Inputhandler, egamekey::swipetwopoints, ie_pressed,&astrategyplayercontroller::onswipetwopointsstarted); Bind_2p_action (Inputhandler, egamekey::swipetwopoints, Ie_repeat,&astrategyplayercontroller::onswipetwopointsupdate); Bind_2p_action (Inputhandler, Egamekey::P inch, ie_pressed,&astrategyplayercontroller::onpinchstarted); Bind_2p_action (Inputhandler, Egamekey::P inch, Ie_repeat,&astrategyplayercontroller::onpinchupdate); Finputactionbinding& toggleingamemenubinding = Inputcomponent->bindaction ("Ingamemenu", ie_pressed, This, &Astrategyplayercontroller::ontoggleingamemenu); Toggleingamemenubinding.bexecutewhenpaused=true; }
Processplayerinput () to detect touch point changes, this is a continuous execution of the function, the approximate logic is: Each execution will be the current screen touch information and the last touch information to do a comparison, detection is a single touch, or hold, or multi-touch or multi-point hold on and so on, Specific logic in inputhandler->updatedetection(deltatime);
voidAstrategyplayercontroller::P rocessplayerinput (Const floatDeltatime,Const BOOLbgamepaused) { if(!bgamepaused && playerinput && inputhandler &&!)bignoreinput) {Inputhandler-updatedetection (deltatime); } Super::P rocessplayerinput (Deltatime, bgamepaused); if(!bignoreinput) { Constulocalplayer* Localplayer = cast<ulocalplayer>(Player); Astrategyspectatorpawn* Strategypawn =Getstrategyspectatorpawn (); if((Strategypawn! = NULL) && (localplayer! =NULL)) { //Create the bounds for the minimap so we can add it as a ' no scroll ' zone. astrategyhud*ConstHUD = cast<astrategyhud>(Gethud ()); AstrategygamestateConst*ConstMygamestate = Getworld ()->getgamestate<astrategygamestate>(); if((mygamestate! = NULL) && (mygamestate->minimapcamera.isvalid () = =true ) ) { if(Localplayer->viewportclient! =NULL) { ConstFintpoint viewportsize = localplayer->viewportclient->viewport->getsizexy (); ConstUInt32 viewtop = Fmath::trunctoint (LOCALPLAYER->ORIGIN.Y *viewportsize.y); ConstUInt32 Viewbottom = viewtop + fmath::trunctoint (LOCALPLAYER->SIZE.Y *viewportsize.y); Fvector TopLeft (HUD->minimapmargin, Viewbottom-hud->minimapmargin-mygamestate->minimapcamera->minimapheight,0 ); Fvector BottomRight ((Int32) Mygamestate->minimapcamera->minimapwidth, Mygamestate->minimapcamera->minimapheight,0 ); Fbox minimapbounds (topleft, TopLeft+bottomright); Strategypawn->getstrategycameracomponent ()Addnoscrollzone (minimapbounds); Strategypawn->getstrategycameracomponent ()->updatecameramovement ( This ); } } } } }
StrategyInput.cpp
voidUstrategyinput::updatedetection (floatdeltatime) {Updategamekeys (deltatime); Processkeystates (deltatime); } voidUstrategyinput::updategamekeys (floatdeltatime) {Astrategyplayercontroller* Mycontroller = castchecked<astrategyplayercontroller>(Getouter ()); //gather current statesUInt32 currenttouchstate =0; for(Int32 i =0; I < Array_count (mycontroller->playerinput->touches); i++) { if(Mycontroller->playerinput->touches[i]. Z! =0) {currenttouchstate|= (1<<i); } } //Detectionfvector2d LocalPosition1 = fvector2d (mycontroller->playerinput->touches[0]); Fvector2d LocalPosition2= Fvector2d (mycontroller->playerinput->touches[1]); Detectonepointactions (Currenttouchstate&1, Prevtouchstate &1, Deltatime, LocalPosition1, touchanchors[0], touch0downtime); Detecttwopointsactions ((Currenttouchstate&1) && (Currenttouchstate &2), (Prevtouchstate &1) && (Prevtouchstate &2), Deltatime, LocalPosition1, LocalPosition2); //save statesPrevtouchstate =currenttouchstate; } voidUstrategyinput::P rocesskeystates (floatdeltatime) { for(Constfactionbinding1p&ab:actionbindings1p) { Constfsimplekeystate* KeyState =Keystatemap.find (AB. Key); if(KeyState && Keystate->events[ab. KeyEvent] >0) {AB. Actiondelegate.executeifbound (KeyState->position, keystate->downtime); } } for(Constfactionbinding2p&ab:actionbindings2p) { Constfsimplekeystate* KeyState =Keystatemap.find (AB. Key); if(KeyState && Keystate->events[ab. KeyEvent] >0) {AB. Actiondelegate.executeifbound (KeyState->position, Keystate->position2, keystate->downtime); } } //update states for(Tmap<egamekey::type,fsimplekeystate>::titerator It (KEYSTATEMAP); It; ++It) {Fsimplekeystate*ConstKeyState = &It.value (); if(keystate->events[ie_pressed]) {KeyState->bdown =true; } Else if(keystate->events[ie_released]) {KeyState->bdown =false; } Fmemory::memzero (KeyState->events,sizeof(keystate->Events)); } }
Multi-touch detection on touch-screen devices for C + + code implementation