1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

LuaAdvent Calendar 2022

Day 17

luaでパーティクルもどきを作る

Posted at

 
この記事はアドカレに参加しています。

luaでパーティクルもどきを作る

半年前の文章のコピペです。
過去の僕は文章が綺麗ですね。
完成品も半年前のものです。

<はじめに>

学校の課題でパーティクルもどきを作ったので、それの紹介みたいなかんじです。
パーティクルについてしっかりと学びたい場合は「パーティクルシステム」とかで調べると面白い記事がでてきたりします。

<コンセプト>

・基準となる円が一つあり、その円から粒子がででくる。
・基準となる円も粒子も「速度」と「角度」があり、それをもとに移動する。
・粒子は時間経過で大きさが小さくなる。大きさが0以下になったら描画されない。
・粒子は時間経過で速度が減速する。
・基準となる円も、粒子も領域外には出られないようにする。
・粒子は1フレームで3つででくる。
・粒子の最大寿命は90フレームにして、最大で270の粒子が存在が存在するようにする。

<コード>

--初期化プログラム
if(obj.time==0)then

 --初期化
 local p={}
 p.x={}
 p.y={}
 p.s={}
 p.spd={}
 p.arg={}
 p.r=0

 --初期値を決定
 p.x[1]=100
 p.y[1]=100
 p.s[1]=20
 p.spd[1]=10
 p.arg[1]=math.rad(30)

 for i=2,271 do
  p.x[i]=0
  p.y[i]=0
  p.s[i]=0
  p.spd[i]=0
  p.arg[i]=0
 end

 --グロ変数に流す
 Pdata=p
end


--乱数のseed値用の関数
function R()
 Pdata.r=Pdata.r+1
 return Pdata.r
end


--Pdataの値を更新
function pa(p)
 --粒子を増やす
 local index=rand(0,90,R())*3+2
 for i=0,2 do
  p.x[index]=p.x[1]
  p.y[index]=p.y[1]
  p.s[index]=rand(0,10,R())
  p.spd[index]=p.spd[1]-rand(0,10,R())
  if(p.spd[index]<0)then p.spd[index]=0 end
  p.arg[index]=p.arg[1]+rand(-30,30,R())/0.3
  index=index+1
 end

 --速度の減速とサイズを小さく
 for i=2,271 do
  p.s[i]=p.s[i]-(p.s[1]/90)
  p.spd[i]=p.spd[i]-(p.spd[1]/90)
 end

 --座標の決定
 for i=1,271 do
  --壁との衝突判定
  if(p.x[i]<=19 or p.x[i]>=380)then
   p.arg[i]=math.pi-p.arg[i] end
  if(p.y[i]<=19 or p.y[i]>=380)then
   p.arg[i]=-1*p.arg[i] end

  --移動量を計算
  local dx,dy
  dx=p.spd[i]*math.cos(p.arg[i])
  dy=p.spd[i]*math.sin(p.arg[i])

  --移動量を加算
  p.x[i]=p.x[i]+dx
  p.y[i]=p.y[i]+dy

  --範囲外に出ないように
  if(p.x[i]<19)then p.x[i]=19
  elseif(p.x[i]>380)then p.x[i]=380 end
  if(p.y[i]<19)then p.y[i]=19
  elseif(p.y[i]>380)then p.y[i]=380 end
 end

end


--関数実行と描画
pa(Pdata)
local p=Pdata
for i=1,271 do
 if(p.s[i]>0)then
  obj.load("figure","円",0xffff00,p.s[i])
  obj.draw(p.x[i],p.y[i])
 end
end

<全体のながれ>

1,グローバル変数の準備
2,粒子を増やしたり、座標を決める関数を作る
3,関数を実行して描画
4,次フレームに移動したら、3のみを行う

<補足>

解説はコメントに書いてあるので、コメントにない補足を書いときます。

・グローバル変数
今回の場合は最大で270の粒子が飛ぶようにします。
なので、粒子の数+基準となる円で、合計271のindexを持つ配列を作ればいいことになります。

・粒子の増やし方
同時に存在する粒子の最大数は270(基準となる円も含めると271)なので、描画する際には

for i=1,271 do
 if(p.s[i]>0)then
  obj.load("figure","円",0xffff00,p.s[i])
  obj.draw(p.x[i],p.y[i])
 end
end

のようにindexが1~271のものを順番にif文で判定していきます。
p.s[i]というのは、描画する際のサイズなので、サイズが0より小さいものは描画されないことになります。

p.s[i]が0より大きいものは描画され、p.s[i]が0以下のものは描画されません。

粒子を増やすには、これを利用します。

粒子を増やしたい場合は、p.s[i]が0以下のものを0よりも大きい数にすればいいことになります。

・粒子の減らし方
粒子を減らすには、p.s[i]の値が0より大きいものを0以下にすればいいことになります。

<おわりに>

rikkyさんのパーティクルスクリプトはすごいですね。

<反省>

分かりずらいコードになったかもしれないと反省。
しかも、限定的な使い方しかできないコードですし、右から左へ順番にフレームを読み込まないといけないのでaviutl向きではないという…

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?