修复废弃方法,更新为现代API - 移除废弃的rand.Seed()调用 - 替换绘制API为vector包 - 提升性能和兼容性

main
huyinsong 1 week ago
parent 22864ffcab
commit fa81ccec6e
  1. 112
      DEPRECATED_METHODS_FIXED.md
  2. 65
      internal/game/game.go
  3. 4
      main.go

@ -0,0 +1,112 @@
# 废弃方法修复记录
## 修复日期
2024年
## 修复的废弃方法
### 1. Go 标准库 - `math/rand`
#### 修复内容:
- **废弃方法**: `rand.Seed(time.Now().UnixNano())`
- **修复方案**: 完全移除该调用
- **原因**: Go 1.20+ 中随机数生成器自动种子化,不再需要手动调用 `rand.Seed()`
- **文件**: `main.go`
#### 变更:
```go
// 修复前
import (
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().UnixNano())
// ...
}
// 修复后
func main() {
// 不再需要 rand.Seed() 调用
// ...
}
```
### 2. Ebitengine v2.5+ - 图形绘制 API
#### 修复内容:
- **废弃方法**: `ebitenutil.DrawRect()``ebitenutil.DrawLine()`
- **新方法**: `vector.DrawFilledRect()``vector.StrokeLine()`
- **原因**: Ebitengine v2.5 后推荐使用性能更好的 vector 包
- **文件**: `internal/game/game.go`
#### 主要变更:
**矩形绘制:**
```go
// 修复前
ebitenutil.DrawRect(screen, x, y, width, height, color)
// 修复后
vector.DrawFilledRect(screen, float32(x), float32(y), float32(width), float32(height), color, false)
```
**线条绘制:**
```go
// 修复前
ebitenutil.DrawLine(screen, x1, y1, x2, y2, color)
// 修复后
vector.StrokeLine(screen, float32(x1), float32(y1), float32(x2), float32(y2), 1, color, false)
```
#### 修复位置:
1. 游戏背景绘制
2. 预览区域背景
3. 网格线绘制
4. 方块绘制 (`drawBlock` 方法)
5. 幽灵方块绘制
6. 下一个方块预览
### 3. 导入包更新
添加了新的导入:
```go
import (
// ... 其他导入
"github.com/hajimehoshi/ebiten/v2/vector"
)
```
## 性能优势
### Vector API 优势:
1. **更好的性能**: vector 包使用 GPU 加速绘制
2. **更准确的渲染**: 减少了像素对齐问题
3. **未来兼容性**: 与 Ebitengine 的发展方向一致
### 随机数优化:
1. **自动优化**: Go 1.20+ 的随机数生成器自动优化
2. **更好的随机性**: 不需要手动种子化
3. **代码简化**: 减少了样板代码
## 验证结果
- ✅ 编译成功
- ✅ Lint 检查通过 (无废弃警告)
- ✅ 功能测试正常
- ✅ 多平台构建正常
## 影响评估
- **兼容性**: 完全向前兼容
- **功能**: 无功能变化,纯技术升级
- **性能**: 理论上性能有所提升
- **维护性**: 符合最新最佳实践
## 建议
1. 定期运行 `make check` 检查代码质量
2. 关注 Ebitengine 官方更新,及时采用新 API
3. 保持 Go 版本更新以享受最新优化

