Chipmunk physics Drag and drop

The c++ tests, do indeed, with enough digging, (from my view) provide all you need for simple and common physics. I could have mainly not been where I am (without consulting somebody else) without it (ком си ком са) without it. However I have reached the point where in depth research into it and online hasn’t gotten me so far. I have noticed the cpp tests, as do the docs, use

 (nameofbody)->setTag(DRAG_BODYS_TAG);
                    

And they (I think) set this up by:
(imagining this is in the curly brackets for a touchbegan event)


    auto location = touch->getLocation();
    auto arr = _physicsWorld->getShapes(location);
    
    PhysicsBody* body = nullptr;
    for (auto& obj : arr)
    {
        if ((obj->getBody()->getTag() & DRAG_BODYS_TAG) != 0)
        {
            body = obj->getBody();
            break;
        }
    }
    

Ofcourse here we have even more definitions needed, The definition of _physicsWorld and more as i found from my debug list. Is there a simpler way? I have frantically searched StackOverflow, the forum and online but what I find is either Java, 3 years outdated, unanswered and/or for box2d. So I ask,

Within the init, and if required, the header, how do I set a tag for chipmunk drag and drop?

A tag is a number for identifying something. Nothing to do with physics.

Your answer is here https://docs.cocos2d-x.org/cocos2d-x/en/event_dispatcher/touch.html

After reading this

I in-depthly searched the physics.cpp/ physics.h in the cpp tests for a match. There isn’t one for the joints (just about the only physics just identical to what i am directly trying to achieve), only

. Are you sure there isn’t another way?

regardless I followed the docs/cpptests:


		bool DEL1::onTouchBegan(Touch* touch, Event* event)
		{
			DEL1::onTouchBegan(touch, event);

			_distance = touch->getLocation().x - VisibleRect::center().x;

			return true;
		}

		void DEL1::onTouchMoved(Touch* touch, Event* event)
		{
			DEL1::onTouchMoved(touch, event);

			_distance = touch->getLocation().x - VisibleRect::center().x;
		}

		void DEL1::onTouchEnded(Touch* touch, Event* event)
		{
			DEL1::onTouchEnded(touch, event);

			_distance = 0;
		}

I already defined these in the header





    bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event);
	void onTouchEnded(cocos2d::Touch* touch, cocos2d::Event*);
	void onTouchMoved(cocos2d::Touch* touch, cocos2d::Event*);

And now i have an error saying “DEL1::onTouchBegan may not be declared outside of it’s class”
help?

Yes. I am sure. You need an event listener if you want to drag stuff around.

Paste the whole header and the whole source. You have an error someplace.

Don’t pick out code you don’t understand and try to work within that. You need to learn proper concepts.

This is an event issue. Nothing for physics quite yet. You can even use containsPoint() when checking if you dragged over something etc. I have a code example from one of my games but let’s see your source and header first

1 Like

Relevant bits of header and cpp, as it is a little over alot

There are quite a few random bits i left for later by the way

Header

#pragma once

#include "cocos2d.h"

class DEL1 : public cocos2d::Scene
{
public:
	static cocos2d::Scene* createScene();

	virtual bool init();

	// a selector callback 
	void menuCloseCallback(cocos2d::Ref* pSender);
	


    bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event);
	void onTouchEnded(cocos2d::Touch* touch, cocos2d::Event*);
	void onTouchMoved(cocos2d::Touch* touch, cocos2d::Event*);
	
	CREATE_FUNC(DEL1);

	//Button and prompts
	cocos2d::Sprite *DEL1ground;
	cocos2d::Sprite *DEL1BASKETR;
	cocos2d::Sprite *DEL1BASKETL;
	cocos2d::Sprite *DEL1BASKETB;
	cocos2d::Sprite *DEL1BALL;
	cocos2d::Sprite *DEL1SLINGDOT;
	cocos2d::PhysicsBody *physicsBody;
    cocos2d::PhysicsBody *physicsBBody;
	cocos2d::PhysicsBody *SpriteBody;
	cocos2d::PhysicsBody *SpringBody;
	cocos2d::Sprite *DEL1B;
	cocos2d::Sprite *DEL1P;
	cocos2d::Sprite *DEL1H;
	cocos2d::Sprite *DEL1Hbl;
	cocos2d::Sprite *DEL1PHbl;
	cocos2d::Sprite *DEL1Pbl;
	cocos2d::Action *ration;
	cocos2d::Action *retion;
	cocos2d::Action *etion;
	cocos2d::Action *ation;
       ....

	bool onContactBegin(cocos2d::PhysicsContact &contact );
    //end Button and prompts

	//Deliverables
	

};

.cpp

Under alterations

If it’s ok with you, may I see the code of the example please?

Umm why do you have functions in a for loop? This isn’t even close to correct.

Also what you are doing in this cpp I think you should separate out into a few classes. Otherwise it’s very confusing to follow. Have you heard of encapsulation yet?

Make a class for each object. In that class init, add events, physics, functionality etc. each class should be able to stand on its own.

