添加windows和macos分发版

main v1.0.2
huyinsong 1 week ago
parent fdc0c294f3
commit c1ca21bdba
  1. 143
      BUILD.md
  2. 526
      Makefile
  3. 89
      assets/icons/README.md
  4. BIN
      assets/icons/app.icns
  5. BIN
      assets/icons/icon_128.png
  6. BIN
      assets/icons/icon_16.png
  7. BIN
      assets/icons/icon_256.png
  8. BIN
      assets/icons/icon_32.png
  9. BIN
      assets/icons/icon_64.png
  10. 267
      build.sh
  11. 44
      internal/font/font.go
  12. 151
      patch/0001-fix-IBlock-disappear-issue.patch

@ -0,0 +1,143 @@
# Tetris Game 构建系统
这是一个统一的构建系统,支持 Windows、macOS 和 Linux 平台的应用打包,所有分发文件统一存放在 `dist/` 目录中。
## 🚀 快速开始
### 构建所有平台
```bash
make all
```
### 构建特定平台
```bash
make windows # 构建 Windows 版本
make macos # 构建 macOS 版本
make linux # 构建 Linux 版本
```
### 查看帮助
```bash
make help
```
## 📁 目录结构
构建完成后,`dist/` 目录结构如下:
```
dist/
├── TetrisGame-Windows-v1.0.zip # Windows 分发包
├── TetrisGame-macOS-v1.0.dmg # macOS 分发包
├── TetrisGame-Linux-v1.0.tar.gz # Linux 分发包
├── windows/ # Windows 构建临时目录
├── macos/ # macOS 构建临时目录
└── linux/ # Linux 构建临时目录
```
## 🛠 可用命令
### 基础命令
- `make help` - 显示帮助信息
- `make info` - 显示构建信息
- `make check-env` - 检查构建环境
- `make clean` - 清理所有构建文件
### 构建命令
- `make windows` - 构建 Windows 版本
- `make macos` - 构建 macOS 版本
- `make linux` - 构建 Linux 版本
- `make all` - 构建所有平台版本
### 验证命令
- `make verify` - 验证构建结果
- `make run` - 运行游戏(开发模式)
- `make test` - 运行测试
### 依赖管理
- `make deps` - 下载依赖
### 迁移命令
- `make migrate` - 迁移旧版本文件到 dist 目录
## 📦 分发包内容
### Windows 版本 (TetrisGame-Windows-v1.0.zip)
```
TetrisGame-Windows-v1.0/
├── TetrisGame.exe # 主程序
├── 启动游戏.bat # 中文启动脚本
├── README.txt # 英文说明
├── 安装说明.txt # 中文说明
└── assets/ # 资源文件
└── fonts/ # 字体文件
├── HYSongYunLangHeiW-1.ttf
└── README.md
```
### macOS 版本 (TetrisGame-macOS-v1.0.dmg)
- 包含完整的 TetrisGame.app 应用包
- 支持拖拽到 Applications 文件夹安装
- 包含应用图标和中文显示名称
### Linux 版本 (TetrisGame-Linux-v1.0.tar.gz)
```
TetrisGame-Linux-v1.0/
├── tetris # 主程序
├── start_game.sh # 启动脚本
├── README.txt # 说明文档
└── assets/ # 资源文件
└── fonts/ # 字体文件
```
## 🔧 系统要求
### 构建环境
- Go 1.19 或更高版本
- macOS (用于构建 macOS 版本的 DMG)
- zip 命令 (用于创建 Windows 压缩包)
- tar 命令 (用于创建 Linux 压缩包)
### 运行环境
- **Windows**: Windows 10/11 (64-bit)
- **macOS**: macOS 10.15 或更高版本
- **Linux**: 64-bit Linux 发行版,支持 X11 或 Wayland
## 🎮 游戏控制
- **←→** 方向键:左右移动方块
- **↑** 方向键:旋转方块
- **↓** 方向键:快速下降
- **空格键**:瞬间下降到底部
- **L 键**:切换中英文界面
- **R 键**:游戏结束后重新开始
## 🌍 多语言支持
游戏支持中英文双语界面,按 L 键可以实时切换语言。
## 📝 版本信息
- **版本**: v1.0
- **构建时间**: 自动生成
- **Git 提交**: 自动检测
## 🔍 故障排除
### 构建失败
1. 检查 Go 环境:`go version`
2. 检查依赖:`make deps`
3. 清理重建:`make clean && make all`
### 字体问题
- 确保 `assets/fonts/` 目录存在
- 确保字体文件 `HYSongYunLangHeiW-1.ttf` 存在
### macOS DMG 创建失败
- 确保在 macOS 系统上运行
- 确保有足够的磁盘空间
- 检查 hdiutil 命令是否可用
## 📄 许可证
© 2025 Tetris Game. All rights reserved.

