Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <windows.h>
- #include <math.h>
- #include <time.h>
- // Types
- typedef struct _COORD vec2;
- typedef enum {
- BLACK, BLUE, GREEN, AQUA, RED, PURPLE,
- YELLOW, LGRAY, GRAY, LBLUE, LGREEN, LAQUA,
- LRED, LPURPLE, LYELLOW, WHITE
- } colors;
- typedef enum {false, true} bool;
- typedef enum {DEAD, INGAME, INMENU, INTITLE} state;
- typedef struct blk
- {
- int fg, bg;
- char ascii;
- bool collide;
- } block;
- typedef struct _player
- {
- int x,y;
- int fg;
- bool canMove;
- char ascii;
- } player;
- typedef struct _camera
- {
- int x,y;
- int px, py;
- int *buffer;
- int width,height;
- } camera;
- // Static variables.
- static camera *cam;
- static player *plr;
- static vec2 curpos;
- static int map[100][100];
- static block *blocks;
- static state gameState;
- // Functions
- void initGame();
- void endGame();
- void spos(int, int);
- void scol(int , int);
- void moveCam(int, int);
- void setRenderOffs(int, int);
- void strpos(char*, int, int);
- void drawMap();
- int rand_range(int, int);
- void redrawMap(int, int);
- void clearMap(int);
- void drawPlayer();
- void setCamBuffer(int, int, int);
- int checkCamBuffer(int, int);
- bool movePlayer(int, int, bool);
- void scrollMap(int, int, int);
- block newBlock(int, int, char, bool);
- void drawBuffer(int, int);
- void drawMapBlock(int, int);
- void drawBlock(block);
- void setBlock(int, int, int);
- block getBlock(int, int);
- void setPlayerGraphic(int, char);
- // Game loops;
- void update();
- void draw();
- // Macros
- #define rcols() ( scol(LGRAY,BLACK) )
- #define min(x, y) ( (x < y) ? x : y )
- #define max(x, y) ( (x > y) ? x : y )
- #define randomize() ( srand(time(NULL)) )
- int main()
- {
- initGame();
- randomize();
- setRenderOffs(10,2);
- clearMap(0);
- int i;
- for ( i = 0; i < 369; i++)
- {
- int x = rand_range(1,99);
- int y = rand_range(1,99);
- int b = rand_range(0,4);
- setBlock(x,y,b);
- }
- drawMap();
- while(gameState != DEAD)
- {
- draw();
- update();
- drawBuffer(65,2);
- }
- endGame();
- return 0;
- }
- block newBlock(int fg, int bg, char a, bool c)
- {
- block nBlock;
- nBlock.fg = fg;
- nBlock.bg = bg;
- nBlock.ascii = a;
- nBlock.collide = c;
- return nBlock;
- }
- void setBlock(int x, int y, int id)
- {
- map[y][x] = id;
- }
- block getBlock(int x, int y)
- {
- return blocks[map[y][x]];
- }
- void drawMap()
- {
- // Fill map based on block id.
- int msize = (int) sqrt(sizeof(map)/sizeof(int));
- int h;
- int w;
- int id = 0;
- int draw_w = min(cam->x+cam->width, msize);
- int draw_h = min(cam->y+cam->height, msize);
- //printf("At X: %d \n At Y: %d",cam->x, cam->y);
- for (h = cam->y; h < draw_h; h++)
- {
- for (w = cam->x; w < draw_w; w++)
- {
- if(h >= 90 || w >= 90 || h < 0 || w < 0)
- {
- id = 5;
- }
- else
- {
- id = map[h][w];
- }
- if( blocks+id != NULL )
- {
- if(plr->x == w && plr->y == h)
- {
- drawPlayer();
- }
- else
- {
- if( checkCamBuffer(w-(cam->x), h-(cam->y)) != id)
- {
- spos(cam->px+( w-cam->x ), cam->py+( h-cam->y ) );
- drawBlock( *(blocks+id) );
- setCamBuffer(w-(cam->x), h-(cam->y), id);
- }
- }
- }
- }
- }
- }
- void drawBuffer(int rx, int ry)
- {
- int h;
- int w;
- for (h = 0; h < cam->height; h++)
- {
- for (w = 0; w < cam->width; w++)
- {
- block blk = blocks[checkCamBuffer(w,h)];
- spos(w+rx,h+ry);
- scol(WHITE, GRAY);
- printf("%d",checkCamBuffer(w,h));
- rcols();
- }
- }
- }
- void drawPlayer()
- {
- int bg = getBlock(plr->x, plr->y).bg;
- scol(plr->fg,bg);
- spos( (plr->x - cam->x) + cam->px , (plr->y - cam->y) + cam->py);
- putchar(plr->ascii);
- }
- bool movePlayer(int xo, int yo, bool checkCollide)
- {
- int msize = (int) sqrt(sizeof(map)/sizeof(int));
- if( (!checkCollide || !blocks[map[plr->y+yo][plr->x+xo]].collide) &&
- plr->x+xo >= 0 && plr->y+yo >= 0 && plr->x+xo < msize-10 && plr->y+yo < msize-10)
- {
- drawMapBlock(plr->x,plr->y);
- plr->x += xo;
- plr->y += yo;
- drawPlayer();
- }
- }
- void scrollMap(int xo, int yo, int speed)
- {
- int dX = 0;
- int dY = 0;
- int mX, mY;
- mX = (xo > 0) ? 1 : (xo == 0) ? 0 : -1;
- mY = (yo > 0) ? 1 : (yo == 0) ? 0 : -1;
- plr->canMove = false;
- fflush(stdin); // We don't want to move oddly once we're done scrolling.
- while(dX != xo || dY != yo)
- {
- moveCam(mX,mY);
- drawMap();
- dX+=mX;
- dY+=mY;
- Sleep(speed);
- }
- Sleep(speed*2);
- plr->canMove = true;
- }
- void drawMapBlock(int x, int y)
- {
- spos( (x-cam->x) + cam->px, (y-cam->y) + cam->py);
- drawBlock( *(blocks+map[y][x]) );
- }
- void clearMap(int block)
- {
- // Fill map based on block id.
- int msize = (int) sqrt(sizeof(map)/sizeof(int));
- int h;
- int w;
- for (h = 0; h < msize; h++)
- {
- for (w = 0; w < msize; w++)
- {
- map[h][w] = block;
- }
- }
- }
- void spos(int x, int y)
- {
- vec2 pos;
- pos.X = x;
- pos.Y = y;
- curpos.X = x;
- curpos.Y = y;
- HANDLE chand = GetStdHandle(STD_OUTPUT_HANDLE);
- SetConsoleCursorPosition(chand, pos);
- }
- void scol(int fg, int bg)
- {
- bg = bg << 4;
- unsigned char col = fg+bg;
- HANDLE chand = GetStdHandle(STD_OUTPUT_HANDLE);
- SetConsoleTextAttribute(chand, col);
- }
- void strpos(char *t, int x, int y)
- {
- spos(x,y);
- puts(t);
- }
- void drawBlock(block blk)
- {
- scol(blk.fg, blk.bg);
- putchar(blk.ascii);
- rcols();
- }
- void setPlayerGraphic(int fg, char a)
- {
- plr->fg = fg;
- plr->ascii = a;
- }
- int rand_range(int rmin, int rmax)
- {
- return rand() % ((rmax+1) - rmin) + rmin;
- }
- void moveCam(int xo, int yo)
- {
- cam->x += xo;
- cam->y += yo;
- }
- void setRenderOffs(int rx, int ry)
- {
- cam->px = rx;
- cam->py = ry;
- }
- void update()
- {
- // Character controller.
- char key = getch();
- switch(key)
- {
- case 'w':
- movePlayer(0,-1,1);
- break;
- case 's':
- movePlayer(0,1,1);
- break;
- case 'a':
- movePlayer(-1,0,1);
- break;
- case 'd':
- movePlayer(1,0,1);
- break;
- }
- }
- void draw()
- {
- // Positional information.
- scol(WHITE,BLACK);
- spos(2,0);
- printf("Pos -> X: %d \n Pos -> Y: %d \n",plr->x,plr->y);
- // Scroll when player is at the edge of the screen (zelda style)
- int scrollX = (cam->width/2 );
- int scrollY = (cam->height/2);
- if( (plr->x - cam->x) >= cam->width-1 )
- {
- scrollMap(scrollX,0,2);
- }
- if( (plr->x - cam->x) <= 0 )
- {
- scrollMap(-scrollX,0,2);
- }
- if( (plr->y - cam->y) >= cam->height-1 )
- {
- scrollMap(0,scrollY,2);
- }
- if( (plr->y - cam->y) <= 0 )
- {
- scrollMap(0,-scrollY,2);
- }
- }
- int checkCamBuffer(int x, int y)
- {
- int result = *(cam->buffer + (y * cam->width) + x);
- if(result == NULL) return -1;
- return result;
- }
- void setCamBuffer(int x, int y, int id)
- {
- *(cam->buffer + (y * cam->width) + x) = id;
- }
- void initGame()
- {
- gameState = INGAME;
- // Init blocks.
- blocks = calloc(6, sizeof(block));
- blocks[0] = newBlock(LGREEN, GREEN, '*',0); // GRASS
- blocks[1] = newBlock(RED, LGRAY, '=',1); // BRICK
- blocks[2] = newBlock(LGRAY, LGRAY, ' ',1); // CEMENT
- blocks[3] = newBlock(LAQUA, AQUA, '~',0); // WATER
- blocks[4] = newBlock(YELLOW, GREEN, '&',0); // FLOWER
- blocks[5] = newBlock(BLUE, BLUE, ' ',1); // VOID
- // Init camera / player.
- cam = malloc(sizeof(camera));
- plr = malloc(sizeof(player));
- cam->x = 0;
- cam->y = 0;
- cam->px = 0;
- cam->py = 0;
- cam->width = 52;
- cam->height = 19;
- cam->buffer = NULL;
- cam->buffer = calloc(cam->width * cam->height, sizeof(int));
- plr->x = (cam->width/2);
- plr->y = (cam->height/2);
- plr->fg = LBLUE;
- plr->canMove = true;
- plr->ascii = '@';
- // Setup cursor visibility
- HANDLE chand = GetStdHandle(STD_OUTPUT_HANDLE);
- CONSOLE_CURSOR_INFO cinfo;
- cinfo.dwSize = 100;
- cinfo.bVisible = false;
- SetConsoleCursorInfo(chand, &cinfo);
- }
- void endGame()
- {
- HANDLE chand = GetStdHandle(STD_OUTPUT_HANDLE);
- CONSOLE_CURSOR_INFO cinfo;
- cinfo.dwSize = 100;
- cinfo.bVisible = true;
- SetConsoleCursorInfo(chand, &cinfo);
- free(blocks);
- free(cam);
- free(plr);
- free(cam->buffer);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement