ウィンドウの点滅

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
chalaza

ウィンドウの点滅

#1

投稿記事 by chalaza » 14年前

プログラミング講座http://www.nhk.or.tv/kow/program/index.php
のテトリスの部分を一通んでみたので、参考にさせてもらい、というかほとんど同じように
テトリスのプログラムを組み立ててみました。GameMainという関数にすべての処理をまとめて、それだけをWinMainで
ループするよう組み立てたのですが、
実行してみるとゲームや何やらの前に、Windows\system32\cmd.exeというウィンドウが点滅して何も始まりません。
ゲーム以前の問題なのですが、参考にしたサイトが『APIを使わない』と書いてあったので
参考の仕方が間違っていたのかもしれません。

コード:

#include "DxLib.h"
#include <stdio.h>
#include <stdlib.h>

int Key[256];
 
int GetHitKeyStateAll_2(int GetHitKeyStateAll_InputKey[]){
    char GetHitKeyStateAll_Key[256];
    GetHitKeyStateAll( GetHitKeyStateAll_Key );
    for(int i=0;i<256;i++){
        if(GetHitKeyStateAll_Key[i]==1) GetHitKeyStateAll_InputKey[i]++;
        else                            GetHitKeyStateAll_InputKey[i]=0;
    }
    return 0;
}
 

 
int MAP[21][12] = {0};

int Block[4][4] = {{0,0,0,0},
			  	   {0,1,1,0},
				   {0,1,1,0},
				   {0,0,0,0}};

int field[21][12] = {0};

//グローバル変数
int X=120, Y=0;
int time=0;
int gameover = 0; 

//関数
void Initialize();
int CreateBlock();
void ShowGameField();
void MoveBlock(int, int);
int CheckOverlap(int, int);
void LockBlock();

//ブロック画像ロード
	int block[8] = {
	LoadGraph( "image/block1.png" ),//ブロック1~7+壁
	LoadGraph( "image/block2.png" ),
	LoadGraph( "image/block3.png" ),
	LoadGraph( "image/block4.png" ),
	LoadGraph( "image/block5.png" ),
	LoadGraph( "image/block6.png" ),
	LoadGraph( "image/block7.png" ),
	LoadGraph( "image/block0.png" )};

//メインゲーム
int GameMain(){
	int GetJoypadInputState( int InputType ) ;

	time=0;//タイムの初期化

	Initialize(); //ステージの初期化

	while(!gameover) {//ゲームオーバーじゃない場合

		if(time<=60 && gameover==0 ){//タイムを加算
			time++;
		}else{
			//重なりがなければ移動
			if(!CheckOverlap(X, Y+1)) {
				MoveBlock(X, Y+1);
			}
			//重なりがあれば壁にする
			else{
				LockBlock();
				CreateBlock();
				ShowGameField();
			}
			time=0;	//1秒ごとにタイムループ
		}
	}
	return 0;
}

void Initialize()
{
	int i, j; //forループ制御用変数

	//画面と壁を初期設定
	for(i = 0; i <= 20; i++) {
		for(j = 0; j <= 11; j++) {
			if((j == 0) || (j == 11) || (i == 20)) {
				field[i][j] = MAP[i][j] = 9;
			}
			else {
				field[i][j] = MAP[i][j] = 0;
			}
		}
	}


CreateBlock();	//初期位置の設定
ShowGameField(); //ゲーム直後の画面を描画

}
int CreateBlock()
{
	X=120, Y=0;//ブロックの初期位置
	int i, j;
	for(i = 0; i<4; i++) {
		for(j = 0; j<4; j++) {
			field[i][j+4] = MAP[i][j+4] + Block[i][j];

			//初期位置に固定ブロックがあったらゲームオーバー
			if(field[i][j+4] > 1) {
				gameover = 1;
				return 1;
			}
		}
	}
	return 0;
}

//画面表示
void ShowGameField()
{

	//画面を一旦クリア
	system("cls");

	//マップ描画
	for(int y=0;y<21;y++){ 
		for(int x=0;x<12;x++){ 
			if(MAP[y][x] != 0){
				DrawGraph( x*20, y*20, block[MAP[y][x]-1], TRUE );
				DrawGraph( x*20, y*20, block[Block[y][x]-1], TRUE );
			}
		}
	}
	
	if(gameover){		//ゲームオーバー処理
	}

}

