this repo has no description

add init for coordinates #4

closed opened by voigt.tngl.sh targeting main from add-gamepad-demo
Labels

None yet.

assignee

None yet.

Participants 1
AT URI
at://did:plc:6q572hlx7omtsszji5w2fyw3/sh.tangled.repo.pull/3mbx4exjkzy22
-446
Interdiff #0 #1
README.md

Failed to calculate interdiff for this file.

-33
coordinates/main.go
··· 2 2 3 3 import ( 4 4 "github.com/firefly-zero/firefly-go/firefly" 5 - "github.com/orsinium-labs/tinymath" 6 5 ) 7 6 8 7 var ( ··· 40 39 firefly.ClearScreen(firefly.ColorNone) 41 40 } 42 41 43 - // draw 10 points in a circular way 44 - ps := CirclePointsInt(10, 5) 45 - for _, p := range ps { 46 - firefly.DrawPoint(translatePoint(p), firefly.ColorRed) 47 - } 48 - 49 42 // points in 4 quadrants 50 43 firefly.DrawPoint(translatePoint(firefly.Point{X: 10, Y: 10}), firefly.ColorCyan) 51 44 firefly.DrawPoint(translatePoint(firefly.Point{X: 10, Y: -10}), firefly.ColorGreen) ··· 58 51 y := -p.Y + SCREENHEIGHT/2 59 52 // firefly.LogDebug(strings.Join([]string{"x: ", strconv.Itoa(x), ", y: ", strconv.Itoa(y)}, " ")) 60 53 return firefly.Point{X: x, Y: y} 61 - } 62 - 63 - func CirclePointsInt(radius float32, n int) []firefly.Point { 64 - points := make([]firefly.Point, 0, n) 65 - seen := make(map[firefly.Point]struct{}, n) 66 - 67 - // Wir samplen mit höherer Auflösung und sammeln eindeutige gerundete Punkte, 68 - // bis wir n Stück haben. 69 - // Oversample-Faktor dynamisch hochdrehen, falls nötig. 70 - for oversample := n * 2; len(points) < n; oversample *= 2 { 71 - for i := 0; i < oversample && len(points) < n; i++ { 72 - angle := 2 * tinymath.Pi * float32(i) / float32(oversample) 73 - 74 - x := int(tinymath.Round(radius * tinymath.Cos(angle))) 75 - y := int(tinymath.Round(radius * tinymath.Sin(angle))) 76 - 77 - p := firefly.Point{X: x, Y: y} 78 - if _, ok := seen[p]; ok { 79 - continue 80 - } 81 - seen[p] = struct{}{} 82 - points = append(points, p) 83 - } 84 - } 85 - 86 - return points 87 54 } 88 55 89 56 func drawCoordinateSystem() {
-11
tmp/go.mod
··· 1 - module github.com/voigt/firefly-zero-playground/tmp 2 - 3 - go 1.25.0 4 - 5 - require github.com/gen2brain/raylib-go/raylib v0.55.1 6 - 7 - require ( 8 - github.com/ebitengine/purego v0.7.1 // indirect 9 - golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect 10 - golang.org/x/sys v0.20.0 // indirect 11 - )
-8
tmp/go.sum
··· 1 - github.com/ebitengine/purego v0.7.1 h1:6/55d26lG3o9VCZX8lping+bZcmShseiqlh2bnUDiPA= 2 - github.com/ebitengine/purego v0.7.1/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= 3 - github.com/gen2brain/raylib-go/raylib v0.55.1 h1:1rdc10WvvYjtj7qijHnV9T38/WuvlT6IIL+PaZ6cNA8= 4 - github.com/gen2brain/raylib-go/raylib v0.55.1/go.mod h1:BaY76bZk7nw1/kVOSQObPY1v1iwVE1KHAGMfvI6oK1Q= 5 - golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= 6 - golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= 7 - golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= 8 - golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-196
tmp/main.go
··· 1 - package main 2 - 3 - import ( 4 - rl "github.com/gen2brain/raylib-go/raylib" 5 - ) 6 - 7 - type Player struct { 8 - Pos rl.Vector2 9 - Vel rl.Vector2 10 - Size rl.Vector2 11 - OnGround bool 12 - 13 - // Timers (seconds) 14 - CoyoteTimer float32 15 - JumpBuffer float32 16 - Jumping bool // true after jump start until we land 17 - } 18 - 19 - func clamp(v, min, max float32) float32 { 20 - if v < min { 21 - return min 22 - } 23 - if v > max { 24 - return max 25 - } 26 - return v 27 - } 28 - 29 - func approach(current, target, delta float32) float32 { 30 - if current < target { 31 - current += delta 32 - if current > target { 33 - return target 34 - } 35 - return current 36 - } 37 - if current > target { 38 - current -= delta 39 - if current < target { 40 - return target 41 - } 42 - return current 43 - } 44 - return current 45 - } 46 - 47 - func main() { 48 - const screenW, screenH int32 = 960, 540 49 - rl.InitWindow(screenW, screenH, "raylib-go: platformer feel (accel/decel + buffer/coyote + variable jump + fast-fall)") 50 - defer rl.CloseWindow() 51 - rl.SetTargetFPS(60) 52 - 53 - groundY := float32(screenH - 80) 54 - groundThickness := float32(80) 55 - 56 - p := Player{ 57 - Pos: rl.NewVector2(120, groundY-60), 58 - Vel: rl.NewVector2(0, 0), 59 - Size: rl.NewVector2(50, 60), 60 - } 61 - 62 - // ---------- Tuning ---------- 63 - maxRunSpeed := float32(380) 64 - 65 - // Separate accel/decel 66 - groundAccel := float32(2600) 67 - groundDecel := float32(3200) 68 - airAccel := float32(1400) 69 - airDecel := float32(300) 70 - 71 - // Jump 72 - jumpSpeed := float32(640) 73 - 74 - // Variable jump height: cut velocity when releasing jump while going up 75 - jumpCutMultiplier := float32(0.35) 76 - 77 - // Coyote time + jump buffer (seconds) 78 - coyoteTime := float32(0.10) 79 - jumpBufferTime := float32(0.12) 80 - 81 - // --- Fast-fall tuning --- 82 - // Base gravity is used when rising (Vel.Y < 0) and jump is held. 83 - // When falling (Vel.Y > 0) we apply higher gravity (fallMultiplier). 84 - // When jump is released early during rise, we apply higher gravity too (lowJumpMultiplier). 85 - gravity := float32(1200) // "floatier" base on the way up 86 - fallMultiplier := float32(2.2) // faster fall 87 - lowJumpMultiplier := float32(2.6) // stronger pull-down if jump released early 88 - maxFallSpeed := float32(2200) // higher terminal velocity for snappy fall 89 - 90 - for !rl.WindowShouldClose() { 91 - dt := rl.GetFrameTime() 92 - 93 - // ---- Input ---- 94 - var dir float32 = 0 95 - if rl.IsKeyDown(rl.KeyA) || rl.IsKeyDown(rl.KeyLeft) { 96 - dir -= 1 97 - } 98 - if rl.IsKeyDown(rl.KeyD) || rl.IsKeyDown(rl.KeyRight) { 99 - dir += 1 100 - } 101 - 102 - jumpPressed := rl.IsKeyPressed(rl.KeySpace) 103 - jumpHeld := rl.IsKeyDown(rl.KeySpace) 104 - jumpReleased := rl.IsKeyReleased(rl.KeySpace) 105 - 106 - // ---- Timers ---- 107 - if p.OnGround { 108 - p.CoyoteTimer = coyoteTime 109 - } else { 110 - p.CoyoteTimer = clamp(p.CoyoteTimer-dt, 0, 999) 111 - } 112 - 113 - if jumpPressed { 114 - p.JumpBuffer = jumpBufferTime 115 - } else { 116 - p.JumpBuffer = clamp(p.JumpBuffer-dt, 0, 999) 117 - } 118 - 119 - // ---- Horizontal movement (accel/decel) ---- 120 - if p.OnGround { 121 - if dir != 0 { 122 - target := dir * maxRunSpeed 123 - p.Vel.X = approach(p.Vel.X, target, groundAccel*dt) 124 - } else { 125 - p.Vel.X = approach(p.Vel.X, 0, groundDecel*dt) 126 - } 127 - } else { 128 - if dir != 0 { 129 - target := dir * maxRunSpeed 130 - p.Vel.X = approach(p.Vel.X, target, airAccel*dt) 131 - } else { 132 - p.Vel.X = approach(p.Vel.X, 0, airDecel*dt) 133 - } 134 - } 135 - p.Vel.X = clamp(p.Vel.X, -maxRunSpeed, maxRunSpeed) 136 - 137 - // ---- Jump using buffer + coyote ---- 138 - if p.JumpBuffer > 0 && p.CoyoteTimer > 0 { 139 - p.Vel.Y = -jumpSpeed 140 - p.OnGround = false 141 - p.CoyoteTimer = 0 142 - p.JumpBuffer = 0 143 - p.Jumping = true 144 - } 145 - 146 - // ---- Variable jump height (jump cut) ---- 147 - // Optional: keep it, feels good in addition to lowJumpMultiplier gravity. 148 - if jumpReleased && p.Jumping && p.Vel.Y < 0 { 149 - p.Vel.Y *= jumpCutMultiplier 150 - } 151 - 152 - // ---- Fast-fall gravity ---- 153 - // If falling: stronger gravity. 154 - // If rising but jump not held: stronger gravity (low jump). 155 - g := gravity 156 - if p.Vel.Y > 0 { 157 - g *= fallMultiplier 158 - } else if p.Vel.Y < 0 && !jumpHeld { 159 - g *= lowJumpMultiplier 160 - } 161 - p.Vel.Y += g * dt 162 - p.Vel.Y = clamp(p.Vel.Y, -100000, maxFallSpeed) 163 - 164 - // ---- Integrate ---- 165 - p.Pos.X += p.Vel.X * dt 166 - p.Pos.Y += p.Vel.Y * dt 167 - 168 - // ---- Ground collision ---- 169 - playerBottom := p.Pos.Y + p.Size.Y 170 - if playerBottom >= groundY { 171 - p.Pos.Y = groundY - p.Size.Y 172 - p.Vel.Y = 0 173 - p.OnGround = true 174 - p.Jumping = false 175 - } else { 176 - p.OnGround = false 177 - } 178 - 179 - // ---- Screen bounds (X) ---- 180 - p.Pos.X = clamp(p.Pos.X, 0, float32(screenW)-p.Size.X) 181 - if p.Pos.X == 0 || p.Pos.X == float32(screenW)-p.Size.X { 182 - p.Vel.X = 0 183 - } 184 - 185 - // ---- Render ---- 186 - rl.BeginDrawing() 187 - rl.ClearBackground(rl.RayWhite) 188 - 189 - rl.DrawRectangle(0, int32(groundY), screenW, int32(groundThickness), rl.LightGray) 190 - rl.DrawRectangleV(p.Pos, p.Size, rl.DarkBlue) 191 - 192 - rl.DrawText("Move: A/D or Left/Right Jump: Space (buffer+coyote+variable+fast-fall)", 20, 20, 20, rl.Black) 193 - 194 - rl.EndDrawing() 195 - } 196 - }
-47
touchpad/.zed/tasks.json
··· 1 - [ 2 - { 3 - "label": "Build & Run Firefly Emulator", 4 - "command": "firefly_cli build && firefly-emulator --id voigt.go-gamepad", 5 - //"args": [], 6 - // Env overrides for the command, will be appended to the terminal's environment from the settings. 7 - // "env": { "foo": "bar" }, 8 - // Current working directory to spawn the command into, defaults to current project root. 9 - //"cwd": "/path/to/working/directory", 10 - // Whether to use a new terminal tab or reuse the existing one to spawn the process, defaults to `false`. 11 - "use_new_terminal": false, 12 - // Whether to allow multiple instances of the same task to be run, or rather wait for the existing ones to finish, defaults to `false`. 13 - // "allow_concurrent_runs": false, 14 - // What to do with the terminal pane and tab, after the command was started: 15 - // * `always` — always show the task's pane, and focus the corresponding tab in it (default) 16 - // * `no_focus` — always show the task's pane, add the task's tab in it, but don't focus it 17 - // * `never` — do not alter focus, but still add/reuse the task's tab in its pane 18 - "reveal": "always", 19 - // What to do with the terminal pane and tab, after the command has finished: 20 - // * `never` — Do nothing when the command finishes (default) 21 - // * `always` — always hide the terminal tab, hide the pane also if it was the last tab in it 22 - // * `on_success` — hide the terminal tab on task success only, otherwise behaves similar to `always` 23 - "hide": "never", 24 - // Which shell to use when running a task inside the terminal. 25 - // May take 3 values: 26 - // 1. (default) Use the system's default terminal configuration in /etc/passwd 27 - // "shell": "system" 28 - // 2. A program: 29 - // "shell": { 30 - // "program": "sh" 31 - // } 32 - // 3. A program with arguments: 33 - // "shell": { 34 - // "with_arguments": { 35 - // "program": "/bin/bash", 36 - // "args": ["--login"] 37 - // } 38 - // } 39 - "shell": "system", 40 - // Whether to show the task line in the output of the spawned task, defaults to `true`. 41 - "show_summary": true, 42 - // Whether to show the command line in the output of the spawned task, defaults to `true`. 43 - "show_command": true, 44 - // Represents the tags for inline runnable indicators, or spawning multiple tasks at once. 45 - // "tags": [] 46 - }, 47 - ]
-4
touchpad/firefly.toml
··· 1 - author_id = "voigt" 2 - app_id = "go-gamepad" 3 - author_name = "Christoph Voigt" 4 - app_name = "Gamepad Demo (Go)"
-132
touchpad/gamepad.go
··· 1 - package main 2 - 3 - import ff "github.com/firefly-zero/firefly-go/firefly" 4 - 5 - var ( 6 - point *ff.Point 7 - center ff.Point 8 - 9 - buttonN bool 10 - buttonE bool 11 - buttonS bool 12 - buttonW bool 13 - ) 14 - 15 - const ( 16 - radius = 26 17 - third = ff.Width / 3 18 - 19 - touchYcenter = third 20 - touchXcenter = ff.Height/2 - radius/2 21 - buttonYcenter = third * 2 22 - buttonXcenter = ff.Height/2 - radius/2 23 - ) 24 - 25 - func init() { 26 - ff.Render = render 27 - ff.Update = update 28 - } 29 - 30 - func update() { 31 - // Buttons 32 - buttons := ff.ReadButtons(ff.Combined) 33 - 34 - if buttons.N { 35 - buttonN = true 36 - } else { 37 - buttonN = false 38 - } 39 - if buttons.E { 40 - buttonE = true 41 - } else { 42 - buttonE = false 43 - } 44 - if buttons.S { 45 - buttonS = true 46 - } else { 47 - buttonS = false 48 - } 49 - if buttons.W { 50 - buttonW = true 51 - } else { 52 - buttonW = false 53 - } 54 - 55 - // Touchpad 56 - center = ff.Point{ 57 - X: touchXcenter, 58 - Y: touchYcenter, 59 - // X: ff.Width/2 - 45, 60 - // Y: ff.Height / 2, 61 - } 62 - 63 - input, pressed := ff.ReadPad(ff.Combined) 64 - if pressed { 65 - point = &ff.Point{ 66 - X: center.X + input.X/20 - radius, 67 - Y: center.Y - input.Y/20 - radius, 68 - } 69 - } else { 70 - point = nil 71 - } 72 - } 73 - 74 - func render() { 75 - ff.ClearScreen(ff.ColorWhite) 76 - 77 - // ff.DrawCircle(ff.Point{X: buttonYcenter - radius, Y: buttonXcenter - radius}, radius*3, ff.Style{FillColor: ff.ColorWhite, StrokeColor: ff.ColorDarkBlue, StrokeWidth: 1}) 78 - // ff.DrawCircle(ff.Point{X: touchYcenter - radius*2, Y: touchXcenter - radius}, radius*3, ff.Style{FillColor: ff.ColorWhite, StrokeColor: ff.ColorDarkBlue, StrokeWidth: 1}) 79 - ff.DrawLine(ff.Point{buttonYcenter, 0}, ff.Point{buttonYcenter, ff.Height}, ff.LineStyle{ff.ColorGray, 1}) 80 - ff.DrawLine(ff.Point{touchYcenter, 0}, ff.Point{touchYcenter, ff.Height}, ff.LineStyle{ff.ColorGray, 1}) 81 - ff.DrawLine(ff.Point{0, ff.Height / 2}, ff.Point{ff.Width, ff.Height / 2}, ff.LineStyle{ff.ColorGray, 1}) 82 - 83 - // Buttons 84 - // B 85 - styleE := ff.Style{FillColor: ff.ColorWhite, StrokeColor: ff.ColorDarkBlue, StrokeWidth: 1} 86 - if buttonE { 87 - styleE = ff.Style{FillColor: ff.ColorRed, StrokeColor: ff.ColorDarkBlue, StrokeWidth: 1} 88 - } 89 - ff.DrawCircle(ff.Point{X: buttonYcenter + radius, Y: buttonXcenter}, radius, styleE) 90 - 91 - // A 92 - styleS := ff.Style{FillColor: ff.ColorWhite, StrokeColor: ff.ColorDarkBlue, StrokeWidth: 1} 93 - if buttonS { 94 - styleS = ff.Style{FillColor: ff.ColorGreen, StrokeColor: ff.ColorDarkBlue, StrokeWidth: 1} 95 - } 96 - ff.DrawCircle(ff.Point{X: buttonYcenter, Y: buttonXcenter + radius}, radius, styleS) 97 - 98 - // Y 99 - styleN := ff.Style{FillColor: ff.ColorWhite, StrokeColor: ff.ColorDarkBlue, StrokeWidth: 1} 100 - if buttonN { 101 - styleN = ff.Style{FillColor: ff.ColorYellow, StrokeColor: ff.ColorDarkBlue, StrokeWidth: 1} 102 - } 103 - ff.DrawCircle(ff.Point{X: buttonYcenter, Y: buttonXcenter - radius}, radius, styleN) 104 - 105 - // X 106 - styleW := ff.Style{FillColor: ff.ColorWhite, StrokeColor: ff.ColorDarkBlue, StrokeWidth: 1} 107 - if buttonW { 108 - styleW = ff.Style{FillColor: ff.ColorBlue, StrokeColor: ff.ColorDarkBlue, StrokeWidth: 1} 109 - } 110 - ff.DrawCircle(ff.Point{X: buttonYcenter - radius, Y: buttonXcenter}, radius, styleW) 111 - 112 - // Touchpad 113 - style := ff.Style{ 114 - FillColor: ff.ColorWhite, 115 - StrokeColor: ff.ColorDarkBlue, 116 - StrokeWidth: 1, 117 - } 118 - 119 - ff.DrawCircle(ff.Point{ 120 - X: touchYcenter - radius*2, 121 - Y: touchXcenter - radius, 122 - }, radius*3, style) 123 - 124 - style = ff.Style{ 125 - FillColor: ff.ColorBlue, 126 - StrokeColor: ff.ColorDarkBlue, 127 - StrokeWidth: 1, 128 - } 129 - if point != nil { 130 - ff.DrawCircle(*point, radius, style) 131 - } 132 - }
-7
touchpad/go.mod
··· 1 - module touchpad 2 - 3 - go 1.24.0 4 - 5 - require github.com/firefly-zero/firefly-go v0.9.5 6 - 7 - require github.com/orsinium-labs/tinymath v1.0.0 // indirect
-8
touchpad/go.sum
··· 1 - github.com/firefly-zero/firefly-go v0.8.1 h1:evb25qj7ELM0wy20IIHtW8+4MI1i+wqVOiCsYdTuh3M= 2 - github.com/firefly-zero/firefly-go v0.8.1/go.mod h1:+X/XGyPdES51OESkV8NSf1mszEBZionoROM7x2pBofw= 3 - github.com/firefly-zero/firefly-go v0.9.5 h1:BzBr4t76bDVVFwNaWJixs1XasqLNBIdg0k9JXblBfU4= 4 - github.com/firefly-zero/firefly-go v0.9.5/go.mod h1:+X/XGyPdES51OESkV8NSf1mszEBZionoROM7x2pBofw= 5 - github.com/orsinium-labs/tinymath v1.0.0 h1:Uzp3GmjWIBxMObx4MQi9ACDu4Q8WKjSRakB1OMo9Bu0= 6 - github.com/orsinium-labs/tinymath v1.0.0/go.mod h1:WPXX6ei3KSXG7JfA03a+ekCYaY9SWN4I+JRl2p6ck+A= 7 - github.com/orsinium-labs/tinymath v1.1.0 h1:KomdsyLHB7vE3f1nRAJF2dyf1m/gnM2HxfTeV1vS5UA= 8 - github.com/orsinium-labs/tinymath v1.1.0/go.mod h1:WPXX6ei3KSXG7JfA03a+ekCYaY9SWN4I+JRl2p6ck+A=

History

2 rounds 0 comments
sign up or login to add to the discussion
3 commits
expand
add init for coordinates
add coordinate system
add points to the coordinate system
expand 0 comments
closed without merging
5 commits
expand
add init for coordinates
add coordinate system
add points to the coordinate system
add circle points
add gamepad demo
expand 0 comments