feat(game): 掉落物单堆叠上限 9999 + 拾取按栈上限拆分;挖掘按住循环挥动
- 地上掉落合并上限 64→9999,超出生成新堆(TestDropStackCap) - 拾取按物品栈上限拆成多栈入包,放不下回吐地面 - 按住左键挖掘时每 0.3 秒循环挥动手部(swingTimer), 挥动幅度收窄并抬高持手位置保持可见 - 新增 -digtest/-swingtest dev 截图测试开关
This commit is contained in:
@@ -66,6 +66,8 @@ var (
|
||||
invTest = flag.Bool("invtest", false, "dev 测试:截图前打开物品栏(E 键界面)并放入若干物品")
|
||||
miniDump = flag.String("minimapdump", "", "dev 诊断:保存一次小地图图像到该路径")
|
||||
waterTest = flag.Bool("underwatertest", false, "dev 测试:截图前置水下渲染状态(验证蓝色叠加)")
|
||||
digTest = flag.Bool("digtest", false, "dev 测试:截图前在视线前方挖一个 2×2×2 的坑(验证挖洞后洞壁光照)")
|
||||
swingTest = flag.Bool("swingtest", false, "dev 测试:截图帧强制手部挥动(验证挖掘挥动动画)")
|
||||
)
|
||||
|
||||
// clientApp 客户端应用:把会话与渲染粘合起来(engine.Ticker + engine.Renderer)。
|
||||
@@ -116,13 +118,14 @@ type clientApp struct {
|
||||
cursorReq atomic.Int32
|
||||
|
||||
// 手持方块(tick 计算 UV → 渲染线程上传,渲染.md §5.2)
|
||||
handInit bool
|
||||
handSlot int
|
||||
handHas bool
|
||||
handDirty bool
|
||||
handUVs [6][4]float32
|
||||
handTint [3]float32 // 手持颜色乘数(空手肤色拳 / 持方块 1,1,1)
|
||||
swing float64 // 挥动动画剩余量(左/右键触发,渲染线程衰减)
|
||||
handInit bool
|
||||
handSlot int
|
||||
handHas bool
|
||||
handDirty bool
|
||||
handUVs [6][4]float32
|
||||
handTint [3]float32 // 手持颜色乘数(空手肤色拳 / 持方块 1,1,1)
|
||||
swing float64 // 挥动动画剩余量(左/右键触发,渲染线程衰减)
|
||||
swingTimer float64 // 按住挖掘时周期性挥动的节拍器
|
||||
|
||||
// 水下状态(渲染线程读;tick 更新)
|
||||
underwater bool
|
||||
@@ -152,6 +155,7 @@ type clientApp struct {
|
||||
invShot bool // dev 测试:-invtest 已注入
|
||||
miniDumped bool // dev 诊断:-minimapdump 已保存
|
||||
waterShot bool // dev 测试:-underwatertest 已注入
|
||||
digShot bool // dev 测试:-digtest 已注入
|
||||
}
|
||||
|
||||
// worldMeshJob 待上传网格。
|
||||
@@ -302,6 +306,16 @@ func (a *clientApp) Tick(dt float64) {
|
||||
if a.in.breakDown || a.in.placeDown {
|
||||
a.swing = 1.0
|
||||
}
|
||||
// 按住挖掘时周期性挥动(原版挖掘节奏,约每 0.3 秒一次)
|
||||
if a.in.breakHeld {
|
||||
a.swingTimer -= dt
|
||||
if a.swingTimer <= 0 {
|
||||
a.swingTimer = 0.3
|
||||
a.swing = 1.0
|
||||
}
|
||||
} else {
|
||||
a.swingTimer = 0
|
||||
}
|
||||
a.in.apply(a.sess)
|
||||
// 水下检测(相机所在方块为水 → 水下渲染效果)
|
||||
camB := a.sess.World.Block(int32(a.sess.Cam.Pos[0]), int32(a.sess.Cam.Pos[1]), int32(a.sess.Cam.Pos[2]))
|
||||
@@ -798,7 +812,21 @@ func (a *clientApp) Render() {
|
||||
}
|
||||
a.cursorReq.Store(-1)
|
||||
}
|
||||
// dev 测试:截图前注入破坏裂纹/实体/ESC/工作台/设置/物品栏/水下(必须在 3D 绘制之前,截图帧才能拍到)
|
||||
// dev 测试:挖坑类测试提前注入(留足网格重建时间);其余截图前注入
|
||||
if a.frames == 100 && *digTest && !a.digShot {
|
||||
a.digShot = true
|
||||
if h, ok := a.sess.Cast(5); ok {
|
||||
for dy := int32(0); dy < 2; dy++ {
|
||||
for dx := int32(-1); dx <= 1; dx++ {
|
||||
for dz := int32(-1); dz <= 1; dz++ {
|
||||
a.sess.World.SetBlock(h.X+dx, h.Y-dy, h.Z+dz, block.Air)
|
||||
}
|
||||
}
|
||||
}
|
||||
a.logf("digtest 注入: 挖坑 (%d,%d,%d)", h.X, h.Y, h.Z)
|
||||
}
|
||||
}
|
||||
// dev 测试:截图前注入破坏裂纹/实体/ESC/工作台/设置/物品栏/水下/挖坑(必须在 3D 绘制之前,截图帧才能拍到)
|
||||
if a.frames == 195 && (*crackStage >= 0 || *spawnTest != "" || *escTest || *craftTest || *optTest || *invTest || *waterTest) {
|
||||
a.injectDevVisuals()
|
||||
}
|
||||
@@ -849,6 +877,9 @@ func (a *clientApp) Render() {
|
||||
}
|
||||
// 手持方块上传与绘制(渲染.md §5.2;上传必须是渲染线程)
|
||||
// 挥动动画:左/右键后手部斜向下摆,逐帧重传立方体
|
||||
if *swingTest && a.frames >= 198 {
|
||||
a.swing = 1.0 // dev 测试:截图帧强制挥动
|
||||
}
|
||||
if a.swing > 0 {
|
||||
a.swing -= 0.12
|
||||
if a.swing < 0 {
|
||||
@@ -865,10 +896,10 @@ func (a *clientApp) Render() {
|
||||
handTint = a.handTint
|
||||
}
|
||||
a.mu.Unlock()
|
||||
swingPos := [3]float32{0.46, -0.44, -0.66}
|
||||
swingPos := [3]float32{0.46, -0.34, -0.66}
|
||||
if a.swing > 0 {
|
||||
swingPos[0] -= float32(a.swing) * 0.22 // 挥动:右移 + 下压
|
||||
swingPos[1] -= float32(a.swing) * 0.18
|
||||
swingPos[0] -= float32(a.swing) * 0.15 // 挥动:向屏幕中心下方摆动(保持手部可见)
|
||||
swingPos[1] -= float32(a.swing) * 0.10
|
||||
handDirty = true // 挥动期间逐帧重传位置
|
||||
}
|
||||
if handDirty {
|
||||
|
||||
Reference in New Issue
Block a user