現在DXライブラリ置き場というサイトの
、サンプルプログラムの10の落ちものプログラムに、
17のプログラムにあったカウントをするプログラムを使えないかと思い実装しようとしています。
色がそろった時に100ポイントずつポイントを増やしていくようにしたいと思っています。
#include "DxLib.h"
#include <stdio.h> // ファイル操作に必要なヘッダファイル
#include <string.h> // 文字列操作に必要なヘッダファイル
#define BLOCKTYPE_NUM 5 // ブロックの種類の数
#define BLOCK_SIZE 24 // ブロックのドットサイズ
#define WORLD_WIDTH 8 // ステージの幅
#define WORLD_HEIGHT 16 // ステージの高さ
#define STAGE_X 210 // ステージの左上頂点のX座標
#define STAGE_Y 50 // ステージの左上頂点のY座標
#define WAIT 500 // 黙っててブロックが落ちるまでの時間
// ステージデータ
char Block[ WORLD_WIDTH ][ WORLD_HEIGHT ] ; // 実際のデータ
char BufferBlock[ WORLD_WIDTH ][ WORLD_HEIGHT ] ; // 一時状態保存用ブロックデータ
// アクティブブロックデータ
int ActiveX , ActiveY ; // アクティブブロックの一番下のブロックの位置
char ActiveBlock[ 3 ] ; // アクティブなブロックのデータ
// カウンター
int WaitCounter ; // 下に勝手に落とすまでの時間計測用
int NowTime ; // 現在のフレームで経過した時間
int OldTime ; // 前のフレームのときにGetNowCount関数で得たタイム
// ブロックの種類ごとの色データ
int BlockColor[ 5 ][ 3 ] =
{
{ 0 , 0 , 255 } , { 255 , 0 , 0 } ,{ 255 , 255 , 0 } ,
{ 0 , 255 , 0 } , { 102 , 51 , 0 }
} ;
void InitGame( void ) ; // ゲームの初期化
void CreateNewActiveBlock( void ) ; // 新しいブロックの生成
int KeyInput( void ) ; // キー入力処理
int TimeFunc( void ) ; // 時間関係処理
int MoveActiveBlock( int MoveX , int MoveY ) ; // アクティブブロックの移動
int CheckHitActiveBlock( int x , int y ) ; // アクティブブロックが画面上のブロックに当たっていないか調べる
int LockActiveBlock( int x , int y ) ; // アクティブブロックを固定する及び次のブロックを出すもし次のブロックを出すスペースがなかったらゲームオーバー
void GameOver( void ) ; // ゲームオーバー処理
int CheckEliminatBlock( void ) ; // 消えるブロックがあるか調べてあったら消す処理をする
void InitBufferBlock( void ) ; // 一時使用用ブロックデータの初期化
int CheckEliminatBlockToOne( int x , int y ) ; // 特定ブロックが消えるか探索
int ScreenDraw( void ) ; // 画面描画処理関数
void DrawNum( int x , int y , int Num ) ; // 数値を画面に表示する関数
// WinMain関数
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
ChangeWindowMode(TRUE);//ウィンドウモード
SetGraphMode( 640 , 480 , 16 ) ;
if( DxLib_Init() == -1 ) // DXライブラリ初期化処理
{
return -1; // エラーが起きたら直ちに終了
}
// ゲームを初期化
InitGame() ;
// 描画先画面を裏画面にセット
SetDrawScreen( DX_SCREEN_BACK ) ;
// メインループ
while( ProcessMessage() == 0 )
{
// キー入力処理
KeyInput() ;
// 時間経過処理
TimeFunc() ;
// 画面描画
ScreenDraw() ;
// 裏画面の内容を表画面に反映させる
ScreenFlip() ;
}
// DXライブラリの終了
DxLib_End() ;
// 終了
return 0 ;
}
// ゲームの初期化
void InitGame( void )
{
int i , j ;
// 前回時間をセット
OldTime = GetNowCount() ;
// アクティブブロックの位置をセット
ActiveX = WORLD_WIDTH / 2 ;
ActiveY = 2 ;
// アクティブブロックを生成
CreateNewActiveBlock() ;
// マップブロックの初期化
for( i = 0 ; i < WORLD_HEIGHT ; i ++ )
for( j = 0 ; j < WORLD_WIDTH ; j ++ )
Block[ j ][ i ] = 0 ;
}
// 新しいブロックの生成
void CreateNewActiveBlock( void )
{
int i ;
// ランダムに3つブロックをセット
for( i = 0 ; i < 3 ; i ++ )
ActiveBlock[ i ] = GetRand( BLOCKTYPE_NUM - 1 ) + 1 ;
}
// キー入力処理
int KeyInput( void )
{
int Key ; // 入力されたキー
static int OldKey ; // 前フレームで取得したキー情報
// キー入力を得る
Key = GetJoypadInputState( DX_INPUT_KEY_PAD1 ) ;
// キー入力に応じて処理をする
if( Key & PAD_INPUT_DOWN ) MoveActiveBlock( 0 , 1 ) ;
if( ( Key & ~OldKey ) & PAD_INPUT_LEFT && ActiveX > 0 ) MoveActiveBlock( -1 , 0 ) ;
if( ( Key & ~OldKey ) & PAD_INPUT_RIGHT && ActiveX < WORLD_WIDTH - 1 ) MoveActiveBlock( 1 , 0 ) ;
if( ( Key & ~OldKey ) & PAD_INPUT_A )
{
int TempBlock ;
// アクティブブロックの配置を変更する
TempBlock = ActiveBlock[ 2 ] ; ActiveBlock[ 2 ] = ActiveBlock[ 0 ] ; ActiveBlock[ 0 ] = TempBlock ;
TempBlock = ActiveBlock[ 0 ] ; ActiveBlock[ 0 ] = ActiveBlock[ 1 ] ; ActiveBlock[ 1 ] = TempBlock ;
}
OldKey = Key ;
// 終了
return 0 ;
}
// 時間関係処理
int TimeFunc( void )
{
int Time ;
// 現在の時間を得る
Time = GetNowCount() ;
// 今フレームで経過した時間を得る
NowTime = Time - OldTime ;
// 現在の時間を保存
OldTime = Time ;
// ウエイトカウンタに経過時間を加算する
WaitCounter += NowTime ;
// 一定時間が経過していたら勝手に下にブロックを落す
if( WaitCounter > WAIT )
{
MoveActiveBlock( 0 , 1 ) ;
// カウンターを0に戻す
WaitCounter = 0 ;
}
// 終了
return 0 ;
}
// アクティブブロックの移動
int MoveActiveBlock( int MoveX , int MoveY )
{
int NewX , NewY ;
// 移動後の座標をセットする
NewX = MoveX + ActiveX ;
NewY = MoveY + ActiveY ;
// 左右移動の処理
if( MoveX != 0 && NewX >= 0 && NewX < WORLD_WIDTH )
{
// 各3つのブロックが画面上のブロックに当たっていないか調べる
if( CheckHitActiveBlock( NewX , NewY ) == - 1 )
{
// あたっていたら左右移動を無効にする
MoveX = 0 ;
}
}
// 上下移動の処理
if( MoveY != 0 )
{
// 画面の一番下のブロック位置まで来ていたらブロックを固定させる
if( NewY >= WORLD_HEIGHT )
{
LockActiveBlock( ActiveX , ActiveY ) ;
// 移動を無効にする
MoveY = 0 ;
}
else
// 各3つのブロックが画面上のブロックに当たっていないか調べる
if( CheckHitActiveBlock( NewX , NewY ) == - 1 )
{
// あたっていたらブロックを固定する
LockActiveBlock( ActiveX , ActiveY ) ;
// 移動を無効にする
MoveY = 0 ;
}
}
// 座標を移動する
ActiveX += MoveX ;
ActiveY += MoveY ;
// 終了
return 0 ;
}
// アクティブブロックが画面上のブロックに当たっていないか調べる
int CheckHitActiveBlock( int x , int y )
{
int i ;
// 3つあるブロックがそれぞれ画面上のブロックに当たっていないか調べる
for( i = 0 ; y - i >= 0 && i < 3 ; i ++ )
{
// 当たっていたらここで終了
if( Block[ x ][ y - i ] != 0 ) return -1 ;
}
// 当たっていない場合だけ0を返す
return 0 ;
}
// アクティブブロックを固定する
// 及び次のブロックを出す
// もし次のブロックを出すスペースがなかったらゲームオーバー
int LockActiveBlock( int x , int y )
{
int i ;
for( i = 0 ; i < 3 ; i ++ )
{
// 画面上から外れている場合はセットしない
if( y - i < 0 ) continue ;
// ブロックの固定
Block[ x ][ y - i ] = ActiveBlock[ i ] ;
}
// 消せるブロックがある場合は消す
CheckEliminatBlock() ;
// 新しいブロックをセット
{
// アクティブブロックの位置をセット
ActiveX = WORLD_WIDTH / 2 ;
ActiveY = 2 ;
// 新しいアクティブブロックを生成
CreateNewActiveBlock() ;
// 次に出そうとしているスペースがなかったらゲームオーバー処理
for( i = 0 ; i < 3 ; i ++ )
{
if( Block[ ActiveX ][ ActiveY - i ] != 0 ) GameOver() ;
}
}
// カウンタリセット
WaitCounter = 0 ;
// 時間待ち
WaitTimer( 200 ) ;
// 終了
return 0 ;
}
// ゲームオーバー処理
void GameOver( void )
{
// 画面中心にゲームオーバーを表示
ScreenDraw() ;
DrawString( 300 , 220 , "GameOver" , GetColor( 255 , 255 , 255 ) ) ;
ScreenFlip() ;
// キー入力待ち
WaitKey() ;
// DXライブラリ終了
DxLib_End() ;
// ソフト終了
exit( -1 ) ;
}
// 消えるブロックがあるか調べてあったら消す処理をする
int CheckEliminatBlock( void )
{
int i , j , k; // 汎用変数
int ClsFlag ; // 一つでも消せたブロックがあったか、のフラグ
int Counter;
Counter = 0 ; // カウンターを初期化
do{
// 一時使用用ブロックデータを初期化
InitBufferBlock() ;
// 消せたブロックがあるか、フラグを倒す
ClsFlag = FALSE ;
// 各ブロックが消えるか調べる
for( i = 0 ; i < WORLD_HEIGHT ; i ++ )
{
for( j = 0 ; j < WORLD_WIDTH ; j ++ )
{
// もしブロックがない場合は次に移る
if( Block[ j ][ i ] == 0 ) continue ;
// ブロックが消えるかどうか調べて調査結果をバッファに保存する
BufferBlock[ j ][ i ] = CheckEliminatBlockToOne( j , i ) ;
}
}
// 消えると判断されたブロックを消す
for( i = 0 ; i < WORLD_HEIGHT ; i ++ )
{
for( j = 0 ; j < WORLD_WIDTH ; j ++ )
{
if( BufferBlock[ j ][ i ] == 1 )
{
ClsFlag = TRUE ;
Block[ j ][ i ] = 0 ;
//100点ずつ追加
Counter += 100 ;
// カウンタ値を表示
DrawNum( 550 , 120 , Counter ) ;
}
}
}
// 空きを積める
for( i = WORLD_HEIGHT - 2 ; i > -1 ; i -- )
{
for( j = 0 ; j < WORLD_WIDTH ; j ++ )
{
if( Block[ j ][ i ] != 0 )
{
for( k = i + 1 ; k < WORLD_HEIGHT && Block[ j ][ k ] == 0 ; k ++ ){}
k -- ;
if( k != i )
{
Block[ j ][ k ] = Block[ j ][ i ] ;
Block[ j ][ i ] = 0 ;
}
}
}
}
}while( ClsFlag ) ; // 消せたブロックがあった場合再度チェック
// 終了
return 0 ;
}
// 一時使用用ブロックデータの初期化
void InitBufferBlock( void )
{
int i , j ;
for( i = 0 ; i < WORLD_HEIGHT ; i ++ )
{
for( j = 0 ; j < WORLD_WIDTH ; j ++ )
{
BufferBlock[ j ][ i ] = 0 ;
}
}
}
// 特定ブロックが消えるか探索
int CheckEliminatBlockToOne( int x , int y )
{
int CheckBlock ;
int i ;
int BlockNum ;
// チェックするブロックの種類を保存
CheckBlock = Block[ x ][ y ] ;
// 左右にどれだけつながっているか調べる
for( i = 0 ; x + i >= 0 && Block[ x + i ][ y ] == CheckBlock ; i -- ){}
i ++ ;
for( BlockNum = 0 ; x + i < WORLD_WIDTH && Block[ x + i ][ y ] == CheckBlock ; BlockNum ++ , i ++ ){}
// 3つ以上つながっていたらここで終了
if( BlockNum >= 3 ) return 1 ;
// 上下にどれだけつながっているか調べる
for( i = 0 ; y + i >= 0 && Block[ x ][ y + i ] == CheckBlock ; i -- ){}
i ++ ;
for( BlockNum = 0 ; y + i < WORLD_HEIGHT && Block[ x ][ y + i ] == CheckBlock ; BlockNum ++ , i ++ ){}
// 3つ以上つながっていたらここで終了
if( BlockNum >= 3 ) return 1 ;
// 左上から右下にかけて繋がっている数を調べる
for( i = 0 ; y + i >= 0 && x + i >= 0 && Block[ x + i ][ y + i ] == CheckBlock ; i -- ){}
i ++ ;
for( BlockNum = 0 ; x + i < WORLD_WIDTH && y + i < WORLD_HEIGHT && Block[ x + i ][ y + i ] == CheckBlock ; BlockNum ++ , i ++ ){}
// 3つ以上つながっていたらここで終了
if( BlockNum >= 3 ) return 1 ;
// 右上から左下にかけて繋がっている数を調べる
for( i = 0 ; y + i >= 0 && x - i < WORLD_WIDTH && Block[ x - i ][ y + i ] == CheckBlock ; i -- ){}
i ++ ;
for( BlockNum = 0 ; x - i >= 0 && y + i < WORLD_HEIGHT && Block[ x - i ][ y + i ] == CheckBlock ; BlockNum ++ , i ++ ){}
// 3つ以上つながっていたらここで終了
if( BlockNum >= 3 ) return 1 ;
// ここまで来ていたら消えない
return 0 ;
}
// 画面描画処理関数
int ScreenDraw( void )
{
int i , j , k ;
int Color ; // 文字の色コード
// 白色コードを取得
Color = GetColor( 255 , 255 , 255 ) ;
// 画面を初期化
ClearDrawScreen() ;
// カウント値表示
DrawString( 460 , 120 , "COUNT" , Color ) ;
DrawNum( 550 , 120 , 0 ) ;
// 枠を描画
DrawBox( STAGE_X - 25 , STAGE_Y , STAGE_X ,
STAGE_Y + WORLD_HEIGHT * BLOCK_SIZE ,
GetColor( 255 , 255 , 255 ) , TRUE ) ;
DrawBox( STAGE_X + WORLD_WIDTH * BLOCK_SIZE , STAGE_Y ,
STAGE_X + 24 + WORLD_WIDTH * BLOCK_SIZE , STAGE_Y + WORLD_HEIGHT * BLOCK_SIZE ,
GetColor( 255 , 255 , 255 ) , TRUE ) ;
DrawBox( STAGE_X - 25 , STAGE_Y + WORLD_HEIGHT * BLOCK_SIZE ,
STAGE_X + 25 + WORLD_WIDTH * BLOCK_SIZE , STAGE_Y + WORLD_HEIGHT * BLOCK_SIZE + 25 ,
GetColor( 255 , 255 , 255 ) , TRUE ) ;
// ブロックを描画
for( i = 0 ; i < WORLD_HEIGHT ; i ++ )
{
for( j = 0 ; j < WORLD_WIDTH ; j ++ )
{
if( Block[ j ][ i ] != 0 )
{
k = Block[ j ][ i ] - 1 ;
DrawBox( STAGE_X +j * BLOCK_SIZE , STAGE_Y + BLOCK_SIZE * i ,
STAGE_X +j * BLOCK_SIZE + BLOCK_SIZE , STAGE_Y + i * BLOCK_SIZE + BLOCK_SIZE ,
GetColor( BlockColor[ k ][ 0 ] ,BlockColor[ k ][ 1 ] ,BlockColor[ k ][ 2 ] ) , TRUE ) ;
}
}
}
// アクティブブロックを描画
for( i = 0 ; i + ActiveY >= 0 && i < 3 ; i ++ )
{
k = ActiveBlock[ i ] - 1 ;
DrawBox( STAGE_X + ActiveX * BLOCK_SIZE , STAGE_Y + ( ActiveY - i ) * BLOCK_SIZE ,
STAGE_X + ActiveX * BLOCK_SIZE + BLOCK_SIZE , STAGE_Y + ( ActiveY - i ) * BLOCK_SIZE + BLOCK_SIZE ,
GetColor( BlockColor[ k ][ 0 ] ,BlockColor[ k ][ 1 ] ,BlockColor[ k ][ 2 ] ) , TRUE ) ;
}
// 終了
return 0 ;
}
// 数値を画面に表示する関数
void DrawNum( int x , int y , int Num )
{
char StrBuf[ 80 ] ;
// 数値を10進数文字列に変換
itoa( Num , StrBuf , 10 ) ;
// 画面に描画
DrawBox( x , y , x + strlen( StrBuf ) * 20 , y + 20 , 0 , TRUE ) ;
DrawString( x , y , StrBuf , GetColor( 255 , 255 , 255 ) ) ;
}
動かしてみると、色がそろって消えるときにカウントされていきません。
何が原因なのか、またどのようにすればよいかを指摘していただけたらと思います。