WCE blog

早稲田大学公認 総合デジタル創作サークル 早稲田コンピュータエンタテインメント

ゲームについて書かれた新書

f:id:WCE:20130403232952j:plain

プログラミング班新4年 hisoji です。
ゲーム制作に関心があるならば、「面白いゲームを作りたい!」「ゲーム会社に就職したい!」「スキル上げたい!」「とくにないです。」など何らかの思惑を持っていると思います。
おそらく、それらは多くのゲーム制作者も考えてきたことであり、自らの経験や考えを本にして書いてくれている人もいます。

そこでゲームを話題にした新書を、読んだことがある範囲で紹介しようと思います。
ここでは紹介されていない、筆者が知らない本も多数あるので、おすすめがあれば是非教えてください。
ちなみに新書で読む利点として、

  • 比較的安い
  • 一般向けに書かれており、読みやすい

などが挙げられます。

僕たちのゲーム史

昔のゲームと今のゲームは一体何が違うのかを、ゲームの変わらない部分と変わっていった部分を定義して、時代をさかのぼりながら考えていきます。

説明と一緒に、当時の記事が紹介されているのが特徴的です。当時の記事の語り口やゲーム画面がその頃の情勢を思い起こさせる気がします。
あの「スーパーマリオ」も発売当時は斬新なゲームだったようなのですが、別に「アクションゲーム」として売られたわけではないそうです。また、ハードウエアやROMの選択、青少年の非行問題など、ゲームとは直接関係ない事柄も歴史に深く関わってきたというのも新鮮に感じます。同人ゲーム、インディーズゲーム業界を取り上げているのも印象的です。

紹介されていないゲームも多々ありますが、各時代のゲームの歴史が、新書の中に可能な限り網羅されていると思います。

教養としてのゲーム史

各時代で有名だったゲームを、ゲームに対する「見立て」「意味づけ」を軸にして追っていきます。

一番初めの「玉を打ち合う」だけのゲームから、変化をつける、敵が攻撃してくる、地形に意味を持たせるなど、その都度多くのアイディアが付加されていく様子が見てとれます。時代が移っていくごとに、ゲーム画面の扱われ方も意味づけもどんどん変わっていきます。

後半のシミュレーションゲームの章も印象的です。シミュレーションゲームは人の欲望と共に成長していったという考えには興味を引かれます。思い通りの国を作り上げたいのか、恋愛を学園生活ごとやり直したいのか、「現実」で彼女と共に過ごしたいのか、時代によっても様々な願望があるようです。

クリエイター・スピリットとは何か?

デジタルハリウッド大学の学長によって書かれた本です。ゲームについては書かれていませんが、ゲーム制作者もある意味で「クリエイター」と言えそうなので今回入れました。

いわゆる「クリエイター」として生きていくとはどういうことか、どんなことをすればいいのかについて書かれています。自分の好きな道具を使ってみる、ひらめいたら何かの媒体(メモ帳、ブログ等)に残しておく等、実際に使えそうな方法が紹介されています。高校生向けだからか、日々の勉強や学校の選び方についても書いてあります。

途中の章では「日本は、クリエイターとして生きるには一番いい国だ」というのがあります。日本人は特定の価値観を押し付けられていないので、固定された世界観を簡単に破壊してしまうというのは、確かに少し思うところがあります。

ゲームの教科書

ゲーム会社での制作経験者が、ゲーム開発について書いています。

ゲームがどんなものか、どんな職業があるのか、実際のスケジュールはどんな感じなのか、どうすればゲーム会社に入れるのか等、ゲーム会社で働く事についての事柄が詳しく書かれています。
ゲーム開発者に必要なスキルが職業ごとに書かれており、ゲーム会社に就職したいという人には参考になります。また、実際にゲーム開発の過程を通じてゲームを作ってみる章もあります。

開発者の実際の一日が書かれているのは参考になります。ミーティングや打ち合わせが何度も行われており、常に試行錯誤しながら完成に近づけていくんだなあと身にしみます。

ちなみに本書内では先ほどの「クリエイター・スピリットとは何か?」が紹介されています。



