1、首先配置Box2D的VS环境

①在官网或GitHub上下载Box2D的源码,http://www.box2d.orghttps://github.com/erincatto/Box2D

②在官网下载premake,https://premake.github.io/

③将下载好的premake.exe放入解压好的Box2D文件夹内(只是为了方便编译,查看帮助可以了解)

Let's make 16 games in C++(十六):Volleyball

④生成工程文件

Let's make 16 games in C++(十六):Volleyball

⑤打开Build工程文件,设置Box2D为启动项,生成解决方案

错误 MSB8036 找不到 Windows SDK 版本8.1。

Let's make 16 games in C++(十六):Volleyball

 

C1083: 无法打开包括文件: “stddef.h”: No such file or directory

vc++目录-->包含目录下拉条点击编辑,增加了路径:C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\ucrt

⑥把生成的Box2D.lib和Box2D文件夹分别放入新建的lib和include文件夹

Let's make 16 games in C++(十六):Volleyball

⑦此时Box2D已经配置完成。只需要在工程中想SFML一样添加Box2D就可以使用。

2、准备游戏需要的背景图

Let's make 16 games in C++(十六):Volleyball

Let's make 16 games in C++(十六):Volleyball

Let's make 16 games in C++(十六):Volleyball

 

3、渲染一个800x600的屏幕

#include<SFML/Graphics.hpp>
#include<Box2D/Box2D.h>

using namespace sf;

const float SCALE = 30.f;
const float DEG = 57.29577f;

b2Vec2 Gravity(0.f, 9.8f);
b2World World(Gravity);

int main()
{
	RenderWindow window(VideoMode(800, 600), "Volleyball Game!");
	window.setFramerateLimit(60);

	Texture t1;
	Texture t2;
	t1.loadFromFile("./Resources/images/background.PNG");
	t2.loadFromFile("./Resources/images/ball.png");

	Sprite sBackground(t1);
	Sprite sBall(t2);
	sBall.setOrigin(32, 32);

	//box2d
	b2PolygonShape shape;
	shape.SetAsBox(30 / SCALE, 30 / SCALE);
	b2BodyDef bdef;
	bdef.type = b2_dynamicBody;

	//ball
	bdef.position.Set(5, 1);
	b2CircleShape circle;
	circle.m_radius = 32 / SCALE;
	b2Body *b = World.CreateBody(&bdef);
	b2FixtureDef fdef;
	fdef.shape = &circle;
	fdef.restitution = 0.95;
	fdef.density = 0.2;
	b->CreateFixture(&fdef);
	b->SetUserData("ball");


	while (window.isOpen())
	{
		Event e;
		while (window.pollEvent(e))
		{
			if (e.type == Event::Closed)
			{
				window.close();
			}
		}
		World.Step(1 / 60.f, 8, 3);

		//Draw
		window.draw(sBackground);
		for (b2Body* it = World.GetBodyList(); it != 0; it = it->GetNext())
		{
			b2Vec2 pos = it->GetPosition();
			float angle = it->GetAngle();

			if (it->GetUserData() == "ball")
			{
				sBall.setPosition(pos.x*SCALE, pos.y*SCALE);
				sBall.setRotation(angle*DEG);
				window.draw(sBall);
			}
		}
		window.display();
	}

	return 0;
}

Let's make 16 games in C++(十六):Volleyball

4、添加玩家完善游戏逻辑

#include<SFML/Graphics.hpp>
#include<Box2D/Box2D.h>

using namespace sf;

const float SCALE = 30.f;
const float DEG = 57.29577f;

b2Vec2 Gravity(0.f, 9.8f);
b2World World(Gravity);

void setWall(int x, int y, int w, int h)
{
	b2PolygonShape gr;
	gr.SetAsBox(w / SCALE, h / SCALE);
	b2BodyDef bdef;
	bdef.position.Set(x / SCALE, y / SCALE);
	
	b2Body * b_ground = World.CreateBody(&bdef);
	b_ground->CreateFixture(&gr, 1);
}

