忍者ブログ

GAM-22のメモ

左右どちらに旋回する方が早いのかを判定

2024.11 ← 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 →

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

左右どちらに旋回する方が早いのかを判定

HSPの掲示板に、左右どちらに旋回する方が早いのかの判定について質問がありました。

方法としては色々あるでしょうが、そのひとつとして、ベクトルの外積を使う方法を紹介します。

// 角度の補正が面倒なので、数学に合わせて0ラジアンはx軸方向に並行とします。
// 考え方としては、自分の向きをaベクトル、自分から目標の向きをbベクトルとして、
// 外積から、abベクトルのなす角のsinを求め、どちらに旋回する方が早いか判定します。

    ; 自分の座標と向き
    mx = 320.0
    my = 240.0
    mr = 0.0

*main

    ; 目標の座標(マウスカーソル)
    tx = 0.0+mousex
    ty = 0.0+mousey
    
    ; aベクトル(自分の向き)
    ax = cos(mr)
    ay = sin(mr)
    ; bベクトル(自分から目標の向き)
    bx = tx-mx
    by = ty-my

;-----------------------------------------------------------
;    ここから重要
;-----------------------------------------------------------

    ; abベクトルの外積
    a×b = ax*by - bx*ay
    ; abベクトルのなす角をsinθとして
    ; a×b = |a||b|sinθ
    sinθ = (a×b)/sqrt(bx*bx+by*by)

    if absf(sinθ)>=0.02 {
        ; sinθの符号で旋回する方向を判定
        if sinθ>=0 {
            mr += 0.02
        } else {
            mr -= 0.02
        }
    }

;-----------------------------------------------------------
;    ここまで
;-----------------------------------------------------------

    redraw 0
    color 255,255,255 : boxf
    color 0,0,0

    ; 自分
    line mx+cos(mr)*100,my+sin(mr)*100, mx,my
    ; 目標
    pos tx-7,ty-9 : mes "◎"

    redraw

    await 10
    goto*main

なぜ外積やsinの符号で判定できるか分からない人は、sinの定義をよく考えてください。

この方法なら、自分が何回転するとしても面倒なことを考えなくて済みます。

説明の為に冗長なソースになっていますが、実際にやってることは簡単です。工夫すれば、かなり短くできるので、HSPコンテストのショート部門に向いているかもしれません。

この手の判定ですが、他の人のゲームのソースを研究すれば、他にも色々な方法があるかもしれません。私はプログラムの技術は人から盗んで学ぶものだと考えているので、そういうのも大切かなと思います。

3/16追記、ショートっぽくサイズを削ってみたら、ここまで短縮できました。

    ; 自分の座標
    #const mx 320
    #const my 240
    mr = 0.0
    ; 目標(mousex,mousey)
    #define tx mousex
    #define ty mousey

*main

    tr = atan(ty-my, tx-mx)
    sinθ = cos(mr)*sin(tr) - cos(tr)*sin(mr)
    mr += 0.02 * (absf(sinθ)>=0.02) * (2*(sinθ>=0)-1)

    redraw 0
    pget -1 : boxf
    color

    ; 自分
    line mx+cos(mr)*100,my+sin(mr)*100, mx,my
    ; 目標
    pos tx-7,ty-9 : mes "◎"

    redraw

    await 10
    goto*main

bベクトルの長さを1にすることで、外積からsinθの変換の手間が省けます。

PR
この記事にコメントする
お名前
タイトル
文字色
URL
コメント
パスワード Vodafone絵文字 i-mode絵文字 Ezweb絵文字
初めまして。
内積・外積について調べてたらココにきました。

外積って3Dで使うものとしか頭になかったので
上のサンプルを実行したら外積の使用方法が一つ増えました。
キャラの追跡とかに役に立ちそうですね^^


これからもゲームで使う数学をどんどん紹介していってください。
たまさん / 2010/03/29(Mon) / 編集
Re:外積の使用方法
コメントありがとうございます。プログラミング関係のコメントは久しぶりなので、嬉しいです。

3Dのプログラムは作ったことはないですが、3Dだと外積は、2つのベクトルからできる平面に垂直なベクトルになるらしいですね。

>キャラの追跡とかに役に立ちそうですね^^
そうですね。こんな感じにマウス追跡とか。
https://blog.cnobi.jp/v1/blog/user/354f95828a2d0bef40423056b5f3ea60/1235786063
追跡ミサイルとか作れますね。

ゲームで使う数学を思いついたら、記事にしようと思います。
 (2010/03/31)
外積で出来るとは思いつかなかった…
ずっと原始的にAtanで場合分けやるものだとw
Qwertityさん / 2010/04/18(Sun) / 編集
Re:無題
学校の授業がプログラムにも役に立つこともなんちゃら…と書こうと思ったんですが、よく考えたら高校では外積は習わなかったですね。それでいて、教科書の三角形の面積公式とかで、普通に外積の式が含まれてたりすんですけどね。
日本の教育には文句を言いたいですww

まあ、容量削減版だと、Atan使っちゃってますけどねw
 (2010/04/19)
この記事にトラックバックする
トラックバックURL:
カテゴリー
カウンター
最新記事
最新コメント
Twitter
人気記事
Amazon お買い得情報
Amazon お買い得情報
プロフィール
自画像
HN :
GAM-22
性別:
男性
職業:
大学1年生
HSP暦:
6年
好きなもの :
ゲーム, アニメ, マヨネーズ
嫌いなもの :
運動, 注射, ホラー映画, 英語
好きなバンド :
Muse, Radiohead
その他 :
文章能力が欠如している
バナー
Copyright © GAM-22のメモ All Rights Reserved
Powered by ニンジャブログ Designed by ピンキー・ローン・ピッグ 忍者ブログ / [PR]