diff --git a/client/main.go b/client/main.go index 5332d19..a04b34d 100644 --- a/client/main.go +++ b/client/main.go @@ -1,11 +1,17 @@ package main import ( + "time" + "github.com/gen2brain/raylib-go/raylib" ) type ClientAuth struct { + +} +type Entity struct { + } type LoginState int @@ -24,12 +30,24 @@ const ( BUTTON_STATE_PRESSED ) +type Scale struct { + window rl.Vector2 + ui uint +} + type ClientState struct { auth *ClientAuth login LoginState login_button ButtonState - ui_scale uint - window_scale rl.Vector2 + scale Scale + screen rl.Rectangle + camera rl.Camera + + command_queue chan interface{} + network_queue chan interface{} + + context *Entity + context_pos rl.Vector2 } const ( @@ -37,19 +55,28 @@ const ( HEIGHT uint = 1000 ) -func scale(original rl.Rectangle, ui_scale uint, window_scale rl.Vector2) rl.Rectangle { +func scale(original rl.Rectangle, scale Scale) rl.Rectangle { return rl.Rectangle{ -X: original.X/window_scale.X, - Y: original.Y/window_scale.Y, - Width: original.Width*float32(ui_scale)/window_scale.X, - Height: original.Height*float32(ui_scale)/window_scale.Y, + X: original.X, + Y: original.Y, + Width: original.Width*float32(scale.ui)/scale.window.X, + Height: original.Height*float32(scale.ui)/scale.window.Y, } } -func center(original rl.Rectangle, off_x, off_y int, window_scale rl.Vector2, width, height uint) rl.Rectangle { +func offset(original rl.Rectangle, off_x, off_y int, scale Scale) rl.Rectangle { return rl.Rectangle{ - X: (float32(width) /window_scale.X - original.Width )/2 + float32(off_x)/window_scale.X, - Y: (float32(height)/window_scale.Y - original.Height)/2 + float32(off_y)/window_scale.Y, + X: original.X + float32(off_x)/scale.window.X, + Y: original.Y + float32(off_y)/scale.window.Y, + Width: original.Width, + Height: original.Height, + } +} + +func center(container, original rl.Rectangle) rl.Rectangle { + return rl.Rectangle{ + X: (container.Width - original.Width )/2 + container.X, + Y: (container.Height - original.Height)/2 + container.Y, Width: original.Width, Height: original.Height, } @@ -91,60 +118,104 @@ func button(rectangle rl.Rectangle, idle, hover, pressed rl.Color, text string, return action, next_state } +func NetworkThread(network_queue chan interface{}) { + for(true) { + // TODO: remove + time.Sleep(time.Millisecond) + } +} + +func LogicThread(state *ClientState) { + for(true) { + select { + case _ = <- state.command_queue: + case _ = <- state.network_queue: + } + time.Sleep(time.Millisecond) + } +} + func main() { state := ClientState{ auth: nil, login: LOGIN_STATE_CREDENTIALS, login_button: BUTTON_STATE_IDLE, - ui_scale: 1, + scale: Scale{ + ui: 1, + }, + camera: rl.NewCamera3D(rl.Vector3{}, rl.Vector3{}, rl.Vector3{}, 90, rl.CameraOrthographic), + context: nil, } + go LogicThread(&state) + rl.SetConfigFlags(rl.FlagWindowHighdpi) rl.InitWindow(0, 0, "roleplay") rl.SetExitKey(0) rl.SetTargetFPS(60) - state.window_scale = rl.GetWindowScaleDPI() - rl.SetWindowSize(int(float32(WIDTH)/state.window_scale.X), int(float32(HEIGHT)/state.window_scale.Y)) + state.scale.window = rl.GetWindowScaleDPI() + rl.SetWindowSize(int(float32(WIDTH)/state.scale.window.X), int(float32(HEIGHT)/state.scale.window.Y)) + + state.screen.Width = float32(WIDTH) /state.scale.window.X + state.screen.Height = float32(HEIGHT)/state.scale.window.Y for(rl.WindowShouldClose() == false) { if(state.auth == nil) { // Draw login rl.BeginDrawing() - rl.ClearBackground(rl.White) + rl.ClearBackground(rl.Black) - logo_rect := scale(rl.Rectangle{Width: 1200, Height: 300}, state.ui_scale, state.window_scale) - logo_rect = center(logo_rect, 0, -300, state.window_scale, WIDTH, HEIGHT) + logo_rect := scale(rl.Rectangle{Width: 1200, Height: 300}, state.scale) + logo_rect = center(state.screen, logo_rect) + logo_rect = offset(logo_rect, 0, -250, state.scale) rl.DrawRectangleRec(logo_rect, rl.Gray) - form_rect := scale(rl.Rectangle{Width: 600, Height: 400}, state.ui_scale, state.window_scale) - form_rect = center(form_rect, 0, 150, state.window_scale, WIDTH, HEIGHT) + form_rect := scale(rl.Rectangle{Width: 600, Height: 400}, state.scale) + form_rect = center(state.screen, form_rect) + form_rect = offset(form_rect, 0, 200, state.scale) rl.DrawRectangleRec(form_rect, rl.Gray) switch(state.login) { case LOGIN_STATE_CREDENTIALS: - submit_rect := scale(rl.Rectangle{Width: 100, Height: 50}, state.ui_scale, state.window_scale) - submit_rect = center(submit_rect, 0, 300, state.window_scale, WIDTH, HEIGHT) + submit_rect := scale(rl.Rectangle{Width: 100, Height: 50}, state.scale) + submit_rect = center(form_rect, submit_rect) + submit_rect = offset(submit_rect, 0, 125, state.scale) var submit_action bool submit_action, state.login_button = button(submit_rect, rl.Black, rl.Brown, rl.Red, "Submit", 12, rl.White, state.login_button) if submit_action { - state.login = LOGIN_STATE_ATTEMPTING + // TODO: real auth via network thread + state.auth = &ClientAuth{} } case LOGIN_STATE_ATTEMPTING: text := "Logging in..." text_size := rl.MeasureTextEx(rl.GetFontDefault(), text, 20, 1.0) - text_rect := center(rl.Rectangle{Width: text_size.X, Height: text_size.Y}, 0, 0, state.window_scale, WIDTH, HEIGHT) + text_rect := center(form_rect, rl.Rectangle{Width: text_size.X, Height: text_size.Y}) rl.DrawText(text, int32(text_rect.X), int32(text_rect.Y), 20, rl.Black) case LOGIN_STATE_ERROR: text := "Error: {TODO}" text_size := rl.MeasureTextEx(rl.GetFontDefault(), text, 20, 1.0) - text_rect := center(rl.Rectangle{Width: text_size.X, Height: text_size.Y}, 0, 0, state.window_scale, WIDTH, HEIGHT) + text_rect := center(form_rect, rl.Rectangle{Width: text_size.X, Height: text_size.Y}) rl.DrawText(text, int32(text_rect.X), int32(text_rect.Y), 20, rl.Black) } rl.EndDrawing() } else { - // Draw game + rl.BeginDrawing() + rl.ClearBackground(rl.Black) + rl.BeginMode3D(state.camera) + + if rl.IsMouseButtonPressed(rl.MouseButtonRight) { + state.context_pos = rl.GetMousePosition() + // TODO: Cast a ray into the bounding boxes + } + + if state.context != nil { + + } + + rl.EndMode3D() + rl.EndDrawing() } } }