int main()
{
	RenderWindow window(VideoMode(800, 600), "Volleyball Game!");
	window.setFramerateLimit(60);

	Texture t1;
	Texture t2;
	Texture t3;
	t1.loadFromFile("./Resources/images/background.PNG");
	t2.loadFromFile("./Resources/images/ball.png");
	t3.loadFromFile("./Resources/images/blobby.png");
	t1.setSmooth(true);
	t2.setSmooth(true);
	t3.setSmooth(true);


	Sprite sBackground(t1);
	Sprite sBall(t2);
	Sprite sPlayer(t3);
	sPlayer.setOrigin(75 / 2, 90 / 2);
	sBall.setOrigin(32, 32);

	//box2d
	setWall(400, 520, 2000, 10);
	setWall(400, 450, 10, 170);
	setWall(0, 0, 10, 2000);
	setWall(800, 0, 10, 2000);

	b2PolygonShape shape;
	shape.SetAsBox(30 / SCALE, 30 / SCALE);
	b2BodyDef bdef;
	bdef.type = b2_dynamicBody;

	//players
	b2Body *pBody[2];
	for (int i = 0; i < 2; i++) 
	{
		bdef.position.Set(20 * i, 2);
		b2CircleShape circle;
		circle.m_radius = 32 / SCALE;
		circle.m_p.Set(0, 13 / SCALE);
		pBody[i] = World.CreateBody(&bdef);
		pBody[i]->CreateFixture(&circle, 5);
		circle.m_radius = 25 / SCALE;
		circle.m_p.Set(0, -20 / SCALE);
		pBody[i]->CreateFixture(&circle, 5);
		pBody[i]->SetFixedRotation(true);
	}
	pBody[0]->SetUserData("player1");
	pBody[1]->SetUserData("player2");

	//ball
	bdef.position.Set(5, 1);
	b2CircleShape circle;
	circle.m_radius = 32 / SCALE;
	b2Body *b = World.CreateBody(&bdef);
	b2FixtureDef fdef;
	fdef.shape = &circle;
	fdef.restitution = 0.95;
	fdef.density = 0.2;
	b->CreateFixture(&fdef);
	b->SetUserData("ball");

	bool onGround = 0;

	while (window.isOpen())
	{
		Event e;
		while (window.pollEvent(e))
		{
			if (e.type == Event::Closed)
			{
				window.close();
			}
		}
		for (int n = 0; n < 2; n++)
		{
			World.Step(1 / 60.f, 8, 3);
		}

		//player1 
		b2Vec2 pos = pBody[0]->GetPosition();
		b2Vec2 vel = pBody[0]->GetLinearVelocity();

		if (Keyboard::isKeyPressed(Keyboard::Right))
		{
			vel.x = 5;
		}
		if (Keyboard::isKeyPressed(Keyboard::Left))
		{
			vel.x = -5;
		}
		if (Keyboard::isKeyPressed(Keyboard::Up))
		{
			if (pos.y*SCALE >= 463)
			{
				vel.y = -13;
			}
		}
		if (!Keyboard::isKeyPressed(Keyboard::Right))
		{
			if (!Keyboard::isKeyPressed(Keyboard::Left))
			{
				vel.x = 0;
			}
		}

		pBody[0]->SetLinearVelocity(vel);


		//player2 
		pos = pBody[1]->GetPosition();
		vel = pBody[1]->GetLinearVelocity();

		if (Keyboard::isKeyPressed(Keyboard::D))
		{
			vel.x = 5;
		}
		if (Keyboard::isKeyPressed(Keyboard::A))
		{
			vel.x = -5;
		}
		if (Keyboard::isKeyPressed(Keyboard::W))
		{
			if (pos.y*SCALE >= 463)
			{
				vel.y = -13;
			}
		}

		if (!Keyboard::isKeyPressed(Keyboard::D))
		{
			if (!Keyboard::isKeyPressed(Keyboard::A))
			{
				vel.x = 0;
			}
		}

		pBody[1]->SetLinearVelocity(vel);

		//ball max speed
		vel = b->GetLinearVelocity();
		if (vel.Length() > 15)
		{
			b->SetLinearVelocity(15 / vel.Length() * vel);
		}

		//Draw
		window.draw(sBackground);
		for (b2Body* it = World.GetBodyList(); it != 0; it = it->GetNext())
		{
			b2Vec2 pos = it->GetPosition();
			float angle = it->GetAngle();

			if(it->GetUserData() == "player1")
			{
				sPlayer.setPosition(pos.x*SCALE, pos.y*SCALE);
				sPlayer.setRotation(angle*DEG);
				sPlayer.setColor(Color::Red);
				window.draw(sPlayer);
			}

			if (it->GetUserData() == "player2")
			{
				sPlayer.setPosition(pos.x*SCALE, pos.y*SCALE);
				sPlayer.setRotation(angle*DEG);
				sPlayer.setColor(Color::Green);
				window.draw(sPlayer);
			}

			if (it->GetUserData() == "ball")
			{
				sBall.setPosition(pos.x*SCALE, pos.y*SCALE);
				sBall.setRotation(angle*DEG);
				window.draw(sBall);
			}
		}
		window.display();
	}

	return 0;
}

结果图:

Let's make 16 games in C++(十六):Volleyball

 

 

相关文章: