I added sprite B to sprite A as a child..
[spriteA addChild:spriteB];
my game logic is based on if spriteB was touched or not.
However I was not able to get spriteB to detect the touch.
I have converted the touchLocation to nodeSpace..
And I can get spriteA to detect the touch with no problem..
The if-condition I use is
if (CGRectContainsPoint(spriteB.boundingBox, touchLocation))
It'll be sweet if someone can point me to a direction..
spriteA is added to spriteBatchNode if that matters.
Thanks in advance!
Update:
I figure that the child is actually detecting the touch.
the reason it wasn't working was because I have the dirty tag set.
In short here's how my game works.
Targets popping from some hides.. and player touches on targets to get points.
I have a few arrays to hold targets at different location.
And I set dirty tag for each target..
target.dirty = TRUE when it pops
target.dirty = FALSE when it hides
this is equivalent to
If it pops, then it's clickable.
If it's behind the hide, then it's NOT clickable.
so right before I enter my if-condition
if (CGRectContainsPoint(curTarget.boundingBox, touchLocation))
I have this
if(curTarget.dirty == FALSE) continue;
My problem is that when I have the above condition check.. I detect no touch..
But If I take the above condition away, I can detect all touches..
but the problem would become the reverse.. which is I am able to click on my targets even it's not visible..
the above logic works if I add the target sprites as a child of the layer instead...
Help!
Related
I display a list of custom panels beneath one another. When the user drags one of those panels out of the list, the panels below should move to fill the gap. No problem so far.
Now I'd like to animate this movement. This code works fine, but doesn't quite do what I want, because the panels still kinda "jump" to their new position. (AnimateWindow only uses the height of pControl and scrolls it in from nothing. That looks weird if the distance between old and new position is much larger than the height.)
TWinControl * pControl = some_panel_from_my_list;
pControl->Visible = false;
pControl->Top = new_top;
pControl->Left = new_left;
AnimateWindow( pControl->Handle, 200, AW_SLIDE | AW_VER_NEGATIVE );
pControl->Visible = true;
Is there some variant of this to just say: "Slide this control from point A to B?"
Google turned up either empty or with too many unrelated hits, and all I find here is iOS or jQuery related... I hope that someone here can point me in the right direction. Thanks!
Edit:
I'm not set on using AnimateWindow--- I know that can't do what I want. I'm asking for alternatives that do. Just found UIAnimationManager which looks promising (and overkill), but I'll need to investigate that further. Implementing my own timer-based animation would be a last resort, because seriously--- such an animation is so normal nowadays I'd be more than surprised if WinAPI doesn't cover it!
I've been looking through the SFML documentation for making clickable sprites, but so far I haven't found anything.
Do you guys think you could help me out?
There is nothing like sf::ClickableSprite in SFML so far, and probably there will never be. (Current list of classes in SFML)
However, you can obtain this behavior with the sf::Sprite object and the events. The idea is simple - as soon as you get the sf::Mouse::isButtonPressed(sf::Mouse::Left) event, check if the mouse is in the sprite. If it is, perform the action. You can perform another action (maybe undo) when button is released.
There is sf::Sprite::getGlobalBounds() function which returns you the position and the dimensions of the sprite. There's also sf::Mouse::getPosition() function, which returns the current position of the mouse. You can use sprite.getGlobalBounds().contains(mousePos) to check whether the mouse is in the sprite.
If you're using views, you'll need to add the view's position to sf::Mouse::getPosition(window), since it gets the mouse position relative to window coordinates.
(thanks to Chaosed0 for additional notes.)
I'm having a weird issue with cocos2d-x when trying to detect which character (currently a CCLayer-extending object) I'm touching. The problem is that the location of the sprite I'm clicking on never matches the touch location that is registered.
I've tried different conversion functions but neither of them seem to work.
Any idea about how can I detect in ccTouchesBegan where a map (CCLayer) is being touched in the same 'scale' than the characters (also CCLayer's)? How can I get the absolute position in the map of the touch poisition as I receive it (I will move the character to the clicked position)?
I know that they may be very basic questions, but I've been looking for the answer for some hours and I can't find the solution. Any suggestion either for cocos2d-x or cocos2d is really welcome.
Thanks in advance!
1) In order to detect whether world point is in the node, I use following function:
bool VUtils::isNodeAtPoint(cocos2d::CCNode* node, cocos2d::CCPoint& touchLocation) {
CCPoint nodePoint = node->convertToNodeSpace(touchLocation);
CCRect rect = CCRectMake(0, 0, node->getContentSize().width, node->getContentSize().height);
return rect.containsPoint(nodePoint);
}
2) touchLocation - is point in world coordinates, in order to get it use CCTouch::getLocation() method in your touch listeners.
I am struggling with my first semi basic game for iPhone. The game operates well but I want a button to display saying restart and then when clicked it restarts the scene. This button should only appear when my sprite (called sprite) falls below the bottom of the iphone screen. I am using both cocos 2d and box 2d if that makes a difference.
Thank you for the help in advanced, it is greatly appreciated!
Quick answer for having the button appear once the sprite falls below a certain point: When you create the button, set its state to not visible. resetButton.isVisible = NO; Then write an if statement about your sprite's position and enable the button once that happens.
if (sprite.position.y >= 0)
{
resetButton.isVisible = YES;
}
This should get you started on that aspect. I'm not at my Mac right now, but if memory serves, a non-visible button is not enabled, so clicking on its location won't matter. If that's incorrect, just add in resetButton.isEnabled = NO; and YES appropriately.
As for resetting the scene, this can get a little tricky depending on what exactly you want to accomplish. You need to essentially replace the scene with itself, but this can cause undesirable flashes. A quick google search found a bunch of forum posts on this. If you can elaborate on what you've already tried and where you're getting caught up, I can try and get more specific.
I have a CCSprite that I'm using in a scene and have created multiple CCAnimation actions to apply to it all using a single CCSpriteFrameCache sharedSpriteFrameCache. While everything is working and I'm able to switch between animations, I feel like I'm doing poorly and would like to simplify my code by retrieving the running action(s) on the CCSprite to stop them individually before running the next action on it.
To help create some context, lets assume the following situation:
We have a CCSprite called mySprite
We have 3 separate CCAnimation actions defined for walking to the right, walking to the left, and sitting looking forward called: actionAnimWalkRight, actionAnimWalkLeft, and actionAnimSitForward respectively.
We want to have the sprite walk to the right when someone touches the screen right of mySprite, walk left when someone touches the screen left of mySprite and sit when someone touches mySprite.
The approach I'm using to accomplish this is as follows:
Place CCSprite as a child in the scene.
Tell the sprite to run an action using: [self runAction:actionWalkRight];
When I want to change the action after someone touches, I have a method called stopAllAnimationActions which I call before I apply a new action that stops any animation action no matter what's running. Basically lists ALL the CCAnimation/CCActions I have defined and stops each one individually since I don't want to use stopAllActions. as follows: [self stopAction:actionWalkRight]; [self stopAction:actionWalkLeft]; [self stopAction:actionSitForward];
Then I apply the new animation after the above method fires using: [self runAction:actionWalkLeft];
While this works, it just seems like a poor design to stop items that I know aren't running just because I don't know exactly what is running. So just looking for advice and the best recommended practice to do something like this within very complex situations so tracking every possible situation is difficult. Any feedback would be appreciated.
When creating the actions set the tag of that action with a constant:
actionWalkRight.tag= kCurrentAction;
[self runAction:actionWalkRight];
Then, retrieve the running action by that tag and stop it.
[self stopActionByTag:kCurrentAction];
I recommend you simplify your process and take advantage of the native Cocos features, including stopAllActions. Don't re-use actions, always create them from scratch as it has been well discussed among Cocos developers that re-using actions can be buggy.
Cocos is well optimized and features like stopAllActions are not performance hogs. It would probably be faster than your approach, actually.