Программа Динамического Освещения с SFML, преобразованием 1.6 в 2.x

Я нашел этот sfml руководство написано еще в 2009 году и я пытаюсь преобразовать его в 2.4.

Я не смог преобразовать эти 2 строки:

win.draw(sf::Shape::Rectangle(le.Blocks[0].fRect, sf::Color(255, 0, 0)));

rt.draw(sf::Shape(sf::Shape::Line(l.position, end, 1, l.color)));

Я пытался конвертировать, используя sf :: RectangleShape, как это было предложено на форумах SFML, но я просто не могу найти подходящие аргументы, чтобы соответствовать. Вот полный код, преобразованный в 2.x за исключением этих двух строк.

Если кто-то будет достаточно любезен, чтобы «завершить» преобразование, я был бы очень благодарен, и я уверен, что этот урок был бы полезен для других.

ГЛАВНЫЙ:

#include <SFML/Graphics.hpp>
#include <iostream>
#include "LightEngine.h"
int main()
{
sf::RenderWindow win(sf::VideoMode(800, 600), "Light Tutorial");
sf::Event event;

LightEngine le;

Light light;
light.radius = 600;
light.angleSpread = 100;
light.position = sf::Vector2f(100, 150);
le.Lights.push_back(light);

Block block;
block.fRect = sf::FloatRect(0, 0, 50, 50);
le.Blocks.push_back(block);while (win.isOpen())
{
while (win.pollEvent(event))
{
if (event.type == sf::Event::Closed) win.close();
}

win.clear();

le.Blocks[0].fRect.left = sf::Mouse::getPosition(win).x;
le.Blocks[0].fRect.top = sf::Mouse::getPosition(win).y;
/*HERE*/ win.draw(sf::Shape::Rectangle(le.Blocks[0].fRect, sf::Color(255, 0, 0)));
le.Step(win);

win.display();
}
}

LightEngine.h

#pragma once//don't allow this header to be included more than once
#include "Light.hpp"#include "Block.hpp"#include <vector>
#include <SFML/Graphics/RenderTarget.hpp> //Place to draw on
#include <SFML/Graphics/Shape.hpp> //SFML programmable Shapes

class LightEngine
{
public:
void Step(sf::RenderTarget &rt);

std::vector <Light> Lights; //Container for Lights

std::vector <Block> Blocks; //Container for Blocks
private:

void ShineLight(Light &lig, sf::RenderTarget &rt);

static const float Distance(const sf::Vector2f &p1, const sf::Vector2f &p2);
static const sf::Vector2f GetCenter(const sf::FloatRect &fr); //Get the center of a rectanglestruct FindDistance //if a light's radius manages to intersect multiple blocks, we need to find the sortest distance to shorten the light
{
FindDistance();
float shortest;
bool LightHitsBlock(Light &l, Block &b, const float cur_ang, float &reflength);
bool start; //to get the first distance to refer off of
};

FindDistance findDis;
};

LightEngine.cpp

#include "LightEngine.h"

LightEngine::FindDistance::FindDistance()
{
start = false;
shortest = 0;
}

const sf::Vector2f LightEngine::GetCenter(const sf::FloatRect &fr)
{
return sf::Vector2f(fr.left + (fr.width / 2), fr.top + (fr.height / 2));
}

const float LightEngine::Distance(const sf::Vector2f &p1, const sf::Vector2f &p2)
{
//We need to look at this as a triangle

/*
/|p1.y
/ |
/  |
/   |
/    |
/     |b
/      |
/       |
/        |
/         |
-----------
a     p2.y
p1.x           p2.x

*/

float a = p2.x - p1.x;  //width length
float b = p2.y - p1.y; //height length
float c = sqrt((a * a) + (b * b)); //Pythagorean Theorem. (c² = a² + b²). c = squareroot(a² + b²)

return c;
}

void LightEngine::Step(sf::RenderTarget &rt)
{
for (unsigned i = 0; i < Lights.size(); i++)
{
ShineLight(Lights[i], rt); //Shine all lights
}
}

