ゲーム制作 環境原猫 9日目

OpenGLのポイントスプライトで、昨日作成した水分子を描画するためにどうすればよいか、本日は調査を行います。

情報源としては

この本を買う

このリポジトリを見る

このブログを見る

などがありそうです。

サクッとこの本を買って勉強したいところですが、目次を見る限りあまり詳しく解説されているように見えないので、このリポジトリこのブログを本日は調べました。

次の日

ゲーム制作 環境原猫 8日目

昨日はゲームウィンドウをフルスクリーン化しました。

今日は、いったんコードから離れて”水分子”の画像を作成します。

新ゲームはシミュレーションで、分子レベルでくっついたり離れたりの相互作用まで計算しようと思っています。

画像同士が重なりあったりするのでアルファ値も考慮する必要があり、GIMPを使って画像を作成します。

このページからGIMPをダウンロードしてインストールし、アルファチャネル付きの画像を作成します。

12×12ドットの”水分子”画像が出来ました。

(੭ ˃̣̣̥ ω˂̣̣̥)੭ु⁾⁾

鉛筆ツールで1ドット単位で描きました。透明度ごとにレイヤーを分けて作成しています。

この”水分子”画像をできれば数百万個描画したく、パフォーマンスを出すためにOpenGLのポイントスプライトで実装予定です。

今日は以上です!

次の日

ゲーム制作 環境原猫 7日目

今日は前々回作成したウィンドウをフルスクリーンにします。

ソースコードのどこをいじればフルスクリーンになるか考えます。

#![windows_subsystem = "windows"]
extern crate sdl2;
extern crate gl;

use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::video::GLProfile;

fn main() {
    let sdl_context = sdl2::init().unwrap();
    let video_subsystem = sdl_context.video().unwrap();
    
    let gl_attr = video_subsystem.gl_attr();
    gl_attr.set_context_profile(GLProfile::Core);
    gl_attr.set_context_version(3, 3);

    let window = video_subsystem.window("Window", 800, 600)
        .opengl()
        .build()
        .unwrap();

    // Unlike the other example above, nobody created a context for your window, so you need to create one.
    let ctx = window.gl_create_context().unwrap();
    gl::load_with(|name| video_subsystem.gl_get_proc_address(name) as *const _);
    
    debug_assert_eq!(gl_attr.context_profile(), GLProfile::Core);
    debug_assert_eq!(gl_attr.context_version(), (3, 3));

    let mut event_pump = sdl_context.event_pump().unwrap();

    'running: loop {
        unsafe {
            gl::ClearColor(0.6, 0.0, 0.8, 1.0);
            gl::Clear(gl::COLOR_BUFFER_BIT);
        }

        window.gl_swap_window();
        for event in event_pump.poll_iter() {
            match event {
                Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
                    break 'running
                },
                _ => {}
            }
        }
        ::std::thread::sleep(::std::time::Duration::new(0, 1_000_000_000u32 / 60));
    }
}

次の行が怪しそうです。

let window = video_subsystem.window("Window", 800, 600)

video_subsystem変数はsdl_context変数から生成されており、sdl_context変数はsdl2::init().unwrap()で生成されています。sdl2のcrateのマニュアルを見てみます。

ソースコード上でsdl2::init()してから、sdl_context.video()としているので、videoモジュールのリンクをクリックしてみます。

すると、Structの中の

WindowBuilderThe type that allows you to build windows.

が怪しそうなので、WindowBuilderをクリックします。

すると、fullscreen_desktopというメソッドがありました。これを使ってみます。

・・・成功しました!(私のデスクトップ上で)

