雪解けの春を待つ

しがない専門学生の徒然日記

ゲーム制作の基礎の基礎の

お久しぶりです。六花です。

 

一週間ほど前に喉風邪をひいてずっと死んでました。

ぶっちゃけ今も咳のし過ぎでプチ呼吸困難。

プログラミングやらなさ過ぎて腕が鈍ってる感やばい……

 

 

最近はゲーム制作というより、

その基礎の基礎で悩んでいたりします。

要するにエンジン? なのか?

 

エンジンっていうとUnityとかUEとか連想してしまうんですけど……

 

いざゲーム作るとなると、

メインループに書くのはどれだーだの

シーン切り替えがどうだーだの

タスクシステムはどうだーだの

考えること多すぎてわけわからんようになりますな。

 

んで、専門学校の学内ライブラリ使えば、

現時点でゲームっぽいサムシングはできるんですけど、

 

 

なんかすっきりしない……

 

なんか雑多だし、

タスクが増えるたびに似たようなクラスが乱立するし、

cppいくつあるんじゃって感じだし、

 

んでいろいろ試して質問して考えた結果、

もっとベースの、エンジンに近いことをやろうかと。

 

ゲームをじゃんじゃん作るっていう時間は無くなっちゃうけど、

自分の使いやすいベースができれば後々楽だし、

 

なにより仕組みを知っておくというのは

スキルアップには欠かせないですしね。

 

 

というわけで、今後はその辺のことをちまちまやっていきます。

楽しいクリスマスはもう終わりだ(絶望)

 

ていうか年明けるんですね……

1年早すぎだろ……就活……

 

 

あとタイトルシーンとか本編シーンとか、

シーン管理にとらわれていたんですけど、

 

シーンを作らないという選択肢もあったんですね……

 

要するにシーン分けなんてしないで、

更新しないところはupdate()をそもそも呼ばなければいいわけで。

 

そうするとリソースの確保と解放も最小限で済むし、

例えばゲーム中にメニュー画面開いて、

メニューの裏でキャラは静止しているけど雲だけは動くという、

シーンをまたいだ演出もできるという。

 

うーん……奥が深い。

 

考え方的にはUnityをC++で作るって感じになりそう。

Unityはもういいやって思ってたけど、

まだまだお世話になりそうですね……

 

というかUnityでゲーム作れたところで就職なんてできないけど、

逆に言えばUnityですらゲーム作れないのに就職なんてできるわけがないわけで。

 

せっかくだし3Dゲームでも作るかー。

 

 

せっかく作ったゲームはそのうちどっかのサイトで公開できるといいな。

 

そうなる日を目標に、精進精進。

 

 

なんか目標を掲げただけで大した話をしてない気もしますが、

今日はこの辺で。

 

 

みなさんメリークリスマス&ハッピーニューイヤーです。

それでは。

 

登れない坂はただの壁だ

通勤時間は往復4時間半!驚きの遠距離通勤生活!

みたいな番組見て

 

「は???普通じゃね???」

 

って思ってしまった往復5時間半通学の六花(ろっか)です。こんばんは。

 

 

さて、最近はアクションゲームを作るべく、

壁ずりベクトルを作ってました。

 

入力は右のまま、

坂道の上では坂に沿って移動するようにする

っていうアレですね。

 

DXライブラリに外積内積を算出する関数はあるんですが、

3D用なだけあって、2Dの外積はないんですよね。

3Dではベクトル、2Dではスカラーになる、憎きあいつです。

 

というわけで作りました。ベクトルクラス。

キャラの座標とかも、点じゃなくてベクトルで保持したほうが後々便利だしね。

 

 

class Vector{

public:

 float x,y,z;

 

 Vector(float x = 0.0f, float y = 0.0f, float z = 0.0f):x(x), y(y), z(z) {}

 ~Vector() {};

 static const float GetDotVec(Vector v1, Vector v2);  //2つのベクトルの内積を返す

 static const float GetCrossVec2(Vector v1, Vector v2);  //2つのベクトルの外積を返す(2次元)

 static const Vector GetCrossVec3(Vector v1, Vector v2);  //2つのベクトルの外積を返す(3次元)

 static const float GetVecLen(Vector v);  //ベクトルの長さを得る

 static const Vector GetUnitVec(Vector v);  //ベクトルを正規化

 static const Vector VecScale(Vector v, float n);  //ベクトルをn倍する

 static const Vector GetUnitNormVec2Left(Vector v);  //2次元ベクトルの単位法線ベクトルを得る v1×v2 ベクトルの左側の方

  static const Vector GetUnitNormVec2Right(Vector v);  //2次元ベクトルの単位法線ベクトルを得る v1×v2 ベクトルの右側の方 

