From 0cb9fa1c023033c250fd0bf33c2cee49fc85f178 Mon Sep 17 00:00:00 2001 From: talha <-> Date: Mon, 12 Aug 2024 19:39:04 +0500 Subject: Added files to git tracking --- src/game_v0.c | 512 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 512 insertions(+) create mode 100644 src/game_v0.c (limited to 'src/game_v0.c') diff --git a/src/game_v0.c b/src/game_v0.c new file mode 100644 index 0000000..62141f6 --- /dev/null +++ b/src/game_v0.c @@ -0,0 +1,512 @@ +#include "raylib.h" +#include "raymath.h" + +#if defined(PLATFORM_WEB) + #include +#endif + +typedef enum { + O = 0, // nothing + //P = 1, // player + t = 2, // tree + T = 3, // troll area + B = 4, // bandit area + T_B = 5, // troll base + B_B = 6, // bandit base + //G = 7, // gate (exit) +} MapSymbol; + +typedef enum { + AA_IDLE = 0, + AA_CHARGE = 1, + AA_ATTACK = 2, +} AttackAnimState; + +typedef enum { + T_IDLE = 0, + T_FOLLOW = 1, + T_AGGRO = 2, +} TrollState; + +typedef enum { + HA_IDLE = 0, + HA_PLAY = 1, +} HitAnimState; + +typedef struct ScuffString { + char *buffer; + int len; + int capacity; +} String; + +typedef struct State { + // how much scaling to apply from original asset resolution + float render_scale; + // game positions + bool is_player_hit; + Vector2 pixels_per_gridbox; + Vector2 mouse_position; + Vector2 player_position; + Color player_tint; + // @note: normally when we place a texture, the coordinates + // are the top left coordinates. This will cause a disconnect + // when moving the player with a point and click motion. + // To fix that we calculate a new position so the player_coordinates + // are in the center. This will make it so when the player clicks on the + // ground somewhere, the character sprite will be properly centered on that point. + Rectangle player_render_rect; + Vector2 player_position_target; + + Vector2 bandit_position; + // troll state + int troll_state; + float troll_move_delta; + Vector2 troll_position; + Vector2 troll_last_player_position; + Vector2 troll_move_dir; + Vector2 troll_position_target; + Rectangle troll_render_rect; + Color troll_tint_base; + Color troll_tint; + // - troll attack + bool troll_anim_attack_play; + int troll_attack_anime_state; + double t_troll_charge_anim_start; + float t_troll_charge_anim_duration; + float t_troll_anim_freq; + float troll_attack_offset_max; + float t_troll_attack_anim_start; + float t_troll_attack_anim_duration; + + // player movement + bool is_player_move; + Vector2 player_move_dir; + // @todo + // direction player is being hit from, incorporate that into the gameplay code + // For now, just update the player_move_dir to the player_hit_dir + // Vector2 player_hit_dir; + float player_move_delta; // amount player will move + // target position player will move to + // 1. the player can move intentionally, in which case carry forward from player position target + // 2. the player can move from feedback of being hit, NOT IMPLEMENTED YET + int player_hit_anim_state; + float player_hit_anim_speed; + float t_player_hit_anim_duration; + float t_player_hit_anim_start; + Vector2 player_move_target; + + // game sprites + Texture2D *grass_sprite; + Texture2D *player_sprite; + + Texture2D *troll_sprite; + Texture2D *troll_weapon_sprite; + Texture2D *bandit_sprite; + Texture2D *bandit_weapon_sprite; + + Texture2D *troll_area_floor_sprite; + Texture2D *bandit_area_floor_sprite; + + Texture2D *troll_base_sprite; + Texture2D *bandit_base_sprite; + + String *action_log; +} State; + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +const int screenWidth = 1280; +const int screenHeight = 1024; +State mega_state = {}; +// layer ground +int floor_grid_map[8][8] = {{O, O, O, O, O, O, O, O}, + {O, O, O, O, T, T, T, T}, + {B, B, B, B, T, T, T, T}, + {B, B, B, B, T, T, T, T}, + {B, B, B, B, T, T, T, T}, + {B, B, B, B, T, T, T, T}, + {B, B, B, B, T, T, T, T}, + {B, B, B, B, T, T, T, T}}; +// vegetation grid +int floor_cover_grid_map[8][8] = {{O, O, O, O, O, O, O, O}, + {O, O, O, O, O, O, O, O}, + {O, O, O, O, O, O, O, O}, + {O, O, O, O, O, O, O, O}, + {O, O, O, O, O, O, O, T_B}, + {O, B_B, O, O, O, O, O, O}, + {O, O, O, O, O, O, O, O}, + {O, O, O, O, O, O, O, O}}; +Vector2 grid_dims = {8, 8}; +//---------------------------------------------------------------------------------- +// Module functions declaration +//---------------------------------------------------------------------------------- +void UpdateDrawFrame(); // Update and Draw one frame + +int main(void) +{ + InitWindow(screenWidth, screenHeight, "raylib browser example"); + SetTargetFPS(60); + Texture2D grass_sprite = LoadTexture("./assets/dungeon/floor/grass/grass_flowers_blue_1_new.png"); + Texture2D player_sprite = LoadTexture("./assets/player/base/human_male.png"); + Texture2D troll_sprite = LoadTexture("./assets/monster/hill_giant_old.png"); + Texture2D bandit_sprite = LoadTexture("./assets/monster/unique/maurice_new.png"); + Texture2D troll_area_floor_sprite = LoadTexture("./assets/dungeon/floor/dirt_northeast_new.png"); + Texture2D bandit_area_floor_sprite = LoadTexture("./assets/dungeon/floor/dirt_east_new.png"); + Texture2D bandit_base_sprite = LoadTexture("./assets/dungeon/floor/hive_3.png"); + Texture2D troll_base_sprite = LoadTexture("./assets/dungeon/floor/dirt_2_old.png"); + Texture2D troll_weapon_sprite = LoadTexture("./assets/item/weapon/club_old.png"); + + mega_state.render_scale = 2.0f; + mega_state.grass_sprite = &grass_sprite; + mega_state.player_sprite = &player_sprite; + mega_state.troll_sprite = &troll_sprite; + mega_state.bandit_sprite = &bandit_sprite; + mega_state.troll_area_floor_sprite = &troll_area_floor_sprite; + mega_state.bandit_area_floor_sprite = &bandit_area_floor_sprite; + mega_state.bandit_base_sprite = &bandit_base_sprite; + mega_state.troll_base_sprite = &troll_base_sprite; + mega_state.troll_weapon_sprite = &troll_weapon_sprite; + mega_state.player_position = (Vector2){50.0f, 50.0f}; + mega_state.player_hit_anim_speed = 50.0f; // pixels per second; + mega_state.t_player_hit_anim_duration = 0.2f; + mega_state.player_render_rect = (Rectangle){.x=0,.y=0,.width=player_sprite.width,.height=player_sprite.height*mega_state.render_scale}; + mega_state.player_move_delta = 5.0f; + mega_state.pixels_per_gridbox = (Vector2){screenWidth/grid_dims.x, screenHeight/grid_dims.y}; + mega_state.player_tint = (Color){255, 255, 255, 255}; + mega_state.troll_state = T_IDLE; + + mega_state.bandit_position = (Vector2){64.0f, 800.0f}; + mega_state.troll_position = (Vector2){1024.0f, 600.0f}; + mega_state.troll_move_delta = 2.0f; + mega_state.t_troll_charge_anim_duration = 1.0f; + mega_state.troll_tint_base = (Color){255, 255, 255, 255}; + mega_state.troll_tint = mega_state.troll_tint_base; + mega_state.t_troll_attack_anim_duration = 0.4f; + mega_state.troll_attack_offset_max = 100.0f; + mega_state.troll_render_rect = (Rectangle){.x=0,.y=0,.width=troll_sprite.width*mega_state.render_scale,.height=troll_sprite.height*mega_state.render_scale}; + + char *str_buffer = (char*)MemAlloc(512*sizeof(char)); + mega_state.action_log = &(String){.buffer=str_buffer, .capacity=512, .len=0}; + + #if defined(PLATFORM_WEB) + emscripten_set_main_loop(UpdateDrawFrame, 0, 1); + #else + SetTargetFPS(60); + + while(!WindowShouldClose()) + { + UpdateDrawFrame(); + } + #endif + + CloseWindow(); + + return 0; +} + +void DrawMapFloorTiles(float scale) +{ + // @note: testing this, might need lighting + Color BlackTint = {128,128,128,255}; + Texture2D grass = *mega_state.grass_sprite; + float winc = (float)grass.width * scale; + float hinc = (float)grass.height * scale; + Vector2 grid_pos = {0, 0}; + for (int ypos=0; yposwidth; + src_rect = (Rectangle){.x=0, .y=0, .width=-mega_state.troll_weapon_sprite->width, .height=mega_state.troll_weapon_sprite->height}; + dest_rect = (Rectangle){.x=troll_weapon_centered.x, .y=troll_weapon_centered.y, + .width=0.5f*scale*mega_state.troll_weapon_sprite->width, + .height=0.5f*scale*mega_state.troll_weapon_sprite->height}; + DrawTexturePro(*mega_state.troll_weapon_sprite, src_rect, dest_rect, + (Vector2){0,0}, 0, RAYWHITE); + // - troll sprite + DrawTextureEx(*mega_state.troll_sprite, (Vector2){mega_state.troll_render_rect.x, mega_state.troll_render_rect.y}, 0, scale, mega_state.troll_tint); + // draw collision box + DrawRectangleLines(mega_state.troll_render_rect.x, mega_state.troll_render_rect.y, mega_state.troll_render_rect.width, mega_state.troll_render_rect.height, RED); + + // draw Bandit + Vector2 bandit_center = GetSpriteCenterPosition(*mega_state.bandit_sprite, mega_state.bandit_position, scale); + src_rect = (Rectangle){.x=0, .y=0, .width=-mega_state.bandit_sprite->width, .height=mega_state.bandit_sprite->height}; + dest_rect = (Rectangle){.x=bandit_center.x, .y=bandit_center.y, + .width=scale*mega_state.bandit_sprite->width, + .height=scale*mega_state.bandit_sprite->height}; + DrawTexturePro(*mega_state.bandit_sprite, src_rect, dest_rect, + (Vector2){0,0}, 0, (Color){255, 128, 128, 255}); + // draw player + Vector2 player_center = GetSpriteCenterPosition(*mega_state.player_sprite, mega_state.player_position, scale); + DrawTextureEx(*mega_state.player_sprite, player_center, 0, scale, mega_state.player_tint); + //DrawTextureEx(*mega_state.player_sprite, (Vector2){mega_state.player_render_rect.x, mega_state.player_render_rect.y}, 0, scale, RAYWHITE); + DrawRectangleLines(mega_state.player_render_rect.x, mega_state.player_render_rect.y, mega_state.player_render_rect.width, mega_state.player_render_rect.height, RED); +} + +void UpdateDrawFrame(void) +{ + BeginDrawing(); + { + // INPUT + mega_state.mouse_position = GetMousePosition(); + if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && mega_state.player_hit_anim_state != HA_PLAY) + { + mega_state.is_player_move = true; + mega_state.player_position_target = mega_state.mouse_position; + mega_state.player_move_dir = Vector2Normalize(Vector2Subtract(mega_state.player_position_target, mega_state.player_position)); + } + if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) + { + // @debug: cleaning up troll collision state + mega_state.troll_attack_anime_state = AA_IDLE; + mega_state.troll_tint = WHITE; + mega_state.is_player_hit = false; + } + + // PROCESSING + if (mega_state.player_hit_anim_state == HA_PLAY) + { + float anim_length = GetTime() - mega_state.t_player_hit_anim_start; + float ft = GetFrameTime(); + float pixel_per_second_per_ft = ft*mega_state.player_hit_anim_speed/mega_state.t_player_hit_anim_duration; + mega_state.player_position = Vector2Add(mega_state.player_position, Vector2Scale(mega_state.player_move_dir, pixel_per_second_per_ft)); + mega_state.player_tint = (Color){255, 128, 128, 255}; + if (anim_length >= mega_state.t_player_hit_anim_duration) + { + mega_state.player_hit_anim_state = HA_IDLE; + mega_state.player_tint = (Color){255, 255, 255, 255}; + } + } + if (mega_state.is_player_move) + { + mega_state.player_position = Vector2Add(mega_state.player_position, Vector2Scale(mega_state.player_move_dir, mega_state.player_move_delta)); + if (Vector2Distance(mega_state.player_position, mega_state.player_position_target) <= 5.0f) + { + mega_state.is_player_move = false; + } + } + // calculate center positions + Vector2 player_centered = GetRenderCenterFromTL(mega_state.player_render_rect, mega_state.player_position); + mega_state.player_render_rect.x = player_centered.x; + mega_state.player_render_rect.y = player_centered.y; + + // process enemies detecting the player + // troll + // get player location on map + // map_world_to_grid + Vector2 grid_pos = Vector2Divide(Vector2Multiply(mega_state.player_position, grid_dims), (Vector2){screenWidth, screenHeight}); + int tile_at_player = floor_grid_map[(int)grid_pos.y][(int)grid_pos.x]; + bool in_troll_area = true; + bool troll_persue_player = true; + if (tile_at_player != T) + { + in_troll_area = false; + if (mega_state.troll_state != T_AGGRO) + { + mega_state.troll_attack_anime_state = AA_IDLE; + troll_persue_player = false; + } + } + + float player_troll_dist = Vector2Distance(mega_state.player_position, mega_state.troll_position); + bool troll_detect = false; + bool troll_attack_start = false; + float slow_multiplier = mega_state.troll_attack_anime_state == AA_CHARGE ? 0.2f : 1.0f; + if (player_troll_dist < 200 && troll_persue_player) + { + troll_detect = true; + mega_state.troll_state = T_FOLLOW; + if (player_troll_dist < 80 && mega_state.troll_attack_anime_state == AA_IDLE) + { + troll_attack_start = true; + } + } + if (troll_detect && mega_state.troll_attack_anime_state != AA_ATTACK) + { + mega_state.troll_last_player_position = mega_state.player_position; + mega_state.troll_position_target = mega_state.troll_last_player_position; + mega_state.troll_move_dir = Vector2Normalize(Vector2Subtract(mega_state.troll_position_target, mega_state.troll_position)); + if (player_troll_dist > 10.0f) + { + // @note: this actually might not even be needed + // move only if both are more than 10pixels apart. + // it becomes jarring other wise + mega_state.troll_position = Vector2Add(mega_state.troll_position, Vector2Scale(mega_state.troll_move_dir, slow_multiplier*mega_state.troll_move_delta)); + } + } + Vector2 troll_centered = GetSpriteCenterPosition(*mega_state.troll_sprite, mega_state.troll_position, mega_state.render_scale); + mega_state.troll_render_rect.x = troll_centered.x; + mega_state.troll_render_rect.y = troll_centered.y; + if (troll_attack_start) + { + // start attack animation + mega_state.troll_anim_attack_play = true; + mega_state.t_troll_charge_anim_start = GetTime(); + mega_state.troll_attack_anime_state = AA_CHARGE; + } + float charge_time = 0.0f; + float charge_color_delta = 0.0f; + if (mega_state.troll_attack_anime_state == AA_CHARGE) + { + // get color based on time + float charge_progress = (GetTime() - mega_state.t_troll_charge_anim_start) / mega_state.t_troll_charge_anim_duration; + mega_state.troll_tint.r = Clamp(mega_state.troll_tint_base.r - (charge_progress*mega_state.troll_tint_base.r), 0, 255); + if (charge_progress >= 1.0f) + { + mega_state.troll_attack_anime_state = AA_ATTACK; + mega_state.t_troll_attack_anim_start = GetTime(); + } + } + else if (mega_state.troll_attack_anime_state == AA_ATTACK) + { + // maximum distance to attack jump in + // mega_state.troll_attack_offset_max = 10.0f; + // mega_state.troll_attack_anim_duration = 1.0f; + float anim_length = GetTime() - mega_state.t_troll_attack_anim_start; + float ft = GetFrameTime(); + float pixel_per_second_per_ft = ft*mega_state.troll_attack_offset_max/mega_state.t_troll_attack_anim_duration; + mega_state.troll_position = Vector2Add(mega_state.troll_position, Vector2Scale(mega_state.troll_move_dir, pixel_per_second_per_ft)); + mega_state.troll_tint = (Color){255, 128, 255, 255}; + // get troll center position and check for collision with player + // now check if colliding with player + bool is_colliding = CheckCollisionRecs(mega_state.player_render_rect, mega_state.troll_render_rect); + if (is_colliding) + { + mega_state.is_player_hit = true; + } + if (anim_length >= mega_state.t_troll_attack_anim_duration || is_colliding) + { + mega_state.troll_attack_anime_state = AA_IDLE; + mega_state.troll_tint = mega_state.troll_tint_base; + if (is_colliding) + { + // make player get hit + mega_state.player_hit_anim_state = HA_PLAY; + mega_state.t_player_hit_anim_start = GetTime(); + mega_state.player_move_dir = mega_state.troll_move_dir; + mega_state.is_player_move = false; // disable walk check, stuff been thrown off + } + } + } + + float player_bandit_delta = Vector2Distance(mega_state.player_position, mega_state.bandit_position); + bool bandit_detect = false; + if (player_bandit_delta < 200) + { + bandit_detect = true; + } + // RENDERING + ClearBackground(RAYWHITE); + DrawMapFloorTiles(2.0f); + DrawFloorCoverTiles(2.0f); + DrawCharacters(2.0f); + + // do text rendering at the end + // draw mouse position for debugging + if (mega_state.is_player_hit) + { + DrawText("player hit", 500, 20, 20, GREEN); + } + if (troll_detect) + { + DrawText("Detecting", mega_state.troll_position.x, mega_state.troll_position.y + mega_state.troll_sprite->height + 20, 20, GREEN); + } + if (bandit_detect) + { + DrawText("Detecting", mega_state.bandit_position.x, mega_state.bandit_position.y + mega_state.bandit_sprite->height + 20, 20, GREEN); + } + DrawText(TextFormat("FPS: %d", GetFPS()), 1200, 20, 20, GREEN); + DrawText(TextFormat("Player Tile: %d", tile_at_player), 20, 20, 20, GREEN); + } + EndDrawing(); +} + + -- cgit v1.2.3