void LightEngine::ShineLight(Light &l, sf::RenderTarget &rt)
{
/*
remember back in the Light class, we had something called 'angleSpread' ?
that's to create a tunnel, or arc shaped light. Like this:
/)
/  )
/    )
/      )
<       )
\      )
\    )
\  )
\)

Obviously it'll look better than an ascii drawing
*/

float current_angle = l.angle - (l.angleSpread / 2); //This will rotate the angle back far enough to get a desired arc

/*
Lights Angle (if it was at 0):

-------------

Current_Angle:
/
/
/
(slanted)

*/

float dyn_len = l.radius; //dynamic length of the light. This will be changed in the function LightHitsBlock()

float addto = 1.f / l.radius;
for (current_angle; current_angle < l.angle + (l.angleSpread / 2); current_angle += addto * (180.f / 3.14f)) //we need to add to the current angle, until it reaches the end of the arc. we divide 1.f by radius for a more solid shape. Otherwize you could see lines seperating
{
dyn_len = l.radius; //Reset the length
findDis.start = true; //Start of finding a light, we need to reset
findDis.shortest = 0; //Reset the shortest.if (l.dynamic) //can this change?
{
for (unsigned i = 0; i < Blocks.size(); i++)
{
findDis.LightHitsBlock(l, Blocks[i], current_angle, dyn_len);
}
}float radians = current_angle * (3.14f / 180); //Convert to radians for trig functions

sf::Vector2f end = l.position;
end.x += cos(radians) * dyn_len;
end.y += sin(radians) * dyn_len;
/*HERE*/rt.draw(sf::Shape(sf::Shape::Line(l.position, end, 1, l.color)));
}
}

bool LightEngine::FindDistance::LightHitsBlock(Light &l, Block &b, float cur_ang, float &refleng)
{
if (b.allowBlock) //can this even block?
{
float distance = Distance(l.position, GetCenter(b.fRect));

if (l.radius >= distance) //check if it's radius is even long enough to hit a block
{
float radians = cur_ang * (3.14f / 180); //convert cur_ang to radians for trig functions
sf::Vector2f pointpos = l.position;

pointpos.x += cos(radians) * distance;
pointpos.y += sin(radians) * distance;
//By doing this, we check if the angle is in the direciton of the block.

if (b.fRect.contains(pointpos)) //If it was, than the point would be intersecting the rectangle of the block
{
if (start || distance < shortest) //If this is the first block, or it has a shorter distance
{
start = false; //definately not the start so other blocks can't automatically set the distance
shortest = distance; //shortest is set to this
refleng = distance; //This is where the dynamic comes in, it changes the length of the reference towhere it's going to stop after it hits the distance from the point to the block
}
return true;
}
}
}
return false;
}

Block.hpp

#pragma once//don't allow this header to be included more than once
#include <SFML/Graphics/Rect.hpp>

class Block
{
public:
Block()
{
allowBlock = true;
fRect = sf::FloatRect(0, 0, 0, 0);
}
/* Like the light class, you can do this in an initializer list, whatever works for you

Block()
: fRect(0,0,0,0), allowBlock(false)
{
}
*/

sf::FloatRect fRect; //Area that will be blocking light
bool allowBlock; //Sometimes we want to keep a block, but don't want it to actually block until a certain point
};

2

Решение

win.draw (sf :: Shape :: Rectangle (le.Blocks [0] .fRect, sf :: Color (255, 0, 0)));

было бы:

sf::RectangleShape rshape;

rshape.setSize(sf::Vector2f(le.Blocks[0].fRect.width, le.Blocks[0].fRect.height));
rshape.setPosition(le.Blocks[0].fRect.left, le.Blocks[0].fRect.top);
rshape.setFillColor(sf::Color(255, 0, 0));

win.draw(rshape);

Соответственно:

rt.draw (sf :: Shape :: Line (l.position, end, 1, l.color));

Поскольку больше нет формы линии:

sf::Vertex line[] =
{
sf::Vertex(l.position, l.color),
sf::Vertex(end, l.color)
};

rt.draw(line, 2, sf::Lines);
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]