ページ 11

文字表示についての質問

Posted: 2008年9月07日(日) 05:04
by
このサイトの掲示板への初投稿です。よろしくお願いします。
今年大学に入り、C言語を学び始めました。わからないことだらけでC言語について調べていたところ、こちらのサイトにたどり着きました。こちらのサイトで学んでゲームが作れたらと思っています。
本題は、「ゲームプログラミングの館」の、~入門編~の、6.文字を表示する、についての質問です。

「どこがわからないのか」…文字を表示することはできたのですが、文字を消す方法が分からず、文字を消すことができなくて困っています。

「自分はどこまでやったのか」…白で文字を表示していたので、同じ座標に背景と同じ色で同じ文字を表示しようとしましたがエラーになってしまいました。

「結局何が行いたいのか」…行いたいことは、まず文字を表示して、ENTERを押したらその文字を消すという処理です。

「自分のC言語の知識はどの程度なのか」…この春から学び始めたばかりで果てしなく初心者です。


長文失礼しました。基本的なことだとは自覚してはいますが、そこから学ばないといけないレベルなのでどうか返信よろしくお願いします。

Re:文字表示についての質問

Posted: 2008年9月07日(日) 07:03
by J
この質問には私からは答えることはしません。
ただ、第13章まで進んでみてください。
きっと私が教えるより、理解できるでしょう。
私が言えるのはこれだけです。

Re:文字表示についての質問

Posted: 2008年9月07日(日) 12:05
by 木霊
>背景と同じ色で同じ文字を表示

「背景と同じ色」というのはどのように色を指定しましたか?
出たというエラーの内容が分からないのですが、宣言していない変数を使ったのではないですか?

>行いたいことは、まず文字を表示して、ENTERを押したらその文字を消すという処理です。

ということですが、ENTERを押されるまでは文字を表示して、押されたら文字を表示しない、と置き換えてもいいですか?
それとも、ENTERを押された後は 背景と同じ色で文字を上書きして見た目だけ消えたように見せるのですか?
後者の方法だと、背景が単色でなければ使えません。

なので前者の方法で進めていきます。

ENTERがまだ押されてなければ「文字を表示する処理」をする、押されていたら「文字を表示する処理」をしない。
このように条件によって違うことがしたい(したくない)場合にはif文を使います。

if ( /*ENTERがまだ押されていない*/ ) { /*文字を表示する*/ }

if文の()の中が真、つまり条件が満たされているか0以外の値であれば{}内の処理がされます。
そしてENTERが押される前か後かを判別する方法ですが、後で第19章と第22章を読んでください。
ここでは簡単に説明します。
ENTERが押されたかどうかの「フラグ」を用意して、ENTERが一度でも押されたら0、まだ押されてなければ1と
仮に決めておいて、フラグが1ならば文字を表示する処理を行う({}内の処理を行う)ようにif文の()の中身を
書いてあげます。等号は「==」です。「=」一つだけだと代入になるので気を付けてください。
キーの入力については第10章がそのまま使えますのでここであえて説明する必要も無いでしょう。
では頑張ってください。

Re:文字表示についての質問

Posted: 2008年9月07日(日) 12:15
by 管理人
規約をよくお読みになって丁寧に質問してくださりありがとうございますm(_ _)m
Jさんの仰るとおり、13章までやってみて下さい。

先に回答すると
ClearDrawScreen();
という関数を呼べば、画面に描いてある内容は消えます。
しかしこれだけでは色んな弊害が出てくるはずです。
まぁとにかく13章まで先に読んでもらったほうが良いと思います。

ただ

>同じ座標に背景と同じ色で同じ文字を表示しようとしましたがエラーになってしまいました。

エラーというのはコンパイル出来ないということですか?
同じ座標に背景と同じ色で描画する事は出来ます。
黒はGetColor(0,0,0)で取得出来ますから、この色で書けばエラーにはなりません。
もしそれでもエラーになるときは、ソースコードを投稿してもらったらはっきりするかもしれません。

Re:文字表示についての質問

Posted: 2008年9月07日(日) 15:36
by
Jさん、木霊さん、管理人さん質問への早いご回答ありがとうございます。
Jさんと管理人さんが仰っているように13章まで進んでみようと思います。それでもわからない場合は改めて質問させていただこうかと思います。
できれば木霊さんの仰っている19章と20章にも、頭が混乱しない程度に先に目を通してみます。
最後にもう1度、回答ありがとうございました。

Re:文字表示についての質問

Posted: 2008年9月07日(日) 18:42
by
とりあえず現状を報告いたします。
13章までを読み、管理人さんの言うとおりに同じ場所に背景と同じ色で文字を表示することができることを確認しました。
どうやら昨日は寝ぼけていたのか失敗していたようです。申し訳ありませんでした。
次は文字に色を重ねるのではなく、文字を消すということに挑戦してみたいと思います。

Re:文字表示についての質問

Posted: 2008年9月07日(日) 19:25
by
連続投稿になりますが文字を消す簡単なプログラムを書いてみました。起動も試して成功したのですが、直すべき点がございましたら、ご指導お願いします。↓がプログラムになります。なおプログラムの元はこのサイトの6章と13章を引用させていただきました。ありがとうございます。

