I've got 2 BALLS

Nächste GameJam, vom 1.11. bis 30.11.
Antworten
Benutzeravatar
Jonathan
Establishment
Beiträge: 2835
Registriert: 04.08.2004, 20:06
Kontaktdaten:

I've got 2 BALLS

Beitrag von Jonathan »

I've got some 2 BALLS

Ein Clone / Nachfolger zum Klassiker "I've got some BALLS".

(Details folgen)
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Jonathan
Establishment
Beiträge: 2835
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Arbeitstitel

Beitrag von Jonathan »

Hachja, hab eigentlich diesen Monat so viel anderes zu tun, aber rein aus Trotz dennoch mit meiner Idee angefangen:
2025-11-11_21-09-38_Balls.png
Weitere Details folgen, hoffentlich.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Schrompf
Moderator
Beiträge: 5278
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: Arbeitstitel

Beitrag von Schrompf »

Coole Sache! Ich freu mich, dass Du dabei bist!
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
grinseengel
Establishment
Beiträge: 972
Registriert: 29.03.2011, 13:47
Echter Name: Andreas

Re: Arbeitstitel

Beitrag von grinseengel »

Sehr gut, noch ein weiteres Projekt für die Action. Bin mal gespannt was das wird. Evtl. ein Plattformer?
Benutzeravatar
Jonathan
Establishment
Beiträge: 2835
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Arbeitstitel

Beitrag von Jonathan »

Bevor es wirklich Neues gibt, an dieser Stelle erstmal ein kleines "Meta"-Update.

Interessant zu sehen, wie viele Projekte hier auf Old-School / Arcade / Pixel-Look gehen. Ich würde raten, dass das bei den meisten hauptsächlich eine Aufwandseinschätzung ist und nicht primär eine Stil-Frage. Ich selbst mache ja offensichtlich genau das selbe, aus genau diesem Grund.

Wie man an meinem freischwebenden Level-Element in 90er Jahre Skybox schon gut erahnen kann, wird es bei mir relativ abstrakt. Das geht nicht nur als Stil durch und ist sehr schnell gebaut, sondern hat auch noch einen anderen, interessanten Vorteil: Gameplay-First. Ich will in verschiedene Level verschiedene Dinge einbauen, auch um meine Skript-Anbindung etwas mehr auszureizen. Nichts davon muss irgendwie sinnvoll sein, Hauptsache die Spielmechanik ist interessant. Ein bisschen Arcade in Reinform. Es gibt absolut null Story oder "Charaktere", dafür aber eine Highscore. Ich finde das recht reizvoll um einfach mal ein paar Dinge auszuprobieren.

Ich plane übrigens auch eine Reihe Anspielungen und Easter-Eggs. Die Steintextur könnten viele hier schonmal gesehen haben, aber bezweifle, dass sie jemand direkt wiedererkannt hat :D (Aber vlt. dann wenn ich demnächst ein paar mehr Elemente eingebaut habe)
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
xTr1m
Beiträge: 17
Registriert: 08.08.2025, 20:08

Re: Arbeitstitel

Beitrag von xTr1m »

Klingt interessant :) und gameplay first ist mMn genau das richtige. Bin gespannt.
Benutzeravatar
Jonathan
Establishment
Beiträge: 2835
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Arbeitstitel

Beitrag von Jonathan »

I've got some 2 BALLS

Es gab früher mal ein simples, aber wie mir scheint doch erstaunlich populäres 3D Arcade-Spiel (man hat ja nix gehabt damals, und Freeware 3D Spiele waren super selten, man musste es alleine deshalb schon spielen): "I've got some BALLS".

Eine originalgetreue Portierung kann man übrigens hier runterladen und spielen (Video gibts auch, für alle die mal kurz reinschauen wollen): https://thefinalcutbg.itch.io/ive-got-some-balls

Um die Homage auszudrücken nenn ich mein Projekt daher fürs erste "I've got 2 BALLS" - soll ja quasi der Nachfolger / die Weiterentwicklung sein. Mal schauen, vielleicht änder ich den aber noch in etwas weniger peinliches, aber ansich find ich den Namen auch einfach ein bisschen witzig :)

Insgesamt erschien mir die Idee perfekt für ein Zwischendrinprojekt. Es ist abstrakt und simpel, man kann in jedem Level neue Spielelemente einbauen, aber selbst wenn fast nix drin ist, kann man damit schon eine handvoll Level füllen - schnell fertig und unendlich erweiterbar quasi. Die abstrakten Spielwelten erlauben zudem eine geschwinde Assetproduktion. Ein bisschen im Gegensatz zum letzen Projekt Vintyr, wo Dinge ja tatsächlich hübsch aussehen sollten.