このような本を読まずとも、普通にゲームは作れると思います。
ただ、ゲームの歴史や他人の手法を知ることは、今後のゲーム制作にも何らかの形でつながってくれる気がします。
興味があったら、是非手にとってみてください。

GDC 2013 関連記事ピックアップ

プログラミング班 @Reputeless です。

世界最大のゲーム開発者向けイベント Game Developers Conference (GDC) が、今年もサンフランシスコで開催されました。
GAME Watch4Gamer.net に掲載された現地取材レポートから、興味深い記事をピックアップして紹介します。

発表!「良いレベルデザインの10の原則」

Square Enix Montreal のクリエイターが、ゲームデザインの 10 の原則を実際の事例を交えて紹介。

「Journey(風ノ旅ビト)」のゲームデザイン解説

風ノ旅ビトが目指したのは「感情」のデザイン。そのアプローチを開発スタジオのデザイナーが解説。

「TOKYO JUNGLE」の成功から振り返る日本の感性を生かしたゲーム制作

普遍と普遍を組み合わせることで、普遍だがユニークなゲームとなった TOKYO JUNGLE の誕生秘話。

色々あったけどやっぱり気になる「シムシティ」 Part2

シムシティ開発チームがコンセプト共有のために用いた「ワン・ページ・デザイン」という手法の披露。

GAME NARRATIVE SUMMIT「教訓あるゲームを作るテクニック」

教訓や道徳を伝えるゲームの作り方を、Microsoft のシニアゲームデザイナーがアドバイス。

NASAがゲーム開発者を本気でリクルーティング

NASA が広報用に作ったゲームと、ゲームの技術を宇宙探査で活用しようとしている研究事例を紹介。

このほかにも、PS4 や Project SHIELD などのハードウェアに関する情報や、最新タイトル、エンジンのテクノロジー解説など、ゲームの舞台裏、そして未来を垣間見れる情報が盛りだくさんです。
目を通せば、きっとゲーム作りのヒントが見つかるはずです。

セルオートマトンを用いた幾何学模様の生成

f:id:WCE:20130401212821p:plain

プログラミング班2年のアゲハマです。
今回は砂山モデルの紹介と、それを使ったきれいな模様の作り方を書きたいと思います。

1.セルオートマトンとは

セルオートマトンとはセルによって構成される計算モデルです。
代表的なものにライフゲームが挙げられます。

詳しくは http://ja.wikipedia.org/wiki/セル・オートマトン へ。

2.砂山モデルの説明

今回用いる砂山モデルについて説明をします。
砂山モデルとは2次元セルオートマトンの一種で、砂山が崩れ落ちる様子をモデル化したものです。

f:id:WCE:20130401211607p:plain

エクセルのような、各セルが整数の値を持つ2次元平面を想像してください。
各セルの値はそこに積まれている砂粒の数を表したものです。
ここで、平面上の適当な場所に砂粒を落としていき、高さが4になったら隣接する4つのセルに1ずつ移動させる、という操作を繰り返します。
すると、この隣接セルへの移動が連鎖反応を引き起こし、大きな雪崩につながることがあります。
この雪崩の頻度と規模は、べき乗に分布することが知られており、べき乗法則に従う自然現象(地震など)の研究に用いられることもあるようです。

3.砂山モデルのプログラミング

では、この砂山モデルをプログラムに書き起こしてみましょう。
ここではSiv3Dライブラリを用いていますが、画像データをピクセルごとに参照できれば何を使っても大丈夫です。

#include <Siv3D.hpp>

const int repsize = 4;
const Point replacer[repsize] = 
{
    Point(-1,0),Point(1,0),Point(0,-1),Point(0,1)
};
const Color backcolor = Palette::Skyblue;
const Color sandcolor = Color(239,228,176,0);
const double scale = 1.0;
const Point size(512,512);

class SandHill
{
    std::vector<std::vector<unsigned>> m_cells,m_temp;
    Image m_image;
    DynamicTexture m_texture;

