你有没有想过,用 Go语言 也能写小游戏?今天就带大家用不到 200 行代码,打造一个简版《植物大战僵尸》!
不仅能 自动射击 、判断胜负 ,还可以 用鼠标点击放僵尸挑战自己,实现真正的人机对抗!
游戏玩法
- • 植物固定位置自动发射子弹
- • 点击鼠标左键放置僵尸,向左移动
- • 子弹打中僵尸可造成伤害,击败 10 个获胜!
- • 有僵尸闯进防线则游戏失败
技术点
- • 游戏开发框架:
Ebiten
- • 植物发射逻辑:定时自动生成子弹
- • 僵尸行为:匀速向左移动,碰到子弹扣血
- • 鼠标点击:在任意位置生成僵尸
- • 游戏结局:胜利 or 失败提示
完整代码(Go + Ebiten)
go
package main
import (
"fmt"
"image/color"
"log"
"math"
"math/rand"
"time"
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
)
type Zombie struct {
x, y float64
hp int
}
type Bullet struct {
x, y float64
}
type Game struct {
zombies []Zombie
bullets []Bullet
shootCD int
mouseDown bool
zombiesKilled int
gameOver bool
gameWin bool
}
func (g *Game) Update() error {
if g.gameOver {
return nil
}
// 自动发射子弹
if g.shootCD <= 0 {
g.bullets = append(g.bullets, Bullet{x: 100, y: 200})
g.shootCD = 15
} else {
g.shootCD--
}
// 更新子弹
newBullets := []Bullet{}
for _, b := range g.bullets {
b.x += 6
if b.x < 800 {
newBullets = append(newBullets, b)
}
}
g.bullets = newBullets
// 更新僵尸
newZombies := []Zombie{}
for _, z := range g.zombies {
z.x -= 1.2
if z.x <= 0 {
g.gameOver = true
g.gameWin = false
return nil
}
hit := false
for i := range g.bullets {
if math.Abs(z.x-g.bullets[i].x) < 10 && math.Abs(z.y-g.bullets[i].y) < 10 {
z.hp--
if z.hp <= 0 {
hit = true
g.zombiesKilled++
if g.zombiesKilled >= 10 {
g.gameOver = true
g.gameWin = true
return nil
}
break
}
}
}
if !hit {
newZombies = append(newZombies, z)
}
}
g.zombies = newZombies
// 鼠标左键放僵尸
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
if !g.mouseDown {
x, y := ebiten.CursorPosition()
g.zombies = append(g.zombies, Zombie{
x: float64(x),
y: float64(y),
hp: 3,
})
g.mouseDown = true
}
} else {
g.mouseDown = false
}
return nil
}
func (g *Game) Draw(screen *ebiten.Image) {
screen.Fill(color.RGBA{0xCC, 0xFF, 0xCC, 0xFF})
// 植物
ebitenutil.DrawRect(screen, 100, 200, 20, 20, color.RGBA{0x00, 0x88, 0x00, 0xFF})
// 子弹
for _, b := range g.bullets {
ebitenutil.DrawRect(screen, b.x, b.y, 5, 5, color.RGBA{0x00, 0x00, 0xFF, 0xFF})
}
// 僵尸
for _, z := range g.zombies {
ebitenutil.DrawRect(screen, z.x, z.y, 20, 20, color.RGBA{0x88, 0x00, 0x00, 0xFF})
}
// 文本信息
msg := "点击鼠标左键放置僵尸! 已击败僵尸:" + itoa(g.zombiesKilled)
if g.gameOver {
if g.gameWin {
msg = " 胜利!你击败了10个僵尸!"
} else {
msg = " 游戏失败!有僵尸入侵了!"
}
}
ebitenutil.DebugPrint(screen, msg)
}
func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
return 800, 600
}
func itoa(n int) string {
return fmt.Sprintf("%d", n)
}
func main() {
rand.Seed(time.Now().UnixNano())
game := &Game{}
ebiten.SetWindowSize(800, 600)
ebiten.SetWindowTitle("Go版植物大战僵尸 - 加入胜利/失败判定")
if err := ebiten.RunGame(game); err != nil {
log.Fatal(err)
}
}
编译运行方法
-
- 安装依赖(需要 Go 和 Ebiten):
arduino
go get github.com/hajimehoshi/ebiten/v2
-
- 运行程序:
go
go run main.go
最后
这个小游戏只是开始,后续你可以扩展:
- • 不同种类植物与僵尸
- • 子弹特效
- • 多行战斗区域
- • 商店系统与阳光资源管理
如果你对游戏开发有兴趣,Go + Ebiten 是一个极具潜力的组合!