用Go写一个《植物大战僵尸》小游戏:支持鼠标放僵尸、胜利失败判定!

你有没有想过,用 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)
    }
}

编译运行方法

    1. 安装依赖(需要 Go 和 Ebiten):
arduino 复制代码
go get github.com/hajimehoshi/ebiten/v2
    1. 运行程序:
go 复制代码
go run main.go

最后

这个小游戏只是开始,后续你可以扩展:

  • • 不同种类植物与僵尸
  • • 子弹特效
  • • 多行战斗区域
  • • 商店系统与阳光资源管理

如果你对游戏开发有兴趣,Go + Ebiten 是一个极具潜力的组合!

相关推荐
行百里er13 分钟前
Redis 持久化——RDB 快照 vs AOF 日志
redis·后端
Ysx1 小时前
踩了 5 次"本地全绿、生产失效"之后,我把交付流程做成了 SOP
后端·程序员
pippocao2 小时前
王者荣耀日志组件BqLog为什么这么快之2——从环形队列到自适应数据总线
后端
孟健2 小时前
Stripe出海收款架构设计:水星银行与香港账户实测对比与资金流闭环
后端·架构
程序员cxuan2 小时前
DeepSeek Harness 出了桌面端?我把它扒了一遍
人工智能·后端·程序员
j7~2 小时前
【Python】(篇七)《使用Python库》 -- 详解
开发语言·后端·python·编程学习·python标准库·python第三方库·python拓展
Memory_荒年2 小时前
订单超时未支付?从“定时扫库”一步步到最终形态
java·后端
卷无止境3 小时前
便宜模型和贵模型到底差在哪儿?一份关于Claude与GPT分级体系的深度梳理
后端·python
k4m7v2pz4 小时前
用中文编程语言写游戏:玄铁语言生命游戏的 macOS 适配实录
游戏·macos·玄铁·生命游戏·中文编程语言·玄铁中文编程
阿狗童鞋4 小时前
SpringBoot微服务实战指南
spring boot·后端·微服务