Leider, und vollkommen unerwartet (haha) hatte ich diesen Monat doch weniger Zeit. Aber gut, jetzt hab ich nochmal ein bisschen was gemacht, und so langsam wirds spielbar. Hier der erste Trailer:
2025-11-22_15-32-18_Balls.mp4
(4.97 MiB) 17-mal heruntergeladen

Zur Technik
Läuft natürlich alles in meiner C++ / OpenGL Engine, die auch das Herzstück vom Landvogt ist. Da hab ich schon seit Uhrzeiten Bullet Physics drin, bisher aber quasi ausschließlich für Kollisionsabfragen. Jetzt ging es also darum, auch dynamische Objekte zu integrieren.

Perfekt zufrieden bin ich mit dem Handling und dem Realismus des Balls noch nicht. Aber, es ist schon besser als im Original (der Ball rollt hier tatsächlich) und man kann halt schon spielen. Daher ist es jetzt erstmal an der Zeit, mehr Spielelemente wie Pickups und Level einzubauen. Mal sehen, wohin die Reise damit dann noch geht.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Jonathan
Establishment
Beiträge: 2835
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Arbeitstitel

Beitrag von Jonathan »

Ein Ausschnitt aus dem Testlevel:
2025-11-22_18-32-17_Balls.jpg
Man startet unten. Man kann dann nach rechts die Steinrampe hoch, auf dem Plateau ein paar Diamanten einsammeln (noch nicht implementiert) und muss dann mit Schwung die Rampe wieder runter um über die Halfpipe auf die höhere Ebene zu kommen. Von da aus muss man dann vorsichtig über die Drahtgitter weiter nach oben rollen.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
grinseengel
Establishment
Beiträge: 972
Registriert: 29.03.2011, 13:47
Echter Name: Andreas

Re: Arbeitstitel

Beitrag von grinseengel »

Das Spielprinzip erinnert mich an "Marble Maze". Der Retro-Klassiker.
Benutzeravatar
Schrompf
Moderator
Beiträge: 5278
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: Arbeitstitel

Beitrag von Schrompf »

Gefällt mir, und grundlegendes Gameplay steht ja schon! End-Kuhle einbauen und Du hast Gameplay.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
scheichs
Establishment
Beiträge: 983
Registriert: 28.07.2010, 20:18

Re: Arbeitstitel

Beitrag von scheichs »

Super cool! Heftig, dass das die Landvogt-Engine ist. Hätte jetzt auf Unity geschwört.
Benutzeravatar
Jonathan
Establishment
Beiträge: 2835
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Arbeitstitel

Beitrag von Jonathan »

Ugh, Bullet Physics ist alt und nicht besonders gut. Zumindest nicht besonders gut dokumentiert...

Die Kugelphysik funktioniert halbwegs ok, aber jetzt hätte ich gerne Sounds. Jedesmal, wenn der Ball gegen die Wand rollt, soll es halt *pock* machen. Das klingt einfach, zumindest einfacher als der Roll-Sound - denn rollen ist etwas, was sich immer über mehrere Frames erstreckt und man will die Geschwindigkeit berücksichtigen etc...

Es gibt grundsätzlich eine Manual-PDF und die API Dokumentation. Das Manual wurde seit Version 2.83 (kam 2015 raus) nicht mehr aktualisiert, aktuell ist Version 3.25 (kam 2022 raus). Im Handbuch wird ungefähr die Hälfte der wichtigen Begriffe mal erwähnt, Collision-Callbacks also z.B. nicht. Die API Dokumentation wurde einfach per Doxygen generiert und enthält größtenteils überhaupt keine Beschreiben, und ansonsten meistens triviale Kommentare. Da kann ich auch gleich den Code lesen.

Irgendwo im Forum heißt es dann, diese Collision-Callbacks sollte man eher verwenden um z.B. Contact-Friction dynamisch zu überschreiben, und wenn man auf Kollisionen reagieren will sollte man am Ende des Simulationsschritts durch alle aufgezeichneten Intersections iterieren. Es wird auf ein Beispiel verwiesen, das im SDK nicht existiert. Auf irgendeiner anderen Webseite findet man dann einen Codeschnipsel, wie so eine Iteration aussehen könnte.

