新C言語~ゲームプログラミングの館~のs.6章について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
bayashi
記事: 6
登録日時: 9年前
住所: 愛知県名古屋市

新C言語~ゲームプログラミングの館~のs.6章について

#1

投稿記事 by bayashi » 9年前

新C言語~ゲームプログラミングの館~のs.6章「 Android3.0の背景みたいなエフェクトの作り方 」http://dixq.net/g/s_06.html
こちらのサイトを参考に、同じようなプログラムを書いて実行してみたのですが、エラーが出てしまいます。
開発環境はMicrosoft Visual C++ 2010、OSは Windows8.1 です。

関係のありそうなところを抜粋します。
<ソースコード>

コード:


#include"DxLib.h"
#define PI 3.141592654


 int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

・
・
・

  int Handle02 = LoadGraph("画像/エフェクト/メニュー背景.png");
    int Handle_effect_light = LoadGraph("画像/menu_back_over.png");
      int Mask_menu = LoadMask("画像/menu_back_mask.png");
      int effect_count = 0;

・
・
・

     while(ScreenFlip()==0&&ProcessMessage()==0&&ClearDrawScreen()==0){ 

            effect_count ++;
                 if(effect_count == 360)
                         effect_count = 0; 

                   CreateMaskScreen();
                   DrawMask(0 , 0 , Mask_menu , DX_MASKTRANS_BLACK);
                   SetDrawBlendMode(DX_BLENDMODE_ADD , 255);
                   DrawRotaGraph2(320 , 240 , 370 , 370 , 1.0 , PI*2.0/240.0 * (float)effect_count , Handle_effect_light , TRUE);
                   DrawRotaGraph2(320 , 240 , 370 , 370 , 1.0 , PI*2.0/240.0 * (float)(effect_count-120) , Handle_effect_light , TRUE);
                   SetDrawBlendMode(DX_BLENDMODE_NOBLEND , 0);
                   DeleteMaskScreen();

・
・
・

<エラー内容>
「GameProg renshuu.exe の 0x69dfbfae でハンドルされていない例外が発生しました: 0xC0000005: 場所 0x6e0b4c90 を読み込み中にアクセス違反が発生しました。」と表示されます。
エラーの発生タイミングについては不確定で、開始直後に発生する場合と、開始してから数秒後に発生する場合があります。条件についてはよくわかりません・・・
ちなみに、DrawRotaGraph2を両方コメントアウトすることで発生しなくなりました。片方だけだと発生しました。
またメッセージボックスの「中断」を押すと、添付ファイルに有る画面が表示されます。

このエラーの原因と思われるもの、また解決方法を教えてください。
(説明もいまいちなので分かり辛いかとは思いますが、お願いいたします<m(__)m> )

(C言語の知識についてですが、あまり有りません。
DxLibの導入もゲームプログラミングの館を見て行いましたので、自力でプロパティをいじったりするのは難しいです(-_-;)。)
添付ファイル
スクリーンショット (1).png

zxc
記事: 79
登録日時: 11年前
住所: 日本の背骨(?)あたり

Re: 新C言語~ゲームプログラミングの館~のs.6章について

#2

投稿記事 by zxc » 9年前

  配列などで範囲外アクセスなどはありませんか?
 
  適当に試してみましたが、マスク関係の関数や描画関係の関数自体の問題ではなさそうな気がします。
添付ファイル
test_mask.zip
(1.31 MiB) ダウンロード数: 101 回

bayashi
記事: 6
登録日時: 9年前
住所: 愛知県名古屋市

Re: 新C言語~ゲームプログラミングの館~のs.6章について

#3

投稿記事 by bayashi » 9年前

わざわざプログラムまで作ってくださってありがとうございますm(__)m
配列についてですが...
この関数内で使っている配列は、キーの入力を管理するための配列のみです(グローバル変数)
またその配列を弄るプログラムは以前からずっとそのままなので、おそらく関係はないと思います。
たくさん配列を作っているとなるとゲーム本体の方なのですが(ちなみに上のプログラムはメニュー画面のところです)、そちらも問題なく動作します。
あるいはメモリが足りていなくて、ゲーム本体の方がこちらのプログラムに影響しているということも有り得るのでしょうか?

zxc
記事: 79
登録日時: 11年前
住所: 日本の背骨(?)あたり

Re: 新C言語~ゲームプログラミングの館~のs.6章について

#4

投稿記事 by zxc » 9年前

コード:

while(・・・・・・・・・){
                   CreateMaskScreen();
・・・・・
                   DeleteMaskScreen();
}
  大部分のゲーム本体で使う変数やインスタンスを生成するのが、メニュー画面より前かメニュー画面で行われるならもしかしたら支障があるかもしれませんが、基本的には問題ないと思います。

  配列やポインタの範囲外アクセスではないとしたら、もしかしたら上のCreateMaskScreen関数とDeleteMaskScreen関数をここ(ループの中)に置いたことが何か良くないのかもしれません。


  リファレンスのサンプルコードのいくつかやCreateMaskScreen関数、SetUseMaskScreenFlag関数等の説明を見る限り、下のようなことを満たすべきであるようです。
  1. CreateMaskScreen関数とDeleteMaskScreen関数は短時間のうちに何度も呼ぶと負荷が大きいので、ループ内では呼ばれていない。マスク画面の有効/無効はSetUseMaskScreenFlag関数で切り替える。
  2. LoadMask関数よりも先にCreateMaskScreen関数が呼ばれている。
  ただこれらを不適切にしたところで、DrawRotaGraph2関数で不具合が出ることは、あまりなさそうな気がするので、原因は別にあると思います。
  

  コードを見る限り、DrawRotaGraph2関数でアクセス違反はあまり起こらないように見えます。
DrawRotaGraph2を両方コメントアウトすることで発生しなくなりました。
  これは何回試行されましたか?仮にDrawRotaGraph2関数が原因らしいなら、そこ以外ではエラーやAssertにならないもっと小規模のコードで再現できますか?
  
  

bayashi
記事: 6
登録日時: 9年前
住所: 愛知県名古屋市

Re: 新C言語~ゲームプログラミングの館~のs.6章について

#5

投稿記事 by bayashi » 9年前

CreateMaskScreenについてですが、呼び出すタイミングを変えてみました。

コード:


#include"DxLib.h"
#define PI 3.141592654
 
 
 int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
 
・
・
・
      
      CreateMaskScreen();

  int Handle02 = LoadGraph("画像/エフェクト/メニュー背景.png");
    int Handle_effect_light = LoadGraph("画像/menu_back_over.png");
      int Mask_menu = LoadMask("画像/menu_back_mask.png");
      int effect_count = 0;
 
・
・
・
 
     while(ScreenFlip()==0&&ProcessMessage()==0&&ClearDrawScreen()==0){ 
 
            effect_count ++;
                 if(effect_count == 360)
                         effect_count = 0; 
 
                   SetUseMaskScreenFlag(true);                   

                   DrawMask(0 , 0 , Mask_menu , DX_MASKTRANS_BLACK);
                   SetDrawBlendMode(DX_BLENDMODE_ADD , 255);
                   DrawRotaGraph2(320 , 240 , 370 , 370 , 1.0 , PI*2.0/240.0 * (float)effect_count , Handle_effect_light , TRUE);
                   DrawRotaGraph2(320 , 240 , 370 , 370 , 1.0 , PI*2.0/240.0 * (float)(effect_count-120) , Handle_effect_light , TRUE);
                   SetDrawBlendMode(DX_BLENDMODE_NOBLEND , 0);
    
                   SetUseMaskScreenFlag(false);

                   if( Key[KEY_INPUT_RETURN] == 1 ){
                            
                            DeleteMaskScreen();
                            Game();    //ゲーム本体
                            CreateMaskScreen();                              

                         }
                 
 
・
・
・

このように書き換えたところ、今度はDrawMaskのところでエラーが出るようになりました。
開始数秒後に発生するというパターンはなく、すべて開始直後に発生します。
もしくは、crt0.cというのが出てきて、下記の場所で止まります。

コード:



int
_tmainCRTStartup(
        void
        )
{
        /*
         * The /GS security cookie must be initialized before any exception
         * handling targetting the current image is registered.  No function
         * using exception handling can be called in the current image until
         * after __security_init_cookie has been called.
         */
        __security_init_cookie();

        return __tmainCRTStartup();
}    // ←ここで止まります


CreateMaskScreen関数の位置を変える前でも、出てくることがありました


DrawRotaGraph2の方ですが・・・
数十回試行しました。
一度VCを再起動してやってみたりしましたが、結局変わりありませんでした。

また、s.6章のプログラムをDLして実行したり、プロジェクトを新規作成してコピペしたりしてみても同様のエラーが出ました。

zxc
記事: 79
登録日時: 11年前
住所: 日本の背骨(?)あたり

Re: 新C言語~ゲームプログラミングの館~のs.6章について

#6

投稿記事 by zxc » 9年前

  お使いになっているDXライブラリは最新のものでしょうか?もしかしたらこういうことか、それに似た状況なのかもしれません。

bayashi
記事: 6
登録日時: 9年前
住所: 愛知県名古屋市

Re: 新C言語~ゲームプログラミングの館~のs.6章について

#7

投稿記事 by bayashi » 9年前

お忙しい中ありがとうございます。
一度DxLibのホームページから最新版をDLしてみましたが、変わらずエラーが発生しました。
ちなみに使用しているマスク画像は、画面サイズと同じ640*480です。

bayashi
記事: 6
登録日時: 9年前
住所: 愛知県名古屋市

Re: 新C言語~ゲームプログラミングの館~のs.6章について

#8

投稿記事 by bayashi » 9年前

Dxlibリファレンスページのサンプルプログラムを実行してみました。

コード:

#include "DxLib.h"

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
            LPSTR lpCmdLine, int nCmdShow )
{
    int MaskHandle ;

    if( DxLib_Init() == -1 )    // DXライブラリ初期化処理
    {
         return -1;    // エラーが起きたら直ちに終了
    }

    // マスク画面を作成します
    CreateMaskScreen() ;

    // マスクデータをロードします
    MaskHandle = LoadMask( "img/menu_back_mask.png" ) ;

    // ロードしたマスクデータを画面の左上に描画します
    DrawMask( 0 , 0 , MaskHandle , DX_MASKTRANS_NONE ) ;

    // 画面いっぱいに赤い四角を描きます
    DrawBox( 0 , 0 , 640 , 480 , GetColor( 255 , 0 , 0 ) , TRUE ) ;

    // キーの入力待ちをします
    WaitKey() ;

    // マスク画面を削除します
    DeleteMaskScreen() ;

    DxLib_End() ;        // DXライブラリ使用の終了処理

    return 0 ;        // ソフトの終了
}


実行結果ですが…
何もいじらない状態だと成功しました。
次に、DrawBoxを  while((GetMouseInput()&MOUSE_INPUT_LEFT) !=0)
で囲んでみました。すると今度は、画面に何も表示されませんでした。
こちらも何かの参考になるでしょうか・・・?(-_-;)

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

Re: 新C言語~ゲームプログラミングの館~のs.6章について

#9

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

WaitKey()やScreenFlip()しないと画面には何も表示されません。
そういう意味では正しく表示されていない状態なのではないでしょうか。
意図とは違うとは思いますが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

zxc
記事: 79
登録日時: 11年前
住所: 日本の背骨(?)あたり

Re: 新C言語~ゲームプログラミングの館~のs.6章について

#10

投稿記事 by zxc » 9年前

  crt0.cはここ見る限り範囲外アクセス等が原因みたいですが、DrawMaskのエラーについては正しい使い方をしていない等、別の原因の可能性もないとは言えないと思います。ちょっとこちらでは出ないエラーですので何ともいえません。

コード:

while((GetMouseInput()&MOUSE_INPUT_LEFT) !=0) 

コード:

while( ( GetMouseInput() && MOUSE_INPUT_LEFT ) !=0 )
とかになるんですかね。私が知らないだけでちゃん意図通り動くのかもしれませんけども。

それにsoftya(ソフト屋)さんの言うとおり描写関係関数群も入れないといけませんね。

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

Re: 新C言語~ゲームプログラミングの館~のs.6章について

#11

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

回答する側も想像でしか答えられず、bayashi さんのやったことが正確に伝わっていない可能性が大きいです。
こういう場合、そのままコピペで動く問題点を含んだミニマムなソースコードをbayashi さんから提示してもらうのが速道です。

【大事なこと】
while(ScreenFlip()==0&&ProcessMessage()==0&&ClearDrawScreen()==0){
の無いループを作ると表示も制御も正常には動きません。
なので通常は作っては行けません。

これです ↓
while((GetMouseInput()&MOUSE_INPUT_LEFT) !=0)

プログラム中に
while(ScreenFlip()==0&&ProcessMessage()==0&&ClearDrawScreen()==0){
がいっぱいあるのも動作の制御に失敗する可能性が高いので、これもやってはいけません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

bayashi
記事: 6
登録日時: 9年前
住所: 愛知県名古屋市

Re: 新C言語~ゲームプログラミングの館~のs.6章について

#12

投稿記事 by bayashi » 9年前

お二方とも、ご返答ありがとうございます。
while文についてですが、描画先を裏画面に設定し、
while(ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && (GetMouseInput()&MOUSE_INPUT_LEFT) !=0) というように変更しましたが、やはり何も表示されません。
そこで試しにwhile文の後ろに DrawBoxを加えてみたところ、今度は表示されました。
つまりはどれかの処理で -1 が返ってきて、while文を抜けてしまっているんですかね?
まぁ参考になるかと思って試したことですので、ならなさそうであればスルーしてもらって大丈夫です。

>>ソフト屋さん

エラーの内容についてですが、s.6章のサンプルプログラムを実行したときも同じエラーが発生しました。
僕が改善したいプログラムはほとんどこれと同じ作りで、他に配列の範囲外アクセスなども見つかりませんでした。
僕自身エラーの原因が全く分からないので、要らないところがどこなのか・・・(-_-;)
いっそのことプロジェクトファイルをそのままうpした方がいいですかね?


あと、もう少し原因を検証しました。ほんと少しですが。。。(一番最初に貼った、自分のプログラムです)
マスク関係の処理(CreateMaskScreen , DrawMask等)をすべてコメントアウトしたら、エラーは発生しませんでした。
DrawMaskのみをコメントアウトしたところ、「利用可能なソースがありません」と出ました(最初に貼った画像の通りです)。

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

Re: 新C言語~ゲームプログラミングの館~のs.6章について

#13

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

そのまま問題が再現するコードを貼ってもらうのが良いと思います。
※なるべくコンパクト化して。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

“C言語何でも質問掲示板” へ戻る