Browse Source

Create FlowFieldTest.c

Rudy Boudewijn van Etten 5 years ago
parent
commit
a80539f6e6
1 changed files with 257 additions and 0 deletions
  1. 257 0
      RTS/FlowFieldTest.c

+ 257 - 0
RTS/FlowFieldTest.c

@@ -0,0 +1,257 @@
+//
+// FLOW fields - work in progress
+//  
+
+#define MAX_AGENTS 50
+
+#include "raylib.h"
+#include <math.h>
+
+// This is our tile map.
+int map[10][20] = { {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
+                    {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,1,1,1},
+                    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1},
+                    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
+                    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
+                    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
+                    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
+                    {1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1},
+                    {1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1},
+                    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}};    
+
+static float tileWidth;
+static float tileHeight;
+static int mapWidth;
+static int mapHeight;
+
+typedef struct player{
+    Vector2 position;
+    int width;
+    int height;
+}player;
+
+static player myplayer = {0};
+
+static float flowfieldmap[10][20] = {0};
+
+typedef struct agent{
+    Vector2 position;
+    int width;
+    int height;
+    Vector2 target;
+    float speed;
+    int pausetime;
+}agent;
+
+static struct agent arr_agent[MAX_AGENTS];
+
+// uses the myplayer.position coordinates.
+// If offsetx is 1 then it checks if the player x position PLus 1 is colliding with a tile.
+static bool playertilecollide(int offsetx,int offsety);
+static bool rectsoverlap(int x1,int y1,int w1,int h1,int x2,int y2,int w2,int h2);
+static float getangle(float x1,float y1,float x2,float y2);
+
+
+
+int main(void)
+{
+    // Initialization
+    //--------------------------------------------------------------------------------------
+    const int screenWidth = 800;
+    const int screenHeight = 450;
+    mapWidth = 20;
+    mapHeight = 10;
+    // Our tile width and height. We use the screen dimension and the map dimension to 
+    // get tile dimensions that fill up the entire screen.
+    tileWidth = (float)screenWidth/(float)mapWidth;
+    tileHeight = (float)screenHeight/(float)mapHeight;
+
+
+    InitWindow(screenWidth, screenHeight, "raylib example.");
+
+
+    // Our player setup    
+    myplayer.position = (Vector2){4*tileWidth,6*tileHeight};
+    myplayer.width = tileWidth/2;
+    myplayer.height = tileHeight/2;
+
+    for(int y=0;y<mapHeight;y++){
+    for(int x=0;x<mapWidth;x++){
+        flowfieldmap[y][x]=GetRandomValue(0,3);
+    }
+    }
+
+    // add units to the screen
+    int y=0;
+    int x=0;
+    int sq=0;
+    for(int i=0;i<MAX_AGENTS;i++){
+        
+        
+        arr_agent[i].position = (Vector2){100+x,100+y};
+        arr_agent[i].width = 10;
+        arr_agent[i].height = 10;
+        arr_agent[i].speed = 1.0f;
+        arr_agent[i].target = (Vector2){400,200};
+        arr_agent[i].pausetime = 0;
+        x+=12;
+        sq++;
+        if(sq == 4){
+            sq=0;
+            y+=12;
+            x=0;
+        }
+    }
+
+    
+    SetTargetFPS(60);               // Set our game to run at 60 frames-per-second
+    //--------------------------------------------------------------------------------------
+
+    // Main game loop
+    while (!WindowShouldClose())    // Detect window close button or ESC key
+    {
+        // Update
+        //----------------------------------------------------------------------------------
+        
+        // Below here we read the key. If the l/r/u/d cursor is pressed then we check the new position is inside
+        // the array bounds and then we check if the collision map on the new position is not set to flag true on that tile.
+        if(IsKeyDown(KEY_RIGHT)&& myplayer.position.x+1<(mapWidth-1)*tileWidth){
+            if(playertilecollide(1,0)==false){
+                myplayer.position.x+=1;
+            }
+        }
+        if(IsKeyDown(KEY_LEFT) && myplayer.position.x-1>-1){
+            if(playertilecollide(-1,0)==false){
+                myplayer.position.x-=1;
+            }
+        }
+        if(IsKeyDown(KEY_UP)&& myplayer.position.y-1>-1){
+            if(playertilecollide(0,-1)==false){
+                myplayer.position.y-=1;
+            }
+        }
+        if(IsKeyDown(KEY_DOWN) && myplayer.position.y+1<(mapHeight-1)*tileHeight){
+            if(playertilecollide(0,1)==false){
+                myplayer.position.y+=1;
+            }
+        }
+        
+        if(IsMouseButtonPressed(0)){
+            for(int i=0;i<MAX_AGENTS;i++){
+                int posx = GetMouseX()/tileWidth;
+                int posy = GetMouseY()/tileHeight;
+                //if(map[posy][posx]==0){
+                    arr_agent[i].target = GetMousePosition();
+                //}
+            }
+        }
+
+        //reset flowfieldmap
+        if(GetRandomValue(0,20)==1){
+        for(int y=0;y<mapHeight;y++){
+        for(int x=0;x<mapWidth;x++){
+            flowfieldmap[y][x]=0;
+        }}
+        }
+        // Move the units.
+        for(int i=0;i<MAX_AGENTS;i++){
+            if(arr_agent[i].pausetime>0){
+                arr_agent[i].pausetime--;                
+            }
+            if(arr_agent[i].pausetime>0)continue;
+            float angle = getangle(arr_agent[i].position.x,arr_agent[i].position.y,arr_agent[i].target.x,arr_agent[i].target.y);
+            Vector2 oldPos = arr_agent[i].position;
+            int posx=arr_agent[i].position.x/tileWidth;
+            int posy=arr_agent[i].position.y/tileHeight;
+            
+            arr_agent[i].position.x+= cos(angle);
+            arr_agent[i].position.y+= sin(angle);
+            if(flowfieldmap[posy][posx]!=0){
+            arr_agent[i].position.x+= cos(flowfieldmap[posy][posx])/1.5;
+            arr_agent[i].position.y+= sin(flowfieldmap[posy][posx])/1.5;
+            }
+            for(int j=0;j<MAX_AGENTS;j++){
+                if(j==i)continue;
+                if(rectsoverlap(arr_agent[i].position.x,arr_agent[i].position.y,arr_agent[i].width,arr_agent[i].height,
+                                arr_agent[j].position.x,arr_agent[j].position.y,arr_agent[j].width,arr_agent[j].height)){
+                    arr_agent[i].position = oldPos;
+                    arr_agent[i].pausetime = GetRandomValue(0,5);
+                    float an2=getangle(arr_agent[i].position.x,arr_agent[i].position.y,arr_agent[j].position.x,arr_agent[j].position.y);
+                    int px = arr_agent[j].position.x/tileWidth;
+                    int py = arr_agent[j].position.y/tileHeight;
+                    flowfieldmap[py][px]=an2+GetRandomValue(-1.5f,1.5f);
+                }
+            }
+        }
+
+        //----------------------------------------------------------------------------------
+        // Draw
+        //----------------------------------------------------------------------------------
+        BeginDrawing();
+
+            ClearBackground(RAYWHITE);
+                
+            // Draw our tilemap.
+            for(int y=0;y<10;y++){
+                for(int x=0;x<20;x++){
+                    if(map[y][x]==1){
+                        DrawRectangle(x*tileWidth,y*tileHeight,tileWidth,tileHeight,BLACK);
+                    }
+                }
+            }
+            
+            // Draw out agents
+            for(int i=0;i<MAX_AGENTS;i++){
+                DrawRectangle(arr_agent[i].position.x,arr_agent[i].position.y,arr_agent[i].width,arr_agent[i].height,BLUE);
+            }
+            
+            
+            // Draw our player
+            DrawRectangle(myplayer.position.x,myplayer.position.y,myplayer.width,myplayer.height,RED);
+            
+            DrawText("Use Cursor Keys to move around..",0,0,20,WHITE);
+        EndDrawing();
+        //----------------------------------------------------------------------------------
+    }
+
+    // De-Initialization
+    //--------------------------------------------------------------------------------------
+    CloseWindow();        // Close window and OpenGL context
+    //--------------------------------------------------------------------------------------
+
+    return 0;
+
+
+}
+
+//Unit collide with solid blocks true/false
+bool playertilecollide(int offsetx,int offsety){
+    int cx = (myplayer.position.x+offsetx)/tileWidth;
+    int cy = (myplayer.position.y+offsety)/tileHeight;
+    for(int y2=cy-1; y2<cy+2;y2++){//Note that the - and + are to be set differently with differently sized players
+    for(int x2=cx-1; x2<cx+2;x2++){
+        if(x2>=0 && x2<mapWidth && y2>=0 && y2<mapHeight){
+            if(map[y2][x2] == 1){
+                int x3 = (x2)*tileWidth;
+                int y3 = (y2)*tileHeight;
+                if(rectsoverlap(myplayer.position.x+offsetx,myplayer.position.y+offsety,myplayer.width,myplayer.height,x3,y3,tileWidth,tileHeight)){
+                    return true;
+                }
+            }
+        }
+    }}
+    return false;
+}
+
+// Rectangles overlap
+bool rectsoverlap(int x1,int y1,int w1,int h1,int x2,int y2,int w2,int h2){
+    if(x1 >= (x2 + w2) || (x1 + w1) <= x2) return false;
+    if(y1 >= (y2 + h2) || (y1 + h1) <= y2) return false;
+    return true;
+}
+
+// Return the angle from - to in float
+float getangle(float x1,float y1,float x2,float y2){
+    return (float)atan2(y2-y1, x2-x1);
+}
+