簡単RPG講座11-2。メニューの総仕上げ編。その2

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

簡単RPG講座11-2。メニューの総仕上げ編。その2

投稿記事 by softya(ソフト屋) » 14年前

[party.h]
パーティ(仲間)処理のヘッダです。
今回の場合主人公しかいませんので、主人公処理と言っても良いでしょう。
アイテム・魔法などの処理もここで行いますが、規模が大きくなったらアイテムや魔法はそれぞれ専用の別モジュールに分ける事をお勧めします。
あとレベルアップなども、このモジュールの中で行う予定です。
●ヘッダ全体
ざっと内容を解説すると
ITEM_MAX_NUMSはアイテムを保持できる最大数です。4つを超えて持つことは出来ません。
enum ITEM_??? アイテム番号を定義しています。
enum MAGIC_??? まほう番号を定義しています。
PlayerParam_t 主人公のパラメータです。
MagicDef_t 魔法の定義構造体です。
party_init() 主人公のパラメータを初期化します。
party_getItemName() アイテム名を得る。
party_useItem() アイテムを使用する。
party_getMagicData() 魔法情報を得る。
party_useMagic() 魔法を使用する。ただし、攻撃魔法は戦闘処理の中で処理する。

CODE:

#ifndef INCLUDE_PARTY_H
#define INCLUDE_PARTY_H

//----------------------------------------------------------------------
//	定数
//----------------------------------------------------------------------

//	アイテム所持数
#define ITEM_MAX_NUMS	(4)

//	アイテムの定義
enum {
	ITEM_NON,		//アイテムを所持していない。
	ITEM_HERB,		//薬草
	ITEM_MG_HERB,	//魔法薬草
	
	ITEM_MAX
};

//	まほうの定義
enum {
	MAGIC_FIRE,		//ほのおの攻撃魔法
	MAGIC_HEAL,		//回復魔法

	MAGIC_MAX_NUMS	//まほう最大数
};

//----------------------------------------------------------------------
//	構造体
//----------------------------------------------------------------------

//	プレイヤーパラメータ
typedef struct {
	int level;		//レベル
	int expp;		//経験値(Experience point)
	int	hp;			//HP
	int	hp_max;		//HPMAX
	int	mp;			//MP
	int	mp_max;		//MPMAX
	int	attack;		//攻撃力
	int	def;		//防御力
	int	money;		//所持金
	int items[ITEM_MAX_NUMS];//所持アイテム(4つまで)
} PlayerParam_t;

//	魔法の定義構造体
typedef struct {
	int magic_id;	//enumの定義番号
	char *name;		//名前
	int level;		//使用可能レベル
	int mp;			//使用MP
	int power;		//効果パワー
	int bField;		//フィールド用
	int bBattle;	//バトル用
} MagicDef_t;

//----------------------------------------------------------------------
//	関数の宣言
//----------------------------------------------------------------------

//	初期化
extern void party_init(PlayerParam_t *playerParam);

//	アイテム名を得る。
extern const char *party_getItemName(int item_no);
//	アイテムを使用する。
extern int party_useItem(PlayerParam_t *playerParam,int item_no);

//	魔法情報を得る。
extern const MagicDef_t *party_getMagicData(PlayerParam_t *playerParam,int maig_list_no,int bBattle);
//	魔法を使用する。
extern int party_useMagic(PlayerParam_t *playerParam,int maig_list_no,int bBattle);

#endif /*INCLUDE_PARTY_H*/
[party.cpp]
それでは、プログラム本体の処理です。

●ヘッダから先頭の定義部分
ヘッダと内部関数を定義しています。

CODE:

#include 

#include "main.h"
#include "party.h"

//----------------------------------------------------------------------
//	内部関数
//----------------------------------------------------------------------

static int party_healSub(int *healP,int max,int power);	//回復処理
●定数
初期パラメータとアイテムのパラメータを定義しています。
初期パラメータやアイテムが多くなってきたらテーブル化したほうが良いかも知れません。
テストのため初期パラメータは大きめとなっています。

CODE:

//----------------------------------------------------------------------
//	定数
//----------------------------------------------------------------------

//	初期パラメータ
#define INI_HP_MAX	(50)	//	10
#define INI_MP_MAX	(15)	//	5
#define INI_ATTACK	(10)	//	9
#define INI_DEFENSE	(10)	//	11

