here2share

Pseudo_Outrun_3D_Racer_.cpp

Feb 18th, 2021 (edited)
626
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.56 KB | None | 0 0
  1. #include <SFML/Graphics.hpp>
  2. using namespace sf;
  3.  
  4. int width = 1024;
  5. int height = 768;
  6. int roadW = 2000;
  7. int segL = 200; //segment length
  8. float camD = 0.84; //camera depth
  9.  
  10. void drawQuad(RenderWindow &w, Color c, int x1,int y1,int w1,int x2,int y2,int w2)
  11. {
  12.     ConvexShape shape(4);
  13.     shape.setFillColor(c);
  14.     shape.setPoint(0, Vector2f(x1-w1,y1));
  15.     shape.setPoint(1, Vector2f(x2-w2,y2));
  16.     shape.setPoint(2, Vector2f(x2+w2,y2));
  17.     shape.setPoint(3, Vector2f(x1+w1,y1));
  18.     w.draw(shape);
  19. }
  20.  
  21. struct Line
  22. {
  23.   float x,y,z; //3d center of line
  24.   float X,Y,W; //screen coord
  25.   float curve,spriteX,clip,scale;
  26.   Sprite sprite;
  27.  
  28.   Line()
  29.   {spriteX=curve=x=y=z=0;}
  30.  
  31.   void project(int camX,int camY,int camZ)
  32.   {
  33.     scale = camD/(z-camZ);
  34.     X = (1 + scale*(x - camX)) * width/2;
  35.     Y = (1 - scale*(y - camY)) * height/2;
  36.     W = scale * roadW  * width/2;
  37.   }
  38.  
  39.   void drawSprite(RenderWindow &app)
  40.   {
  41.     Sprite s = sprite;
  42.     int w = s.getTextureRect().width;
  43.     int h = s.getTextureRect().height;
  44.  
  45.     float destX = X + scale * spriteX * width/2;
  46.     float destY = Y + 4;
  47.     float destW  = w * W / 266;
  48.     float destH  = h * W / 266;
  49.  
  50.     destX += destW * spriteX; //offsetX
  51.     destY += destH * (-1);    //offsetY
  52.  
  53.     float clipH = destY+destH-clip;
  54.     if (clipH<0) clipH=0;
  55.  
  56.     if (clipH>=destH) return;
  57.     s.setTextureRect(IntRect(0,0,w,h-h*clipH/destH));
  58.     s.setScale(destW/w,destH/h);
  59.     s.setPosition(destX, destY);
  60.     app.draw(s);
  61.     }
  62. };
  63.  
  64.  
  65. int main()
  66. {
  67.     RenderWindow app(VideoMode(width, height), "Outrun Racing!");
  68.     app.setFramerateLimit(60);
  69.  
  70.     Texture t[50];
  71.     Sprite object[50];
  72.     for(int i=1;i<=7;i++)
  73.      {
  74.        t[i].loadFromFile("images/"+std::to_string(i)+".png");
  75.        t[i].setSmooth(true);
  76.        object[i].setTexture(t[i]);
  77.      }
  78.  
  79.     Texture bg;
  80.     bg.loadFromFile("images/bg.png");
  81.     bg.setRepeated(true);
  82.     Sprite sBackground(bg);
  83.     sBackground.setTextureRect(IntRect(0,0,5000,411));
  84.     sBackground.setPosition(-2000,0);
  85.  
  86.     std::vector<Line> lines;
  87.  
  88.     for(int i=0;i<1600;i++)
  89.      {
  90.        Line line;
  91.        line.z = i*segL;
  92.  
  93.        if (i>300 && i<700) line.curve=0.5;
  94.        if (i>1100) line.curve=-0.7;
  95.  
  96.        if (i<300 && i%20==0) {line.spriteX=-2.5; line.sprite=object[5];}
  97.        if (i%17==0)          {line.spriteX=2.0; line.sprite=object[6];}
  98.        if (i>300 && i%20==0) {line.spriteX=-0.7; line.sprite=object[4];}
  99.        if (i>800 && i%20==0) {line.spriteX=-1.2; line.sprite=object[1];}
  100.        if (i==400)           {line.spriteX=-1.2; line.sprite=object[7];}
  101.  
  102.        if (i>750) line.y = sin(i/30.0)*1500;
  103.  
  104.        lines.push_back(line);
  105.      }
  106.  
  107.    int N = lines.size();
  108.    float playerX = 0;
  109.    int pos = 0;
  110.    int H = 1500;
  111.  
  112.     while (app.isOpen())
  113.     {
  114.         Event e;
  115.         while (app.pollEvent(e))
  116.         {
  117.             if (e.type == Event::Closed)
  118.                 app.close();
  119.         }
  120.  
  121.   int speed=0;
  122.  
  123.   if (Keyboard::isKeyPressed(Keyboard::Right)) playerX+=0.1;
  124.   if (Keyboard::isKeyPressed(Keyboard::Left)) playerX-=0.1;
  125.   if (Keyboard::isKeyPressed(Keyboard::Up)) speed=200;
  126.   if (Keyboard::isKeyPressed(Keyboard::Down)) speed=-200;
  127.   if (Keyboard::isKeyPressed(Keyboard::Tab)) speed*=3;
  128.   if (Keyboard::isKeyPressed(Keyboard::W)) H+=100;
  129.   if (Keyboard::isKeyPressed(Keyboard::S)) H-=100;
  130.  
  131.   pos+=speed;
  132.   while (pos >= N*segL) pos-=N*segL;
  133.   while (pos < 0) pos += N*segL;
  134.  
  135.   app.clear(Color(105,205,4));
  136.   app.draw(sBackground);
  137.   int startPos = pos/segL;
  138.   int camH = lines[startPos].y + H;
  139.   if (speed>0) sBackground.move(-lines[startPos].curve*2,0);
  140.   if (speed<0) sBackground.move( lines[startPos].curve*2,0);
  141.  
  142.   int maxy = height;
  143.   float x=0,dx=0;
  144.  
  145.   ///////draw road////////
  146.   for(int n = startPos; n<startPos+300; n++)  
  147.    {
  148.     Line &l = lines[n%N];
  149.     l.project(playerX*roadW-x, camH, startPos*segL - (n>=N?N*segL:0));
  150.     x+=dx;
  151.     dx+=l.curve;
  152.  
  153.     l.clip=maxy;
  154.     if (l.Y>=maxy) continue;
  155.     maxy = l.Y;
  156.  
  157.     Color grass  = (n/3)%2?Color(16,200,16):Color(0,154,0);
  158.     Color rumble = (n/3)%2?Color(255,255,255):Color(0,0,0);
  159.     Color road   = (n/3)%2?Color(107,107,107):Color(105,105,105);
  160.  
  161.     Line p = lines[(n-1)%N]; //previous line
  162.  
  163.     drawQuad(app, grass, 0, p.Y, width, 0, l.Y, width);
  164.     drawQuad(app, rumble,p.X, p.Y, p.W*1.2, l.X, l.Y, l.W*1.2);
  165.     drawQuad(app, road,  p.X, p.Y, p.W, l.X, l.Y, l.W);
  166.    }
  167.  
  168.     ////////draw objects////////
  169.     for(int n=startPos+300; n>startPos; n--)
  170.       lines[n%N].drawSprite(app);
  171.  
  172.     app.display();
  173.     }
  174.  
  175.     return 0;
  176. }
  177.  
Add Comment
Please, Sign In to add comment