I am developing a game in cocos2d-x. In that game I am having two sprites, When i click on a sprite one after another it should swap.I don't know the code for that please help.I created the sprite using following code.
CCSprite *splash=CCSprite::create("misc_textur111.jpg");
splash->setPosition(ccp(500,300));
this->addChild(splash,1);
CCSprite *splash1=CCSprite::create("misc_textur222.jpg");
splash1->setPosition(ccp(300,600));
this->addChild(splash,1)
Now I need to swap the position of both the images.please help.
You can do it like:
CCPoint position(splash->getPosition());
splash->setPosition(splash1->getPosition());
splash1->setPosition(position);
I'd suggest, if you can, upgrading to a newer release of Cocos2d-x. Version 2.23 or even better, version 3.v. Dragging sprites around is trivial with the new EventDispatcher You can create a Listener for each Sprite.
Example:
//Create a "one by one" touch event listener (processes one touch at a time)
auto listener1 = EventListenerTouchOneByOne::create();
// When "swallow touches" is true, then returning 'true' from the onTouchBegan method will "swallow" the touch event, preventing other listeners from using it.
listener1->setSwallowTouches(true);
//Trigger when moving touch
listener1->onTouchMoved = [](Touch* touch, Event* event){
auto target = static_cast<Sprite*>(event->getCurrentTarget());
//Move the position of current button sprite
target->setPosition(target->getPosition() + touch->getDelta());
};
Check out the Cocos2d-x Wiki: http://cocos2d-x.org/wiki
Related
I am creating a game like bounce ball using box2d in cocos2d-x. I created a dynamic body object and i want it to move when touch began. I am using the following code to move the dynamic body but it is not moving. Please anyone could help me to solve the problem.
bullet2=CCSprite::create("block.png");
bullet2->setPosition(ccp(2740, 1220));
this->addChild(bullet2,0);
ballBodyDefB.type=b2_dynamicBody;
ballBodyDefB.position.Set(2740/PTM_RATIO, 1170/PTM_RATIO);
ballBodyDefB.userData=bullet2;
ballBodyDefB.gravityScale=0;
_bullet=_world->CreateBody(&ballBodyDefB);
b2PolygonShape bulletshape;
bulletshape.SetAsBox(bullet2->getContentSize().width/PTM_RATIO/2,
bullet2->getContentSize().height/PTM_RATIO/2);
b2FixtureDef b_bullet ;
b_bullet.shape = &bulletshape;
b_bullet.density = 1.0f;
b_bullet.friction = 0.1f;
b_bullet.restitution = 0.0;
_bullet->CreateFixture(&b_bullet);
CCTouchbegan:
b2Vec2 force = b2Vec2(0, -450);
_block->ApplyLinearImpulse(force, _block->GetPosition());
Hi moving the sprite which follow b2body is easy. You need to attach Sprite to the b2body.userData and in box2d world step synchronize the position and rotation of your sprite with your b2body.
I can't answer directly your question, please post your code and what version of cocos2d-x you have for more details:
Check if your code contain code about: (depend on cocos2d-x version, you use CCSprite which is deprecated in 3.2, we use Sprite only anyway)
box2d world (you already have _world)
_world step iteration
syncing sprite position with b2body
Anyway you can find more details at these links:
http://www.cocos2d-x.org/wiki/Box2D and http://www.cocos2d-x.org/wiki/Getting_Started_with_Cocos2d-x
I hope to pop down a score panel when players win and pass the gate.
Normally it will pop down score board.
I think the best way is to use layer and pull down it.
But I only get the transition of scene, just wonder is there any way for layer transition?
Did not see an equivalent of CCTransitionScene :CCScene for CCLayer but layers can runActions using which we can bring out most of the animations/transitions.
Here is what I do in such situations but I guess you are thinking of the same thing. Nevertheless,
1.Create a layer and add it as a child at a position outside of your screen frame.
2.Then use CCMoveTo to move it to the desired location when you want to pull it down.
I have done something similar in the past.
Display your layer offscreen
i.e setposition(0, CCDirector::sharedDirector()->getWinSize().height*1.5f);
create an action to move it onscreen (I like to use CCEaseSineOut)
you can also use a callfunc to call a function when it has finished its animation
scoreLayer->runAction( CCSequence::create( CCEaseSineOut::create(CCMoveTo::create(1.0f, ccp(0, 0-_screenHeight*1.5f))), CCCallFunc::create(this, callfunc_selector(MainLayer::scorefinishedMove)), NULL));
Note: that function might need some fixes to ending brackets etc. And you may want to seperate out some of those actions rather than putting the initialization right in the runAction function
For layer transition you can do this:
CCScene* newScene = CCTransitionCrossFade::create(.5f,Layer2::scene());
CCDirector::sharedDirector()->pushScene(newScene);
In Layer2.cpp
CCScene* Layer2::scene()
{
CCScene* scene = CCScene::create();
CCLayer* layer = new Layer2();
scene->addChild(layer,1);
return scene;
}
I'm creating a game that uses the starling-layer (the game itself) and the classic display list which contains several Popups and Stuff like that.
I have one thing that troubles me:
If MouseEvents are generated on displayList-elements they always go through to the starling layer and produce TouchEvents etc. which is quite annoying.
I was wondering there is some general (and easy to use) approach to handle that.
One possibility was to listen on all displayList-Elements for the following Events:
interfaceElement.addEventListener(MouseEvent.MOUSE_MOVE, stopPropagationHandler);
interfaceElement.addEventListener(MouseEvent.MOUSE_DOWN, stopPropagationHandler);
interfaceElement.addEventListener(MouseEvent.MOUSE_UP, stopPropagationHandler);
private function stopPropagationHandler(e:MouseEvent):void {
e.stopPropagation();
}
But this looks quite nasty to me.
And even if I did it like that, I have one more issue:
If a starling-element is below that display-list-element and if it has a TouchEvent.TOUCH for rollover-behavior >> the rollover-appearance will not be removed from the starling if you hover over the display-list-element.
I also thought about putting a dummy-starling element behind every display-list-element,... to stop the events.. but that all sounds a bit "over-complicated" for such a "simple" task.
Or am I missing something?
A hint would be much appreciated.
Thanks.
You could create 1 main container in the displaylist (not the stage) and listen for ROLL_OVER and ROLL_OUT, and set somekind of global flag there, that your mouse is over the display-list container. Then in your starling events, check for this flag. This isn't the nicest solution out there i guess, but it should work
var isOverDisplayList:Boolean = false;
container.addEventListener(MouseEvent.ROLL_OVER, onRollOver);
container.addEventListener(MouseEvent.ROLL_OUT, onRollOut);
function onRollOver(e:MouseEvent) {
isOverDisplayList = true;
}
function onRollOut(e:MouseEvent) {
isOverDisplayList = false;
}
I'm trying to set a button to invisible in AS3 however when the I leave the frame and come back to it the button is visible again. This is for a jeopardy game I make making for comm tech class.
Here is what I currently have:
a1.addEventListener(MouseEvent.CLICK, a1mouseClick);
function a1mouseClick(mouse:MouseEvent) {
a1.visible = false;
gotoAndStop("A1");
trace("Going to A1");
}
however when it comes back to the frame with the a1 button it is visible again.
Here is my current animation: https://dl.dropbox.com/u/23938245/jeporady.fla
While moving through the timeline flash player can recreates sprites, movie clips and text fields, so your buttons appears visible again. To prevent recreation move all controls to separate level without key frames. If key frames are required try to set the same instance name for this button in all keyframes.
#fsbmain and #prototypical they are right.
While moving through the timeline flash player can recreates sprites, movie clips and text fields, so your buttons appears visible again. To prevent recreation move all controls to separate level without key frames. If key frames are required try to set the same instance name for this button in all keyframes.
I was looking at your project, and offer a quick fix, you need to do the following:
Create a new layer on top to manage a few of actions availables for all frames with the following actions:
import flash.display.DisplayObject;
// Manages the buttons visible state
var buttonsStates:Object = {
"a1":true, "b1":true, "c1":true, "d1":true, "e1":true,
"a2":true, "b2":true, "c2":true, "d2":true, "e2":true,
"a3":true, "b3":true, "c3":true, "d3":true, "e3":true,
"a4":true, "b4":true, "c4":true, "d4":true, "e4":true,
"a5":true, "b5":true, "c5":true, "d5":true, "e5":true
};
// Checks the buttons visibility
function checkVisibility () {
for (var buttonName:String in buttonsStates)
{
var child:DisplayObject = this.getChildByName(buttonName);
child.visible = buttonsStates[buttonName];
}
}
// Saves the visible satatus to false
function setVisibilityToFalse(target:*) {
buttonsStates[target.name] = false;
target.visible = false;
}
Every time you want to check the visibility of the buttons you must call the checkVisibility() function. For example, every time you return to the button list.
Finally the event handler for each button must be like this:
function a1mouseClick(mouse:MouseEvent) {
setVisibilityToFalse(mouse.currentTarget); // Saves the visible state to false
gotoAndStop("A1");
trace("Going to A1");
}
You can download the edited file here http://cl.ly/Lt6X
You are missing a fundamental aspect of how the flash timeline and keyframes function. Once you move away from that frame, the stage instance of the content of that frame and it's properties/states are gone. When you return to that frame, the instance is created again based on the keyframe contents.
I think the best solution given your current approach is to put the main board persistent throughout all the frames. You can do that by creating a layer for it, and have it's keyframe extend from frame 2 to frame 27. However, your next issue will be adjusting visibility of all the elements on that screen when you don't want them visible.
My suggestion would be to put all the elements of that screen into a movieclip symbol of it's own and add that movieclip, and all code for it's listeners, to this new layer you created. For example you might name that instance - main_board and therefore you could modify it's visibility with main_board.visible property. If you did choose that solution, you would need to modify all the code on that frame to use that instance name as well ie :
main_board.a1.visible = false;
Also, you'd need to modify all you addEventListener lines as well :
main_board.a1.addEventListener(MouseEvent.CLICK, a1mouseClick);
Your approach for this game could be greatly simplified, but even further beyond the scope of this question than I have already gone!
I have 3 separate movie clips in a frame, each clip can be moved around the stage using a simple touch and drag event, which is shown below, incase it has some relevance. I want to drag each of the three clips onto a fourth clip and when all 3 are contained within the fourth clip I want an event triggered that changes the current frame. What is the easiest way of doing this in AS3 ? Any examples would be great as I am a complete beginner. Thanks
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
Gem1_MC.addEventListener(TouchEvent.TOUCH_BEGIN, fl_TouchBeginHandler_2);
Gem1_MC.addEventListener(TouchEvent.TOUCH_END, fl_TouchEndHandler_2);
var fl_DragBounds_2:Rectangle = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
function fl_TouchBeginHandler_2(event:TouchEvent):void
{
event.target.startTouchDrag(event.touchPointID, false, fl_DragBounds_2);
}
function fl_TouchEndHandler_2(event:TouchEvent):void
{
event.target.stopTouchDrag(event.touchPointID);
}
In the future you'd want to implement a solution where your drag and drop functionality is abstracted into a class but to work with what you've got, here's a basic solution:
Keep track of when the three MovieClips are considered "contained within" the fourth clip
var contained:Array = new Array(false, false, false);
In the event of an object finishing it's drag, check to see if it's contained in mc1. At the end of these checks, find out if they're all true:
function fl_TouchEndHandler_2(event:TouchEvent):void {
// Drag & drop stuff...
contained[2] = Gem2_MC.hitTestObject(Gem4_MC)); // where Gem4_MC is your 4th movie clip.
if (contained.indexOf(false) == -1) { // This returns -1 if it can't find false
gotoAndStop(frame_number_you_want);
}
}
As a side note, hitTestObject() uses a simple "bounding box" to dectect "collision". This means it may register a hit as true even when two movie clips don't look like they're actually touching. Pixel perfect collision detection in Flash is possible but more complicated and worth its own post. A simple example of pixel perfect collision in AS3 can be found here.