ゲーム作りは楽しい

なんか書く

セガ本 進捗 2

Chapter2を読みました

VRAMに色情報書き込んで描画しようみたいな章だったのですが、残念なことに指定されたライブラリがうまくリンクできなかった。(IDEのバージョンが違うからだと思います。) ので、仕方なく流し読み

そのままChapter3も読み途中です。 本日はここまで

セガ本読み始めました

感謝

もうすぐゲームプログラマ3年目くらいなのですが
ゲームプログラマになる前に覚えておきたい技術」を友人からプレゼントで頂きました。
ありがとうございます。(持ってなかったので欲しかった)

ただ、2年間サーバーエンジニアしてた身からするとゲームプログラマとはいえこの本が言うようなゲームプログラマではなかったかもしれないのでいい機会
初心にかえろう

Chapter1を終えました

なんか、コンソールでごねごねするゲームを作りました。
コンソールで完結させるようなものを当分作ってはいなかったのでなんか初心に戻ったかもしれない笑

クソワンデッキデュエル

ワンデッキデュエルとは

カードキングダムで紹介された1つのデッキを使って昔ながらの遊戯王を楽しむゲームです。

本家はポケモンカード等たまに出てくるが、基本は遊戯王の原型を保ち、遊戯王が好きな人、好きだった人が楽しめるような構築になっています。

作ったデッキ

さて、私も最近ワンデッキデュエルを遊んでいるのですが、もはや遊戯王の原型を保てないほど沢山のカードゲームのカードが入っており、なんのゲームだかわかりません笑。他のゲームの名詞は遊戯王の名詞と置き換えて無理やり遊んでいます。(クリーチャーはモンスターと同義など)
ただ、厳密にルールを決めてると言うよりは柔軟に翻訳をして雑に遊んでいます。

そんな感じで雑なので「クソワンデッキデュエル」とでも名乗ることにします。

いろいろ突っ込んでいた結果、最近デッキ枚数が120枚を越えてきたので、圧縮版のデッキも組みました。

f:id:mahou_ptr:20200222191829j:plain


自分のルールでは生贄はなしで遊んでいるので、ブルーアイズとかはいきなり出して構いません。

また、ひとつのカードに複数のカードが含まれてたりもして、むちゃくちゃです。
(重なった魔法など発動は1度までですが死者蘇生した場合は再度使用できます)

f:id:mahou_ptr:20200222192657j:plain:w150

そんな感じで、遊戯王というルールに上乗せする形で、色んなカードゲームのカードを見ては、これを入れたら盛り上がりそう!みたいなことを考えながら遊びを作っています。

2019 10~12月 アニメ/ゲーム感想

まえがき

もともと仕事の中で個人的に始めたやつなんですが、遊んだゲームの感想とかをまとめてました。
勿体ないのでブログにも記載しようかと思ってこちらにも記載します。
あと最近、アニメは全然見れてないです。

今期見たアニメ

ゲームがメインでアニメがそれの追尾のはずだが、発売延期によりゲーム発売される前にアニメが先に終わってしまった。
レベルファイブの日野社長のブログによると発売予定していたゲームをタイトルを変えて2020年に4月発売予定とのこと
イナズマイレブンの新作はiOS aOS switch ps4クロスプラットフォームが予定されていたのもあり、各ハードでの操作感やグラフィックなどが気になっています。
(アニメ放送自体はもっと前ですが終わったと知ってdアニメで見ました)

今期遊んだゲーム

  • moon

有名な作品らしいですが、プレイしたことがなかったのでやってみました。
敵と戦わないアンチRPG
個性的なキャラクターが魅力的で面白かったのと、無茶ぶりくらいな謎解き要素が多く難しい印象でした。
BGMが自分で何を流すか選べるというのはRPGにしては珍しいとも思いました。
(でも金をためてbgmを買うので攻略に必要なもの以外ほぼ買わなかった)
名作にはキャラが個性的なものが多くUndertaleとかも影響を受けた作品なんじゃないかと思いました。(敵を倒さない所なども含め)

ドラクエシリーズではかなりの人気作でしたがクリアまでプレイしたことがなかったのでやりました。しんりゅうを倒しました。
性格によってパラメータの上がり幅が変わるシステムだったのを初めて知り、他のドラクエにはなかったシステムだったので驚きました。
これだけのボリュームのものをFCでつくらているのはやはりすごいなと思ったのと
昔から人気なコンシューマのシリーズ作品はFCの時代から明らかにクオリティの高いものを作れていると改めて思いました。

ジャンプ後方向転換できないとか、床から落ちる場合にx軸の速度が無視されて真下に垂直に落ちるなどの操作性がとても気持ちよくなかった印象でした。(関連シリーズの「デモンズブレイゾン」も遊びましたがこちらは操作性がかなり改善されていた)
また、同じステージを最低でも2周もさせられるという仕組みが面倒臭かった。
ラスボスに挑むためにはランダムドロップの専用の武器を必ず装備する必要があり、そうでない場合はなんどもラス面をやらされるという辛い設計でした。
もともとACだったのもありそう簡単にクリアさせない意図があったのかなと思います。
エンディングのスタッフがみんなニックネームで書かれていたのがみていて面白かった。

  • 戦え原始人3

