ゲーム作りは楽しい

なんか書く

自作列挙型 enum to string メモ書き

自作列挙型を作っていますが

enumから文字列への変換をめちゃスマートに扱えるように実装できたと思ったがMSVCでしかコンパイルできないコンパイラ依存になってしまった

メモ程度にコードをあげておきます

 

#pragma once
#include<string>
#include<unordered_map>

#define EXPAND( x ) x
#define IE_FOR_EACH_1(_macro,e1)_macro(e1)
#define IE_FOR_EACH_2(_macro,e1,...) _macro(e1) EXPAND( IE_FOR_EACH_1(_macro,__VA_ARGS__) )
#define IE_FOR_EACH_3(_macro,e1,...) _macro(e1) EXPAND( IE_FOR_EACH_2(_macro,__VA_ARGS__) )
#define IE_FOR_EACH_4(_macro,e1,...) _macro(e1) EXPAND( IE_FOR_EACH_3(_macro,__VA_ARGS__) )
#define IE_FOR_EACH_5(_macro,e1,...) _macro(e1) EXPAND( IE_FOR_EACH_4(_macro,__VA_ARGS__) )
#define IE_FOR_EACH_6(_macro,e1,...) _macro(e1) EXPAND( IE_FOR_EACH_5(_macro,__VA_ARGS__) )
#define IE_FOR_EACH_7(_macro,e1,...) _macro(e1) EXPAND( IE_FOR_EACH_6(_macro,__VA_ARGS__) )
#define IE_FOR_EACH_8(_macro,e1,...) _macro(e1) EXPAND( IE_FOR_EACH_7(_macro,__VA_ARGS__) )
#define IE_FOR_EACH_9(_macro,e1,...) _macro(e1) EXPAND( IE_FOR_EACH_8(_macro,__VA_ARGS__) )
#define IE_FOR_EACH_10(_macro,e1,...)_macro(e1) EXPAND( IE_FOR_EACH_9(_macro,__VA_ARGS__) )

//必要次第追加
#define IE_GET_FOR_EACH(e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,NAME, ...) NAME
#define IE_FOR_EACH(macro,...) EXPAND(IE_GET_FOR_EACH(__VA_ARGS__,IE_FOR_EACH_10,IE_FOR_EACH_9,IE_FOR_EACH_8,IE_FOR_EACH_7,IE_FOR_EACH_6,IE_FOR_EACH_5,IE_FOR_EACH_4,IE_FOR_EACH_3,IE_FOR_EACH_2,IE_FOR_EACH_1)(macro, __VA_ARGS__))

