はじめに
※この記事は新歓ブログリレー57日目の記事です。
新入生のみなさん、はじめまして。
はじめましてですね?(大事なことなので二回言いました)。
はじめましてですよ?大事なことな(ry
19-情報通信系のNです。
突然ですが、みなさんはtraPの何に興味を持って、このブログを覗いていますか?
競技プログラミングに興味がある、CTFに興味がある、Webプログラミングに興味がある…
そして、
ゲーム制作に興味がある。
様々あると思いますが、この記事はゲーム制作に興味がある人向けのものとなります。
traPは競技プログラミングやCTFといった競技系で注目されがちですが、プロジェクトというチームでゲーム制作をするような活動もあるので、ゲームを作りたい!という人にも是非入ってほしいと思ってこの記事を書いています。
また、競技プログラミングやCTFが強い方も、是非一度開発というものも経験してみてほしい、その楽しさを知ってほしいという目的もあります。
traPに入ったらみんな競技系をしていて、みんな強そうで、敷居が高くなっている、なんてことありませんか?
確かに強い人はたくさんいますが、安心してください、僕みたいなクソ雑魚うんちマンもいます。
かくいう僕も一年の夏ごろから「みんなやっているから」なんて理由で競技プログラミングをはじめてみました。確かに問題を解くのは楽しいのですが、時間を測って素早く解くことの要求される競プロは、ノロマな僕には厳しいものがありました。
コンテストに28回も出てやっと到達したレートも、後から始めた人に3回くらいで抜かされてしまうような実力です。
そんなノロマな僕でも、開発するのであれば時間制限はありません。思う存分考えることができます。
僕はこの一年間、じゃぱりぱーくというゲームを作るプロジェクトに入って、グラフィック班としてキャラの立ち絵や、オブジェクトのドット絵を描いていました。
その経験も活かし、Unityでゲームを作ったりもしました。
そんな感じでまったりと活動している人もいる、ということは知っておいてほしいです。traPに入ったから、情報系の学系を目指してるからって必ず競技プログラミングやCTFをはじめなきゃいけないなんてことはないですし、やってみたいけど、強い人ばかりだと気が引けるなんて人も僕みたいなのもいるので安心して入ってください。
これはtraPに限った話ではないですが、義務感を感じてなにかをするのはやめた方がいいです。
自分が楽しいと思うこと、やってみたいと思うことだけやってればいいと思います。だって、大学のサークルなんですから。仕事ではないですよ。
さて、前置きが長くなってしまいましたが、以上がはじめに、僕の伝えたかったことです。それでは、本編をどうぞ。
えぬたそのゲーム開発日記
開発環境
今回は個人的に使いたかったC言語、C++を用いて開発していく。画像を表示したり、音楽を再生するのに、DXライブラリというライブラリを使う。
ゲームの仕様
僕の好きなゲームの一つである「トルネコの大冒険」のようなローグライクなゲームを作っていく。敵とか凝りだすと無限に開発することになるので、キリのいいところで終わりにしたい。
まずは環境構築
本記事では、統合開発環境であるVisualStudio 2019を用いる。
DXライブラリを使えるようなプロジェクトの作成方法は こちら を参考にした。
では早速開発!
そもそもDXライブラリ使うの初めてだし、汚いコードだし、教えられるほどの技術もないので、日記形式で完成までの苦悩を語っていきたい。
1日目
まずやることをまとめたりした方がいいのだろうが、とりあえず行き当たりばったりで作っていかないとピンとこないので、最初にプレイヤー(自機)を作っていきたいと思う。
ローグライクなので、1回キーを入力すると1マス進むような移動にしたい。
こちら の記事を参考にして、組んでみた。
↑と変えたところは、main.cppでの変数を用いたいので、その部分を引数にしたくらいだ。
移動は一回キーが押下されるごとに、一マス動くみたいな仕様にした。また、一マスは32pxに設定した。斜め移動は後々考えることにしよう(多分四方向で諦め、時間があれば)。
とりあえず、自機を矢印キーで移動できるようにするところまで実装完了。
↑の動画の黄色いのが自機である。読者には伝わらないだろうが、自分で作るとこの黄色いのが動くだけでもかなり感動した。
ただこのままだと1フレームに座標が一気に変化しているので、かくかく動いている。スムーズに移動するようにするため、今動いているかというフラグを追加し、動いてる間は座標が完全に移動し切るまで入力を受け付けないようにした。
int型で扱えるように工夫したが、きちんと32の倍数になっているか確認するため、自機の座標も表示している。調べてもあまり出てこなかったので、なんかもっといい方法があったら教えていただきたい。(ソースコードはまとめてgithubにあげる予定なので、そちらを参照していただきたい。)
2日目
とりあえずプレイヤーが動くようになったので、次はマップ的なものを作っていきたいと思う。
こちらの動画を参考にしてダンジョン生成を実装した。
実際は32pxで一マスにするので、描画するときはフィールドのインデックスに32をかけて描画するみたいな実装にした。
ダンジョン生成アルゴリズムを簡単にまとめると以下の図のようになる。
実際には上の処理を行った後、一番外側の通路だけ消したりしている。具体的な実装はソースコードを見るか、さきほど貼った動画を見るとわかりやすいだろう。
3日目
実際には二日目の実装が重く、二日目で一週間くらいかかっているので、三日目というのはもちろん嘘であるが、まぁ頭のいいみなさんなら一日で理解して実装できることだろう。
次にメインカメラを実装していこうと思う。今はマップ全体が描画されていてプレイヤーが動いている感じであるが、実際はマップの一部が描画され、カメラはプレイヤーに追従していく形になるはずだ。
それを実装するうえで、プレイヤーとの相対座標を定義する。
その相対座標系を-とすると、
はの座標-描画する幅/2からの座標+描画する幅/2まで
はの座標-描画する高さ/2からの座標+描画する高さ/2まで
を描画すればいいことになる。
ただここで問題があって、フィールドのインデックスはマップチップ一個につき一個でプレイヤーの座標は滑らかに動かすため、連続的(実際にはフレームごとに不連続であるが、マップチップのサイズの倍数でない)ので、プレイヤーの座標をそのまま使って、
field[player.y / MAP_SIZE - FIELD_HEIGHT / 2)][player.x / MAP_SIZE - FIELD_WIDTH / 2]
という風にすると、当然プレイヤーの座標はMAP_SIZE(32px)で割り切れないため、エラーが起きてしまう。ここで、プレイヤーの座標は32の倍数で確保し、滑らかに動かすための+δの部分をまた別の変数で置いてやることで、実装することに成功した。これに気づくまでめっちゃ時間かかった。
4日目
今日は壁の当たり判定を実装しようと思う。描画する前にもしプレイヤーのいる位置が壁ならもとに戻すといった処理を追加することによって実装が完了した。こんな感じ。
ついでにちょっと見えてるマスが少ないような気がしたのでウィンドウを少し大きくした。
5日目
今日は敵の実装をしていきたい。以前プレイヤーを作成するときに使ったCHARACTER型のenemyという変数を用意する。また敵がいるということはプレイヤーにHPや攻撃力といったものが必要なので、それらを構造体に追加した。一般的な攻撃力やHP、またダメージの計算方法などはよく知らないので、階層が進むごとに強くなればいい程度の思いつきで階層が進むごとにHP、ともに乱数を絡めて上がる仕様にした。
敵のAIとして、abs(player.x - enemy.x)とabs(player.y - enemy.y)の大小で場合分けし、大きい方の座標を動かすことにした。通路での動きは、四方向しか移動できないことを活かし、distanceという変数をabs(player.x - enemy.x) + abs(player.y - enemy.y)で定義し、これが三マス以下のときは同じ部屋にいるときと同様の処理をするようにすることで、プレイヤーを追うようにした。
プレイヤーと重ならないようにするのが意外としんどくて、かなり苦労した。頭の中もぐちゃぐちゃでコードもぐちゃぐちゃだが、まぁ動いてるからヨシッ!w
6日目
クリア演出とゲームオーバー演出を作ることにした。HPが0以下になったらゲームオーバー、五階以降にある宝箱を取ったらクリアみたいな感じにした。
攻撃すると一ターン消費、みたいな処理を書くのがちょっと苦労したが、まぁ、動いてるからヨシッ!w
ゴールを作ったときと同じように、ランダムな位置を取得してきて、宝箱を配置した。クリア演出はGAMEOVERのときと一緒。
7日目
これで大体の実装が終わったので、プレイヤーは誰なのか、敵は誰なのかを考えることにした。
プレイヤーはどうしよう、僕でいっか、ということで「えぬたその大冒険」になった。
そして作り出したキャラクターがこちら。
どう見ても美化しすぎである。ゲームなので許してほしい。ゲームなので許してほしい。
次は敵である。僕の敵って誰だろう。。。うん、陽キャかな。
ってことで敵は陽キャである。描いたのがこちら。
さてここから四方向分のドットを打たなければいけない。面倒だ。
僕は、前だけ向いて生きていくことにした。
追記: 陽キャを倒しました。
こちら から遊ぶことができます。
また、ソースコードは こちら から
おわりに
みなさん、いかがでしたでしょうか。少しでもゲーム制作に興味を持っていたのなら、うれしい限りです。
最後に、少しだけ、僕が思う、traPのおすすめポイントを紹介して、締めとさせていただきたいと思います。
人生の夏休みと言われている大学生の期間、みなさんはどう過ごすつもりでしょうか。遊び、勉強、趣味、様々あると思いますが、この期間を何もせずに過ごすか、自己研鑽に励むかで成長具合は大きく変わるでしょう。
そう考えて「何か自分のやりたい勉強をしたい。」と思う人は多いと思います。
traPはそう思う人にとって、デジタル創作の分野に限りますが、最高の環境です。
独学を進めていて、わからないことがあった、詰まってしまった。自分だけで解決しようとすると1週間かかってしまうようなことが、先輩に聞けば一瞬で解決するようなこともあります。無駄な時間を費やすことなく、快適に独学していけます。
逆に、自分からなにかしようと思わない人にとっては、少し退屈に感じてしまうサークルかもしれません。
もし、入ってから、したいことはあるけど、なにを勉強すればいいかわからない、みたいに思っている人がいたら、ぜひその旨を先輩に伝えてみて下さい。あなたが一年後、二年後にしたいことができるようになっているようなフローチャートを先輩方が組んでくれることでしょう。
自発的な行動で、traPを有効活用してみてはいかがでしょうか。
それでは、最後までご清読、ありがとうございました。
明日は
天才神絵師鴨…?!天才鴨絵師神…?!
traP激ウマギャグ班、鴨担当の @summon_salmon さん
の記事です。お楽しみに。