I have 5 images stacked in the bottom of my screen. My game's aim is to drag these images and connect them on certain conditions.(Sort of jigsaw puzzle)
I used the following code
var touchListener = new CCEventListenerTouchAllAtOnce ();
touchListener.OnTouchesEnded = OnTouchesEnded;
touchListener.OnTouchesMoved = HandleTouchesMoved;
AddEventListener (touchListener, this);
void HandleTouchesMoved (List touches, CCEvent touchEvent)
{
foreach(var tap in touches)
{
var locationOnScreen = tap.Location;
alarmicSprite.PositionY = locationOnScreen.Y;
alarmicSprite.PositionX = locationOnScreen.X;
pressSwitchSprite.PositionY = locationOnScreen.Y;
pressSwitchSprite.PositionX = locationOnScreen.X;
}
}
This code moves all images at once to the touched coordinates. My requirement is to get one image dragged at a time unlike all at once. Cocossharp API and tutorials given in Xamarin and Github in my mind is not that helpful.
Is there a method which allows to drag one image on one touch instance?
Help appreciated
Here is an example that creates two sprites and lets you drag them individually.
Design:
- You need to detect which sprite is being touched and then only move that sprite.
- Save the sprite being touched in OnTouchesBegan
- Move the currently touched sprite in OnTouchesMoved
Notes:
- The OnTouchesBegan is called once for EVERY sprite that registers for the event. So if 20 sprites add the listener, the OnTouchesBegan event is called 20 times (unless swallowed, see below)
- Programmatically you determine if the touch position is inside the bounding box of the sprite calling OnTouchesBegan. However "Swallowing" the touch will stop any remaining queued up calls to it. To swallow, just return true.
Once you find the the sprite of interest, you return true to "swallow" the touch event and stop the rest of the sprites from calling back. This saves cpu and executes your OnTouchesMoved sooner. The system will not call OnTouchesMoved until it is completely done dealing with OnTouchesBegan.
CCSprite currentSpriteTouched;
CCSprite Sprite1;
CCSprite Sprite2;
protected override void AddedToScene()
{
base.AddedToScene();
// Use the bounds to layout the positioning of our drawable assets
CCRect bounds = VisibleBoundsWorldspace;
Sprite1 = new CCSprite("redball.png");
Sprite2 = new CCSprite("blueball.png");
Sprite1.Position = bounds.Center;
Sprite2.Position = bounds.Center;
AddChild(Sprite1);
AddChild(Sprite2);
// Register for touch events
var touchListener = new CCEventListenerTouchOneByOne();
touchListener.IsSwallowTouches = true;
touchListener.OnTouchBegan = this.OnTouchesBegan;
touchListener.OnTouchMoved = this.OnTouchesMoved;
AddEventListener(touchListener, Sprite2);
AddEventListener(touchListener.Copy(), Sprite1);
}
void OnTouchesMoved(CCTouch touch, CCEvent touchEvent)
{
if (currentSpriteTouched != null)
{
currentSpriteTouched.Position = touch.Location;
}
}
bool OnTouchesBegan(CCTouch touch, CCEvent touchEvent)
{
// This is called once for each sprite
// To stop the remaining sprites from calling,
// "swallow" the touch by returning true
CCSprite caller = touchEvent.CurrentTarget as CCSprite;
currentSpriteTouched = null;
if (caller == Sprite1)
{
if (Sprite1.BoundingBoxTransformedToWorld.ContainsPoint(touch.Location))
{
System.Diagnostics.Debug.WriteLine("Sprite 1 touched ");
currentSpriteTouched = Sprite1;
return true; // swallow
}
else
{
return false; // do not swallow and try the next caller
}
}
else if (caller == Sprite2)
{
if (Sprite2.BoundingBoxTransformedToWorld.ContainsPoint(touch.Location))
{
currentSpriteTouched = Sprite2;
System.Diagnostics.Debug.WriteLine("Sprite 2 touched ");
return true; // swallow
}
else
{
return false; // do not swallow and try the next caller
}
}
else
{
// something else touched
System.Diagnostics.Debug.WriteLine("Something else was touched");
return false; // Do not swallow
}
}
I followed this link TouchableSpriteTest and achieved my required functionality(with help from jaybers)
Sample code
protected override void AddedToScene ()
{
--------------------------
--------------------------
// Register for touch events
var touchListener = new CCEventListenerTouchOneByOne ();
touchListener.IsSwallowTouches = true;
touchListener.OnTouchBegan = OnTouchBegan;
touchListener.OnTouchEnded = OnTouchesEnded;
touchListener.OnTouchMoved = HandleTouchesMoved;
batterySprite.AddEventListener (touchListener);
pressSwitchSprite.AddEventListener (touchListener.Copy ());
wireSprite3.AddEventListener (touchListener.Copy ());
lampSprite.AddEventListener (touchListener.Copy ());
wireSprite2.AddEventListener (touchListener.Copy ());
}
bool OnTouchBegan (CCTouch touch, CCEvent touchEvent)
{
var target = (CCSprite)touchEvent.CurrentTarget;
var locationInNode = touch.Location;
var s = target.ContentSize;
CCRect rect = target.BoundingBoxTransformedToWorld;
if (rect.ContainsPoint (locationInNode)) {
target.Opacity = 180;
return true;
}
return false;
}
void HandleTouchesMoved (CCTouch touch, CCEvent touchEvent)
{
var target = (CCSprite)touchEvent.CurrentTarget;
CCPoint pt = touch.PreviousLocation + touch.Delta;
target.Position = target.WorldToParentspace (pt);
}