void MoveBlock(int x2, int y2)
{
	int i, j; //forループ制御用変数

	//今までのブロックを消して
	for(i = 0; i<4; i++) {
		for(j = 0; j<4; j++) {
			field[Y+i][X+j] -= Block[i][j];
		}
	}
	//ブロックの座標を更新
	X = x2;
	Y = y2;

	//新しい座標でブロックを入れなおす
	for(i = 0; i<4; i++) {
		for(j = 0; j<4; j++) {
			field[Y+i][X+j] += Block[i][j];
		}
	}
	ShowGameField();
}



int CheckOverlap(int x2, int y2)
{
	int i, j; //forループ制御用変数

	//ブロックが向かう位置に固定ブロックもしくは壁があるかどうかを検査
	for(i = 0; i<4; i++) {
		for(j = 0; j<4; j++) {
			if(Block[i][j]) {
				if(MAP[y2 + i][x2 + j] != 0) {
					return 1;
				}
			}
		}
	}
	return 0;
}

void LockBlock()
{
	int i, j; //forループ制御用変数

	//ブロックを壁に加える
	for(i = 0; i<21; i++) {
		for(j = 0; j<12; j++) {
			MAP[i][j] = field[i][j];
		}
	}
}


 
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ){
        SetMainWindowText("テトリス");
    ChangeWindowMode(TRUE);
    SetGraphMode(560,420,32);
    if( DxLib_Init() == -1 ) return -1;
    SetDrawScreen( DX_SCREEN_BACK );


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

		
 
        ScreenFlip();
    }
 
    DxLib_End();
    return 0;
}


non
記事: 1097
登録日時: 15年前

Re: ウィンドウの点滅

#2

投稿記事 by non » 14年前

WinMainの中に、DxLibのお決まりのループがあって、その中で呼び出されるGameMainには
初期化があり再び、whileがある。
中身は知らないけど、構造的におかしいでしょう。
GameMainをばらして、WinMainの中に各パーツを入れるように考え直した方がいいでしょう。
non

chalaza

Re: ウィンドウの点滅

#3

投稿記事 by chalaza » 14年前

言われてみればその通りでした…
とりあえずGameMainをWinMainに移して、初期化をループからはずしてみました。
ついでに点滅の原因と思う不要な画面クリアを消去したのですが、
そしたら今度はウィンドウは点滅しなくなったものの、応答なしになって終わってしまうようになってしまいました…
他にまだおかしいところがあるようなのですが…何か重要なところが間違っているのでしょうか

コード:

#include "DxLib.h"
#include <stdio.h>
#include <stdlib.h>

int Key[256];
 
int GetHitKeyStateAll_2(int GetHitKeyStateAll_InputKey[]){
    char GetHitKeyStateAll_Key[256];
    GetHitKeyStateAll( GetHitKeyStateAll_Key );
    for(int i=0;i<256;i++){
        if(GetHitKeyStateAll_Key[i]==1) GetHitKeyStateAll_InputKey[i]++;
        else                            GetHitKeyStateAll_InputKey[i]=0;
    }
    return 0;
}
 

 
int MAP[21][12] = {0};

int Block[4][4] = {{0,0,0,0},
			  	   {0,1,1,0},
				   {0,1,1,0},
				   {0,0,0,0}};

int field[21][12] = {0};

//グローバル変数
int X=120, Y=0;
int time=0;
int gameover = 0; 

//関数
void Initialize();
int CreateBlock();
void ShowGameField();
void MoveBlock(int, int);
int CheckOverlap(int, int);
void LockBlock();

//ブロック画像ロード
	int block[8] = {
	LoadGraph( "image/block1.png" ),//ブロック1~7+壁
	LoadGraph( "image/block2.png" ),
	LoadGraph( "image/block3.png" ),
	LoadGraph( "image/block4.png" ),
	LoadGraph( "image/block5.png" ),
	LoadGraph( "image/block6.png" ),
	LoadGraph( "image/block7.png" ),
	LoadGraph( "image/block0.png" )};



void Initialize()
{
	int i, j; //forループ制御用変数

	//画面と壁を初期設定
	for(i = 0; i <= 20; i++) {
		for(j = 0; j <= 11; j++) {
			if((j == 0) || (j == 11) || (i == 20)) {
				field[i][j] = MAP[i][j] = 8;
			}
			else {
				field[i][j] = MAP[i][j] = 0;
			}
		}
	}


CreateBlock();	//初期位置の設定
ShowGameField(); //ゲーム直後の画面を描画

}
int CreateBlock()
{
	X=120, Y=0;//ブロックの初期位置
	int i, j;
	for(i = 0; i<4; i++) {
		for(j = 0; j<4; j++) {
			field[i][j+4] = MAP[i][j+4] + Block[i][j];

			//初期位置に固定ブロックがあったらゲームオーバー
			if(field[i][j+4] > 1) {
				gameover = 1;
				return 1;
			}
		}
	}
	return 0;
}

