初めまして。C++で動くブロック崩しを作成していますがそれに関して2つ質問させて頂きます。
(1)オブジェクト指向によるブロック、パドルでのクラス宣言
オブジェクト指向に基づきプログラミングをしており、パドル、ブロック、ボールといった物体をクラス定義しそれらをゲームクラスで統括する方法をとっています。また、他クラスのインスタンスやメソッドはgetter/setter関数で取得し、その際に参照するクラスの宣言は"const Ball& ball"の様に行っています。
他クラスを参照する必要のある場合は、例えばBlockクラス内でBallとの衝突判定や衝突応答を行いたい時に宣言を行っています。衝突判定ならばBoolean型を返すだけなのでconstで宣言出来るのですが、衝突応答ではボールを反射させる(ボールの速度を変化させる)必要があるためconstで宣言出来ません。
現在は"Ball& ball"と宣言をしていますが、これでは他クラス内でインスタンスの値を変更できてしまうため行儀が良いとは思えません。言っている事が矛盾しているとは思いますが、何とか"const Ball& ball"で宣言しつつBlockクラス内でボールの速度を変化させる方法は無いでしょうか?
(2)ブロックとボールの衝突応答
ブロックとボールの衝突応答について、以下の様に記述しています。
void Block::reflect(Ball& ball){
Vector ballnext;
ballnext.x=ball.getx()+ball.getVx(),ballnext.y=ball.gety()+ball.getVy();
if(fabsf(ballnext.x-this->x) <= this->width/2 && fabsf(ball.getx()-this->x) >= this->width/2){
ball.setVx(-ball.getVx());
}
else if(fabsf(ballnext.y-this->y) <= this->height/2 && fabsf(ball.gety()-this->y) >= this->height/2){
ball.setVy(-ball.getVy());
}
}
この関数より前にブロック内にボールが含まれるかどうかの衝突判定を行っています。この関数では、数秒先のボールの位置がブロック内に含まれており、現在のボールの位置が含まれていない場合のそれぞれの位置関係で反射方向を決めています。
ですがこれでは上手く反射されません。ボールがブロックに接触し暫く突き進んだ後に反射されます。
しかし、
ballnext.x=ball.getx()+ball.getVx()*2,ballnext.y=ball.gety()+ball.getVy()*4;
の様に記述すると上手く反射されます。何故こうなるのかが理解出来ません。
長文になってしまい申し訳ありませんが、どなたかご教授して頂けたら幸いでございます。
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
付け加えると、登場人物たちにあまり直接交渉させない方が良いです。
たとえば、あとひとつ user というクラス(のインスタンス)を参加させて
while(1)
{
パドル.ユーザーの操作(ユーザー.操作()) // ユーザーの操作を与えて、次に進む位置を計算できるようにする
if(ボール.次に進む位置() == パドル.次に進む位置())
{ // ボールとパドルが接触する(ただし、単純に == で良いかどうか場別の問題として
ボール.反射してね(パドル.スピード())
}
for(int i = 0; i < ブロック::総数(); i++)
// ブロックの総数を求めるために、static なメンバー関数が使える
// 処理を簡単にするために、総数は消えてしまったブロックも含むことにしよう
{
if (個別のブロック[i].存在する && 個別のブロック[i].座標 == ボール.次に進む位置()) // ボールがぶつかるブロックが存在する
{
個別のブロック[i].消えてね(); ここで、ブロックの「生存数」は -1 になるように処理しよう
ボール.反射してね(0); // ブロックだから、ぶつかる方のスピードはゼロとして
]
}
if (ブロック::生存数 == 0) break; // 一面クリア
パドル.ひとつ進む();
ボール.ひとつ進む();
}
こんな感じの処理を念頭に置くと、うまく設計できるんではないかという気がします。(確かめてません)
返事が遅くなり申し訳ありません。
色々と手解きして頂きありがとうございます。とりあえず質問前にしようとしていたブロック、パドルのクラス内でのボール反射処理は止め、全てボールクラス内にて行うように修正しました。
また私の方で設計に多少の間違いがあり、その結果この様に不躾な質問をしてしまい反省しております。
ユーザ(user)というクラスで全ての物体の管理を行うアイデアは素晴らしいと思います。余力があれば実装させて頂きます。
回答して頂き本当にありがとうございました。
No.2
- 回答日時:
一般的には、矛盾を感じたら設計がどこかおかしいというのは言えることです……が。
あと、setter() や getter() が単純にメンバーの値を返す/値を設定するとしたら、多分、設計がおかしいです。
基本的にメンバーは自分の挙動を決定するための情報ではありますが、逆に言えば、それをそのまま相手に渡す必要はないのです。
たとえば、衝突判断の場合、ボールの側から見れば、
・次に進む予定の所に存在するブロックはないか?
・もしあったら、そのブロックに消えてもらって、(そのブロックにたとえば erase() メッセージを送る・C++ の実装では、そのブロックのたとえば、erase() メンバーを呼び出す)
・自分自身の速度やら進行方向を(自分で)変更する。
となりますし、ブロックの側から見れば(それぞれのブロックごとに)
・自分が存在している位置にボールが来るつもりはないか(たとえば、ボールに next() メッセージを送る)
・もし、自分の位置にボールが来るのなら、自分自身は消える
・ボールに対しては、「反射してね」というメッセージを送る(具体的に「反射」をどう表現するかは、ボールの責任)
という流れが設定できるかと思います。
つまりは、お互いに相手の情報に手を出さないということです。
ボールはブロックに対して、「消えてね」というだけで良いですし、ブロックはボールに対しては(具体的な位置を指定するのではなく)「反射してね」といえば良いだけです。
ボールの進行方向や速度までブロックが決めようとすると、概ね全体の構成は破綻します。
後半の問題については、ボールとブロックの「位置」が実はどこなのかが影響している気がします。
ボールの位置が中心で、ブロックの位置が左下だったら、「ぶつかる」というのは、単純に判定していれば、ボールがブロックにめり込んだ後になりますね。
No.1
- 回答日時:
> 言っている事が矛盾しているとは思いますが、何とか"const Ball& ball"で宣言しつつBlockクラス内でボールの速度を変 化させる方法は無いでしょうか?
メンバ変数を mutable にすれば可能ですが、それは「正しい設計」ですか?
早速のご返事ありがとうございます。
「正しい設計」かどうかは答え辛いですね。。。当方C++についてはまだ未熟なため、あまり自信がございません。
mutableの存在を忘れていました。本日帰宅後に一度挑戦してみたいと思います。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 物理学 英語表現についてどうもわからないので教えて貰えないでしょうか? 具体的には以下の文の中でreflec 1 2023/04/29 20:59
- その他(プログラミング・Web制作) ボールの動きがスムーズに動いてかつ目盛り線描画を維持するためには 4 2023/05/31 10:01
- その他(プログラミング・Web制作) 物理の斜方投射で目盛りに数値を入れたい 2 2023/05/27 06:32
- その他(プログラミング・Web制作) Pythonによる物理の斜方投射の位置座標表示について 2 2023/06/05 12:46
- その他(プログラミング・Web制作) 物理の斜方投射の目盛り線とx軸、y軸の追加について 3 2023/05/26 21:11
- その他(プログラミング・Web制作) Pythonにおける物理のシミュレーションでの単位変換について 2 2023/06/02 17:11
- その他(プログラミング・Web制作) Pythonでのかんたんな物理シミュレーションについての書籍 5 2023/06/02 07:37
- 英語 英語の形容詞句と副詞句 3 2022/05/14 23:35
- アニメ dragon ball superのキャラクター 1 2022/10/20 15:14
- 邦楽 気にしないでもいいのだが 5 2023/08/28 00:43
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
皆さんは、疎遠になった人や、...
-
マンション10階から飛び降りた...
-
Instagramの同じ端末のブロック...
-
インスタの裏垢をブロックされ...
-
ブロックしたユーザー名の人が...
-
すぐブロックしてしまう人は、...
-
5ch のエロ広告を見えないよう...
-
LINE相手が勝手にブロックされ...
-
中学校の体育祭でブロック名を...
-
「ブロックしてほしい」と頼む...
-
自分はこのサイトで通報した記...
-
ブロックして勝手に消えていく...
-
野村訓市さんの髪型にしたいで...
-
インスタブロックしてた子が ブ...
-
カカオトークでの質問です。 ブ...
-
バイト先の後輩にLINEブロック...
-
いちいちブロックするねーって...
-
スキマバイトタイミーである企...
-
女性の方に質問です! 物凄く嫌...
-
元彼からの嫌がらせ?
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
マンション10階から飛び降りた...
-
インスタの裏垢をブロックされ...
-
Instagramの同じ端末のブロック...
-
5ch のエロ広告を見えないよう...
-
LINE相手が勝手にブロックされ...
-
ブロックしたユーザー名の人が...
-
「ブロックしてほしい」と頼む...
-
教えてグーのウザい悪口(・・?
-
LINEって、スマホ故障したら 勝...
-
知恵袋よりおしえてgooさんの方...
-
相手のインスタのアカウントを...
-
結婚、恋愛カテに常にいる、 は...
-
インスタブロックしてた子が ブ...
-
深夜特急 千一夜物語 しましよう
-
女性の方に質問です! 物凄く嫌...
-
知らない人がいつも私の質問に...
-
コストコでお買い物
-
自分に原因があり、嫌われ修復...
-
いちいちブロックするねーって...
-
インスタで裏垢から話しかけた...
おすすめ情報