Advertisement
Garey

Pseudo-3D Road

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