#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include "DxLib.h"
#include"data.h"
//関数プロトタイプ宣言
void Load_Graph(); //ロード処理
void Player_Operation();//プレイヤーの操作、移動ルーチン
void Enemis_Operation();//敵の移動ルーチン
void Erorr_Message(); //エラーメッセージ処理
void Player_Burret(); //プレイヤー攻撃
void HitPoint_Burret( int Burret_x, int Burret_y, int Enemy_x, int Enemy_y );//当たり判定
void Sound_effects( int Sound_data, int flagORframe );
int Key[256];
int Color = GetColor( 255, 255, 255 ); //基本(黒)
int SRand((unsigned)time(NULL)); //乱数
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 X_Player = 100; //X座標
int Y_Player = 30; //Y座標
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
ChangeWindowMode(TRUE);//ウィンドウモード
// 画面モードの設定
SetGraphMode( 640 , 480 , 16 ) ;
if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化
while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
//↑メッセージ処理 ↑画面をクリア ↑入力状態を保存 ↑ESCが押されていない
Load_Graph();
Player_Operation();
Enemis_Operation();
Player_Burret();
ScreenFlip();
}
DxLib_End();
return 0;
}
//プレイヤー操作
void Player_Operation(){
//プレイヤーの移動ルーチン
if( CheckHitKey(KEY_INPUT_RIGHT) == 1 ) X_Player += 3;
if( CheckHitKey(KEY_INPUT_LEFT) == 1 ) X_Player -= 3;
if( CheckHitKey(KEY_INPUT_UP) == 1 ) Y_Player -= 3;
if( CheckHitKey(KEY_INPUT_DOWN) == 1 ) Y_Player += 3;
if( X_Player > 625 ) X_Player -= 3;
if( X_Player < 0 ) X_Player += 3;
if( Y_Player > 455 ) Y_Player -= 3;
if( Y_Player < 0 ) Y_Player += 3;
DrawGraph( X_Player, Y_Player, Player.Graph, TRUE ); //画像の表示
}
//プレイヤーの弾移動ルーチン
void Player_Burret(){
if( CheckHitKey(KEY_INPUT_Z) == 1){
if( Burret.FPS == 0 ){
for(int i=0 ; i<Player_Burret_MAX ; i++){
if( Burret.Flag[i] == 0 ){
Burret.X[i] = X_Player;
Burret.Y[i] = Y_Player;
Burret.Flag[i] = 1;
break;
}
}
Burret.FPS = Burret_FPS;
}
else
Burret.FPS -= 1;
}
for( int i=0 ; i< Player_Burret_MAX ; i++ ){
if( Burret.Flag[i] == 1 ){
Burret.Y[i] -= 16;
if( Burret.Y[i] < -80 ) Burret.Flag[i] = 0;
HitPoint_Burret( Burret.X[i], Burret.Y[i], Enemis_X, Enemis_Y );
DrawGraph( Burret.X[i], Burret.Y[i], Burret.Graph, TRUE );
}
}
}
//攻撃判定
void HitPoint_Burret(int Burret_x, int Burret_y, int Enemy_x, int Enemy_y ){
int Attack_hankei;
Attack_hankei = ((5+9)*(5+9));
if( ((Burret_x+3 - Enemy_x+8)*(Burret_x+3 - Enemy_x+8))+((Burret_y+5 - Enemy_y+5)*(Burret_y+5 - Enemy_y+5)) <= Attack_hankei ){
if( Enemis.damage_Flag == 0 ){
Enemis.damage_Flag = 1;
}
}
else if( Enemis.damage_Flag == 1 ){
DrawGraph( Enemy_x+7, Enemy_y-3, damage_Graph, TRUE );
Enemis.damage_FPS ++;
if( Enemis.damage_FPS == Graph_Counter_MAX ){
Sound_effects( Music.Graph,1 );
Enemis.damage_FPS = 0;
Enemis.damage_Flag= 0;
}
}
//-----
#ifdef _DEBUG
DrawCircle( Enemy_x+8 , Enemy_y+5 , 9 , Color, FALSE ) ;
DrawCircle( Burret_x+3 , Burret_y+5 , 5 , Color, FALSE );
DrawLine(Enemy_x+8,Enemy_y+5,Burret_x+3,Burret_y+5,Color);
#endif
//-----
}
//敵の移動ルーチン
void Enemis_Operation(){
if( Enemis_X < 0 ) Enemis.direction = TRUE;
if( Enemis.direction == TRUE ) Enemis_X += 2;
if( Enemis_X > 625 ) Enemis.direction = FALSE;
if( Enemis.direction == FALSE ) Enemis_X -= 2;
DrawGraph( Enemis_X, Enemis_Y, Enemis.Graph, TRUE );
}
//サウンドの再生
void Sound_effects( int Sound_data, int flagORframe ){
//再生方法がフレームではない 再生されているかどうか
int Sound_flag=0, During_Sound_flag=0;
int Sound_frame=0; //再生方法がフレーム
if( flagORframe == 1 ) Sound_flag = 1;
else if( flagORframe > 1 ) Sound_frame = 1;
if( CheckSoundMem( Sound_data) == 1 ){
During_Sound_flag = 1;
}
else
During_Sound_flag = 0;
if( Sound_flag == 1 && During_Sound_flag == 0 ){
PlaySoundMem( Sound_data, DX_PLAYTYPE_BACK );
}
}
//画像の読み込み
void Load_Graph(){
//プレイヤーグラフィックの読み込み
Player.Graph = LoadGraph( "media\\jiki.png", 0 );
//弾画像の読み込み
Burret.Graph = LoadGraph( "media\\tama.png", 0 );
//敵画像の読み込み
Enemis.Graph = LoadGraph( "media\\enemy.png", 0 );
//ダメージ画像読み込み
damage_Graph = LoadGraph( "media\\damage.png", 0 );
//音の読み込み
Music.Graph = LoadSoundMem("media\\bakugeki.wav");
//音の読み込み
Music.hassya = LoadSoundMem("media\\masingan.wav");
if( Player.Graph == -1 || Enemis.Graph == -1 || Burret.Graph == -1 || damage_Graph == -1 || Music.Graph == -1 || Music.hassya == -1 ){//エラー表示
Erorr_Message();
}
}
//エラーメッセージ処理
void Erorr_Message(){
MessageBox( NULL, "画像を読み込めません。プログラムを終了します。", "Graph error", MB_OK);
exit(0);
}
//変数マクロ
#define Player_Burret_MAX 3 //連続で発射される弾の数
#define Graph_Counter_MAX 10 //何フレーム間グラフィックを表示するか
#define Burret_FPS 5 //なんフレーム目で2発目を出すか
#define Burret_Music_FPS 5 //何フレーム間音を停止するか
//敵データ
extern int Enemis_X = 10; //X座標
extern int Enemis_Y = 110; //Y座標
//自機構造体
struct Player{
int Graph;
};
//弾構造体
struct Burret{
int X[Player_Burret_MAX];
int Y[Player_Burret_MAX];
int Flag[Player_Burret_MAX];
int FPS;
int Graph;
};
//弾データ
int damage_Graph;
//敵機データ
//敵機構造体
struct Enemis{
int Graph;
int damage_Flag;
int damage_FPS;
bool direction;
};
//音データ
struct Music{
int Graph;
int hassya;
};
//構造体宣言
Player Player;
Burret Burret;
Enemis Enemis;
Music Music;
開発言語:C言語
OS:WindowsXP
メモリ:1GB
質問内容:
今回は、このプログラムで実行するとどんどんメモリが消費されてしまう件で質問しました。
音楽の部分を作ってる時にテストで、実行してみるといきなりパソコンがカクカクして、メモリが原因っぽそうだったので
タスクマネージャーで確認してみると、メモリ使用量がどんどん増えていきました。
音楽の部分が原因?だとおもってその部分だけ実行されないようにしてみても同じ結果でした。
原因はなんでしょうか?また、解決法はなんでしょうか?
今まで気づかなかっただけで今までもメモリがどんどん消費されていた?可能性があるので、コードを丸々貼り付けました。
まったく関係ないのですが、攻撃判定の部分を他のゲームでも再利用できるようにしたいので、構造体の部分をローカル変数にするべきでしょうか?
例:
Enemis.damage_FPS = 0;
Enemis.damage_Flag= 0;
この部分を
int Enemis_damage_FPS = 0;
int Enemis_damage_Flag= 0;
にする。
他のゲームでもなるべく再利用できるようにするために、色々工夫して改造してみたいと思っています。
まだまだ初心者なので無駄が多く読みにくいコードですが、よろしくお願いします。
ちなみに、音楽の部分はまだ出来てません。