//	アイテムパラメータ
#define ITEM_HERB_POWER		(30)
#define ITEM_MG_HERB_POWER	(30)
●内部で使うテーブルです。
s_itemNames アイテム名を定義しています。enumと合わせないと名前の表示がずれます。
s_magicDatas 魔法データの定義ですが、魔法はデータが複雑なので構造体です。これもenumと合わせてください。
魔法が使えるレベルや消費mp、攻撃(回復)力、フィールド/バトル使用の可・不可などを定義しています。
今回のものは仮なので、バランス調整時に改めて調整します。

CODE:

//----------------------------------------------------------------------
//	変数
//----------------------------------------------------------------------


//	アイテムの名前定義。 enumと合わせてください。
static const char *s_itemNames[ITEM_MAX] = {
	"なし",		//	ITEM_NON
	"薬草",		//	ITEM_HERB
	"魔法薬草",	//	ITEM_MG_HERB
};


//	魔法データの定義。 enumと合わせてください。
static const MagicDef_t s_magicDatas[MAGIC_MAX_NUMS] = {
	//	enumの番号	名前		level,	mp	パワー	フィールド用	バトル用
	{ MAGIC_FIRE, "ほのお",		2,		2,	15,		FALSE,	TRUE },	//MAGIC_FIRE	ほのおの攻撃魔法
	{ MAGIC_HEAL, "かいふく",	4,		5,	30,		TRUE,	TRUE },	//MAGIC_HEAL	回復魔法
};
●party_init
主人公のパラメータを初期化します。
ただし、テスト用にパラメータをいじってあります(初期レベルが5だったり)。
これはあくまでテスト用で、戦闘部分を作るときにはちゃんとした値にします。

CODE:

//----------------------------------------------------------------------
//	パラメータ初期化
//----------------------------------------------------------------------
void party_init(PlayerParam_t *playerParam)
{
	//	パラメータに初期値を与える。
	playerParam->level = 5;				//レベル
	playerParam->expp = 0;				//経験値(Experience point)
	playerParam->hp = INI_HP_MAX/2;		//HP
	playerParam->hp_max = INI_HP_MAX;	//HPMAX
	playerParam->mp = INI_MP_MAX/2;		//MP
	playerParam->mp_max = INI_MP_MAX;	//MPMAX
	playerParam->attack = INI_ATTACK;	//攻撃力
	playerParam->def = INI_DEFENSE;		//防御力
	playerParam->money = 0;				//所持金
	for( int i=0 ; iitems[i] = ITEM_NON;//所持アイテム(4つまで)
		if( i%2==0 ) {
			playerParam->items[i] = ITEM_HERB;//所持アイテム(4つまで)
		} else {
			playerParam->items[i] = ITEM_MG_HERB;//所持アイテム(4つまで)
		}
	}
}
●party_getItemName
アイテム名をアイテム番号(item_no)から得て戻り値で返します。

CODE:

//----------------------------------------------------------------------
//	アイテム名を得る。
//----------------------------------------------------------------------
const char *party_getItemName(int item_no)
{
	//	ガード
	MACRO_ASSERT( item_no hp),playerParam->hp_max,ITEM_HERB_POWER);
		//break;

	case ITEM_MG_HERB:	//魔法薬草	
		//	回復させる。利用有無は関数側で判定。
		return party_healSub(&(playerParam->mp),playerParam->mp_max,ITEM_MG_HERB_POWER);
		//break;
	}
	
	//	アイテムを使用した。
	return TRUE;
}
●party_getMagicData
魔法データをメニューの魔法リストの番号から返す関数です。
レベルやバトル・フィールドの条件で使える魔法が変わるのでリスト番号も変わります。

CODE:

//----------------------------------------------------------------------
//	魔法情報を得る。
//----------------------------------------------------------------------
const MagicDef_t *party_getMagicData(PlayerParam_t *playerParam,int maig_list_no,int bBattle)
{
	//	魔法テーブルの検索
	int activeNo = 0;
	for( int i=0 ; ilevel >= s_magicDatas[i].level ) {
				//	該当番号?
				if( maig_list_no == activeNo ) {
					return &s_magicDatas[i];
				}
				activeNo++;//番号をカウント
			}
		}
	}
	
	//	該当魔法がない。
	return NULL;
}
●party_useMagic
魔法を使用してMPを消費します。ただし攻撃魔法などは戦闘処理側で処理します。
今回実装されているのは回復魔法です。
最初にMPが十分にあるか確認して、もし足らなければ魔法は実行されません。
回復処理はparty_healSub()で行われ、もし回復する場合はTRUEが戻ってくるのでMPを消費します。

