【HTML&CSSではじめるミニゲーム作成の基本】スプライトの接触判定をじっくり理解しよう


※ 当ページには【広告/PR】を含む場合があります。
2023/12/24
【HTML&CSSではじめるミニゲーム作成の基本】CSSバックグラウンドスライド式のアニメーション用png画像をInkscapeで作成する
【HTML&CSSではじめるミニゲーム作成】高速なアルゴリズムで接触してるスプライトを検索する
合同会社タコスキングダム|TacosKingdom,LLC.

シューティングゲーム他、様々な平面上で表現される2次元ゲームにおいて、スプライト同士の接触をどのように決定するかは、これまでにさまざまなアルゴリズムが検討されてきた、とても深いテーマになっています。

HTMLで要素同士の接触をどのように設計するかは、Mozillaのmdn web docsにその実装指針が解説されています。

参考|二次元の衝突検出

このブログ記事では、最も簡単なアルゴリズムである、「座標軸に沿った囲みボックス」と「円形衝突」について実例をもって考察していきます。


合同会社タコスキングダム|タコキンのPスクール【Html&Cssアプリ】Html/JavascriptとSassを使った四択クイズゲームの作り方

すぐに作れる ずっと使える Inkscapeのすべてが身に付く本

HTML/CSSでスプライトをキーボード入力操作できるプログラムを作成する

まずは接触判定などを一切考えないで、キーボードの上下左右キーからスプライトを動かすだけのHTMLプログラムを描いてみます。

まずは主要なHTML要素を以下の用に作成しておきます。

            
            <body>
    <section id="game-stage">
        <div id="taco-screen">
            <div id="taco"></div>
        <div>
    </section>
    <section id="console-area">
        <input type="text" id="game-status" name="message" value="">
    </section>
</body>
        
HTMLゲームづくりの作成方針として、最初から要素ごとにid属性を付けておいたほうが後々実装が楽になるでしょう。

次にこのHTML要素へ以下のようなcssスタイルを仕込んでおきます。

            
            body {
    display: block;
    margin: 0;
    padding: 0;
}
#game-stage {
    display: block;
    position: relative;
    width: 100%;
    height: 280px;
    padding: 0;
    margin: 0 auto;
    pointer-events: none;
    /* ポイント① ... カスタムプロパティの利用 */
    --x-pos: 20px;
    --y-pos: 0px;
}
#taco-screen {
    display: block;
    position: absolute;
    background: aqua;
    padding: 0;
    width: 80px;
    height: 60px;
    /* ポイント① ... カスタムプロパティの利用 */
    top: var(--y-pos);
    left: var(--x-pos);
}
#taco {
    display: block;
    width: 100%;
    height: 100%;
    background: transparent url('https://raw.githubusercontent.com/tacoskingdom/commonBlogMaterial/main/tacokin-p-school/blog109/character_juken_tako_okuto_pass.svg') no-repeat 0 0;
    background-size: 80px 60px;
}
#console-area {
    display: block;
    position: absolute;
    width: 100%;
    height: 20px;
    top: 280px;
    padding: 0 0 0 0;
    margin: 0 auto;
}
#game-status {
    width: 100%;
    font-size: 1.1rem;
    background: #f5b560;
    pointer-events: none;
    border: navajowhite;
    outline: none;
}
        
各DOM要素に細かいスタイルの指定を施している訳ですが、一つ一つ説明すると切りがないので、このコードの重要な点に絞ります。

もっとも重要な点として、
「キーボードの矢印キーからスプライトを動かす」ために、カスタムプロパティ(CSS変数)を使います。

CSSのカスタムプロパティについては、別ブログでじっくり解説しましたので、そちらをご覧ください。

参考|【CSS/Sassで作るミニゲーム】CSS変数(カスタムプロパティ)とシンプルなJSコードでHTML要素をコントロール

実際にスプライトを処理するのはjavascript側に頼る必要があります。

なので、jsスクリプト(
<script>タグ内)の実装は以下の通りです。

            
            const isSupported = window.CSS && window.CSS.supports && window.CSS.supports('--a', 0);
