Created
May 17, 2024 19:26
-
-
Save karl-zylinski/a23501d5e1cf585f82c5f8928bc73ab6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package game | |
| import rl "vendor:raylib" | |
| import "core:mem" | |
| import "core:fmt" | |
| import "core:encoding/json" | |
| import "core:os" | |
| Animation_Name :: enum { | |
| Idle, | |
| Run, | |
| } | |
| Animation :: struct { | |
| texture: rl.Texture2D, | |
| num_frames: int, | |
| frame_timer: f32, | |
| current_frame: int, | |
| frame_length: f32, | |
| name: Animation_Name, | |
| } | |
| update_animation :: proc(a: ^Animation) { | |
| a.frame_timer += rl.GetFrameTime() | |
| if a.frame_timer > a.frame_length { | |
| a.current_frame += 1 | |
| a.frame_timer = 0 | |
| if a.current_frame == a.num_frames { | |
| a.current_frame = 0 | |
| } | |
| } | |
| } | |
| draw_animation :: proc(a: Animation, pos: rl.Vector2, flip: bool) { | |
| width := f32(a.texture.width) | |
| height := f32(a.texture.height) | |
| source := rl.Rectangle { | |
| x = f32(a.current_frame) * width / f32(a.num_frames), | |
| y = 0, | |
| width = width / f32(a.num_frames), | |
| height = height, | |
| } | |
| if flip { | |
| source.width = -source.width | |
| } | |
| dest := rl.Rectangle { | |
| x = pos.x, | |
| y = pos.y, | |
| width = width / f32(a.num_frames), | |
| height = height, | |
| } | |
| rl.DrawTexturePro(a.texture, source, dest, {dest.width/2, dest.height}, 0, rl.WHITE) | |
| } | |
| PixelWindowHeight :: 180 | |
| Level :: struct { | |
| platforms: [dynamic]rl.Vector2, | |
| } | |
| platform_collider :: proc(pos: rl.Vector2) -> rl.Rectangle { | |
| return { | |
| pos.x, pos.y, | |
| 96, 16, | |
| } | |
| } | |
| main :: proc() { | |
| track: mem.Tracking_Allocator | |
| mem.tracking_allocator_init(&track, context.allocator) | |
| context.allocator = mem.tracking_allocator(&track) | |
| defer { | |
| for _, entry in track.allocation_map { | |
| fmt.eprintf("%v leaked %v bytes\n", entry.location, entry.size) | |
| } | |
| for entry in track.bad_free_array { | |
| fmt.eprintf("%v bad free\n", entry.location) | |
| } | |
| mem.tracking_allocator_destroy(&track) | |
| } | |
| rl.InitWindow(1920, 1080, "My First Game") | |
| rl.SetWindowPosition(200, 200) | |
| rl.SetWindowState({.WINDOW_RESIZABLE}) | |
| rl.SetTargetFPS(500) | |
| player_pos: rl.Vector2 | |
| player_vel: rl.Vector2 | |
| player_grounded: bool | |
| player_flip: bool | |
| player_run := Animation { | |
| texture = rl.LoadTexture("cat_run.png"), | |
| num_frames = 4, | |
| frame_length = 0.1, | |
| name = .Run, | |
| } | |
| player_idle := Animation { | |
| texture = rl.LoadTexture("cat_idle.png"), | |
| num_frames = 2, | |
| frame_length = 0.5, | |
| name = .Idle, | |
| } | |
| current_anim := player_idle | |
| level: Level | |
| if level_data, ok := os.read_entire_file("level.json", context.temp_allocator); ok { | |
| if json.unmarshal(level_data, &level) != nil { | |
| append(&level.platforms, rl.Vector2 { -20, 20 }) | |
| } | |
| } else { | |
| append(&level.platforms, rl.Vector2 { -20, 20 }) | |
| } | |
| platform_texture := rl.LoadTexture("platform.png") | |
| editing := false | |
| for !rl.WindowShouldClose() { | |
| rl.BeginDrawing() | |
| rl.ClearBackground({110, 184, 168, 255}) | |
| if rl.IsKeyDown(.LEFT) { | |
| player_vel.x = -100 | |
| player_flip = true | |
| if current_anim.name != .Run { | |
| current_anim = player_run | |
| } | |
| } else if rl.IsKeyDown(.RIGHT) { | |
| player_vel.x = 100 | |
| player_flip = false | |
| if current_anim.name != .Run { | |
| current_anim = player_run | |
| } | |
| } else { | |
| player_vel.x = 0 | |
| if current_anim.name != .Idle { | |
| current_anim = player_idle | |
| } | |
| } | |
| player_vel.y += 1000 * rl.GetFrameTime() | |
| if player_grounded && rl.IsKeyPressed(.SPACE) { | |
| player_vel.y = -300 | |
| } | |
| player_pos += player_vel * rl.GetFrameTime() | |
| player_feet_collider := rl.Rectangle { | |
| player_pos.x - 4, | |
| player_pos.y - 4, | |
| 8, | |
| 4, | |
| } | |
| player_grounded = false | |
| for platform in level.platforms { | |
| if rl.CheckCollisionRecs(player_feet_collider, platform_collider(platform)) && player_vel.y > 0 { | |
| player_vel.y = 0 | |
| player_pos.y = platform.y | |
| player_grounded = true | |
| } | |
| } | |
| update_animation(¤t_anim) | |
| screen_height := f32(rl.GetScreenHeight()) | |
| camera := rl.Camera2D { | |
| zoom = screen_height/PixelWindowHeight, | |
| offset = {f32(rl.GetScreenWidth()/2), screen_height/2}, | |
| target = player_pos, | |
| } | |
| rl.BeginMode2D(camera) | |
| draw_animation(current_anim, player_pos, player_flip) | |
| for platform in level.platforms { | |
| rl.DrawTextureV(platform_texture, platform, rl.WHITE) | |
| } | |
| //rl.DrawRectangleRec(player_feet_collider, {0, 255, 0, 100}) | |
| if rl.IsKeyPressed(.F2) { | |
| editing = !editing | |
| } | |
| if editing { | |
| mp := rl.GetScreenToWorld2D(rl.GetMousePosition(), camera) | |
| rl.DrawTextureV(platform_texture, mp, rl.WHITE) | |
| if rl.IsMouseButtonPressed(.LEFT) { | |
| append(&level.platforms, mp) | |
| } | |
| if rl.IsMouseButtonPressed(.RIGHT) { | |
| for p, idx in level.platforms { | |
| if rl.CheckCollisionPointRec(mp, platform_collider(p)) { | |
| unordered_remove(&level.platforms, idx) | |
| break | |
| } | |
| } | |
| } | |
| } | |
| rl.EndMode2D() | |
| rl.EndDrawing() | |
| free_all(context.temp_allocator) | |
| } | |
| rl.CloseWindow() | |
| if level_data, err := json.marshal(level, allocator = context.temp_allocator); err == nil { | |
| os.write_entire_file("level.json", level_data) | |
| } | |
| free_all(context.temp_allocator) | |
| delete(level.platforms) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment