山水堂
A015.パーティクル基本
パーティクルの基本的なプログラムです。
http://dxlib.o.oo7.jp/dxprogram.html#N15
DXライブラリを参考にしました!
-- conf.lua function love.conf(t) t.window.width = 640 t.window.height = 480 end
640x480で設計していますので、コンフィグファイルを設定しておきましょう。
-- main.lua -- ショットとパーティクルの最大数 local MAX_SHOT = 4 local MAX_SPARK = 800 -- プレイヤーの位置 local player_x, player_y = 0, 0 local shot_table = {} local spark_table = {} -- その他変数 local keystate = {} local okey = {} local nkey = {} function love.keypressed(key, irepeat) keystate[key] = true if key == "escape" then love.event.quit() end end function love.keyreleased(key) keystate[key] = false end function shallowcopy(orig) -- 浅くコピー local orig_type = type(orig) local copy if orig_type == "table" then copy = {} for orig_key, orig_value in pairs(orig) do copy[orig_key] = orig_value end else -- number, string, boolean, etc copy = orig end return copy end function reset_key() -- キー情報をリセット okey = shallowcopy(nkey) nkey = shallowcopy(keystate) end function is_keyone(key) -- キー入力(初回のみ) return okey[key] ~= true and nkey[key] == true end function is_keypress(key) -- キー入力(押しっぱなし) return nkey[key] end function draw_box( -- DXライブラリ風 left, top, right, bottom, colors, fill_flag ) -- なければ、初期セット colors = colors or {} fill_flag = fill_flag or true -- fillを生成 local fill = "line" if fill_flag then fill = "fill" end -- 色をセット local get_color = { love.graphics.getColor() } love.graphics.setColor(colors[1] or 0, colors[2] or 0, colors[3] or 0, colors[4] or 255) -- 描画! love.graphics.polygon( fill, left, top, right, top, right, bottom, left, bottom ) -- 色を復帰 love.graphics.setColor(unpack(get_color)) end -- 花火を出す処理 function create_spark(x, y) local spark = {} spark.x = x * 100 spark.y = y * 100 spark.sx = love.math.random(0, 1000) - 500 spark.sy = -love.math.random(0, 500) spark.g = love.math.random(0, 10) spark.bright = 255 table.insert(spark_table, spark) end -- 火花移動処理 function move_spark(dt) local i, max = 1, #spark_table while i <= max do spark_table[i].y = spark_table[i].y + spark_table[i].sy * dt * 60 spark_table[i].x = spark_table[i].x + spark_table[i].sx * dt * 60 spark_table[i].sy = spark_table[i].sy + spark_table[i].g * dt * 60 spark_table[i].bright = spark_table[i].bright - 2 * dt * 60 -- 火花の明るさが0以下になったら火花データを無効にする if spark_table[i].bright < 0 then table.remove(spark_table, i) max = max - 1 else i = i + 1 end end end -- ショットを撃つ処理 function create_shot() table.insert( shot_table, { x = player_x + 16, y = player_y } ) end -- ショットの移動処理 function move_shot(dt) local i, max = 1, #shot_table while i <= max do shot_table[i].y = shot_table[i].y - 8 * dt * 60 -- 画面外に出ていたら火花を出したあとショットデータを無効にする if shot_table[i].y < 150 then -- 花火を出す数をセット local value = love.math.random(0, 60) for j = 1, value do if #spark_table < MAX_SPARK then create_spark(shot_table[i].x + 8, shot_table[i].y + 8) end end table.remove(shot_table, i) max = max - 1 else i = i + 1 end end end function love.load() -- プレイヤーの初期位置をセット player_x = 320 player_y = 400 end function love.update(dt) -- 初期化処理 if dt > 1 then dt = 1 end reset_key() -- キー入力取得 if is_keypress("left") then player_x = player_x - 3 * dt * 60 end if is_keypress("right") then player_x = player_x + 3 * dt * 60 end -- ショットの移動処理 move_shot(dt) -- 花火の移動処理 move_spark(dt) -- ショットボタンを押していたらショットを出す if is_keypress("z") and #shot_table < MAX_SHOT then create_shot() end end function love.draw() -- プレイヤーを描画する draw_box(player_x, player_y, player_x + 48, player_y + 48, {255, 0, 0}, true) -- ショットを描画する for i, shot in ipairs(shot_table) do draw_box(shot.x, shot.y, shot.x + 16, shot.y + 16, {255, 255, 255}, true) end -- 花火を描画する for i, spark in ipairs(spark_table) do draw_box(spark.x / 100, spark.y / 100, spark.x / 100 + 1, spark.y / 100 + 1, {spark.bright, spark.bright, spark.bright}, true ) end end
長くなりましたが、これを実行してみるとパーティクルをシューティングするサンプルが始まります!
カーソルの左右で、プレイヤーの左右の移動。
キーボードのZでショット。
今回もデルタタイムを工夫してみました。
必要に応じていろいろと変更して遊んでみてください!
[2016.08.19] 新規:0.10.1で動作確認