質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

Q&A

解決済

2回答

1294閲覧

C++ マウスの左クリックが押された瞬間に画像を完全に消したい

kinakomoti-_-

総合スコア3

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

0グッド

0クリップ

投稿2022/12/15 10:13

前提

DXライブラリを参考にして、射的ゲームを作成しています。

実現したいこと

的(画像)にマウスの左クリックが押された瞬間に画像を完全に消して得点と的の破壊数を加算させたい

発生している問題・エラーメッセージ

・的に左クリック長押しすると得点と的の破壊数が加算し続けてしまう
・的に左クリックが押されたとき、表面上では画像は消えているが、まだ残ってしまっている。

該当のソースコード

C++

1#include "Game.h" 2#include "Scene.h" 3#include "DxLib.h" 4 5 6//更新 7void Game_Update() { 8 if (CheckHitKey(KEY_INPUT_B) != 0) { //Bキーが押されていたら 9 Scene_ChangeScene(eScene_Menu);//シーンをメニューに変更 10 } 11} 12 13//描画 14void Game_Draw() { 15 16 ChangeWindowMode(TRUE); 17 SetAlwaysRunFlag(TRUE); 18 19 SetDrawScreen(DX_SCREEN_BACK); 20 int MI, XPos, YPos; 21 int X = 250, Y = 250; //画像の座標 22 int SIZE = 45; // 当たり判定修正用 23 int targetGraph; 24 int score = 0; // 得点 25 int breakNum = 0; // 破壊数 26 int W, H; 27 28 29 // 的 30 targetGraph = LoadGraph("image\\tg.png"); 31 32 // 的のグラフィックのサイズを得る 33 GetGraphSize(targetGraph, &W, &H); 34 35 36 37 38 while (ProcessMessage() == 0) 39 { 40 ClearDrawScreen(); // 裏画面を初期化 41 SetFontSize(10); 42 DrawString(0, 0, "得点:", GetColor(255, 255, 255)); 43 DrawFormatString(50, 0, GetColor(255, 255, 255), "%d", score); 44 DrawString(120, 0, "破壊数:", GetColor(255, 255, 255)); 45 DrawFormatString(200, 0, GetColor(255, 255, 255), "%d", breakNum); 46 DrawString(0, 450, "Bキーを押すとメニュー画面に戻ります。", GetColor(255, 255, 255)); 47 48 MI = GetMouseInput(); // マウスのボタンの押下状態を取得する 49 int CLK = (int)(MI & MOUSE_INPUT_LEFT); // マウスクリックの取得 50 GetMousePoint(&XPos, &YPos); // マウス座標の取得 51 52 int HIT = (int)(CLK && (XPos<X + W && XPos>X - W + SIZE) && (YPos<Y + H && YPos>Y - H + SIZE)); // 当たり判定 53 54 55 // 的表示 56 DrawGraph(X, Y, targetGraph, FALSE); 57 58 X++; if (X > 500)X = 0; // 的の移動 59 60 // マウスボタンが押されていて,且つ,マウスカーソル位置が特定の範囲内にあるかどうか 61 if (HIT) { 62 DeleteGraph(targetGraph, FALSE); 63 score += 100; 64 breakNum += 1; 65 } 66 67 68 69 70 ScreenFlip(); // 裏画面の内容を表画面に反映 71 } 72 73 74} 75

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pig_vba

2022/12/16 00:26

処理の内容的に、オブジェクトを即座に削除してしまうより生存フラグを設定してあげるのはどうでしょうか? 各処理を「的が生存しているときのみ実行する」としてあげれば望みの動作は可能だと思います。 以下はSTGの敵消滅エフェクトを実装する記事なので厳密には別のことですが、処理の流れの参考になる部分があるかと思います。 https://bituse.info/game/shot/17
fana

2022/12/16 01:27 編集

生存フラグを条件にする話はここで言われていますね https://dxlib.xsrv.jp/cgi/patiobbs/patio.cgi?mode=view&no=5422 まぁ,「言われていますね」というか「言った」わけなのですが. 場所を変えることは問題ないと思いますが,相互にリンクでも貼ると良いのではないでしょうか.
kinakomoti-_-