 static const Vector GetUnitNormVec3(Vector v1, Vector v2);  //3次元平面の単位法線ベクトルを得る v1,v2は平面上に存在するベクトル


 //オペレータ定義

 Vector& operator = (const Vector& v) { x = v.x; y = v.y; z = v.z; return *this; }

 Vector& operator + (const Vector& v) { return Vector(x + v.x, y + v.y, z + v.z); }

 Vector& operator - (const Vector& v) { return Vector(x - v.x, y - v.y, z - v.z); }

 Vector& operator += (const Vector& v) { return Vector(x += v.x, y += v.y, z += v.z); }

 Vector& operator -= (const Vector& v) { return Vector(x -= v.x, y -= v.y, z -= v.z); }

};

 

const float Vector::GetDotVec(Vector v1, Vector v2)

 { return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;}

const float Vector::GetCrossVec2(Vector v1, Vector v2)

 { return (v1.x*v2.y) - (v1.y*v2.x);}
const Vector Vector::GetCrossVec3(Vector v1, Vector v2){

  Vector Result;

  Result.x = v1.y*v2.z - v1.z*v2.y; Result.y = v1.z*v2.x - v1.x*v2.z; Result.z = v1.x*v2.y - v1.y*v2.x;

  return Result;

}
const float Vector::GetVecLen(Vector v) { return std::pow(v.x*v.x + v.y*v.y + v.z*v.z, 0.5f);}
const Vector Vector::GetUnitVec(Vector v) {

  float len = GetVecLen(v);

  Vector Result = v; Result.x /= len; Result.y /= len; Result.z /= len;

  return Result;

}
const Vector Vector::VecScale(Vector v, float n) {

  Vector Result;

  Result.x *= n; Result.y *= n; Result.z *= n;

  return Result;

}
const Vector Vector::GetUnitNormVec2Left(Vector v) {  //左回りに90度回転してるだけやで☆

  Vector Result = v;

  float tmpx = Result.x; Result.x = Result.y; Result.y = (-1)*tmpx;

  Result = GetUnitVec(Result);

  return Result;

}
const Vector Vector::GetUnitNormVec2Right(Vector v) {  //こっちは右回りやで☆

  Vector Result = v;

  float tmpx = Result.x; Result.x = (-1)*Result.y; Result.y = tmpx;

  Result = GetUnitVec(Result);

  return Result;

}
const Vector Vector::GetUnitNormVec3(Vector v1, Vector v2) {

  Vector Result = GetCrossVec3(v1, v2);

  Result = GetUnitVec(Result);

  return Result;

}

 

 

はてブロでソースコードを綺麗に公開してる人ってどうやってるの……

 

まあこれを使って、

 進行ベクトル+坂の法線ベクトル

で壁ずりベクトルが出せる、と。

 

 

 ただ、「坂に当たった」っていう判定が難しい……

外積を使うと簡単なんだけど、それでは「線分」じゃなくて「線」との判定なんだよね。

そうすると、坂の延長線上ならどこでもヒットしてしまう。

 

線分と点の当たり判定は内積でやるんだけど、

 v1・v2=|v1||v2|cosθ=|v1||v2|

この条件では誤差で全くヒットしない。

 

今は誤差範囲を設定してなんとか動いたけど、

やっぱり入力方向によっては坂をすり抜ける……

 

まあピクセル単位でやってりゃそうなるわな、って感じですが。

なんかいい方法ないかなー。

 

まだ重力もつけてないので、

まだまだ改良の余地あり、ですかね。

 

ちなみに上に乗せたコード、

プログラミング始めて半年の学生が書いたコードということにご注意ください。

おかしなところあればコメントくださるとうれしいです!

 

 

まだクラス内関数の勉強も足りないなー

constとかstaticを関数につけた時の効果とかあいまいだし……

 

先は長いなぁ

 

 

話も長くなったので今日はこれにて。

 

はじめまして

こんばんは、六花(ろっか)です。

 

さて、まずなんでブログを始めたのかというと、

まあ今勉強中のゲームプログラミングでね

 

やること多すぎて整理しきれないんじゃ……

 

ということで、毎日が勉強の日々なんだけども、

その中で思ったこととか疑問なこととかをつらつら書いて

自分の中でまとめていけたらなということです。

 

完全に個人の日記になりますな。

 

主にDXライブラリを使ったゲーム制作、

C++のあれこれ、クラス設計、

後はGitかな……わけわかんねえあれ……

 

 

とりあえずまずはこの日記が続けられるように頑張ります。

きっと明日あたりから本気出す。

 

 

それでは今回はこれで。