if (isSupported) {
    const stage = document.getElementById("game-stage");
    const styles = getComputedStyle(stage);
    const xpos = styles.getPropertyValue('--x-pos');
    const ypos = styles.getPropertyValue('--y-pos');
    const input = document.getElementById("game-status");
    input.value = `矢印キーで動きます|[タコの位置]x=${xpos},y=${ypos}`;
    document.body.addEventListener("keydown", (e) => {
        const stage = document.getElementById("game-stage");
        const styles = getComputedStyle(stage);
        const xpos = styles.getPropertyValue('--x-pos');
        const ypos = styles.getPropertyValue('--y-pos');
        const input = document.getElementById("game-status");
        input.value = `矢印キーで動きます|[タコの位置]x=${xpos},y=${ypos}`;
        const key = e.keyCode;
        if(key === 40){
            stage.style.setProperty('--y-pos', `${parseInt(ypos.replace('px','')) + 4}px`);
        }
        if(key === 39){
            stage.style.setProperty('--x-pos', `${parseInt(xpos.replace('px','')) + 4}px`);
        }
        if(key === 38){
            stage.style.setProperty('--y-pos', `${parseInt(ypos.replace('px','')) - 4}px`);
        }
        if(key === 37){
            stage.style.setProperty('--x-pos', `${parseInt(xpos.replace('px','')) - 4}px`);
        }
        e.preventDefault();
    }, false);
}
else {
    const input = document.getElementById("game-status");
    input.value ='お使いのブラウザはカスタムプロパティ非対応です';
}
        
このスクリプトでも別のブログで説明していた「getComputedStyle/getPropertyValue」・「setProperty」を駆使して、DOM要素の座標を取得・設定させています。

なお、キーボード入力をJS側から処理するイベントは、色々なサイトで解説されている通りですので、ここでは割愛します。

参考|JavaScriptでキーボードの入力を判定した処理を実装する方法

キーボード入力イベントの実装の自体も重要ですが、HTMLブラウザゲーム作成に欠かせない、イベントの発火順序である
「バブリングフェーズ」と「イベントのpreventDefault」の理解も必要になります。

これについては、以下の記事を参考にしてください。

参考|【Sassで作るCssミニゲーム〜番外編】親子要素でonclickなどのイベントをどちらか一方に指定する方法

ここまでのプログラムを動かすと以下のようなHTMLアプリになるでしょう。

※以下のゲームを動かす場合、キーボード入力が受け付けないときは
ゲーム画面枠内を一度クリックしてみてください。

さて、スプライトを動かすだけで、結構骨のある内容になっていますが、本題にも辿り着いていないので、もうしばらくお付き合いください。


合同会社タコスキングダム|タコキンのPスクール【Html&Cssアプリ】Html/JavascriptとSassを使った四択クイズゲームの作り方

すぐに作れる ずっと使える Inkscapeのすべてが身に付く本

座標軸に沿った囲みボックスで接触判定

接触判定でもっとも基本になるのが囲みボックスでの判定です。

「囲みボックス」はスプライト画像をできるだけスッポリと収めるサイズに設定した四角の枠を指します。

合同会社タコスキングダム|タコキンのPスクール

自分の囲みボックスの内側に、他の要素の囲みボックスもしくは境界が入ったと判定される場合、それらの要素は「接触」したとみなします。

この記事では基本的な2つの接触タイプとして以下の実装を考えてみます。

            
            1. 壁面(画面枠)との接触
2. 他のスプライトとの接触
        
他にもマップ上に設置された障害物だったり、イベント状態で移動を切り替えられるようにするなど、特殊なケースもありますが、応用的な課題はここでは取り上げません。

壁面(画面枠)との接触

スプライトが画面外へはみ出さないように制限を付けます。

具体的には、JSスクリプト側に以下のようなロジックを追加することになります。

            
            if (
    (スプライトのL < 左側の壁枠のx座標) || (スプライトのL+W > 右側の壁枠のx座標)
) {
    //スプライトのx座標を変更しない
}
if (
    (スプライトのT < 上側の壁枠のy座標) || (スプライトのT+H > 下側の壁枠のy座標)
) {
    //スプライトのy座標を変更しない
}
        
これで、スプライトを移動しても画面外に見切れることはなくなります。

他のスプライトとの接触

考え方は壁面と同じで各軸の座標の大小関係を比較するのですが、他のスプライトにも
囲みボックスが存在しているので、2つの囲みボックスの位置関係の比較でやや複雑になります。

合同会社タコスキングダム|タコキンのPスクール

この衝突領域が発生しているかどうかを調べるために、対象となる2つの囲みボックスの位置をx軸とy軸の順でチェックしていきます。

            
            //x軸の位置関係からチェック
if ((自分のL > 相手のL+W) || (自分のL+W < 相手のL)) {
    //衝突はしていないときの処理
    ...
}
else {
    //衝突している可能性があるので、y軸の位置関係もチェック
    if ((自分のT > 相手のT+H) || (自分のT+H < 相手のT)) {
        //衝突はしていないときの処理
        ...
    }
    else {
        //衝突しているときの処理
        ...
    }
}
        
この時点では実装の分かりやすさを重視したため、コード的にはあまりきれいではないのですが、実践では判定する関数化を行って、汎用性のあるやり方に修正をする必要があります。

囲みボックスの接触判定を実装してみる

では上の内容を踏まえて、HTML/CSS/JSのパートを修正していきましょう。

            
            <body>
    <section id="game-stage">
        <div id="taco-screen">
            <div id="taco"></div>
        </div>
        <!-- 👇の要素を追加 -->
        <div id="dagon-screen">
            <div id="dagon"></div>
        </div>
    </section>
    <section id="console-area">
        <input type="text" id= "game-status" name="message" value="">
    </section>
</body>
        
次にCSSスタイルの修正です。

            
            body {
    display: block;
    margin: 0;
    padding: 0;
}

#game-stage {
    display: block;
    position: relative;
    width: 100%;
    height: 280px;
    padding: 0;
    margin: 0 auto;
    pointer-events: none;

    --x-pos: 20px;
    --y-pos: 0px;

    /* 👇敵スプライトの座標 */
    --x2-pos: 120px;
    --y2-pos: 50px;

    /* 👇接触判定時の背景色 */
    --collision-state: aqua;
}

#taco-screen {
    display: block;
    position: absolute;
    padding: 0;
    width: 80px;
    height: 60px;
    top: var(--y-pos);
    left: var(--x-pos);

    /* 👇接触時に色が切り替わるように修正 */
    background: var(--collision-state);
    z-index: 1;
}

#taco {
    display: block;
    width: 100%;
    height: 100%;
    background: transparent url('https://raw.githubusercontent.com/tacoskingdom/commonBlogMaterial/main/tacokin-p-school/blog109/character_juken_tako_okuto_pass.svg') no-repeat 0 0;
    background-size: 80px 60px;
}

/* 👇接触対象の敵スプライトのスタイルを追加 */
#dagon-screen {
    display: block;
    position: absolute;
    padding: 0;
    top: var(--y2-pos);
    left: var(--x2-pos);
    width: 80px;
    height: 60px;
    background: var(--collision-state);
    z-index: 0;
}
#dagon {
    display: block;
    width: 100%;
    height: 100%;
    background: transparent url('https://raw.githubusercontent.com/tacoskingdom/commonBlogMaterial/main/tacokin-p-school/blog109/character_cthulhu_kuturufu.svg') no-repeat 0 0;
    background-size: 80px 60px;
}

#console-area {
    display: block;
    position: absolute;
    width: 100%;
    height: 20px;
    top: 280px;
    padding: 0 0 0 0;
    margin: 0 auto;
}
#game-status {
    width: 100%;
    font-size: 1.1rem;
    background: #f5b560;
    pointer-events: none;
    border: navajowhite;
    outline: none;
}
        
最後にJSスクリプトに衝突判定に実装します。

            
            const isSupported = window.CSS && window.CSS.supports && window.CSS.supports('--a', 0);
