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

1、首先配置Box2D的VS环境

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

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

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

④生成工程文件

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

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

 

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文件夹

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

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

 

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;
}

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;
}

结果图:

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
The following is the data that you can add to your input file (as an example). Notice that the first line is going to be a line representing your own hobbies. In my case, it is the Vitaly,table tennis,chess,hacking line. Your goal is to create a class called Student. Every Student will contain a name (String) and an ArrayList<String> storing hobbies. Then, you will add all those students from the file into an ArrayList<Student>, with each Student having a separate name and ArrayList of hobbies. Here is an example file containing students (the first line will always represent yourself). NOTE: eventually, we will have a different file containing all our real names and hobbies so that we could find out with how many people each of us share the same hobby. Vitaly,table tennis,chess,hacking Sean,cooking,guitar,rainbow six Nolan,gym,piano,reading,video games Jack,cooking,swimming,music Ray,piano,video games,volleyball Emily,crochet,drawing,gardening,tuba,violin Hudson,anime,video games,trumpet Matt,piano,Reading,video games,traveling Alex,swimming,video games,saxophone Roman,piano,dancing,art Teddy,chess,lifting,swimming Sarah,baking,reading,singing,theatre Maya,violin,knitting,reading,billiards Amy,art,gaming,guitar,table tennis Daniel,video games,tennis,soccer,biking,trumpet Derek,cooking,flute,gaming,swimming,table tennis Daisey,video games,guitar,cleaning,drawing,animated shows,reading,shopping Lily,flute,ocarina,video games,baking Stella,roller skating,sudoku,watching baseball,harp Sophie,viola,ukulele,piano,video games Step 2. Sort the student list in the ascending order of student names and print them all on the screen After reading the file and storing the data in an ArrayList<Student>, your program should sort the ArrayList<Student> in alphabetical order based on their names and then print the students' data (please see an example below). As you can see, here is the list of all students printed in alphabetical order based on their names and hobbies. You are not going to have yourself printed in this list (as you can see, this list does not have Vitaly). Alex: [swimming, video games, saxophone] Amy: [art, gaming, guitar] Daisey: [video games, guitar, cleaning, drawing, animated shows, reading, shopping] Daniel: [video games, tennis, soccer, biking, trumpet] Derek: [cooking, flute, gaming, swimming] Emily: [crochet, drawing, gardening, tuba, violin] Hudson: [anime, video games, trumpet] Jack: [cooking, swimming, music] Lily: [flute, ocarina, video games, baking] Matt: [piano, Reading, video games, traveling] Maya: [violin, knitting, reading, billiards] Nolan: [gym, piano, reading, video games] Ray: [piano, video games, volleyball] Roman: [piano, dancing, art] Sarah: [baking, reading, singing, theatre] Sean: [cooking, guitar, rainbow six] Sophie: [viola, ukulele, piano, video games] Stella: [roller skating, sudoku, watching baseball, harp] Teddy: [chess, lifting, swimming] Step 3. Find all students who share the same hobby with you and print them all on the screen Finally, your program should print the information related to the students who share the same hobby as you. In my case, it would be the following based on the above-mentioned file. There are 0 students sharing the same hobby called "hacking" with me. There are 1 students (Teddy) sharing the same hobby called "chess" with me. There are 2 students (Amy, Derek) sharing the same hobby called "table tennis" with me.
最新发布
06-10

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值