転職を繰り返したサラリーマンの多趣味ブログ

30才未経験でSEに転職した人の多趣味ブログ

Pyxelに入門したので、画像を表示させて動かしてみる。

最近、Pyxelに入門しました。入門して環境構築をやってみたのが、前回の記事です。
uuc1h.hatenablog.jp
入門したからには、Pyxelをこれから学んでいこうと思います。
何か新しい技術を学ぼうとしたとき、これまで自分は書籍、Udemyなどの動画、体系的にまとめられたサイトなどを頼っていました。

ですがPyxelに関しては、基本的に公式リファレンスを頼りに学んでいこうと思います。
書籍や動画、サイトなどで勉強すると、それらを「終わらせる」ことが目的になってしまうことがありますからね。
github.com
リファレンスが充実しているし、翻訳ではない日本語なので読みやすいし、公式なので情報が最新というメリットだらけなので。
具体的には

  1. サンプルを実行して挙動を確認
  2. APIリファレンスを頼りに、サンプルのコードを確認
  3. サンプルから得た知識で、自分でコードを書いてみる

というのを繰り返します。

まず確認したサンプルは「01_hello_pyxel.py」です。
https://kitao.github.io/pyxel/wasm/examples/01_hello_pyxel.html
画面を表示させ、そこに画像と文字を表示させるというシンプルなアプリケーションですね。
ここでは、init関数、run関数、update関数、draw関数の挙動を確認できました。

次に確認したサンプルは「02_jump_game.py」です。
https://kitao.github.io/pyxel/wasm/examples/02_jump_game.html
普通に楽しいアクションゲームで、ドット絵もきれいで音楽もいい感じです。
なのにソースコードは130行くらいなので、驚きました。

ここでソースコードを確認する前に、ドット絵や音楽はどうなっているんだろうという方が気になりました。
PyxelにはPyxel Editorというツールが用意されていて、Pyxel Editorを使えばドット絵、音楽が作成できます。
起動コマンドは、これです。

pyxel edit リソースファイル名

自分が確認したいリソースファイルはassetsフォルダ配下にあるjump_game.pyxresなので、起動コマンドはこのようになります。

pyxel edit assets/jump_game.pyxres

無事に中身を確認できました。


サンプルのアセットまで確認できるのはいいですね。Pyxel Editorも色々できそうなので、ちょっとずつ使っていきます。


では、ソースコードの確認を行います。
大きくわけると、__init__関数、update関数、update_player関数、update_floor関数、update_fruit関数、draw関数のみで構成されています。
めちゃめちゃシンプルですね。
そして、このサンプルから学べる要素を自分なりにピックアップしました。

  • プレイヤーをキーボードで操作する。
  • フルーツと床をランダムに表示し、ゲームのフレームごとに移動する。
  • フルーツに触れたら、スコアする。
  • フルーツ、床に触れたら、プレイヤーはジャンプする。
  • プレイヤーが画面下に落下したらスコアをリセットし、プレイヤーを再表示する。

と、こんなところでしょうか。
今回は「プレイヤーをキーボードで操作する」という点に集中し、コードを書いてみました。

class App:
    def __init__(self):
        # 画面サイズ設定
        pyxel.init(SCREEN_WIDTH, SCREEN_HEIGHT, title="First Game")
        # asset読み込み
        pyxel.load("assets/jump_game.pyxres")

        # 各変数定義
        self.player_x = SCREEN_WIDTH / 2 - 8
        self.player_y = SCREEN_HEIGHT / 2 -8

        # Pyxelアプリケーション開始、フレーム更新時にupdate関数、描画時にdraw関数を呼び出す
        pyxel.run(self.update, self.draw)

    def update(self):
        # Qキーを押せばPyxelアプリケーション終了
        if pyxel.btnp(pyxel.KEY_Q):
            pyxel.quit()

        # Playerの挙動
        self.update_player()

    def update_player(self):
        if pyxel.btn(pyxel.KEY_LEFT):
            self.player_x = self.player_x - 0.5

        if pyxel.btn(pyxel.KEY_RIGHT):
            self.player_x = self.player_x + 0.5

    def draw(self):
        # 背景色指定
        pyxel.cls(0)

        # 人物表示
        pyxel.blt(self.player_x, self.player_y, 0, 0, 0, 16, 16)
        

App()