‹‹( ´ω`)/››

皆さんも成功したでしょうか?

成功したらVSCode上でcommit & pushしてソースをアップしてください。うまくいったでしょうか?

(ついでにWindowのタイトル名も変えておきました)

今日は以上です!

次の日

ゲーム制作 環境原猫 6日目

昨日までで準備はほとんど終わりました。これからゲームを本格的に開発していきたいところですが、その前にGitを導入したいと思います。

Gitの効能

・何か機能追加して動かなくなってしまったとき、ソースを過去の動く時点に戻せる

・GitHubなどを使えばソースのバックアップになる

・複数人で共同開発できる

(੭ ˃̣̣̥ ω˂̣̣̥)੭ु⁾⁾

あと何かありますかね?

とにかくあったほうが便利なので導入します。

このページからダウンロードしてインストールします。インストール手順は調べればいっぱい出てくるので省略します。

インストール後、Git Bashを起動してユーザ名とメールアドレスを登録しておきます。

git config --global user.name "ユーザー名"

git config --global user.email "メールアドレス"

インストール後、VSCodeでcargo newコマンドにより作成したフォルダを開くと、既にGit管理対象になっていると思います。

左の枝分かれしているようなアイコン(Source Control)を押して、Message欄に何かコメント(Initial commitとか)を入れて、Commitボタンを押します。

そのあとは、Publish Branchボタンを押してGit Hubなどに登録しましょう。(Git Hubのアカウントを持っていない方はあらかじめ作成してください)

うまくいけば以下のようにGitHubにファイルを登録できます。

今日は以上です!

次の日

ゲーム制作 環境原猫 5日目

昨日はRustで利用するライブラリを決定しました。本日は決定したライブラリrust-sdl2を導入してウィンドウを表示します。

まずRust-SDL2のページからライブラリをダウンロードします。Windows環境の場合、SDL2-devel-2.26.2-VC.zipをダウンロード(2023年1月5日時点)します。

解凍後に生成された3つのlibファイルをRustのlibフォルダ内にコピーします。

コピー元:SDL2-2.26.2\lib\x64\*.lib (解凍ファイル)

コピー先:C:\Program Files\Rust\lib\rustlib\x86_64-pc-windows-msvc\lib (デフォルトインストールの場合)

次に、Cargo.tomlファイルの[dependencies]に、SDL2のcrate(一般的な言い方はライブラリ)を使うための記述を追加します。

[dependencies]
sdl2 = “0.35”
gl = “0.14.0”

glは、OpenGLのために必要です。

これで準備が整いました。ウィンドウを表示するようにmain.rsを書き換えます。(Rust-SDL2のページのサンプルコード)

extern crate sdl2;
extern crate gl;

use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::video::GLProfile;

fn main() {
    let sdl_context = sdl2::init().unwrap();
    let video_subsystem = sdl_context.video().unwrap();
    
    let gl_attr = video_subsystem.gl_attr();
    gl_attr.set_context_profile(GLProfile::Core);
    gl_attr.set_context_version(3, 3);

    let window = video_subsystem.window("Window", 800, 600)
        .opengl()
        .build()
        .unwrap();

    // Unlike the other example above, nobody created a context for your window, so you need to create one.
    let ctx = window.gl_create_context().unwrap();
    gl::load_with(|name| video_subsystem.gl_get_proc_address(name) as *const _);
    
    debug_assert_eq!(gl_attr.context_profile(), GLProfile::Core);
    debug_assert_eq!(gl_attr.context_version(), (3, 3));

    let mut event_pump = sdl_context.event_pump().unwrap();

    'running: loop {
        unsafe {
            gl::ClearColor(0.6, 0.0, 0.8, 1.0);
            gl::Clear(gl::COLOR_BUFFER_BIT);
        }

        window.gl_swap_window();
        for event in event_pump.poll_iter() {
            match event {
                Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
                    break 'running
                },
                _ => {}
            }
        }
        ::std::thread::sleep(::std::time::Duration::new(0, 1_000_000_000u32 / 60));
    }
}

cargo buildコマンドでビルドします。

ワーニングが出ました。使っていない変数の指摘ですね。気になるようなら指示通り変数名を ctx から _ctx に変更しましょう。

最後にcargo runで実行します。すると

error: process didn’t exit successfully: target\debug\env_pri_cat.exe (exit code: 0xc0000135, STATUS_DLL_NOT_FOUND)

というようなエラーが出ると思います。exeがあるtarget\debugフォルダに必要なdllをコピーします。

コピー元:SDL2-2.26.2\lib\x64\SDL2.dll (解凍ファイル)

コピー先:target\debug\SDL2.dll

もう一度、cargo runで実行します。

どうでしょうか?ウィンドウが表示されたでしょうか?

私のWindows環境ではオーバーレイでFPS情報等を表示するツール(RivaTuner Statistics Server)を入れているので色々文字が表示されていますが、紫色のウィンドウが表示されたかと思います。

おめでとうございます!

これであとは中身を作るだけです!完成した際は、Steam向けにexeとSDL2.dll の最低2ファイルを提供すれば良さそうですね。

最後に、生成されたexe をエクスローラから直接実行すると、余分なウィンドウが表示されてしまうと思います。 main.rsの先頭に以下の1行を追加することで防げます。

#![windows_subsystem = "windows"]

今回は以上です!

(੭ ˃̣̣̥ ω˂̣̣̥)੭ु⁾⁾

次の日

ゲーム制作 環境原猫 4日目

昨日はRustでの儀式が成功しましたが、Rustオンリーではゲームに必要なウインドウ表示、入力イベント処理、サウンド再生が(効率よく)出来ません。

そこで、Rust向けのゲームライブラリ/ゲームエンジンを利用します。

候補としては、

rust-sdl2 — SDLのRust向けバインディング 。SDLとはC言語で書かれたクロスプラットフォームのマルチメディアライブラリで、広く利用され安定している。2はバージョン。

Bevy — Amethyst後継。ECS (エンティティ、コンポーネント、システム)にプログラム分割するソフトウェアパターンを利用

Fyrox — Rustで書かれた機能豊富で量産可能な汎用2D/3Dゲームエンジンとシーンエディタ

piston — OpenGLをラッピングしているらしい

Tauri — UIにReactやVue.jsのようなJavaScriptフレームワークがそのまま使える

などがあるようです。

最適なゲームライブラリ/ゲームエンジンは、自分の作成したいゲームの内容で変わると思います。

私の場合、まだおぼろげにしかゲーム内容を決めてないので、まずは一番低水準であろうrust-sdl2を選択します。今後必要に迫られた時点で、他のライブラリ/ゲームエンジンも導入していければと思います。

次回はrust-sdl2を使うよ!

(੭ ˃̣̣̥ ω˂̣̣̥)੭ु⁾⁾

次の日

ゲーム制作 環境原猫 3日目

昨日はRustをインストールしました。今日は

大切な儀式(Hello, world!)

を行います。cargo new コマンドを使ってプロジェクト用フォルダを作ります。

D:\Library\Documents\My Work\Rust>cargo new env_pri_cat --bin
Created binary (application) env_pri_cat package

D:\Library\Documents\My Work\Rust>cd env_pri_cat

cargo runコマンドでコンパイル&実行します。

D:\Library\Documents\My Work\Rust\env_pri_cat>cargo run
Compiling env_pri_cat v0.1.0 (D:\Library\Documents\My Work\Rust\env_pri_cat)
Finished dev [unoptimized + debuginfo] target(s) in 1.16s
Running target\debug\env_pri_cat.exe

Hello, world!

問題なく儀式を終えました!

(੭ ˃̣̣̥ ω˂̣̣̥)੭ु⁾⁾

ソースコードはsrcディレクトリ内のmain.rsにあります。

fn main() {
    println!("Hello, world!");
}

メモ帳や秀丸を使ってソースを書きたくないので、コードエディタとしてVSCodeを利用したいと思います。

こちらのページからインストーラをダウンロードします。

私はWindows環境なので、Windows用の「System Installer」x64 を選択してインストールしました。(インストールオプションはデフォルト)

初回起動時、外観を選べます。私は目に優しそうな「Dark」にしました。

「File」メニューから「Open Folder」で、先ほどcargo newで作成したenv_pri_catフォルダを選択します。

Do you trust the authors of the files in this folder? (このフォルダ内のファイルを信頼する?)と聞かれるので、Yesを選択します。

すると、左ペインからソースを選択して表示できます。「Terminal」メニューから「New Terminal」を選択するとコマンドが打てるので、そこからコンパイルや実行が出来ます。

VSCodeにはRust用の便利な拡張機能があります。今後、順次必要に応じて追加予定です。

次の日

ゲーム制作 環境原猫 2日目

開発言語がRustに決まったので、さっそくインストールしていきます。

Steam用ゲームの開発はWindows環境でも行えるし、開発ツールも限定されないので、とっても嬉しいです。

(੭ु ›ω‹ )੭ु⁾⁾♡

iOS用のアプリ開発はMacでなければ行えませんでした(リリースには必ずMacが必要)。開発ツールのXcodeは、はっきり言ってバグだらけでお世辞にも使いやすいツールではありませんでした。

アプリの提出手続きも分かり難く、毎回手順を忘れてしまうんですよね・・・。それらの手続きから解放されると思うととっても嬉しいです。

このページから、RUSTUP-INIT.EXE(64-BIT)をダウンロードし、実行します。

Install the C++ build tools before proceeding.

と、赤い文字でC++のビルドツールが必要であると警告が出た場合は、こちらのページからビルドツールをダウンロードします。

ビルドルーツのインストーラを起動し、「C++によるデスクトップ開発」から「MSVC v143 VS 2022 C++ x64/x86 build tools」と「Windows 11 SDK」を選択してインストールします。

ビルドツールのインストールが終わったら、最初のRustインストーラRUSTUP-INIT.EXE(64-BIT)を再度実行します。

すると、今度は赤文字の警告は表示されず、

1) Proceed with installation (default)
2) Customize installation
3) Cancel installation
>2

のように選択肢が表示されます。今回は 2 を指定しました。

I’m going to ask you the value of each of these installation options.
You may simply press the Enter key to leave unchanged.

Default host triple? [x86_64-pc-windows-msvc]

プラットフォーム名?はデフォルトのままにします。エンター押下。

Default toolchain? (stable/beta/nightly/none) [stable]

ツールチェインは、stable:安定版、beta:テスト版、nightly:最新開発版があるようです。安定版にしたいのでエンター押下。

Profile (which tools and data to install)? (minimal/default/complete) [default]

どのツールとデータを入れるか?最小、標準、完全から選択。標準で良さそうなのでエンター押下。

Modify PATH variable? (Y/n)

環境変数のパスを追加するか?Yを指定。

Current installation options:

default host triple: x86_64-pc-windows-msvc
default toolchain: stable
profile: default
modify PATH variable: yes

1) Proceed with installation (default)
2) Customize installation
3) Cancel installation
>1

現在の設定が表示されるので、今度は1でインストール実行。

info: profile set to ‘default’
info: setting default host triple to x86_64-pc-windows-msvc
info: syncing channel updates for ‘stable-x86_64-pc-windows-msvc’
info: latest update on 2022-12-15, rust version 1.66.0 (69f9c33d7 2022-12-12)
info: downloading component ‘cargo’
info: downloading component ‘clippy’
info: downloading component ‘rust-docs’
19.0 MiB / 19.0 MiB (100 %) 10.8 MiB/s in 1s ETA: 0s
info: downloading component ‘rust-std’
27.1 MiB / 27.1 MiB (100 %) 11.0 MiB/s in 2s ETA: 0s
info: downloading component ‘rustc’
65.4 MiB / 65.4 MiB (100 %) 10.8 MiB/s in 6s ETA: 0s
info: downloading component ‘rustfmt’
info: installing component ‘cargo’
info: installing component ‘clippy’
info: installing component ‘rust-docs’
19.0 MiB / 19.0 MiB (100 %) 3.6 MiB/s in 3s ETA: 0s
info: installing component ‘rust-std’
27.1 MiB / 27.1 MiB (100 %) 17.2 MiB/s in 1s ETA: 0s
info: installing component ‘rustc’
65.4 MiB / 65.4 MiB (100 %) 19.0 MiB/s in 3s ETA: 0s
info: installing component ‘rustfmt’
info: default toolchain set to ‘stable-x86_64-pc-windows-msvc’

stable-x86_64-pc-windows-msvc installed

– rustc 1.66.0 (69f9c33d7 2022-12-12)

Rust is installed now. Great!

To get started you may need to restart your current shell.
This would reload its PATH environment variable to include
Cargo’s bin directory (%USERPROFILE%.cargo\bin).

Press the Enter key to continue.

インストールが完了しました。コマンドプロンプトを立ち上げなおして、rustup update と打ち込んでパスが通っている事と、最新版であることを確認します。

D:\Library\Documents\My Work\Rust>rustup update
info: syncing channel updates for ‘stable-x86_64-pc-windows-msvc’
info: checking for self-updates

stable-x86_64-pc-windows-msvc unchanged – rustc 1.66.0 (69f9c33d7 2022-12-12)

info: cleaning up downloads & tmp directories

rustup self update と打ち込んで、rustup自身も最新であることを確認します。

D:\Library\Documents\My Work\Rust>rustup self update
info: checking for self-updates
rustup unchanged – 1.25.1

Rustのインストールが完了しました。長くなったので今日はここまでにします。

次の日

ゲーム制作 環境原猫 1日目

2023年元旦より、新たなゲーム制作を開始したいと思います。

(੭ु ›ω‹ )੭ु⁾⁾♡

最近はアプリ制作に飽きた、というかAppleのiPhone、というかiOSが肥大化してシンプルじゃなくなってきて嫌いになってきたので、スマホ向けではなくてSteam向けにWindows環境で何か熱のこもった面白いゲームを作りたいと思っています。

Steamでゲーム出したい方は必見!

このブログを毎日見て真似れば、Steamで自分だけのゲームが公開出来るようになるよ!

たぶん・・・

制作するゲーム内容は猫を進化させるシミュレーションにしたいと思っています。なんか過去に似たようなアプリ作ったけど、今回はハードウェアを限界まで使ってCPUに悲鳴を上げさせるようなやつにしたいです。

ということは開発言語としてC++を選定するのが良いと思うのですが、メモリ周りでデバッグに苦労するのは嫌なのでRustを使おうと思っています。

ゲーム制作でRustを使うのはまだまだ普通じゃないのか、ゲーム用ライブラリ/フレームワークが充実してない気がしますが、低水準部分から作るのも楽しそうなのでRustで作ろうと思います。

2023年の目標

1日最低30分毎日ゲーム開発

(੭ ˃̣̣̥ ω˂̣̣̥)੭ु⁾⁾

あ、バックエンドはRustで確定だけど、移植性考えてフロントは別の仕組みにする予定です。(候補案:WebGL/WASM)

次の日

実録!アプリ申請リジェクト — その後

あまりだらだら続けてもしょうがないので、その後の経緯をざっくりまとめ、最後に対処方法を書いてみます。

その後の経緯:

 App Store Connectサイトでアプリのメタデータを更新できなかった件については、その後1か月くらい経過した時点でいつの間にか更新できるようになっていました。さすがに開発者皆が利用しているサイトなので、どこかの時点でAppleが対応せざるを得なくなったと推察します。

「あなたのID」は、いつどこで利用するのですか?の質問ですが、これに関しては画面遷移図を作成し、トップ画面からどのような経路で「あなたのID」がある画面にたどり着くか、また「あなたのID」部分を赤まるで囲って、画像を見た瞬間に誰でもわかる形にしたところOKになりました。驚くことに、その後再度「あなたのID」は、いつどこで利用するのですか?と同じ質問が来たりしてびっくりしましたが、再度同じ画像を提示して事なきを得ました。

「利用規約(EULA)」と「プライバシーポリシー」の件についても、画面遷移図を作成し、赤まるで囲って”ここにあるよ”と明示したら通りました。

その後も、具体的な内容は省きますが上記以外の質問を5,6問ほど次々にされました。それも一度にではなくこちらが回答を返す度に、モグラたたきのように目についたから今回はこの質問!というような形でリジェクトと共に質問を投げられました。この審査員の方の仕事のやり方には疑問を感じざるを得ません。

対処方法:

アプリ審査員は当たり外れがある気がします。過去5,6アプリほど申請してリジェクトを喰らうことは全くなかったのですが、今回は急にリジェクトの嵐でした。

肝心の対処方法ですが、私が今回当たった審査員の場合、相手をスマホをさわったことのないIT素人だと思ったらうまくいきました。

こちらで当然だと思うことは全く通じないので回答として直感的に理解できる画像を多用しました。

明らかに審査員の落ち度だと思ってもそれを指摘せず、無感情で淡々と、誰にでもわかりやすい表現(画像)で説明しました。

付け加えると、こちら(開発者)に寄り添うような姿勢はみじんもなかったので、まじめな方ほど感情的になってしまい審査がうまくいかない気がします。

感情を殺して、素人相手だと思って過剰すぎるほど分かり易い回答を淡々と返すのが最善かと思います。

以上です。アプリ開発者の方に少しでもこの経験がお役に立てば幸いです。

大手には作れないアプリを(気持ちだけは(๑•̀ㅂ•́)و✧)