+499
Diff
round #0
boxfighter/eg_6x10.fff
boxfighter/eg_6x10.fff
This is a binary file and will not be displayed.
+7
boxfighter/go.mod
+7
boxfighter/go.mod
+4
boxfighter/go.sum
+4
boxfighter/go.sum
···
1
+
github.com/firefly-zero/firefly-go v0.9.5 h1:BzBr4t76bDVVFwNaWJixs1XasqLNBIdg0k9JXblBfU4=
2
+
github.com/firefly-zero/firefly-go v0.9.5/go.mod h1:+X/XGyPdES51OESkV8NSf1mszEBZionoROM7x2pBofw=
3
+
github.com/orsinium-labs/tinymath v1.0.0 h1:Uzp3GmjWIBxMObx4MQi9ACDu4Q8WKjSRakB1OMo9Bu0=
4
+
github.com/orsinium-labs/tinymath v1.0.0/go.mod h1:WPXX6ei3KSXG7JfA03a+ekCYaY9SWN4I+JRl2p6ck+A=
+21
boxfighter/main.go
+21
boxfighter/main.go
···
1
+
package main
2
+
3
+
import (
4
+
"github.com/firefly-zero/firefly-go/firefly"
5
+
)
6
+
7
+
var (
8
+
font firefly.Font
9
+
)
10
+
11
+
func init() {
12
+
firefly.Boot = boot
13
+
firefly.Render = render
14
+
}
15
+
16
+
func boot() {
17
+
}
18
+
19
+
func render() {
20
+
firefly.DrawText("x", font, firefly.Point{X: 100, Y: 100}, firefly.ColorDarkBlue)
21
+
}
+131
boxfighter/tmp/box.go
+131
boxfighter/tmp/box.go
···
1
+
package main
2
+
3
+
import "github.com/firefly-zero/firefly-go/firefly"
4
+
5
+
const (
6
+
boxWidth = 24
7
+
boxHeight = 24
8
+
9
+
g = 0.05 // Gravity (้ๅๅ ้ๅบฆ) ใฎ็ฅ
10
+
jump = -3.0 // ใธใฃใณใๅ
11
+
)
12
+
13
+
// boxData represents the box character
14
+
type boxData struct {
15
+
x float32
16
+
y float32
17
+
vy float32 // Velocity of y (้ๅบฆใฎyๆๅ) ใฎ็ฅ
18
+
19
+
w int
20
+
h int
21
+
}
22
+
23
+
// newbox creates a new box
24
+
func newBox() *boxData {
25
+
return &boxData{
26
+
x: 10,
27
+
y: 160 - 45,
28
+
vy: 0,
29
+
30
+
w: 15,
31
+
h: 25,
32
+
}
33
+
}
34
+
35
+
// reset resets the box's position for a new game
36
+
func (gd *boxData) reset() {
37
+
gd.x = 10
38
+
gd.y = 10
39
+
gd.vy = 0
40
+
}
41
+
42
+
// jump makes the box jump
43
+
func (gd *boxData) jump() {
44
+
gd.y += jump
45
+
}
46
+
47
+
func (gd *boxData) left() {
48
+
gd.x -= 1
49
+
}
50
+
51
+
// jump makes the box jump
52
+
func (gd *boxData) right() {
53
+
gd.x += 1
54
+
}
55
+
56
+
// move moves the box
57
+
func (gd *boxData) gravity() {
58
+
if gd.y < 160-25 {
59
+
gd.vy += g // ้ๅบฆใซๅ ้ๅบฆใ่ถณใ
60
+
gd.y += gd.vy // ไฝ็ฝฎใซ้ๅบฆใ่ถณใ
61
+
}
62
+
}
63
+
64
+
// draw draws the box
65
+
func (gd *boxData) draw() {
66
+
firefly.DrawRect(firefly.Point{X: int(gd.x), Y: int(gd.y)}, firefly.Size{W: gd.w, H: gd.h}, firefly.Style{FillColor: firefly.ColorNone, StrokeColor: firefly.ColorBlack, StrokeWidth: 1})
67
+
}
68
+
69
+
// position returns the box's position
70
+
func (gd *boxData) position() (int, int, int, int) {
71
+
l := int(gd.x)
72
+
t := int(gd.y)
73
+
r := int(gd.x) + boxWidth
74
+
b := int(gd.y) + boxHeight
75
+
76
+
return l, t, r, b
77
+
}
78
+
79
+
// // isHit returns true if the box is hit by a wall
80
+
// func (gd *boxData) isHit(wl, wt, wr, wb int) bool {
81
+
// gl, gt, gr, gb := gd.position()
82
+
83
+
// if gr < wl || gl > wr {
84
+
// return false
85
+
// }
86
+
87
+
// if gb < wt || gt > wb {
88
+
// return false
89
+
// }
90
+
91
+
// return true
92
+
// }
93
+
94
+
// hitWalls returns true if the box hits any walls
95
+
// func (gd *boxData) hitWalls(w *wallsData) bool {
96
+
// for _, wall := range w.walls {
97
+
// // ไธใฎๅฃใ่กจใๅ่งๅฝขใไฝใ
98
+
// bLeft, bTop, bRight, bBottom := wall.top()
99
+
100
+
// // ไธใฎๅฃใจใฎๅฝใใๅคๅฎ
101
+
// if gd.isHit(bLeft, bTop, bRight, bBottom) {
102
+
// return true
103
+
// }
104
+
105
+
// // ไธใฎๅฃใ่กจใๅ่งๅฝขใไฝใ
106
+
// bLeft, bTop, bRight, bBottom = wall.bottom()
107
+
108
+
// // ไธใฎๅฃใจใฎๅฝใใๅคๅฎ
109
+
// if box.isHit(bLeft, bTop, bRight, bBottom) {
110
+
// return true
111
+
// }
112
+
// }
113
+
114
+
// return false
115
+
// }
116
+
117
+
// hitTop returns true if the box hits the top of the screen
118
+
// func (gd *boxData) hitTop() bool {
119
+
// return gd.y < 0
120
+
// }
121
+
122
+
// func (gd *boxData) hitBottom() bool {
123
+
// b := int(gd.y) + boxHeight
124
+
// return b > 160
125
+
// }
126
+
127
+
// score returns the current score of the player based on the box's position
128
+
// func (gd *boxData) score(w *wallsData) int {
129
+
// l, _, _, _ := gd.position()
130
+
// return w.score(l)
131
+
// }
+189
boxfighter/tmp/box2.go
+189
boxfighter/tmp/box2.go
···
1
+
package main
2
+
3
+
const (
4
+
groundY = float32(screenH - 80)
5
+
groundThickness = float32(80)
6
+
7
+
// ---------- Tuning ----------
8
+
maxRunSpeed = float32(380)
9
+
10
+
// Separate accel/decel
11
+
groundAccel = float32(2600)
12
+
groundDecel = float32(3200)
13
+
airAccel = float32(1400)
14
+
airDecel = float32(300)
15
+
16
+
// Jump
17
+
jumpSpeed = float32(640)
18
+
19
+
// Variable jump height: cut velocity when releasing jump while going up
20
+
jumpCutMultiplier = float32(0.35)
21
+
22
+
// Coyote time + jump buffer (seconds)
23
+
coyoteTime = float32(0.10)
24
+
jumpBufferTime = float32(0.12)
25
+
26
+
// --- Fast-fall tuning ---
27
+
// Base gravity is used when rising (Vel.Y < 0) and jump is held.
28
+
// When falling (Vel.Y > 0) we apply higher gravity (fallMultiplier).
29
+
// When jump is released early during rise, we apply higher gravity too (lowJumpMultiplier).
30
+
gravity = float32(1200) // "floatier" base on the way up
31
+
fallMultiplier = float32(2.2) // faster fall
32
+
lowJumpMultiplier = float32(2.6) // stronger pull-down if jump released early
33
+
maxFallSpeed = float32(2200) // higher terminal velocity for snappy fall
34
+
)
35
+
36
+
var dir float32 = 0.0
37
+
38
+
type Vector2 struct {
39
+
X float32
40
+
Y float32
41
+
}
42
+
43
+
type Player struct {
44
+
Pos Vector2
45
+
Vel Vector2
46
+
Size Vector2
47
+
OnGround bool
48
+
49
+
CoyoteTimer float32
50
+
JumpBuffer float32
51
+
Jumping bool
52
+
}
53
+
54
+
func clamp(v, min, max float32) float32 {
55
+
if v < min {
56
+
return min
57
+
}
58
+
if v > max {
59
+
return max
60
+
}
61
+
return v
62
+
}
63
+
64
+
func approach(current, target, delta float32) float32 {
65
+
if current < target {
66
+
current += delta
67
+
if current > target {
68
+
return target
69
+
}
70
+
return current
71
+
}
72
+
if current > target {
73
+
current -= delta
74
+
if current < target {
75
+
return target
76
+
}
77
+
return current
78
+
}
79
+
return current
80
+
}
81
+
82
+
func newPlayer() *Player {
83
+
return &Player{
84
+
Pos: Vector2{X: 120, Y: groundY - 60},
85
+
Vel: Vector2{X: 0, Y: 0},
86
+
Size: Vector2{X: 50, Y: 60},
87
+
}
88
+
}
89
+
90
+
func (p *Player) jump() {
91
+
_ = dir
92
+
}
93
+
94
+
func (p *Player) left() {
95
+
dir -= 1
96
+
}
97
+
98
+
func (p *Player) right() {
99
+
dir += 1
100
+
}
101
+
102
+
func GetFrameTime() float32 {
103
+
return 1 / 60
104
+
}
105
+
106
+
func renderPlayer() {
107
+
// Get time in seconds for last frame drawn (delta time)
108
+
// float GetFrameTime(void);
109
+
dt := GetFrameTime()
110
+
111
+
// ---- Timers ----
112
+
if p.OnGround {
113
+
p.CoyoteTimer = coyoteTime
114
+
} else {
115
+
p.CoyoteTimer = clamp(p.CoyoteTimer-dt, 0, 999)
116
+
}
117
+
118
+
if jumpPressed {
119
+
p.JumpBuffer = jumpBufferTime
120
+
} else {
121
+
p.JumpBuffer = clamp(p.JumpBuffer-dt, 0, 999)
122
+
}
123
+
124
+
// ---- Horizontal movement (accel/decel) ----
125
+
if p.OnGround {
126
+
if dir != 0 {
127
+
target := dir * maxRunSpeed
128
+
p.Vel.X = approach(p.Vel.X, target, groundAccel*dt)
129
+
} else {
130
+
p.Vel.X = approach(p.Vel.X, 0, groundDecel*dt)
131
+
}
132
+
} else {
133
+
if dir != 0 {
134
+
target := dir * maxRunSpeed
135
+
p.Vel.X = approach(p.Vel.X, target, airAccel*dt)
136
+
} else {
137
+
p.Vel.X = approach(p.Vel.X, 0, airDecel*dt)
138
+
}
139
+
}
140
+
p.Vel.X = clamp(p.Vel.X, -maxRunSpeed, maxRunSpeed)
141
+
142
+
// ---- Jump using buffer + coyote ----
143
+
if p.JumpBuffer > 0 && p.CoyoteTimer > 0 {
144
+
p.Vel.Y = -jumpSpeed
145
+
p.OnGround = false
146
+
p.CoyoteTimer = 0
147
+
p.JumpBuffer = 0
148
+
p.Jumping = true
149
+
}
150
+
151
+
// ---- Variable jump height (jump cut) ----
152
+
// Optional: keep it, feels good in addition to lowJumpMultiplier gravity.
153
+
if jumpReleased && p.Jumping && p.Vel.Y < 0 {
154
+
p.Vel.Y *= jumpCutMultiplier
155
+
}
156
+
157
+
// ---- Fast-fall gravity ----
158
+
// If falling: stronger gravity.
159
+
// If rising but jump not held: stronger gravity (low jump).
160
+
g := gravity
161
+
if p.Vel.Y > 0 {
162
+
g *= fallMultiplier
163
+
} else if p.Vel.Y < 0 && !jumpHeld {
164
+
g *= lowJumpMultiplier
165
+
}
166
+
p.Vel.Y += g * dt
167
+
p.Vel.Y = clamp(p.Vel.Y, -100000, maxFallSpeed)
168
+
169
+
// ---- Integrate ----
170
+
p.Pos.X += p.Vel.X * dt
171
+
p.Pos.Y += p.Vel.Y * dt
172
+
173
+
// ---- Ground collision ----
174
+
playerBottom := p.Pos.Y + p.Size.Y
175
+
if playerBottom >= groundY {
176
+
p.Pos.Y = groundY - p.Size.Y
177
+
p.Vel.Y = 0
178
+
p.OnGround = true
179
+
p.Jumping = false
180
+
} else {
181
+
p.OnGround = false
182
+
}
183
+
184
+
// ---- Screen bounds (X) ----
185
+
p.Pos.X = clamp(p.Pos.X, 0, float32(screenW)-p.Size.X)
186
+
if p.Pos.X == 0 || p.Pos.X == float32(screenW)-p.Size.X {
187
+
p.Vel.X = 0
188
+
}
189
+
}
+73
boxfighter/tmp/keys.go
+73
boxfighter/tmp/keys.go
···
1
+
package main
2
+
3
+
import ff "github.com/firefly-zero/firefly-go/firefly"
4
+
5
+
// Check if a key is being pressed (key held down)
6
+
// bool IsKeyDown(int key)
7
+
// {
8
+
// bool down = false;
9
+
10
+
// if ((key > 0) && (key < MAX_KEYBOARD_KEYS))
11
+
// {
12
+
// if (CORE.Input.Keyboard.currentKeyState[key] == 1) down = true;
13
+
// }
14
+
15
+
// return down;
16
+
// }
17
+
func IsKeyDown(buttons ff.Buttons) bool {
18
+
var down bool
19
+
20
+
if buttons.S == true {
21
+
down = true
22
+
}
23
+
if buttons.E == true {
24
+
down = true
25
+
}
26
+
if buttons.W == true {
27
+
down = true
28
+
}
29
+
if buttons.N == true {
30
+
down = true
31
+
}
32
+
if buttons.Menu == true {
33
+
down = true
34
+
}
35
+
36
+
return down
37
+
}
38
+
39
+
// // Check if a key has been released once
40
+
// bool IsKeyReleased(int key)
41
+
// {
42
+
// bool released = false;
43
+
44
+
// if ((key > 0) && (key < MAX_KEYBOARD_KEYS))
45
+
// {
46
+
// if ((CORE.Input.Keyboard.previousKeyState[key] == 1) && (CORE.Input.Keyboard.currentKeyState[key] == 0)) released = true;
47
+
// }
48
+
49
+
// return released;
50
+
// }
51
+
func IsKeyReleased(buttons, buttonsOld ff.Buttons) bool {
52
+
var released bool
53
+
54
+
if buttons.AnyPressed() == false {
55
+
if buttonsOld.S == true && buttons.S == false {
56
+
released = true
57
+
}
58
+
if buttonsOld.E == true && buttons.E == false {
59
+
released = true
60
+
}
61
+
if buttonsOld.W == true && buttons.W == false {
62
+
released = true
63
+
}
64
+
if buttonsOld.N == true && buttons.N == false {
65
+
released = true
66
+
}
67
+
if buttonsOld.Menu == true && buttons.Menu == false {
68
+
released = true
69
+
}
70
+
}
71
+
72
+
return released
73
+
}
+74
boxfighter/tmp/main copy.go
+74
boxfighter/tmp/main copy.go
···
1
+
package main
2
+
3
+
import (
4
+
"github.com/firefly-zero/firefly-go/firefly"
5
+
)
6
+
7
+
const (
8
+
screenW = 240
9
+
screenH = 160
10
+
)
11
+
12
+
var (
13
+
frames = 0
14
+
score = 0
15
+
16
+
font firefly.Font
17
+
p *Player
18
+
19
+
buttons firefly.Buttons
20
+
buttonsOld firefly.Buttons
21
+
22
+
jumpPressed bool = false
23
+
jumpHeld bool = false
24
+
jumpReleased bool = false
25
+
)
26
+
27
+
func init() {
28
+
firefly.Boot = boot
29
+
// firefly.Update = update
30
+
firefly.Render = render
31
+
}
32
+
33
+
func boot() {
34
+
p = newPlayer()
35
+
}
36
+
37
+
// func update() {
38
+
// frames += 1
39
+
40
+
// renderPlayer()
41
+
// buttons = firefly.ReadButtons(firefly.Combined)
42
+
// buttonsOld = firefly.ReadButtons(firefly.Combined)
43
+
44
+
// jumpPressed = buttons.N
45
+
// jumpHeld = buttons.Held(buttonsOld).N
46
+
// jumpReleased = buttons.JustReleased(buttonsOld).N
47
+
48
+
// if buttons.N {
49
+
// p.jump()
50
+
// }
51
+
52
+
// if buttons.W {
53
+
// p.left()
54
+
// }
55
+
56
+
// if buttons.E {
57
+
// p.right()
58
+
// }
59
+
// }
60
+
61
+
func render() {
62
+
// firefly.ClearScreen(firefly.ColorWhite)
63
+
64
+
// ff.DrawRect(ff.Point{X: 0, Y: int(groundY)}, ff.Size{W: screenW, H: int(groundThickness)}, ff.Style{FillColor: ff.ColorLightGray, StrokeColor: ff.ColorLightGray, StrokeWidth: 1})
65
+
// ff.DrawRect(
66
+
// ff.Point{X: int(p.Pos.X), Y: int(p.Pos.Y)},
67
+
// ff.Size{W: int(p.Size.X), H: int(p.Size.Y)},
68
+
// ff.Style{FillColor: ff.ColorDarkBlue, StrokeColor: ff.ColorDarkBlue, StrokeWidth: 1},
69
+
// )
70
+
71
+
// firefly.DrawText("F: "+strconv.Itoa(frames), font, firefly.Point{X: 10, Y: 10}, firefly.ColorDarkBlue)
72
+
firefly.DrawText("x", font, firefly.Point{X: 100, Y: 100}, firefly.ColorDarkBlue)
73
+
// rl.DrawText("Move: A/D or Left/Right Jump: Space (buffer+coyote+variable+fast-fall)", 20, 20, 20, rl.Black)
74
+
}
History
1 round
0 comments
voigt.tngl.sh
submitted
#0
1 commit
expand
collapse
implement boxfighter
no conflicts, ready to merge