2022/12/16 01:26

コメントありがとうございます。 アドバイスのおかげで実装することができました。 ありがとうございます!
guest

回答2

0

左クリックされ続けると得点が
加算し続けてしまう問題は
いつ、マウスカーソルで目的の的をクリックした瞬間が求まるか?というのを
staticな変数かグローバル変数などで
処理すれば分かります。
つまり、これはキーボードの特定のキーを
押した瞬間を処理することができれば
応用すれば出来ます。
static int PressedMouseClick;

if(マウスカーソルが的に当たっている && !PressedMouseClick && マウスを押した状態){
//得点加算
}
PressedMouseClick=マウスを押した状態;

VisualC++とDxlibで恐らくデバッグしてませんが動くと思います。

投稿2022/12/16 10:10

littlestream

総合スコア35

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

LoadGraph, DrawGraph, DeleteGraph についてググった雰囲気だと,表示の消し方というのがちょっと乱暴と言うか強引というか…に見えます.
(あと,ググって出てくるリファレンスだと,DeleteGraph の引数は1個ということになっている様子?)

表面上では画像は消えているが、まだ残ってしまっている

データと表示とを分けて考えるという事ができていないのかな?と見えます.
プログラムはデータとデータに対する処理さえ動いていれば「動いている」わけで,表示というのはそれを可視化する手段にすぎない…的な話です.
DrawGraph で画像を表示しようがしまいが,そこにデータは存在するのであって処理も動いている.だから得点が増えたり等々するわけです.
(わかりやすく言えば,DrawGraphを用いた的の表示を一切行わなければ「見えない透明な的を撃て!」というゲームになるわけですね)

…というわけで,[質問へのコメント]欄に述べられているように,しっかりと データとして/処理として 「今現在のデータの状態ではこの処理を実施して良いのかどうか? 実施して良い状態であれば実施する」というのを実装することを考えてください.


C++

1//「的が存在しているか否か」を表すためのデータを用意する. 2//ここでは,ゲームらしく(?) 「的のHP」という変数を用意して, 3//「この値が1以上の場合には的は存在していて,そうでない(:0以下の)の場合には的は既に破壊されていて存在しない」 4//のだということにする. 5int TargetHP = 1; 6 7/* この辺は省略 */ 8 9while( ProcessMessage() == 0 ) 10{ 11 /* この辺は省略 */ 12 13 //入力情報を取得 14 MI = GetMouseInput(); // マウスのボタンの押下状態を取得する 15 int CLK = (int)(MI & MOUSE_INPUT_LEFT); // マウスクリックの取得 16 GetMousePoint(&XPos, &YPos); // マウス座標の取得 17 18 // 19 //的に関する処理は,的が存在している状況でのみ実施すればよい 20 // 21 if( TargetHP >= 1 ) //今現在,的が存在しているなら 22 { 23 //的を表示 24 DrawGraph(X, Y, targetGraph, FALSE); 25 26 //撃たれたかどうか判定 27 int HIT = (int)(CLK && (XPos<X + W && XPos>X - W + SIZE) && (YPos<Y + H && YPos>Y - H + SIZE)); // 当たり判定 28 29 if( HIT ) //的が撃たれた時 30 { 31 //的のHPを減らす 32 --TargetHP; 33 34 //破壊された際にはスコア増加等を行う 35 if( TargetHP <= 0 ) 36 { 37 score += 100; 38 breakNum += 1; 39 } 40 } 41 42 //的の移動 43 X++; 44 if( X > 500 )X = 0; 45 } 46 47 // 48 ScreenFlip(); // 裏画面の内容を表画面に反映 49} 50 51//※これは↑のwhileの後でやればいいんじゃないかな 52DeleteGraph(targetGraph, FALSE); //※これの第二引数はリファレンスには書かれていない様子?

投稿2022/12/16 01:23

編集2022/12/16 01:59
fana

総合スコア11632

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問