発射されない

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

発射されない

#1

投稿記事 by kameo » 15年前

こんにちは kameoです。
次のようなプログラムを作製したいと思います。
①三角型のプレイヤーを十字キーで操作する。
②スペースを押すと、弾が1個だけとぶ
③弾が消えると次の弾が打てるようになる。(リセット)

そこで次のようなプログラムを組みました。
#include "DxLib.h"

typedef struct{ //プレイヤー
int x,y,img;
}ch_t;
int image[9]; //画像イメージ
char Key[256];
ch_t ch;



void shoot(){ //発射
int flag=0; //発射フラグ
int tamax,tamay=0; //弾の座標

tamax=ch.x; //弾はプレイヤーの上から発射されるように座標設定する。
tamay=ch.y-32;

if(Key[KEY_INPUT_SPACE]==1 && flag==0) flag=1; //発射されていなくかつスペースを押すと弾は飛び出す。

if(flag=1){
tamay-=8;
DrawGraph(tamax,tamay,image[6],TRUE);
if(tamay<-32){
tamay=ch.y;
flag=0;              //リセット
}
}

}







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


if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //ウィンドウ化と初期化処理
//プレイヤー座標及び向き
ch.x =320;
ch.y =240;
int muki=0;

SetDrawScreen( DX_SCREEN_BACK ) ; //描画先を裏画面に設定
LoadDivGraph( "jiji.png" , 9 , 3 , 3 , 32 , 32 , image ) ;//画像を分割してimage配列に保存

while(1){
ClearDrawScreen();
GetHitKeyStateAll(Key);
if(ProcessMessage()==-1)break;


void shoot();     //発射関数
//移動
if( Key[ KEY_INPUT_RIGHT ] == 1 ) {
ch.x+=4 ;
muki=4;
}
if( Key[ KEY_INPUT_LEFT ] == 1 ) {
ch.x-=4 ;
muki=3;
}
if( Key[ KEY_INPUT_UP ] == 1 ) {
ch.y-=4 ;
muki=0;
}
if( Key[ KEY_INPUT_DOWN ] == 1 ) {
ch.y+=4 ;
muki=1;
}

//プレイヤー描写
ch.img=image[muki];

DrawGraph( ch.x-15 , ch.y-24 , ch.img , TRUE ) ;


if (Key[KEY_INPUT_ESCAPE]==1) break;
ScreenFlip();//裏画面を表画面に反映
}

DxLib_End();
return 0;
}
コンパイルエラーは出ていないのですが、スペースを押しても反応がありません。
たぶん関数の使い方に問題があると思うのですが
いまいち原因がつかめません。
どなたかアドバイスをください。お願いします。

DVDM

Re:発射されない

#2

投稿記事 by DVDM » 15年前

>>kameoさん

まず、while文の中にある「void shoot();     //発射関数」の所ですが
関数を呼ぶなら「shoot();」で構いません。

そして、shoot関数の中にある変数ですが、ローカル変数なので
関数を抜けた時に値が消えてしまいます。

void shoot(){ //発射
[color=aqua>static[/color] int flag=0; //発射フラグ
[color=aqua>static[/color] int tamax,tamay=0; //弾の座標


このように[color=aqua>static[/color]を付けるか、グローバル変数にするか等で対処します。
これで、関数を抜けても値が保持されたままになります。



tamax=ch.x; //弾はプレイヤーの上から発射されるように座標設定する。
tamay=ch.y-32;



ここですが、関数が呼ばれるたびに tamax, tamayに座標がセットされ、
動いているように見えないと思います。
これを、スペースキーが押されたらキャラの位置に弾をセットするという風に書き換えます。

if(Key[KEY_INPUT_SPACE]==1 && flag==0)
{
flag=1; //発射されていなくかつスペースを押すと弾は飛び出す。
tamax = ch.x; // スペースが押されてから座標をセットする
tamay = ch.y-32;
}



そして最後

if(flag=1){
tamay-=8;

この部分ですが、flagが1かどうかを判断する時は if(flag==1) や if(flag)と書きます。
これで、画面外に行けば弾がもう一回打てるようになると思います。


ただ、今の段階では向きを考慮しない打ち方なので上方向にしか飛ばないと思います。
考え方は一緒なので、向きでどこに飛ばすかなどの処理も追加してみて下さい~。

kameo

Re:発射されない

#3

投稿記事 by kameo » 15年前

分かりやすい回答 本当にありがとうございます。

頭の中では「こんなことをしたければこんな感じでプログラムすればいいのかな?」
とある程度予想してプログラムすることができるんですけど
C言語の知識が薄いため(基本的な文法含め)
関数がいつ呼ばれるかなどのタイミングや
変数がプログラム上どのように変化するかなどが
いまいち把握しきれません。

今こうして簡単な動作をいろいろなサイトから勉強していますが、
なにか他に効率のよい練習方法などありますか?

話題が変わってしまって申し訳ないのですが
アドバイスお願いします。

DVDM

Re:発射されない

#4

投稿記事 by DVDM » 15年前

>>kameoさん
[color=gray>>関数がいつ呼ばれるかなどのタイミングや
>変数がプログラム上どのように変化するかなどが
>いまいち把握しきれません。[/color]

プログラムは基本的に上から下に向かって実行されます。
kameoさんが実際に組んだプログラムの一部を抜粋しました。

ClearDrawScreen();
GetHitKeyStateAll(Key);
if(ProcessMessage()==-1)break;
shoot(); //発射関数


まずは、ClearDrawScreen();
次は、GetHitKeyStateAll(Key);
その次は、if(ProcessMessage()==-1)break;
次は、shoot();
・・・という風に、処理は上から流れてきます。


例えばこんなプログラムがあったとします。

1:int x=0;
2:int y=0;

3:x++;
4:y+=5;

ここで、3:が処理された時の「x」「y」の値はいくつになるでしょうか?

xは1足されてx=1ですが、この時点で、yはまだ y+=5を処理していません。
なので、3が処理された時の「x」「y」の値は「x=1」「y=0」になります。
4:が処理された時に始めてyは5になります。



[color=gray>>今こうして簡単な動作をいろいろなサイトから勉強していますが、
>なにか他に効率のよい練習方法などありますか?[/color]
これは私個人な意見なのですが、一番効率のいい方法はプログラムを打ち込んでいくことです。
プログラムは思い通りには動きません。
必ず、打ち込んだ通りにしか動かないからです。

まず、このような処理があるんだとなったら、どういう動きをしているのか実際打ち込んでみて下さい。
ここで、あーこんなことが出来るんだで終わらないで下さい。
何回も使っていればその内、なにも見ないで使えるようになりますよ。


まだ、やりはじめて間もないかもしれませんが、地道な努力が一番効率良く作業できると思います。

kameo

Re:発射されない

#5

投稿記事 by kameo » 15年前

ありがとうございます。
一日一歩づつ
ゆっくりと理解していきたいと思います。

閉鎖

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