前言

hi,大家好,这里是白泽。今天给大家分享一个 GitHub 9.8k 的 Go 语言 2D 游戏引擎。

https://github.com/hajimehoshi/ebiten

引擎的贡献者依旧在积极维护,是一个兼具学习 & 娱乐的项目!

为此我也用这个引擎写了一个生存游戏: avoid-the-enemies【如下图】:https://github.com/BaiZe1998/avoid-the-enemies

当然详细的游戏设计我还是想再通过下一期文章讲解,这期的内容主要讲解游戏引擎提供的能力,一些官方有趣的 demo,以及以我的开发为例,讲解如何使用这个引擎快速上手开发属于自己的游戏。

avoid-the-enemies 玩法

尽可能存活是你唯一要做的事!

游戏的体验实况已经录制并上传了,欢迎你的关注 B站:白泽talk,QQ群:622383022。

当然,如果您是一位 Go 学习的新手,您可以在我开源的学习仓库:https://github.com/BaiZe1998/go-learning 中,找到我往期翻译的英文书籍,或者Go学习路线,等一系列精彩内容。

有趣的 Demo

在这个游戏引擎的 examples 目录下集成很多的游戏小 demo 以及素材,只要安装了 go 开发环境就能直接编译运行了。

而且它支持跨平台运行的:Win、macOS、Linux、FreeBSD、Android、IOS、Xbox、Siwtch 都不在话下。(支持手柄外设)

Flappy

复刻经典 flappy bird 小游戏,只是鼠鼠实在是太大了,难度指数:5。


粒子效果

酷炫指数:5。

钢琴

娱乐指数:5,午休的时候来一曲吧。

引擎核心流程

由于引擎本身帮助开发者完成了多平台适配,以及最重要的 UI 的渲染,因此开发游戏只需要关注左侧这张图的三个核心方法即可。

整个引擎就是一个循环,这个循环每秒大约可以执行60次,那就是达到了所谓的 FPS 60。

这个循环中要做的事有两件事,一部分写数值,一部分绘制角色。(调用上图左侧的两个 Func)。开发者需要编写 Game 结构体的 Draw 和 Update 函数,然后交由引擎每秒调用大约 60 次。

avoid-the-enemies 拆解

接下来将以我的生存小游戏为例,讲解一下这个游戏引擎的正确打开方式。

绘制游戏窗口

给定一个宽和高,就可以初始化一个游戏窗口,所有的绘制内容都将以窗口的左上角作为 (0, 0),右为x正轴,下为y正轴控制角色位置。

func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
return screenWidth, screenHeight
}

画面绘制

下面以我编写的游戏为例,讲解一下游戏开发流程。

以像素小人的移动来说,只要我在一秒内不断更换连续的像素图片,遍历对应的索引,并绘制连贯动作的角色图片,就能达到动画的效果了

当然在具体的实现时,我们需要去素材网站上下载对应的图片,在并且了解对应图片的像素大小,如上图每个小人是32px*32px,因此为了达到播放跑动的效果,需要通过循环,不断获取子图,然后在一秒内快速替换。

func (g *Game) Draw(screen *ebiten.Image) {
// ...
// 绘制角色
op := &ebiten.DrawImageOptions{}
op.GeoM.Translate(g.player.x, g.player.y)
i := (g.player.count / 5) % frameCount
sx, sy := frameOX+i*frameWidth, frameOY
screen.DrawImage(runnerImage.SubImage(image.Rect(sx, sy, sx+frameWidth, sy+frameHeight)).(*ebiten.Image), op)
// ...
}

数值状态变更

假设需要实现武器每五秒钟刷新,只需要写一个武器生成器,并在 Update 方法中调用,即可得到武器的数据。再配合上述 Draw 方法,将武器渲染出来即可。

// 生成武器
func GenerateWeapon(g *Game) {
if time.Since(g.weaponTimer) > time.Second*5 {
g.weaponTimer = time.Now()
if len(g.weapons) < 2 {
g.uniqueId++
weapon := weaponList[rand.Intn(len(weaponList))]
switch weapon.(type) {
case *MeleeWeapon:
newWeapon := weapon.(*MeleeWeapon).Copy()
// 使用指针类型有拷贝的bug,当两个人获得同一把武器的时候,旋转会draw两次,所以看起来转速快了一倍
g.weapons[g.uniqueId] = newWeapon
g.weaponPosition[g.uniqueId] = f64.Vec2{rand.Float64() * (screenWidth - frameWidth/2), rand.Float64() * (screenHeight - frameHeight/2)}
case *RangedWeapon:
newWeapon := weapon.(*RangedWeapon).Copy()
g.weapons[g.uniqueId] = newWeapon
g.weaponPosition[g.uniqueId] = f64.Vec2{rand.Float64() * (screenWidth - frameWidth/2), rand.Float64() * (screenHeight - frameHeight/2)}
}
}
}
} func (g *Game) Update() error {
GenerateWeapon(g)
return nil
}

比如需要绘制子弹的移动轨迹,可以通过一个 map 记录地图上所有子弹起始位置,目标位置,移动速度,子弹贴图等内容,通过计时器配合 Update 方法每秒多次更新子弹的数据,最后再借助 Draw 方法,完成子弹的绘制,达到子弹移动的效果。

小节

游戏开发可能是很多人小时候的一个愿望,白泽也一样,今天实现了,很有趣很开心~

有更多好的 idea 欢迎积极评论。

