2017-06-18 4 views
2

Ich fand diese sfml tutorial im Jahr 2009 geschrieben und ich versuche, es in 2.4 zu konvertieren.Dynamic Lighting Programm mit SFML, 1,6 bis 2.x Konvertierung

ich nicht in der Lage gewesen, diese 2 Zeilen zu konvertieren:

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

Ich habe versucht, mit sf :: RectangleShape zu konvertieren, wie in den SFML Foren vorgeschlagen vorbei, aber ich kann einfach nicht das bekommen finden richtige Argumente zu passen. Hier ist der vollständige Code, der mit Ausnahme dieser 2 Zeilen in 2.x konvertiert wurde.

Wenn jemand so freundlich wäre, die Konvertierung "abzuschließen", wäre ich sehr dankbar und ich bin mir sicher, dass dieses Tutorial für andere hilfreich wäre.

MAIN:

#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 rectangle 


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

Antwort

2

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

wäre:

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

Dementsprechend:

rt.draw (sf :: :: Form Line (l.position, Ende, 1, l.color));

Da es keine Linienform ist mehr:

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

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

Gute Arbeit, danke. Nur eine Sache für jeden hinzufügen, der den Code verwenden möchte: rshape.setSize-Parameter sollten innerhalb von sf :: Vector2f sein –

+0

@ NathanielG.M. Du hast Recht, danke, ich habe es korrigiert. – nvoigt