【SDL2】簡単な3D衝突検出の解説
このコミットが含まれているのは:
コミット
26559a7940
バイナリファイルは表示されません。
188
gemini/blog.atom
188
gemini/blog.atom
|
@ -3,13 +3,131 @@
|
|||
<id>gemini://technicalsuwako.moe</id>
|
||||
<title>テクニカル諏訪子</title>
|
||||
|
||||
<updated>2024-02-01T00:00:00Z</updated>
|
||||
<updated>2024-02-17T00:00:00Z</updated>
|
||||
|
||||
<author><name>テクニカル諏訪子</name></author>
|
||||
<link href="gemini://technicalsuwako.moe" rel="alternate"></link>
|
||||
|
||||
|
||||
|
||||
<entry>
|
||||
<id>blog/sdl2-easy-collision.gmi</id>
|
||||
<author><name>凛</name></author>
|
||||
<title type="html">【SDL2】簡単な3D衝突検出の解説</title>
|
||||
<published>2024-02-17T00:00:00Z</published>
|
||||
|
||||
<category term="blog"></category>
|
||||
|
||||
<category term="jp"></category>
|
||||
|
||||
<category term="プログラミング"></category>
|
||||
|
||||
<category term="zig"></category>
|
||||
|
||||
<category term="sdl"></category>
|
||||
|
||||
<category term="opengl"></category>
|
||||
|
||||
<category term="ゲーム開発"></category>
|
||||
|
||||
<link href="gemini://technicalsuwako.moe/blog/sdl2-easy-collision.gmi" rel="alternate"></link>
|
||||
<content type="html">
|
||||
|
||||
|
||||
|
||||
<p>最近、自作のゲームを作成していますが、衝突検出を実装する事に懸念を抱きました。<br />
|
||||
しかし、作った後はそんなに難しくないと気づきました。<br />
|
||||
その為、今回はこれについて説明します。<br />
|
||||
記事での利用している言語はZig言語ですが、C言語やC++でも使えます。</p>
|
||||
<h2 id="heading">プログラミングタイム!!</h2>
|
||||
<p>3つのオブジェクトを設置します。</p>
|
||||
<pre><code lang=""><span style="color:#080;font-style:italic">// オブジェクト
|
||||
</span><span style="color:#080;font-style:italic"></span><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>Wall<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">struct</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>x<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span>,<span style="color:#bbb"> </span>y<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span>,<span style="color:#bbb"> </span>z<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span>,<span style="color:#bbb"> </span>size<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span><span style="color:#bbb"> </span>};<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"></span><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>Floor<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">struct</span><span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>x<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span>,<span style="color:#bbb"> </span>y<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span>,<span style="color:#bbb"> </span>z<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span>,<span style="color:#bbb"> </span>size<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span><span style="color:#bbb"> </span>};<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"></span><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>Player<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">struct</span><span style="color:#bbb"> </span>{<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>xpos<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span>,<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>ypos<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span>,<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>zpos<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span>,<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>xsize<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span>,<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>ysize<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span>,<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>zsize<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span>,<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>velocity<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span>,<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>gravity<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span>,<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"></span>};<span style="color:#bbb">
|
||||
</span><span style="color:#bbb">
|
||||
</span><span style="color:#bbb"></span><span style="color:#a2f;font-weight:bold">var</span><span style="color:#bbb"> </span>wall<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span>Wall<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>.x<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#666">-</span><span style="color:#666">6.0</span>,<span style="color:#bbb"> </span>.y<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#666">0.0</span>,<span style="color:#bbb"> </span>.z<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#666">-</span><span style="color:#666">26.0</span>,<span style="color:#bbb"> </span>.size<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#666">6.0</span><span style="color:#bbb"> </span>};<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"></span><span style="color:#a2f;font-weight:bold">var</span><span style="color:#bbb"> </span>floor<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span>Floor<span style="color:#bbb"> </span>{<span style="color:#bbb"> </span>.x<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#666">-</span><span style="color:#666">6.0</span>,<span style="color:#bbb"> </span>.y<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#666">-</span><span style="color:#666">7.0</span>,<span style="color:#bbb"> </span>.z<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#666">-</span><span style="color:#666">26.0</span>,<span style="color:#bbb"> </span>.size<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#666">50.0</span><span style="color:#bbb"> </span>};<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"></span><span style="color:#a2f;font-weight:bold">var</span><span style="color:#bbb"> </span>player<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span>Player<span style="color:#bbb"> </span>{<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>.xpos<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#666">0.0</span>,<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>.ypos<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#666">50.0</span>,<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>.zpos<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#666">0.0</span>,<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>.xsize<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#666">0.2</span>,<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>.ysize<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#666">0.8</span>,<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>.zsize<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#666">0.2</span>,<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>.velocity<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#666">0.1</span>,<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>.gravity<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#666">0.2</span>,<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"></span>};<span style="color:#bbb">
|
||||
</span><span style="color:#bbb">
|
||||
</span><span style="color:#bbb"></span><span style="color:#a2f;font-weight:bold">fn</span><span style="color:#bbb"> </span>draw()<span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">void</span><span style="color:#bbb"> </span>{<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span><span style="color:#080;font-style:italic">// ここは`glBegin`、`glVertex3f`等を設置しますが、長すぎる為、これはスキップします。
|
||||
</span><span style="color:#080;font-style:italic"></span>}<span style="color:#bbb">
|
||||
</span></code></pre><p>上記のコードで、主に「gravity」や「velocity」が大切です。<br />
|
||||
次は衝突検出の関数を作ります。</p>
|
||||
<pre><code lang=""><span style="color:#a2f;font-weight:bold">fn</span><span style="color:#bbb"> </span>checkPosToObj(xpos<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span>,<span style="color:#bbb"> </span>ypos<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span>,<span style="color:#bbb"> </span>zpos<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span>,<span style="color:#bbb"> </span>size<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span>,<span style="color:#bbb"> </span>obj<span style="color:#666">:</span><span style="color:#bbb"> </span>anytype)<span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">bool</span><span style="color:#bbb"> </span>{<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>thresholdX<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span><span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span>size;<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>thresholdY<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span><span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span>size;<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>thresholdZ<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span><span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span>size;<span style="color:#bbb">
|
||||
</span><span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>deltaX<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span><span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#a2f">@abs</span>(xpos<span style="color:#bbb"> </span><span style="color:#666">-</span><span style="color:#bbb"> </span>obj.xpos);<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>deltaY<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span><span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#a2f">@abs</span>(ypos<span style="color:#bbb"> </span><span style="color:#666">-</span><span style="color:#bbb"> </span>obj.ypos);<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>deltaZ<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span><span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#a2f">@abs</span>(zpos<span style="color:#bbb"> </span><span style="color:#666">-</span><span style="color:#bbb"> </span>obj.zpos);<span style="color:#bbb">
|
||||
</span><span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">return</span><span style="color:#bbb"> </span>deltaX<span style="color:#bbb"> </span><span style="color:#666">&lt;</span><span style="color:#bbb"> </span>thresholdX<span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">and</span><span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>deltaY<span style="color:#bbb"> </span><span style="color:#666">&lt;</span><span style="color:#bbb"> </span>thresholdY<span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">and</span><span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>deltaZ<span style="color:#bbb"> </span><span style="color:#666">&lt;</span><span style="color:#bbb"> </span>thresholdZ;<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"></span>}<span style="color:#bbb">
|
||||
</span></code></pre><p>床と壁のサイズ値は1つだけで、プレイヤは3つ(X, Y, Z)がある為、上記を使った方が良いですね。<br />
|
||||
両方のオブジェクトが3つのサイズ値があれば、下記の関数を使っては良いと思います。</p>
|
||||
<pre><code lang=""><span style="color:#a2f;font-weight:bold">fn</span><span style="color:#bbb"> </span>checkObjToObj(a<span style="color:#666">:</span><span style="color:#bbb"> </span>anytype,<span style="color:#bbb"> </span>b<span style="color:#666">:</span><span style="color:#bbb"> </span>anytype)<span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">bool</span><span style="color:#bbb"> </span>{<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>thresholdX<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span><span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span>a.xsize;<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>thresholdY<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span><span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span>a.ysize;<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>thresholdZ<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span><span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span>a.zsize;<span style="color:#bbb">
|
||||
</span><span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>deltaX<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span><span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#a2f">@abs</span>(a.xpos<span style="color:#bbb"> </span><span style="color:#666">-</span><span style="color:#bbb"> </span>b.xpos);<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>deltaY<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span><span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#a2f">@abs</span>(a.ypos<span style="color:#bbb"> </span><span style="color:#666">-</span><span style="color:#bbb"> </span>b.ypos);<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">const</span><span style="color:#bbb"> </span>deltaZ<span style="color:#666">:</span><span style="color:#bbb"> </span><span style="color:#0b0;font-weight:bold">f32</span><span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span><span style="color:#a2f">@abs</span>(a.zpos<span style="color:#bbb"> </span><span style="color:#666">-</span><span style="color:#bbb"> </span>b.zpos);<span style="color:#bbb">
|
||||
</span><span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">return</span><span style="color:#bbb"> </span>deltaX<span style="color:#bbb"> </span><span style="color:#666">&lt;</span><span style="color:#bbb"> </span>thresholdX<span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">and</span><span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>deltaY<span style="color:#bbb"> </span><span style="color:#666">&lt;</span><span style="color:#bbb"> </span>thresholdY<span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">and</span><span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>deltaZ<span style="color:#bbb"> </span><span style="color:#666">&lt;</span><span style="color:#bbb"> </span>thresholdZ;<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"></span>}<span style="color:#bbb">
|
||||
</span></code></pre><p>thresholdはいつでもプレイヤ以外のオブジェクトのサイズとなります。</p>
|
||||
<pre><code lang=""><span style="color:#a2f;font-weight:bold">pub</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">fn</span><span style="color:#bbb"> </span>main()<span style="color:#bbb"> </span><span style="color:#666">!</span><span style="color:#0b0;font-weight:bold">void</span><span style="color:#bbb"> </span>{<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span><span style="color:#080;font-style:italic">// ...
|
||||
</span><span style="color:#080;font-style:italic"></span><span style="color:#bbb"> </span><span style="color:#080;font-style:italic">// 衝突検出
|
||||
</span><span style="color:#080;font-style:italic"></span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">if</span><span style="color:#bbb"> </span>(checkPosToObj(floor.x,<span style="color:#bbb"> </span>floor.y,<span style="color:#bbb"> </span>floor.z,<span style="color:#bbb"> </span>floor.size,<span style="color:#bbb"> </span>player))<span style="color:#bbb"> </span>{<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>std.debug.print(<span style="color:#b44">&#34;床を触って良かった! ypos = {d}</span><span style="color:#b62;font-weight:bold">\n</span><span style="color:#b44">&#34;</span>,<span style="color:#bbb"> </span>.{player.ypos});<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>player.ypos<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span>floor.y<span style="color:#666">+</span>(player.ysize);<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>}<span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">else</span><span style="color:#bbb"> </span>{<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>std.debug.print(<span style="color:#b44">&#34;ああああああ!! ypos = {d}</span><span style="color:#b62;font-weight:bold">\n</span><span style="color:#b44">&#34;</span>,<span style="color:#bbb"> </span>.{player.ypos});<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>player.ypos<span style="color:#bbb"> </span><span style="color:#666">-=</span><span style="color:#bbb"> </span>player.gravity;<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>}<span style="color:#bbb">
|
||||
</span><span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span><span style="color:#a2f;font-weight:bold">if</span><span style="color:#bbb"> </span>(checkPosToObj(plane.x,<span style="color:#bbb"> </span>plane.y,<span style="color:#bbb"> </span>plane.z,<span style="color:#bbb"> </span>plane.size,<span style="color:#bbb"> </span>player))<span style="color:#bbb"> </span>{<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>std.debug.print(<span style="color:#b44">&#34;壁だわ...</span><span style="color:#b62;font-weight:bold">\n</span><span style="color:#b44">&#34;</span>,<span style="color:#bbb"> </span>.{});<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>player.zpos<span style="color:#bbb"> </span><span style="color:#666">=</span><span style="color:#bbb"> </span>plane.z<span style="color:#666">+</span>(player.zsize);<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span>}<span style="color:#bbb">
|
||||
</span><span style="color:#bbb"> </span><span style="color:#080;font-style:italic">// ...
|
||||
</span><span style="color:#080;font-style:italic"></span>}<span style="color:#bbb">
|
||||
</span></code></pre><h2 id="heading-1">結果</h2>
|
||||
<p><video src="https://ass.technicalsuwako.moe/zig-cd.ogv" controls="controls" style="max-height: 400px;"></video></p>
|
||||
<p>ねぇ!簡単でしょ〜!</p>
|
||||
<p>以上</p>
|
||||
|
||||
|
||||
</content>
|
||||
</entry>
|
||||
|
||||
<entry>
|
||||
<id>blog/sp-120.gmi</id>
|
||||
<author><name>凛</name></author>
|
||||
|
@ -345,73 +463,5 @@ SucklessやOpenBSDチームによって作られたソースコードを開く
|
|||
</content>
|
||||
</entry>
|
||||
|
||||
<entry>
|
||||
<id>blog/anti-virus-dangerous.gmi</id>
|
||||
<author><name>凛</name></author>
|
||||
<title type="html">【セキュリティ】ウィルス対策ソフトは危険</title>
|
||||
<published>2023-12-25T00:00:00Z</published>
|
||||
|
||||
<category term="jp"></category>
|
||||
|
||||
<category term="blog"></category>
|
||||
|
||||
<category term="linux"></category>
|
||||
|
||||
<category term="bsd"></category>
|
||||
|
||||
<category term="セキュリティー"></category>
|
||||
|
||||
<category term="デジタル自主"></category>
|
||||
|
||||
<category term="ソフトウェア"></category>
|
||||
|
||||
<category term="メール"></category>
|
||||
|
||||
<category term="プライバシー"></category>
|
||||
|
||||
<link href="gemini://technicalsuwako.moe/blog/anti-virus-dangerous.gmi" rel="alternate"></link>
|
||||
<content type="html">
|
||||
|
||||
|
||||
|
||||
<p>メリークリスマス!!<br />
|
||||
今回は大切な人へのプレゼントとして何を購入しましたか?<br />
|
||||
ウィルス対策ソフトと答えたら、返品した方が良いです。</p>
|
||||
<h2 id="heading">何故ウィルス対策ソフトが危険?</h2>
|
||||
<p>セキュリティ上の問題以外にも、ウィルス対策ソフトには様々な問題があります。<br />
|
||||
例えば、パソコンの速度が遅くなったり、多くのウェブページが表示されなくなることがあります。<br />
|
||||
しかし、これらはセキュリティの問題とは直接関係がありません。</p>
|
||||
<p>本当の危険は、ウィルス対策ソフトが貴方のファイルの内容(パスワードやクレジットカード番号を含む)をスキャンし、それらをネットにアップロードする事にあります。<br />
|
||||
<a href="https://www.gnu.org/proprietary/proprietary.html">殆どのウィルス対策ソフトはプロプライエタリなソフトウェアですであり、それ自体がセキュリティ上のリスクとなる事もあります。</a><br />
|
||||
<a href="https://gigazine.net/news/20221208-apple-csam-scan-canceled/">iPhoneユーザーはファイル内容のスキャンとネット上にアップロードに反対しましたが、何故パソコンユーザーはこれを推奨されるのでしょうか?</a><br />
|
||||
ウィルス対策ソフトを購入しないで下さい。<br />
|
||||
それは詐欺です!</p>
|
||||
<h2 id="heading-1">本当のウィルス対策はあるのでしょうか?</h2>
|
||||
<p>はい、存在します!<br />
|
||||
これは、自分の判断力を駆使する事です!<br />
|
||||
ブラウザでの広告をクリックしない事が重要です。<br />
|
||||
「Sponsor」や「スポンサー」というラベルが付いている広告は、絶対にクリックしないで下さい。<br />
|
||||
フィッシングメールには注意し、その対策についてはこの後で詳しく解説します。<br />
|
||||
WindowsやmacOSの代わりにLinuxやBSDを使用を検討してみて下さい。<br />
|
||||
Linux向けウィルスも存在しますが、その数は格段に少ないです。<br />
|
||||
デフォルト設定でJavascript、XHR、及びiFrameを無効にし、信頼出来るウェブサイトでのみ「必要な場合」に限り有効にして下さい。<br />
|
||||
不番な物があれば、リスクを避ける為に仮想マシンで実行する事をお勧めします。</p>
|
||||
<h2 id="heading-2">フィシングメールの対策</h2>
|
||||
<p>銀行、政府等による、ウィルス対策ソフトなしでフィッシングメールに対策出来ないって言われますが、実はそれが嘘です。<br />
|
||||
対策は:</p>
|
||||
<ul>
|
||||
<li>良いメールクライエントを使う事(Neomutt又はClaws Mailが超勧めます)</li>
|
||||
<li>HTMLメールを無効にし、テキストのみの表示にする事が良いです</li>
|
||||
<li>使わないサービスからメールが届いた場合、直ぐに削除する事</li>
|
||||
<li>使うサービスからメールが届いた場合、「To:」は会社のメールアドレスと、内容で貴方の名前か会社名で始まる事を確認する事(「顧客様、」や「ご担当者様」等といった曖昧な表現で始まる場合はフィッシングメールである可能性が高い)</li>
|
||||
<li>使うサービスからメールが届いた場合、メール内のリンクをクリックしないで下さい(メールアドレス確認メールを除く)。代わりに、ブラウザで手動で会社のウェブページを開き、ログインして下さい。特に「下記のリンクをクリックして下さい」みたいなリンクは絶対にクリックしないで下さい!!これは1番重要な点です!!)</li>
|
||||
<li>添付ファイルがあるメールは、特に予期していない場合は開かないで下さい</li>
|
||||
</ul>
|
||||
<p>以上</p>
|
||||
|
||||
|
||||
</content>
|
||||
</entry>
|
||||
|
||||
|
||||
</feed>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
# 記事一覧
|
||||
|
||||
=> /blog/sdl2-easy-collision.gmi 2024年02月17日 【SDL2】簡単な3D衝突検出の解説
|
||||
=> /blog/sp-120.gmi 2024年02月01日 【076】sp 1.2.0登場
|
||||
=> /blog/neovim-code-template.gmi 2024年01月31日 【Neovim】テンプレートと作り方
|
||||
=> /blog/freebsd-nas-auto-backup.gmi 2024年01月30日 【FreeBSD】簡単にNASの自動的にバックアップする方法
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
=> /blog.gmi ブログ一覧へ
|
||||
|
||||
# 【SDL2】簡単な3D衝突検出の解説
|
||||
公開日:2024-02-17
|
||||
|
||||
最近、自作のゲームを作成していますが、衝突検出を実装する事に懸念を抱きました。
|
||||
しかし、作った後はそんなに難しくないと気づきました。
|
||||
その為、今回はこれについて説明します。
|
||||
記事での利用している言語はZig言語ですが、C言語やC++でも使えます。
|
||||
|
||||
## プログラミングタイム!!
|
||||
3つのオブジェクトを設置します。
|
||||
|
||||
```zig
|
||||
// オブジェクト
|
||||
const Wall = struct { x: f32, y: f32, z: f32, size: f32 };
|
||||
const Floor = struct { x: f32, y: f32, z: f32, size: f32 };
|
||||
const Player = struct {
|
||||
xpos: f32,
|
||||
ypos: f32,
|
||||
zpos: f32,
|
||||
xsize: f32,
|
||||
ysize: f32,
|
||||
zsize: f32,
|
||||
velocity: f32,
|
||||
gravity: f32,
|
||||
};
|
||||
|
||||
var wall = Wall { .x = -6.0, .y = 0.0, .z = -26.0, .size = 6.0 };
|
||||
var floor = Floor { .x = -6.0, .y = -7.0, .z = -26.0, .size = 50.0 };
|
||||
var player = Player {
|
||||
.xpos = 0.0,
|
||||
.ypos = 50.0,
|
||||
.zpos = 0.0,
|
||||
.xsize = 0.2,
|
||||
.ysize = 0.8,
|
||||
.zsize = 0.2,
|
||||
.velocity = 0.1,
|
||||
.gravity = 0.2,
|
||||
};
|
||||
|
||||
fn draw() void {
|
||||
// ここは`glBegin`、`glVertex3f`等を設置しますが、長すぎる為、これはスキップします。
|
||||
}
|
||||
```
|
||||
|
||||
上記のコードで、主に「gravity」や「velocity」が大切です。
|
||||
次は衝突検出の関数を作ります。
|
||||
|
||||
```zig
|
||||
fn checkPosToObj(xpos: f32, ypos: f32, zpos: f32, size: f32, obj: anytype) bool {
|
||||
const thresholdX: f32 = size;
|
||||
const thresholdY: f32 = size;
|
||||
const thresholdZ: f32 = size;
|
||||
|
||||
const deltaX: f32 = @abs(xpos - obj.xpos);
|
||||
const deltaY: f32 = @abs(ypos - obj.ypos);
|
||||
const deltaZ: f32 = @abs(zpos - obj.zpos);
|
||||
|
||||
return deltaX < thresholdX and
|
||||
deltaY < thresholdY and
|
||||
deltaZ < thresholdZ;
|
||||
}
|
||||
```
|
||||
|
||||
床と壁のサイズ値は1つだけで、プレイヤは3つ(X, Y, Z)がある為、上記を使った方が良いですね。
|
||||
両方のオブジェクトが3つのサイズ値があれば、下記の関数を使っては良いと思います。
|
||||
|
||||
```zig
|
||||
fn checkObjToObj(a: anytype, b: anytype) bool {
|
||||
const thresholdX: f32 = a.xsize;
|
||||
const thresholdY: f32 = a.ysize;
|
||||
const thresholdZ: f32 = a.zsize;
|
||||
|
||||
const deltaX: f32 = @abs(a.xpos - b.xpos);
|
||||
const deltaY: f32 = @abs(a.ypos - b.ypos);
|
||||
const deltaZ: f32 = @abs(a.zpos - b.zpos);
|
||||
|
||||
return deltaX < thresholdX and
|
||||
deltaY < thresholdY and
|
||||
deltaZ < thresholdZ;
|
||||
}
|
||||
```
|
||||
|
||||
thresholdはいつでもプレイヤ以外のオブジェクトのサイズとなります。
|
||||
|
||||
```zig
|
||||
pub fn main() !void {
|
||||
// ...
|
||||
// 衝突検出
|
||||
if (checkPosToObj(floor.x, floor.y, floor.z, floor.size, player)) {
|
||||
std.debug.print("床を触って良かった! ypos = {d}\n", .{player.ypos});
|
||||
player.ypos = floor.y+(player.ysize);
|
||||
} else {
|
||||
std.debug.print("ああああああ!! ypos = {d}\n", .{player.ypos});
|
||||
player.ypos -= player.gravity;
|
||||
}
|
||||
|
||||
if (checkPosToObj(plane.x, plane.y, plane.z, plane.size, player)) {
|
||||
std.debug.print("壁だわ...\n", .{});
|
||||
player.zpos = plane.z+(player.zsize);
|
||||
}
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
## 結果
|
||||
|
||||
=> /static/zig-cd.ogv
|
||||
|
||||
ねぇ!簡単でしょ〜!
|
||||
|
||||
以上
|
バイナリファイルは表示されません。
|
@ -3,6 +3,7 @@
|
|||
# avatar = gemini://076.moe/static/suwako.jpg
|
||||
# description = テクニカル諏訪子様のtwtxtフィード
|
||||
# link = ホームページ gemini://technicalsuwako.moe
|
||||
2024-02-17T00:00:00Z09:00 【SDL2】簡単な3D衝突検出の解説 - gemini://technicalsuwako.moe/blog/sdl2-easy-collision.gmi
|
||||
2024-02-01T00:00:00Z09:00 【076】sp 1.2.0登場 - gemini://technicalsuwako.moe/blog/sp-120.gmi
|
||||
2024-01-31T00:00:00Z09:00 【Neovim】テンプレートと作り方 - gemini://technicalsuwako.moe/blog/neovim-code-template.gmi
|
||||
2024-01-30T00:00:00Z09:00 【FreeBSD】簡単にNASの自動的にバックアップする方法 - gemini://technicalsuwako.moe/blog/freebsd-nas-auto-backup.gmi
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
title: 【SDL2】簡単な3D衝突検出の解説
|
||||
author: 凛
|
||||
date: 2024-02-17
|
||||
tags: blog,jp,プログラミング,zig,sdl,opengl,ゲーム開発
|
||||
----
|
||||
最近、自作のゲームを作成していますが、衝突検出を実装する事に懸念を抱きました。\
|
||||
しかし、作った後はそんなに難しくないと気づきました。\
|
||||
その為、今回はこれについて説明します。\
|
||||
記事での利用している言語はZig言語ですが、C言語やC++でも使えます。
|
||||
|
||||
## プログラミングタイム!!
|
||||
3つのオブジェクトを設置します。
|
||||
|
||||
```zig
|
||||
// オブジェクト
|
||||
const Wall = struct { x: f32, y: f32, z: f32, size: f32 };
|
||||
const Floor = struct { x: f32, y: f32, z: f32, size: f32 };
|
||||
const Player = struct {
|
||||
xpos: f32,
|
||||
ypos: f32,
|
||||
zpos: f32,
|
||||
xsize: f32,
|
||||
ysize: f32,
|
||||
zsize: f32,
|
||||
velocity: f32,
|
||||
gravity: f32,
|
||||
};
|
||||
|
||||
var wall = Wall { .x = -6.0, .y = 0.0, .z = -26.0, .size = 6.0 };
|
||||
var floor = Floor { .x = -6.0, .y = -7.0, .z = -26.0, .size = 50.0 };
|
||||
var player = Player {
|
||||
.xpos = 0.0,
|
||||
.ypos = 50.0,
|
||||
.zpos = 0.0,
|
||||
.xsize = 0.2,
|
||||
.ysize = 0.8,
|
||||
.zsize = 0.2,
|
||||
.velocity = 0.1,
|
||||
.gravity = 0.2,
|
||||
};
|
||||
|
||||
fn draw() void {
|
||||
// ここは`glBegin`、`glVertex3f`等を設置しますが、長すぎる為、これはスキップします。
|
||||
}
|
||||
```
|
||||
|
||||
上記のコードで、主に「gravity」や「velocity」が大切です。\
|
||||
次は衝突検出の関数を作ります。
|
||||
|
||||
```zig
|
||||
fn checkPosToObj(xpos: f32, ypos: f32, zpos: f32, size: f32, obj: anytype) bool {
|
||||
const thresholdX: f32 = size;
|
||||
const thresholdY: f32 = size;
|
||||
const thresholdZ: f32 = size;
|
||||
|
||||
const deltaX: f32 = @abs(xpos - obj.xpos);
|
||||
const deltaY: f32 = @abs(ypos - obj.ypos);
|
||||
const deltaZ: f32 = @abs(zpos - obj.zpos);
|
||||
|
||||
return deltaX < thresholdX and
|
||||
deltaY < thresholdY and
|
||||
deltaZ < thresholdZ;
|
||||
}
|
||||
```
|
||||
|
||||
床と壁のサイズ値は1つだけで、プレイヤは3つ(X, Y, Z)がある為、上記を使った方が良いですね。\
|
||||
両方のオブジェクトが3つのサイズ値があれば、下記の関数を使っては良いと思います。
|
||||
|
||||
```zig
|
||||
fn checkObjToObj(a: anytype, b: anytype) bool {
|
||||
const thresholdX: f32 = a.xsize;
|
||||
const thresholdY: f32 = a.ysize;
|
||||
const thresholdZ: f32 = a.zsize;
|
||||
|
||||
const deltaX: f32 = @abs(a.xpos - b.xpos);
|
||||
const deltaY: f32 = @abs(a.ypos - b.ypos);
|
||||
const deltaZ: f32 = @abs(a.zpos - b.zpos);
|
||||
|
||||
return deltaX < thresholdX and
|
||||
deltaY < thresholdY and
|
||||
deltaZ < thresholdZ;
|
||||
}
|
||||
```
|
||||
|
||||
thresholdはいつでもプレイヤ以外のオブジェクトのサイズとなります。
|
||||
|
||||
```zig
|
||||
pub fn main() !void {
|
||||
// ...
|
||||
// 衝突検出
|
||||
if (checkPosToObj(floor.x, floor.y, floor.z, floor.size, player)) {
|
||||
std.debug.print("床を触って良かった! ypos = {d}\n", .{player.ypos});
|
||||
player.ypos = floor.y+(player.ysize);
|
||||
} else {
|
||||
std.debug.print("ああああああ!! ypos = {d}\n", .{player.ypos});
|
||||
player.ypos -= player.gravity;
|
||||
}
|
||||
|
||||
if (checkPosToObj(plane.x, plane.y, plane.z, plane.size, player)) {
|
||||
std.debug.print("壁だわ...\n", .{});
|
||||
player.zpos = plane.z+(player.zsize);
|
||||
}
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
## 結果
|
||||
|
||||
<video src="https://ass.technicalsuwako.moe/zig-cd.ogv" controls="controls" style="max-height: 400px;"></video>
|
||||
|
||||
ねぇ!簡単でしょ〜!
|
||||
|
||||
以上
|
読み込み中…
新しいイシューから参照