シーン分け 継承について
シーン分け 継承について
シーン分けについてですが
継承を学んだので継承でシーン分けを考えていたのですが、
プレイ画面で引数が変わる場合継承ができなくて困っています。
その場合は共通に
しなければなりませんか?
なにかいい方法があれば教えてくださいお願いします。
int no = 0;//シーンの番号
int main(){
[tab=30]Windows windows;
[tab=30]HWND hwnd = windows.CreateSimPleWindow();//ウインドウの作成
[tab=30]Graphics g;
[tab=30]g.Init( hwnd );//グラフィックの初期化
[tab=30]Input input;
[tab=30]Field field( g );
[tab=30]Scene *scene = new Title;
[tab=30]scene->Init( g );
[tab=30]while( DoEvents() ){
[tab=30][tab=30]g.Clear();
[tab=30][tab=30]input.Update(); //キーの更新[/color]
[tab=30][tab=30]KeyboardState key = input.GetKeyboard(); //キーの情報を取得
[tab=30][tab=30][color=#00FF000]//キー入力でプレイ画面に行く[/color]
[tab=30][tab=30]if( no == 0 ){ //タイトル画面
[tab=30][tab=30]if( key.Just( Key::A ) ){
[tab=30][tab=30][tab=30][tab=30]delete scene;
[tab=30][tab=30][tab=30][tab=30]no = 1;//プレイ画面に移動
[tab=30][tab=30][tab=30][tab=30]scene = new Field( g );
[tab=30][tab=30][tab=30][tab=30]scene->Init( g );
[tab=30][tab=30]}
[tab=30][tab=30]scene->KeyUpdate();
[tab=30][tab=30]scene->Update( );
[tab=30][tab=30]scene->Draw( g );
[tab=30][tab=30]}
[tab=30][tab=30] //プレイ画面
[tab=30][tab=30] if( no == 1 ){
[tab=30][tab=30]field.KeyUpdate( &field, key );//問題の部分です
[tab=30][tab=30] field.Update( );
[tab=30][tab=30]field.Draw( g );
[tab=30][tab=30] }
[tab=30][tab=30] g.Update();
[tab=30] }
[tab=30] scene->Release();
[tab=30] g.Release();
}
継承を学んだので継承でシーン分けを考えていたのですが、
プレイ画面で引数が変わる場合継承ができなくて困っています。
その場合は共通に
しなければなりませんか?
なにかいい方法があれば教えてくださいお願いします。
int no = 0;//シーンの番号
int main(){
[tab=30]Windows windows;
[tab=30]HWND hwnd = windows.CreateSimPleWindow();//ウインドウの作成
[tab=30]Graphics g;
[tab=30]g.Init( hwnd );//グラフィックの初期化
[tab=30]Input input;
[tab=30]Field field( g );
[tab=30]Scene *scene = new Title;
[tab=30]scene->Init( g );
[tab=30]while( DoEvents() ){
[tab=30][tab=30]g.Clear();
[tab=30][tab=30]input.Update(); //キーの更新[/color]
[tab=30][tab=30]KeyboardState key = input.GetKeyboard(); //キーの情報を取得
[tab=30][tab=30][color=#00FF000]//キー入力でプレイ画面に行く[/color]
[tab=30][tab=30]if( no == 0 ){ //タイトル画面
[tab=30][tab=30]if( key.Just( Key::A ) ){
[tab=30][tab=30][tab=30][tab=30]delete scene;
[tab=30][tab=30][tab=30][tab=30]no = 1;//プレイ画面に移動
[tab=30][tab=30][tab=30][tab=30]scene = new Field( g );
[tab=30][tab=30][tab=30][tab=30]scene->Init( g );
[tab=30][tab=30]}
[tab=30][tab=30]scene->KeyUpdate();
[tab=30][tab=30]scene->Update( );
[tab=30][tab=30]scene->Draw( g );
[tab=30][tab=30]}
[tab=30][tab=30] //プレイ画面
[tab=30][tab=30] if( no == 1 ){
[tab=30][tab=30]field.KeyUpdate( &field, key );//問題の部分です
[tab=30][tab=30] field.Update( );
[tab=30][tab=30]field.Draw( g );
[tab=30][tab=30] }
[tab=30][tab=30] g.Update();
[tab=30] }
[tab=30] scene->Release();
[tab=30] g.Release();
}
Re: シーン分け 継承について
main()関数の実装内容を見せられても、何とも言えない気がします。
問題の箇所だと指摘されている、
・fieldクラスについて
・どうして引数が変わるのか、ご自身が考える設計内容について
の情報が無いとコメント難しいと思います。
問題の箇所だと指摘されている、
・fieldクラスについて
・どうして引数が変わるのか、ご自身が考える設計内容について
の情報が無いとコメント難しいと思います。
Re: シーン分け 継承について
失礼しました
ポインタで渡すのは
先行宣言をするためにポインタにしています。
Field.cpp
KeyUpdateではキー入力の処理をしています
block.Turn関数でfieldのポインタを渡したいので引数で渡しています
void Field::KeyUpdate( Field *field,KeyboardState &key){
[tab=30]//キーの入力にやる操作
省略
[tab=30] if( key.Just( Key::A ) ){
[tab=30][tab=30] block.Turn( *field );
[tab=30] }
[tab=30] if( key.Just( Key::S ) ){
[tab=30][tab=30] block.Turn( *field );
[tab=30] }
}
Block.cpp
TurnではfieldのGet()関数を使いたいので、参照で渡し
Getが真なら処理を実行させる形です
void Block::Turn(Field &field){
省略
[tab=30] //回転できるかどうか調べる
[tab=30] //ブロックがすでに合ったらフラグを立てる
[tab=30] //もしくはフィールド外なら回転しない
[tab=30] for(int i = 0;i < 4; i ++ ){
[tab=30][tab=30] for(int j = 0;j < 4; j ++ ){
[tab=30][tab=30][tab=30] if( field.Get( pos.x + j, pos.y + i ) ){
[tab=30][tab=30][tab=30][tab=30] 省略
[tab=30][tab=30][tab=30] }
[tab=30][tab=30][tab=30] if( pos.x + j < 0 || pos.x + j >= Field_X ){
[tab=30][tab=30][tab=30][tab=30] 省略
[tab=30][tab=30][tab=30] }
[tab=30][tab=30] }
[tab=30] }
}
このような説明で理解いただけましたか?
お願いします。
ポインタで渡すのは
先行宣言をするためにポインタにしています。
Field.cpp
KeyUpdateではキー入力の処理をしています
block.Turn関数でfieldのポインタを渡したいので引数で渡しています
void Field::KeyUpdate( Field *field,KeyboardState &key){
[tab=30]//キーの入力にやる操作
省略
[tab=30] if( key.Just( Key::A ) ){
[tab=30][tab=30] block.Turn( *field );
[tab=30] }
[tab=30] if( key.Just( Key::S ) ){
[tab=30][tab=30] block.Turn( *field );
[tab=30] }
}
Block.cpp
TurnではfieldのGet()関数を使いたいので、参照で渡し
Getが真なら処理を実行させる形です
void Block::Turn(Field &field){
省略
[tab=30] //回転できるかどうか調べる
[tab=30] //ブロックがすでに合ったらフラグを立てる
[tab=30] //もしくはフィールド外なら回転しない
[tab=30] for(int i = 0;i < 4; i ++ ){
[tab=30][tab=30] for(int j = 0;j < 4; j ++ ){
[tab=30][tab=30][tab=30] if( field.Get( pos.x + j, pos.y + i ) ){
[tab=30][tab=30][tab=30][tab=30] 省略
[tab=30][tab=30][tab=30] }
[tab=30][tab=30][tab=30] if( pos.x + j < 0 || pos.x + j >= Field_X ){
[tab=30][tab=30][tab=30][tab=30] 省略
[tab=30][tab=30][tab=30] }
[tab=30][tab=30] }
[tab=30] }
}
このような説明で理解いただけましたか?
お願いします。
Re: シーン分け 継承について
引数が変わるので継承ができないというのは、Fieldクラスが継承されるクラスですか?
それと、KeyUpdate関数について、どのように引数を変更したいのですか?
その説明ではイマイチ伝わらないと思います。
それと、KeyUpdate関数について、どのように引数を変更したいのですか?
その説明ではイマイチ伝わらないと思います。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: シーン分け 継承について
codeタグを利用していただくと手間もかからず読みやすくなります。
詳しくはフォーラムルールをお読みください。
シーン分け継承がどの様な形でつなげるつもりなのか、こちらに伝わらないって感じです。
意図している継承とは、どんな事でしょうか?
現状のfieldクラス自体の定義も見せてください。
詳しくはフォーラムルールをお読みください。
int no = 0;//シーンの番号
int main(){
Windows windows;
HWND hwnd = windows.CreateSimPleWindow();//ウインドウの作成
Graphics g;
g.Init( hwnd );//グラフィックの初期化
Input input;
Field field( g );
Scene *scene = new Title;
scene->Init( g );
while( DoEvents() ){
g.Clear();
input.Update(); //キーの更新
KeyboardState key = input.GetKeyboard(); //キーの情報を取得
//キー入力でプレイ画面に行く
if( no == 0 ){ //タイトル画面
if( key.Just( Key::A ) ){
delete scene;
no = 1;//プレイ画面に移動
scene = new Field( g );
scene->Init( g );
}
scene->KeyUpdate();
scene->Update( );
scene->Draw( g );
}
//プレイ画面
if( no == 1 ){
field.KeyUpdate( &field, key );//問題の部分です
field.Update( );
field.Draw( g );
}
g.Update();
}
scene->Release();
g.Release();
}
//Field.cpp
//KeyUpdateではキー入力の処理をしています
//block.Turn関数でfieldのポインタを渡したいので引数で渡しています
void Field::KeyUpdate( Field *field,KeyboardState &key){
//キーの入力にやる操作
//省略
if( key.Just( Key::A ) ){
block.Turn( *field );
}
if( key.Just( Key::S ) ){
block.Turn( *field );
}
}
//Block.cpp
//TurnではfieldのGet()関数を使いたいので、参照で渡し
//Getが真なら処理を実行させる形です
void Block::Turn(Field &field){
//省略
//回転できるかどうか調べる
//ブロックがすでに合ったらフラグを立てる
//もしくはフィールド外なら回転しない
for(int i = 0;i < 4; i ++ ){
for(int j = 0;j < 4; j ++ ){
if( field.Get( pos.x + j, pos.y + i ) ){
//省略
}
if( pos.x + j < 0 || pos.x + j >= Field_X ){
//省略
}
}
}
}
今まで見せていただいたコードでは、どういう所で継承を使いたいのかイマイチ掴めておりません。シーン分けについてですが
継承を学んだので継承でシーン分けを考えていたのですが、
プレイ画面で引数が変わる場合継承ができなくて困っています。
その場合は共通に
しなければなりませんか?
なにかいい方法があれば教えてくださいお願いします。
シーン分け継承がどの様な形でつなげるつもりなのか、こちらに伝わらないって感じです。
意図している継承とは、どんな事でしょうか?
現状のfieldクラス自体の定義も見せてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: シーン分け 継承について
それらは、オリジナルかどこかのサイトが提供しているライブラリのクラスの名前ではないでしょうか?
どこらへんが釣られているのか説明をお願いします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: シーン分け 継承について
度々申し訳ありません
GraphicsとWindowsの型はオリジナルで自分で作りました。
GraphicsはDirect3Dの初期化と解放をクラスにしました。
Windowsも同様でWindowsの初期化を行っています。
Textureもオリジナルで、ddsの読み込みと解放をしています。
Inputはキーボードの状態を初期化と更新を行っています。
Main関数で行われているのはDoEventも自作関数でメッセージが呼ばれたら終了させる処理を作っています。
できる限りKeyUpdateは引数を変えない方向でお願いしたいのですが無理でしょうか?
できないなら、別の方法を考えいたします。何度も申し訳ありません。
お願いします。
GraphicsとWindowsの型はオリジナルで自分で作りました。
GraphicsはDirect3Dの初期化と解放をクラスにしました。
Windowsも同様でWindowsの初期化を行っています。
Textureもオリジナルで、ddsの読み込みと解放をしています。
Inputはキーボードの状態を初期化と更新を行っています。
Main関数で行われているのはDoEventも自作関数でメッセージが呼ばれたら終了させる処理を作っています。
できる限りKeyUpdateは引数を変えない方向でお願いしたいのですが無理でしょうか?
できないなら、別の方法を考えいたします。何度も申し訳ありません。
お願いします。
Scene.h
class Scene{
public:
virtual void Init(Graphics &g){}
virtual void KeyUpdate(){}
virtual void Update(){}
virtual void Draw(Graphics &g){ }
virtual void Release( ){}
public:
int scene;
};
Field.h
class Field:public Scene{
public:
//初期化の処理
Field(Graphics &g):
block( g ),
field( Field_X * Field_Y, 0 )
{
next.texture = next.CreateTexture( g, "Next.bmp" );
texture.texture = texture.CreateTexture( g, "bg.bmp");
}
void Init( Graphics &g ){ }
void KeyUpdate( Field *field,KeyboardState &key);
void Update();
//フィールド外に出ないように制御させる
//一番左から一番右までの制御させる
//座標 + 移動量がフィールド外なら移動量を0にする
void Chaeck(Block *block );
//一番したまで来たらそこにブロックを設定する
//移動量がフィールド外に出たら当たっている事を調べる
//当たっていたらTrue を返し当たっていなかったらfalse
bool FirstLower(Block *block);
//座標Y
bool CheckHitY(Block *block );
void CheckHitX(Block *block);
//ブロックを設定する
//もしブロックもしくはフィールドの一番したなら現在の座標に設定させ、初期値に戻す
void BlockSet(Block *block );
//ブロックを消す処理
//一列がうまっているかどうかを数えて、すべて埋まっていたらその列を消去する
//消去したら消したブロックの上からすべておろす
void Delete();
void FieldDown(int y );
int Get( int x,int y ){
return field[ x + y * Field_X ];
}
void Set(int x, int y){
field[ x + y * Field_X ] = 1;
}
void Draw(Graphics &g);
void Release(){
next.Release();
texture.Release();
}
public:
Texture next;
Texture texture;
Block block;
std::vector< int >field;
};
main.cpp
class Title:public Scene {
public:
void Init(Graphics &g){
D3DXCreateTextureFromFile( g.device, "title.bmp", &texture.texture );
}
void Update(){
}
void Draw( Graphics &g ){
if( g.Begin() ){
g.DrawSprite( texture, Point( 0, 0), Rect( 0, 0, 720, 480 ), Color( 0xff, 0xff, 0xff ) );
g.End();
}
}
void Release(){
texture.Release();
}
public:
Texture texture;
};
int no = 0;
int main(){
Windows windows;
HWND hwnd = windows.CreateSimPleWindow();
Graphics g;
g.Init( hwnd );
Input input;
Field field( g );
Scene *scene = new Title;
scene->Init( g );
while( DoEvents() ){
g.Clear();
input.Update(); //キーの更新
KeyboardState key = input.GetKeyboard(); //キーの情報を取得
//キー入力でプレイ画面に行く
if( no == 0 ){ //タイトル画面
if( key.Just( Key::A ) ){
delete scene;
no = 1;
scene = new Field( g );
scene->Init( g );
}
scene->Update( );
scene->Draw( g );
}
//プレイ画面
if( no == 1 ){
field.KeyUpdate( &field, key );
field.Update( );
field.Draw( g );
}
g.Update();
}
scene->Release();
g.Release();
}
bool DoEvents()
{
MSG msg;
for(;;)
{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
if( msg.message == WM_QUIT )return false;
TranslateMessage( &msg );
DispatchMessage( &msg ); //ウィンドウプロシージャの呼び出し
}
else
{
return true;
}
}
return false;
}
Re: シーン分け 継承について
何もしない処理を追加して共通化するのはどうでしょうか?
下のようなコードになります
下のようなコードになります
#include <stdio.h>
class Title : public Scene {
public:
...
...
void KeyUpdate( Field *field,KeyboardState &key);
...
...
};
void Title::KeyUpdate( Field *field,KeyboardState &key)
{
// 何もしない
}
...
...
if( no == 0 ){
if( key.Just( Key::A ){
delete scene;
no = 1;
scene = new Field( g );
scene->Init( g );
}
scene->KeyUpdate( &field, key ); // 上の何もしない関数を追加
scene->Update();
scene->Draw( g );
}
// プレイ画面
if( no == 1 ){
field.KeyUpdate( &field, key );
field.Update( );
field.Draw( g );
}
g.Update();
Re: シーン分け 継承について
不思議さんは側溝にでも捨てておいて。
一口にシーン遷移といってもその実装の仕方は大量にあります。
一例として、自分の考えた実装を書いておきます。
せっかく継承を使うんですから変数noなんて使わないで下さいな。
それと、上のコードはコンパイルしてないのでかなり怪しいです。あくまでも参考程度にして下さい。
シーン遷移の実装に正解はないので自分の良いと思う実装を模索してみて下さい。
一口にシーン遷移といってもその実装の仕方は大量にあります。
一例として、自分の考えた実装を書いておきます。
// 全てシーンの基底クラス
class Scene
{
public:
Scene(){}
virtual ~Scene()
{
/*ゲーム全体の終了処理*/
}
virtual Scene* Update() = 0;
virtual void Draw() = 0;
private:
// 全てのシーンで使うリソース
static Window window;
static Graphic g;
static Input input;
};
// ゲームを初期化するシーン
class Init : public Scene
{
public:
Init()
{
/*ゲーム全体の初期化処理*/
}
Scene* Update()
{
return new Title(); // 初期化が終わったらタイトルへ
}
}
// タイトルのシーン
class Title : public Scene
{
public:
Title(){}
~Title(){}
Scene* Update()
{
input.update();
if( /*何か押した*/ ) return new Game(); // 何か押したらゲームへ
return this;
}
void Draw(){}
};
// ゲーム?のシーン
class Field : public Scene
{
public:
Field(){}
~Field(){}
void get(){}
Scene* Update()
{
input.update();
if( /*何か押した*/ ) block.turn( this );
return this;
}
void Draw(){}
private:
// ここでしか使わないリソース
Block block;
};
int main()
{
std::unique_ptr<Scene> scene( new Scene() );
while( /*ゲームが終わるまで*/ )
{
Scene* next( scene.update() );
scene.draw();
// ポインタが異なっていたら(違うシーンに移っていたら)シーンを更新する
if( next != scene.get() ) scene.reset( next );
}
}
それと、上のコードはコンパイルしてないのでかなり怪しいです。あくまでも参考程度にして下さい。
シーン遷移の実装に正解はないので自分の良いと思う実装を模索してみて下さい。