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
Community-Fossil
Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »BlueCobold« (09.11.2016, 06:59)
Ah ja. Du glaubst also, dass du es bei floats tatsächlich schaffst, dass alle drei Member genau 1,0000000 HP haben, obwohl du vorher immer den Schaden durch 3 (oder N) teilst, somit höchst wahrscheinlich immer sehr nette und für floats nicht darstellbare Kommazahlen bekommst und diese von irgendwas mehrfach abziehst?
Ah ja. Du glaubst also, dass du es bei floats tatsächlich schaffst, dass alle drei Member genau 1,0000000 HP haben, obwohl du vorher immer den Schaden durch 3 (oder N) teilst, somit höchst wahrscheinlich immer sehr nette und für floats nicht darstellbare Kommazahlen bekommst und diese von irgendwas mehrfach abziehst? Man kann sicherlich eine Regel einbauen, die prüft, ob alle genau 1,000000 HP haben, aber was soll das bringen? Sie ist für die Praxis irrelevant. Oder willst du das auch für 2,0000000 und 3,000000 HP einbauen? Oder auch für selektierte Kommazahlen? Wenn dem so ist, dann sind deine floats nutzlos. Der Witz, dass 2 Typen von 3 sterben, tritt ja nur deswegen ein, weil der Schaden eben nicht durch 3, sondern nur durch 2 geteilt wird. Warum du das genau machst, wo du doch gesagt hast, dass durch N teilen kein Problem wäre - und wo alle 3 auch noch leben würden - erschließt sich mir nicht so recht.
Siehst du jetzt den Widerspruch?
Alternative: Wie viel des eingehenden Schadens verteilt wird, hängt nur vom Lifelink, nicht aber von den angebundenen Einheiten ab. So kann man später dafür sorgen, dass der LifeLink besser oder schlechter wird.
Der LifeLink könnte bspw. pauschal 10 %, 25 %, ... des eingehenden Schadens an die angebundene Einheit weiterleiten. Werden weitere Einheiten angebunden, gilt dafür dann entweder der gleiche Prozentwert oder der Prozentwert könnte von den Anzahl der Links abhängig sein. Weiterhin sollte die Anzahl der Links begrenzt sein.
Erhält der Charakter mehr Schaden, sodass eine angebundene stirbt, könnte der "überschüssige" Schaden verloren gehen oder wieder der Einheit angerechnet werden. Bei letzterem könnte dieser Schaden wieder verteilt werden, oder direkt der Einheit angerechnet werden, als Strafe dafür, dass ein Link zerstört wurde.
Die Verbindungen könnten entweder immer von der Einheit aufgebaut werden, die mit den anderen verbunden werden soll, oder von einer dritten Einheit, die eher als "Supporter" zu bezeichnen wäre. In beiden Fällen könnte es sinnvoll sein, dass nur bestimmte Einheiten diese Fähigkeit anwenden können. Es wäre auch möglich, dass von den ersten beiden Möglichkeiten beides vorhanden ist, es den Supporter aber mehr kosten würde.
Letztendlich ist das eine Game Design Entscheidung, keine Performance-Entscheidung. Man muss auch darauf achten, dass diese Fähigkeit nicht zu stark im Vergleich zu anderen Fähigkeiten wird. Auch muss man darauf achten, dass die Verbindungen dem Spieler am Ende sinnvoll präsentiert werden und dass er diese Verbindungen sinnvoll aufbauen kann.
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].
Community-Fossil
Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer
Ich verstehe dein Problem nicht. Du hast Schaden X, den teilst du durch N. Jede Einheit bekommt also S=X/N Schaden. Entweder hat sie mehr HP als das und bleibt am Leben oder sie hat weniger HP als das und ist tot. Wenn dabei ein Overkill auftritt, weil S>HP ist, bleibt ein Rest, den du nun entweder wieder an die restlichen (bedingt durch Rundungsfehler eventuell noch am Leben gebliebenen Member) verteilen musst via S/(N-1), womit der Damage-Algo rekursiv wird, oder du lässt ihn einfach verfallen. Das ist eine Design-Entscheidung.Du darfst mir natürlich auch gerne zeigen, wie ich meine Unit nun mit minimalster HP am Leben halte ohne auf einen minimal Wert zu prüfen.
Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »BlueCobold« (09.11.2016, 12:50)
@anti-freak: kann es sein, dass du meinen Beitrag übersehen hast? Was hältst du von der Alternative, die ich vorgeschlagen habe?Alternative: Wie viel des eingehenden Schadens verteilt wird, hängt nur vom Lifelink, nicht aber von den angebundenen Einheiten ab. So kann man später dafür sorgen, dass der LifeLink besser oder schlechter wird.
Der LifeLink könnte bspw. pauschal 10 %, 25 %, ... des eingehenden Schadens an die angebundene Einheit weiterleiten. Werden weitere Einheiten angebunden, gilt dafür dann entweder der gleiche Prozentwert oder der Prozentwert könnte von den Anzahl der Links abhängig sein. Weiterhin sollte die Anzahl der Links begrenzt sein.
Erhält der Charakter mehr Schaden, sodass eine angebundene stirbt, könnte der "überschüssige" Schaden verloren gehen oder wieder der Einheit angerechnet werden. Bei letzterem könnte dieser Schaden wieder verteilt werden, oder direkt der Einheit angerechnet werden, als Strafe dafür, dass ein Link zerstört wurde.
Die Verbindungen könnten entweder immer von der Einheit aufgebaut werden, die mit den anderen verbunden werden soll, oder von einer dritten Einheit, die eher als "Supporter" zu bezeichnen wäre. In beiden Fällen könnte es sinnvoll sein, dass nur bestimmte Einheiten diese Fähigkeit anwenden können. Es wäre auch möglich, dass von den ersten beiden Möglichkeiten beides vorhanden ist, es den Supporter aber mehr kosten würde.
Letztendlich ist das eine Game Design Entscheidung, keine Performance-Entscheidung. Man muss auch darauf achten, dass diese Fähigkeit nicht zu stark im Vergleich zu anderen Fähigkeiten wird. Auch muss man darauf achten, dass die Verbindungen dem Spieler am Ende sinnvoll präsentiert werden und dass er diese Verbindungen sinnvoll aufbauen kann.
Ich würde dir, wie aus dem Beitrag vielleicht hervorgeht, stark von einem strikten "am Leben erhalten" abraten. Nicht weil die Implementation dabei problematisch wäre, sondern eher, weil es sonst einen viel zu großen Vorteil liefern würde und ein Balancing mit den anderen Spielmechaniken erschweren würde. Ein Nebeneffekt wäre natürlich, dass man sich um das "Am Leben erhalten" keine Gedanken machen muss, und man könnte tendenziell performantere Implementationen finden, sollte das für dich noch von Bedeutung sein.
Aber wie geschrieben: im wesentlichen ist hier eine Entscheidung bezüglich des Game Design erforderlich.
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 |
Stat LifeLinkComponent::shareDmgWithLifeLinkMembers(Stat _damage, const CastableInfo& _dealerInfo) { Stat totalPoolHp = 0; auto pool = _generateUniqueUnitPool(totalPoolHp); // kill every member of our pool (except the original unit) if (totalPoolHp <= _damage) { for (auto unit : pool) { Stat damageToUnit = unit->getHealth(); unit->applyDamageWithoutModifiers(damageToUnit, _dealerInfo); _damage -= damageToUnit; } return _damage; } auto poolCopy = pool; while (!pool.empty() && _damage > 0) { auto damageForEach = _damage / (pool.size() + 1); auto& unit = *pool.back(); pool.pop_back(); static const Stat minHP = 1.f; if (unit.getHealth() <= minHP) continue; auto damageToStayAlive = unit.getHealth() - minHP; auto damageToUnit = damageToStayAlive < damageForEach ? damageToStayAlive : damageForEach; _damage -= damageToUnit; unit.applyDamageWithoutModifiers(damageToUnit, _dealerInfo); } auto selfHp = m_Unit.getHealth(); for (auto itr = std::begin(poolCopy); itr != std::end(poolCopy) && _damage >= selfHp; ++itr) { auto& unit = **itr; auto damageToUnit = unit.getHealth(); _damage -= damageToUnit; unit.applyDamageWithoutModifiers(damageToUnit, _dealerInfo); } return _damage; } |
Dann lies bitte meine anderen Posts. Ich muss das nicht in jedem Beitrag wieder und wieder wiederholen.Ich verstehe dein Problem nicht. Du hast Schaden X, den teilst du durch N. Jede Einheit bekommt also S=X/N Schaden. Entweder hat sie mehr HP als das und bleibt am Leben oder sie hat weniger HP als das und ist tot. Wenn dabei ein Overkill auftritt, weil S>HP ist, bleibt ein Rest, den du nun entweder wieder an die restlichen (bedingt durch Rundungsfehler eventuell noch am Leben gebliebenen Member) verteilen musst via S/(N-1), womit der Damage-Algo rekursiv wird, oder du lässt ihn einfach verfallen. Das ist eine Design-Entscheidung.Du darfst mir natürlich auch gerne zeigen, wie ich meine Unit nun mit minimalster HP am Leben halte ohne auf einen minimal Wert zu prüfen.
Wieso aber irgendwas mit minimalstem HP am Leben bleiben sollte, ist mir unklar.
Community-Fossil
Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer
Zitat von »BlueCobold«
Falls du Angst vor Rundungsfehlern hast oder unbedingt jeden solange wie möglich am Leben halten willst: http://ideone.com/n2SaV3 Hat allerdings die Bedingung, dass HP==0 noch nicht tot ist, sondern erst HP < 0. Ansonsten müsstest du einen Threshold definieren wie tief HP denn mit diesem Algo gehen dürfte. Das ist sicher nicht sinnvoll, weil ja beliebig klein zwischen 0 und 1.
Lass solche persönlichen Angriffe lieber bleiben, meine sind härter.
... und diese Signatur kürzer!
- übersichtlicher
- logischer
- verständlicher
Community-Fossil
Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer
Ich habe meinen Vorschlag sogar in C++ umgesetzt und verlinkt. Was willst du mehr?Warum macht ihr nicht jeder einen Vorschlag und dann wird verglichen, wie sich jeder Algorithmus unter verschiedenen Umständen verhält!?
Werbeanzeige