Tracer un pseudo globe 3D
Je voudrais tracer un petit globe où le personnage principal peut marcher, exactement comme Sonic & Knukles Bonus Stage. Pour ceux qui ne veulent pas google, voici une photo .
Je connais Raycasting, utilisé dans Wolfenstein et dans d'autres jeux pour "simuler" une perspective 3D dans une carte 2D.
Mais je ne savais pas comment programmer le globe, et je suppose que ce n'était pas un vrai rendu 3D, car Sonic était un jeu 16 bits.
Une idée sur la façon de le faire sans aucun moteur 3D sophistiqué?
Réponses
Aperçu
- Configurez une piste 1D sans fin de 2x plans 2D. Lorsque vous avancez, l'avion derrière vous s'avance pour vous permettre de courir; cela se produit à plusieurs reprises, que vous couriez en avant ou en arrière.
- Faites maintenant la même chose en 2D c'est-à-dire avec des plans 2D 2x2. Où que vous alliez, le monde continue sous vos pieds.
- Transformez les plans en vue en perspective.
- Créez maintenant un effet de renflement sphérique grâce à la transformation de l'espace de l'écran, c'est-à-dire en ajustant tous les pixels du sol pour les faire paraître incurvés, même si c'est une surface vraiment plate et répétitive.
- Même lorsque le personnage pivote de 90 degrés sur quelques images, cela montre toujours le même effet de monde incurvé.
Plans 3D en 2D
Supposons que vous ayez des plans plats 2x2 rendus sur votre écran sous forme de carrés (vus de haut en bas), et que vous pouvez vous déplacer dessus comme décrit ci-dessus.
Nous devons maintenant transformer ces plans (collectivement), vus de haut en bas, en une perspective oblique au sol.
Cela se fait en 2 étapes:
- presser le plan de sol combiné de sorte que sa moitié supérieure "pince" à la largeur de la fenêtre et sa moitié inférieure dépasse la largeur de la fenêtre. Cela se fait en utilisant
yRatiocomme calculé dans la section de code ci-dessous, c'est-à-dire que plus nous sommes proches du sommet, plus nous mettons à l'échellexafin de pincer le haut du carré pour qu'il ressemble à un tronc ou un triangle. - Réduisez-le et repositionnez-le en y de sorte que son bas affleure le bas de la fenêtre et que son haut soit (disons) à mi-chemin de l'écran - c'est votre horizon.
Ces deux étapes dépendent de la position actuelle du joueur.
Courbure
Une formule en demi-cercle est nécessaire pour la transformation des pixels, qui seront déplacés le long de l'écran y pour obtenir l'effet de renflement. Cette partie est laissée à votre recherche.
semicircleDisplace(xCurrent)
{
//formula to calculate maximal (horizon) yDisplacement from xCurrent
//...
return yDisplacement;
}
pixels[xCurrent][yCurrent].y += semicircleDisplace(xCurrent);
Le problème avec cela est que nous renflons tous les pixels tout aussi près du bas de l'écran, que près du haut, ce qui conduit à une sorte de U à l'envers vers le terrain, alors que ce que nous voulons vraiment près du bas de la l'écran est une ligne presque droite; à mi-chemin, un certain déplacement / renflement; et à l'horizon, déplacement maximal. Nous y parvenons en utilisant un facteur interpolé (éventuellement linéaire):
semicircleDisplace(xCurrent, yCurrent)
{
//formula to calculate maximal (horizon) yDisplacement from xCurrent
//...
//linear interpolation based on where we are between bottom of screen and horizon
yRange = yMax - yMin
yRatio = yCurrent - yMin
yFactor = yRatio / yRange
return yDisplacement * yFactor;
}
pixels[xCurrent][yCurrent].y += semicircleDisplace(xCurrent, yCurrent);
yFactorest une valeur entre 0.0et 1.0par laquelle vous multipliez yDisplacement. Si l'interpolation linéaire (qui n'est pas chère) ne donne pas un bel aspect, vous pouvez jouer avec des interpolations non linéaires pour obtenir le bon type de courbure du sol. Mais je suppose que linéaire aura l'air très bien.