Seit etwa einem Jahr Schneeballspiel, ein Plug-In, das auf Minecrafts Multiplayer-Serversoftware Spigot funktioniert. Ich mache ein Schneeballspiel.35339 /). Zusätzlich zu den Grundfunktionen Schlagen, Werfen und Fangen denke ich, dass ich in der Lage bin, etwas zu machen, das einigermaßen zufriedenstellend ist, wie die automatische Beurteilung des Wechsels von Bällen und Schlagzonen und eine Klopffunktion mit einem gewissen Grad an Genauigkeit.
Dies ist fast wie der erste Java-Code, den ich in meinem Leben geschrieben habe, und ich bin immer noch auf einem Niveau, auf dem ich kaum sagen kann, dass ich ein Anfänger bin. Außerdem ist der Code dieses Plug-Ins extrem schmutzig, da ich ihn entwickelt habe, indem ich nacheinander Funktionen hinzugefügt habe, nachdem ich das Basisteil mit einer ziemlich einfachen Konstruktion erstellt habe.
Derzeit kann der Quellcode veröffentlicht auf Github unter der Lizenz von Spigot den Menschen nicht gezeigt werden, und es ist schwierig, fast die gesamte Geschichte zu lesen. Es besteht aus Teilen und Tauchpunkten. Außerdem gibt es keine Kommentare in der Zeile. (Weil ich mich gefragt habe, ob ich auf Englisch schreiben soll oder nicht)
Bis zu diesem Punkt konnte ich den Inhalt erfassen, da mir die Funktionen in den Sinn gekommen sind, die ich regelmäßig hinzufügen möchte, aber ich bin sicher, ich werde nie wissen, was sie sind. Daher möchte ich es so weit umgestalten, dass es vorerst zu einer Form wird.
Für diese Arbeit habe ich diesen Artikel mit der Absicht geschrieben, Dinge wie "Was ich gedacht und geschrieben habe" auf Japanisch anstelle von Code zusammenzufassen. Obwohl dieser Artikel hauptsächlich für mich selbst geschrieben wurde, hoffe ich, dass er nützlich ist, wenn jemand andere Sport-Plug-Ins entwickeln möchte.
Zuallererst die Implementierung des gebundenen Teils des Balls, der in jedem Ballspiel absolut notwendig zu sein scheint.
Da es in Minecraft keine diagonalen Ebenen gibt, wird die Sprungbewegung durch "Umkehren nur einer der X-, Y- oder Z-Koordinaten des Bewegungsvektors des Objekts in Abhängigkeit von der Ebene, auf die es trifft" ersetzt.
Wenn in Spigot der verwendete Ball Projectile ist, blockiert ProjectileHitEvent den Ball. / Kann "Kollision mit Entität" erkennen.
Für welche Seite Sie treffen, hat Spigot einen Typ namens BlockFace, so dass Sie `` event.getHitBlock (). GetFace (event.getEntity (). GetLocation (). GetBlock ())
`ausführen können. Wenn Sie es tun, können Sie es bekommen. Wenn danach die erfasste Blockfläche AUF oder AB ist, kann das Y der Geschwindigkeit des Balls invertiert werden, wenn es OST oder WEST ist, kann X invertiert werden, und wenn es SÜD oder NORD ist, kann Z invertiert werden.
Zum Zeitpunkt des Aufrufs von ProjectileHitEvent ist der ursprüngliche Ball bereits aus dem Spiel verschwunden. Daher ruft World.spawnEntity (Location, EntityType) einen neuen Ball auf und kehrt ihn um. Es ist notwendig einzustellen.
Bei dieser Methode gibt es jedoch ein Problem. Block.getFace (Block) gibt BlockFace nur zurück (wird null), wenn der ursprüngliche Block und der Argumentblock nebeneinander liegen. Dies ist ein großes Problem, da die Position des Balls und die Position des Blocks zum Zeitpunkt des Ereignisses durch einen Block oder mehr getrennt sein können, wenn die Geschwindigkeit des Balls schneller als ein bestimmtes Niveau ist. Zusätzlich gibt BlockFace Werte an diagonalen Positionen wie Südwesten und Nordnordosten zurück, zusätzlich zu den sechs Nord-, Süd-, Ost- und Westpositionen. Dieses Problem scheint gelöst zu sein, indem "ToString von BlockFace geschrieben und X invertiert wird, wenn EAST oder WEST enthalten ist, und Z, wenn SOUTH oder NORTH enthalten sind". Wenn Sie es versuchen, können Sie sehen, dass der Bereich der "diagonalen Beurteilung" ziemlich groß ist und die Bewegung ein wenig eingängig ist.
Wenn das zurückgegebene BlockFace null ist oder \ _ wie SOUTH_EAST enthält, muss es daher entweder nach oben, unten, Osten, Westen, Norden oder Süden korrigiert werden. Der Teil dort ist [BlockIterator](https://hub.spigotmc.org/javadocs/spigot/org/bukkit/util/BlockIterator.html#BlockIterator-org.bukkit.World-org.bukkit.util.Vector-org. Ich habe es so geschrieben mit bukkit.util.Vector-double-int-).
hitFaceModifier
if(hitFace == null || hitFace.toString().contains("_")){
BlockIterator blockIterator = new BlockIterator(hitLoc.getWorld(), hitLoc.toVector(), velocity, 0.0D, 3);
Block previousBlock = hitLoc.getBlock();
Block nextBlock = blockIterator.next();
while (blockIterator.hasNext() && (!Util.doesRepel(nextBlock) ||nextBlock.isLiquid() || nextBlock.equals(hitLoc.getBlock()))) {
previousBlock = nextBlock;
nextBlock = blockIterator.next();
}
hitFace = nextBlock.getFace(previousBlock);
}
Kurz gesagt, holen Sie den Block in Richtung der Bewegungsvektorrichtung des Balls von den Koordinaten des Balls, wenn er trifft, überprüfen Sie in der Reihenfolge "Ist es ein Block, der springen kann" und verlassen Sie die Schleife, wenn dies in Ordnung ist Der Mechanismus ist derart, dass der Block in dieser Richtung die dem ursprünglichen Block benachbarte Oberfläche als "Kollisionsfläche" zurückgibt. Auch hier gibt es viel zu entdecken, aber im Grunde funktioniert es.
Wenn es auf diese Weise implementiert wird, kann es von Blöcken abprallen, für die Sie kein Trefferurteil wie eine Ananas wünschen, oder es kann beurteilt werden, dass es die Seitenfläche eines Teppichs oder eines Redstone-Drahtes getroffen hat, abhängig von dem Winkel, in dem es trifft, was zu einem seltsamen Verhalten führt. Um dies zu verhindern, "Wenn Sie diese Art von Block treffen, überschreiben Sie ihn mit UP" "Diese Art von Block sollte vom Ball vermieden werden, wenn er trifft (Projectile HitEvent ist jedoch nicht abbrechbar, daher müssen Sie die Bewegung selbst neu schreiben Es gibt) ”, es kann gut sein, eine Liste im Voraus zu erstellen. Ich habe es in diesem Format geschrieben, bin mir aber im Code dort nicht sehr sicher, deshalb werde ich es hier weglassen.
Wenn Sie es so beschreiben und die Geschwindigkeit reduzieren, um es an den Abstoßungskoeffizienten des Balls anzupassen, können Sie vorerst den richtigen Sprung implementieren. Wenn Sie es jedoch so machen, scheint es, dass "Wenn Sie versuchen, die Rolldistanz des Goros der Realität näher zu bringen." Probleme wie "Der erste Sprung springt zu stark" und "Wenn der Sprung der Fliege auf ein angemessenes Niveau eingestellt ist, rollt sie wie eine Eisenkugel" treten auf. (Ist dies die Ursache für das abnormale Rollen des Balls in einem berühmten Original-Baseballspiel, das für eine Weile zu einem heißen Thema wurde?) Daher schreibe ich: "Je schneller die Ballgeschwindigkeit zum Zeitpunkt des Abpralls ist, desto größer ist die Verzögerung" und "je kleiner der Winkel zwischen dem Normalenvektor der zurückprallenden Oberfläche und dem Vektor nach dem Abprall des Balls ist, desto größer ist die Verzögerung". Je schneller der Ball im rechten Winkel trifft, desto leichter fällt der Ball zusammen und der Boden kann gegraben werden. Die Verlustkraft ist also größer, aber es gibt keine richtigen Daten und ich passe sie an meine eigenen Gefühle an. Wegen der Eignung dieses Gebiets habe ich den Titel "ähnliche" Physik genannt.
Außerdem möchte ich irgendwie die Schwierigkeit der einseitigen Kurve zum Ausdruck bringen, die in die entgegengesetzte Richtung der Änderung springt, und den Ärger, in die Foul-Zone zu entkommen, wenn die Fliege, die beim Schneiden schneidet, springt. Der Spin von wird dem Ball als Metadaten in Form eines Rotationsvektors gegeben, und dieser Wert wird zum Zeitpunkt des Springens verwendet, so dass die Rotation in gewissem Maße reflektiert wird.
Dies ist jedoch ziemlich problematisch, und im Allgemeinen ist die Auswirkung der Rotation auf die Bewegung beim Abprallen des Balls "proportional zum äußeren Produkt des Bodennormalenvektors und des Ballrotationsvektors (Vektordarstellung der Rotation)". Dies erfüllt jedoch nicht die obigen Anforderungen. Aus der Sicht des rechten Flügelspielers wird angenommen, dass ein getroffener Ball, der in Richtung der Foulzone schneidet, dieselbe Rotationsachse hat wie ein rechtshändiger First Baseman, der einen Schuss in Richtung der hellen Seite wirft. Wenn Sie versuchen zu befriedigen, ist die Richtung der Änderung zum Zeitpunkt des Springens zwischen der ersteren und der letzteren völlig entgegengesetzt.
Ich bin mir nicht sicher, welche Ursache dieses Phänomen hat. Daher: "Wenn es sich um eine Low-Liner-Flugbahn handelt, die nicht zum Außenfeld fliegt, sollte sie möglicherweise zur Seite der fairen Zone springen. Wenn es sich um eine Fliege handelt, sollte sie zur Seite der Foul-Zone springen." Es ist so geschrieben, dass der Sprung in einer Richtung geändert wird, die proportional zum äußeren Produkt von "dem Vektor der Bewegung des Balls vor dem Umkehren des Sprunges" ist.
Dies erklärt jedoch nicht die entgegengesetzte Richtung des Tennisscheibenaufschlags und die Wurfkurve des Werfers. Es ist also wahrscheinlich eine klare Fehlimplementierung dessen, was physisch nicht streng ist. Er gibt jedoch auf, weil er nicht in der Lage ist, die richtigen Gesetze der Physik zu finden und umzusetzen. Diejenigen, die mit Physik vertraut sind, würde mich sehr freuen, wenn Sie mir diesbezüglich etwas erzählen könnten. Wenn die Anzahl der Umdrehungen hoch ist und der Ball beim Abprallen rutscht, entkommt er dann in die Foulzone? Ich habe darüber nachgedacht, aber ich weiß nicht, wie ich es beschreiben soll.
Der Rest wurde aufgeteilt, weil es länger war als ich erwartet hatte, nur mit Buchstaben. Werfen und Schlagen Fangen / Tipps
Recommended Posts