I would prefer to keep the amount of classes minimal(this class is ONE game level and i want to keep it that way) The joints are ready i just want to drag them. Thanks for letting me know that it isn’t right, i have already removed the code. I have been following the sonar physics course and a few github pages.

I follow my code very easily, though i completely understand your confusion. In future I’ll use commenting to make it simpler to follow

But the cpp tests created a drag feature in the very same cpp, I really want to do the same.

Yes but those programmers understand the concepts. You don’t. You have functions in a for loop! Seriously. Your questions are getting harder to answer without frustration from our community because you aren’t studying and learning. You are trying to cut and paste and change names.

I think it’s great you want to make games. I also admire that you want to do it with coding versus a drag and drop game maker. However, coding is an art. It takes practice. It takes studying. It takes reading. You can’t be a programmer reading stack overflow. You can’t be a programmer asking questions about every step you need to solve. You need dedication to studying and learning to apply what you have studied.

  1. Make a class for each object in your game. Each class would have in it what it needs to operate as you want. Initialization, events, physics, update method. What sprites are involved, what actions etc etc

  2. Use these classes as needed by instantiating them.

  3. Store objects in a vector if you need to so you can get back to them.

  4. Each level is a class or create a generic level class and send in the data for that level as a data structure of some sort.

  5. Maybe have a game object that deals with all of this and instantiate this class in AppDelegate.

So I’m writing a whole game as part of the docs. The first few sections are in place already. I guess I should do this faster.

The Sonar tutorials are out of date.

I only refer to that when the pdf/ my course doesn’t cover something

They very well are outdated. So I altered them as best as I could, and achieved simple physics-based features quite well.

Ok the LAST thing I want to do is cause stress among you. Sorry, expect, I’d say expect at maximum 3 more new topics for the 34 days. I suppose the decent progress and the running deadline are making me quite desperate and stressful. You said you will not answer without effort so I always put research into my questions, clearly I didn’t put enough…

I’m not saying dont post topics. Please do. Whatever.

However, each topic needs to contain:

  1. accurate description of your issue

  2. full header and source - Since you are using one file this is very important. You posted a problem in this thread that wasn’t clear until you posted the full source. Then I was able to see you are trying to declare functions inside a for loop.

  3. What have you tried already? What do you think is causing your trouble, etc.

:slight_smile:

Ok, thanks, I’ll be sure to stick by this mantra in future! Starting now:

  1. Hello, I am trying to set a drag and drop feature for my circle physics body. Despite research I Haven’t found a clear solution as all places I found are either for another physics engine, outdated or simply for another language. I have set up the touch events in the header:

2_sort of_)

    bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event);
	void onTouchEnded(cocos2d::Touch* touch, cocos2d::Event*);
	void onTouchMoved(cocos2d::Touch* touch, cocos2d::Event*);

and tried to use a similar structure to that of the cpp tests:

bool DEL1::onTouchBegan(Touch* touch, Event* event)
{
    auto location = touch->getLocation();
    auto arr = _physicsWorld->getShapes(location);
    
    PhysicsBody* body = nullptr;
    for (auto& obj : arr)
    {
        if ((obj->getBody()->getTag() & DRAG_BODYS_TAG) != 0)
        {
            body = obj->getBody();
            break;
        }
    }
    
    if (body != nullptr)
    {
        Node* mouse = Node::create();
        auto physicsBody = PhysicsBody::create(PHYSICS_INFINITY, PHYSICS_INFINITY);
        physicsBody->setDynamic(false);
        mouse->addComponent(physicsBody);
        mouse->setPosition(location);
        this->addChild(mouse);
        PhysicsJointPin* joint = PhysicsJointPin::construct(physicsBody, body, location);
        joint->setMaxForce(5000.0f * body->getMass());
        _physicsWorld->addJoint(joint);
        _mouses.insert(std::make_pair(touch->getID(), mouse));
        
        return true;
    }
    
    return false;
}

void DEL1::onTouchMoved(Touch* touch, Event* /*event*/)
{
    auto it = _mouses.find(touch->getID());
    
    if (it != _mouses.end())
    {
        it->second->setPosition(touch->getLocation());
    }
}

void DEL1::onTouchEnded(Touch* touch, Event* /*event*/)
{
    auto it = _mouses.find(touch->getID());
    
    if (it != _mouses.end())
    {
        this->removeChild(it->second);
        _mouses.erase(it);
    }
}

You have probably seen, like myself, that alot of definitions are missing, scattered somewhere in the midsts of the cpp, which makes sense as that solution was made by people 4x the cocos2d-x programmer I’ll ever be. I have attempted to just “find them” but then this leads to many redirections.
So I ask, within one function, how do I set up the properties of “DRAG_BODYS_TAG”? I aim to do this within a single class, having the ontouch trio pre-declared in the header.

As I said. A tag is just a number. This isn’t your concern right now. You need to get your events working first. Then add code to them to make them do what you want. The code you have in your events now is not needed even.

So leave the space where the event code is, blank?

Maybe put in a cout so you can verify the events are being triggered?

I’ll go for a cclog, but thanks for giving me the idea

1 Like