アプリケーションを開始すると画像が画面中央に表示され、キーボードの←→キーで画像が左右に移動するというもの。
サンプルとリファレンスを見れば、これくらいさっと書けるのがいいですね。

長くなってきたので、今日はこのへんで終わりです。
次回も、サンプル「02_jump_game.py」の分析を行います。

Pyxelに入門してみた。まずは環境構築。

最近ゲーム開発を全然やっていないのですが、ゲーム開発ネタは気になってしまいます。
そんな中、Xでこの記事を目にしました。
qiita.com
さくっと読める記事で、内容もすごく面白いです。基本的に何にでも感化されやすいので、さっそくPyxelに入門することにしました。

環境構築

入門するには、環境構築を行わないといけません。環境構築、けっこう躓くことがあるんですよね。
Pyxelは公式ドキュメントが充実していて(何より日本語で書かれている!)、かなーり親切に書かれています。
それでも私は躓くところがあったので、私がやった環境構築手順を紹介します。


まず最初にやったことは、Python3のインストールです。
https://www.python.org/
私は公式インストーラーでPythonをインストールしたのですが、インストール時に「Add Python 3.x to PATH」にチェックを入れ忘れないように注意が必要です。
Pyxel公式にも、「pyxelコマンドを有効にするために必要」と記載があります。

Python3のインストールが完了したら、コマンドプロンプトを起動して次のコマンドを実行します。

pip install -U pyxel

これでPyxelのインストールは完了ですが、念のために確認しましょう。

pip show pyxel

このコマンドでPyxelのバージョンやインストール場所が表示されれば、インストールは成功しています。
というように、Pyxelのインストールはさくっと終われました。


次はサンプルを実行しようと、Pyxelのサンプルコードをコピーしようとしました。

pyxel copy_examples

このサンプルは、Pyxel公式にあります。
github.com
このコマンドが、私の場合はなぜか失敗しました。Chat GPTに聞いたら、PythonのPATHが正しく設定されていない可能性があるとのことなので、Pythonのパスを指定して実行したら成功しました。

python -m pyxel copy_examples

成功したら、こんな感じで各サンプルがコピーされます。


サンプルのコピーも終わったので、次はHello World的な簡単なコードを書いて実行してみたいと思います。
で、ここで思ったのが、どのエディタ使おう問題です。普段Pythonでコードを書かないので、そこから悩みました。
で、VS Codeが使いたかったので、Visual Studio CodePython拡張機能をいくつかインストールしました。

で、さっそく以下のコードを書いてみました。

import pyxel

pyxel.init(80,64)

pyxel.cls(1)
pyxel.rect( 5, 5, 16,16, 2)

pyxel.show()

ですが、「インポート "pyxel" を解決できませんでした」とエラーがでてしまいました。
Pyxelのインストールができていることは確認済みなので、VS Codeに問題がありそうです。
ここでもChat GPTに質問すると、VS Codeでは使用するPythonインタープリタPython環境)の指定が必要とのことでした。
方法は簡単で、VS Code右下にあるPythonのバージョン部分をクリックします。(画像でいうと、3.12.3のところです。)

そうすると、Pythonインタープリタを選べます。

ここで大事なのは、PyxelをインストールしたPython環境を選択することです。私はこの設定が間違っていたため、pyxelを解決できなかったみたいです。

ということで、無事に実行が成功しました。
入門というか、やっと入門する準備が整った状態ですね。

サンプルを見ると、コードが短い!色々、出来そう!ということで、これからPyxelで遊んでいきたいと思います。

Unityでプロジェクト作成時に出るエラーを解決!Collab service is deprecated and has been replaced with PlasticSCM

Unityでプロジェクトを作成すると、「Collab service is deprecated and has been replaced with PlasticSCM」というエラーが大量に吐かれまくったという経験をしたことは多いのではないでしょうか。

原因としては、Unity Teamsのバージョン管理コンポーネントのUnity CollaborateがUnity Plastic SCMにアップグレードされるため、Unity Collaborateは廃止になるというお知らせです。

Unityのバージョン管理はGitで行っているので、自分はどちらも使いません。とりあえずエラーを止めたいと思ったら、対策方法は色々出てきました。

qiita.com

qiita.com

数ある対策方法の中で、自分が取った対策はこれです。

Project Settings / サービス / Collaborateを開き、Collaborateをオフにする。

