Tracer un pseudo globe 3D

Sep 06 2020

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

1 Engineer Sep 06 2020 at 15:22

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:

  1. 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'échelle xafin de pincer le haut du carré pour qu'il ressemble à un tronc ou un triangle.
  2. 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.