    //移動するセルの値をm_tempに保存する
    void calcFlow()
    {
        for( unsigned y=0; y<m_image.height; ++y )
        {
            for( unsigned x=0; x<m_image.width; ++x )
            {
                unsigned& cell = m_cells[y][x];
                if( repsize <= cell )
                {
                    const int plus = cell / repsize;
                    cell %= repsize;
                    
                    for(int i=0; i<repsize; ++i)
                    {
                        Point p = replacer[i]+Point(x,y);
                        p.x = Clamp<int>(p.x,0,m_image.width-1);
                        p.y = Clamp<int>(p.y,0,m_image.height-1);
                        m_temp[p.y][p.x] += plus;
                    }
                }
            }
        }
    }
    //m_tempに保存した値をセルに加える
    void updateCells()
    {
        for( unsigned y=0; y<m_image.height; ++y )
        {
            for( unsigned x=0; x<m_image.width; ++x )
            {
                m_cells[y][x] += m_temp[y][x];
                m_temp[y][x] = 0;
            }
        }
    }
    void updateImage()
    {
        for( unsigned y=0; y<m_image.height; ++y )
        {
            for( unsigned x=0; x<m_image.width; ++x )
            {
                m_image[y][x].a = 255*m_cells[y][x]/repsize;
            }
        }
    }
public:
    SandHill(int w, int h, const Color& c)
        :m_cells(h,std::vector<unsigned>(w)),m_temp(m_cells),m_image(w,h,c),m_texture(m_image){}
    void drop(const Point& pos, unsigned value)
    {
        Point p = pos;
        p.x = Clamp<int>(p.x,0,m_image.width-1);
        p.y = Clamp<int>(p.y,0,m_image.height-1);
        m_cells[p.y][p.x] += value;
    }
    void update()
    {
        calcFlow();
        updateCells();
        updateImage();
    }
    void draw()
    {
        m_texture.fill(m_image);
        m_texture.scale(scale).draw(size*(1-scale)/2);
    }
};

void Main()
{
    Window::Resize(size.x,size.y);
    Graphics::SetBackGround(backcolor);

    SandHill sandhill(size.x,size.y,sandcolor);
    
    while(System::Update())
    {
        if(Input::MouseL.pressed)//クリックした場所に砂を落とす
        {
            sandhill.drop(size/2+(Mouse::Pos()-size/2)/scale,500);
        }
        sandhill.update();
        sandhill.draw();
    }
}

実行結果:
f:id:WCE:20130401212750p:plain
なんとなく上から砂を落としているように見えますね。

4.模様を作る

先ほどのプログラムでマウスの位置を固定していると、対称的な図形が現れてきます。
初期値も行う操作も対称的なので当然と言えば当然な気もしますが、少しルールを変えればもっと綺麗な模様が作れそうです。
ということで、先ほどのソースコードの以下の部分を書き換えてみましょう。

const int repsize = 4;
const Point replacer[repsize] = 
{
    Point(-1,0),Point(1,0),Point(0,-1),Point(0,1)
};
const Color backcolor = Palette::Skyblue;
const Color sandcolor = Color(239,228,176,0);
const double scale = 1.0;

ここを以下のように書き換えてください。

const int repsize = 24;
const Point replacer[repsize] = 
{
    Point(-3,-3),Point(-2,-3),Point(-1,-3),Point(0,-3),Point(0,-2),Point(0,-1),
    Point(3,-3),Point(3,-2),Point(3,-1),Point(3,0),Point(2,0),Point(1,0),
    Point(3,3),Point(2,3),Point(1,3),Point(0,3),Point(0,2),Point(0,1),
    Point(-3,3),Point(-3,2),Point(-3,1),Point(-3,0),Point(-2,0),Point(-1,0)
};
const Color backcolor = Palette::Black;
const Color sandcolor = Alpha(0);
const double scale = 3.0;

書き換え前のreplacerは、現在のセルを中心とした相対座標で、上下左右の4つの隣接するセルを表しています。
それに対して書き換え後のreplacerは、下の画像の黒い場所を表しています。

つまり、セルに24個の砂粒が積まれたら、この画像の黒い部分に1つずつ割り振るという操作になります。
もはや砂山でも何でもないですが、実行結果は次のようになります。

