From c22309081af64bc24c0b586aee081959d9da2c39 Mon Sep 17 00:00:00 2001 From: Alexander Popov Date: Sun, 2 Jul 2023 19:40:27 +0300 Subject: [PATCH] example windows on V --- .editorconfig | 5 + .../assets => .assets}/monogram-extended.ttf | Bin ~/.assets/v-logo.png | Bin 0 -> 4328 bytes ~/V/example_window/README.md | 4 + ~/V/example_window/game.v | 117 ++++++++++++++++++ ~/V/example_window/text.v | 39 ++++++ 6 files changed, 165 insertions(+) rename ~/{SDL/assets => .assets}/monogram-extended.ttf (100%) create mode 100644 ~/.assets/v-logo.png create mode 100644 ~/V/example_window/README.md create mode 100644 ~/V/example_window/game.v create mode 100644 ~/V/example_window/text.v diff --git a/.editorconfig b/.editorconfig index 860a0be..b829a7e 100644 --- a/.editorconfig +++ b/.editorconfig @@ -30,6 +30,11 @@ indent_size = 2 indent_style = space indent_size = 4 +# V +[*.v] +indent_style = tab +indent_size = 4 + # JavaScript [*.js] indent_style = space diff --git a/~/SDL/assets/monogram-extended.ttf b/~/.assets/monogram-extended.ttf similarity index 100% rename from ~/SDL/assets/monogram-extended.ttf rename to ~/.assets/monogram-extended.ttf diff --git a/~/.assets/v-logo.png b/~/.assets/v-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..98ebfb19b39f747612a6d4ca84a4e6480b62d133 GIT binary patch literal 4328 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 C3V3n= literal 0 HcmV?d00001 diff --git a/~/V/example_window/README.md b/~/V/example_window/README.md new file mode 100644 index 0000000..c7decdc --- /dev/null +++ b/~/V/example_window/README.md @@ -0,0 +1,4 @@ +* draw rect +* draw text +* draw image +* key event diff --git a/~/V/example_window/game.v b/~/V/example_window/game.v new file mode 100644 index 0000000..38c5dc4 --- /dev/null +++ b/~/V/example_window/game.v @@ -0,0 +1,117 @@ +module main + +import os +import gg +import gx +import sokol.sapp + +const ( + win_width = 512 + win_height = 512 +) + +struct Game { +mut: + gg &gg.Context = unsafe { nil } + player Player +} + +struct Player { +mut: + pos_x int + pos_y int + lives int + image gg.Image +} + +fn frame(mut game Game) { + game.gg.begin() + + game.gg.draw_rect_filled(game.player.pos_x, game.player.pos_y, 50, 50, gx.hex(0x5C7A56FF)) + + // draw ui + game.draw_text(gg.window_size().width - 10, 0, 'Lives: ${game.player.lives}', 36, + gx.white, 'right', 'top', true) + + // draw image + game.gg.draw_image(0, game.gg.window_size().height - game.player.image.height, game.player.image.width, + game.player.image.height, game.player.image) + + game.gg.end() +} + +fn main() { + print('Loading... ') + mut game := &Game{} + + mut font_path := os.resource_abs_path(os.join_path('..', '..', '.assets', 'monogram-extended.ttf')) + + game.gg = gg.new_context( + bg_color: gx.hex(0x2A2A3AFF) + width: win_width + height: win_height + create_window: true + enable_dragndrop: false + window_title: 'Runner' + font_path: font_path + user_data: game + frame_fn: frame + event_fn: on_event + ) + + game.player = &Player{ + pos_x: 10 + pos_y: 10 + lives: 3 + } + + game.player.image = game.gg.create_image(os.resource_abs_path(os.join_path('..', '..', '.assets', 'v-logo.png'))) or { + panic(err) + } + + println('OK!\n') + println('High DPI: ${gg.high_dpi()}') + println('Window size: ${gg.window_size().width}x${gg.window_size().height}') + println('Screen size: ${gg.screen_size().width}x${gg.screen_size().height}') + println('Fullscreen: ${gg.is_fullscreen()}\n') + + game.gg.run() + println('\nBye!') +} + +fn (mut game Game) key_down(key gg.KeyCode) { + match key { + .escape { + game.gg.quit() + } + .f11 { + sapp.toggle_fullscreen() + println('Set fullscreen: ${gg.is_fullscreen()}') + } + .left { + game.player.pos_x -= 2 + } + .right { + game.player.pos_x += 2 + } + .up { + game.player.pos_y -= 2 + } + .down { + game.player.pos_y += 2 + } + else {} + } +} + +fn on_event(e &gg.Event, mut game Game) { + // println('code=$e.char_code') + // println('code=$e.key_code') + + match e.typ { + .key_down { + game.key_down(e.key_code) + } + else {} + } +} diff --git a/~/V/example_window/text.v b/~/V/example_window/text.v new file mode 100644 index 0000000..9f8130c --- /dev/null +++ b/~/V/example_window/text.v @@ -0,0 +1,39 @@ +module main + +import gx + +fn (game &Game) text_format(color gx.Color, size int, h_align gx.HorizontalAlign, v_align gx.VerticalAlign) gx.TextCfg { + return gx.TextCfg{ + color: color + align: h_align + vertical_align: v_align + size: size + } +} + +pub fn (game &Game) draw_text(x int, y int, text string, size int, color gx.Color, ha string, va string, shadow bool) { + mut v_align := gx.VerticalAlign.baseline + mut h_align := gx.HorizontalAlign.left + + match va { + 'top' { v_align = gx.VerticalAlign.top } + 'middle' { v_align = gx.VerticalAlign.middle } + 'bottom' { v_align = gx.VerticalAlign.bottom } + 'baseline' { v_align = gx.VerticalAlign.baseline } + else { v_align = gx.VerticalAlign.top } + } + + match ha { + 'left' { h_align = gx.HorizontalAlign.left } + 'center' { h_align = gx.HorizontalAlign.center } + 'right' { h_align = gx.HorizontalAlign.right } + else { h_align = gx.HorizontalAlign.left } + } + + if shadow { + game.gg.draw_text(x + 2, y + 2, text, game.text_format(gx.black, size, h_align, + v_align)) + } + + game.gg.draw_text(x, y, text, game.text_format(color, size, h_align, v_align)) +}