Man sollte meinen "Sound bei Kollision abspielen" wäre ein Standardproblem. Aber alles was ich dazu finde sind Forendiskussionen, keine offiziellen Best-Practise Guides. Und die meisten Vorschläge sind halt auch nicht besonders gut. "Prüfe ob es im letzten Frame noch keine Kollision gab" - ja toll, ich hab aber eine Kugel die über den Boden rollt und dann gegen eine Wand stößt. Da gibt es in jedem Frame Kollisionen. Ich kann das auch nicht in mehrere Objekte unterteilen, das wären Speziallösungen die nur meistens, aber nicht immer funktionieren.

Am Ende muss ich also selber herausfinden, wie es gehen soll. Ich kann tatsächlich die Kontaktpunkte abfragen und da gibt es so Felder wie "appliedImpulse" was ich ja vlt. benutzen könnte um zwischen Rollen und Anstoßen zu unterscheiden. Aber es gibt keinerlei Informationen, wie das Feld korrekt zu interpretieren ist, und manchmal wenn ich gerade über den Boden rolle hab ich einen hohen Impuls und wenn ich dann gegen eine Wand stoße plötzlich einen niedrigen. Ich muss also gucken, welche Informationen ich zur Verfügung habe, zufällig raten, was die richtige Interpretation dieser Information sein könnte, und dann einen Test implementieren und hoffen, dass er funktioniert. Es sollte eine einfache und robuste Lösung für dieses Problem geben, aber die zu finden setzt Verständnis von den Interna der Physikberechnung voraus, und die hab ich derzeit einfach nicht. Oh well...
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Andy16823
Beiträge: 31
Registriert: 18.06.2014, 17:22

Re: Arbeitstitel

Beitrag von Andy16823 »

Ich habe etwas Erfahrung mit Bullet, du kannst deinen RigidBodys und Collion Objects ja ein UserObject zuweisen. Du müsstes praktisch bei den Kollision testen ob dein Ball mit der Wand kollidiert und dann den Sound abspielen. Ich denke dein Problem wird sein, dass du die Kollision irgendwie Resetten magst bzw. den Sound nur einmal bei der Kollision abspielen magst und nicht Permanent. Das bedeutet du müsstest irgendwie sicher stellen den Sound nur bei der Initial Collision zu triggern. Evtl. kannst du ja hiermit etwas anfangen.

https://github.com/Andy16823/GFX-Next/b ... ndler3D.cs

Eventuell kannst du ja hin gehen und die States in einer Liste festhalten, mit welchen Wänden dein Ball kollidiert ist und zu welcher Zeit. Wenn die Wand nicht in der Liste ist, kannst du den Sound abspielen. Ich würde die Wände einfach mit einem Debounce-System aus der Liste löschen. Das heißt, du brauchst ein Struct mit der UUID des Entities und einem Long-Member mit dem letzten Timestamp. Am Ende jedes Frames prüfst du praktisch, welche Wände länger als n Sekunden keine Kollision hatten, und entfernst diese aus der Liste. Du musst natürlich den timestamp bei einer Kollision mit einer existierenden Wand Updaten.
Benutzeravatar
Jonathan
Establishment
Beiträge: 2835
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Arbeitstitel

Beitrag von Jonathan »

Danke für die Tips. Mein Hauptproblem ist jedoch nicht unbedingt das finden von Kollisionen sondern das Filtern der gefundenen.

Wenn man sich das Bild oben anschaut: Das Level ist ein großes Mesh. Der Ball rollt auf dem Mesh, und knallt dann in die Wand. Aber weil er rollt, gibt es in jedem Frame ein Kollisionsevent (außer der Ball springt) - und es ist immer mit dem selben Objekt. Man könnte jetzt Boden und Wand in getrennte Objekte packen. Aber es soll ja später auch bewegliche Dinge wie Schaufelräder oder so geben - also im allgemeinen nicht-konvexe Objekte die man nicht weiter zerlegen will. Alles einfach in viele kleine Objekte zerlegen wird also vermutlich früher oder später scheitern, vom Aufwand mal ganz abgesehen.

Problem Nummer 2, ist dass ein leichtes Berühren und ein frontaler Aufschlag zwei unterschiedliche Dinge sind, die unterschiedliche Sounds erzeugen sollten. Selbst wenn das Aufteilen in unterschiedliche Objekte wenig Aufwand wäre und immer gut funktionieren würde, würde dieses Problem also bleiben. Man muss zwangsläufig mehr Informationen über die Kollision verarbeiten.