どの方法も手間などは大差ないと思いますが、これだとUnity Editor内で操作が完結するので自分はこの方法で対処したいと思います。

時間経過によるイベント処理を簡単に実装する - コルーチンの活用法

Unityでゲームを作る際、自分は時間経過があるイベントが欠かせません。
例えば、RPGで敵を倒した1秒後に報酬品をテキスト表示するなどです。

このような時間経過のイベントには、コルーチンを使います。
ですがこのコルーチン、自分はいつも使い方を忘れてしまいます。
docs.unity3d.com
毎回調べるのも面倒なので、メモとして残しておきます。

コルーチンの使い方

時間経過が必要な処理を書く場合、戻り値の方をIEnumeratorを指定します。
また、yieldも必ず記述が必要です。

IEnumerator ShowMessage() {

    yield return new WaitForSeconds(1.0f);
    finishMessage.gameObject.SetActive(true);
    finishMessage.text = "あなたのゴールタイムは\n" + tc.timerValue.ToString("N2") +"秒です";

    retryButton.SetActive(true);

}

この処理では、ShowMessageメソッドが呼び出されたら、1秒待ってからfinishMessageオブジェクトが有効となり、テキスト表示が行われます。
秒数指定をyield return new WaitForSecounds(1.0f)で行っています。


次に、ShowMessageメソッドの呼び出し方にも注意が必要です。

StartCoroutine(ShowMessage());

このように、StartCoroutineメソッドの引数に呼び出したいメソッドを指定する必要があります。

コルーチンの停止方法

コルーチンをスタートさせたら、止めたい場合もあると思います。
その時は、StopCoroutineを使います。

StopCoroutine(ShowMessage());

StopCoroutineは止めたいコルーチンを引数に指定していますが、複数のコルーチンをまとめて止めたい場合はStopAllCoroutinesを使います。

StopAllCoroutines();

docs.unity3d.com
docs.unity3d.com

自分の場合は、ここらへんを理解できていればゲームを作りで困ることはありません。

レースゲームで、スタートと同時に時間カウントアップの計測を開始させる方法について

unityroomに投稿した以下ゲームですが、車を操作するゲームです。
unityroom.com
車を操作するスクリプト自体はよくあるものなんですが、車をスタートさせると時間カウントアップを開始させるようにしました。
今後のために、メモとして残しておきます。

車の制御について

private void Update() {

    float steerAmount = Input.GetAxis("Horizontal") * steerSpeed * Time.deltaTime;
    float moveAmount = Input.GetAxis("Vertical") * moveSpeed * Time.deltaTime;

    transform.Rotate(0, 0, -steerAmount);
    transform.Translate(0, moveAmount, 0);

}

steerAmountが曲がる速度、moveAmountが直線の速度です。
こういった移動関連の実装では、Time.deltaTimeを使うことがお約束になっています。

Time.deltaTimeを使う意図として、フレームレートによる動きの差異を減らすためとは分かっているのですが、いつも何となく使っていました。

ちゃんと理解できていなかったので調べてみたら、以下の記事がかなり丁寧にまとめられていました。
qiita.com
nekojara.city

時間カウントアップの開始タイミングについて

時間カウントアップは、以下のように実装しました。
uuc1h.hatenablog.jp
この時間カウントアップを開始するタイミングを、車を操作するためにキーボードの矢印キーを押した瞬間にしたいと思いました。
そこで、さきほどのスクリプトを以下のように変更しました。

private void Awake() {

    timer = FindObjectOfType<TimersComponent>();
    isStart = false;

}

private void Update() {

    if (!timer.countFlg && Input.GetAxis("Vertical") > 0 && !isStart){

        timer.countFlg = true;
        isStart = true;

    }

    float steerAmount = Input.GetAxis("Horizontal") * steerSpeed * Time.deltaTime;
    float moveAmount = Input.GetAxis("Vertical") * moveSpeed * Time.deltaTime;

    transform.Rotate(0, 0, -steerAmount);
    transform.Translate(0, moveAmount, 0);

}

Updateメソッドにあるif文の制御で、timer.counfFlgをtrueにすることで、カウントアップを開始します。
実装方法はともかく、思った通りに動いてくれるので結果としては満足しています。

unityroomに投稿したゲームのBGMとSEの制御方法

久しぶりにunityroomに投稿した以下ゲームより、メモとして残しておきたい部分を記しておきます。
unityroom.com

BGMとSEの制御について

