Android 游戏:从一组图像中一次将一个图像拖入屏幕

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

我的屏幕底部堆叠了 5 张图片。我的游戏目的是拖动这些图像并在特定条件下将它们连接起来。(有点像拼图游戏) 我使用了以下代码

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

此代码一次将所有图像移动到触摸的坐标。我的要求是一次拖动一个图像,而不是一次拖动所有图像。 Cocossharp API 和 Xamarin 中给出的教程和 Github 在我看来没有多大帮助。 有没有一种方法可以在一个触摸实例上拖动一个图像? 帮助赞赏

这里是创建两个精灵并允许您单独拖动它们的示例。

设计:

  • 您需要检测哪个精灵被触摸,然后只移动那个精灵。
  • 在 OnTouchesBegan 中保存被触摸的精灵
  • 在 OnTouchesMoved 中移动当前触摸的精灵

备注

  • OnTouchesBegan 为每个 注册事件的精灵调用一次。所以如果20个精灵添加监听器,OnTouchesBegan事件被调用20次(除非被吞噬,见下文)
  • 您以编程方式确定触摸位置是否在调用 OnTouchesBegan 的精灵的边界框内。然而 "Swallowing" 触摸将停止任何剩余的排队呼叫。吞下去,就return真。
  • 一旦找到感兴趣的 sprite,您 return 忠实于 "swallow" 触摸事件并阻止其余 sprite 回调。这可以节省 cpu 并更快地执行您的 OnTouchesMoved。系统在处理完 OnTouchesBegan 之前不会调用 OnTouchesMoved。

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

我按照这个 link TouchableSpriteTest 实现了我需要的功能(在 jaybers 的帮助下)

示例代码

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