fragxspark

simcode

Jul 2nd, 2025
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.77 KB | Source Code | 0 0
  1. #include "raylib.h"
  2. #include "raymath.h"
  3. #include <stdio.h>
  4. #include <math.h>
  5.  
  6. // RayGUI implementation
  7. #define RAYGUI_IMPLEMENTATION
  8. #include "raygui.h"
  9.  
  10. #ifndef MAP_DIFFUSE
  11.     #define MAP_DIFFUSE MATERIAL_MAP_ALBEDO
  12. #endif
  13.  
  14. #define MAX_PLANES 4
  15.  
  16. int main(void)
  17. {
  18.     // Initialize window (can be resized)
  19.     InitWindow(1920, 1080, "Airplane Simulation");
  20.     SetTargetFPS(60);
  21.  
  22.     // --- Load terrain ---
  23.     Image hm = LoadImage("Great Lakes/Height-Map.png");
  24.     if (!hm.data) { printf("Failed to load heightmap\n"); CloseWindow(); return 1; }
  25.     ImageResize(&hm, hm.width/3, hm.height/3);
  26.     Mesh terrainMesh = GenMeshHeightmap(hm, (Vector3){1000,350,1000});
  27.     Model terrain     = LoadModelFromMesh(terrainMesh);
  28.     UnloadImage(hm);
  29.     Texture2D terrainTex = LoadTexture("Great Lakes/Diffuse-Map.png");
  30.     terrain.materials[0].maps[MAP_DIFFUSE].texture = terrainTex;
  31.  
  32.     // Optional saturation shader
  33.     Shader sat = LoadShader(0, "Assets/saturation.fs");
  34.     float satVal = 3.0f;
  35.     SetShaderValue(sat, GetShaderLocation(sat, "saturation"), &satVal, SHADER_UNIFORM_FLOAT);
  36.     terrain.materials[0].shader = sat;
  37.  
  38.     // --- Load plane model ---
  39.     Model planeModel = LoadModel("Assets/plane.obj");
  40.     Texture2D planeTex = LoadTexture("Assets/An2_aeroflot.png");
  41.     planeModel.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = planeTex;
  42.  
  43.     // --- Load runway ---
  44.     Texture2D runwayTex = LoadTexture("Assets/runway_texture.png");
  45.     Mesh runwayMesh = GenMeshPlane(6.0f, 22.0f, 1, 1);
  46.     Model runway = LoadModelFromMesh(runwayMesh);
  47.     runway.materials[0].maps[MAP_DIFFUSE].texture = runwayTex;
  48.  
  49.     // --- Audio ---
  50.     InitAudioDevice();
  51.     Music engineSound = LoadMusicStream("Assets/airplane-sound.mp3");
  52.     PlayMusicStream(engineSound);
  53.  
  54.     // --- Spawn setup ---
  55.     const float spawnX = -1000.0f, spawnY = 5500.0f, spawnZ = 19000.0f;
  56.     Matrix scaleM  = MatrixScale(0.005f, 0.005f, 0.005f);
  57.     Matrix corrM   = MatrixRotateY(PI/2);
  58.     Matrix baseSpawn = MatrixMultiply(
  59.                           MatrixTranslate(spawnX, spawnY, spawnZ),
  60.                           MatrixMultiply(corrM, scaleM)
  61.                        );
  62.     Matrix spawned[MAX_PLANES] = { 0 };
  63.     int spawnedCount = 0;
  64.  
  65.     // --- Simulation state ---
  66.     float transX = spawnX, transY = spawnY, transZ = spawnZ;
  67.     float pitch = 0, roll = 0, yaw = 0;
  68.     bool firstPerson = false, freeCam = false, gameOver = false;
  69.  
  70.     // --- Camera ---
  71.     Camera camera = { 0 };
  72.     camera.position   = (Vector3){0, 60, 120};
  73.     camera.target     = (Vector3){0, 10,  0};
  74.     camera.up         = (Vector3){0, 1,   0};
  75.     camera.fovy       = 8.0f;
  76.     camera.projection = CAMERA_PERSPECTIVE;
  77.  
  78.     // --- Landing spot ---
  79.     Vector3 landingSpot     = {100.0f, 27.458f, 1.0f};
  80.     const float collisionThreshold = 5.0f;
  81.  
  82.     // --- Menu flags ---
  83.     bool inMenu      = true;
  84.     bool gameStarted = false;
  85.  
  86.     // --- Main loop ---
  87.     while (!WindowShouldClose())
  88.     {
  89.         int W = GetScreenWidth();
  90.         int H = GetScreenHeight();
  91.  
  92.         // Only update audio when playing
  93.         if (gameStarted) UpdateMusicStream(engineSound);
  94.  
  95.         // Input: toggle views
  96.         if (gameStarted && !gameOver)
  97.         {
  98.             if (IsKeyPressed(KEY_F)) firstPerson = !firstPerson;
  99.             if (IsKeyPressed(KEY_R)) freeCam     = !freeCam;
  100.         }
  101.  
  102.         // Simulation update
  103.         if (gameStarted && !gameOver)
  104.         {
  105.             const float groundAlt       = 6000.0f;
  106.             const float constantGravity = 0.5f;
  107.             float speedFactor = 1.0f;
  108.             if (transY <= groundAlt)
  109.             {
  110.                 transY    -= constantGravity;
  111.                 speedFactor = 0.5f;
  112.             }
  113.  
  114.             Vector3 forward = { sinf(DEG2RAD*yaw), 0, cosf(DEG2RAD*yaw) };
  115.  
  116.             if (IsKeyDown(KEY_LEFT_SHIFT))
  117.             {
  118.                 transX += forward.x * 40.5f * speedFactor;
  119.                 transZ += forward.z * 40.5f * speedFactor;
  120.                 transY += sinf(DEG2RAD*pitch) * 20.5f * speedFactor;
  121.             }
  122.             if (IsKeyDown(KEY_SPACE))
  123.             {
  124.                 transX += forward.x * 50.0f * speedFactor;
  125.                 transZ += forward.z * 50.0f * speedFactor;
  126.             }
  127.             if (IsKeyDown(KEY_W)) transY += 12.0f * speedFactor;
  128.             if (IsKeyDown(KEY_S)) transY -= 12.0f * speedFactor;
  129.  
  130.             if (IsKeyDown(KEY_DOWN))  pitch += 0.2f;
  131.             else if (IsKeyDown(KEY_UP)) pitch -= 0.2f;
  132.             else if (pitch > 0.2f)      pitch -= 0.2f;
  133.             else if (pitch < -0.2f)     pitch += 0.2f;
  134.  
  135.             if (IsKeyDown(KEY_D)) yaw -= 0.4f;
  136.             if (IsKeyDown(KEY_A)) yaw += 0.4f;
  137.  
  138.             if (IsKeyDown(KEY_LEFT))  roll -= 0.7f;
  139.             else if (IsKeyDown(KEY_RIGHT)) roll += 0.7f;
  140.             else if (roll > 0.0f) roll -= 0.3f;
  141.             else if (roll < 0.0f) roll += 0.3f;
  142.  
  143.             transX = Clamp(transX, -189900.0f,  9900.0f);
  144.             transZ = Clamp(transZ, -9900.0f,   189900.0f);
  145.             transY = Clamp(transY, 5500.0f,   200000.0f);
  146.  
  147.             Matrix rotM   = MatrixRotateXYZ((Vector3){DEG2RAD*pitch, DEG2RAD*yaw, DEG2RAD*roll});
  148.             Matrix transM = MatrixTranslate(transX, transY, transZ);
  149.             planeModel.transform = MatrixMultiply(rotM, MatrixMultiply(transM, MatrixMultiply(corrM, scaleM)));
  150.  
  151.             Vector3 planePos = { planeModel.transform.m12, planeModel.transform.m13, planeModel.transform.m14 };
  152.             if (Vector3Distance(planePos, landingSpot) < collisionThreshold) gameOver = true;
  153.         }
  154.  
  155.         // Camera update
  156.         if (gameStarted && !freeCam)
  157.         {
  158.             Vector3 ppos = { planeModel.transform.m12, planeModel.transform.m13, planeModel.transform.m14 };
  159.             if (firstPerson)
  160.             {
  161.                 camera.position = Vector3Add(ppos, (Vector3){0,0.5f,0});
  162.                 Matrix pr = MatrixRotateXYZ((Vector3){DEG2RAD*pitch, DEG2RAD*yaw, DEG2RAD*roll});
  163.                 Matrix cm = MatrixMultiply(pr, corrM);
  164.                 camera.target = Vector3Add(camera.position, Vector3Transform((Vector3){0,0,1}, cm));
  165.                 camera.up     = Vector3Transform((Vector3){0,1,0}, cm);
  166.             }
  167.             else
  168.             {
  169.                 Matrix fr = MatrixRotateXYZ((Vector3){DEG2RAD*pitch, DEG2RAD*yaw, 0});
  170.                 Vector3 offset = Vector3Transform((Vector3){-15,2.5,0}, fr);
  171.                 Vector3 desired = Vector3Add(ppos, offset);
  172.                 camera.position = Vector3Lerp(camera.position, desired, 0.1f);
  173.                 camera.target   = ppos;
  174.             }
  175.         }
  176.         else if (freeCam)
  177.         {
  178.             UpdateCamera(&camera, CAMERA_FREE);
  179.         }
  180.  
  181.         // --- DRAW ---
  182.         BeginDrawing();
  183.           ClearBackground(inMenu ? RAYWHITE : SKYBLUE);
  184.  
  185.           if (inMenu)
  186.           {
  187.               DrawText("Airplane Simulation",
  188.                        W/2 - MeasureText("Airplane Simulation", 40)/2,
  189.                        H/2 - 120, 40, DARKBLUE);
  190.  
  191.               if (GuiButton((Rectangle){W/2 -100, H/2 -40, 200, 50}, "Start"))
  192.               {
  193.                   inMenu      = false;
  194.                   gameStarted = true;
  195.                   gameOver    = false;
  196.                   spawnedCount= 0;
  197.                   transX = spawnX; transY = spawnY; transZ = spawnZ;
  198.                   pitch = roll = yaw = 0;
  199.               }
  200.               if (GuiButton((Rectangle){W/2 -100, H/2 +20, 200, 50}, "Exit"))
  201.               {
  202.                   CloseWindow();
  203.                   return 0;
  204.               }
  205.           }
  206.           else  // gameplay
  207.           {
  208.               BeginMode3D(camera);
  209.                 DrawModel(terrain, (Vector3){-50,0,-50}, 1.0f, WHITE);
  210.                 DrawGrid(500,1);
  211.                 DrawModel(runway,  (Vector3){95,27.458f,15}, 1.0f, WHITE);
  212.  
  213.                 // --- Draw Planes ---
  214.                 // First, draw the player-controlled plane. Its transform is already set from the simulation update.
  215.                 DrawModel(planeModel, (Vector3){0,0,0}, 1.0f, WHITE);
  216.  
  217.                 // Now, draw the other spawned planes.
  218.                 // To do this without messing up the player plane's transform for the next frame,
  219.                 // we'll save it, draw the other planes by temporarily changing the transform,
  220.                 // and then restore it.
  221.                 Matrix playerTransform = planeModel.transform; // Save player's transform
  222.  
  223.                 for (int i = 0; i < spawnedCount; i++)
  224.                 {
  225.                     planeModel.transform = spawned[i]; // Temporarily use the spawned plane's transform
  226.                     DrawModel(planeModel, (Vector3){0,0,0}, 1.0f, WHITE);
  227.                 }
  228.  
  229.                 planeModel.transform = playerTransform; // Restore player's transform
  230.  
  231.                 DrawSphere(landingSpot, 1.0f, RED);
  232.               EndMode3D();
  233.  
  234.               DrawFPS(960,10);
  235.  
  236.             // <-- Add Planes
  237.               Rectangle addBtn = { 20, 20, 140, 40 };
  238.               // We can have a max of MAX_PLANES total. 1 is the player plane.
  239.               if (GuiButton(addBtn, "Add Planes"))
  240.               {
  241.                   if ((1 + spawnedCount) < MAX_PLANES)
  242.                       spawned[spawnedCount++] = baseSpawn;
  243.               }
  244.  
  245.               // Now draw one lettered button per active plane.
  246.               // There is always 1 (the player) + `spawnedCount` others.
  247.               for (int i = 0; i < 1 + spawnedCount; i++)
  248.               {
  249.                   // Position each button below the last, starting below the "Add Planes" button
  250.                   Rectangle letterBtn = {
  251.                       addBtn.x,
  252.                       addBtn.y + addBtn.height + 10 + (i * (addBtn.height + 10)),
  253.                       addBtn.width,
  254.                       addBtn.height
  255.                   };
  256.                  
  257.                   char label[2] = { 'A' + i, '\0' };  // "A", "B", "C", etc.
  258.                  
  259.                   // When a button is clicked, you could use its index 'i'
  260.                   // to select that plane for camera focus or control.
  261.                   if (GuiButton(letterBtn, label))
  262.                   {
  263.                       // For future use:
  264.                       // if (i == 0) {
  265.                       //     // This is the player's plane (Plane A)
  266.                       // } else {
  267.                       //     // This is a spawned plane (B, C, ...). Its index in the `spawned` array is `i - 1`.
  268.                       //     // For example: select spawned[i - 1]
  269.                       // }
  270.                   }
  271.               }
  272.  
  273.  
  274.               // Game Over overlay
  275.               if (gameOver)
  276.               {
  277.                   DrawRectangle(0,0,W,H, Fade(BLACK, 0.5f));
  278.                   DrawText("LANDED!",
  279.                            W/2 - MeasureText("LANDED!", 40)/2,
  280.                            H/2 - 50, 40, WHITE);
  281.                   DrawText("Press Y to Play Again or N to Exit",
  282.                            W/2 - MeasureText("Press Y to Play Again or N to Exit", 20)/2,
  283.                            H/2 + 10, 20, WHITE);
  284.                   if (IsKeyPressed(KEY_Y))
  285.                   {
  286.                       gameOver     = false;
  287.                       spawnedCount = 0;
  288.                       transX = spawnX; transY = spawnY; transZ = spawnZ;
  289.                       pitch = roll = yaw = 0;
  290.                   }
  291.                   if (IsKeyPressed(KEY_N)) break;
  292.               }
  293.           }
  294.         EndDrawing();
  295.     }
  296.  
  297.     // --- Cleanup ---
  298.     CloseAudioDevice();
  299.     UnloadMusicStream(engineSound);
  300.     UnloadModel(terrain);     UnloadTexture(terrainTex); UnloadShader(sat);
  301.     UnloadModel(planeModel);  UnloadTexture(planeTex);
  302.     UnloadModel(runway);      UnloadTexture(runwayTex);
  303.     CloseWindow();
  304.  
  305.     return 0;
  306. }
Advertisement
Add Comment
Please, Sign In to add comment