アフィリエイト広告を利用しています

広告

posted by fanblog

2018年05月24日

《その393》2つのボール間の距離・壁との位置関係


 2つのボール間の距離・壁との位置関係

 今回はのアプリは、前回とほとんど同じですが、球が2つある点が異なります。
球と球が衝突したときの はね返りについては、計算が難しそうなのでスルーして (*^▽^*)ゞ
適当にはね返るようにしてあります(お互いの速度を交換するだけ)が、実行してみるとそんなに不自然には見えません

 球が2つになると、お互いの位置関係もチェックしなければなりません。
 コスト削減のために、
(2球の x座標の差 < 半径の和) && (2球の y座標の差 < 半径の和)
のときだけ、2球の距離を計算しています。

 球と壁との位置関係,球と床・天井との位置関係,2球の位置関係 といった個々の位置関係チェックだけでは対応できないような、複数の位置関係に起因するエラーが発生する可能性があります。
下記のプログラムでは、例えば、2球が衝突したときにお互いの x座標をいきなり 少しだけ拡げていますが、これがないと、ごく稀にですが 2球が合体してしまうエラーが発生します。

add_d161_2.png

add_d162_2.png


 以下は、MainPage.xaml.cpp です。

//
// MainPage.xaml.cpp
// MainPage クラスの実装。
//


#include "pch.h"
#include "MainPage.xaml.h"

using namespace App11;

using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;


double current_w = 0; // ウィンドウ幅
double current_h = 0; // 高さ
double x01 = 0; // 橙色ボールの x座標
double y01 = 0; // y座標
double x02 = 0; // 赤色ボールの x座標
double y02 = 0; // y座標

// 橙色ボールの初期速度
double vx01 = 4; // x方向速度
double vy01 = 1; // y方向速度

// 赤色ボールの初期速度
double vx02 = -5; // x方向速度
double vy02 = -5; // y方向速度


MainPage::MainPage()
{
InitializeComponent();

// 画面サイズを取得
current_w = Window::Current->Bounds.Width;
current_h = Window::Current->Bounds.Height;

// 赤色ボールの最初の位置は ウィンドウの右下です。
x02 = current_w - 80;
y02 = current_h - 80;

// ボールを動かし始めます。
StartTimer();
}


void MainPage::StartTimer() {
auto timer = ref new Windows::UI::Xaml::DispatcherTimer();
TimeSpan span;
span.Duration = 1000;
timer->Interval = span;
timer->Start();

auto rcpt
= timer->Tick +=
ref new EventHandler<Object^>(this, &MainPage::OnTick);
}


void MainPage::OnTick(Object^ sender, Object^ e) {
// 橙色ボールと右壁
if (x01 > current_w - 80) {
vx01 = -vx01; x01 = current_w - 80;
}
// 橙色ボールと床
if (y01 > current_h - 80) {
vy01 = -vy01; y01 = current_h - 80;
}
// 橙色ボールと左壁
if (x01 < 0) {
vx01 = -vx01; x01 = 0;
}
// 橙色ボールと天井
if (y01 < 0) {
vy01 = -vy01; y01 = 0;
}

// 橙色ボールの位置
x01 += vx01;
y01 += vy01;

// 赤色ボールと右壁
if (x02 > current_w - 80) {
vx02 = -vx02; x02 = current_w - 80;
}
// 赤色ボールと床
if (y02 > current_h - 80) {
vy02 = -vy02; y02 = current_h - 80;
}
// 赤色ボールと左壁
if (x02 < 0) {
vx02 = -vx02; x02 = 0;
}
// 赤色ボールと天井
if (y02 < 0) {
vy02 = -vy02; y02 = 0;
}

// 赤色ボールの位置
x02 += vx02;
y02 += vy02;

// 橙色ボールと赤色ボール
if (x02 - x01 > 80 || x02 - x01 < -80)
goto LABEL;
if (y02 - y01 > 80 || y02 - y01 < -80)
goto LABEL;

// 橙色ボールと赤色ボール
double d = sqrt((x02 - x01) * (x02 - x01) + (y02 - y01) * (y02 - y01));
if (d < 80) {
double temp = vx01;
vx01 = vx02;
vx02 = temp;
temp = vy01;
vy01 = vy02;
vy02 = temp;

if (x01 <= x02) {
if (x01 > 10) x01 -= 5;
else x02 += 5;
}
else {
if (x02 > 10) x02 -= 5;
else x01 += 5;
}
}

LABEL:;
// 2球をそれぞれの位置に移動させます。
img1->Margin = Windows::UI::Xaml::Thickness(x01, y01, 0, 0);
img2->Margin = Windows::UI::Xaml::Thickness(x02, y02, 0, 0);
}


// ウィンドウサイズ変更時のイベントハンドラ
void App11::MainPage::
page_SizeChanged(Platform::Object^ sender,
Windows::UI::Xaml::SizeChangedEventArgs^ e)
{
current_w = Window::Current->Bounds.Width;
current_h = Window::Current->Bounds.Height;

// 以下は、
// ドラッグによるアプリウィンドウの急激な縮小が
// 行われた場合の対策です。

if (x01 > current_w - 80) {
x01 = current_w - 80;
if (sqrt((x02 - x01) * (x02 - x01) + (y02 - y01) * (y02 - y01)) < 80)
x02 = x01 - 80;
}
if (x02 > current_w - 80) {
x02 = current_w - 80;
if (sqrt((x02 - x01) * (x02 - x01) + (y02 - y01) * (y02 - y01)) < 80)
x01 = x02 - 80;
}
if (y01 > current_h - 80) {
y01 = current_h - 80;
if (sqrt((x02 - x01) * (x02 - x01) + (y02 - y01) * (y02 - y01)) < 80)
y02 = y01 - 80;
}
if (y02 > current_h - 80) {
y02 = current_h - 80;
if (sqrt((x02 - x01) * (x02 - x01) + (y02 - y01) * (y02 - y01)) < 80)
y01 = y02 - 81;
}
}




この記事へのコメント
コメントを書く

お名前:

メールアドレス:


ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバックURL
https://fanblogs.jp/tb/7692842
※ブログオーナーが承認したトラックバックのみ表示されます。

この記事へのトラックバック

 たまに、クリック お願いします m(_ _)m

 AA にほんブログ村 IT技術ブログ C/C++へ

こうすけ:メール kousuke_cpp@outlook.jp

【1】★★C++ 記事目次★★ ← 利用可能です。
・新版明解C++入門編 / 新版明解C++中級編
・その他 C++ 関連記事

【2】★★こうすけ@C#★★
・C# の初歩的な記事


検索
<< 2018年08月 >>
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
プロフィール
こうすけさんの画像
こうすけ

 たまに、クリック お願いします m(_ _)m

 AA にほんブログ村 IT技術ブログ C/C++へ

こうすけ:メール kousuke_cpp@outlook.jp

【1】★★C++ 記事目次★★ ← 利用可能です。
・新版明解C++入門編 / 新版明解C++中級編
・その他 C++ 関連記事

【2】★★こうすけ@C#★★
・C# の初歩的な記事


×

この広告は30日以上新しい記事の更新がないブログに表示されております。