My portfolio

Menu▼

  • Top
  • About
  • Portfolio
  • Diary
  • Privacy policy
  • フーリエ級数を用いたスプライトの動きの制御

    Outline

    職業訓練の終了課題で横スクロールシューティングの作成を担当しました。 今回は中ボスの作成をしました。 敵が画面上部で停滞⇒画面下部に移動⇒画面下部で停滞⇒画面上部に移動を繰り返すような動きにしました。 その際矩形波をフーリエ級数展開し第2項で打ち切ったものを用いました。

    フーリエ級数

    矩形波のフーリエ級数展開は下のようになる。この式のうちn=1,2について合計した。(ただし4/πは省略した)

    Unity(2022.3.201f)

    PackageDownLoad(一部です)
    Script using System.Collections; using System.Collections.Generic; using UnityEngine; public class EagleS2 : MonoBehaviour { GameObject player; public GameObject bulletPref; GameObject camera; int loopCnt; const int maxHp = 200; int hp; bool isAngry=false; Vector2 initPos; // Start is called before the first frame update void Start() { initPos = transform.position; hp=maxHp; loopCnt = 0; camera = GameObject.FindGameObjectWithTag("MainCamera"); if(camera!=null) { transform.SetParent(camera.transform); } player = GameObject.FindGameObjectWithTag("MyShip"); camera.GetComponent<CameraManagerS2>().nowCameraMove = false; } // Update is called once per frame void Update() { if (hp <= 0) { camera.GetComponent<CameraManagerS2>().nowCameraMove = true; Destroy(gameObject); } else if (hp < maxHp / 2) { isAngry = true; } } private void FixedUpdate() { Vector2 v; GameObject bullet; if (bulletPref!=null && player!=null && camera!=null && loopCnt%10==0) { v = (player.transform.position - this.transform.position).normalized * 5; bullet = Instantiate(bulletPref, transform.position, Quaternion.identity); bullet.transform.SetParent(camera.transform); bullet.GetComponent<Rigidbody2D>().velocity = v; if(isAngry) { int startDeg=loopCnt*3; for(int i=startDeg;i<(startDeg+360);i+=20) { float rad=i*Mathf.Deg2Rad; v=new Vector2(Mathf.Cos(rad), Mathf.Sin(rad)); bullet = Instantiate(bulletPref, transform.position, Quaternion.identity); bullet.transform.SetParent(camera.transform); bullet.GetComponent<Rigidbody2D>().velocity = v*5; } } } if (loopCnt <= 10) { GetComponent<Rigidbody2D>().velocity = new Vector2(-80,0); } else { GetComponent<Rigidbody2D>().velocity=Vector2.zero; } //float y=(Mathf.Sin(Mathf.Deg2Rad*loopCnt)+0.33f*Mathf.Sin(Mathf.Deg2Rad*loopCnt*3f))*5f+initPos.y;//フーリエ級数矩形波 第二項まで float y = SquareWave(loopCnt * Mathf.Deg2Rad, 2)*5+initPos.y; Vector2 pos=new Vector2(transform.position.x,y); transform.position = pos; loopCnt++; } private void OnTriggerEnter2D(Collider2D collision) { if (collision.gameObject.tag == "MyShot") { hp--; } } float SquareWave(float rad,int terms) {//矩形波をフーリエ展開し、ある項までで打ち切った結果を返す。(4/π は省略) float result=0; float magunitude;//角度についている係数 for (int i = 1; i <= terms; i++) { magunitude = (2 * i) - 1; result += (1 / magunitude) * Mathf.Sin(magunitude * rad); } return result; } }