我用 GitHub 9.8k 的 Go 语言 2D 游戏引擎写了个游戏的更多相关文章

  1. Git安装配置和提交本地代码至Github,修改GitHub上显示的项目语言

    1. 下载安装git Windows版Git下载地址: https://gitforwindows.org/ 安装没有特别要求可以一路Next即可,安装完成后可以看到: 2. 创建本地代码仓库 打开G ...

  2. GitHub小技巧-定义项目语言

    GitHub是根据项目里文件数目最多的文件类型,识别项目类型.后端项目难免会包含前端的资源,有时候就会被标记成前端语言,因为项目里 css 等文件比较多, 被误识别成css项目. GitHub不提供指 ...

  3. swift语言注册非免费苹果账号iOS游戏框架Sprite Kit基础教程

    swift语言注册非免费苹果账号iOS游戏框架Sprite Kit基础教程 1.2.3  注册非免费苹果账号swift语言注册非免费苹果账号iOS游戏框架Sprite Kit基础教程 免费的苹果账号在 ...

  4. C++学习(三十九)(C语言部分)之 游戏项目(2048游戏)

    /***************************项目 2048**********************c语言编写 图形库制作时间:2019.04.03 准备工具: vs2013 图形库 i ...

  5. C语言编程学习:写的秒速计算四则混合运算项目

    C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构.C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现 ...

  6. C语言编程学习开发的俄罗斯方块小游戏

    C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构.C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现 ...

  7. C语言头文件怎么写?(转载)

    ---恢复内容开始--- c语言头文件怎么写?我一直有这样的疑问,但是也一直没去问问到底咋回事:所以今天一定要把它弄明白! 其实学会写头文件之后可以为我们省去不少事情,可以避免书写大量的重复代码,还在 ...

  8. C语言初级编程实践:2048小游戏

    大部分同学学习C语言编程以后不知道能通过什么样的项目才可以锻炼自己的思维功力,2048相信大家都应该熟悉,不管是手机上还是网页版的相信大家都玩过,这个简单的控制台版本的游戏是我曾经在伟易达上班时一个嵌 ...

  9. Git Github jekyll,gem Liquid模板语言 Markdown

    Git Git教程  常用 Git 命令清单   Git远程操作详解  使用jekyll建立个人网站 Git is a free and open source distributed version ...

  10. github修改仓库项目的语言类型

    github是 采用Linguist来自动识别你的代码应该归为哪一类. 解决方法: 我们可以在仓库的根目录下添加.gitattributes文件: ## 使用 `.gitattributes` 配置文 ...

随机推荐

  1. rabbitmq学习记录

    一.RabbitMQ的概念 RabbitMQ 是一个消息中间件:它接受并转发消息.你可以把它当做一个快递站点,当你要发送一个包裹时,你把你的包裹放到快递站,快递员最终会把你的快递送到收件人那里,按照这 ...

  2. 北京思特奇2023年校招笔试(Java)

    北京思特奇2023年校招笔试(Java) 1.表达式 (short)10/10.2*2 运算后结果是什么类型? 答案:double,浮点数默认是double,自动类型向上转换为浮点数类型 2. ser ...

  3. OpenHarmony社区运营报告(2022年9月)

    篇首语 在开放原子开源基金会.OpenAtom OpenHarmony(简称"OpenHarmony")工作委员会.会员及共建单位和开发者的共同努力下,OpenHarmony在技术 ...

  4. 实践指南:EdgeOne与HAI的梦幻联动

    在当今快速发展的数字时代,安全和速度已成为网络服务的基石.EdgeOne,作为腾讯云提供的边缘安全加速平台,以其全球部署的节点和强大的安全防护功能,为用户提供了稳定而高效的网络体验.而HAI(Hype ...

  5. 使用 K8S 部署 RSS 全套自托管解决方案- RssHub + Tiny Tiny Rss

    前言 什么是 RSS? RSS 是一种描述和同步网站内容的格式,是使用最广泛的 XML 应用.RSS 搭建了信息迅速传播的一个技术平台,使得每个人都成为潜在的信息提供者.发布一个 RSS 文件后,这个 ...

  6. Avalonia下拉可搜索树(TreeComboBox)

    1.需求分析   树形下拉的功能是ComboBox和TreeView的功能结合起来,再结合数据模板来实现这一功能. 2.代码实现   1.创建UserControl集成TreeView控件   2.将 ...

  7. 【鸿蒙千帆起】《钢岚》成为首款基于HarmonyOS NEXT开发的战棋新游

      近日,紫龙游戏旗下BlackJack工作室全新战棋旗舰作品<钢岚>在华为游戏中心首发上线,并宣布<钢岚>完成鸿蒙原生应用开发,成为基于HarmonyOS NEXT开发的首款 ...

  8. 批处理for 的理解及例子

    前言 首先for的代码形式是: for %i in (set) do command 这里面有一些小知识知识点: 比如说i是变量,那么i可以换成其他字符吗?答案是可以的.但是必须是26个字母中的其中一 ...

  9. 使用electron的demo时遇到的错误

    使用electron的demo时的错误 Electron | Build cross-platform desktop apps with JavaScript, HTML, and CSS. (el ...

  10. 力扣287(java&python)-寻找重复数(中等)

    题目: 给定一个包含 n + 1 个整数的数组 nums ,其数字都在 [1, n] 范围内(包括 1 和 n),可知至少存在一个重复的整数. 假设 nums 只有 一个重复的整数 ,返回 这个重复的 ...