全然知らない作品だったのですが、switchのスーファミにあったので一通り遊んでクリアしました。
操作性としては、ダッシュと攻撃とジャンプとしゃがむ くらいですが
ダッシュ中は攻撃できなかったのでスピード感もって進むことはできなかった。
ただ、そこがこのゲームの駆け引きの部分だったのかもしれない。
ステージの途中で遠距離型の武器が隠されていて入手するとかなり有利に戦えるようになったのがすごく楽しかったし気持ち良かった。
ラスボスだけすごく理不尽な攻撃をしてきたのが辛かった。
(僕が攻略できてないだけかもしれません。)

MMORPG自体が実は初めてでわくわくしました。
通りがかりの戦闘中のプレイヤーに応援してあげることで手助けができる機能があり(応援するとテンションがあがる)、自分も知らない人に応援してもらえて嬉しかったし、そのあとフレンドになれたという成功体験ができました。
また、オンラインゲームとはいえ一人で遊ぶ機会が多いと思いますが、野良の人とパーティを組むのは少し敷居の高さがあると思います。
なので、休憩中のプレイヤーをAI行動でレンタルできる機能があり一人プレイでも問題なく楽しむことができました。
ストーリーは全体として新しい城についたら必ず困ってる人がいてイベントがある。攻略すると進むという統一された形になっていたのでわかりやすかった。(自分はまだver1までの範囲ですが)
サーバーは細かく別れていて、初心者・カムバック専用/ソロ専用/学生専用/実況者専用/etc...
同じ目的や状況に合わせたサーバー選びができたのがいいなと思いました。
もちろん自分の場合は迷わず初心者サーバーに入れりました。
また、オンラインというのもあって他のドラクエ以上に育成はサクサクできた印象です。
レベル80未満の間は経験値2倍の装備が最初で手に入ったり、初心者サーバー限定で毎日定時にメタル系が必ず出てくる時間があったりしました。

さすがにまだクリアはしていないので今後ものんびり進めていきたいです。

3Dがより強化されて広い世界を冒険している印象が今まで以上に感じられワクワク感がすごかったです。特にワイルドエリアという他のプレイヤーとも繋がれる場所が広い。
また、町も魅力的な町が多くて良かった。
育成面は従来の「がくしゅうそうち」が廃止されてデフォルトで手持ちポケモン全員が育つようになったのでストーリーもサクサク進めれて良かった印象です。
自分はバトルガチ勢ではないので厳選やガチ育成はしないのですがそこら周りもより良くなっている印象でした。
新アイテムの「けいけんちアメ」でレベル上げが早かったり、ポケモンの性格補正を変えれるアイテムがでたりしていました。
毎回ポケモンの新作を遊ぶたびに思うことですが、このゲームはいろんな楽しみ方がされているゲームだからすごくいいし、かつ毎度それら全てに磨きがかかっている気がしています。
(ストーリー、育成、バトル、図鑑コンプ、ポケモンとのふれあい etc)

転職します。

先に言いますが、転職エントリではないです。 あの文化好きじゃない。


いろいろあり、次もまたゲーム業界ですが
ソーシャルゲームのサーバーエンジニア ⇒ コンシューマー
といった感じで、同じゲームプログラマーですが全く違った方向に行きます。

でも、もともと興味があった分野なので楽しみです(あと不安やプレッシャーもいい感じに感じてます)

もともと知識がゼロだったのもあり、学んでみたいと思い約二年サーバーエンジニアをやらしてもらってました。
ゲームプログラマーを目指す人たちって目に見えるアプリケーションのとことかに意識を向けがちでサーバーのこととか良くわからなかったりするのかなと思います。(自分もそうでした)
やってみて思ったのは、確かに目に見えないところではあるが自分はゲームを作っているぞという感覚は決して失われなかったので結構楽しいじゃんといった感じでした。
まぁこれは人や会社によっては変わるかも。。

ソーシャルゲームのサーバーということでたくさんのユーザーを抱えたサービスにもなるので、そういった経験を仕事の中で学べたのはよかったなと思っています。

リポジトリに別れを告げるのを忘れてた。。まぁいいけど(笑)

さて、またこれからリスタートにはなりますが頑張っていきます。

ハッシュドポテトの作り方 C++編

はじめに

本記事はネタである。 ハッシュドポテイトうんめなー

今日もハッシュドポテイト食べたいなー

よし、作ろう

1. ポテトを用意する

// ポテト
struct 
{
    std::uint8_t taste;     // 味
    std::uint8_t fragrance; // 香り
    std::uint8_t freshness; // 新鮮さ
    std::uint8_t size;      // 大きさ
};

まずはポテトを用意した。 評価する要素として、テキトーに4つ用意した

2. ポテトの下ごしらえ

