ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

FFもどきコミュの5.実装方法

  • mixiチェック
  • このエントリーをはてなブックマークに追加

○実装方法

 ☆大方針
  Cで書く。プラプラとかよくわかんにゃいから。
  でも環境はC++Builder

  非同期で書く。近頃のCPUパワーを信じて、画面表示とキー受付は非同期にする。

  ステータス、という現状を表す配列を共有した、複数スレッドの動作により実現する。
  各スレッドは、各スレッドが担当するステータス以外からの入力を、
  関数ポインタに準じたものでステータスから受け取る。

  シナリオはテキストベースにして、リコンパイルしなくても、
  いいようにしたい。

  ラッパーを多用して、改善しやすく、可搬性高く設計する。

  性能は読めない、性能は低いという弱点はあるけど気にしない。


 ☆こんなかんじやろうか

 ・ステータスコントロール・スレッド 
  (キー入力に応じて、ステータスを変更する。
  現状のイベント要素配列、に応じて、受け付けた


global 次のキー入力を受け付けても良いかどうかのフラグ
VSYNC待ちになっているかどうかを表すフラグ



  キー入力受付スレッド
  ↓(パラレル・
全ての状態をイベントとみなす事に、簡略化の意義がある。
  イベント要素配列
stat {

//
 key_statchange( 次のキー入力受付による、イベント要素変更内容構造体




event {
event_id
key_statchange
music
map
mapwindow

  音楽要素配列
  ↑         ↑


  画面表示要素配列
  ↑(
 ・画面表示作成スレッド
  ↓
  画面作成・VSYNC待ち

 タイマースレッド?

 非同期と
 画面表示









コメント(4)

ソースおいてみたら、やる気がでるかも!という話を聞いて載せてみた。


main.cpp

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;



//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{

}
//---------------------------------------------------------------------------





void __fastcall TForm1::renderTimerTimer(TObject *Sender)
{

Form1->map->render ( );





}
//---------------------------------------------------------------------------

//忘れそうなローカル規約群
// Canvas->Draw( x, y, Image1->Picture->Graphic );
// Canvas->MoveTo ( x, y );
// Canvas->LineTo ( x + stat.map_w[x][y], y + stat.map_w[x][y]);
/*
Canvas->Pen->Color = clBlack;
Canvas->MoveTo ( _sx, _sy );
Canvas->LineTo ( _ex, _ey );
*/

void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
TShiftState Shift)
{

///わざわざタイマー噛ませているのは、押し続け処理の為
Form1->key = Key;

}

//---------------------------------------------------------------------------



void __fastcall TForm1::firstInitTimer(TObject *Sender)
{
Form1->syslog->Lines->Add ("firstinit");

Form1->map = new cMap(16, Form1->mapchipRsc, Form1->mapCanvas, 6, 6, Form1->syslog );

firstInit->Enabled = false;

renderTimer->Enabled = true;
keyScanTimer->Enabled = true;

Form1->syslog->Lines->Add ("firstinit end");
}
//---------------------------------------------------------------------------
//-------------sample
//int __fastcall TForm1::render( void )
//{
//}



///わざわざタイマー噛ませているのは、押し続け処理の為
void __fastcall TForm1::keyScanTimerTimer(TObject *Sender)
{
if ( Form1->key )
Form1->map->keyProcess( &Form1->key , Form1->syslog );



}
//---------------------------------------------------------------------------




main.h

//---------------------------------------------------------------------------
#ifndef mainH
#define mainH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
#include <MPlayer.hpp>
//---------------------------------------------------------------------------


#define INITDEBUG
#define KEYDEBUG



//cScenario
//cMap
// 等に、共通の関数として、keyProcess


class cRpg
{
public:
bool keyProcessActive;
bool renderProcessActive;

virtual __fastcall void render ( void ){};
virtual __fastcall void keyProcess ( Word &Key ){};

void(cRpg::*activeRender)(void); // 同じクラスのメンバ関数へのポインタ
void(cRpg::*activeKeyProcess)(Word &Key); // 同じクラスのメンバ関数へのポインタ





};


class cGameStat;
class cScenario;



class cCharaStat
{
// int mapWindow[5][5];




};




// cMap マップ関係の大元 


//クラス等、インスタンスがないものにはプレフィクスをつける
//クラスは、c

//クラス名は大文字で、ロワーキャメルケース c...
//クラスのメンバインスタンス・メンバ関数もロワーキャメルケース

//引数は全部小文字とアンスコ



#define WORLDMAPSIZE 1000

// oddでなければならない
#define MAPWINDOWSIZE 15


// cMap - cMapConst マップ関係の初期に決めたらあと定数
// ある一枚のワールドマップ
// map切り替えが起こらないかぎり、変更はされない。
class cMap : cRpg
{


private:
int mapchipRscWidth; // map chipの集合体(原資のimgの大きさ、cMapConstInitで
int mapchipRscHeight; // map chipの集合体(原資のimgの大きさ、cMapConstInitで

TImage *mapchipRsc; // map chipの集合体Imageへのポインタ
TImage *renderTarget; // マップを書く先
int mapchipSize; // map chipの一つのマス目の大きさ

int mapXPos;
int mapYPos; // キャラクターのワールドマップ上での位置

int worldMap[WORLDMAPSIZE][WORLDMAPSIZE]; // 自ずとしてれたworld map
// 本当はコンストラクタで、ファイルから呼ばれないといけない。



public:


// マップを作るときにしか呼ばれない。
// Form1のインスタンスが出来てからじゃないと、imgでForm1上のImageインスタンスを指せないから、
__fastcall cMap( int chipsize, TImage *mapchip_rsc_img, TImage *render_target, int map_x_pos, int map_y_pos, TMemo *syslog)
{

syslog->Lines->Add("cMap constuructor start");

mapXPos = map_x_pos;
mapYPos = map_y_pos;

syslog->Lines->Add( IntToStr (mapXPos ) );

mapchipRsc = mapchip_rsc_img;
renderTarget = render_target;
mapchipSize = chipsize;

if ( mapchip_rsc_img-> AutoSize ) // imgはAutoSize = trueにしといて!
mapchipRscWidth = mapchip_rsc_img->Width,
mapchipRscHeight = mapchip_rsc_img->Height;
else
{
syslog->Lines->Add("cMapConst specified img->AutoSize is not true");
return;

}


つづきー


if ( mapchip_rsc_img-> AutoSize ) // imgはAutoSize = trueにしといて!
mapchipRscWidth = mapchip_rsc_img->Width,
mapchipRscHeight = mapchip_rsc_img->Height;
else
{
syslog->Lines->Add("cMapConst specified img->AutoSize is not true");
return;

}




// 変更しないと
// wolrdMapの初期化 初期化してねぇと、リンカがインスタンスを確保しないので、テストできねぇ
for ( int x = 0; x < WORLDMAPSIZE; x ++ )
for ( int y = 0; y < WORLDMAPSIZE; y ++ )
worldMap[x][y] = 240;
worldMap[5][6] = 0;


syslog->Lines->Add("cMapConst end");
}


// mapを書く関数です。
// 初期化時に与えられている変数と、引数として渡される主人公のx_pos, y_posを元に書きます。
virtual __fastcall void render ( void )
{


int mapWindow [MAPWINDOWSIZE][MAPWINDOWSIZE];

// ワールドマップの内容を、見える画面であるマップウィンドウに変換します。
// ワールドマップの上と下、左と右はつながっています。
// つながらないマップを作りたい時は、十分に進入禁止エリアを作れば大丈夫です。


int mapWindowX = 0, mapWindowY = 0;
int worldX, worldY;



for ( int y = -1 * ( MAPWINDOWSIZE -1 ) /2 ; y <= ( MAPWINDOWSIZE -1 ) /2 ; y++ ){

worldY = y + mapYPos + MAPWINDOWSIZE;
worldY %= MAPWINDOWSIZE;

for ( int x = -1 * ( MAPWINDOWSIZE -1 ) /2 ; x <= ( MAPWINDOWSIZE -1 ) /2 ; x++ ){

worldX = x + mapXPos + MAPWINDOWSIZE;
worldX %= MAPWINDOWSIZE;

mapWindow [mapWindowX++][mapWindowY] = worldMap [worldX][worldY];



}
mapWindowX = 0;
mapWindowY++;

}


// ある、イベントでは、ここに何か描画が必要かもしれません
// イベントに応じてマップウィンドウに描画が必要かもしれません。
// それとも写真とか絵にしちまうか!


// マップウィンドウを元に描画します

TRect render_src;
TRect render_dest;

renderTarget->Canvas->CopyMode = cmSrcCopy;

for ( int y = 0; y < MAPWINDOWSIZE ; y ++ )
for ( int x = 0 ; x < MAPWINDOWSIZE ; x ++ ){

render_dest = Rect( x * mapchipSize , y * mapchipSize, x * mapchipSize + mapchipSize, y * mapchipSize +mapchipSize );



int mapchipX = mapWindow[x][y] % ( mapchipRscWidth / mapchipSize) * mapchipSize;
int mapchipY = mapWindow[x][y] / ( mapchipRscWidth / mapchipSize) * mapchipSize;


render_src = Rect( mapchipX, mapchipY, mapchipX + mapchipSize, mapchipY + mapchipSize );
renderTarget->Canvas->CopyRect( render_dest, mapchipRsc->Canvas, render_src );


};


}



void __fastcall keyProcess( Word *Key , TMemo *syslog )
{

syslog->Lines->Add("cMap->keyProcess");
syslog->Lines->Add ("map keyProces start" + IntToStr( (int)( *Key ) ));

if ( *Key == VK_LEFT ) // left 37
mapXPos --;

if ( *Key == VK_UP ) // up 38
mapYPos --;

if ( *Key == VK_RIGHT ) // right 39
mapXPos ++;

if ( *Key == VK_DOWN ) //down 40
mapYPos ++;

*Key = 0;

syslog->Lines->Add ("mapXPos" + IntToStr( mapXPos ) + "mapYPos" + IntToStr( mapYPos ));

}
};


class TForm1 : public TForm
{
__published: // IDE 管理のコンポーネント
TTimer *renderTimer;
TLabel *Label1;
TLabel *Label2;
TLabel *Label3;
TLabel *Label4;
TLabel *Label5;
TLabel *Label6;
TImage *Image1;
TImage *mapchipRsc;
TMemo *syslog;
TImage *mapCanvas;
TTimer *firstInit;
TTimer *keyScanTimer;
void __fastcall renderTimerTimer(TObject *Sender);

void __fastcall FormKeyDown(TObject *Sender, WORD &Key,
TShiftState Shift);



void __fastcall firstInitTimer(TObject *Sender);



void __fastcall keyScanTimerTimer(TObject *Sender);
private: // ユーザー宣言
public: // ユーザー宣言


// int __fastcall init( void );


cMap *map;
Word key;

__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

FFもどき 更新情報

FFもどきのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング