ゲームプログラミングと数学が出会う時

中野

シューティングゲームばかり作っている中2の中野です。今回はいろいろな物理・数学に関することをここに記したいと思います(内容は至って真面目です。期待しないでください)。

微分の基礎

第一章では微分の基本中の基本について説明します。まず、微分とは読んで字の如く“微小部分で考える”ということです。たとえば正比例などのグラフの場合は直線なので、傾きが一定です(傾きの求め方:\( \frac{𝛥𝑦}{𝛥𝑥} \)(ここの𝛥というのは変化量という意味です))。しかし直線じゃない線を考えた場合に、\(𝛥𝑥\)の範囲を変えると\(𝛥𝑦\)が変わってしまいます。では例として \( 𝑦 = 4.9𝑥2 \) を考えてみましょう。

  • x=2 から x=3 の変化を考える場合
  • \[ \frac{𝛥𝑦}{𝛥𝑥} = \frac{(4.9 × 3 × 3) - (4.9 × 2 × 2)}{3 - 2} = 44.1 - 19.6 = 24.5 \]
  • x=2 から x=4 の範囲を考える場合
  • \[ \frac{𝛥𝑦}{𝛥𝑥} = \frac{(4.9 × 4 × 4) - (4.9 × 2 × 2)}{4 - 2} = 29.4 \]

上記より𝛥𝑥の範囲によって傾きが違うことがわかります。では、いよいよ本題に入りましょう。上記の変数を使って考えてみましょう。\(𝑥 = 2\)から\(𝑥 = 2 + ℎ\)の範囲まで考えることにしましょう。

\[ \frac{𝛥𝑦}{𝛥𝑥} = \frac{4.9(2 + ℎ)^2 - 4.9 × 2^2}{(2 + ℎ) - 2} = \frac{19.6ℎ + 4.9ℎ^2}{ℎ} = 19.6 + 4.9ℎ \]

微分とは“微小部分で考える”という意味でした。要はここで言う\(𝛥𝑥 = ℎ\)を極限まで小さくする(0に限りなく近づける)ということです。このℎを限りなく0に近づけることを数学で

\[ \lim_{h \to 0} 19.6 + 4.9ℎ = 19.6 \]

この19.6のことを俗に“微分係数”とよびます。ここまで微分の導入(基本中の基本)をやってきました。これで数学に興味のある人が増えたら幸いです。

ゲームにおける重力の考え方

皆さんはマ○オとかのゲームでジャンプするシーンを知っていますよね。本章ではそのようなゲームにおける、ジャンプのプログラムについて考えてみましょう。まず有名なこちらの2式を見てください。

\[ y_t = ν_0t - \frac{1}{2} gt^2 \] \[ ν^2 - ν^2_0 = -2gy_{max} \]

基本的にはこれで求めることができます。しかし、プログラミングでは初速度を考えづらい状況がほとんどですよね。よって速さの概念を無くしましょう。移項などを繰り返すと、結局\( y_t = \sqrt{2gy_{max}t} - \frac{1}{2}gt^2 \)という式が作れます。ではこれをプログラミングで表現してみましょう。ちなみに言語はC言語、テキストエディタ・デバッガはVisual Studio 2017 Community、ライブラリはDXライブラリを使っています。Visual StudioはMicrosoft社から無料でダウンロードできます。ここに詳しいことが書いてあります。DX ライブラリは「画像を表示する」とか「特定のキーを監視する」ときに便利なライブラリです。詳しいことはここからどうぞ。ではこれをプログラミングで表現してみましょう。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include DxLib.h
#include <math.h>
#define g 9.8067
#define y_max 2.000
int x = 0;
int y = 480;
int time1;
int time2;
double t;
int flag = 0;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    ChangeWindowMode(TRUE);
    if (DxLib_Init() == -1) {
        return -1;
    }
    while (CheckHitKey(KEY_INPUT_ESCAPE) == FALSE && ProcessMessage() != -) {
        if (CheckHitKey(KEY_INPUT_SPACE) == 1 && flag == 0) {
            flag = 1;
            time1 = GetNowCount();
        }
        if (flag == 1) {
            DrawPixel(x, 480 - y, GetColor(255, 255, 255));
            time2 = GetNowCount();
            t = (double)(time2 - time1) / 1000.000;
            x += 6;
            y = (int)((sqrt(2.000 * g * y_max) * t - 0.500 * g * t * t) * 480.000 / y_max);
        }
        if (y < 0) {
            ClearDrawScreen();
            flag = 0;
            y = 0;
            x = 0;
        }
        ScreenFlip();
    }
    DxLib_End();
    return 0;
}

これをVisual Studioにコピペして実行してみてください。点が放物線を描いているように見えるはずです。

二乗を表現する方法

1 2 3 4 5 6 7 8 9...などという数を二乗するとそれぞれ 1 4 9 16 25 36 49 64 81...となりますよね?本章はこれらの数列をプログラミングで表現してみたいと思います(すごく原始的です)。まず上の数列を見ると“差”は、3 5 7 9 11 13 15 17...ですよね?そうです、2 ずつ差が増えているのです。これを再現すれば皆さんでも簡単に表現することが可能です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#include <stdio.h>;
int main(void) {
    int a = 1; //二乗した数
    int b = 1; //二乗する前の数
    int s = 3; //二乗した数たちの最初の差
    while (a <= 10000) { //二乗した数の上限は 10000 まで
        printf("%d の二乗は%d です\n", b, a); //二乗した数を表示する(改行付き)
        a += s; //次の二乗した数に差を足す
        s += 2; //今の差に 2 を足して次の差にする
        b += 1; //二乗する前の数に 1 ずつ足す
    }
    return 0;
}

これをコピペしてVisual Studioで実行してみてください。右の図みたいなものができるはずです。

展示作品

  • シューティングゲーム
  • <概要>上から降ってくる緑の弾を方向キーで回避する遊び。
    <考察>弾が降ってくるときに最初の方だけ、ガガガッってなる、
    というエラーがある(未解決)。

  • アクションゲーム
  • <概要>Z キーで攻撃、X キーでガード、方向キーで移動。
    <考察>あまり完成の目処が立っていない為、文化祭で発表されない確率が微小レベルで存在。

  • 放物線
  • <概要>スペースキーの押下で、等間隔で放物線を描く。
    <考察>本部誌の第二章参照。

  • スクリーンセーバー
  • <概要>物理部と書かれた楕円が色を変えながら反射する。
    <考察>背景も RGB で次第に青っぽく、赤っぽくするようにした。思いの他、難しかった。また、楕円のサイズの関係上、物理部の端っこが楕円の色と重なり気持ち悪くなった。

    今年の僕の部誌はこれでおしまいです。来年また部誌でお会いしましょう。

次へいったいどのくらい大きな声を出せばブラジルの人に声が届くのか>
前へ投擲について>