Android game : Drag one image at a time into screen from a group of images

十年热恋 提交于 2019-12-06 07:13:58

问题


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


回答1:


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
        }
    }
    



回答2:


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);
        }


来源:https://stackoverflow.com/questions/33168953/android-game-drag-one-image-at-a-time-into-screen-from-a-group-of-images

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!