Skip to content

プレイヤーとブロックの配置

あさちゅん edited this page Nov 11, 2016 · 2 revisions

背景の設定

真っ黒い画面だとモチベーションも上がらないのでまずは背景を設定しましょう。

デフォルトのウィンドウはゲームをするには小さいので 1280×720 にリサイズします。次にTextureを作り、描画しますが、そのままだと大きさが足りないので、ウィンドウの大きさと同じRectを作り、そこに貼り付けて描画します。縦横比が崩れてしまうので、実際に作るときはウィンドウと同じ縦横比の画像を用意しましょう。

# include <Siv3D.hpp>

void Main()
{
	Window::Resize(1280, 720);

	Texture background(L"Example/Windmill.png");

	while (System::Update())
	{
		Rect(Window::Size())(background).draw();
	}
}

Blockクラスの作成

足場となるBlockクラスを作ります。

まず、メンバ変数として必要なのはどこに配置されているかを示すRectFと表示する画像を示すTextureになります。RectFの方はコンストラクタで設定できるようにしておきましょう。

次にメンバ関数についてですが、ブロックのようにゲーム内に描画されるオブジェクトは「更新のみを行う関数」と「描画のみを行う関数」を分けましょう。
今回はそれぞれをupdate関数, draw関数としました。ブロックは一度設置すると、そのまま更新されることはないのでupdate関数は不要なのですが、今後のことを考えて作っておきましょう。

class Block
{
public:

	// 引数のないコンストラクタも作っておくといろいろ便利.
	Block() {}

	Block(const RectF& region) :
		m_region(region),
		m_texture(L"Example/Brick.jpg") {}

	void update()
	{

	}

	void draw()
	{
		m_region(m_texture).draw();
	}


private:

	RectF m_region;

	Texture m_texture;

};

ブロックの配置

さっき使ったBlockを配置していきます。

複数配置したいのでArray(Siv3D版vector)を使用します。update関数とdraw関数のために二回for文を回すのは無駄に見えますが、今後のために面倒でも分けておいてください。

また、backgroundの前にblocksのdraw関数を呼んでしまうと、ブロックが後ろに入って背景しか見えなくなるので描画順に注意してください。

// Blockクラスの定義をここに書く

void Main()
{
	Window::Resize(1280, 720);

	Texture background(L"Example/Windmill.png");
	Array<Block> blocks;

	blocks.push_back(Block({-400, 400, 200, 200}));
	blocks.push_back(Block({-200, 400, 200, 200}));
	blocks.push_back(Block({0, 400, 200, 200}));
	blocks.push_back(Block({200, 400, 200, 200}));
	blocks.push_back(Block({200, 200, 200, 200}));
	blocks.push_back(Block({400, 400, 200, 200}));
	blocks.push_back(Block({800, 400, 200, 200}));
	blocks.push_back(Block({1000, 400, 200, 200}));
	blocks.push_back(Block({1300, 200, 400, 30}));

	while (System::Update())
	{
		for (size_t i = 0; i < blocks.size(); i++)
		{
			blocks[i].update();
		}



		Rect(Window::Size())(background).draw();

		for (size_t i = 0; i < blocks.size(); i++)
		{
			blocks[i].draw();
		}
	}
}

Playerクラスの作成

同様にPlayerクラスも作成しましょう。

メンバ変数としてRectFを持ちたいところですが、キャラクターは座標で管理した方が扱いやすいのでVec2をメンバに持たせます。

ただの点だと見辛いので点を中心とした円をdraw関数で描画しておきます。update関数内では左右キーの状態によってx座標を変更します。これにより水平方向に移動することができるようになります。

class Player
{
public:

	Player() : m_position(100, 200) {}

	void update()
	{
		if (Input::KeyRight.pressed)
		{
			m_position.x += 5.0;
		}
		if (Input::KeyLeft.pressed)
		{
			m_position.x -= 5.0;
		}
	}

	void draw()
	{
		Circle(m_position, 50).draw();
	}
	
private:

	Vec2 m_position;
};


void Main()
{
	// Player以外省略
	Player player;

	while (System::Update())
	{
		player.update();

		player.draw();
	}
}

プレイヤーの描画

次にPlayerクラスにもTextureを持たせ描画しますが、ここで一つ注意があります。

今までm_positionで指定してきた座標はキャラクターの座標なので、その足元が示されるべきですが、RectFで指定する座標は画像の左上です。