if (isSupported) {
    const stage = document.getElementById("game-stage");
    const styles = getComputedStyle(stage);
    const xpos = styles.getPropertyValue('--x-pos');
    const ypos = styles.getPropertyValue('--y-pos');
    const input = document.getElementById("game-status");
    input.value = `矢印キーで動きます|[タコの位置]x=${xpos},y=${ypos}`;
    document.body.addEventListener("keydown", (e) => {
        const stage = document.getElementById("game-stage");
        const styles = getComputedStyle(stage);
        const stageW = Number(styles.width.replace('px',''));
        const stageH = Number(styles.height.replace('px',''));
        const xpos = styles.getPropertyValue('--x-pos');
        const ypos = styles.getPropertyValue('--y-pos');
        const x2pos = styles.getPropertyValue('--x2-pos');
        const y2pos = styles.getPropertyValue('--y2-pos');
        const input = document.getElementById("game-status");
        input.value = `矢印キーで動きます|[タコの位置]x=${xpos},y=${ypos}|[敵の位置]x=${x2pos},y=${y2pos}`;

        //👇2つのスプライトの座標と画像サイズ
        const _x1 = parseInt(xpos.replace('px',''));
        const _y1 = parseInt(ypos.replace('px',''));
        const _x2 = parseInt(x2pos.replace('px',''));
        const _y2 = parseInt(y2pos.replace('px',''));
        const tacoW = 80;
        const tacoH = 60;
        const dagonW = 80;
        const dagonH = 60;

        const key = e.keyCode;
        if(key === 40){
            //下に移動(y座標を+4)
            let _ny = _y1 + 4;
            //👇画面下に接触した場合、座標を元に戻す
            if (_ny + tacoH > stageH) _ny -= 4;
            stage.style.setProperty('--y-pos', `${_ny}px`);

            //👇敵スプライトとの接触判定
            //x軸の位置関係からチェック
            if (_x1 > _x2 + dagonW || _x1 + tacoW < _x2) {
                //衝突はしていないときの処理
                stage.style.setProperty('--collision-state', 'aqua');
            }
            else {
                //衝突している可能性があるので、y軸の位置関係もチェック
                if (_ny > _y2+dagonH || _ny+tacoH < _y2) {
                    //衝突はしていないときの処理
                    stage.style.setProperty('--collision-state', 'aqua');
                }
                else {
                    //衝突しているときの処理
                    stage.style.setProperty('--collision-state', 'red');
                }
            }
        }
        if(key === 39){
            //右に移動(x座標を+4)
            let _nx = _x1 + 4;
            //👇画面右に接触した場合、座標を元に戻す
            if (_nx + tacoW > stageW) _nx -= 4;
            stage.style.setProperty('--x-pos', `${_nx}px`);

            //👇敵スプライトとの接触判定
            //x軸の位置関係からチェック
            if (_nx > _x2 + dagonW || _nx + tacoW < _x2) {
                //衝突はしていないときの処理
                stage.style.setProperty('--collision-state', 'aqua');
            }
            else {
                //衝突している可能性があるので、y軸の位置関係もチェック
                if (_y1 > _y2+dagonH || _y1+tacoH < _y2) {
                    //衝突はしていないときの処理
                    stage.style.setProperty('--collision-state', 'aqua');
                }
                else {
                    //衝突しているときの処理
                    stage.style.setProperty('--collision-state', 'red');
                }
            }
        }
        if(key === 38){
            //上に移動(y座標を-4)
            let _ny = _y1 - 4;
            //👇画面上に接触した場合、座標を元に戻す
            if (_ny < 0) _ny += 4;
            stage.style.setProperty('--y-pos', `${_ny}px`);

            //👇敵スプライトとの接触判定
            //x軸の位置関係からチェック
            if (_x1 > _x2 + dagonW || _x1 + tacoW < _x2) {
                //衝突はしていないときの処理
                stage.style.setProperty('--collision-state', 'aqua');
            }
            else {
                //衝突している可能性があるので、y軸の位置関係もチェック
                if (_ny > _y2+dagonH || _ny+tacoH < _y2) {
                    //衝突はしていないときの処理
                    stage.style.setProperty('--collision-state', 'aqua');
                }
                else {
                    //衝突しているときの処理
                    stage.style.setProperty('--collision-state', 'red');
                }
            }
        }
        if(key === 37){
            //左に移動(x座標を-4)
            let _nx = _x1 - 4;
            //👇画面左に接触した場合、座標を元に戻す
            if (_nx < 0) _nx += 4;
            stage.style.setProperty('--x-pos', `${_nx}px`);

            //👇敵スプライトとの接触判定
            //x軸の位置関係からチェック
            if (_nx > _x2 + dagonW || _nx + tacoW < _x2) {
                //衝突はしていないときの処理
                stage.style.setProperty('--collision-state', 'aqua');
            }
            else {
                //衝突している可能性があるので、y軸の位置関係もチェック
                if (_y1 > _y2+dagonH || _y1+tacoH < _y2) {
                    //衝突はしていないときの処理
                    stage.style.setProperty('--collision-state', 'aqua');
                }
                else {
                    //衝突しているときの処理
                    stage.style.setProperty('--collision-state', 'red');
                }
            }
        }
        e.preventDefault();
    }, false);
}
else {
    const input = document.getElementById("game-status");
    input.value ='お使いのブラウザはカスタムプロパティ非対応です';
}
        
