Multi-touch detection on touch-screen devices C + + code implementation

Source: Internet
Author: User

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-&GT;ORIGIN.Y *viewportsize.y); ConstUInt32 Viewbottom = viewtop + fmath::trunctoint (LOCALPLAYER-&GT;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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.