<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>游戏编程 on lfkdsk's Blog</title><link>https://blog.lfkdsk.org/tags/%E6%B8%B8%E6%88%8F%E7%BC%96%E7%A8%8B/</link><description>Recent content in 游戏编程 on lfkdsk's Blog</description><generator>Hugo</generator><language>cn</language><lastBuildDate>Thu, 08 Sep 2016 16:04:42 +0000</lastBuildDate><atom:link href="https://blog.lfkdsk.org/tags/%E6%B8%B8%E6%88%8F%E7%BC%96%E7%A8%8B/index.xml" rel="self" type="application/rss+xml"/><item><title>如何处理游戏中的碰撞事件</title><link>https://blog.lfkdsk.org/how-to-solve-co/</link><pubDate>Thu, 08 Sep 2016 16:04:42 +0000</pubDate><guid>https://blog.lfkdsk.org/how-to-solve-co/</guid><description>&lt;blockquote>
&lt;p>作者 ：&lt;a href="https://github.com/lfkdsk">刘丰恺&lt;/a>&lt;/p>
&lt;p>作者博客：&lt;a href="https://lfkdsk.github.io/">若梦浮生&lt;/a>&lt;/p>
&lt;p>转载需征得作者本人同意&lt;/p>
&lt;/blockquote>
&lt;p>之前试着在Android平台封装了一个轻量级的游戏开发框架&lt;a href="https://github.com/lfkdsk/JustWeEngine">JustWeEngine&lt;/a> ,因为是轻量级的所以也没想太多，很多地方的处理都不太够，比如关于碰撞事件的处理，就是一个简单的On2的遍历，前一阵还被吐槽了233333。&lt;/p>
&lt;p>其实优化On2碰撞的思路是一而贯之的，就是不去处理根本不可能撞在一起的对象。所以就文章讨论一下我了解的在游戏开发中经常被使用的碰撞机制。&lt;/p>
&lt;h2 id="示例图">示例图&lt;/h2>
&lt;p>&lt;img src="https://blog.lfkdsk.org/how-to-solve-co/bird.jpeg" alt="bird">&lt;/p>
&lt;p>图示是使用了四叉树进行碰撞判断的一个图示，变成紫色的是从四叉树中拿取的离我最近的可能碰撞对象，这里我们只需要处理最近的四个对象就可以了，这个demo感谢&lt;a href="https://github.com/icela/FriceEngine">FriceEngine&lt;/a>的demo。&lt;/p>
&lt;h2 id="物体分组">物体分组&lt;/h2>
&lt;p>对Engine所加载的对象进行分层处理，每层维护一个对象列表，对可能根本不需要进行碰撞处理的对象不去处理，不会发生碰撞的层也不去处理，这样我们的O2的复杂度没变，但是我们减少了很多无用的碰撞对象，而我们想要他们碰撞也可以非常简单的切换。&lt;/p>
&lt;p>我在JustWeEngine里面就试着用了物体分组的方式&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">enum&lt;/span> LayerType {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Button,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Default
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">interface&lt;/span> &lt;span style="color:#a6e22e">LayerListener&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">boolean&lt;/span> &lt;span style="color:#a6e22e">Touch&lt;/span>(MotionEvent event);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">Collision&lt;/span>(BaseSub baseSub);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">Update&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">Draw&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">protected&lt;/span> LayerType layerType;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">protected&lt;/span> String layerName;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Layer的刷新范围也是绘制范围&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">protected&lt;/span> Rect layerField;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">protected&lt;/span> Screen layerScreen;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#a6e22e">Layer&lt;/span>(LayerType layerType, Screen layerScreen, Rect layerField) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">this&lt;/span>.&lt;span style="color:#a6e22e">setLayerType&lt;/span>(layerType);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">this&lt;/span>.&lt;span style="color:#a6e22e">layerField&lt;/span> &lt;span style="color:#f92672">=&lt;/span> layerField;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">this&lt;/span>.&lt;span style="color:#a6e22e">layerScreen&lt;/span> &lt;span style="color:#f92672">=&lt;/span> layerScreen;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>通过引入Layer的概念，把不同的对象放到不同的组里面，分别进行碰撞处理。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">private&lt;/span> ArrayList&lt;span style="color:#f92672">&amp;lt;&lt;/span>Layer&lt;span style="color:#f92672">&amp;gt;&lt;/span> e_layers;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">interface&lt;/span> &lt;span style="color:#a6e22e">ScreenListener&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">Init&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">Load&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">Update&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">void&lt;/span> &lt;span style="color:#a6e22e">Touch&lt;/span>(MotionEvent event);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>然后在&lt;code>Screen&lt;/code>类里面就不再处理碰撞事件，而是统一的在Layer中进行处理。&lt;/p></description></item></channel></rss>