上篇文章我们实现了《太空大战》玩家飞机和敌机的绘制和移动,本篇文章将实现《太空大战》v1.1.0版本:实现玩家发射子弹。
本文在上篇文章最终代码的基础上进行迭代。
导入inpututil包
在本节课中,我们需要使用 inpututil 包中的 IsKeyJustPressed 函数判断是否按下了X键,因此我们需要在 main.go 文件中导入 inpututil 包,如下所示:
import (
"github.com/hajimehoshi/ebiten/v2/inpututil"
)
创建子弹相关常量
在本节课中,我们需要创建子弹相关的常量,如下所示:
const (
bulletWidth = 5
bulletHeight = 15
bulletSpeed = 3
)
创建子弹结构体
首先,我们创建子弹结构体,如下所示:
// Bullet 结构体表示子弹
type Bullet struct {
x, y float64
active bool
}
Bullet结构体包含两个字段:x和y分别表示子弹的x和y坐标,active表示子弹是否处于激活状态。
注意:坐标原点在屏幕左上角,x轴向右增长,y轴向下增长。
使用切片维护玩家发射的所有子弹
接下来,我们给Game结构体添加一个切片维护玩家发射的所有子弹,如下所示:
// Game 结构体表示游戏
type Game struct {
player Player
enemies []Enemy
bullets []Bullet
}
在Update方法中处理玩家发射子弹
在 Update 方法中,我们添加如下代码:
// Update 更新游戏状态
func (g *Game) Update() error {
...
// 处理射击
if inpututil.IsKeyJustPressed(ebiten.KeyX) {
g.bullets = append(g.bullets, Bullet{
x: g.player.x + playerWidth/2 - bulletWidth/2,
y: g.player.y - bulletHeight,
active: true,
})
}
...
}
上述代码中,我们使用 inpututil.IsKeyJustPressed 函数判断是否按下了X键,如果按下了X键,则创建一个子弹,并将其添加到bullets切片中。
接下来我们还需要在 Update 方法中处理子弹的移动,如下所示:
func (g *Game) Update() error {
...
// 更新子弹位置
for i := range g.bullets {
if g.bullets[i].active {
g.bullets[i].y -= bulletSpeed
if g.bullets[i].y < 0 {
g.bullets[i].active = false
}
}
}
...
}
上述代码中,我们使用 range 关键字遍历 bullets 切片,如果子弹处于激活状态,则将其y坐标减去子弹速度(子弹由下往上移动),如果子弹y坐标小于0,则将其激活状态设置为false,表示子弹已经消失。
在Draw方法中绘制子弹
在 Update 方法中处理子弹的状态后,我们还需要在 Draw 方法中根据子弹的状态绘制子弹,如下所示:
// drawBullet 绘制子弹
func (g *Game) drawBullet(screen *ebiten.Image) {
for _, bullet := range g.bullets {
if bullet.active {
bulletRect := ebiten.NewImage(bulletWidth, bulletHeight)
bulletRect.Fill(color.RGBA{255, 255, 255, 255})
bulletOpts := &ebiten.DrawImageOptions{}
bulletOpts.GeoM.Translate(bullet.x, bullet.y)
screen.DrawImage(bulletRect, bulletOpts)
}
}
}
// Draw 绘制游戏画面
func (g *Game) Draw(screen *ebiten.Image) {
// 绘制背景
screen.Fill(color.Black)
//绘制玩家
g.drawPlayer(screen)
//绘制敌人
g.drawEnemy(screen)
//绘制子弹
g.drawBullet(screen)
}
上述代码中,我们将子弹的绘制封装在 drawBullet 方法中,然后在 Draw 方法中调用 drawBullet 方法绘制子弹。在 drawBullet 方法中,我们使用 range 关键字遍历 bullets 切片,如果子弹处于激活状态,则根据子弹的坐标 (x, y) 绘制一个白色的矩形表示子弹。
运行v1.1.0版本
到这里,我们已经实现了《太空大战》v1.1.0版本,下面我们打开集成终端,输入如下命令运行:
leicw@CodeAI世界:code003$ go run main.go
运行成功后,我们按下X键发射子弹,如下图所示:

到这里,我们完成了玩家发射子弹的功能。当然,目前玩家发射的子弹还不具备击毁敌机的功能,我们将在下篇文章中通过碰撞检测实现击毁敌机,敬请期待!
如果遇到问题,欢迎在评论区留言。如需获取更多精彩内容,可以关注下方的微信公众号。
900

被折叠的 条评论
为什么被折叠?



