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で動作確認