CODE:

//----------------------------------------------------------------------
//	魔法を使用する。
//----------------------------------------------------------------------
int party_useMagic(PlayerParam_t *playerParam,int maig_list_no,int bBattle)
{
	const MagicDef_t *pMagicData = party_getMagicData(playerParam,maig_list_no,bBattle);
	MACRO_ASSERT( pMagicData != NULL );//無いと思うがガード。
	
	//	もしmp不足なら?
	if( playerParam->mp mp ) {
		//	発動しない。
		return FALSE;
	}
	
	//	魔法効果(回復などに限る)。攻撃魔法などは、戦闘処理で担当。
	switch( pMagicData->magic_id ) {
	case MAGIC_HEAL:	//回復魔法
		//	回復させる。回復魔法を使ったらTRUEで戻る。
		if( party_healSub(&(playerParam->hp),playerParam->hp_max,pMagicData->power) ) {
			//	mpを消費
			playerParam->mp -= pMagicData->mp;
		}
		break;
	}
	
	//	成功
	return TRUE;
}
●party_healSub
共通の回復処理です。
回復先の変数はポインタで更新できるようになっています。
まず、回復する値がMAX未満なら回復処理を発動します。MAXなら未発動でFALSEを返します。
回復する値はpower値に15%程の乱数値を加算したもので、値のゆらぎがあります。
回復した場合にはTRUEを返します。

CODE:

//----------------------------------------------------------------------
//	回復共通処理
//----------------------------------------------------------------------
static int party_healSub(int *healP,int max,int power)
{
	//	回復必要?
	if( *healP  max) {
			*healP = max;
		}
		//	回復した。
		return TRUE;
	} else {
		//	回復しなかった。
		return FALSE;
	}
}
以上、パーティ処理でした。
続いてはメニュー処理です。
最後に編集したユーザー softya(ソフト屋) on 2011年2月07日(月) 19:09 [ 編集 1 回目 ]

きょーちゃん
記事: 11
登録日時: 14年前

Re: 簡単RPG講座11-2。メニューの総仕上げ編。その2

投稿記事 by きょーちゃん » 14年前

こんばんは。毎回楽しく読ませていただいてます。
まだ全然内容にはついていけてませんが^^;

ここで質問すべきかどうか迷ったのですが、マップについて質問です。
platinumを使ってはいるのですがfmfファイルの使い方がよくわからないので、パーツを並べた一枚絵をそのまま読み込んで使っています。
ですが、こちらの講座ではマップチップの組み合わせでマップを構成してますよね(と思ったのですが合ってるでしょうか)?
素人目にはその処理ってすごく大変そう(重くなりそう)・・・って思ってしまうんですが
今後、マップが増えたり、イベントを配置したりということを考えるならチップを組み合わせる方が効率的なのでしょうか?
まだ全然プログラムの効率とか考えるようなレベルじゃないんですが・・・

こういう質問って掲示板ですべきでしょうか?
質問ばかりですいません。あと、もし場違いな質問だったらごめんなさい。

taketoshi
記事: 222
登録日時: 14年前

Re: 簡単RPG講座11-2。メニューの総仕上げ編。その2

投稿記事 by taketoshi » 14年前

ゲームを作ったことはないのですが
こういう風にゲームは作られれているのか、と
全体的な流れを読むことが出来て楽しみです。

まだゲームを作ったことがないのですが、力が付いたら参考にさせていただいて、作ってみたいと思いました。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 簡単RPG講座11-2。メニューの総仕上げ編。その2

投稿記事 by softya(ソフト屋) » 14年前

>>きょーちゃんさん
>こういう質問って掲示板ですべきでしょうか?
>質問ばかりですいません。あと、もし場違いな質問だったらごめんなさい。

このぐらいなら、ここでかまいませんよ。
RPG講座ではplatinumで3レイヤ(層)使っています。
ただし、描画用は1レイヤで後はイベント・レイヤと当たり判定用レイヤです。
今時のパソコンなら当たり判定やイベントレイヤの他にマップ描画に2レイヤぐらい使っても合成は楽々出来ると思いますが、ビデオカードの性能に左右されるで実験はしてくださいね。

町マップのppjを添付しておきますので参考にしてください。
添付ファイル

