How do I add Apply Force into my code?

I want use applyforce to move my circle left and right but I don't know how to
go about it. Any ideas?

Here is my code currently

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#pragma once
#include "Box2D\Box2D.h"

#define DEG2RAD 0.017453f
#define RAD2DEG 57.29577f

class PhysicalBody {
protected:
	b2Body * m_body = nullptr;

	const float mk_fDensity = 2.0f;
	const float mk_fFriction = 0.4f;
	const float mk_fRestitution = 0.6f;
public:
	void setUserData(void* data) { m_body->SetUserData(data); };
};

#pragma once
#include "Box2D\Box2D.h"
#include <SFML\Graphics.hpp>

#include "PhysicalBody.h"


class DynamicPlayer : public sf::CircleShape, PhysicalBody
{
private:
public:
	sf::CircleShape player;

	DynamicPlayer(b2World * world, const sf::Vector2f& position, const float radius, const float orientation);

	void update();
	void draw(sf::RenderTarget &Target, sf::RenderStates states) const;
};


#include "DynamicPlayer.h"

DynamicPlayer::DynamicPlayer(b2World * world, const sf::Vector2f& position, const float radius, const float orientation)
{	
	
	b2BodyDef l_bodyDef;
	b2CircleShape l_shape;
	b2FixtureDef l_fixtureDef;

	l_bodyDef.type = b2_dynamicBody;
	l_bodyDef.position.Set(position.x, position.y);
	l_bodyDef.angle = orientation * DEG2RAD;

	m_body = world->CreateBody(&l_bodyDef);

	l_shape.m_radius = radius;

	l_fixtureDef.density = mk_fDensity;
	l_fixtureDef.friction = mk_fFriction;
	l_fixtureDef.restitution = mk_fRestitution;
	l_fixtureDef.shape = &l_shape;

	m_body->CreateFixture(&l_fixtureDef);

	setPosition(position);
	setRadius(radius);
	setOrigin(radius, radius);
	setRotation(orientation);
	setFillColor(sf::Color(255.f, 150.f, 25.f));	
}

void DynamicPlayer::update()
{
	b2Vec2 pos = m_body->GetPosition();
	setPosition(pos.x, pos.y);
	float angle = m_body->GetAngle()* RAD2DEG;
	setRotation(angle); 
}

void DynamicPlayer::draw(sf::RenderTarget & target, sf::RenderStates states) const
{
	target.draw((sf::CircleShape)*this);

	sf::RectangleShape line(sf::Vector2f(getRadius(), 0.01f));
	line.setPosition(getPosition());
	line.setOrigin(0.f, 0.005f);
	line.rotate(getRotation());
	target.draw(line);
}
ok I figure out that I need to add this piece of code:

 
m_body->ApplyForce(b2Vec2(0, 50), m_body->GetWorldCenter());


but I'm now getting two errors. Error E0165 & C2660
You need to post the entire error message, not just the codes.

I think your issue is that, according to the box2d docs, the ApplyForce member function requires three parameters.

1
2
3
4
void b2Body::ApplyForce	(	const b2Vec2 & 	force,
const b2Vec2 & 	point,
bool 	wake 
)	
Sorry these are the full error messages:

E0165 - too few argurments in function call
C2660 - b2Body::ApplyForce does not take 2 arguments

I'm confused though, what else do I need to add on to fix those errors
Last edited on
you have to match the function and its call exactly.

1
2
3
4
5
6
7
8
9
10
11
if the function is this:

void b2Body::ApplyForce	(	const b2Vec2 & 	force,
const b2Vec2 & 	point,
bool 	wake 
)	
then you need something like this:
b2Vec2 f = whatever;
b2Vec2 p = numbers;
bool w = false;
ApplyForce(f,p,w); 

where whatever, numbers, and false are dummies... you have to fill that part in. To do that you need to know what the values mean, from the documentation... force and point, we know what that means in physics or english, but you should still see what they represent in this system and fill in values that make sense.
Last edited on
Thanks a lot. Is there anywhere to make this work at the press of a button now since I only want to apply force when a key is pressed like if I was to press the Left and right arrow keys or A & D keys
You're using SFML for your windowing/event framework? Sure, you just need to make sure you handle the KeyPressed and KeyReleased events, or query the state of the sf::Keyboard.
See "The KeyPressed and KeyReleased events" section of https://www.sfml-dev.org/tutorials/2.5/window-events.php
Note the warning:
Sometimes, people try to react to KeyPressed events directly to implement smooth movement. Doing so will not produce the expected effect, because when you hold a key you only get a few events (remember, the repeat delay). To achieve smooth movement with events, you must use a boolean that you set on KeyPressed and clear on KeyReleased; you can then move (independently of events) as long as the boolean is set.
The other (easier) solution to produce smooth movement is to use real-time keyboard input with sf::Keyboard (see the dedicated tutorial*).

* https://www.sfml-dev.org/tutorials/2.5/window-inputs.php


Last edited on
I'm getting a weird type of error now. So I created two new void functions called Right and left and put the apply force code inside both of them and in my main class I added the keyPressed if statements and the code runs fine but whenever I attempted to move the shape the debug just closes down and says this

1
2
3
4
Exception thrown: read access violation.
**this** was nullptr.

The program '[18508] Platformer Project.exe' has exited with code 0 (0x0).


Here is my code I added in

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//DynamicPlayer header

void left();
void right();

//DynamicPlayer class

void DynamicPlayer::left()
{
	
	b2Vec2 f(5, 0);
	b2Vec2 p(0, 0);
	bool w = false;

	m_body->ApplyForce(f, p, w);
	
}

void DynamicPlayer::right()
{
	b2Vec2 f(-5, 0);
	b2Vec2 p(0, 0);
	bool w = false;

	m_body->ApplyForce(f, p, w);
}

//Main class

if (event.key.code == sf::Keyboard::Left)
{
Player.left();
}
if (event.key.code == sf::Keyboard::Right)
{
Player.right();
}





I think this violation has something to do with this statement but I don't know what

1
2
3
4
5
6
7
inline void b2Body::ApplyForce(const b2Vec2& force, const b2Vec2& point, bool wake)
{
	if (m_type != b2_dynamicBody)
	{
		return;
	}
}
Last edited on
Not enough information to tell. When you run the code through the debugger, what line does it crash on?
Its not any particular line within my code. That's seems to work fine. Its the box2d line of code that I put in my last comment
But you're saying there's a read access violation, so where exactly does that happen? I don't think line 3 of your excerpt would cause a violation.
Is m_body being correctly initialized? Can you check to see if m_body is null?
Last edited on
Yes. I have a physicalBody class where m_body is null

1
2
//PhysicalBody
b2Body * m_body = nullptr;
Last edited on
Before the bug happens, put a breakpoint before you dereference m_body.
If m_body is null here, then the error is that you're dereferencing a null pointer.

I don't know if that is actually the problem, but that's the only thing I can think if you are getting " read access violation. **this** was nullptr.".
Last edited on
How can I put a breakpoint there? because by just putting break; before it causes
another error
Last edited on
Breakpoints are a debugging feature, it's not a language feature.
https://docs.microsoft.com/en-us/visualstudio/debugger/using-breakpoints?view=vs-2019
yea it says my "this" value is null but does that mean I have to add new values onto the code?

Also the error was still occuring in the b2Body class from box2d not any of my actual classes
Last edited on
Topic archived. No new replies allowed.