2D Vehicle Physics Prototype

Het begon als een kleine wireframe-demo geschreven in GFA BASIC op mijn Atari ST-computer (en werd later geporteerd naar C voor gebruik in het eigenlijke spel). Ter gelegenheid van het 30-jarig bestaan heb ik dit project opnieuw gemaakt in JavaScript, in een iets mooiere, "geremasterde" vorm, voor iedereen die het wil bekijken of spelen.

Instructies

Je kunt de recreatie spelen met aanraakbediening op mobiele apparaten. Naast de standaard "Car"-modus (1), kun je ook de technisch eenvoudigere "Ship"-modus (2) en "Brick"-modus (3) selecteren via de modusselector in de instellingen of door op de overeenkomstige cijfers op je toetsenbord te drukken.

  • B: Schakelt de botsingsbarrières rond de zijden van het speelveld in of uit.
  • G: Schakelt verticale zwaartekracht in of uit (dit is voornamelijk relevant in de Ship- en Brick-modi).
  • Z: Schakelt de zogenaamde "dead zone" van de camera om, wat bepaalt hoe ver het voertuig kan bewegen voordat de camera hem volgt.
  • X: Schakelt een zoomsysteem in dat afhankelijk is van de snelheid; de camera trekt iets terug wanneer je sneller rijdt (net als in GTA).

\Op een volledig legale manier die geen auteursrechten of handelsmerken schendt.*

Vrijwaringsclausule: Dit werk is geheel onafhankelijk van, en op geen enkele wijze verbonden met, de "Grand Theft Auto"-franchise en de uitgever "Take-Two", of de ontwikkelaar bekend als "Rockstar Games".

Hoe het werkt

Het prototype combineert een algemeen bruikbaar 2D rigid body (star lichaam) met een doelbewust eenvoudig model van een auto.

De oorspronkelijke simulatie begon met iets dat lijkt op de "Brick". Vervolgens voegde ik verbeteringen toe om de "Ship" te maken (die bewust doet denken aan het klassieke spel "Thrust" uit 1986), om uiteindelijk de elementen toe te voegen die nodig waren om het meer als een "Car" te laten aanvoelen.

De kern: 2D Rigid Body Dynamics

In de kern van het systeem ligt een eenvoudige klassieke 2D rigid body dynamics simulatie. Voor zover ik weet, was deze aanpak destijds nog niet gebruikelijk in games (met enkele opmerkelijke uitzonderingen). De meeste voertuigen in games werden gemaakt met basis "puntfysica" (F = ma), waarbij elke rotationele component werd afgehandeld via diverse onhandige "hacks". Het gebruik van proper rigid-body physics (inclusief koppels/torques) zorgt ervoor dat rotatie consistenter wordt afgehandeld.

De voertuiglaag

Bovenop die kern heb ik een "innovatieve" voertuigsimulatie-laag toegevoegd, gebaseerd op een eenvoudig, benaderend en technisch incorrect model van hoe banden zich gedragen. Het was in feite een semi-geïnformeerde gok; hoewel ik wist dat het fysiek niet accuraat was, leek het voor mijn doeleinden van dat moment "goed genoeg".

Van input naar beweging

De huidige JavaScript-recreatie werkt als volgt: de browserinterface levert de besturing, de simulatie vordert in vaste tijdstappen (fixed time steps) en de Canvas-renderer tekent de resulterende status. Door deze taken gescheiden te houden, is het eenvoudiger te volgen hoe een knopdruk verandert in een kracht, en hoe die kracht resulteert in beweging.

Eén object, drie gedragingen

Een voertuig combineert een rigid body met een shell (die de weergavevorm en botsingsgeometrie beschrijft) en een dynamics object (dat het gedrag bepaalt).

  • Brick: Accepteert krachten via een pointer-drag.
  • Ship: Voegt stuwkracht toe op een specifiek bevestigingspunt.
  • Car: Voegt motorvermogen en sturing toe, waarbij weerstand wordt toegepast op vier bandposities.

Wanneer je van modus wisselt, worden de shell en het gedrag vervangen, terwijl de positie en beweging van het body behouden blijven.

Krachten die het object kunnen verplaatsen en draaien

Het rigid body houdt de positie en snelheid bij, samen met de hoek en hoeksnelheid.

  • Een kracht door het centrum verandert de beweging.
  • Een kracht die buiten het centrum wordt uitgeoefend, kan het object ook doen draaien.

De simulatie telt de krachten en het koppel op, update de snelheid en verplaatst vervolgens de positie en hoek. Een punt op een roterend lichaam heeft zijn eigen snelheid, die een combinatie is van de beweging van het lichaam en de beweging rond het centrum.

Barrières maken gebruik van diezelfde puntsnelheid. Wanneer een vorm een rand kruist, verplaatst de simulatie deze terug naar binnen en past een contactimpuls toe als het object tegen de barrière in beweegt. Een impact buiten het centrum kan daarom zowel de snelheid als de draaiing (spin) veranderen. Dit is een eenvoudige barrier solver met wrijvingsloze randen, in plaats van een algemeen botsingssysteem.

De doelbewust benaderende banden

Voor elke band meet de "Car" de snelheid op die positie en splitst deze in twee componenten: in de richting van het wiel en zijwaarts eroverheen. Er wordt een kleine weerstand toegepast op het rollen en een veel sterkere weerstand op de zijwaartse beweging.

  • Sturing: Verandert de richting van de voorwielen, waardoor hun krachten het lichaam ook doen draaien.
  • Handrem: Verhoogt de rolweerstand aan de achterzijde en vermindert de zijwaartse grip aan de achterzijde.

Deze weerstandskrachten zijn proportioneel aan de snelheid, zonder een maximumlimiet. Dit is een handig dempingsmodel in plaats van een realistische weergave van bandwrijving, slip of beschikbare grip. Het creëert echter met minimale rekenkracht het gewenste gevoel van wielen die zijwaartse bewegingen tegenwerken. De "Ship" en "Brick" maken gebruik van dezelfde fysica-kern, maar passen krachten op een andere manier toe.

De onderdelen samenvoegen

De Vehicle coordinator vraagt het geselecteerde dynamics object om krachten toe te passen en laat vervolgens het rigid body vorderen. Daarnaast zet hij de lokale punten van de shell om in wereldposities voor het tekenen en bepaalt hij het oppervlaktepunt dat naar elke barrière is gericht.

Wanneer een vlakke zijde een barrière raakt, gebruikt het systeem het middelpunt van de contactpunten. Hiermee wordt kunstmatige spin voorkomen, wat wel zou gebeuren als er slechts één enkele hoek als contactpunt zou worden gekozen.