THOMAS热评:好吧。 嗨,大家好。 我托马斯热闹。 本次研讨会将是 编写使用SDL用C 2D游戏。 所以我知道你们都 问:是的,我真的 要玩游戏和做游戏, 但是这是什么SDL公司吗? 因此,SDL是一个C库。 它代表的是简单 Directme​​dia层。 它是一个跨平台, 游戏开发库。 它可以在Windows,Mac, Linux的,甚至是iOS和Android。 它处理之类的东西 访问音频系统 为计算机,键盘,和 鼠标,游戏杆,如果他们连接。 在手机上,它甚至可以做 触摸输入和所有的。 当然,它处理图形, 拉东西到屏幕上。 所以这是非常广泛的应用,即使 你可能没有听说过。 它的建成,例如 Valve的Source引擎, 其中的权力游戏,如 门户和团队要塞2。 它也是在一个非常大的数 对独立游戏出来, 所以我很高兴能看到你 一切都将使得它。 本次研讨会的目标是让你 着手与SDL发展。 我们要学习如何 创建一个游戏窗口。 我们要创造的精灵, 这是在你的游戏影像 可左右移动。 我们要学习如何 以和动画精灵, 所以移动它们,使 他们随时间改变。 我们要学习如何 捕获的键盘和鼠标 从计算机输入。 我们不会说话 今天是3D图形, 因为这是一个非常复杂的 主题,我们没有时间了。 我们不会学习如何 在我们的游戏播放音频。 我们不会建 任何东西,但Linux操作系统。 现在的告诫有一些, 希望通过年底的研讨会上, 你会舒服 SDL的文档, 这样你就可以去搞清楚 如何播放音频自己。 还建设了Mac或PC应该工作 完全一样的建筑物为Linux, 但安装是怎么回事,以 有点不同。 所以,你应该能够推测 如何做这些事 通过今天的研讨会结束。 所以对于成立,我们将 使用虚拟机。 我们将使用CS50 IDE,因为 我们只是要编写的C. 但是,由于IDE是不是一个浏览器,我们 不能创建新的窗口或显示 图形在其中。 因此,我们需要一个虚拟机。 所以,你可以按照说明进行操作 在这里manual.CS50.net/appliance/15 安装官方CS50家电, 这仅仅是一个Linux虚拟 机。 然后,一旦你有 所有设置up--它 可能需要一点时间,因为 你会非常大download-- 在VM sudo易于得到更新运行。 这是真正回事 更新所有软件 包你的虚拟机上。 在这之后,你要运行 命令和apt-get安装,libsdl2-2.0-0, libsdl2-DBG,libsdl2-dev的,并 此外libsdl2图像-2.0-0, libsdl2图像,DBG, 和libsdl2图像-dev的。 那么是什么呢? 这只是安装调试 信息,文档,页眉, 和二进制文件的两个库。 普通的旧,SDL 2.0, 而另一个库 所谓SDL映像, 我们将使用 加载图像文件转换为我们的游戏。 所以,一旦你也 这,只是当它问, 你只要键入yes,按Enter键 安装这些程序包, 然后,你应该是好去。 因此,要获得分配的代码,你 can--哦,亲爱的,这是不更新。 除非你有GitHub的account-- 如果你有一个GitHub的帐户, 你可以做到这一点的Git 克隆命令回购 并且将下载的Git 回购与它所有的代码, 所以,你必须代码。 如果你没有一个GitHub上 帐户,你应该做的是类型 wgithttps://github.com/tlively/sdl seminar--这里是different-- /archive/master.zip。 如此反复,这是完全一样的 URL,它除了将是 tlively / SDL_seminar / master.zip和 您正在使用wgit下载的。 然后你就可以只 解压缩该存档 然后你就会有 所有的源代码。 所以,我们对此深感抱歉。 然后将代码也将在主办 在一对夫妇的CS50研讨会的网页 天。 好吧。 那么,我们如何开始 编写我们自己的游戏? 好了,第一件事 我们要想做的事情 是看SDL文件。 因此,这里的虚拟机。 而这里的网页。 我已经浏览到生活libsdl.org。 我打算在这里做的是去了 侧边栏,下文件, 并点击维基。 这将使我的维基 拥有最让SDL的文档。 在侧边栏上的在这里,我们 要点击的API类, 因为是要给 我们一个很好的分类视图 为SDL整个API的。 因此,例如,我们有 基本的初始化 并关闭,所有的排序 使用SDL管理的东西, 然后我们有一节 显示的东西到屏幕上。 这是视频。 输入事件,这让 从键盘输入, 来自鼠标获取输入,并 操纵杆,如果你甚至有它。 还有力反馈的东西 如游戏控制器, 我们不会谈论。 而这里的声音。 然后还有一大堆其他的 东西,SDL能为你做。 不过今天我们要重点 在初始化这里, 在视频显示图像 部,和处理输入事件。 所以这些是主要 文档章节 你应该担心。 只是为了好玩,如果我们去了 这里的名字点击API, 我们可以看到每一个列表 在SDL库单一的事情。 因此,所有这些功能,枚举, 结构,东西疯狂的数额, 按字母顺序。 而且很显然,直到 你知道你在做什么, 这不会是太大的帮助, 这就是为什么我们的API类。 所以,让我们开始吧。 希望你已把 下载分发代码。 所以你可以做的是,对 这里在CS50器具, 只需打开一个终端。 开始了。 所以,我已经下载了 使用的是.zip分布码 方法。 而且我解压缩它。 所以,在这里它是在SDL研讨会主人。 所以,我要进入该目录。 而我们在这里看到的是什么 我们有七C文件。 并且这将代码 我们要寻找今天。 我们有一个Makefile文件。 我们有一个资源目录, 它简单地具有图像 你会看到很快。 因此,让我们打开这些文件 使用G-编辑的编辑器。 所以我想打开所有文件 首先打招呼,以.c结束。 开始了。 所以这是一个很小的窗口,所以我们 要尝试做出更大。 不,它就走了。 好吧。 因此,这里的第一个 文件我们要关注一下。 这就是所谓的hello1_sdl.c。 而这一切确实是初始化SDL 库,这样我们就可以开始使用它。 你怎么知道来 与此代码自己? 那么,如果我们查看 在文档 我们进入初始化 并关闭部分, 它会告诉我们一切 有关如何初始化SDL。 所以肯定阅读一些其他的时间。 它会告诉你一切 什么是怎么回事。 但问题的主要症结是, 我们需要调用这个函数SDL在这 并把它传递什么样的东西 我们希望库初始化。 因此,在我们的例子中,我们只是 初始化视频现在, 这样我们就可以开始显示图像。 在这里,你可以看到,如果 我们点击一​​个SDL在里面,我们 可以得到更多的信息, 包括返回值。 因此,我们在这里看到,这 returnes零上的成功。 因此,在我们的代码,我们将 见,如果它不返回零, 如果它不返回 零,所以并不成功, 那么我们要简单地打印 使用该其他函数的误差, SDL得到错误,它返回一个字符串 描述所发生的错误。 我们要打印 错误,然后我们只是 要退出程序 错误代码。 然后,我们需要另一件事 做的是,程序退出前, 如果我们成功初始化SDL, 我们只需要调用它SDL退出。 这是怎么回事处理清理 所有我们SDL的内部资源。 因此,文档那里 - 再次, 在这里我们是在初始化 并关闭部分 的文件。 您只需点击 功能在这里,SDL退出, 你可以阅读所有关于这一点。 而很多这些功能 文档页面 有示例代码,所以这 是非常好的资源。 肯定花一些时间 阅读维基的部分 如果你打算怎么办 本作的一个项目。 好吧。 所以这是我们的整个程序。 我们现在可以is--我做 要在这里打开makefile文件, 所以我打算拿 看看是如何工作的。 这是一个非常简单的makefile, 类似于您以前见过。 其中一个主要的差别 的是,在这里,这 将要插入的运行的结果 这个命令,你已把 如果你已经安装了SDL安装。 这是一个命令 那将产生 一些额外的标志编译。 除此之外,我们给它 所有常用的命令,以及 这两个命令。 因此,-lsdl2图像手柄 连接在SDL的图片库。 而-lm实际处理链接 在标准C数学库。 因此,我们不会需要 那些为我们所有的C文件, 但我们只是把它们使我们能 使用相同的Makefile的一切 没有修改。 在这里人士透露, 这是你会 把你要去的文件 编译为您的项目。 但是,由于每一位我的C 文件在这里有一个主要功能, 它会感到困惑 如果我们把他们全押。 所以我要去只是说, 现在,hello1_sdl.c, 这是我们刚刚看到的一个。 所以,如果我回去了 在这里,我可以做到让。 而它所做的是它只是 编译的第一个文件。 然后我们可以键入./game,因为 这是它产生的可执行文件。 和所有它所做的就是打印 初始化成功。 所以,我们做了正确的事情。 但是,这是一种无聊, 因为我们没有看到一个窗口, 什么也没有走动。 如此之大,我们得到了SDL初始化。 现在,让我们继续前进的东西 更有趣一点。 所以在这里,我们有hello2_window.c,和 这将是一个稍微 复杂的C程序 SDL初始化像以前一样, 但现在我们也将 初始化SDL计时器。 而这将让我们 访问内部计时器 和使用功能与时间。 然后让我们来看看这儿吧。 我们要做的就是,我们有这个指针 到SDL窗口结构,其中 将是此调用创建 的功能,SDL创建窗口。 现在,这需要大量的参数, 让我们去看看文档。 所以,再一次,我要去 按类别API,我 下到视频这里,和第一 部分,显示窗口管理。 因此,这部分有 它一吨的东西, 但是,如果你去翻 这些功能,你会 看到,可能是一个大家 想被称为SDL创建窗口, 这恰好是正确的上方。 所以这是 文档此功能。 窗口的将有一个标题, x和y位置在屏幕上, 这将有宽度,高度, 然后它会采取一些标志。 现在,我们并不真正关心 所有这些标志的权利, 但是,如果你想干的事 就像做一个全屏幕的窗口, 你可以看看那个。 现在,我们只是 使用这些特殊值, SDL窗口以及中心 为x和y,以 刚刚创建窗口 在我们的屏幕的中央。 所以,这就是那个在做什么。 如果窗口恰好是 空,这意味着有错误, 话又说回来,我们只是要 打印使用SDL得到错误的错误。 然后,因为我们初始化 SDL,我们现在需要将其关闭。 所以我们称之为SDL之前退出 返回一个用于为主。 因此,我们有这个窗口有望打开。 而我们要去 做的是我们要去 呼吁SDL为5000毫秒, 这是相同的五秒钟。 当我们与完成后, 这将销毁窗口, 清理SDL库​​, 和退出程序。 因此,让我们继续前进,并给了一个镜头。 所以现在,而不是改变 makefile文件每一次, 我根本就做,而且 然后在命令行上, 说的来源等于再 我们编译的文件。 所以这是hello2_window.c。 太棒了。 没有误差修改。 现在,如果我们运行的可执行文件, 我们看到这个窗口。 现在也有一些 问题的窗口。 我们可以移动它,但它有 它里面这种背景下的垃圾。 所以,我们还没有得出 任何东西,所以它的 刚刚满垃圾,哪 几乎是我们所期望的。 此外,我们不能关闭窗口。 我按在该X 角落里,什么也没有发生。 所以我们会看到如何修复 在一点点。 因此,让我们修正了部分地方 窗口充满垃圾第一。 因此,如果我们去到hello3_image.c什么 我们可以看到的是,我们已经添加了一些 这里更多的东西。 我们已经添加了这个新头 文件以获取定时器功能。 我想我们做了,在过去 之一,也和我没有提到它。 但是现在因为我们是 处理图像, 我们需要包含SDL 图像头文件中。 所以这是同样的事情, 之前,这里初始化SDL, 同样的处理创建窗口。 我们已经看到过了。 现在,我们需要创建一些所谓的 渲染,有点其中随之而来 与窗口。 但它是一个排序 抽象的对象是 负责做这一切的 绘制操作的窗口。 它实际上相当于 要加载的程序 成在图形硬件的 计算机或您的手机或什么的。 因此,我们希望标志通过它 - 你可以看一下文档 以获得更多的细节这里 - 要 将SDL渲染加速,这 意味着它的将是 使用图形硬件 而不仅仅是模拟软件。 我们要使用 SDL渲染PRESENTVSYNC。 VSYNC是一个东西,只是使 图形看起来更好,防止 这个东西叫做屏幕 恐怖,有一半 一帧和一半的下一个的 帧的同时被绘制 它看起来可怕。 但同样,你可以去阅读 关于你自己的。 所以,我们在这里有一些标志。 因此,我们正要打电话 这个功能SDL打造渲染器。 我们要去给它的窗口 与该渲染器相关联。 负一层是指我们不关心什么 显卡驱动程序,我们要使用。 所以这应该差不多 永远是负面的, 除非你知道的图形驱动程序。 然后,我们正要 通过它我们的标志。 所以,如果返回null,则我们 要打印错误像往常一样, 但我们也要去 销毁窗口 之前清理这些资源 调用SDL退出并返回。 现在,有趣的部分在这里 是我们载入我们的形象 使用此功能IMG_load。 这就是我们要的唯一功能 从SDL图像库使用。 这是我们所需要的只有一个。 这是一个函数,该函数的字符串 即任何图像资源的路径。 而且它可以是一个的.png,一个GIF, 位图,这些事情。 这就是为什么这个功能是太好。 它可以处理几乎任何格式。 它加载到内存中,并将其存储 作为一个东西被称为SDL表面。 现在的SDL表面仅仅是一个结构 表示在存储器中的图像数据。 所以,你可以阅读更多关于 该文件2英寸 如果这样的错误,那么我们 要做到整个事情的地方 我们打​​印错误,关闭我们的 资源,然后退出程序。 现在,有趣的是,前 我们可以得出这样的形象窗口, 我们需要真正使纹理。 现在,纹理对应 要加载的图像数据 成图形的硬件的存储器。 这样的表面是在主 内存,常规内存 我们一直在使用的所有学期, 和纹理在这个独立的VRAM 内存显卡控制。 因此,我们调用这个函数 SDL_CreateTextureFromSurface。 我们给它我们的渲染器和我们的面。 然后,我们实际上 与表面完成的, 所以我们只是要释放它。 我们不需要它了。 然后,因此,如果此调用 误码和返回null, 那么我们要做到全 错误再次报告的事情。 好吧。 在这里,我们遇到了一些 实际的渲染功能。 因此调用SDL_RenderClear 并将其传递 与我们的窗口相关联的渲染 只是使窗口走到黑。 因此,将删除该垃圾,我们看到了 我们的窗口前,并使其变黑。 然后我们要去 打电话SDL_RenderCopy, 给予我们的渲染器,我们的纹理。 我们将谈论什么 这些领域都在一个位。 但是,这会 取纹理数据 并复制到我们的 窗口绘制图像。 因此,我们已经做了这个副本之后 将数据放置到我们的窗口, 我们必须做到这一点额外的功能 所谓SDL_RenderPresent。 这是有趣的 因为这得到 到称为双缓冲主题。 因此,双缓冲是一种技术, 让你的图形看起来好了很多。 再次,它阻止了屏幕撕裂 我早先提到,在那里 你有两个缓冲区。 有在后台缓存 存储器和前缓冲器。 前缓冲区是字面上 什么是你的屏幕上的时刻。 所以,我们做所有这些画的变化, 就像SDL渲染复制或SDL_RenderClear 到后台缓冲区。 因此,他们修改的东西 在后面的缓冲区。 在这里,我们可能会借鉴这种 绿化广场到后台缓冲区。 于是,当我们完成做 我们的渲染操作,这 可能需要很长的 一次,我们要怎么做 是切换缓冲器。 因此,它确实只是需要的 前台缓存和后缓冲器 和交换机他们,所以 即,瞬间, 在一个操作中,而不是 也许成百上千, 我们所有的新渲染 对象是在屏幕上。 这样可以防止事情 像画面清爽 当我们只抽一半 我们为框架的对象。 所以这就是为什么我们需要调用 SDL_RenderPresent,以及 作为SDL_RenderCopy。 同样,我们只是 等待五秒钟。 然后,我们将 清理我们的资源。 我们有相当多的越是这个时候。 然后,我们正要 退出程序。 因此,让我们做到这一点。 我要键入make,然后来源 等于hello--这是现在3image.c。 好吧,那编译没有错误。 你可以在这里看到我现在已经 拉出我的形象,您好,CS50! 我们的窗口,其中 五秒钟后消失。 现在,这仍然有问题,对不对? 这不是一个很好的应用, 因为当我尝试关闭该窗口, 什么都没发生。 x是仍然没有反应。 所以,让我们一起来看看 下一个文件,hello4animation。 因此,这是该文件 这是怎么回事介绍 移动和运动,我们的形象。 所以,我们要做的 同样的事情之前, 启动SDL,创建 窗口中,创建渲染器, 加载图像成 内存,打造质感。 我们之前已经看到了这一切。 现在,这是新的。 我们要呼吁的结构 SDL的矩形,这仅仅是一个矩形。 如果我们在这里,我们可以 做一个搜索SDL RECT, 你可以看到这是一个 结构非常简单。 它有一个X,A Y为 的位置,并且它 具有宽度和高度为 矩形的尺寸。 所以,我们要做的是我们 要定义这个SDL RECT DEST, 为目的地。 这是地方 屏幕里的 我们将在其中进行绘制 我们的形象,对这样 如果我们将要 围绕移动图像, 那么目标在哪里 我们要绘制图像 需要走动。 所以,我们要调用这个 功能SDL_QueryTexture。 而注意到我传递的地址 dest.w的,这是宽度, 和dest.h,这是高度。 因此SDL_QueryTexture是怎么回事 存储在这些领域的宽度 与我们的纹理的高度。 然后我要去 做的是我要去 设置dest.x为窗口 宽度减去dest.w,这是 精灵的宽度除以2。 这是要设置,使 该图像是完全居中 在我们的窗口,没事吧? 所以,现在我有一个y位置。 而这将 是一个变量,它是 不断变化的,因为我们将要 移动所述图像在y方向。 现在我们有一些 被称为动画循环。 那么,如何在动漫作品? 那么,人眼可以检测到12个不同的 在每一秒的图像,没事吧? 如果你刷12的图像卡我这么 在第二个,我看到每个这些图像 作为它的独特的个人的图像。 现在,如果你闪更多 我的第二图像, 然后我的眼睛会启动 模糊在一起 我会认为它是运动, 代替一个鲜明的图​​像。 因此,例如,电影和电视, 他们闪烁的图像,在你24倍 一秒。 所以这是每秒24帧。 计算机屏幕,在另一方面, 常常是每秒60帧。 这是他们的刷新速度。 这是他们经常刷新 画面在屏幕上。 因此,我们的目标将是60 每秒为我们的游戏框架。 因此,让我们看到,在代码中。 因此,对于每一帧,我们是第一 要清除窗口。 这是一般模式。 你总是清除 窗口中的每个帧,然后 做你的绘图 操作,然后在结束, 做RenderPresent显示 中的所有帧。 然后,你要 有一个等待的结束 要等到下一个 框架应该开始。 所以,如果我是做了很多 复杂的计算这里 这花了超过16毫秒, 这将是对我来说是不可能的 得到60的帧速率 我想,因为每帧 时间太长来计算。 此外,我们真的做的 排序工作的一个可忽略的量 在这里,因为只有 有一件事我们正在绘制。 所以,我只是等待的1/60 第二,它是长度 在帧之间的帧的。 排序所以我假装做 我所有的工作都为零时。 但是,在一个真正的游戏, 你必须减 的时间量花费做 所有这些工作从您的休息时间。 所以无论如何,我是什么 其实在做这个循环? 我清楚的窗口。 我设置了dest.y,这是一个int到 我的实际y位置浇铸成一个int。 现在,我想飘分辨率 在我的游戏我的y位置, 但实际 绘制到屏幕上, 它需要整数,因为它是在单位 像素,所以这是中投是什么。 我要绘制图像。 因此,这是源矩形。 这是目标矩形。 所以,我通过空的 源矩形 说我要画我的整个纹理。 但是,如果你有很多的 在你的游戏贴图 而且他们都在一个大的纹理贴图 被装入的SDL仅作为一个 纹理,你可以 使用源矩形 挑的更小的纹理之一, 的小精灵之一, 指出,大纹理贴图的。 所以,再一次,我路过我的呈现,我 纹理,现在的目标。 这将在其中是 窗口它会被绘制。 然后,因为我的动画 什么,我需要运动, 我将要更新 每一帧精灵的位置。 所以,我有这个常数叫做滚动 速度在每秒的像素单元。 现在,每次我们做一个动作, 该帧是只有1/60秒。 所以,我要除以60。 然后,让我们来看看,我 减去从y位置。 为什么我减去? 我们会得到,在第二。 于是我收拾我的资源 并且该程序已经结束了。 因此,让我们做的。 因此,让我们进入化妆SRCS = hello4 animation.c的,没事吧? 游戏。 你去那里。 所以我把它滚动起来 窗口,这是非常整洁。 但是且慢,我被减去 从每次y位置。 这是怎么回事呢? 嗯,事实证明,在SDL,和 事实上,在大多数计算机图形学, 的原点的坐标系统 是窗口的左边顶部。 因此,正x方向运行 在你的右侧窗口。 和正y方向 实际上下降。 如此反复,原产地在 你的窗口的左上方, 正y方向是向下, 和正x是向右。 所以,当我从减 y位置,这是 打算让他走在负 y方向上,这是向上的窗口。 所以,这是怎么回事那里。 凉。 让我们来看看下一个文件。 下面是部分 展现在我们终于 获取的X窗口的一角 这是应该关闭窗口 上班。 发生什么了? 我们初始化SDL,创建窗口, 创建渲染器,加载图像, 创建纹理 就像我们以前看到的。 我们有相同的目标矩形 和以前一样,同一个呼叫查询质感。 但是这一次,我们再 将要划分的宽度 和由4我们的目的地的高度。 这不仅具有的效果 扩展我们的形象下来的时候 我们四个在窗口中显示出来。 所以这是相当整洁。 我们可以只规模就这样。 我们将启动精灵 在屏幕的中心。 而现在我们有x和y的速度和 他们都将从零开始。 这是错误的文件。 对不起。 所以,这一切真的。 这是所有仍然在这个文件中。 我们拥有的4分和一切。 所以在这里,我们有我们的x和y位置 为窗口的中心。 我们给它一个初始速度 这个常数速度,这 我相信是每秒300像素。 现在,我们有这个中断也可以同样 是所谓的亲密要求布尔值。 并且,而不是做一个 上的计时器无限循环在这里, 我们将要动画作为 只要靠近不要求。 那么,我们如何处理事件? 那么,SDL排队的事件 幕后文字队列。 然后将每个帧, 我们可以出队事件 使用该队列 此调用SDL_PullEvent。 再次,肯定会去阅读 关于此的文档。 有很多更多的细节和大量的 更多的功能,你可以用这个使用。 我们通过它的地址 这件事情,SDL_Event 我们这里在栈上。 现在,什么是SDL_event? 由于SDL,如果我们看在 该documentation--我们 看,API按类别,输入 的事件,事件处理, 我们可以看一下数 这里的不同事件 我们可以看到有 整个吨他们。 那么,什么是这个SDL_Event的事情吗? SDL_Event是工会。 哇,什么是联盟? 你可能从未 之前听说过。 这就是确定。 联合是一种像 一个结构,除了一个结构 对所有的空间 其领域和存储器, 而工会只有 足够的空间,以适应最大 其一个字段的,这意味着它 只能存储的领域之一 在一个时间,哪一种 有意义的事件,对吧? 我们可以有一个键盘 事件或窗口事件, 但单个事件不能同时是 键盘事件和一窗口事件, 所以它会是愚蠢的,有空间 这两个我们活动的工会里面。 所以,如果你想 创建自己的联盟​​, 它看起来完全一样 如创建一个结构, 不同之处在于,我们使用union关键字 而不是struct关键字。 请记住,所有的 你的工会里面的东西, 这是工会的实际变量 只能具有这些值中的一个 的时间。 那么,如何才能知道什么样的事件 我们只是弹出此队列中? 好了,我们可以测试Event.type访问。 如果这是相等 到SDL_QUIT,我们知道 它的事件 生成时,我们 打是X窗口的角落。 我们可以设在靠近请求等于1。 剩下的只是一些动画 那你以前见过。 因此,让我们继续前进,使 这一点,看看它如何工作的。 所以,我要键入make和 然后SRCS = hello5_events.c。 在那里,我们走了。 游戏。 现在,我们可以看到它是 的确由四个按比例缩小。 现在是蹦跳着。 我有一些碰撞检测 与窗口的侧面正在进行 我们可以看一看。 当我去关闭它会发生什么? 它关闭。 太棒了。 我们收到了该事件。 我们处理它。 因此,让我们回头看看代码。 因此,如何做,我得到它 蹦跳着这样呢? 还记得我设置x和 Ÿ最初的速度。 和速度是一个积极的 不变的,所以这是 要得到它开始了 下降和向右。 现在,每个帧中,除了处理 可能发生的任何事件, 我要检测是否我的精灵 正试图走出去的窗口。 因此,我们可以做到这一点,只需检查 X_POS 0,Y_POS 0,然后 也X_POS和Y_POS与 窗口宽度和窗口的高度。 请注意,我已经减 精灵的宽度。 这是因为如果我没有 减去精灵​​的宽度, 它只会检查 精灵的起源 没去窗外。 但是,我们希望整个 宽度精灵 永远是在窗口内侧及 精灵的整个高度 永远是在窗口内。 这就是减法是什么。 很多几何可以在这里 是画出来有帮助 在纸面上的坐标 系统看看是怎么回事。 所以,如果我不冲突,我只是 简单复位位置 以便它不会 在屏幕中。 而且我会,如果它反弹 上的侧壁之一, 我要去否定 x速度,以便它 开始弹跳在其他方向。 同样,如果它击中 的顶部或底部, 我要设置Y速度 等于负y速度, 因此,它会弹回来。 所以这是我们刚刚是怎么在这里。 和更新位置 就像我们之前所看到的, 除以60,因为我们是 仅处理1/60秒。 然后渲染, 完全一样之前。 所以这就是一切 这是怎么回事这个文件。 所以这是我们如何做到的事件。 最主要的是要带走这里 这SDL_PullEvent功能。 而且你一定要读 文档更多关于SDL_Event 工会,因为这种数据类型 非常非常重要的,因为我们用它 对于各种事件。 例如,我们使用它的键盘 事件,而这正是该文件是。 那么我们有什么? 我们有同样的事情之前, 初始化SDL,创建一个窗口, 创建一个渲染器,加载图像 到内存中,创建质感。 再次,我们要 有这样的DEST矩形, 我们要缩放图像 四,使它有点小。 现在,我们将启动 精灵在屏幕的中央。 但是这一次,我们要设置 初始x和y速度为零, 因为键盘是 要控制的那些。 进而,我们要 跟踪这些变量 上,下,左,右。 那就是要保持 跟踪我们是否已经 按下键盘的按钮, 对应于上,下,左, 和权利。 现在,这是一种奇特的 因为我们可以用W,A,S, 这里D或实际箭头键。 我们会看到,在短短的一秒钟。 所以,我们要处理 就像之前的事件。 我们拉的事件。 但是,现在我们要 接通事件类型。 如果是SDL_QUIT,我们 要设置关闭 要求之一,就像以前一样。 处理中的x 窗口的角落里, 使我们的窗口中实际关闭。 否则,如果我们得到一个SDL键向下 事件,这意味着我们按下的键, 那么我们要做的是我们 在这里要对这个事情进行切换, 这是指:所以event.key 是指把我们的活动结合, 去拿到钥匙 事件结构在它。 所以,事实证明,这 联合是一个关键的事件结构。 然后去到关键 事件的结构及其场 所谓的键符,然后扫描码。 再次,肯定读 这个文档。 关键字输入挺有意思的。 你可以得到的扫描码或键码。 这是一个有点微妙,但 该文档是相当不错的。 因此,如果我们看到的扫描码 我们的按键是W或向上, 我们要设置为1。 然后我们打破了开关。 如果是A或离开,我们设置左1,等 等等,等等,为向下和向右。 现在,在这个外部开关, 如果我们看到一个重要起来活动, 这意味着我们已经发布了一个关键 而且我们不再按它。 所以我要说起来等于0, 左等于0,下等于0,右 等于0,等等。 并注意我们在每个这些 2箱子摆正彼此相邻 没有单独的代码 对于第一种情况,其中 意味着,无论是 一个S或向下就在这里, 它会执行该代码。 所以这是非常方便的。 这使我们不得不做更多 条件和IFS与事 像那样。 所以,我们要 确定速度。 我们设置的速度为0。 那么,如果达被压 不下来,​​那么我们 设置Y速度为负速度。 记住负的,因为 y轴负方向是向上。 而正y方向是向下。 如果向下压 与不涨,那么我们 将它设置为正的速度, 这意味着下降画面。 同样的事情左右。 然后,我们要更新 就像之前的位置。 我们要做的碰撞 检测与发展, 但我们不会重置 速度,因为速度是刚 由键盘控制。 但是,我们要重新设置 位置,以保持它在窗口中。 而且我们要设置 在结构中的位置 然后做所有的 从之前渲染的东西。 因此,让我们看看会发生什么。 因此,请SRCS--让我们来看看, 这是hello6_keyboard.c。 不好了。 所以,我们得到了一些警告这里。 而这只是说我们没有 检查每一个可能的一种 的事件。 这是确定的,因为 有236人左右。 所以,我要忽视这些警告。 它仍然编译的罚款。 所以,我要玩游戏。 它不动。 但是现在,当我醪我的键盘上, 我可以做一些WASD移动在这里, 我用我的方向键以及。 同时注意,即使我 按正确的,现在, 它不会窗外, 因为我重置的每一帧。 所以这是相当整洁。 你可以围绕马里奥想象移动与 一些箭头键或类似的东西。 是的,在X确实工作。 我们将因此最终文件 看,hellow7_mouse。 这是关于让鼠标输入。 所以在这一块,我们 进口数学头, 因为我们将有 数学一点点在这里。 老一套,炒冷饭,目的地, 老一套,看到过。 嗯,这很有意思。 所以,我们又回到了只检查 为SDL退出事件。 这是为什么? 所以,你可以从事件鼠标输入。 就像当鼠​​标移动, 你得到一个事件的。 当按下鼠标按钮, 你可以得到一个事件的。 但是,还有一个,稍微简单 也许,让鼠标输入API。 而这只是SDL获取鼠标状态。 所以,我有一个int x和 y表示光标位置。 我将它传递给SDL_GetMouseState, 其中规定这些。 这是在位置 协调窗口系统。 所以,如果质量是在左上角 窗口,那会0,0。 现在,我什么都做的是我要去 做矢量数学一点点。 我敢打赌,你以为你不会 看到在CS50,但在这里它是。 我会做一些矢量 数学获得向量 从图像到光标。 所以为什么我有 这个减法吗? 好吧,如果我只是用DEST .--所以 我需要翻译鼠标x 和y由宽度的一半,并 图像的高度, 因为我想的中心 图像将逐步转向鼠标, 图像的不原点。 所以,这只是为了确保我说 绕中心的图像在这里。 然后我们得到增量x和y,其中 是从目标差 到图像的实际位置。 然后我们就可以得到 距离在这里,这 将是毕达哥拉斯 定理,x的平方根 x次加y乘以y。 现在,以防止抖动,而且我可以告诉 你这是什么一样,如果我不这样做, 如果光标和之间的距离 图像中心少于5, 我只是不会移动图像。 否则,我们设置的速度。 我们设置这样的 速度将始终是恒定的。 和所有的最终结果 此数学是图像 是要走向光标。 现在,事实证明, SDL_GetMouseState, 在除了设置 x和这里y参数, 它也返回对应一个int 到的鼠标按钮的状态。 因此,我们不能读取 直接,但我们可以 使用这些宏,单 位运算符,没有那么可怕, 只需按位和。 所以我们说按钮,这是结果 我们SDL_GetMouseState的,如果该 和位和,该宏 在这里,SDL_BUTTON_LEFT。 因此,这是要简单地解决 到对应位图 以鼠标左键被按下。 因此如果按位 并发生和它的 不是零,这意味着 左按钮被按下, 那么,我们实际上是要否定 同时在x和Y速度, 这只会让图像失控。 更新位置。 碰撞检测,看到了 一切之前,渲染,没事的。 让我们做到这一点。 所以,你得让SRCS = hello7_mouse.c。 大。 没有错误。 而且游戏。 所以在这里我有我的鼠标。 并且图像确实是 追我的鼠标。 如今,在游戏中,你做的,也许 这就像一个敌人追 你的小字符或什么的。 但在这里,我们有 像追逐鼠标。 当我点击,鼠标 开始追图​​像 并且图像是 逃离鼠标。 所以,这很酷。 并注意再次,有 还在碰撞检测在这里。 所以这是最后的小 演示中,我已经在这里设立。 让我们来看看一件事。 所以回到这里,我提到的这种抖动。 好吧。 因此,如果距离小于五个像素, 我设置x和y的速度为零。 如果我们摆脱那会发生什么? 所以,我要只是这样做。 请原谅这个可怕的风格, 但是我们注释掉了正确的代码。 所以,我要保存并执行 从之前使其相同的命令。 好吧。 现在会发生什么? 好。 我们还在继 鼠标像以前一样, 但是,当我们得到的鼠标, 我们已经有了这个总抖动。 这是怎么回事呢? 那么,在我们的矢量 数学,还记得我们 服用之间的距离 光标和图像的中心? 那么,作为一个接近 0,我们开始变得 像这种疯狂的行为 其中,图像排序 像光标周围振荡。 这就是创造这种抖动。 这就是真难看。 你可能不 想让你的游戏这样做, 除非它是某种特殊效果。 所以这就是为什么我们有 眼前这个乱 切五个像素关闭,在这里我们说 如果是五年内的像素,我们是很好的。 我们不需要再移动图像。 所以,这是怎么回事那里。 所以这是相当多了。 现在你知道了如何创建 一个窗口,加载图像, 绘制图像窗口,得到 键盘输入,让鼠标输入, 还有一帮其他的 输入你会不会 知道如何,如果你只是花 几分钟看文档。 所以,你实际上有相当 在您的处置,现在一些工具 写一个完整的游戏。 现在,每场比赛都需要一些音频, 但音频文件 也还不错。 我敢打赌,如果 你了解所有的事情 我们谈到了今天 图像,和表面, 窗户,和一切,然后 搞清楚音频API不是 会是那么糟糕。 因此,我期待着看到 您创建了SDL的内容。