以上を組み上げると、以下のようなHTMLプログラムで動くと思います。

※以下のゲームを動かす場合、キーボード入力が受け付けないときは
ゲーム画面枠内を一度クリックしてみてください。


合同会社タコスキングダム|タコキンのPスクール【Html&Cssアプリ】Html/JavascriptとSassを使った四択クイズゲームの作り方

すぐに作れる ずっと使える Inkscapeのすべてが身に付く本

円形領域で接触判定

先程の囲みボックスが理解できたら、「円形領域」への応用は容易です。

円形領域とはその名の通りで、画像を囲う円によって他のスプライトや壁面との接触判定を行う方式です。

合同会社タコスキングダム|タコキンのPスクール

判定の起点となるのは、
「画像の中心(重心)位置からの距離」を利用することが先程の囲みボックス方式と異なります。

先程の2つの接触判定ロジックも少し調整が必要で、画面枠との判定は以下のようにします。

            
            if (
    (スプライト中心のx座標 - R < 左側の壁枠のx座標) || (スプライト中心のx座標 + R > 右側の壁枠のx座標)
) {
    //スプライトのx座標を変更しない
}
if (
    (スプライト中心のy座標 - R < 上側の壁枠のy座標) || (スプライト中心のy座標 + R > 下側の壁枠のy座標)
) {
    //スプライトのy座標を変更しない
}
        
他のスプライトとの接触判定は更にシンプルになり、

            
            if (自分のR + 相手のR > D) {
    //衝突はしていないときの処理
    ...
}
else {
    //衝突しているときの処理
    ...
}
        
というようにロジックを修正します。

円形領域の接触判定を実装してみる

では上の内容を踏まえて、CSS/JSのパートを修正していきましょう。(※HTMLパートはそのまま利用)

まずCSSは円形領域の表示にちょこっと変えただけです。

            
            /* ...中略 */

#taco-screen {
    display: block;
    position: absolute;
    padding: 0;
    background: var(--collision-state);
    z-index: 1;
    width: 80px;
    top: var(--y-pos);
    left: var(--x-pos);
    /* 👇円形領域になるように調整 */
    height: 80px;
    border-radius: 50%;
}
#taco {
    display: block;
    width: 100%;
    height: 100%;
    background: transparent url('https://raw.githubusercontent.com/tacoskingdom/commonBlogMaterial/main/tacokin-p-school/blog109/character_juken_tako_okuto_pass.svg') no-repeat 0 0;
    /* 👇円形領域になるように調整 */
    background-size: 80px 80px;
}

#dagon-screen {
    display: block;
    position: absolute;
    padding: 0;
    top: var(--y2-pos);
    left: var(--x2-pos);
    width: 80px;
    background: var(--collision-state);
    z-index: 0;
    /* 👇円形領域になるように調整 */
    height: 80px;
    border-radius: 50%;
}
#dagon {
    display: block;
    width: 100%;
    height: 100%;
    background: transparent url('https://raw.githubusercontent.com/tacoskingdom/commonBlogMaterial/main/tacokin-p-school/blog109/character_cthulhu_kuturufu.svg') no-repeat 0 0;
    /* 👇円形領域になるように調整 */
    background-size: 80px 80px;
}

/* ...以下略 */
        
次に、JSスクリプトはロジックを入れ替えしているのですが、割と使いまわしも多いです。

実装は以下のようにしました。

            
            const isSupported = window.CSS && window.CSS.supports && window.CSS.supports('--a', 0);
