Layering Tiles (日本語)

こんにちわ! 本日、私はこちらで解説されているタイルマップの仕組みを応用して画像によるレイヤーの実装方法を説明します。

これは私の main.lua であり、このようになっています:

require "map"

function love.load() -- ゲームの開始時のみ実行されます。
	love.graphics.setBackgroundColor( 255, 255, 255 )
end

'main.lua' で全ての関数を呼び出せるようにするために require 'map' (全てのタイルマッピングを行うファイルの名称) を宣言する必要があります。

function love.draw() -- ゲームでは毎回実行します。
	draw_map()
end

function love.update(dt) -- ゲームでは毎回実行します。
end

function love.focus(bool) -- ウィンドウからマウスが出たり入ったりした場合に実行されます。
end

function love.keypressed( key, unicode ) -- キーが押された場合に実行されます。
	move_map(key)
end

function love.keyreleased( key, unicode ) -- キーが離された場合に実行されます。
end

function love.mousepressed( x, y, button ) -- マウスが押された場合に実行されます。
end

function love.mousereleased( x, y, button ) -- マウスが離された場合に実行されます。
end

function love.quit() -- ゲームが閉じられる前に即時実行します。
end

残りのコードは自明です: タイルを描画してから、マップを動かすためにキーが押されたか確認するために調べます。

こちらには前述のコードを基にして、ひとつひとつかみ砕いた 'map.lua' があります。

layers = {}

tile = {}

for i = 0, 4 do -- 3 から 1 を引いたタイル画像の数に変更します。
	tile[i] = love.graphics.newImage( "tiles/tile"..i..".png" )
end

これは何かと言いますと 'layers' および 'tile' と呼ばれる二つのテーブル型です。 それらは別々にではなく for ループ で各画像を登録するために使用します。 フォルダ 'tiles' に記録された画像があることに注意してください。

layers[1] = {
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
}

layers[1].map_w = 20 -- マップの幅を定義します。重要: これは (map_h と同様の) 垂直方向と作成された水平寸法は必ず一致させる必要があります。
layers[1].map_h = 20 -- マップの高さを定義します。
layers[1].map_x = 0 -- 水平方向にマップを描画開始します。
layers[1].map_y = 0 -- 垂直方向にマップを描画開始します。
layers[1].map_offset_x = -50 -- 最も良い結果に対するタイル幅による大きさ。
layers[1].map_offset_y = -50 -- 最も良い結果に対するタイル高による大きさ。
layers[1].map_display_w = 800/50 -- 最も良い結果で画面幅をタイル幅で除算します。
layers[1].map_display_h = 700/50 -- 画面幅をタイル高で除算します。
layers[1].tile_w = 50 -- 画像と関連付けます。
layers[1].tile_h = 50 -- 画像と関連付けます。

これは何かと言いますと全て '0' (この目的のための純粋な画像) を使用したマップを作成することです。 これを今実行すると (まだ draw_map を差癖していないためできませんが) 白い背景に見えるでしょう。 [1]

layers[2] = {
	{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, 
	{ 1, 0, 2, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 2, 0, 1 },
	{ 1, 3, 0, 2, 0, 2, 0, 2, 0, 0, 0, 0, 2, 0, 2, 0, 2, 0, 3, 1 }, 
	{ 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 3, 1 }, 
	{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, 
	{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, 
	{ 1, 0, 2, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 2, 0, 1 },
	{ 1, 3, 0, 2, 0, 2, 0, 2, 0, 0, 0, 0, 2, 0, 2, 0, 2, 0, 3, 1 }, 
	{ 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 3, 1 }, 
	{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, 
	{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, 
	{ 1, 0, 2, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 2, 0, 1 },
	{ 1, 3, 0, 2, 0, 2, 0, 2, 0, 0, 0, 0, 2, 0, 2, 0, 2, 0, 3, 1 }, 
	{ 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 3, 1 }, 
	{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, 
	{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, 
	{ 1, 0, 2, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 2, 0, 1 },
	{ 1, 3, 0, 2, 0, 2, 0, 2, 0, 0, 0, 0, 2, 0, 2, 0, 2, 0, 3, 1 }, 
	{ 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 3, 1 }, 
	{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, 
}

layers[2].map_w = 20 -- マップの幅を定義します。重要: これは (map_h と同様の) 垂直方向と作成された水平寸法は必ず一致させる必要があります。
layers[2].map_h = 20 -- マップの高さを定義します。
layers[2].map_x = 0 -- 水平方向にマップを描画開始します。
layers[2].map_y = 0 -- 垂直方向にマップを描画開始します。
layers[2].map_offset_x = -50 -- 最も良い結果に対するタイル幅による負の大きさ。
layers[2].map_offset_y = -50 -- 最も良い結果に対するタイル高による負の大きさ。
layers[2].map_display_w = 800/50 -- 最も良い結果で画面幅をタイル幅で除算します。
layers[2].map_display_h = 700/50 -- 画面幅をタイル高で除算します。
layers[2].tile_w = 50 -- 画像と関連付けます。
layers[2].tile_h = 50 -- 画像と関連付けます。

同じものですが、 1 は緑、 2 は青、 3 は赤です。 それは、これと少し同じようになります: [2]

ayers[3] = {
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },	
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0 }, 
	{ 0, 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0 }, 
	{ 0, 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0 }, 
	{ 0, 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0 }, 
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
}

layers[3].map_w = 20 -- マップの幅を定義します。重要: これは (map_h と同様の) 垂直方向と作成された水平寸法は必ず一致させる必要があります。
layers[3].map_h = 20 -- マップの高さを定義します。
layers[3].map_x = 0 -- 水平方向にマップを描画開始します。
layers[3].map_y = 0 -- 垂直方向にマップを描画開始します。
layers[3].map_offset_x = -50 -- 最も良い結果に対するタイル幅による負の大きさ。
layers[3].map_offset_y = -50 -- 最も良い結果に対するタイル高による負の大きさ。
layers[3].map_display_w = 800/50 -- 最も良い結果で画面幅をタイル幅で除算します。
layers[3].map_display_h = 700/50 -- 画面幅をタイル高で除算します。
layers[3].tile_w = 50 -- 画像と関連付けます。
layers[3].tile_h = 50 -- 画像と関連付けます。

そして最終的に最後の一つです。 4 は橙色です。それはこのようになります。 [3]

function draw_map()
	for l = 1, #layers do
		for y = 1, layers[l].map_display_h do
			for x = 1, layers[l].map_display_w do
				love.graphics.draw(
				tile[layers[l][y+layers[l].map_y][x+layers[l].map_x]], 
				(x*layers[l].tile_w)+layers[l].map_offset_x, 
				(y*layers[l].tile_h)+layers[l].map_offset_y)
			end
		end
	end
end

これはマップを描画します。どのように機能する(編集された) か理解するには記事をお読みください。

function move_map(key)
 	for l = 1, #layers do	
		if key == 'up' then
			layers[l].map_y = layers[l].map_y-1
			if layers[l].map_y < 0 then 
				layers[l].map_y = 0; 
			end
		end
		if key == 'down' then
			layers[l].map_y = layers[l].map_y+1
			if layers[l].map_y > layers[l].map_h - layers[l].map_display_h then 
				layers[l].map_y = layers[l].map_h - layers[l].map_display_h; 
			end
		end
		if key == 'left' then
			layers[l].map_x = math.max(layers[l].map_x-1, 0)
		end
		if key == 'right' then
			layers[l].map_x = math.min(layers[l].map_x+1, layers[l].map_w - layers[l].map_display_w)
		end
	end
end

再度、前の記事を参照してください。