@ -13,6 +13,7 @@ import (
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
"github.com/hajimehoshi/ebiten/v2/inpututil"
"github.com/hajimehoshi/ebiten/v2/vector"
)
// Game represents the main game state
@ -64,18 +65,18 @@ func (g *Game) Update() error {
// Draw renders the game state
func (g *Game) Draw(screen *ebiten.Image) {
// Draw board background
ebitenutil.DrawRect(screen, 0, 0, float64(config.BoardWidth*config.BlockSize), float64(config.BoardHeight*config.BlockSize), color.RGBA{40, 40, 40, 255})
vector.DrawFilledRect(screen, 0, 0, float32(config.BoardWidth*config.BlockSize), float32(config.BoardHeight*config.BlockSize), color.RGBA{40, 40, 40, 255}, false)
// Draw preview area background
ebitenutil.DrawRect(screen, float64(config.PreviewX-config.BlockSize), 0, float64(6*config.BlockSize), float64(config.ScreenHeight), color.RGBA{30, 30, 30, 255})
vector.DrawFilledRect(screen, float32(config.PreviewX-config.BlockSize), 0, float32(6*config.BlockSize), float32(config.ScreenHeight), color.RGBA{30, 30, 30, 255}, false)
// Draw grid lines
gridColor := color.RGBA{60, 60, 60, 255}
for x := 0; x <= config.BoardWidth; x++ {
ebitenutil.DrawLine(screen, float64(x*config.BlockSize), 0, float64(x*config.BlockSize), float64(config.BoardHeight*config.BlockSize), gridColor)
vector.StrokeLine(screen, float32(x*config.BlockSize), 0, float32(x*config.BlockSize), float32(config.BoardHeight*config.BlockSize), 1, gridColor, false)
}
for y := 0; y <= config.BoardHeight; y++ {
ebitenutil.DrawLine(screen, 0, float64(y*config.BlockSize), float64(config.BoardWidth*config.BlockSize), float64(y*config.BlockSize), gridColor)
vector.StrokeLine(screen, 0, float32(y*config.BlockSize), float32(config.BoardWidth*config.BlockSize), float32(y*config.BlockSize), 1, gridColor, false)
}
// Draw placed blocks
@ -101,12 +102,12 @@ func (g *Game) Draw(screen *ebiten.Image) {
for _, pos := range ghostPiece.GetAbsolutePositions() {
if pos[1] >= 0 {
ghostColor := color.RGBA{128, 128, 128, 128}
ebitenutil.DrawRect(screen,
float64(pos[0]*config.BlockSize),
float64(pos[1]*config.BlockSize),
float64(config.BlockSize-1),
float64(config.BlockSize-1),
ghostColor)
vector.DrawFilledRect(screen,
float32(pos[0]*config.BlockSize),
float32(pos[1]*config.BlockSize),
float32(config.BlockSize-1),
float32(config.BlockSize-1),
ghostColor, false)
}
}
@ -126,12 +127,12 @@ func (g *Game) Draw(screen *ebiten.Image) {
for _, block := range g.nextPiece.Blocks {
x := config.PreviewX + block.X*config.BlockSize
y := config.PreviewY + block.Y*config.BlockSize
ebitenutil.DrawRect(screen,
float64(x),
float64(y),
float64(config.BlockSize-1),
float64(config.BlockSize-1),
types.BlockColors[g.nextPiece.BlockType])
vector.DrawFilledRect(screen,
float32(x),
float32(y),
float32(config.BlockSize-1),
float32(config.BlockSize-1),
types.BlockColors[g.nextPiece.BlockType], false)
}
}
@ -408,27 +409,27 @@ func (g *Game) wouldCollide(piece *tetromino.Tetromino) bool {
// drawBlock draws a single block at the specified position
func (g *Game) drawBlock(screen *ebiten.Image, x, y int, blockType types.BlockType) {
ebitenutil.DrawRect(screen,
float64(x*config.BlockSize),
float64(y*config.BlockSize),
float64(config.BlockSize-1),
float64(config.BlockSize-1),
types.BlockColors[blockType])
vector.DrawFilledRect(screen,
float32(x*config.BlockSize),
float32(y*config.BlockSize),
float32(config.BlockSize-1),
float32(config.BlockSize-1),
types.BlockColors[blockType], false)
// Add a subtle border for 3D effect
borderColor := color.RGBA{255, 255, 255, 50}
ebitenutil.DrawRect(screen,
float64(x*config.BlockSize),
float64(y*config.BlockSize),
float64(config.BlockSize-1),
vector.DrawFilledRect(screen,
float32(x*config.BlockSize),
float32(y*config.BlockSize),
float32(config.BlockSize-1),
2,
borderColor)
ebitenutil.DrawRect(screen,
float64(x*config.BlockSize),
float64(y*config.BlockSize),
borderColor, false)
vector.DrawFilledRect(screen,
float32(x*config.BlockSize),
float32(y*config.BlockSize),
2,
float64(config.BlockSize-1),
borderColor)
float32(config.BlockSize-1),
borderColor, false)
}
// max returns the maximum of two integers

@ -2,8 +2,6 @@ package main
import (
"log"
"math/rand"
"time"
"tetris/internal/game"
"tetris/pkg/config"
@ -12,8 +10,6 @@ import (
)
func main() {
rand.Seed(time.Now().UnixNano())
ebiten.SetWindowSize(config.ScreenWidth, config.ScreenHeight)
ebiten.SetWindowTitle("Tetris")

Loading…
Cancel
Save