Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!
Werbeanzeige
C-/C++-Quelltext |
|
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 |
//fügt eine neue Lichtquelle in Form eines Kreises hinzu void CLightMachine::AddLightCircle(int _x, int _y, int _radius, Color _color) { //Erstellt ein neues VertexArray in Form eines Kreises mit 92 Vertices VertexArray circle(TrianglesFan, 92); //Setzt die Position des Mittelpunktes auf der Rendertextur, die die Größe des Fensters +10 hat circle[0].position.x = _x - m_ViewX + 10; circle[0].position.y = _y - m_ViewY + 10; circle[0].color = Color(255, 255, 255, _color.a); //durchläuft die einzelnen Vertices for (int angle = 1; angle <= 91; angle++) { //setzt die Position abhängig vom Radius circle[angle].position = Vector2f((_x - m_ViewX + 10) + _radius * cos(angle*4*3.1415926535 / 180), (_y - m_ViewY + 10) + _radius * sin(angle*4*3.1415926535 / 180)); //überprüft auf Kollision des Lichtstrahls mit einem soliden Block circle[angle].position = IsLineIntersecting(circle[0], circle[angle], angle*4, _radius); //setzt die Farbe circle[angle].color = Color(_color.r, _color.g, _color.b, 255); } //zeichnet den Lichtkreis m_lightTexture.draw(circle, BlendMultiply); } |
C-/C++-Quelltext |
|
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 |
Vector2f CLightMachine::IsLineIntersecting(Vertex _firstPoint, Vertex _secondPoint, int _angle, int _radius) { //wenn der Lichtstrahl außerhalb der Welt ist: Beende die Funktion und gib 0,0 zurück if (_firstPoint.position.y <= 0 && _secondPoint.position.y < _firstPoint.position.y) return Vector2f(0, 0); //setzt einen Startwert int currentRadius = 5; int x, y; bool is_intersecting = false; //läuft durch, bis der Strahl kollidiert oder den Radius erreicht hat while (is_intersecting == false) { //setzt die neue Position des Endpunktes abhängig vom derzeitigen Radius _secondPoint.position = Vector2f(_firstPoint.position.x + currentRadius * cos(_angle*3.1415926535 / 180), _firstPoint.position.y + currentRadius * sin(_angle*3.1415926535 / 180)); //berechnet Position des Blockes in der Matrix, den der Lichtstrahl schneidet (Die Blöcke sind in einer Matrix angeordnet mit Seitenlänge 100) x = (_secondPoint.position.x - 10 + m_ViewX) / 100; y = (_secondPoint.position.y - 10 + m_ViewY) / 100; //prüft, ob der entsprechende Block Licht durchlässt, oder nicht if (!m_pWorld->isBlockPassable(x, y)) { //berechne Länge des Lichtstrahles, damit er genau einen Block erleuchtet int length = 0; if ((_angle >= 45 && _angle < 135) || (_angle >= 225 && _angle < 315)) length = 100 / (abs(sin(_angle*3.1415926535 / 180))); else length = 100 / (abs(cos(_angle*3.1415926535 / 180))); //prüft, ob die Länge des Lichtstrahls den Radius überschreitet und setzt die Länge ggf. auf diesen if (currentRadius + length > _radius) _secondPoint.position = Vector2f(_firstPoint.position.x + _radius * cos(_angle*3.1415926535 / 180), _firstPoint.position.y + _radius * sin(_angle*3.1415926535 / 180)); else _secondPoint.position = Vector2f(_firstPoint.position.x + (length + currentRadius) * cos(_angle*3.1415926535 / 180), _firstPoint.position.y + (currentRadius + length) * sin(_angle*3.1415926535 / 180)); //gibt den neuen Endpunkt des Lichtstrahls zurücl return _secondPoint.position; } //kollidierte der Lichtstrahl nicht: erhöhe den Radius um 2 (bzw. 10, wenn schnelle Lichtberechnung eingestellt ist) if (m_fastLight) currentRadius += 10; else currentRadius += 2; //ist der Lichtstrahl bis jetzt nicht kollidiert, aber der Radius überschritten: gib Ausgangspunkt zurück if (currentRadius > _radius) return _secondPoint.position; } return _secondPoint.position; } |
C-/C++-Quelltext |
|
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 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
Vector2f CLightMachine::IsLineIntersecting(Vertex _firstPoint, Vertex _secondPoint, int _angle, int _radius) { //Wenn der Strahl außerhalb der Welt ist: gib 0,0 zurück if (_firstPoint.position.y <= 0 && _secondPoint.position.y < _firstPoint.position.y) return Vector2f(0, 0); int lastX, lastY; Vector2f firstCollisionPoint(-1, -1); Vector2f secondCollisionPoint(-1, -1); //Berechne Position des Startpunktes des Strahls int x = _firstPoint.position.x - 10 + m_ViewX; int y = _firstPoint.position.y - 10 + m_ViewY; //die Position des ersten Kollisionspunktes int xA = 0; int yA = 0; //Der Betrag, der in jedem Schritt addiert wird int stepX = 0; int stepY = 0; //Prüfe Kollision mit Horizontalen nach oben if (_angle >= 180) { //Berechne die y-Koordinate des nächsten Kollisionspunktes, durch den der Lichtstrahl geht yA = (y / 100) * 100 - 1; //Berechne die x-Koordinate des nächsten Kollisionspunktes, durch den der Lichtstrahl geht xA = x + (y - yA) / tan(_angle*3.1415926535 / 180); if (yA < 0 || xA < 0) { firstCollisionPoint = _secondPoint.position; } //ist der Block solide: speichere diesen Punkt als Kollisionspunkt mit der Horizontalen else if (!m_pWorld->isBlockPassable(xA / 100, yA / 100)) { firstCollisionPoint = Vector2f(xA - m_ViewX + 10, yA - m_ViewY + 10); } //Berechne den Betrag, der in jedem Schritt addiert wird stepX = 100 / tan(_angle*3.1415926535 / 180); stepY = -100; } //Prüfe Kollision mit Horizontalen nach unten else { yA = (y / 100) * 100 + 100; xA = x + (y - yA) / tan(_angle*3.1415926535 / 180); if (yA < 0 || xA < 0) { firstCollisionPoint = _secondPoint.position; } else if(!m_pWorld->isBlockPassable(xA / 100, yA / 100)) { firstCollisionPoint = Vector2f(xA - m_ViewX + 10, yA - m_ViewY + 10); } stepX = 100 / tan(_angle*3.1415926535 / 180); stepY = 100; } bool is_intersecting = false; if (firstCollisionPoint.x != -1 && firstCollisionPoint.y != -1) { while (is_intersecting == false) { //Berechne den nächsten Kollisionspunkt xA = xA + stepX; yA = yA + stepY; if (yA < 0 || xA < 0) { firstCollisionPoint = _secondPoint.position; is_intersecting = true; } //Prüfe, ob der Strahl nun länger als der Radius ist else if (sqrt(pow(x - xA, 2) + pow(y - yA, 2)) > _radius) { firstCollisionPoint = Vector2f(_firstPoint.position.x + _radius * cos(_angle*3.1415926535 / 180), _firstPoint.position.y + _radius * sin(_angle*3.1415926535 / 180)); is_intersecting = true; } //Prüfe, ob der Endpunkt des Strahls in einem soliden Block liegt else if (!m_pWorld->isBlockPassable(xA / 100, yA / 100)) { firstCollisionPoint = Vector2f(xA - m_ViewX + 10, yA - m_ViewY + 10); is_intersecting = true; } } } //das gleiche wird nun mit der Vertikalen durchgeführt, sodass man am Ende einen Kollisionspunkt mit der Horizontalen und einen mit der Vertikalen hat //Prüfe Kollision mit Vertikalen nach links if (_angle <= 90 || _angle > 315) { xA = (x / 100) * 100 - 1; yA = y + (x - xA) * tan(_angle*3.1415926535 / 180); if (yA < 0 || xA < 0) { secondCollisionPoint = _secondPoint.position; } else if (!m_pWorld->isBlockPassable(xA / 100, yA / 100)) { secondCollisionPoint = Vector2f(xA - m_ViewX + 10, yA - m_ViewY + 10); } stepX = -100; stepY = 100 * tan(_angle*3.1415926535 / 180); } else { xA = (x / 100) * 100 + 100; yA = y + abs(x - xA) * tan(_angle*3.1415926535 / 180); if (yA < 0 || xA < 0) { secondCollisionPoint = _secondPoint.position; } else if (!m_pWorld->isBlockPassable(xA / 100, yA / 100)) { secondCollisionPoint = Vector2f(xA - m_ViewX + 10, yA - m_ViewY + 10); } stepX = 100; stepY = 100 * tan(_angle*3.1415926535 / 180); } is_intersecting = false; while (is_intersecting == false) { xA = xA + stepX; yA = yA + stepY; if (yA < 0 || xA < 0) { secondCollisionPoint = _secondPoint.position; is_intersecting = true; } else if (sqrt(pow(x - xA, 2) + pow(y - yA, 2)) > _radius) { secondCollisionPoint = Vector2f(_firstPoint.position.x + _radius * cos(_angle*3.1415926535 / 180), _firstPoint.position.y + _radius * sin(_angle*3.1415926535 / 180)); is_intersecting = true; } else if (!m_pWorld->isBlockPassable(xA / 100, yA / 100)) { secondCollisionPoint = Vector2f(xA - m_ViewX + 10, yA - m_ViewY + 10); is_intersecting = true; } } //gib den Punkt zurück, bei dem die Länge des Strahls kürzer ist if (sqrt(pow(firstCollisionPoint.x - x, 2) + pow(firstCollisionPoint.y - y, 2)) < sqrt(pow(secondCollisionPoint.x - x, 2) + pow(secondCollisionPoint.y - y, 2))) return firstCollisionPoint; else return secondCollisionPoint; } |
Administrator
Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von »Roflo« (15.05.2015, 15:05)
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Roflo« (15.05.2015, 17:06)
Weil ich es noch nirgends gelesen habe (hoffe habe es nicht überlesen )
Die Performanceprobleme treten im Release-Modus auf?
@Koshi what the...? versteh nur Bahnhof!
Ich glaube du irrst dich im Thread
...Ich habe im Nachhinein das Gefühl, dass die krassen Performanceprobleme (teilweise 1 Frame pro Sekunde) erst nach Verwendung eines Profilers aufgetreten sind...
Werbeanzeige