実行結果:
f:id:WCE:20130401223804p:plain
面白い模様がいくつかできました。
画像がなんとなくぼやけて見えるのは、自動で補間がかかっているからです。
ちなみに、このようなドット絵を拡大する時はニアレストネイバー法を用いるとぼやけずに拡大できます。

5.まとめ

先ほどのreplacerを画像から読み込めるようにしたものがこちらです。
これで生成される画像はグレースケールなので、Photoshopのグラデーションマップなどで適切に加工すると良いと思います。

ロボット・メカの描き方 装甲の形状1

 どーも、CG班3年(新4年)の現象也です。
現象也はタイトル通りロボットやメカの描き方というマニアックな記事を書きます。
これぐらいしか、ブログにするようなネタがないんで。


 ロボットやメカの描き方を扱った書籍やHPって、メカは立方体を組み合わせて~、パースはどうとるか、関節の曲げ方だとか一般的なことに終始したものが多いと思います。
そういった内容も大事だとは思いますが、それでかっこいいロボットやメカが描ける気はしません。
例えば書籍で「面が間延びしないように凹凸を入れて描くようにしましょう」とあっても、実際どんな凹凸を入れればいいのかわかりません。
乱暴な言い方をすると「凹凸を入れるといいけど、どんな凹凸を入れるかは君のセンスに任せる!」ということです。
それってあんまりですよね・・・

 そこで現象也はセンスではなく現実的な視点からロボット・メカのデザインを導く方法を記事にしたいと思います。
タイトルでは「ロボット・メカの描き方」としてるんですが、どっちかていうと「ロボット・メカを描く際の注意点」ぐらいに理解してください。
それと言い忘れましたが、記事にするのはいわゆるリアルロボットのデザインについての個人的な考えです。
兵器も科学もへったくれもない「スーパーロボット」のデザインについては取り扱いませんし、我流なので参考程度に読んでください。


 初回は見た目を大きく左右する装甲の形状についてポイントを3つ挙げます。
f:id:WCE:20130330210811p:plain

①装甲に厚みを持たせる

被弾時に敵の砲弾やビームから機体を守るものですから、容易に貫通されないよう装甲にはある程度の厚みが必要です。
よく装甲がペラペラのイラストを観るんですが、意識しないとミスするポイントなので注意してください。
ただし、いくら厚い方がいいからと厚くしすぎると今度は鈍重な機体になります。
常に敵と正対して戦うことを想定して作られた戦車のように、一番被弾する前面装甲は厚くそうでない上面や背面の装甲は薄いといったデザインもありだと思います。

②前面での装甲の分割は避ける

せっかくの装甲なのに分割してしまっては、そこが弱点になって防御力がダウンします。
できれば分割しない方がいいのですが、巨大な装甲を一体成型するのは難しいということや装甲の取り外し、見栄えのことを考えると分割したくなります。
その場合は前面に分割ラインがくるのを避けるようにデザインしましょう。
関節の稼動を妨げないよう装甲がスライドするような機構を導入するのであればその限りではないと思います。(上のイラストの肩部装甲前面)

③適度にC面を入れる

C面というのは上のイラストの③の部分のように2面を斜めに接続する面のことを言い、C面を入れることを面取りと言います。
多くは直交する2面を45°に接続するのですが、これによって衝突時に機体の角が破損したり、衝突した物体を破損させたりするのを防ぎます。
デザイン的にはイラストの情報量が増え、面が間延びしなくなるので多用されます。
ですがあまりに小さい部品の角にまで面取りするとごみごみするので程々にしましょう。


こんな記事を書いてると合理的に描いた方がいいんだ!と思われるかもしれませんが、そんなことはありません。
リアルロボットのリアルはあくまで「それっぽい」という意味だと思います。
なので、見た目のかっこよさを重視しつつも隙あらば上記のようなポイントを抑えるというスタンスがいいと思います。

関連記事
ロボット・メカの描き方 装甲の形状2

台詞をつけるあそび

CG班新3年の灰色です。
今回は3月29日の活動報告をしたいと思います。

