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);
}
我的屏幕底部堆叠了 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);
}