123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353 |
- //
- // Template topdown smooth movement player.
- // Map setup through array.
- // Agents, BreathFirst distance map.
- #include "raylib.h"
- #include <math.h>
- #define MAX_PATH 1024
- #define MAX_AGENT 32 // Maximum number of ai entities
- #define SPEED 1
- enum terrain{TREE=1,GROUND=0,PLAYER=2,AIPLAYER=3,GOAL=4,GOALREACHED=5};
- enum flag{UP,DOWN,LEFT,RIGHT,WAIT};
- //
- // You can set any number of 3 and 2 on the map. more 4's untested. keep the borders(1) intact(memory errors)
- //
- //1=border(TREE),2=PLAYER,3=AIPLAYER,4=Path finding objective(GOAL)
- int map1[10][10] = { {1,1,1,1,1,1,1,1,1,1},
- {1,0,0,0,0,1,0,0,3,1},
- {1,0,0,0,0,1,0,0,0,1},
- {1,3,0,0,0,1,0,0,0,1},
- {1,0,0,0,0,1,1,0,1,1},
- {1,0,0,0,0,1,0,0,0,1},
- {1,1,1,0,1,1,0,0,0,1},
- {1,0,0,0,0,0,2,0,0,1},
- {1,0,0,0,0,0,0,0,0,1},
- {1,1,1,1,1,1,1,1,1,1}
- };
- int map[10][10] = {0};
- int dijkstramap[10][10]={0};
- typedef struct pathnode{
- int x;
- int y;
- }pathnode;
- typedef struct agent{
- bool active;
- Vector2 position;
- Vector2 size;
- }agent;
- static struct agent arr_agent[MAX_AGENT];
- typedef struct player{
- Vector2 position;
- Vector2 size;
- }player;
- player myPlayer = {0};
- void makedijkstramap();
- static float distance(float x1,float y1,float x2,float y2);
- static float edistance(float x1,float y1,float x2,float y2);
- //Unit collide with solid blocks true/false
- bool recttilecollide(int x, int y, int w, int h, int offsetx,int offsety);
- // Our rectsoverlap function. Returns true/false.
- static bool rectsoverlap(int x1,int y1,int w1,int h1,int x2,int y2,int w2,int h2);
- void updateplayer();
-
- int topdijkstralen=0;
- int screenWidth;
- int screenHeight;
- int tileWidth,tileHeight,mapWidth,mapHeight;
- int main(void)
- {
- // Initialization
- //--------------------------------------------------------------------------------------
- screenWidth = 800;
- screenHeight = 600;
- mapWidth = 10;
- mapHeight = 10;
- tileWidth = ceil((float)screenWidth/(float)mapWidth);
- tileHeight = ceil((float)screenHeight/(float)mapHeight);
-
- InitWindow(screenWidth, screenHeight, "raylib example.");
-
- SetTargetFPS(200); // Set our game to run at 60 frames-per-second
- //--------------------------------------------------------------------------------------
- //makedijkstramap(); // The 4 = the goal that gets flooded from...
- //
- // Copy our original map into the active map...
- for(int y=0;y<mapHeight;y++){
- for(int x=0;x<mapHeight;x++){
- map[y][x]= map1[y][x];
- }}
-
- // set our player up..
- for(int y=0;y<mapHeight;y++){
- for(int x=0;x<mapHeight;x++){
- if(map[y][x]==PLAYER){
- myPlayer.position = (Vector2){x*tileWidth,y*tileHeight};
- myPlayer.size = (Vector2){tileWidth/2,tileHeight/2};
- map[y][x]=GROUND;
- }
- }}
- // set our agents(ai) up..
- int agentcount=0;
- for(int y=0;y<mapHeight;y++){
- for(int x=0;x<mapHeight;x++){
- if(map[y][x]==AIPLAYER){
- arr_agent[agentcount].active=true;
- arr_agent[agentcount].position = (Vector2){x*tileWidth,y*tileHeight};
- arr_agent[agentcount].size = (Vector2){tileWidth/2,tileHeight/2};
- map[y][x]=GROUND;
- agentcount++;
- }
- }}
- // Main game loop
- while (!WindowShouldClose()) // Detect window close button or ESC key
- {
- // Update
- //----------------------------------------------------------------------------------
-
- updateplayer();
-
- //----------------------------------------------------------------------------------
- // Draw
- //----------------------------------------------------------------------------------
- BeginDrawing();
- ClearBackground(RAYWHITE);
- //drawmap (tile positions)
- for(int y=0;y<10;y++){
- for(int x =0;x<10;x++){
- int m=map[y][x];
- if(m==TREE){
-
- DrawRectangle(x*tileWidth,y*tileHeight,tileWidth,tileHeight,(Color){40,90,20,255});
- DrawCircle(x*tileWidth+tileWidth/1.5,y*tileHeight+tileHeight/1.5,tileWidth/5,(Color){20,50,20,255});
- DrawRectangle(x*tileWidth+tileWidth/2.2,y*tileHeight+tileHeight/2,tileWidth/8,tileHeight/3,BROWN);
-
- DrawCircle(x*tileWidth+tileWidth/2,y*tileHeight+tileHeight/3,tileWidth/4,(Color){120,250,20,255});
- DrawCircle(x*tileWidth+tileWidth/2.2,y*tileHeight+tileHeight/4,tileWidth/9,(Color){220,255,220,155});
- }
- if(m==GROUND){
- DrawRectangle(x*tileWidth,y*tileHeight,tileWidth,tileHeight,DARKGREEN);
- DrawRectangle(x*tileWidth+5,y*tileHeight+10,2,1,GREEN);
- DrawRectangle(x*tileWidth+tileWidth/6,y*tileHeight+tileHeight/6,2,1,GREEN);
- DrawRectangle(x*tileWidth+tileWidth/1.5,y*tileHeight+tileHeight/1.5,2,1,GREEN);
- DrawRectangle(x*tileWidth+tileWidth/2,y*tileHeight+tileHeight/2,2,1,GREEN);
-
- }
- if(m==PLAYER){
- DrawRectangle(x*tileWidth,y*tileHeight,tileWidth,tileHeight,BLUE);
- DrawText("Player",x*tileWidth,y*tileHeight+tileHeight/4,16,BLACK);
- }
- if(m==AIPLAYER){
- DrawRectangle(x*tileWidth,y*tileHeight,tileWidth,tileHeight,RED);
- DrawText("Ai_Player",x*tileWidth,y*tileHeight+tileHeight/4,16,WHITE);
- }
- if(m==GOAL){
- DrawRectangle(x*tileWidth,y*tileHeight,tileWidth,tileHeight,WHITE);
- DrawText("City",x*tileWidth+tileWidth/4,y*tileHeight+tileHeight/4,26,BLACK);
- }
- if(m==GOALREACHED){
- DrawRectangle(x*tileWidth,y*tileHeight,tileWidth,tileHeight,YELLOW);
- DrawText("Captured",x*tileWidth+4,y*tileHeight+tileHeight/4,16,BLACK);
- }
- DrawText(FormatText("%i",dijkstramap[y][x]),x*tileWidth+tileWidth/2-10,y*tileHeight+tileHeight/2-10,20,BLACK);
- }
- }
-
- // Draw our agents..
- for(int i=0;i<MAX_AGENT;i++){
- int x = arr_agent[i].position.x;
- int y = arr_agent[i].position.y;
- int w = arr_agent[i].size.x;
- int h = arr_agent[i].size.y;
- DrawRectangle(x,y,w,h,RED);
- DrawText(FormatText("Agent %i",i),x,y+h/8,h/8,WHITE);
- }
-
-
- // Draw our player..
- int x = myPlayer.position.x;
- int y = myPlayer.position.y;
- int w = myPlayer.size.x;
- int h = myPlayer.size.y;
- DrawRectangle(x,y,w,h,BLUE);
- DrawText("Player",x,y+h/8,h/4,BLACK);
-
-
- DrawText("Cursors U/D/L/R",10,10,26,BLACK);
- DrawText("Cursors U/D/L/R",9,9,26,WHITE);
-
-
-
- EndDrawing();
- //----------------------------------------------------------------------------------
- }
- // De-Initialization
- //--------------------------------------------------------------------------------------
- CloseWindow(); // Close window and OpenGL context
- //--------------------------------------------------------------------------------------
- return 0;
- }
- void updateplayer(){
- for(int sp=0;sp<SPEED;sp++){ // our movement speed (makes to check collision every step)
- Vector2 oldpos = myPlayer.position;
- if(IsKeyDown(KEY_LEFT)){
- myPlayer.position.x-=1;
- }
- if(IsKeyDown(KEY_RIGHT)){
- myPlayer.position.x+=1;
- }
- if(recttilecollide(myPlayer.position.x,myPlayer.position.y,tileWidth/2,tileHeight/2,0,0)){
- myPlayer.position = oldpos;
- }
- oldpos = myPlayer.position;
- if(IsKeyDown(KEY_UP)){
- myPlayer.position.y-=1;
- }
- if(IsKeyDown(KEY_DOWN)){
- myPlayer.position.y+=1;
- }
- if(recttilecollide(myPlayer.position.x,myPlayer.position.y,tileWidth/2,tileHeight/2,0,0)){
- myPlayer.position = oldpos;
- }
- }
- }
- void makedijkstramap(){
-
- int startx;
- int starty;
- // First make sure every map value is 0.
- for(int y=0;y<mapHeight;y++){
- for(int x=0;x<mapWidth;x++){
- dijkstramap[y][x] = 0;
- if(map1[y][x]==1)dijkstramap[y][x]=-1;
- if(map1[y][x]==4){
- startx = x;
- starty = y;
- }
- }}
-
- //
-
- //
- // Flood the map with distances from the start.
- //
-
- // We store the distance on each map cell if there is no wall there.
- //
- struct pathnode list[MAX_PATH];
- dijkstramap[starty][startx]=1;
- int listlen=0;
- list[listlen].x=startx;
- list[listlen].y=starty;
- listlen+=1;
- int failed=0;
- // 4 way search! left/up/down/right
- int dx[8]={ -1,0,1,-1,1,-1,0,1};
- int dy[8]={-1,-1,-1,0,0,1,1,1};
- // While we have a list to work with
- while(listlen>0){
- // Take the first value from the array.
- int x1=list[0].x;
- int y1=list[0].y;
-
- // shift all up.
- for(int i=0;i<listlen;i++){
- list[i].x = list[i+1].x;
- list[i].y = list[i+1].y;
- }
- // Decrease list length
- listlen-=1;
- //
- // Here we check around our current position.
- for(int i=0;i<8;i++){
- int nx = x1+dx[i];
- int ny = y1+dy[i];
- if(nx<0 || ny<0 || nx>= mapWidth || ny>= mapHeight)continue;
- // If we can get there then put the new distance there and add this position
- // to the list.
- if(dijkstramap[ny][nx]==0 && map[ny][ny]!=1){
- dijkstramap[ny][nx]=dijkstramap[y1][x1]+1;
- if(dijkstramap[ny][nx]>topdijkstralen)topdijkstralen=dijkstramap[ny][nx];
- // add to last
- //
- list[listlen].x = nx;
- list[listlen].y = ny;
- listlen++;
- //
- }
- }
- // Error?
- failed+=1;
- if(failed>160000)return;
-
- }
-
-
- }
- // Manhattan Distance (less precise)
- float distance(float x1,float y1,float x2,float y2){
- return (float)abs(x2-x1)+abs(y2-y1);
- }
- // Euclidean distance (more precise)
- float edistance(float x1,float y1,float x2,float y2){
- return sqrt( (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2) );
- }
- //Unit collide with solid blocks true/false
- bool recttilecollide(int x, int y,int w, int h, int offsetx,int offsety){
- //y+=abs(mapy);//for scrolling
- int cx = (x+offsetx)/tileWidth;
- int cy = (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(x+offsetx,y+offsety,w,h,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;
- }
|