cocos2dx - sub layer that covers its parent partially keep capturing all touches - cocos2d-x

In my cocos2dx game, I have a CCLayer that contains another CCLayer. The sublayer just cover part of the container layer. I 'think' I achieve this through:
this->setContentSize( CCSizeMake( 100, 200 ) );
however, the sublayer always capture touches even though it is outside its size and position area... Is it common?
I can filter through the touches position by comparing it inside the ccTouch** functions, but I think it is a hack, what is the proper way to set the sublayer to properly cover just the partial area of its parent?

The only thing i can think of straight away is making this inner layer a CCNODE and also extent it with CCTouchDelegate.
Now with this, when u register with the TouchDispatcher, you make sure it doesn't Swallowtouches(the boolean value given as the last parameter)...
This way when you receive a touch ... just see if it is within the boundary of this inner layer of urs and if it is not, send let the parent class use this touch.
Hope this helps.

Related

Cocos2d-x 3 - Disable collision between two bodies and detect when them separate each other

I'm developing a cocos2d-x game (version 3.8). My game uses chipmunk physics and it has a static body that works like an interruptor. This interruptor is enabled when another body is over it. The interruptor is disabled when bodies separate each other.
I want to:
Moving body don't collision with interruptor. It has to cross interruptor with no bounce
I want to detect when moving body separates the interruptor
My first approach was implementing onContactBegin method. I return false when those two bodies get in touch. This way the body crosses the interruptor and does not bounce.
The problem is onContactSeparate method is not called, because contact did not happen.
If I return true in onContactBegin method, onContactSeparate is called and I can detect it. The problem is the body does not cross the interruptor, it bounces.
[EDIT] More info
This is the scenario where two sprites are separated. The ball can move and interruptor is a static body. Ball could be over the interruptor.
This is the scenario where two sprites are in contact and object1 (the ball) is over the interruptor. I want to detect where two sprites separate each other.
Any help would be appreciated!
It seems to me like you are using Box2D within cocos, so I'll answer with that as my base assumption.
This is what i would do.
My interrupter would be a b2Body* with no BodyDef dimensions defined or just a 0x0 dimension def.
I would set the user data for the bodyDef to a rectangle that describes my interruption area. This way you can always have your interruption area represented, but will not collide with anything.
(Optional) If you want the interruption area to move around based on the fake body you assigned to it, you can updated it just after the step function using something like below.
world->Step(delta, 10, 10);
for (auto physicsBody = _world->GetBodyList(); physicsBody; physicsBody = physicsBody->GetNext())
{
auto userData = static_cast<Node*>(physicsBody->GetUserData());
if(userData != NULL)
{
// Set interruptor area rectangle = physicsBody->GetPosition();
}
}
To let the rest of the system know when I have left the interrupter I would store a function pointer to the function I want to call when this happens, When a object enters the interruption area I would flag it saying "I'm in the area" after that, the first update step you get when it's not in the area anymore I would fire the callback and reset the flags I used to get to that point.
I hope this helps. You are not giving a lot of context for what you want to do, an image would be helpful. Especially when it comes to looking for help with code that has a visual representation as well.
[EDIT]
Based on the behaviour you want this is the way I did this. The first thing to know is that you don't need physics collisions for the behaviour you want. You can do this by using bounding box intersection tests and use flags and callbacks to figure out the rest.
I have an object that knows about both the ball and my interrupter nodes. In the update loop of this object I check if the two intersects. I set a flag indicating "I am in the interrupter", the next frame that I am not in the interrupter and my flag is still true I call the function that I assigned with my "leaving logic" in it, and set then flag back to false.

Added TableView to Sprite is not visible and all other Sprites are visible

I inherited Sprite and I want to put inside TableView but when I add inherited Sprite to scene table is not visible but all others sprites added to inherited sprite are visible ( I checked it creates cells, position and z index are set right, when I add TableView directly to Scene it is visible).
I'm able to add a TableView to a Sprite in Cocos2d-x v3.6, but it's a little hard to say exactly why yours isn't showing up. Here are some things to check:
Have you added the TableView as a child to the Sprite via addChild?
When you add the TableView to the Sprite, is your DataSource set properly? (This seems to be the case given your question).
Are there positioning issues when you add it to the Sprite due to the anchor position(s) of your Sprite and it's parent(s)? It could be the TableView with incorrect positioning, or it could be the TableViewCells themselves. Remember that when you add a child to some Node, its anchor point is Vec2(0.5, 0.5).
You're not forced to override cocos2d::Size cellSizeForTable(cocos2d::extension::TableView *table), and if you don't have cell heights, the cells might not show up.
Try "dumbing down" any logistics you have and follow the code in TableViewTestScene.cpp, which is part of the cpp-tests. (cocos-directory/tests/cpp-tests/Classes/ExtensionsTest/TableViewTest)
Last resort: Try doing something silly like giving your table and cells a large height and width of 500-1000 pixels each. Give them an absolute position somewhere in your Sprite. Give each of them a Label that says "Hello, World!" and see if they show up.
It might be helpful to see your applicable code, too.
A very late edit: I realized today that it seems as though Layer objects (and thus TableViews) always have an Anchor Point of Vec2::ANCHOR_BOTTOM_LEFT. Could this be your issue?