なのでそのことを考慮して、横幅と縦幅、m_positionから画像の左上の座標を計算してRectFを作成、draw関数を呼びます。

class Player
{
public:

	Player() :
		m_position(100, 200),
		m_texture(L"Example/Siv3D-kun.png") {}

	void update()
	{
		if (Input::KeyRight.pressed)
		{
			m_position.x += 5.0;
		}
		if (Input::KeyLeft.pressed)
		{
			m_position.x -= 5.0;
		}
	}

	void draw()
	{
		RectF(m_position.x - 72.5, m_position.y - 200, 145, 200)(m_texture).draw();
	}

private:

	Vec2 m_position;

	Texture m_texture;
};

まとめ

まだ、重力も当たり判定も実装していないので、Siv3D君が宙を平行移動している状態ですが、とりあえず絵面として必要なものは揃いました。次回は重力とジャンプ機能を実装しようと思います。

見本

# include <Siv3D.hpp>

class Block
{
public:

	// 引数のないコンストラクタも作っておくといろいろ便利.
	Block() {}

	Block(const RectF& region) :
		m_region(region),
		m_texture(L"Example/Brick.jpg") {}

	// 描画以外の操作をする関数
	void update()
	{
		// 今回は何もない
	}

	// 描画をする関数(描画操作以外行わないこと.)
	void draw()
	{
		m_region(m_texture).draw();
	}


private:

	// ブロックの領域
	RectF m_region;

	// ブロックのテキスチャ(画像)
	Texture m_texture;
};


class Player
{
public:

	Player() :
		m_position(100, 200),
		m_texture(L"Example/Siv3D-kun.png") {}

	// 描画以外の操作をする関数
	void update()
	{
		if (Input::KeyRight.pressed)
		{
			m_position.x += 5.0;
		}
		if (Input::KeyLeft.pressed)
		{
			m_position.x -= 5.0;
		}
	}

	// 描画をする関数(描画操作以外行わないこと.)
	void draw()
	{
		RectF(m_position.x - 72.5, m_position.y - 200, 145, 200)(m_texture).draw();
	}

private:

	// プレイヤーの座標
	Vec2 m_position;

	// プレイヤーのテクスチャ(画像)
	Texture m_texture;
};


void Main()
{
	Window::Resize(1280, 720);

	Texture background(L"Example/Windmill.png");
	Player player;
	Array<Block> blocks;

	blocks.push_back(Block({-400, 400, 200, 200}));
	blocks.push_back(Block({-200, 400, 200, 200}));
	blocks.push_back(Block({0, 400, 200, 200}));
	blocks.push_back(Block({200, 400, 200, 200}));
	blocks.push_back(Block({200, 200, 200, 200}));
	blocks.push_back(Block({400, 400, 200, 200}));
	blocks.push_back(Block({800, 400, 200, 200}));
	blocks.push_back(Block({1000, 400, 200, 200}));
	blocks.push_back(Block({1300, 200, 400, 30}));

	while (System::Update())
	{
		for (size_t i = 0; i < blocks.size(); i++)
		{
			blocks[i].update();
		}

		player.update();

		// 実際には縦横比を合わせるように.
		Rect(Window::Size())(background).draw();

		for (size_t i = 0; i < blocks.size(); i++)
		{
			blocks[i].draw();
		}

		player.draw();
	}
}

|| - 目次 - | 次の章へ進む →


Written by あさちゅん

Siv3D について

  1. Siv3D の基本
  2. 図形を描く
  3. テクスチャを描く
  4. テキストを描く
  5. 文字列と数値の変換
  6. キーボード入力
  7. マウス入力
  8. サウンドの再生
  9. MIDI の再生
  10. ウィンドウと背景
  11. 図形のあたり判定
  12. 乱数
  13. ダイアログ
  14. ドラッグ & ドロップ
  15. アプリの状態
  16. テキストファイル
  17. INI, CSV, JSON
  18. バイナリファイル
  19. GUI
  20. アセット管理
  21. 画像編集
  22. Web カメラ
  23. マイク入力
  24. 経過時間の測定
  25. HSV カラー
  26. ファイルダウンロード
  27. 3D 描画
  28. 2D のレンダーステート
  29. 3D のレンダーステート
  30. パーティクル
  31. スクリーンショット
  32. アプリケーションの公開
  33. さらに学ぶには

表現テクニック集

入出力デバイス

開発のヒント

Clone this wiki locally