//画面表示
void ShowGameField()
{

	//マップ描画
	for(int y=0;y<21;y++){ 
		for(int x=0;x<12;x++){ 
			if(MAP[y][x] != 0){
				DrawGraph( x*20, y*20, block[MAP[y][x]-1], TRUE );
				DrawGraph( x*20, y*20, block[Block[y][x]-1], TRUE );
			}
		}
	}
	
	if(gameover){		//ゲームオーバー処理
	}

}

void MoveBlock(int x2, int y2)
{
	int i, j; //forループ制御用変数

	//今までのブロックを消して
	for(i = 0; i<4; i++) {
		for(j = 0; j<4; j++) {
			field[Y+i][X+j] -= Block[i][j];
		}
	}
	//ブロックの座標を更新
	X = x2;
	Y = y2;

	//新しい座標でブロックを入れなおす
	for(i = 0; i<4; i++) {
		for(j = 0; j<4; j++) {
			field[Y+i][X+j] += Block[i][j];
		}
	}
	ShowGameField();
}



int CheckOverlap(int x2, int y2)
{
	int i, j; //forループ制御用変数

	//ブロックが向かう位置に固定ブロックもしくは壁があるかどうかを検査
	for(i = 0; i<4; i++) {
		for(j = 0; j<4; j++) {
			if(Block[i][j]) {
				if(MAP[y2 + i][x2 + j] != 0) {
					return 1;
				}
			}
		}
	}
	return 0;
}

void LockBlock()
{
	int i, j; //forループ制御用変数

	//ブロックを壁に加える
	for(i = 0; i<21; i++) {
		for(j = 0; j<12; j++) {
			MAP[i][j] = field[i][j];
		}
	}
}


 
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ){
        SetMainWindowText("テトリス");
    ChangeWindowMode(TRUE);
    SetGraphMode(560,420,32);
    if( DxLib_Init() == -1 ) return -1;
    SetDrawScreen( DX_SCREEN_BACK );

	int GetJoypadInputState( int InputType ) ;

	time=0;//タイムの初期化

	Initialize(); //ステージの初期化
 
    while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
          //↑メッセージ処理          ↑画面をクリア           ↑入力状態を保存       ↑ESCが押されていない
 
 //メインゲーム

		if(time<=60 && gameover==0 ){//タイムを加算
			time++;
		}else{
			//重なりがなければ移動
			if(!CheckOverlap(X, Y+1)) {
				MoveBlock(X, Y+1);
			}
			//重なりがあれば壁にする
			else{
				LockBlock();
				CreateBlock();
				ShowGameField();
			}
			time=0;	//1秒ごとにタイムループ
		}
		
 
        ScreenFlip();
    }
 
    DxLib_End();
    return 0;
}


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

Re: ウィンドウの点滅

#4

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

終了処理まわりにブレークポイントを貼ってデバッガで調べてみてはどうでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

hidden

Re: ウィンドウの点滅

#5

投稿記事 by hidden » 14年前

関数がどっからどこでとか細かく確認できていないので間違ってたら申し訳ないのですが
41~50がグローバルだとするとDxLib_Init以前にLoadGraphが呼ばれているのではないですか?

chalaza

Re: ウィンドウの点滅

#6

投稿記事 by chalaza » 14年前

最初から作った構造が悪かったかもしてませんが、DxLib_Initより後にLoadGraphを置くとすると、
関数の設計の中の画像描写より後にLoadすることになるので関数内の描写がエラーになるのですが、
この場合、ゲーム内の関数をDxLib_Initより後にすることもできないのですが、
関数をばらすしかないのでしょうか…

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

Re: ウィンドウの点滅

#7

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

配列だけ宣言しておいてInitialize()でロードすれば良いと思いますが。
それではダメなのでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

chalaza

Re: ウィンドウの点滅

#8

投稿記事 by chalaza » 14年前

起動できました!ありがとうございます。
まだ四角テトリミノが落ちるだけですが、綺麗に再現できました。
解決になります。

コード:

#include "DxLib.h"
#include <stdio.h>
#include <stdlib.h>

int Key[256];
 
int GetHitKeyStateAll_2(int GetHitKeyStateAll_InputKey[]){
    char GetHitKeyStateAll_Key[256];
    GetHitKeyStateAll( GetHitKeyStateAll_Key );
    for(int i=0;i<256;i++){
        if(GetHitKeyStateAll_Key[i]==1) GetHitKeyStateAll_InputKey[i]++;
        else                            GetHitKeyStateAll_InputKey[i]=0;
    }
    return 0;
}
 

 
int MAP[21][12] = {0};