Object changing layer when going between frames?

I have a child of an object that stays on the scene when the frame changes. So I gotoAndStop(2); and the object is still there. However, when I come back to frame one. The object is on the lowest layer, despite the fact that I originally added it using addChildAt(character, 1); I think this adds it to the first layer? Anyone know how I can fix this issue of keeping a movieclip object on the top layer despite changing frames? Thanks.
In AS3/Flash, the bottom most layer is 0. So doing addChildAt(character, 1) would make your character the second to the bottom layer. addChildAt(character, 0) would make it the very bottom/back layer.
If you want to make it the top most layer, you do any one of the following:
addChild(character); //this is the shortest amount of code
addChildAt(character, numChildren-1); //the is exactly the same as above
setChildIndex(character, numChildren-1); //this is also the same but requires the character already be present on the display list
The latter (setChildIndex) may be preferred IF your character originates on the timeline (eg not created through code). The reason being, if you change through code the parentage of something created on the timeline, it will not go away when no longer present on the timeline.
If you want a way to force something to always be on top, you can do something along these lines:
this.addEventListener(Event.ADDED, bringToTop);
function bringToTop(e:Event):void {
setChildIndex(character, numChildren-1);
}
Doing that, makes it so whenever any other object is added as a child of this, it will set the character to the very top most layer/z-index.

Object does not rotate around pivot point

I have an object which looks like this:
When I try to rotate it using [INSTANCENAME].rotation += 10;
it still rotates around the middle of the object. Am I doing something wrong?
I've done a little research, and apparently there is no direct way to change the pivot point programmatically, AFAIK. Rather odd, seeing as you can change it in the Flash Pro IDE. (For those reading, the pivot point is NOT the same as the registration point.)
[EDIT: Thinking more about it, I don't think the pivot point actually "exists", at least in the context of a programmable property. It only exists in the context of some tools in the Flash IDE.]
You will need to place your object ALONE inside another object, so that the desired pivot point of the inner object is over the center of the outer object. Then, rotate the outer object.
You can later control your object's "pivot point" by changing the position of the inner object.
Since the outer object's center moves depending on its size, and the position of the inner object determines the size of the outer object, you'd need to apply some math. The x position of the inner object would need to be equal to the distance from the desired pivot point on the inner object to the far right edge of that inner object. The same concept applies to the y position.
This can be accomplished both in the IDE directly, or through code, whichever you choose.
An example of code to change this dynamically. This function is inside the outer object. (You can get pivotX and pivotY off an event listener, if you want.) [Sorry, the code is untested.]
function newPivot(int pivotX, int pivotY):void
{
inner.x = inner.width - pivotX;
inner.y = inner.height - pivotY;
}
I hope that solves your problem!
A very simple way is to do like this.
Convert the image to a symbol(MovieClip). [you might have already done it].
Double Click on the MovieClip/Sprite to enter inside.
Move the Image so that the registration point align towards the pivot.
NB: Applicable only in case of FLASH IDE.

as3: Making an animation

I am playing with animation in AS3 and flex4, and I've come into a problem. My application is a game board (like a chess board), where each field is a border container added to some position.
Also I am adding a child element (shape), to this container on mouse click. What I want to achieve is to be able to move shapes smoothly from one field to another. But it appears that the shape goes behind the neighbor field this way http://screencast.com/t/iZ3DCdobs.
I believe this happens because shape is a child of specific border container, and to make it visible over every other container, I would need to use layers somehow....
I would be happy if anybody could suggest a solution
Yes you're right on that. You should add the movable objects to a different layer.
As there are no typical layers in AS, you could try to drop the fields in one sprite and any other objects to a different an than place them on each other, so that when you will move a object it won't go behind other objects.
If you place both sprites in the same position you will still have accurate x,y positions between movable objects and fields.
You have two options:
First one is to have different layers for your DisplayObjects: as an example, the bottom layer would hold all the boards, and the upper layer would hold all the pieces.
Second option is to manipulate the index of the objects with swapChildren(), swapChildrenAt(), and setChildIndex(). So to bring a MovieClip to the topmost front, you would do MovieClip(parent).setChildIndex(this, 0);
If the situation is that always the shape object gets hidden behind the next ( right side ) grid container, the I suggest you create your grid in reverse.
Suppose you are creating a chess grid. that is a 8x8 grid. Normally you would create your grid using 2 for loops, looping from 0 to 8 with say the x and y points starting at 0,0 for the first grid and going on till the end. What I suggest you to do is to create from 8,8 to 0,0.
Display objects in flash are stacked on top of each other based on their child index.
For example: If you create two objects. Rectangle and Circle as follows
var rect:Rectangle = new Rectangle();
this.addChild(rect);
var circ:Circle = new Circle();
this.addChild(circ);
The circle will always be on top of the rectangle in this scenario because the circle was added after the rectangle to the display list.
So if you reverse the order of creation of your grid, the right grid cell will be added to the display list first and so the grid cells to the left will always be on top of the right ones. Hence, the problem that you are facing will not occur.