ハッシュドポテトを作る前にきっちり水で洗い、皮をむきましょう。特に芽には気をつけましょう。

// ポテト
struct Potate
{
    union
    {
        struct 
        {
            std::uint8_t taste;     // 味
            std::uint8_t fragrance; // 香り
            std::uint8_t freshness; // 新鮮さ
            std::uint8_t size;      // 大きさ
        };
        std::uint32_t individual; // 個体値
    };
};

同じポテトでも、それぞれ個性は違うもの!ここでは各要素をまとめた個体値を定義した。

3. ハッシュしていく

いよいよ準備したポテトをハッシュしていく

// ポテト
struct Potate
{
    union
    {
        struct 
        {
            std::uint8_t taste;     // 味
            std::uint8_t fragrance; // 香り
            std::uint8_t freshness; // 新鮮さ
            std::uint8_t size;      // 大きさ
        };
        std::uint32_t individual; // 個体値
    };
    
    bool operator ==(const Potate& other) const
    {
        return this->individual == other.individual;
    }
    bool operator !=(const Potate& other) const
    {
        return this->individual != other.individual;
    }
};

template<>
struct std::hash<Potate>
{
    std::size_t operator()(const Potate& potate) const
    {
        return potate.individual;
    }
};

よし!! これでポテトは無事にハッシュできるようになったわけだ。

4. 油で揚げる

ハッシュされただけでハッシュドポテトといえるのだろうか? 否!、しっかり油で揚げる必要がある。 カリッカリだからおいしいのだ!

しっかりハッシュされいるポテトは揚げるとしましょう。

// ハッシュできてれば揚げてよし
template<class T>
constexpr bool is_hashed = std::is_invocable_r_v<std::size_t, std::hash<T>, T>;

// ハッシュドポテト
using HashBrowns = std::conditional_t<is_hashed<Potate>, Potate, void>;

これでハッシュドポテトの完成です!!!

5. 食べる!!

おいしいハッシュドポテトをせっかく作ったので感想を言いましょう。

int main()
{
    // 感想
    using Impressions = std::unordered_map<HashBrowns, std::string>;
    Impressions impressions;
    
    HashBrowns potate{5, 5, 5, 5};
    impressions[potate] = "The potate Delicious!!!";
    std::cout << impressions[potate] << std::endl;
}

とっても、おいしいですね!!

まとめ

今回は、ハッシュドポテトの作り方を学びました。

皆さんも是非、ハッシュドポテトを作って、召し上がってください!

CocosCreator Effect classを考える

挨拶

久しぶりの投稿です。 4月から就職しました。(一応ゲームエンジニア)
最近はCocosCreatorを触っているのでそれ関連でEffectの管理を考えてみました。

Effect.js

cc.ComponentとしてEffectのマネージャーを作成する

export let Effect = cc.Class({
    extends: cc.Component,

    properties: {
        _effects: [],
        _isPause: false
    },
    statics: {
        main: null
    },

    // LIFE-CYCLE CALLBACKS:

    onEnable() {
        if (Effect.main)
            return;
        Effect.main = this;
    },
    onDisable() {

        if (Effect.main !== this)
            return;

        Effect.main = null;

    },
    update(dt) {
        if (this._isPause)
            return;
        //パフォーマンス不安
        this._effects = this._effects.filter((elm) => {
            if (elm._effect === null) {
                return false;
            }
            elm._timer += dt;
            let isDestory = !elm._effect.update(elm._timer);
            if (isDestory) {
                elm._effect.onDestroy();
            }
            return !isDestory;
        });
    },
    add(effect) {
        if (effect instanceof IEffect)
            this._effects.push({ _timer: 0, _effect: effect });
        else
            throw "effect type is must extends `IEffect`";
    },

    clear() {
        this._effects = [];
    },
    pause() {
        this._isPause = true;
    },
    resume() {
        this._isPause = false;
    }
});

add関数に渡すのはIEffectを継承して実装したエフェクトのインスタンスとする

export class IEffect {
    constructor(node = null) {
        this.node = node;
    }
    update(timeSec) {
        return timeSec <= 1.0;
    }
    onDestroy() {
        if (this.node !== null)
            this.node.destroy();
    }
}

Effectのupdate(dt)が追加したエフェクト全てのupdate(timeSec)に各経過時間を渡して呼んでいる
コンストラクタでnodeを登録しておけば自動でdestroy()をよんでもらえる。
cc.Nodeやcc.Componentを渡すことができる

Sample1

Sample1.js

import { Effect, IEffect } from "Effect";

class Sample1 extends IEffect {
    update(timeSec) {
        this.node.scale += 0.01;
        return timeSec <= 1;
    }
}
cc.Class({
    extends: cc.Component,

    start() {
        this.t = 0;
        Effect.main.add(new Sample1 (this.node));
    },
    update(dt) {
    },
});

Effectコンポーネントがアタッチされたノードをもつシーンで このスクリプトがアタッチされたプレハブを生成したりすればよい