Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <SFML/Graphics.hpp>
- #include <math.h>
- using namespace sf;
- int width = 1024;
- int height = 768;
- int roadW = 2000;
- int segL = 200; // segment length
- float camD = 0.84; // camera depth
- struct Line
- {
- float x,y,z; // center of line in the 3d world
- float X,Y,W; // parameterization of the line on the screen
- float scale, curve;
- Line() { curve=x=y=z=0; }
- // project onto the given camera position
- void project(int camX, int camY, int camZ)
- {
- scale = camD/(z-camZ);
- X = (1 + scale*(x - camX)) * width/2;
- Y = (1 - scale*(y - camY)) * height/2;
- W = scale * roadW * width/2;
- }
- };
- // draw a quadtrilateral parameterized by two midpoints (x1,y1), (x2,y2) and 2 widths w1, w2.
- void drawQuad(RenderWindow &w, Color c, int x1, int y1, int w1, int x2, int y2, int w2)
- {
- ConvexShape shape(4);
- shape.setFillColor(c);
- shape.setPoint(0, Vector2f(x1-w1,y1));
- shape.setPoint(1, Vector2f(x2-w2, y2));
- shape.setPoint(2, Vector2f(x2+w2, y2));
- shape.setPoint(3, Vector2f(x1+w1, y1));
- w.draw(shape);
- }
- int main()
- {
- RenderWindow app(VideoMode(width, height), "Outrun Racing!");
- app.setFramerateLimit(60);
- Texture bg;
- bg.loadFromFile("/Users/alleyuan/code-snippets/16_games/08 Outrun/images/bg.png");
- bg.setRepeated(true);
- Sprite sBackground(bg);
- sBackground.setTextureRect(IntRect(0,0,5000,411));
- sBackground.setPosition(-2000,0);
- std::vector<Line> lines;
- for (int i = 0; i < 1600; i++)
- {
- Line line;
- line.z = i * segL;
- if (i > 300 && i < 700) line.curve = 0.5;
- if (i > 750) line.y = sin(i/30.0) * 1500; // add wavy terrain to the end of the track
- lines.push_back(line);
- }
- int N = lines.size();
- int pos = 0;
- int playerX = 0;
- while(app.isOpen())
- {
- Event e;
- while (app.pollEvent(e))
- {
- if (e.type == Event::Closed)
- app.close();
- }
- if (Keyboard::isKeyPressed(Keyboard::Right)) playerX += 200;
- if (Keyboard::isKeyPressed(Keyboard::Left)) playerX -= 200;
- if (Keyboard::isKeyPressed(Keyboard::Up)) pos += 200;
- if (Keyboard::isKeyPressed(Keyboard::Down)) pos -= 200;
- // loop the track
- while (pos >= N*segL) pos -= N*segL;
- while (pos < 0) pos += N*segL;
- app.clear(Color(105,205,4));
- app.draw(sBackground);
- int startPos = pos/segL;
- int camH = 1500 + lines[startPos].y;
- float x = 0, dx = 0; // curvature offset, dx = rate of change of the curvature
- int maxy = height;
- for (int n = startPos; n < startPos+300; n++)
- {
- Line &l = lines[n%N];
- l.project(playerX - x, camH, pos - (n>=N?N*segL:0));
- x += dx;
- dx += l.curve;
- if (l.Y >= maxy) continue;
- maxy = l.Y;
- Color grass = (n/3)%2?Color(16,200,16):Color(0,154,0);
- Color rumble = (n/3)%2?Color(255,255,255):Color(0,0,0);
- Color road = (n/3)%2?Color(107,107,107):Color(105,105,105);
- Line p = lines[(n-1)%N]; // prev line
- drawQuad(app, grass, 0, p.Y, width, 0, l.Y, width);
- drawQuad(app, rumble, p.X, p.Y, p.W*1.2, l.X, l.Y, l.W*1.2);
- drawQuad(app, road, p.X, p.Y, p.W, l.X, l.Y, l.W);
- }
- app.display();
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment