チャックのプログラム


▲サンプルプログラム

サンプルプログラム書いてたら時間なくなっちゃって説明がおざなりだよ

ゲーム制作にかかわる人が自由な記事を作る Advent Calendar 2022 (12月2日分)


▲こう、マウスカーソルとチャックが並んでたとして、



▲こうつかんで



▲ひっぱったらこう開いてほしい。で、



▲よしんばアサッテの方向にひっぱったとしても、



▲このように開いてほしい、みたいな部分はどうするのか。



▲ベクトルの内積をつかいます。
(内積というのは、ほんとうは高校で習うらしいのですが、僕は小5の2学期で算数をあきらめたので知りませんでした。
このプログラムは、内積にするとき単位ベクトルにしたりしなかったりランダムに触った結果できたもので、
なぜこれでちゃんと動くのかは正直わかりません。)

チャック原点~終点を vec1
チャック原点~マウス間を vec2 として、
vec1とvec2を単位ベクトル化しないまま内積(dot)を出す
dotをvec1の長さで割った値をvec1の単位ベクトルに掛けるとチャックのツマミがいいかんじの場所にいきます。

//
//java scriptっぽい疑似コードで失礼
//
//ベクトルはvar v = {x:10, y:0}みたいなオブジェクトで扱ってます
//
//内積だすメソッド
function dotProduct(v1, v2){
    return v1.x * v2.x + v1.y * v2.y;
}
//チャック原点の座標
var zipperPos = {x:20, y:20};
//チャックのベクトル
var zipperVec = {x:100,y:50};
//チャックのベクトルの長さ
var zipperMagnitude = Math.sqrt(zipperVec.x ** 2 + zipperVec.y ** 2);
//チャックの単位ベクトル
var zipperVecUnit = {
    zipperVec.x / zipperMagnitude,
    zipperVec.y / zipperMagnitude,
};
//チャック原点から見たマウス座標との差
var mouseVec = {
    x:mouse.x - zipperPos.x,
    y:mouse.y - zipperPos.y,
};
var dot = dotProduct(zipperVec, mouseVec);//単位ベクトル化しない内積
var zipperProgress = dot / zipperMagnitude;//チャックのベクトルの長さに対してどれくらい進んでいるか(0~ベクトル長さ)
//
//※ここでzipperProgressを0~zipperMagnitude間に丸めないとツマミがハミ出ますが割愛
//
//最終的なツマミの座標
var pulltabPos = {
    x:zipperPos.x + zipperVecUnit.x * zipperProgress,
    y:zipperPos.y + zipperVecUnit.y * zipperProgress,
}
    



サンプルプログラムでやってるような曲線(直線のグループ)上のチャックのプログラムまで書く時間がなかったですゴメンナサイ。
ゲーム制作にかかわる人が自由な記事を作る Advent Calendar 2022 (12月2日分)