Go语言2D游戏开发入门004:零基础打造射击游戏《太空大战》3
上篇文章我们实现了玩家发射子弹的功能,本篇文章将实现《太空大战》v1.2.0版本:实现子弹击毁敌机的功能。
初探碰撞检测原理
要想实现子弹击毁敌机的功能,我们需要先了解碰撞检测的原理。为了简化碰撞检测的难度,我们将使用游戏对象的矩形边界来进行碰撞检测。

上图中,橙色矩形表示玩家发射的子弹,红色矩形表示敌机。要想判断子弹是否击中敌机,我们只需要判断子弹的矩形边界是否与敌机的矩形边界相交即可。如果相交,则认为子弹击中了敌机。
为了便于理解,我们先讨论一下子弹与敌机不相交的情况,排除这些情况后,剩下的情况就是子弹与敌机相交的情况。
首先来看 X 轴的情况,当子弹的 x 坐标 + 子弹的宽度 < 敌机的 x 坐标和当子弹的 x 坐标 > 敌机的 x 坐标 + 敌机的宽度时,子弹与敌机不相交。
x1+w1 < x2 || x1 > x2 + w2
接着来看 Y 轴的情况,当子弹的 y 坐标 + 子弹的高度 < 敌机的 y 坐标和当子弹的 y 坐标 > 敌机的 y 坐标 + 敌机的宽度时,子弹与敌机不相交。
y1+h1 < y2 || y1 > y2+h2
排除这四种情况后,剩下的情况就是子弹与敌机相交的情况。我们将该碰撞检测过程封装成一个函数,如下所示:
func CheckRectCollision(x1, y1, w1, h1, x2, y2, w2, h2 float64) bool {return !(x1+w1 < x2 || x1 > x2 + w2 || y1+h1 < y2 || y1 > y2+h2)
}
本文的代码在上篇文章的代码基础上进行修改。
实现子弹击毁敌机的功能
接下来我们实现子弹击毁敌机,并且实现得分的功能。
首先在 Game 结构体中添加一个字段表示得分,如下所示:
// Game 结构体表示游戏
type Game struct {...score int...
}
然后在 NewGame 函数中初始化得分,如下所示:
// NewGame 初始化游戏
func NewGame() *Game {rd = rand.New(rand.NewSource(time.Now().UnixNano()))return &Game{player: Player{x: screenWidth/2 - playerWidth/2,y: screenHeight - playerHeight,},score: 0,gameOver: false,}
}
将碰撞检测函数添加到 main.go 文件中,如下所示:
func CheckRectCollision(x1, y1, w1, h1, x2, y2, w2, h2 float64) bool {return !(x1+w1 < x2 || x1 > x2 + w2 || y1+h1 < y2 || y1 > y2+h2)
}
接着在 Update 方法中,检测子弹与敌机的碰撞,如下所示:
// Update 更新游戏状态
func (g *Game) Update() error {...// 检测子弹与敌人的碰撞for i, bullet := range g.bullets {if !g.bullets[i].active {continue}enemies := make([]Enemy, 0, len(g.enemies))for _, enemy := range g.enemies {if CheckRectCollision(bullet.x, bullet.y, bulletWidth, bulletHeight,enemy.x, enemy.y, enemyWidth, enemyHeight) {g.bullets[i].active = falseg.score++} else {enemies = append(enemies, enemy)}}g.enemies = enemies}...
}
上述代码中,我们使用了 for range 语句遍历 g.bullets 数组,并使用 CheckRectCollision 函数检测子弹与敌机的碰撞。如果碰撞,则将子弹的 active 字段设置为 false,表示子弹被销毁,并且将得分加1,否则将敌机添加到 enemies 数组中(没被添加的敌机相当于被击毁了)。
最后在 Draw 方法中,绘制得分,如下所示:
// Draw 绘制游戏画面
func (g *Game) Draw(screen *ebiten.Image) {...// 绘制分数ebitenutil.DebugPrint(screen, fmt.Sprintf("Score: %d", g.score))...
}
最后使用如下命令运行游戏,如下所示:
leicw@CodeAI世界:code003$ go run main.go
游戏启动后,效果如下所示:

到这里,我们完成了子弹击毁敌机并且简单实现了得分功能。下篇文章我们将实现敌机发射子弹攻击玩家的功能,敬请期待!
如果遇到问题,欢迎在评论区留言。如果您觉得本文对您有帮助,期待您的分享和点赞!
推荐阅读
- 十分钟带你入门Go语言(Golang)开发
- 如何修改powershell命令提示符PS1,打造Linux风格的命令提示符
- 互联网、因特网和万维网傻傻分不清,一文带你彻底理解计算机中的各种网络
