[1.1] 自分が今行いたい事は何か
海戦ゲームを作成中で、まずマウスクリックした位置に丸を表示させ、一度クリックした所を白抜き丸にして履歴を残したいと思っています。
[1.2] どのように取り組んだか(プログラムコードがある場合記載)
「龍神」をベースにして、以下のコードように行っています。
char.cpp
#include "../include/GV.h"
//キャラクタ画像計算(24周期で1周。4種類の画像をループ)
void calc_ch(){
if(ch.cnt==0 && ch.flag==2){ //今の瞬間死んだら
ch.x=FIELD_MAX_X/2;
ch.y=FIELD_MAX_Y+30;
ch.mutekicnt++; //無敵状態へ
}
if(ch.flag==2){ //死んで浮上中なら
unsigned int push=CheckStatePad(configpad.left)+
CheckStatePad(configpad.right)+
CheckStatePad(configpad.up)+
CheckStatePad(configpad.down);
ch.y-=1.5; //キャラ(自機)を上に上げる
//1秒以上か、キャラがある程度上にいて、何か押されたら
if(ch.cnt>60 || (ch.y<FIELD_MAX_Y-20 && push)){
ch.cnt=0;
ch.flag=0; //キャラステータスを元に戻す
}
}
if(ch.mutekicnt>0){ //無敵中なら(カウントが0でないなら)
ch.mutekicnt++;
if(ch.mutekicnt>120) //無敵中が2秒以上だったら
ch.mutekicnt=0; //無敵解除(元に戻す)
}
ch.cnt++; //キャラクタのカウントアップ
ch.img=(ch.cnt%24)/6; //現在の画像決定
}
void ch_move(){//キャラクタの移動制御
int i,sayu_flag=0,joge_flag=0;
double x,y,mx,my,naname=1;
double move_x[4]={-4.0,4.0,0,0},move_y[4]={0,0,4.0,-4.0};//{左,右,下,上}のスピード
int inputpad[4];
inputpad[0]=CheckStatePad(configpad.left); inputpad[1]=CheckStatePad(configpad.right);
inputpad[2]=CheckStatePad(configpad.down); inputpad[3]=CheckStatePad(configpad.up);
if(CheckStatePad(configpad.left)>0)//左キーが押されていたら
ch.img+=4*2;//画像を左向きに
else if(CheckStatePad(configpad.right)>0)//右キーが押されていたら
ch.img+=4*1;//画像を右向きに
for(i=0;i<2;i++)//左右分
if(inputpad[i]>0)//左右どちらかの入力があれば
sayu_flag=1;//左右入力フラグを立てる
for(i=2;i<4;i++)//上下分
if(inputpad[i]>0)//上下どちらかの入力があれば
joge_flag=1;//上下入力フラグを立てる
if(sayu_flag==1 && joge_flag==1)//左右、上下両方の入力があれば斜めだと言う事
naname=sqrt(2.0);//移動スピードを1/ルート2に
for(int i=0;i<4;i++){//4方向分ループ
if(inputpad[i]>0){//i方向のキーボード、パッドどちらかの入力があれば
x=ch.x , y=ch.y;//今の座標をとりあえずx,yに格納
mx=move_x[i]; my=move_y[i];//移動分をmx,myに代入
if(CheckStatePad(configpad.slow)>0){//低速移動なら
mx=move_x[i]/3; my=move_y[i]/3;//移動スピードを1/3に
}
//x+=mx , y+=my;//スピード1より速い
x+=mx/naname , y+=my/naname;//今の座標と移動分を足す
if(!(x<10 || x>FIELD_MAX_X-10 || y<5 || y>FIELD_MAX_Y-5)){//計算結果移動可能範囲内なら
ch.x=x , ch.y=y;//実際に移動させる
}
}
}
}
void own_set(){ //自軍セット
int Cr = GetColor( 255 , 0 , 255 ) ;
int MouseInput = GetMouseInput();
while((MouseInput & MOUSE_INPUT_LEFT) == 0){
// メッセージ処理
if( ProcessMessage() == -1 )
{
break ; // エラーが起きたらループから抜ける
}
MouseInput = GetMouseInput() ;
}
int MouseX , MouseY ;
GetMousePoint( &MouseX , &MouseY ) ;
DrawCircle( MouseX , MouseY , 10 , Cr , TRUE ) ;
if(draw_count<OWN_MAX){
own[draw_count].x=MouseX;
own[draw_count].y=MouseY;
draw_count++;
}
int Cr_y = GetColor( 0, 255 , 255 ) ;
for(int i=0; i<OWN_MAX; i++){
DrawCircle( own[i].x , own[i].y , 10 , Cr_y , FALSE ) ;
}
}
以下のコードは、メイン画面のステージ座標を表示しています。
graph.cpp
#include "../include/GV.h"
void graph_enemy(){
int i;
for(i=0;i<ENEMY_MAX;i++){
if(enemy[i].flag==1){
DrawRotaGraphF(enemy[i].x+FIELD_X,enemy[i].y+FIELD_Y,1.0f,0.0f,img_enemy[0][enemy[i].img],TRUE);
}
}
}
void graph_ch(){
if(ch.mutekicnt%2==0)
DrawRotaGraphF(ch.x+FIELD_X,ch.y+FIELD_Y,1.0f,0.0f,img_ch[0][ch.img],TRUE);
}
void graph_board(){
//座標ステージ表示
int Cr = GetColor( 255 , 255 , 255 ) ; // 白色の値を取得
//for(int stage_x=FIELD_X; stage_x<640; stage_x=stage_x+INTERVAL)
// DrawLine(stage_x, FIELD_Y, stage_x, 480-FIELD_Y, Cr) ; // 縦線を描画
//for(int stage_y=FIELD_Y; stage_y<480; stage_y=stage_y+INTERVAL)
// DrawLine(FIELD_X, stage_y, 640-FIELD_X, stage_y, Cr) ; // 横線を描画
//自軍
for(int stage_x=FIELD_X+30; stage_x<330; stage_x=stage_x+INTERVAL)
DrawLine(stage_x, FIELD_Y+20, stage_x, 480-20-FIELD_Y, Cr) ; // 縦線を描画
for(int stage_y=FIELD_Y+20; stage_y<480-10; stage_y=stage_y+INTERVAL)
DrawLine(FIELD_X+30, stage_y, 320, stage_y, Cr) ; // 横線を描画
//敵軍
for(int stage_x=350; stage_x<640; stage_x=stage_x+INTERVAL)
DrawLine(stage_x, FIELD_Y+20, stage_x, 480-20-FIELD_Y, Cr) ; // 縦線を描画
for(int stage_y=FIELD_Y+20; stage_y<480-10; stage_y=stage_y+INTERVAL)
DrawLine(350, stage_y, 640-FIELD_X, stage_y, Cr) ; // 横線を描画
//テキスト表示
// 白色の値を取得
int Cr_t = GetColor( 255 , 255 , 255 ) ;
// 文字列の描画
//縦軸
DrawString( 40 , 45 , "1" , Cr_t );
DrawString( 40 , 65 , "2" , Cr_t );
DrawString( 40 , 85 , "3" , Cr_t );
DrawString( 40 , 105 , "4" , Cr_t );
DrawString( 40 , 125 , "5" , Cr_t );
DrawString( 40 , 145 , "6" , Cr_t );
DrawString( 40 , 165 , "7" , Cr_t );
DrawString( 40 , 185 , "8" , Cr_t );
DrawString( 40 , 205 , "9" , Cr_t );
DrawString( 35 , 225 , "10" , Cr_t );
DrawString( 35 , 245 , "11" , Cr_t );
DrawString( 35 , 265 , "12" , Cr_t );
DrawString( 35 , 285 , "13" , Cr_t );
DrawString( 35 , 305 , "14" , Cr_t );
DrawString( 35 , 325 , "15" , Cr_t );
DrawString( 35 , 345 , "16" , Cr_t );
DrawString( 35 , 365 , "17" , Cr_t );
DrawString( 35 , 385 , "18" , Cr_t );
DrawString( 35 , 405 , "19" , Cr_t );
DrawString( 35 , 425 , "20" , Cr_t );
//DrawString( 35 , 445 , "21" , Cr_t );
//DrawString( 35 , 465 , "22" , Cr_t );
//横軸
DrawString( 77 , 10 , "A" , Cr_t );
DrawString( 97 , 10 , "B" , Cr_t );
DrawString( 117 , 10 , "C" , Cr_t );
DrawString( 137 , 10 , "D" , Cr_t );
DrawString( 157 , 10 , "E" , Cr_t );
DrawString( 177 , 10 , "F" , Cr_t );
DrawString( 197 , 10 , "G" , Cr_t );
DrawString( 217 , 10 , "H" , Cr_t );
DrawString( 237 , 10 , "I" , Cr_t );
DrawString( 257 , 10 , "J" , Cr_t );
DrawString( 277 , 10 , "K" , Cr_t );
DrawString( 297 , 10 , "L" , Cr_t );
//DrawString( 317 , 10 , "M" , Cr_t );
DrawString( 365 , 10 , "a" , Cr_t );
DrawString( 385 , 10 , "b" , Cr_t );
DrawString( 405 , 10 , "c" , Cr_t );
DrawString( 425 , 10 , "d" , Cr_t );
DrawString( 445 , 10 , "e" , Cr_t );
DrawString( 465 , 10 , "f" , Cr_t );
DrawString( 485 , 10 , "g" , Cr_t );
DrawString( 505 , 10 , "h" , Cr_t );
DrawString( 525 , 10 , "i" , Cr_t );
DrawString( 545 , 10 , "j" , Cr_t );
DrawString( 565 , 10 , "k" , Cr_t );
DrawString( 585 , 10 , "l" , Cr_t );
//DrawString( 605 , 10 , "m" , Cr_t );
int Cr_t2 = GetColor( 255 , 0 , 0 ) ;
DrawString( 177 , 453 , "OWN" , Cr_t2 );
DrawString( 460 , 453 , "ENEMY" , Cr_t2 );
// DrawGraph( 0, 0,img_board[10],FALSE);
}
//弾丸の描画
void graph_bullet(){
int i,j;
SetDrawMode(DX_DRAWMODE_BILINEAR); //線形補完描画
for(i=0; i<SHOT_MAX; i++){ //敵の弾幕数分ループ
if(shot[i].flag>0){ //弾幕データがオンなら
for(j=0; j<SHOT_BULLET_MAX; j++){ //その弾幕が持つ弾の最大数分ループ
if(shot[i].bullet[j].flag!=0){ //弾データがオンなら
if(shot[i].bullet[j].eff==1)
SetDrawBlendMode(DX_BLENDMODE_ADD,255);
//DrawRotaGraphF(
// shot[i].bullet[j].x+FIELD_X,shot[i].bullet[j].y+FIELD_Y,
// 1.0, shot[i].bullet[j].angle+PI/2,
// img_bullet[shot[i].bullet[j].knd][shot[i].bullet[j].col],TRUE);
DrawRotaGraphF(
shot[i].bullet[j].x+FIELD_X,shot[i].bullet[j].y+FIELD_Y,
1.0, shot[i].bullet[j].angle+3.141529/2,
img_bullet[shot[i].bullet[j].knd][shot[i].bullet[j].col],TRUE);
if(shot[i].bullet[j].eff==1)
SetDrawBlendMode(DX_BLENDMODE_NOBLEND,0);
}
}
}
}
SetDrawMode(DX_DRAWMODE_NEAREST); //描画形式を戻す
}
//自機ショット描画
void graph_cshot(){
for(int i=0; i<CSHOT_MAX; i++){
if(cshot[i].flag>0){
DrawRotaGraphF(cshot[i].x+FIELD_X,cshot[i].y+FIELD_Y
,1,0,img_cshot[cshot[i].knd],TRUE);
}
}
}
void graph_effect(int knd){
for(int i=0; i<EFFECT_MAX; i++){
if(effect[i].flag>0 && effect[i].knd==knd){
if(effect[i].eff==1) //エフェクトが光エフェクトなら
SetDrawBlendMode(DX_BLENDMODE_ADD,effect[i].brt);
if(effect[i].eff==2) //エフェクトがαエフェクトなら
SetDrawBlendMode(DX_BLENDMODE_ALPHA,effect[i].brt);
DrawRotaGraphF(effect[i].x+FIELD_X+dn.x
,effect[i].y+FIELD_Y+dn.y
,effect[i].r,effect[i].ang,effect[i].img,TRUE);
if(effect[i].eff==1 || effect[i].eff==2)
SetDrawBlendMode(DX_BLENDMODE_NOBLEND,0);
}
}
}
extern void graph_back_main();
void graph_main(){
graph_back_main(); //背景描画メイン
graph_effect(0); //敵が死ぬエフェクト
graph_enemy(); //敵の描画
graph_cshot(); //自機ショットの描画
if(bright_set.brt!=255)SetDrawBright(255,255,255);
graph_ch(); //自機の描画
if(bright_set.brt!=255)
SetDrawBright(bright_set.brt,bright_set.brt,bright_set.brt);
graph_bullet();
if(bright_set.brt!=255)SetDrawBright(255,255,255);
graph_effect(1); //ボムのエフェクト
graph_effect(2); //ボム線のエフェクト
graph_effect(3); //ボムキャラのエフェクト
graph_board(); //ボードの描画
}
graph_back.cpp
#include "../include/GV.h"
void graph_back00(){
//SetDrawArea(32,16,416,464); //描画可能エリアを設定
//windowsizeは640,480
//SetDrawArea(32,16,608,464); //(x1,y1)=(32,16),(x2,y2)=(640-32,480-16)
SetDrawArea(30,10,611,471); //(x1,y1)=(32,16),(x2,y2)=(640-30+1,480-10+1)
////0の480上からcount分ずつ下に描画
DrawGraph(FIELD_X,count%480+FIELD_Y-480,img_back[0],FALSE);
////0からcount分ずつ下に描画
DrawGraph(FIELD_X,count%480+FIELD_Y ,img_back[0],FALSE);
//SetDrawArea(0,0,640,480); //描画可能エリアを戻す
}
void graph_back_main(){
graph_back00();
}
main.cpp
#define GLOBAL_INSTANCE
#include "../include/GV.h"
//ループで必ず行う3大処理
int ProcessLoop(){
if(ProcessMessage()!=0)return -1;//プロセス処理がエラーなら-1を返す
if(ClearDrawScreen()!=0)return -1;//画面クリア処理がエラーなら-1を返す
GetHitKeyStateAll_2();//現在のキー入力処理を行う
GetHitPadStateAll(); //現在のパッド入力処理を行う
return 0;
}
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(ProcessLoop()==0){//メインループ
music_ini();
switch(func_state){
case 0://初回のみ入る処理
load(); //データロード
first_ini();//初回の初期化
func_state=99;
break;
case 99://STGを始める前に行う初期化
ini();
load_story();
func_state=100;
break;
case 100://通常処理
// calc_ch(); //キャラクタ計算
// ch_move(); //キャラクタの移動制御
//cshot_main(); //自機ショットメイン
// enemy_main();//敵処理メイン
//shot_main(); //敵ショットメイン
//out_main(); //当たり計算
//effect_main(); //エフェクトメイン
graph_main();//描画メイン
own_set();
stage_count++;
break;
default:
printfDx("不明なfunc_state\n");
break;
}
music_play();
if(CheckStateKey(KEY_INPUT_ESCAPE)==1)break;//エスケープが入力されたらブレイク
ScreenFlip();//裏画面反映
count++;
}
DxLib_End();//DXライブラリ終了処理
return 0;
}
困っていることは、デバッグでは狙い通り、クリックした位置に丸が表示され、2回目以降のクリックは履歴が白抜き丸で残るようになるのですが、実行するとなぜか一回目だけ履歴が残り後は消えてしまいます。
[1.4] 今何がわからないのか、知りたいのか
今後何をしていけばいいのかがわからないので、指針を教えていただけたらと思っています。
よろしくお願いします。
[2] 環境
[2.1] OS : Windows, Linux等々
Windows7
[2.2] コンパイラ名 : VC++ 2008EE, Borand C++, gcc等々
VC++2008EE
[3] その他
・どの程度C言語を理解しているか
メモリの状態をある程度イメージできる程度。
ゲームはまともに作るのは初めてです。
・ライブラリを使っている場合は何を使っているか
DXライブラリ
※すいません、送信前にプレビューしてみたところ、コードが改行とかうまくいかず間延びしてしまっています。直そうとしてみましたがダメでした。
見づらくてすいません。ソースファイルを添付しましたので、そちらをご覧ください。
以上よろしくお願いします。