[拡張子 zip は無効化されているため、表示できません]


アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 簡単RPG講座11-2。メニューの総仕上げ編。その2

投稿記事 by softya(ソフト屋) » 14年前

>>taketoshiさん

きょーちゃんさんにも書いたのですがRPG講座で文法レベルやアルゴリズムで謎のことがあれば質問掲示板で質問してくださいね。
質問大歓迎です。

ISLe
記事: 2650
登録日時: 14年前

Re: 簡単RPG講座11-2。メニューの総仕上げ編。その2

投稿記事 by ISLe » 14年前

きょーちゃん さんが書きました:ですが、こちらの講座ではマップチップの組み合わせでマップを構成してますよね(と思ったのですが合ってるでしょうか)?
素人目にはその処理ってすごく大変そう(重くなりそう)・・・って思ってしまうんですが
パソコンなら良いのですが、ケータイアプリだと画面サイズより横幅の大きい画像を読み込んだりオフスクリーンを作ったりできないという制限があったりします。
ファミコン時代のハードウェアBGは画面と同じかちょっと大きいくらいのサイズしか無かったのでチップを書き換えるしかありませんでした。
そういうのを再現している感じでしょうかね。

最近のゲームは一枚絵の背景を使ったものも珍しくないですけど繋ぎ合わせて表示する必要があると逆にプログラムはたいへんだったりします。

きょーちゃん
記事: 11
登録日時: 14年前

Re: 簡単RPG講座11-2。メニューの総仕上げ編。その2

投稿記事 by きょーちゃん » 14年前

>softyaさん
ありがとうございます!さっそくダウンロードさせていただきました。
まだplatinumも使いこなせてないのですが、いろいろいじくりながら勉強してみます。

>ISLeさん
ありがとうございます。一枚絵もナシではないってことですね。
ではいつかはマップチップ使いこなせるようになるのを目標に、当面は一枚絵であがいてみます。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 簡単RPG講座11-2。メニューの総仕上げ編。その2

投稿記事 by softya(ソフト屋) » 14年前

>きょーちゃんさん。
一枚絵の問題は、歩けない所や歩ける所の設定をどうするか考えないいけない事でしょう。
ゲーム会社なら専用の設定ツールとか作れば良いわけですが。

なんのかんので、マップチップはブロック単位で管理できるので便利なんですよね。
地形書き換えもマップチップの変更で済みますし。

ISLe
記事: 2650
登録日時: 14年前

Re: 簡単RPG講座11-2。メニューの総仕上げ編。その2

投稿記事 by ISLe » 14年前

一枚絵の場合は、同じ大きさのモノクロ画像(ビットマップ)を用意して移動できるところとできないところを区別する感じになりますね。
チップサイズで割ったり余りを求めたりが要らないのでコードがシンプルにはなりますけど、プログラム以外の制作コストがチップ単位がピクセル単位になる分跳ね上がります。
プログラムで楽ができるのは実寸大のマップ画像をそのまま固定して表示する場合だけです。
繋ぎ合わせたり解像度を落としたりするとチップを使う場合とまったく同じコードが必要になります。
スクロールさせる場合もオフセットの計算でチップを使う場合に追加する半分くらいのコードが必要です。

マップチップはむしろ性能の低いマシンで使われているので「大変そう(重くなりそう)」というのは違うよと書いただけのつもりでした。
一枚絵はもっとたいへんです。
珍しくはなくなっても一枚絵マップが売りにされることは少なくないです。
それだけみんなやりたがらないということなのです。
最後に編集したユーザー ISLe on 2011年2月08日(火) 17:43 [ 編集 1 回目 ]

きょーちゃん
記事: 11
登録日時: 14年前

Re: 簡単RPG講座11-2。メニューの総仕上げ編。その2

投稿記事 by きょーちゃん » 14年前

>>softyaさん
今は「ゲームプログラムの館」にあるように2次元配列で歩けないところを作ってるんですが、書き換えがすごく大変でした^^;
マップチップの方が後々楽そうですね。

>>ISLeさん
なんだか勘違いをしてしまったみたいですいません。
まだ固定マップしか作ったことなかったのでそのあたりの感覚が全然分かってませんでした。
>マップチップはむしろ性能の低いマシンで・・・
ちょっと驚きでした。
チップひとつひとつを読み込んで配置して・・・ってすごく大変そうに思えたのですが、まだまだパソコンの気持ちが分かってないですねw