if (isSupported) {
    const stage = document.getElementById("game-stage");
    const styles = getComputedStyle(stage);
    const xpos = styles.getPropertyValue('--x-pos');
    const ypos = styles.getPropertyValue('--y-pos');
    const input = document.getElementById("game-status");
    input.value = `矢印キーで動きます|[タコの位置]x=${xpos},y=${ypos}`;
    document.body.addEventListener("keydown", (e) => {
        const stage = document.getElementById("game-stage");
        const styles = getComputedStyle(stage);
        const stageW = Number(styles.width.replace('px',''));
        const stageH = Number(styles.height.replace('px',''));
        const xpos = styles.getPropertyValue('--x-pos');
        const ypos = styles.getPropertyValue('--y-pos');
        const x2pos = styles.getPropertyValue('--x2-pos');
        const y2pos = styles.getPropertyValue('--y2-pos');
        const input = document.getElementById("game-status");
        input.value = `矢印キーで動きます|[タコの位置]x=${xpos},y=${ypos}|[敵の位置]x=${x2pos},y=${y2pos}`;

        //👇2つのスプライトの座標と画像サイズと円形領域の半径
        const _x1 = parseInt(xpos.replace('px',''));
        const _y1 = parseInt(ypos.replace('px',''));
        const _x2 = parseInt(x2pos.replace('px',''));
        const _y2 = parseInt(y2pos.replace('px',''));
        const tacoW = 80;
        const tacoH = 80;
        const tacoR = 40;
        const dagonW = 80;
        const dagonH = 80;
        const dagonR = 40;

        //2つのスプライトの中心位置
        let _cx1 = _x1 + tacoW/2;
        let _cy1 = _y1 + tacoH/2;
        let _cx2 = _x2 + dagonW/2;
        let _cy2 = _y2 + dagonH/2;

        const key = e.keyCode;
        if(key === 40){
            //下に移動(y座標を+4)
            let _ny = _y1 + 4;
            //👇画面下に接触した場合、座標を元に戻す
            _cy1 = _ny + tacoH/2;
            if (_cy1 + tacoR > stageH) {
                _ny -= 4;
                _cy1 = _ny + tacoH/2;
            }
            stage.style.setProperty('--y-pos', `${_ny}px`);
        }
        if(key === 39){
            //右に移動(x座標を+4)
            let _nx = _x1 + 4;
            //👇画面右に接触した場合、座標を元に戻す
            _cx1 = _nx + tacoW/2;
            if (_cx1 + tacoR > stageW) {
                _nx -= 4;
                _cx1 = _nx + tacoW/2;
            }
            stage.style.setProperty('--x-pos', `${_nx}px`);
        }
        if(key === 38){
            //上に移動(y座標を-4)
            let _ny = _y1 - 4;
            //👇画面上に接触した場合、座標を元に戻す
            _cy1 = _ny + tacoH/2;
            if (_cy1 - tacoR < 0) {
                _ny += 4;
                _cy1 = _ny + tacoH/2;
            }
            stage.style.setProperty('--y-pos', `${_ny}px`);
        }
        if(key === 37){
            //左に移動(x座標を-4)
            let _nx = _x1 - 4;
            //👇画面左に接触した場合、座標を元に戻す
            _cx1 = _nx + tacoW/2;
            if (_cx1 - tacoR < 0) {
                _nx += 4;
                _cx1 = _nx + tacoW/2;
            }
        }
        //👇敵スプライトとの接触判定(中心距離の位置関係からチェック)
        const d = Math.sqrt((_cx1 - _cx2)*(_cx1 - _cx2) + (_cy1 - _cy2)*(_cy1 - _cy2));
        if (tacoR + dagonR > d) {
            //衝突しているときの処理
            stage.style.setProperty('--collision-state', 'red');
        }
        else {
            //衝突はしていないときの処理
            stage.style.setProperty('--collision-state', 'aqua');
        }
        e.preventDefault();
    }, false);
}
else {
    const input = document.getElementById("game-status");
    input.value ='お使いのブラウザはカスタムプロパティ非対応です';
}
        
これで再度、HTML/CSS/JSを試すと、以下のように「円形領域」の衝突判定が可能となるでしょう。

※以下のゲームを動かす場合、キーボード入力が受け付けないときは
ゲーム画面枠内を一度クリックしてみてください。


合同会社タコスキングダム|タコキンのPスクール【Html&Cssアプリ】Html/JavascriptとSassを使った四択クイズゲームの作り方

すぐに作れる ずっと使える Inkscapeのすべてが身に付く本

まとめ

以上、今回はブラウザからでも即時動くHTML&CSSミニゲームづくりに役立つ、「スプライトの接触判定」について実際のサンプルコードとともに解説していきました。

ただし、今回は高々2つのスプライトの接触を判定するだけだったので、とても簡単そうに見えましたが、「接触判定」の眞の難しさは上記で説明したような接触判定のそのもののアルゴリズムよりも、
「接触しそうなスプライトを効率的に探しだす」という別のアルゴリズムが重要になってきます。

こちらのアルゴリズムについても機会があればまた今後じっくり解説していきましょう。