#include "DxLib.h"

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
        ChangeWindowMode( TRUE ) ;   
        if( DxLib_Init() == -1 ) return -1; 
 

        int White,Black ;
        White = GetColor( 255 , 255 , 255 ) ;

        while( CheckHitKey( KEY_INPUT_Z ) == 0 ){
			DrawString(  200, 150 , "zを押すと文字を消します。" , White ); 
				if( ProcessMessage() == -1 )
                         break ;       
        }
		ClearDrawScreen();            
		while( CheckHitKey( KEY_INPUT_RETURN ) == 0 ){	
			DrawString( 200 , 250 , "ENTERキーを押すと終了します。" , White ); 
			if( ProcessMessage() == -1 )
                         break ;        
        }


        DxLib_End() ;           
        return 0 ;             
}
ご指導お待ちしています。

Re:文字表示についての質問

Posted: 2008年9月07日(日) 19:32
by 管理人
「文字を消す」のではなく、「文字を書かない」という考えの方が正しいと思います。

このループのアルゴリズムは

while(){
    メッセージ処理;
    画面消去;
    描画;
    描画反映;
}

となっていますから、毎回描画したものだけこちらに見えるわけですので、
書かなければ(処理しなければ)描画されないわけです。

36章のプログラム

http://dixq.net/g/#36

に赤字の部分を追加したプログラムがこちらです。

#include "DxLib.h"

char Key[256];

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
    ChangeWindowMode(TRUE);//ウィンドウモード
    if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化

    while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
          //↑メッセージ処理          ↑画面をクリア           ↑入力状態を保存       ↑ESCが押されていない

        if(Key[KEY_INPUT_Z]==1)
            DrawString(0,0,"Zキーが押されていますよ。",GetColor(255,255,255));

        ScreenFlip();
    }

    DxLib_End();
    return 0;
}

このプログラムがわかれば「消す」ではなく「描画しない」ことによって
真っ暗になるのが解ると思います。

また13章以降は一部を除いて順番が特にないので、どの章から読んでいただいても大丈夫です。
(まぁ順番に読んでもらった方が良いとは思います)

Re:文字表示についての質問

Posted: 2008年9月07日(日) 19:57
by 管理人
先ほどの投稿はNo:21002の投稿された記事を見ずに投稿しました。

投稿されたプログラムについての回答は以下に書きますのでご覧下さい。

まず、ゲームを作るときは裏画面処理が必須になってくるので、
13章以前のプログラムコードは忘れて下さい。

41章に、毎回必ず書くべきコードをかいています。

http://dixq.net/g/#41

これからプログラムを書くときは毎回これをコピペして、

//ココ

と書かれている部分を消してその部分に処理を書いていってください。

while(継続条件){
    //処理
}

を連続して書いていく方法では、もし似たような処理を10個行いたくなったらどうしましょう?

while(継続条件){
    //処理
}

while(継続条件){
    //処理
}

while(継続条件){
    //処理
}

while(継続条件){
    //処理
}

while(継続条件){
    //処理
}

while(継続条件){
    //処理
}

while(継続条件){
    //処理
}

while(継続条件){
    //処理
}

while(継続条件){
    //処理
}

while(継続条件){
    //処理
}

と書いていくのは大変です。しかし
私が上に提示したプログラムを拡張して
A~Iキーが入力されたらそのキーが入力中だと表示するプログラムをこのようにかくと

#include "DxLib.h"

char Key[256];

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
    ChangeWindowMode(TRUE);//ウィンドウモード
    if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化

    while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
          //↑メッセージ処理          ↑画面をクリア           ↑入力状態を保存       ↑ESCが押されていない

        if(Key[KEY_INPUT_A]==1) DrawString(0,0,"Aキーが押されていますよ。",GetColor(255,255,255));
        if(Key[KEY_INPUT_B]==1) DrawString(0,0,"Bキーが押されていますよ。",GetColor(255,255,255));
        if(Key[KEY_INPUT_C]==1) DrawString(0,0,"Cキーが押されていますよ。",GetColor(255,255,255));
        if(Key[KEY_INPUT_D]==1) DrawString(0,0,"Dキーが押されていますよ。",GetColor(255,255,255));
        if(Key[KEY_INPUT_E]==1) DrawString(0,0,"Eキーが押されていますよ。",GetColor(255,255,255));
        if(Key[KEY_INPUT_F]==1) DrawString(0,0,"Fキーが押されていますよ。",GetColor(255,255,255));
        if(Key[KEY_INPUT_G]==1) DrawString(0,0,"Gキーが押されていますよ。",GetColor(255,255,255));
        if(Key[KEY_INPUT_H]==1) DrawString(0,0,"Hキーが押されていますよ。",GetColor(255,255,255));
        if(Key[KEY_INPUT_I]==1) DrawString(0,0,"Iキーが押されていますよ。",GetColor(255,255,255));

        ScreenFlip();
    }

    DxLib_End();
    return 0;
}

似たような重複した記述が少なく、効率的ですよね。
このように、

ループの中の

while(){
    ProcessMessage();
    ClearDrawScreen();
    //ココ
    ScreenFlip();
}

「//ココ」に処理を追加していく書き方がよいでしょう。
 

Re:文字表示についての質問

Posted: 2008年9月07日(日) 22:06
by
ご評価ありがとうございます。私はまだ先に進んでいないので意味が10分の1も理解できていないと思いますが、効率的にプログラムを書く方法をわかりやすく教えてくださったんだと思います。今回の「文字を書かない」というプログラムについては解決できたと感じているので解決のマークを表示させていただきます。Jさん、木霊さん、管理人さん、本当にありがとうございました。この先ゲームを作っていく上でいろんな問題が発生すると思いますが、その時もこの掲示板を利用させてください。また、その時はよろしくお願いします。