#define IE_MAPPING_ENUM_VAL(name) \
[]()\
{\
   struct Check\
   {\
       int v=0;\
       template<class... Args>\
       Check(const Args& ...args)\
       {\
           constexpr int size = sizeof...(args);\
           if constexpr(size == 1)\
           {\
               v = name;\
           }\
           if constexpr(size == 2)\
           {\
               int name;\
               v = name;\
           }\
       }\
   };\
   if constexpr(ie::detail::NameCheck(#name))\
   {\
       return Check(1).v;\
   }\
   else\
   {\
       return Check(1, 2).v;\
   }\
\
   return 0;\
}()

#define IE_MAPPING_TO_STRING(name) {IE_MAPPING_ENUM_VAL(name), ie::detail::MappingEnumString( #name )},

namespace ie
{
    namespace detail
    {
        struct Value
        {
            constexpr Value() = default;
            constexpr Value(const int& other) :
                value(other)
            {}
        protected:
            int value = 0;
        };

        constexpr bool NameCheck(const char* test)
        {
            for (int i = 0; test[i] != '\0'; ++i)
            {
                if (test[i] == '=')
                {
                    return false;
                }
            }
            return true;
        }
        std::string MappingEnumString(const std::string& str)
        {
            return str.substr(0, str.find('='));
        }
    }
}


#define INTEGER_ENUM(...)\
struct : ie::detail::Value{\
   using  _ENUM=enum { __VA_ARGS__ };\
   using Value::Value;\
   decltype(auto) operator +=(int value) { *this = this->value + value;    return *this; }\
   decltype(auto) operator -=(int value) { *this = this->value - value;    return *this; }\
   decltype(auto) operator *=(int value) { *this = this->value * value;    return *this; }\
   decltype(auto) operator /=(int value) { *this = this->value / value;    return *this; }\
   decltype(auto) operator %=(int value) { *this = this->value % value;    return *this; }\
   decltype(auto) operator ++() { *this = this->value + 1; return *this; }\
   decltype(auto) operator --() { *this = this->value - 1; return *this; }\
   decltype(auto) operator ++(int) { auto ret = *this; *this = this->value + 1; return ret; }\
   decltype(auto) operator --(int) { auto ret = *this; *this = this->value - 1; return ret; }\
   constexpr operator _ENUM()const{ return static_cast<_ENUM>(value); }\
   std::string to_string()const\
   {\
       static std::unordered_map<int, std::string> map\
       {\
           IE_FOR_EACH(IE_MAPPING_TO_STRING, __VA_ARGS__ )\
       };\
       if (map.find(value) == map.end())\
       {\
           return "Unknown:" + std::to_string(value);\
       }\
       return map.at(value);\
   }\
}

使い方は

using Example = INTEGER_ENUM(
    A,
    B,
    Default = A
);

int main()
{
    Example a = Example::Default;

    std::cout<<a.to_string();
//出力 A
    return 0;
}

とやるだけで非常にシンプルです。 INTEGER_ENUMマクロが無名構造体を生成してto_string()メソッドも自動生成してくれるというものですが MSVCのラムダ内ならメンバtemplateが使えることや、templateの文法エラーのチェックタイミングなどの関係でほかのコンパイラでは使用できません

ゲームジャムは楽しいよ

みなさんゲームジャムをご存知でしょうか?

限られた時間のなかで即席チームでゲーム開発するイベントみたいなものです!

 

僕は名古屋でハッカソンという名の実質ゲームジャムを運営していて、先日このイベントが行われました。

これが第9回目になるのですが40人を越える名古屋の学生が集まり、就活支援の方やゲーム会社の方にも協賛をいただいて盛り上がった一日になりました。

当日僕は運営をしていて作品は作っていないので見ててうずうずしていましたが、8時間という限られた時間のなかでどのチームも楽しそうに制作してるのを感じられました。

 

こーゆーイベントはなかなか見つからなかったりもするかもですが、いい経験にもなると思いますし、楽しいと思います。

特に2019卒の学生さん向けに今年の夏からも多くのゲーム会社がインターンだったりゲームジャムを開催すると思います。

是非みなさんも機会があればゲームジャムとかにでてみてはいかがでしょうか?

 

 

 

 

四分木空間分割やってみた

アクションゲーム作るマンだから、空間分割をやってみました。

参考サイトは大正義

http://marupeke296.com/COL_2D_No8_QuadTree.html

です。

f:id:mahou_ptr:20170322054803p:plain上のスクショだとA30とB30の判定で試した奴なので、速度差がわかりにくいですが、10000*10000で試したりすると多少早くなります

判定のチェック回数自体が減っているのは一目でわかりますね!

 

作ったclassとかは後日

曲と同期するためのclassを作る

音楽ゲームを作る時などに役立つ、曲と同期するための記事を書きました

qiita.com

classって素敵

ゲームを作っているとシーンclassみたいなものをだいたい使うわけですが

ついメインシーンclassとかにゲームのメイン部分を書いていっちゃうんですよね

 

でも、例えばチュートリアルシーンみたいなのを作りたくなったときとかにメインシーンとは別でメイン動作と同じものが必要になったとき、すべて移さなくちゃいけなくて大変だったりするんですよね

だから動作のclassを作ったうえでシーンclassに持たせてやるのがあとあと何かあったときに楽に移植できたりしていいなぁって思いますね

XMMATRIXにはめられた話

たまに動作が停止するのでなんでだーなんでだーって原因をさぐっていたら

DirectX::XMMATRIXやDirectX::XMVECTOR(それをメンバにもつclassも)をスマートポインタで扱ってたのがマズかったらしい

こいつらの扱いには注意が必要そうですね

 

 

DirectWriteのttf読み込みやっとできた

ずっとやりたかったけど、MSのサンプル見てても結構めんどくさくて困ってたんです

スタックオーバーフローでそれっぽいの見つけたので、ぽいぽいっと入れたらやっとできた

 

とりあえず一安心です。

 

困ったときはググろうな!!