新歓の準備も終わり、暇になっていた僕はらくがきして遊んでいました。
すると、シナリオ班の雀荘に「ワルそうなおっさん書いてー」と頼まれたので描きました。
f:id:WCE:20130330214202p:plain
ワルそうなおっさんです。心まで悪に染まりきっています。
すると、背後でそれを見ていたジャミラスが台詞をつけてきました。
f:id:WCE:20130330214410p:plain
そしてジャミラスはこういって雀荘を煽ります。
「え?シナリオ班長なんだからもっと面白いこと言えるんじゃないですかぁ↑?」
こうしてなぜか唐突に、台詞つけ大会が始まったのでした。

というわけで、作品をまとめて紹介します。

作:ジャミラス
f:id:WCE:20130330214749p:plain

作:サムエル
f:id:WCE:20130330215256p:plain

作:ベンケイ
f:id:WCE:20130330215346p:plain

作:ジャミラス
f:id:WCE:20130330222151p:plain

作:ジャミラス
f:id:WCE:20130330222204p:plain


以上です。
いかがでしたか?個人的にはジャミラスの「池袋駅、どっちですかね」が一番ツボでした。
結構ホームページには真面目なことを書いてますが、普段の活動は結構遊んでたりもしますよっというおはなしでした。

あれ?結局雀荘が何も言ってないような・・・

新歓期の日程

新歓期の WCE のイベントは次の通りです。

サークル見学・説明会(どの日も同じ内容)

場所: 51 号館横 2 階 理工学生ラウンジ
4/10 (水) 18:15 - 19:30
4/12 (金) 18:15 - 19:30
4/17 (水) 18:15 - 19:30
4/19 (金) 18:15 - 19:30

Haskell 勉強会見学

場所: 63 号館 1 階 馬車道
【雨のため中止】4/3 (水) 10:40 - 12:10

来る際には事前連絡は不要です。当日はこのポスターが目印です。
プログラミング、CG・イラスト制作、DTM、シナリオ制作について語り合いましょう。
メンバー一同お待ちしてます!

伏せ音の入れ方

CG班新2年のベンケイです。
いよいよ明日、大学生活を共にする仲間たちと出会うことになります。
それぞれが、それぞれのvisionを思い描いて、新たな一歩を踏み出すことでしょう。
まあその初日にTOEICがあるんですけどね。
いきなり残念な気分になります。

さて、私は唯一の先進理工学部生(電生の方とかいらっしゃってもいいような気がしますが)ですので、増えてくれるといいなとか思っています。
ですから、皆さんの役に立つような内容を書ければいいなと思っているのですが、まだまだ未熟ですので、発信できるような知識・技術がありません。

ということで、豆知識的なことでもやろうと思い、「伏せ音の簡単な入れ方」を説明してみようかと思います。個人情報がとやかく言われる時代ですから思わぬ場面で役に立つかもしれません。

フリーソフトのAudacityを使ってやってみます(サウンド編集ソフトなら多分何でもOK)。

まず、一般的な「ピー音」からやってみましょう。
1. 編集したい音声データを開きます。
2. 伏せたい部分を選択します。
f:id:WCE:20130327135642p:plain
3. ジェネレータを開き、トーンをクリックします。
f:id:WCE:20130327135744p:plain
4. 波形は「サイン波」、周波数は1000くらい、振幅は音の大きさですので範囲内(0~1)で調節してください。
f:id:WCE:20130327135812p:plain  
これで完成です。

これだけではつまらないので、効果音でも入れてみましょう。
今回は「銃声音」を入れてみます。
音源はSenses Circuit様からお借りしました。
1. 編集したい音声データと効果音(今回は銃声音)を開きます。同時に開くことができます。
f:id:WCE:20130327135949p:plain
2. タイムシフトツールを使って位置を合わせます。
f:id:WCE:20130327135959p:plain
3. 伏せたい部分を選択し、ジェネレータ→無音をクリックします。
f:id:WCE:20130327140008p:plain
これで完成です。
こんな感じで簡単に編集ができます。
オリジナルの効果音を作ってやってみるのも面白いかもしれません。

参考までに今回編集したものです。
元音声
ピー音
銃声音