BGMとSEは、1つのゲームオブジェクトにAudio Sourceコンポーネントを2つ追加して制御しています。
1つがBGM用、もう1つがSE用という感じで。

こうすることで、BGMのボリュームだけ大きくしたり、SEのボリュームを小さくしたりといったことが可能なので重宝しています。

制御に使っているスクリプトは、以下の通りです。

 [SerializeField] AudioSource audioSourceBGM;

 [SerializeField] AudioClip[] audioClipsBGM;

 [SerializeField] AudioSource audioSourceSE;

 [SerializeField] AudioClip[] audioClipsSE;

 public static SoundManager instance;

 private void Awake() {
        
     if (instance == null) {

            instance = this;

     }

}

void Start()
{
    audioSourceBGM.Stop();

    audioSourceBGM.clip = audioClipsBGM[0];
    audioSourceBGM.Play();

}

public void StopBGM() {

    audioSourceBGM.Stop();

}

public void PlaySE(int index) {

    audioSourceSE.PlayOneShot(audioClipsSE[index]);

}  

BGMとSEの音源を、配列として格納可能にしています。

今回作ったゲームでは、BGM音源を1つ、SE音源を3つセットしています。
スクリプトに戻りますと、BGM音源は1つだけなのでStart()メソッドで再生しています。
SE音源に関しては、PlaySE(int index)メソッドを作成し、外部クラスから再生できるようにしています。引数によって、3つあるうち任意のSE音源が再生可能です。

AWSクラウドプラクティショナー合格の勉強方法と経験談

AWSクラウドラクティショナーを受験して、無事に合格しました。
記憶の新しいうちに、自分がやってきた勉強内容などを記録しておきます。

はじめに

自分はIT業界に8年ほどいますが、AWSは未経験でした。それが、2023年に参画した現場でAWSを使用しており、全く会話についていけなかったので受験を決意しました。
そのため、AWSの経験は全くの未経験からスタートしました。

ちなみに勉強した期間は、2か月です。

勉強したこと

  1. AWS認定クラウドラクティショナー 改訂第2版(AWS認定資格試験テキスト)
  2. 【CLF-C02版】この問題だけで合格可能!AWS 認定クラウドラクティショナー 模擬試験問題集(6回分390問)

勉強したことは、この2つのみです。ただ、結果としてAWS認定資格試験テキストは最後まで読んでいないです。途中までしか読んでおらず、結構流し読みでした。
なので、Udemyの講座であるAWS認定クラウドラクティショナー模擬試験問題集をひたすらやっていました。

www.udemy.com

この講座ですが、試験6回分の問題集で構成されています。

まずは、基本レベル①と基本レベル②を全問合格するまで繰り返し解きました。
この講座は解説が充実しているので、「問題を解く→解説を見る」でかなり知識がつきます。なので、結果としてAWS認定資格試験テキストを最後まで読まなかったです。

基本レベル①、基本レベル②が満点になったら、本番レベルにチャレンジします。
基本レベルの知識はしっかりついたので、本番レベルもスラスラ解けると思いきや、40%ほどしか解けず、ここで出鼻をくじかれます。
本番レベルでは、基本レベルでは出てこなかったサービスが多く出てきたり、基本レベルに出てきたサービスであっても、問題の問われ方が違ったりと、難易度はかなり上がります。

で、実際の試験の難易度は、本番レベルでした。

そのため、本番レベルも解けるようにしておく必要があります。

実際の試験を受けて

実際に試験を受けた所感としては、Udemy講座の本番レベルと同程度の難易度だったと感じました。あと当たり前ですが、Udemy講座と全く同じ問題はありませんでした。
似たような問題はありましたが、Udemy講座の解説をしっかり読んで理解していないと、解けない問題が多かったです。

あと、AWSクラウド導入フレームワークのセキュリティパースペクティブや、AWS Well-Architectedは、かなり勉強しておいたほうがいいです。あくまで感覚ですが、これらの問題が多かったと思います。

docs.aws.amazon.com

aws.amazon.com

最後に

ここに書いた勉強方法で、無事に合格しました。ただ点数としては、合格ラインギリギリでしたね。上に書いた、セキュリティパースペクティブAWS Well-Architectedをもっと勉強しておけば、もう少し点数はよかったと思います。

自分の経験をつらつらと書きましたが、これから受験する人の参考に少しでもなれば嬉しいです。