@ -1,223 +1,331 @@
# Tetris Game Makefile # Tetris Game - 统一构建系统
# Supports cross-compilation for Windows, macOS, and Linux # 支持 Windows 和 macOS 应用打包,统一使用 dist 目录
# Variables # 基础配置
BINARY_NAME=tetris BINARY_NAME := tetris
MAIN_PATH=. APP_NAME := TetrisGame
BUILD_DIR=build VERSION := 1.0
VERSION?=dev BUILD_TIME := $(shell date '+%Y-%m-%d %H:%M:%S')
LDFLAGS=-ldflags "-s -w" GIT_COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
# Platform specific settings # 目录配置
WINDOWS_BINARY=$(BINARY_NAME).exe DIST_DIR := dist
MACOS_BINARY=$(BINARY_NAME)_macos ASSETS_DIR := assets
LINUX_BINARY=$(BINARY_NAME)_linux BUILD_TEMP := .build_temp
# Default target # Go 构建标志
GO_LDFLAGS := -ldflags "-s -w"
GO_LDFLAGS_GUI := -ldflags "-s -w -H windowsgui"
# 平台特定配置
WINDOWS_DIR := $(DIST_DIR)/windows
MACOS_DIR := $(DIST_DIR)/macos
LINUX_DIR := $(DIST_DIR)/linux
# 版本文件名
WINDOWS_ZIP := $(APP_NAME)-Windows-v$(VERSION).zip
MACOS_DMG := $(APP_NAME)-macOS-v$(VERSION).dmg
LINUX_TAR := $(APP_NAME)-Linux-v$(VERSION).tar.gz
# 颜色输出
BLUE := \033[34m
GREEN := \033[32m
YELLOW := \033[33m
RED := \033[31m
RESET := \033[0m
.DEFAULT_GOAL := help
# 帮助信息
.PHONY: help .PHONY: help
help: ## Show this help message help: ## 显示帮助信息
@echo "Available targets:" @echo "$(BLUE)🎮 Tetris Game 构建系统$(RESET)"
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " %-20s %s\n", $$1, $$2}' $(MAKEFILE_LIST) @echo ""
@echo "$(GREEN)基础命令:$(RESET)"
# Build targets @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " $(YELLOW)%-20s$(RESET) %s\n", $$1, $$2}' $(MAKEFILE_LIST)
.PHONY: build @echo ""
build: ## Build for current platform @echo "$(GREEN)示例:$(RESET)"
@echo "Building $(BINARY_NAME) for current platform..." @echo " make all # 构建所有平台"
go build $(LDFLAGS) -o $(BINARY_NAME) $(MAIN_PATH) @echo " make windows # 仅构建 Windows 版本"
@echo "Build complete: $(BINARY_NAME)" @echo " make macos # 仅构建 macOS 版本"
@echo " make clean # 清理所有构建文件"
.PHONY: build-windows
build-windows: ## Build for Windows (64-bit) - requires Windows or cross-compilation setup
@echo "Building $(BINARY_NAME) for Windows..."
@echo "Note: Cross-compilation for Ebitengine requires proper CGO setup"
@mkdir -p $(BUILD_DIR)
CGO_ENABLED=1 GOOS=windows GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/$(WINDOWS_BINARY) $(MAIN_PATH)
@echo "Build complete: $(BUILD_DIR)/$(WINDOWS_BINARY)"
.PHONY: build-windows-native
build-windows-native: ## Build for Windows using native Go (may have limitations)
@echo "Building $(BINARY_NAME) for Windows (native Go)..."
@mkdir -p $(BUILD_DIR)
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build $(LDFLAGS) -tags ebitengine -o $(BUILD_DIR)/$(WINDOWS_BINARY) $(MAIN_PATH)
@echo "Build complete: $(BUILD_DIR)/$(WINDOWS_BINARY)"
.PHONY: build-macos
build-macos: ## Build for macOS (Intel) - requires macOS or cross-compilation setup
@echo "Building $(BINARY_NAME) for macOS (Intel)..."
@echo "Note: Cross-compilation for Ebitengine requires proper CGO setup"
@mkdir -p $(BUILD_DIR)
CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/$(MACOS_BINARY)_amd64 $(MAIN_PATH)
@echo "Build complete: $(BUILD_DIR)/$(MACOS_BINARY)_amd64"
.PHONY: build-macos-arm
build-macos-arm: ## Build for macOS (Apple Silicon) - requires macOS or cross-compilation setup
@echo "Building $(BINARY_NAME) for macOS (Apple Silicon)..."
@echo "Note: Cross-compilation for Ebitengine requires proper CGO setup"
@mkdir -p $(BUILD_DIR)
CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 go build $(LDFLAGS) -o $(BUILD_DIR)/$(MACOS_BINARY)_arm64 $(MAIN_PATH)
@echo "Build complete: $(BUILD_DIR)/$(MACOS_BINARY)_arm64"
.PHONY: build-macos-current
build-macos-current: ## Build for current macOS architecture
@echo "Building $(BINARY_NAME) for current macOS architecture..."
@mkdir -p $(BUILD_DIR)
go build $(LDFLAGS) -o $(BUILD_DIR)/$(MACOS_BINARY)_$$(go env GOARCH) $(MAIN_PATH)
@echo "Build complete: $(BUILD_DIR)/$(MACOS_BINARY)_$$(go env GOARCH)"
.PHONY: build-linux
build-linux: ## Build for Linux (64-bit) - requires Linux or cross-compilation setup
@echo "Building $(BINARY_NAME) for Linux..."
@echo "Note: Cross-compilation for Ebitengine requires proper CGO setup"
@mkdir -p $(BUILD_DIR)
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/$(LINUX_BINARY) $(MAIN_PATH)
@echo "Build complete: $(BUILD_DIR)/$(LINUX_BINARY)"
.PHONY: build-current-platform
build-current-platform: ## Build for current platform (recommended)
@echo "Building $(BINARY_NAME) for current platform: $$(go env GOOS)/$$(go env GOARCH)"
@mkdir -p $(BUILD_DIR)
go build $(LDFLAGS) -o $(BUILD_DIR)/$(BINARY_NAME)_$$(go env GOOS)_$$(go env GOARCH) $(MAIN_PATH)
@echo "Build complete: $(BUILD_DIR)/$(BINARY_NAME)_$$(go env GOOS)_$$(go env GOARCH)"
.PHONY: build-all
build-all: ## Build for all platforms (requires proper cross-compilation setup)
@echo "Attempting to build for all platforms..."
@echo "Note: This may fail without proper cross-compilation environment"
$(MAKE) build-current-platform
-$(MAKE) build-windows-native
@echo "Build summary:"
@ls -la $(BUILD_DIR)/ 2>/dev/null || echo "No builds completed successfully"
# Development targets
.PHONY: run
run: ## Run the game
@echo "Starting Tetris game..."
go run $(MAIN_PATH)
.PHONY: dev # 信息显示
dev: clean build run ## Clean, build and run for development .PHONY: info
info: ## 显示构建信息
@echo "$(BLUE)📋 构建信息$(RESET)"
@echo " 应用名称: $(APP_NAME)"
@echo " 版本: v$(VERSION)"
@echo " 构建时间: $(BUILD_TIME)"
@echo " Git 提交: $(GIT_COMMIT)"
@echo " Go 版本: $(shell go version)"
@echo " 当前平台: $(shell go env GOOS)/$(shell go env GOARCH)"
@echo " 分发目录: $(DIST_DIR)/"
# 环境检查
.PHONY: check-env
check-env: ## 检查构建环境
@echo "$(BLUE)🔍 环境检查$(RESET)"
@go version >/dev/null 2>&1 || (echo "$(RED)❌ Go 未安装$(RESET)" && exit 1)
@echo "$(GREEN)✅ Go 环境正常$(RESET)"
@[ -d "$(ASSETS_DIR)" ] || (echo "$(RED)❌ assets 目录缺失$(RESET)" && exit 1)
@echo "$(GREEN)✅ 资源目录存在$(RESET)"
@[ -f "main.go" ] || (echo "$(RED)❌ main.go 文件缺失$(RESET)" && exit 1)
@echo "$(GREEN)✅ 源代码文件存在$(RESET)"
# 准备目录
.PHONY: prepare
prepare: ## 准备构建目录
@echo "$(BLUE)📁 准备构建目录$(RESET)"
@mkdir -p $(DIST_DIR)
@mkdir -p $(WINDOWS_DIR)
@mkdir -p $(MACOS_DIR)
@mkdir -p $(LINUX_DIR)
@mkdir -p $(BUILD_TEMP)
# 清理
.PHONY: clean
clean: ## 清理构建文件
@echo "$(BLUE)🧹 清理构建文件$(RESET)"
@rm -rf $(DIST_DIR)
@rm -rf $(BUILD_TEMP)
@rm -f *.zip *.dmg *.tar.gz
@rm -f $(BINARY_NAME) $(BINARY_NAME).exe
@rm -rf TetrisGame.app
@echo "$(GREEN)✅ 清理完成$(RESET)"
# Windows 构建
.PHONY: build-windows-binary
build-windows-binary: check-env prepare
@echo "$(BLUE)🪟 构建 Windows 二进制文件$(RESET)"
GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build $(GO_LDFLAGS_GUI) -o $(BUILD_TEMP)/$(APP_NAME).exe .
@echo "$(GREEN)✅ Windows 二进制文件构建完成$(RESET)"
.PHONY: create-windows-startup-script
create-windows-startup-script:
@echo "创建 Windows 启动脚本..."
@echo '@echo off' > $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
@echo 'chcp 65001 >nul' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
@echo 'echo 🎮 正在启动 Tetris Game...' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
@echo 'echo.' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
@echo 'echo 🎯 游戏控制:' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
@echo 'echo ←→ 左右移动' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
@echo 'echo ↑ 旋转方块' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
@echo 'echo ↓ 快速下降' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
@echo 'echo 空格 瞬间下降' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
@echo 'echo L 切换中英文' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
@echo 'echo.' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
@echo '"%~dp0$(APP_NAME).exe"' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
.PHONY: create-windows-docs
create-windows-docs:
@echo "创建 Windows 说明文档..."
@echo '🎮 Tetris Game - Windows Version v1.0' > $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/README.txt
@echo '' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/README.txt
@echo '📥 Installation: This is a portable version, no installation required.' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/README.txt
@echo '🚀 How to Start: Double-click TetrisGame.exe or 启动游戏.bat' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/README.txt
@echo '🎯 Game Controls: ←→ Move, ↑ Rotate, ↓ Soft drop, Space Hard drop, L Language' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/README.txt
@echo '🔧 System Requirements: Windows 10/11 (64-bit)' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/README.txt
@echo '' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/README.txt
@echo '© 2025 Tetris Game. All rights reserved.' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/README.txt
.PHONY: package-windows
package-windows: build-windows-binary
@echo "$(BLUE)📦 打包 Windows 应用$(RESET)"
# 创建 Windows 应用目录
@rm -rf $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)
@mkdir -p $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)
# 复制主程序文件
@cp $(BUILD_TEMP)/$(APP_NAME).exe $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/
# 复制资源文件
@cp -r $(ASSETS_DIR) $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/
# 创建启动脚本和文档
@$(MAKE) create-windows-startup-script
@$(MAKE) create-windows-docs
# 创建压缩包
@cd $(WINDOWS_DIR) && zip -r ../$(WINDOWS_ZIP) $(APP_NAME)-Windows-v$(VERSION)/
@echo "$(GREEN)✅ Windows 应用打包完成: $(DIST_DIR)/$(WINDOWS_ZIP)$(RESET)"
# macOS 构建
.PHONY: build-macos-binary
build-macos-binary: check-env prepare
@echo "$(BLUE)🍎 构建 macOS 二进制文件$(RESET)"
go build $(GO_LDFLAGS) -o $(BUILD_TEMP)/$(BINARY_NAME) .
@echo "$(GREEN)✅ macOS 二进制文件构建完成$(RESET)"
.PHONY: create-macos-plist
create-macos-plist:
@echo "创建 macOS Info.plist..."
@echo '<?xml version="1.0" encoding="UTF-8"?>' > $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo '<plist version="1.0">' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo '<dict>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <key>CFBundleDisplayName</key>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <string>俄罗斯方块</string>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <key>CFBundleExecutable</key>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <string>$(BINARY_NAME)</string>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <key>CFBundleIdentifier</key>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <string>com.tetrisgame.app</string>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <key>CFBundleName</key>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <string>$(APP_NAME)</string>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <key>CFBundleShortVersionString</key>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <string>$(VERSION)</string>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <key>CFBundleIconFile</key>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <string>app</string>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <key>LSApplicationCategoryType</key>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <string>public.app-category.games</string>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo '</dict>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo '</plist>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
.PHONY: create-dmg
create-dmg:
@echo "创建 DMG 文件..."
@DMG_SIZE="50m" && \
TEMP_DMG="$(BUILD_TEMP)/temp_$(MACOS_DMG)" && \
MOUNT_POINT="$(BUILD_TEMP)/dmg_mount" && \
rm -rf $$MOUNT_POINT && \
mkdir -p $$MOUNT_POINT && \
hdiutil create -size $$DMG_SIZE -fs HFS+ -volname "Tetris Game" $$TEMP_DMG && \
hdiutil attach $$TEMP_DMG -mountpoint $$MOUNT_POINT && \
cp -R $(MACOS_DIR)/$(APP_NAME).app $$MOUNT_POINT/ && \
ln -s /Applications $$MOUNT_POINT/Applications && \
hdiutil detach $$MOUNT_POINT && \
hdiutil convert $$TEMP_DMG -format UDZO -o $(DIST_DIR)/$(MACOS_DMG) && \
rm -f $$TEMP_DMG
.PHONY: package-macos
package-macos: build-macos-binary
@echo "$(BLUE)📦 打包 macOS 应用$(RESET)"
# 创建 .app 包结构
@rm -rf $(MACOS_DIR)/$(APP_NAME).app
@mkdir -p $(MACOS_DIR)/$(APP_NAME).app/Contents/MacOS
@mkdir -p $(MACOS_DIR)/$(APP_NAME).app/Contents/Resources
# 复制可执行文件
@cp $(BUILD_TEMP)/$(BINARY_NAME) $(MACOS_DIR)/$(APP_NAME).app/Contents/MacOS/
@chmod +x $(MACOS_DIR)/$(APP_NAME).app/Contents/MacOS/$(BINARY_NAME)
# 复制资源文件
@cp -r $(ASSETS_DIR) $(MACOS_DIR)/$(APP_NAME).app/Contents/Resources/
# 创建 Info.plist
@$(MAKE) create-macos-plist
# 复制应用图标
@if [ -f "$(ASSETS_DIR)/icons/app.icns" ]; then \
cp "$(ASSETS_DIR)/icons/app.icns" $(MACOS_DIR)/$(APP_NAME).app/Contents/Resources/; \
echo "$(GREEN)✅ 已复制应用图标 app.icns$(RESET)"; \
else \
echo "$(YELLOW) 图标文件 $(ASSETS_DIR)/icons/app.icns 不存在$(RESET)"; \
fi
# 创建 DMG
@$(MAKE) create-dmg
@echo "$(GREEN)✅ macOS 应用打包完成: $(DIST_DIR)/$(MACOS_DMG)$(RESET)"
# Linux 构建
.PHONY: build-linux-binary
build-linux-binary: check-env prepare
@echo "$(BLUE)🐧 构建 Linux 二进制文件$(RESET)"
@echo "$(YELLOW) 注意: Linux 交叉编译需要 CGO 支持,建议在 Linux 系统上构建$(RESET)"
@if [ "$$(go env GOOS)" = "linux" ]; then \
go build $(GO_LDFLAGS) -o $(BUILD_TEMP)/$(BINARY_NAME)_linux .; \
else \
echo "$(YELLOW) 当前不在 Linux 系统,跳过 Linux 构建$(RESET)"; \
mkdir -p $(BUILD_TEMP); \
echo "# Linux 构建需要在 Linux 系统上进行" > $(BUILD_TEMP)/$(BINARY_NAME)_linux.txt; \
fi
@echo "$(GREEN)✅ Linux 二进制文件构建完成$(RESET)"
.PHONY: package-linux
package-linux: build-linux-binary
@echo "$(BLUE)📦 打包 Linux 应用$(RESET)"
@if [ "$$(go env GOOS)" = "linux" ] && [ -f "$(BUILD_TEMP)/$(BINARY_NAME)_linux" ]; then \
echo "正在打包 Linux 应用..."; \
rm -rf $(LINUX_DIR)/$(APP_NAME)-Linux-v$(VERSION); \
mkdir -p $(LINUX_DIR)/$(APP_NAME)-Linux-v$(VERSION); \
cp $(BUILD_TEMP)/$(BINARY_NAME)_linux $(LINUX_DIR)/$(APP_NAME)-Linux-v$(VERSION)/$(BINARY_NAME); \
chmod +x $(LINUX_DIR)/$(APP_NAME)-Linux-v$(VERSION)/$(BINARY_NAME); \
cp -r $(ASSETS_DIR) $(LINUX_DIR)/$(APP_NAME)-Linux-v$(VERSION)/; \
echo '#!/bin/bash' > $(LINUX_DIR)/$(APP_NAME)-Linux-v$(VERSION)/start_game.sh; \
echo 'echo "🎮 Starting Tetris Game..."' >> $(LINUX_DIR)/$(APP_NAME)-Linux-v$(VERSION)/start_game.sh; \
echo 'cd "$$(dirname "$$0")"' >> $(LINUX_DIR)/$(APP_NAME)-Linux-v$(VERSION)/start_game.sh; \
echo './$(BINARY_NAME)' >> $(LINUX_DIR)/$(APP_NAME)-Linux-v$(VERSION)/start_game.sh; \
chmod +x $(LINUX_DIR)/$(APP_NAME)-Linux-v$(VERSION)/start_game.sh; \
cd $(LINUX_DIR) && tar -czf ../$(LINUX_TAR) $(APP_NAME)-Linux-v$(VERSION)/; \
echo "$(GREEN)✅ Linux 应用打包完成: $(DIST_DIR)/$(LINUX_TAR)$(RESET)"; \
else \
echo "$(YELLOW) 跳过 Linux 打包(需要在 Linux 系统上构建)$(RESET)"; \
mkdir -p $(LINUX_DIR); \
echo "# Linux 版本需要在 Linux 系统上构建" > $(LINUX_DIR)/README.txt; \
echo "$(YELLOW) Linux 版本跳过$(RESET)"; \
fi
.PHONY: install # 主要构建目标
install: ## Install the game to GOPATH/bin .PHONY: windows
@echo "Installing $(BINARY_NAME)..." windows: package-windows ## 构建 Windows 版本
go install $(LDFLAGS) $(MAIN_PATH)
@echo "Installation complete!"
# Quality assurance targets .PHONY: macos
.PHONY: test macos: package-macos ## 构建 macOS 版本
test: ## Run tests
@echo "Running tests..."
go test -v ./...
.PHONY: test-coverage .PHONY: linux
test-coverage: ## Run tests with coverage linux: package-linux ## 构建 Linux 版本
@echo "Running tests with coverage..."
go test -v -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html
@echo "Coverage report generated: coverage.html"
.PHONY: fmt .PHONY: all
fmt: ## Format code all: clean windows macos ## 构建所有支持的平台版本
@echo "Formatting code..." @if [ "$$(go env GOOS)" = "linux" ]; then \
go fmt ./... $(MAKE) linux; \
else \
echo "$(YELLOW) 当前平台不支持 Linux 交叉编译,跳过 Linux 构建$(RESET)"; \
fi
@echo ""
@echo "$(GREEN)🎉 所有平台构建完成!$(RESET)"
@echo ""
@echo "$(BLUE)📋 构建结果:$(RESET)"
@ls -lh $(DIST_DIR)/*.zip $(DIST_DIR)/*.dmg $(DIST_DIR)/*.tar.gz 2>/dev/null || true
.PHONY: vet # 验证和测试
vet: ## Run go vet .PHONY: verify
@echo "Running go vet..." verify: ## 验证构建结果
go vet ./... @echo "$(BLUE)🔍 验证构建结果$(RESET)"
@echo ""
@echo "$(GREEN)构建文件:$(RESET)"
@ls -lh $(DIST_DIR)/ 2>/dev/null || echo "无构建文件"
@echo ""
@if [ -f "$(DIST_DIR)/$(WINDOWS_ZIP)" ]; then \
echo "$(GREEN)✅ Windows 版本: $(WINDOWS_ZIP)$(RESET)"; \
unzip -l $(DIST_DIR)/$(WINDOWS_ZIP) | head -10; \
fi
@if [ -f "$(DIST_DIR)/$(MACOS_DMG)" ]; then \
echo "$(GREEN)✅ macOS 版本: $(MACOS_DMG)$(RESET)"; \
fi
@if [ -f "$(DIST_DIR)/$(LINUX_TAR)" ]; then \
echo "$(GREEN)✅ Linux 版本: $(LINUX_TAR)$(RESET)"; \
fi
.PHONY: lint # 开发相关
lint: ## Run golangci-lint (requires golangci-lint to be installed) .PHONY: run
@echo "Running golangci-lint..." run: ## 运行游戏(开发模式)
golangci-lint run @echo "$(BLUE)🎮 启动游戏$(RESET)"
go run .
.PHONY: check .PHONY: test
check: fmt vet test ## Run format, vet, and tests test: ## 运行测试
@echo "$(BLUE)🧪 运行测试$(RESET)"
go test -v ./...
# Dependency management
.PHONY: deps .PHONY: deps
deps: ## Download dependencies deps: ## 下载依赖
@echo "Downloading dependencies..." @echo "$(BLUE)📦 下载依赖$(RESET)"
go mod download go mod download
.PHONY: deps-update
deps-update: ## Update dependencies
@echo "Updating dependencies..."
go mod tidy
go get -u ./...
go mod tidy go mod tidy
.PHONY: deps-vendor
deps-vendor: ## Vendor dependencies
@echo "Vendoring dependencies..."
go mod vendor
# Cleanup targets
.PHONY: clean
clean: ## Clean build artifacts
@echo "Cleaning build artifacts..."
@rm -f $(BINARY_NAME)
@rm -rf $(BUILD_DIR)
@rm -f coverage.out coverage.html
@echo "Clean complete!"
.PHONY: clean-all
clean-all: clean ## Clean everything including vendor
@echo "Cleaning vendor directory..."
@rm -rf vendor/
# Release targets
.PHONY: release
release: clean build-current-platform ## Create release build for current platform
@echo "Creating release package for current platform..."
@mkdir -p $(BUILD_DIR)/releases
@CURRENT_OS=$$(go env GOOS); \
CURRENT_ARCH=$$(go env GOARCH); \
if [ "$$CURRENT_OS" = "windows" ]; then \
cd $(BUILD_DIR) && zip releases/$(BINARY_NAME)-$$CURRENT_OS-$$CURRENT_ARCH.zip $(BINARY_NAME)_$$CURRENT_OS_$$CURRENT_ARCH; \
else \
cd $(BUILD_DIR) && tar -czf releases/$(BINARY_NAME)-$$CURRENT_OS-$$CURRENT_ARCH.tar.gz $(BINARY_NAME)_$$CURRENT_OS_$$CURRENT_ARCH; \
fi
@echo "Release package created in $(BUILD_DIR)/releases/"
@ls -la $(BUILD_DIR)/releases/
# Docker targets (optional)
.PHONY: docker-build
docker-build: ## Build Docker image
@echo "Building Docker image..."
docker build -t $(BINARY_NAME):$(VERSION) .
.PHONY: docker-run
docker-run: ## Run in Docker container
@echo "Running in Docker container..."
docker run --rm -it $(BINARY_NAME):$(VERSION)
# Info targets
.PHONY: info
info: ## Show build information
@echo "=== Build Information ==="
@echo "Binary name: $(BINARY_NAME)"
@echo "Version: $(VERSION)"
@echo "Go version: $$(go version)"
@echo "Build directory: $(BUILD_DIR)"
@echo "Current platform: $$(go env GOOS)/$$(go env GOARCH)"
@echo "CGO enabled: $$(go env CGO_ENABLED)"
.PHONY: env
env: ## Show Go environment
@echo "=== Go Environment ==="
@go env
.PHONY: cross-compile-info
cross-compile-info: ## Show cross-compilation information
@echo "=== Cross-Compilation Information ==="
@echo "Ebitengine requires CGO for cross-compilation."
@echo "To build for other platforms, you need:"
@echo "1. C compiler for target platform"
@echo "2. Platform-specific libraries"
@echo "3. Proper CGO_ENABLED=1 setting"
@echo ""
@echo "Recommended approach:"
@echo "- Build on the target platform directly"
@echo "- Use GitHub Actions or CI/CD for multi-platform builds"
@echo "- Use Docker with multi-stage builds"

@ -0,0 +1,89 @@
# 应用图标目录
本目录包含 Tetris 游戏的应用图标文件。
## 文件说明
### 主要图标文件
- `app.icns` - macOS 应用图标文件 (96K)
- 格式: Mac OS X icon, "ic12" type
- 包含所有标准尺寸 (16x16 到 1024x1024)
- 支持 Retina 显示屏 (@2x 版本)
### PNG 图标文件
- `icon_16.png` - 16x16 像素图标
- `icon_32.png` - 32x32 像素图标
- `icon_64.png` - 64x64 像素图标
- `icon_128.png` - 128x128 像素图标
- `icon_256.png` - 256x256 像素图标
## 图标设计
### 设计元素
- **主题**: 俄罗斯方块彩色块图案
- **背景**: 深蓝色 (#2c3e50) 圆角矩形
- **方块颜色**:
- 红色 (#e74c3c)
- 蓝色 (#3498db)
- 橙色 (#f39c12)
- 绿色 (#2ecc71)
- 紫色 (#9b59b6)
- 深橙色 (#e67e22)
- 青绿色 (#1abc9c)
- 深灰色 (#34495e)
### 技术特性
- **多分辨率支持**: 适配不同显示密度
- **圆角设计**: 符合 macOS 设计规范
- **高光效果**: 增加视觉层次感
- **白色边框**: 增强方块定义
## 构建集成
在 macOS 构建过程中,`app.icns` 文件会自动复制到应用包中:
```bash
# 构建 macOS 版本
make macos
# 图标将自动复制到:
# dist/macos/TetrisGame.app/Contents/Resources/app.icns
```
## 图标使用
### macOS 应用
- 文件位置: `TetrisGame.app/Contents/Resources/app.icns`
- Info.plist 配置: `CFBundleIconFile = app`
- 显示位置: Finder、Dock、应用启动台
### 其他平台
- Windows: 可使用 PNG 文件转换为 .ico 格式
- Linux: 直接使用 PNG 文件
## 维护说明
### 更新图标
如需更新应用图标:
1. 替换 `app.icns` 文件
2. 可选:更新对应的 PNG 文件
3. 重新构建应用: `make clean && make macos`
### 创建新图标
如需从零创建新图标:
1. 创建 1024x1024 的高分辨率设计
2. 生成多个尺寸的 PNG 文件
3. 使用 macOS `iconutil` 工具创建 .icns 文件:
```bash
iconutil -c icns icon.iconset -o app.icns
```
## 文件完整性
所有图标文件的校验和:
- `app.icns`: 96K (Mac OS X icon format)
- 总体设计一致性: ✅
- 多分辨率覆盖: ✅
- macOS 兼容性: ✅

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 B

@ -0,0 +1,267 @@
#!/bin/bash
# Tetris Game 自动化构建脚本
# 支持 Windows、macOS 和 Linux 平台
set -e # 遇到错误立即退出
# 颜色定义
BLUE='\033[34m'
GREEN='\033[32m'
YELLOW='\033[33m'
RED='\033[31m'
RESET='\033[0m'
# 配置
VERSION="1.0"
BUILD_TIME=$(date '+%Y-%m-%d %H:%M:%S')
GIT_COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
# 函数:打印带颜色的消息
print_info() {
echo -e "${BLUE} $1${RESET}"
}
print_success() {
echo -e "${GREEN}$1${RESET}"
}
print_warning() {
echo -e "${YELLOW} $1${RESET}"
}
print_error() {
echo -e "${RED}$1${RESET}"
}
# 函数:显示帮助信息
show_help() {
echo -e "${BLUE}🎮 Tetris Game 自动化构建脚本${RESET}"
echo ""
echo "用法: $0 [选项] [平台]"
echo ""
echo "平台:"
echo " windows 构建 Windows 版本"
echo " macos 构建 macOS 版本"
echo " linux 构建 Linux 版本"
echo " all 构建所有平台 (默认)"
echo ""
echo "选项:"
echo " -h, --help 显示帮助信息"
echo " -c, --clean 构建前清理"
echo " -v, --verify 构建后验证"
echo " -i, --info 显示构建信息"
echo " --no-color 禁用颜色输出"
echo ""
echo "示例:"
echo " $0 # 构建所有平台"
echo " $0 windows # 仅构建 Windows"
echo " $0 -c all # 清理后构建所有平台"
echo " $0 -cv macos # 清理、构建 macOS 并验证"
}
# 函数:显示构建信息
show_info() {
print_info "构建信息"
echo " 版本: v${VERSION}"
echo " 构建时间: ${BUILD_TIME}"
echo " Git 提交: ${GIT_COMMIT}"
echo " Go 版本: $(go version 2>/dev/null || echo '未安装')"
echo " 当前平台: $(go env GOOS 2>/dev/null || echo 'unknown')/$(go env GOARCH 2>/dev/null || echo 'unknown')"
echo " 工作目录: $(pwd)"
}
# 函数:检查环境
check_environment() {
print_info "检查构建环境..."
# 检查 Go
if ! command -v go &> /dev/null; then
print_error "Go 未安装或不在 PATH 中"
exit 1
fi
print_success "Go 环境正常"
# 检查必要文件
if [ ! -f "main.go" ]; then
print_error "main.go 文件不存在"
exit 1
fi
if [ ! -d "assets" ]; then
print_error "assets 目录不存在"
exit 1
fi
print_success "源代码文件检查通过"
}
# 函数:清理构建文件
clean_build() {
print_info "清理构建文件..."
make clean
print_success "清理完成"
}
# 函数:构建指定平台
build_platform() {
local platform=$1
print_info "构建 ${platform} 版本..."
case $platform in
windows)
make windows
;;
macos)
make macos
;;
linux)
make linux
;;
all)
make all
;;
*)
print_error "不支持的平台: $platform"
exit 1
;;
esac
print_success "${platform} 构建完成"
}
# 函数:验证构建结果
verify_build() {
print_info "验证构建结果..."
make verify
print_success "验证完成"
}
# 函数:显示构建结果摘要
show_summary() {
echo ""
print_success "🎉 构建完成!"
echo ""
print_info "构建结果摘要:"
if [ -d "dist" ]; then
echo " 分发目录: dist/"
# 显示文件大小
if [ -f "dist/TetrisGame-Windows-v1.0.zip" ]; then
local size=$(ls -lh dist/TetrisGame-Windows-v1.0.zip | awk '{print $5}')
echo " Windows 版本: TetrisGame-Windows-v1.0.zip (${size})"
fi
if [ -f "dist/TetrisGame-macOS-v1.0.dmg" ]; then
local size=$(ls -lh dist/TetrisGame-macOS-v1.0.dmg | awk '{print $5}')
echo " macOS 版本: TetrisGame-macOS-v1.0.dmg (${size})"
fi
if [ -f "dist/TetrisGame-Linux-v1.0.tar.gz" ]; then
local size=$(ls -lh dist/TetrisGame-Linux-v1.0.tar.gz | awk '{print $5}')
echo " Linux 版本: TetrisGame-Linux-v1.0.tar.gz (${size})"
fi
echo ""
print_info "总计文件数: $(find dist/ -type f -name '*.zip' -o -name '*.dmg' -o -name '*.tar.gz' | wc -l | tr -d ' ')"
# 计算总大小
local total_size=$(find dist/ -type f -name '*.zip' -o -name '*.dmg' -o -name '*.tar.gz' -exec ls -l {} \; | awk '{sum += $5} END {print sum}')
if [ -n "$total_size" ] && [ "$total_size" -gt 0 ]; then
local total_mb=$((total_size / 1024 / 1024))
echo " 总大小: ${total_mb}MB"
fi
else
print_warning "dist 目录不存在"
fi
echo ""
print_info "使用说明:"
echo " - 查看详细文档: cat BUILD.md"
echo " - 验证构建: make verify"
echo " - 运行游戏: make run"
}
# 主函数
main() {
local platform="all"
local clean_first=false
local verify_after=false
local show_info_only=false
# 解析命令行参数
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_help
exit 0
;;
-c|--clean)
clean_first=true
shift
;;
-v|--verify)
verify_after=true
shift
;;
-i|--info)
show_info_only=true
shift
;;
--no-color)
# 禁用颜色
BLUE=''
GREEN=''
YELLOW=''
RED=''
RESET=''
shift
;;
windows|macos|linux|all)
platform=$1
shift
;;
*)
print_error "未知参数: $1"
echo "使用 $0 --help 查看帮助"
exit 1
;;
esac
done
# 显示标题
echo -e "${BLUE}🎮 Tetris Game 自动化构建脚本 v${VERSION}${RESET}"
echo ""
# 如果只是显示信息
if [ "$show_info_only" = true ]; then
show_info
exit 0
fi
# 检查环境
check_environment
# 清理(如果需要)
if [ "$clean_first" = true ]; then
clean_build
fi
# 构建
build_platform "$platform"
# 验证(如果需要)
if [ "$verify_after" = true ]; then
verify_build
fi
# 显示摘要
show_summary
}
# 错误处理
trap 'print_error "构建过程中发生错误,退出码: $?"' ERR
# 运行主函数
main "$@"

@ -62,11 +62,29 @@ func NewFontRenderer() *FontRenderer {
// loadFromAssetsDirectory 专门扫描 assets/fonts 目录并加载字体文件 // loadFromAssetsDirectory 专门扫描 assets/fonts 目录并加载字体文件
func loadFromAssetsDirectory() ([]byte, string) { func loadFromAssetsDirectory() ([]byte, string) {
assetsPath := "assets/fonts" // 尝试多个可能的路径
possiblePaths := []string{
"assets/fonts", // 开发环境
"Contents/Resources/assets/fonts", // macOS 应用包内部
"../Resources/assets/fonts", // macOS 应用包相对路径
filepath.Join(getExecutableDir(), "assets/fonts"), // 可执行文件同目录
}
var assetsPath string
var found bool
// 查找存在的资源路径
for _, path := range possiblePaths {
if _, err := os.Stat(path); err == nil {
assetsPath = path
found = true
log.Printf("📁 找到字体目录: %s", path)
break
}
}
// 检查目录是否存在 if !found {
if _, err := os.Stat(assetsPath); os.IsNotExist(err) { log.Printf("📁 未找到 assets/fonts 目录,已尝试路径: %v", possiblePaths)
log.Printf("📁 assets/fonts 目录不存在,请创建并放入字体文件")
return nil, "" return nil, ""
} }
@ -87,16 +105,16 @@ func loadFromAssetsDirectory() ([]byte, string) {
}) })
if err != nil { if err != nil {
log.Printf("❌ 扫描 assets/fonts 目录失败: %v", err) log.Printf("❌ 扫描字体目录失败: %v", err)
return nil, "" return nil, ""
} }
if len(fontFiles) == 0 { if len(fontFiles) == 0 {
log.Printf("📂 assets/fonts 目录为空,请添加字体文件 (.ttf, .ttc, .otf)") log.Printf("📂 字体目录为空,请添加字体文件 (.ttf, .ttc, .otf)")
return nil, "" return nil, ""
} }
log.Printf("🔍 在 assets/fonts 目录找到 %d 个字体文件", len(fontFiles)) log.Printf("🔍 在 %s 找到 %d 个字体文件", assetsPath, len(fontFiles))
// 字体优先级:微软雅黑 > 其他中文字体 > 任意字体 // 字体优先级:微软雅黑 > 其他中文字体 > 任意字体
fontPriorities := [][]string{ fontPriorities := [][]string{
@ -133,10 +151,20 @@ func loadFromAssetsDirectory() ([]byte, string) {
} }
} }
log.Printf("❌ assets/fonts 目录中没有可用的字体文件") log.Printf("❌ 字体目录中没有可用的字体文件")
return nil, "" return nil, ""
} }
// getExecutableDir 获取可执行文件所在目录
func getExecutableDir() string {
execPath, err := os.Executable()
if err != nil {
log.Printf("⚠ 获取可执行文件路径失败: %v", err)
return "."
}
return filepath.Dir(execPath)
}
// tryLoadFont 尝试加载字体文件并验证格式 // tryLoadFont 尝试加载字体文件并验证格式
func tryLoadFont(fontPath string) ([]byte, error) { func tryLoadFont(fontPath string) ([]byte, error) {
data, err := os.ReadFile(fontPath) data, err := os.ReadFile(fontPath)

@ -1,151 +0,0 @@
From ffe9242a73abfb3e8ee9b6effd57e64155717bfb Mon Sep 17 00:00:00 2001
From: yinqiang <zhuyinqiang@foxmail.com>
Date: Sat, 7 Jun 2025 22:50:07 +0800
Subject: [PATCH] fix IBlock disappear issue
---
block.go | 21 +++++++++++----------
game.go | 26 +++++++++++++++-----------
2 files changed, 26 insertions(+), 21 deletions(-)
diff --git a/block.go b/block.go
index ad276ea..0b3aaee 100644
--- a/block.go
+++ b/block.go
@@ -14,7 +14,7 @@ type Block struct {
type BlockType int
const (
- IBlock BlockType = iota
+ IBlock BlockType = iota + 1
JBlock
LBlock
OBlock
@@ -32,13 +32,14 @@ type Tetromino struct {
// Colors for different block types
var BlockColors = map[BlockType]color.Color{
- IBlock: color.RGBA{0, 255, 255, 255}, // Cyan
- JBlock: color.RGBA{0, 0, 255, 255}, // Blue
- LBlock: color.RGBA{255, 165, 0, 255}, // Orange
- OBlock: color.RGBA{255, 255, 0, 255}, // Yellow
- SBlock: color.RGBA{0, 255, 0, 255}, // Green
- TBlock: color.RGBA{128, 0, 128, 255}, // Purple
- ZBlock: color.RGBA{255, 0, 0, 255}, // Red
+ EmptyBlock: color.RGBA{0, 0, 0, 0}, // Black
+ IBlock: color.RGBA{0, 255, 255, 255}, // Cyan
+ JBlock: color.RGBA{0, 0, 255, 255}, // Blue
+ LBlock: color.RGBA{255, 165, 0, 255}, // Orange
+ OBlock: color.RGBA{255, 255, 0, 255}, // Yellow
+ SBlock: color.RGBA{0, 255, 0, 255}, // Green
+ TBlock: color.RGBA{128, 0, 128, 255}, // Purple
+ ZBlock: color.RGBA{255, 0, 0, 255}, // Red
}
// TetrominoShapes defines the shape of each tetromino type
@@ -102,8 +103,8 @@ func NewTetromino(blockType BlockType, x, y int) *Tetromino {
shape := TetrominoShapes[blockType]
blocks := make([]Block, 0)
- for i := 0; i < len(shape); i++ {
- for j := 0; j < len(shape[i]); j++ {
+ for i := range shape {
+ for j := range shape[i] {
if shape[i][j] {
blocks = append(blocks, Block{
X: j,
diff --git a/game.go b/game.go
index aa9896f..2aa98e9 100644
--- a/game.go
+++ b/game.go
@@ -24,6 +24,7 @@ const (
// Game constants
InitialDropInterval = 60
MinDropInterval = 5
+ EmptyBlock = 0
)
// Game represents the main game state
@@ -90,9 +91,9 @@ func (g *Game) Draw(screen *ebiten.Image) {
}
// Draw placed blocks
- for y := 0; y < BoardHeight; y++ {
- for x := 0; x < BoardWidth; x++ {
- if g.board[y][x] != 0 {
+ for y := range BoardHeight {
+ for x := range BoardWidth {
+ if g.board[y][x] != EmptyBlock {
g.drawBlock(screen, x, y, g.board[y][x])
}
}
@@ -311,7 +312,7 @@ func (g *Game) isColliding() bool {
}
// Check collision with other pieces
if y >= 0 && x >= 0 && x < BoardWidth && y < BoardHeight {
- if g.board[y][x] != 0 {
+ if g.board[y][x] != EmptyBlock {
return true
}
}
@@ -324,6 +325,9 @@ func (g *Game) lockPiece() {
if g.currentPiece == nil {
return
}
+ // if g.currentPiece.BlockType == IBlock {
+ // g.currentPiece.BlockType = IBlock
+ // }
positions := g.currentPiece.GetAbsolutePositions()
for _, pos := range positions {
@@ -378,8 +382,8 @@ func (g *Game) clearLines() {
// isLineFull checks if a line is completely filled
func (g *Game) isLineFull(y int) bool {
- for x := 0; x < BoardWidth; x++ {
- if g.board[y][x] == 0 {
+ for x := range BoardWidth {
+ if g.board[y][x] == EmptyBlock {
return false
}
}
@@ -391,15 +395,15 @@ func (g *Game) removeLine(y int) {
for i := y; i > 0; i-- {
copy(g.board[i], g.board[i-1])
}
- for x := 0; x < BoardWidth; x++ {
- g.board[0][x] = 0
+ for x := range BoardWidth {
+ g.board[0][x] = EmptyBlock
}
}
// spawnNewPiece creates a new piece at the top of the board
func (g *Game) spawnNewPiece() {
if g.nextPiece == nil {
- g.nextPiece = NewTetromino(BlockType(rand.Intn(7)), 0, 0)
+ g.nextPiece = NewTetromino(BlockType(rand.Intn(7)+1), 0, 0)
}
g.currentPiece = g.nextPiece
@@ -409,7 +413,7 @@ func (g *Game) spawnNewPiece() {
}
g.currentPiece.Y = 0
- g.nextPiece = NewTetromino(BlockType(rand.Intn(7)), 0, 0)
+ g.nextPiece = NewTetromino(BlockType(rand.Intn(7)+1), 0, 0)
if g.isColliding() {
g.gameOver = true
@@ -423,7 +427,7 @@ func (g *Game) wouldCollide(piece *Tetromino) bool {
if x < 0 || x >= BoardWidth || y >= BoardHeight {
return true
}
- if y >= 0 && y < BoardHeight && x >= 0 && x < BoardWidth && g.board[y][x] != 0 {
+ if y >= 0 && y < BoardHeight && x >= 0 && x < BoardWidth && g.board[y][x] != EmptyBlock {
return true
}
}
--
2.39.5 (Apple Git-154)
Loading…
Cancel
Save