int Block[4][4] = {{0,0,0,0},
			  	   {0,1,1,0},
				   {0,1,1,0},
				   {0,0,0,0}};

int field[21][12] = {0};

int block[8];

//グローバル変数
int X=120, Y=0;
int time=0;
int gameover = 0; 

//関数
void Initialize();
int CreateBlock();
void ShowGameField();
void MoveBlock(int, int);
int CheckOverlap(int, int);
void LockBlock();





void Initialize()
{

	//ブロック画像ロード
	block[0] = LoadGraph( "image/block1.png" );//ブロック1~7+壁
	block[1] = LoadGraph( "image/block2.png" );
	block[2] = LoadGraph( "image/block3.png" );
	block[3] = LoadGraph( "image/block4.png" );
	block[4] = LoadGraph( "image/block5.png" );
	block[5] = LoadGraph( "image/block6.png" );
	block[6] = LoadGraph( "image/block7.png" );
	block[7] = LoadGraph( "image/block0.png" );

	int i, j; //forループ制御用変数

	//画面と壁を初期設定
	for(i = 0; i <= 20; i++) {
		for(j = 0; j <= 11; j++) {
			if((j == 0) || (j == 11) || (i == 20)) {
				field[i][j] = MAP[i][j] = 8;
			}
			else {
				field[i][j] = MAP[i][j] = 0;
			}
		}
	}


CreateBlock();	//初期位置の設定
ShowGameField(); //ゲーム直後の画面を描画

}
int CreateBlock()
{
	X=4, Y=0;
	int i, j;
	for(i = 0; i<4; i++) {
		for(j = 0; j<4; j++) {
			field[i][j+4] = MAP[i][j+4] + Block[i][j];

			//初期位置に固定ブロックがあったらゲームオーバー
			if(field[i][j+4] > 1) {
				gameover = 1;
				return 1;
			}
		}
	}
	return 0;
}

//画面表示
void ShowGameField()
{



	
	if(gameover){		//ゲームオーバー処理
	}

}

void MoveBlock(int x2, int y2)
{
	int i, j; //forループ制御用変数

	//今までのブロックを消して
	for(i = 0; i<4; i++) {
		for(j = 0; j<4; j++) {
			field[Y+i][X+j] -= Block[i][j];
		}
	}
	//ブロックの座標を更新
	X = x2;
	Y = y2;

	//新しい座標でブロックを入れなおす
	for(i = 0; i<4; i++) {
		for(j = 0; j<4; j++) {
			field[Y+i][X+j] += Block[i][j];
		}
	}
	ShowGameField();
}



int CheckOverlap(int x2, int y2)
{
	int i, j; //forループ制御用変数

	//ブロックが向かう位置に固定ブロックもしくは壁があるかどうかを検査
	for(i = 0; i<4; i++) {
		for(j = 0; j<4; j++) {
			if(Block[i][j]) {
				if(MAP[y2 + i][x2 + j] != 0) {
					return 1;
				}
			}
		}
	}
	return 0;
}

void LockBlock()
{
	int i, j; //forループ制御用変数

	//ブロックを壁に加える
	for(i = 0; i<21; i++) {
		for(j = 0; j<12; j++) {
			MAP[i][j] = field[i][j];
		}
	}
}


 
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ){
        SetMainWindowText("アクションゲーム");
    ChangeWindowMode(TRUE);
    SetGraphMode(560,420,32);

    if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化

	int GetJoypadInputState( int InputType ) ;

	time=0;//タイムの初期化

	Initialize(); //ステージの初期化
 
    while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
          //↑メッセージ処理          ↑画面をクリア           ↑入力状態を保存       ↑ESCが押されていない
 
 //メインゲーム

		if(time<=60 && gameover==0 ){//タイムを加算
			time++;
		}else{

			//重なりがなければ移動
			if(!CheckOverlap(X, Y+1)) {
				MoveBlock(X, Y+1);
			}
			//重なりがあれば壁にする
			else{
				LockBlock();
				CreateBlock();
				ShowGameField();
			}
				//1秒ごとにタイムループ
		time=0;
		}
			//マップ描画
	for(int y=0;y<21;y++){ 
		for(int x=0;x<12;x++){ 

			if(field[y][x] != 0){
				DrawGraph( x*20+40, y*20, block[field[y][x]-1], TRUE );
			}
			
		}
	}

        ScreenFlip();
    }
 
    DxLib_End();
    return 0;
}


閉鎖

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