Aber gut. Ich kann über alle Events iterieren und auf die Kollisionspunkte zugreifen - nur waren die Infos da für mich auch nach langem rumspielen einfach nicht nützlich. Dann probier ich halt was eigenes aus, hehe. Ich tracke jetzt die Geschwindigkeit des Balls. Wenn die sich von einem Frame auf den nächsten Signifikant verändert (im Betrag oder Richtung, beides ist möglich!) während gleichzeitig ein Kollisionsevent stattfindet, dann impliziert das einen Aufprall. Zusätzlich solle man nach jedem Event noch ein paar Frames warten, manchmal passieren 2 Richtungsänderungen direkt nacheinander (wenn man in eine Ecke rollt). Der Code sieht dann so aus:

Code: Alles auswählen

// handle collisions:
auto world = m_scene_manager.get_collision_world();
const int num_manifolds = world->getDispatcher()->getNumManifolds();

auto ball_velocity = as_glmVec(m_ball_physic->get_collision_object()->getLinearVelocity());

for( int i=0; i<num_manifolds; i++ )
{
	btPersistentManifold* contact_manifold = world->getDispatcher()->getManifoldByIndexInternal(i);
	for( int j=0; j<contact_manifold->getNumContacts(); j++ )
	{
		//btManifoldPoint& pt = contact_manifold->getContactPoint(j); // no useful info :(
		
		// velocity change
		auto vel_change = length(ball_velocity) / length(m_ball_last_velocity);
		if( vel_change < 1.f) // basically and absolute value
			vel_change = 1.f/vel_change;

		// check for velocity changes:
		if( m_ball_collision_free_frames > 5 &&
			length(m_ball_last_velocity) > 1.0  && //only if ball is sufficiently fast
			(dot(normalize(ball_velocity), normalize(m_ball_last_velocity)) < 0.8 // sudden change of direction
			|| vel_change > 1.5f ) // sudden speed difference 
			)
		{
			m_sound_ball_collide.Play();
			m_ball_collision_free_frames = 0;
		}
	}
}
m_ball_collision_free_frames++;
m_ball_last_velocity = ball_velocity;
Das funktioniert fürs erste ganz gut. Die Threshold sind halt wichtig, die muss man richtig einstellen. Man kann aber anhand derer auch vergleichen, wie stark der Aufprall denn nun war (also nicht nur eine binäre Entscheidung treffen) und entsprechend den richtigen Sound spielen (oder Lautstärke anpassen).

Zusätzlich kann es noch passieren, dass man mehrere Frames betrachten muss. Es gibt zum Beispiel eine Halfpipe, wo es dann in sehr sehr kurzer Zeit viele kleine Richtungsänderungen gibt. Möchte man da auch einen Kollisionssound haben? Vielleicht. Dann müsste man halt gucken, ob die Gesamtänderung über die letzten X Frames über einem Schwellwert liegt.

Aber fürs erste reicht das hier schon. Einen Rollsound hätte ich noch gerne, dafür werd ich wohl ähnliche Kriterien finden. Und dann geht es an komplexere Level :)
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Jonathan
Establishment
Beiträge: 2835
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Arbeitstitel

Beitrag von Jonathan »

Nachtrag: ( war ja klar :D - sobald man darüber nachdenkt, versteht man es besser )

Anstatt die Geschwindigkeitsänderung mit irgendwelche Werten zu vergleichen könnte man ja auch einfach einen physikalischen Impuls berechnen, der für die Richtungsänderung verantwortlich ist. Statt Betrag und Richtung einzeln zu behandeln kann man so also die Kombination von beiden ausrechnen (und so nicht versehentlich einen der 2 Tests stärker gewichten). Vom Impuls sollte es dann auch einen direkten und sinnvollen Zusammenhang zur Sound-Lautstärke geben.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
TomasRiker
Establishment
Beiträge: 119
Registriert: 18.07.2011, 11:45
Echter Name: David Scherfgen
Wohnort: Hildesheim

Re: I've got 2 BALLS

Beitrag von TomasRiker »

Anhand der Rotationsgeschwindigkeit und ob ein Kontakt zum Boden besteht (Kollision mit Fläche, deren Normale senkrecht genug zur Rotationsachse steht) kannst du dann noch ein Roll-Geräusch in Lautstärke und Höhe variieren.
Antworten