当前位置: 首页 > news >正文

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

游戏启动后,效果如下所示:

在这里插入图片描述

到这里,我们完成了子弹击毁敌机并且简单实现了得分功能。下篇文章我们将实现敌机发射子弹攻击玩家的功能,敬请期待!

如果遇到问题,欢迎在评论区留言。如果您觉得本文对您有帮助,期待您的分享点赞

推荐阅读

  1. 十分钟带你入门Go语言(Golang)开发
  2. 如何修改powershell命令提示符PS1,打造Linux风格的命令提示符
  3. 互联网、因特网和万维网傻傻分不清,一文带你彻底理解计算机中的各种网络
http://www.dtcms.com/a/541033.html

相关文章:

  • 学习FreeRTOS(FreeRTOS移植到STM32F103C8T6)
  • json缩放 json 缩放
  • maxkb部署,版本升级步骤与注意事项(超详细图文)
  • 测试开发话题02---概念篇
  • 网站建设推广优化排名全国工商核名查询系统官网
  • ASP Content Linking
  • 【研究生随笔】Pytorch中的卷积神经网络(1)
  • Android运行项目报错集合
  • 为什么电脑会蓝屏?怎么快速解决电脑蓝屏问题
  • js建设网站html5网站开发价格
  • ESP32学习笔记(基于IDF):OneNET物模型数据交互(控制小灯)
  • JavaScript逆向与爬虫实战——基础篇(css反爬之动态字体实现原理及绕过)
  • 浏览器在请求 js/css 静态文件时,服务器返回了 500 内部错误 500 Internal Server Error
  • CSS 实现酷炫的不规则圆角与斜角边框效果(四种方法详解)
  • 在线网站地图生成器自建购物网站多少钱
  • 网站开发的整个流程一家只做卫生巾的网站
  • xv6-riscv开发调试环境搭建(vscode+ubuntu)
  • 架构兜底五大手段:构建韧性系统的全面防御体系
  • 阿里巴巴有几个网站是做外贸的wordpress 禅意主题
  • 在 `PaddleOCR` 中配置自定义模型(如自己训练的检测/识别模型)
  • 云谷系统网站开发网站备案要收费吗
  • 前端页面初始化加载速度优化方案
  • 【数据库】金仓数据库构建集团化医院全栈信创“全链路解决方案”
  • MATLAB基于自适应动态特征加权的K-means算法
  • 我的Dify OCR 识别发票准确率测试工具
  • 免费域名申请网站大全封面型网站首页怎么做
  • 专业的网站建设化妆品备案
  • 详解使用CodeBuddy解决高难度项目问题
  • Days.js实时更新时间格式文案在切换全局语言之后的方案
  • 网站icp备案时间网站营销网站营销推广