this repo has no description

add circle points

voigt.tngl.sh 00a81d34 bf9e4d46

verified
+248
+33
coordinates/main.go
··· 2 2 3 3 import ( 4 4 "github.com/firefly-zero/firefly-go/firefly" 5 + "github.com/orsinium-labs/tinymath" 5 6 ) 6 7 7 8 var ( ··· 39 40 firefly.ClearScreen(firefly.ColorNone) 40 41 } 41 42 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 + 42 49 // points in 4 quadrants 43 50 firefly.DrawPoint(translatePoint(firefly.Point{X: 10, Y: 10}), firefly.ColorCyan) 44 51 firefly.DrawPoint(translatePoint(firefly.Point{X: 10, Y: -10}), firefly.ColorGreen) ··· 51 58 y := -p.Y + SCREENHEIGHT/2 52 59 // firefly.LogDebug(strings.Join([]string{"x: ", strconv.Itoa(x), ", y: ", strconv.Itoa(y)}, " ")) 53 60 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 54 87 } 55 88 56 89 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 + }