love2d教程4--材质和贴图
”说明,在love2d的wiki上以下的这些操作都⽐较费时,建议不要在draw和update⾥重复加载同样的数据,
⽽是创建以后保存以重复使⽤。”
材质可以简单的说是⼀些图⽚素材,love2d可以从⽂件和ImageData(可以看作内存中的图像数据)
载⼊图⽚wImage(path或imagedata),返回⼀个Image对象(可以被画在屏幕上)
培训总结发言说明只能从main.lua所在⽂件夹为相对路径,载⼊图⽚,不能使⽤外⾯的图⽚。
显⽰图⽚使⽤aphics.draw(image, x, y),x、y为显⽰在屏幕上的坐标(说明draw其它参数下⾯
有解释)。
说明在有些较⽼的显卡上只⽀持显⽰为2的整数幂分辨率的图⽚,下⾯这段代码可以把图⽚修改海龟怎么画
为2的整数幂,不过最新的0.8已经不需要了。
--修改图⽚为2的倍数
function newPaddedImage(filename)
local source = wImageData(filename)
local w, h = source:getWidth(), source:getHeight()
-- Find clost power-of-two.
local wp = math.pow(2, il(math.log(w)/math.log(2)))
local hp = math.pow(2, il(math.log(h)/math.log(2)))
-- Only pad if needed:
if wp ~= w or hp ~= h then
local padded = wImageData(wp, hp)
padded:paste(source, 0, 0)
单片机工作原理
wImage(padded)
end
wImage(source)
异常现象end
下⾯说⼀下如何从⼀副⼤图⽚中提取所需的部分。
love2d提供了Quad类型,可以通过quad = wQuad( x, y, width, height, sw, sh )
创建⼀个quad对象,其中x、y是⼤图中⼩图左顶点的坐标,width、height是⼩图的宽和⾼,sw、sh是
⼤图的宽和⾼。
显⽰所需的⼩图使⽤aphics.drawq(image,quad, x, y, r, sx, sy, ox, oy, kx, ky )
其中image是⼤图(需要在绘图前使⽤wImage(path)创建),quad是我们刚才
创建的quad对象,x、y在屏幕上显⽰的坐标;(以下的⼏个参数有默认值,没特殊要求不⽤)r为逆时针
旋转的度数(弧度制);sx、sy是以原图为中⼼沿x、y轴⽅向的缩放系数,可以为负,当x为负时,相当
于左右翻转后再缩放,y为负时即上下颠倒后再缩放;ox、oy即显⽰的坐标与原x、y坐标分别向左、向下
便宜ox、oy像素;kx、ky wiki上解释为Shearing factor ,不知到什么意思(如果你恰好知道,请告诉我)
,我试了⼀下发现这种变换会偏离原坐标中⼼,⽽且当kx、ky都为1时居然没显⽰,但为其它值却可以显⽰。
接着我们学习⼀下贴图(tile,中⽂意思为贴瓷砖)。贴图实际是重复利⽤图⽚的⼀种⽅法,但要求这些图⽚
可以⽆缝拼接,即把⼩图⽚拼装成⼤图后没有缝隙。对于⼩图的管理可以有两种⽅法,⼀种是把许多⼩图⽚放
到⼀个⼤图⽚中(地图多⽤),另⼀种则就是把⼩图按⼀定名称和顺序编号,直接存贮(⼈物图像多⽤)。
wiki上的Tutorial:Tile-bad Scrolling,是采⽤的第⼆种⽅法,我就不重复了,下⾯我介绍⼀下第⼀种⽅法。
请在⽹上下载,最新版本是0.8.1。(说明最新的是0.9了,你可以直接点链接下载0.8.1的)
1、⽂件-新建,如下图,把地图⼤⼩的宽和⾼都改为10
2、在视图菜单⾥把显⽰⽹格和对齐⽹格都勾上,你会看到⼀副⽹格
3、地图-新图块
如下图,把边距和间距都设为1(这个间距是根据图⽚来的,你可以打开tmw_dert_spacing.png,放⼤后可以看见⽹格,我就⽤1试了⼀下正好),点击浏览,打开⾃带的example下的"tmw_dert_spacing.png"图⽚
4、⽤⿏标选择右边的图块中的⼩图,在坐标的⽹格⾥便可以绘图了,按住⿏标左键不放拖动,可以连续画。
画错了,在⼯具栏中有橡⽪擦。如下图,标有红⾊的是我选的⼏幅⼩图。
5、打开地图--地图属性,我们为tmw_dert_spacing.png添加五个属性,如下图,即⽔平和竖直⽅向图块的个数,
图块的宽和⾼,图⽚的格式。
接着⽂件-导出为,在弹出的对话框下⾯的“保存类型”选择"lua⽂件。
6、把刚导出的lua⽂件和刚才的tmw_dert_spacing.png图⽚都复制到love2d⼯程下,把图⽚放到asts⽂件夹⾥。
下⾯我们来看看这个lua⽂件,它只有⼀⾏,⽽且返回了⼀个table。
你可以⼿动把它换⼀下⾏,或者把notepad++的视图菜单--⾃动换⾏勾上。
可以看到有⼀个data表如下
data =
{
30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31 }
这不就是我们刚才选择的图块的编号在⽹格⾥的顺序吗?
下⾯我们可以直接把data复制出来,更好的是写⼀个读取该⽂件的函数。
其中我感兴趣的有图⽚路径,可是这个路径在love2d⾥⽤不了,但图⽚
的名字到可以⽤(在tilets下的name),还有imagewidth,imageheight,
tilewidth,tileheight,width(图块⽔平的个数),height(图块竖直的个数)
spacing(⽔平间隔), margin (竖直间隔)。
客至杜甫再看看tmw_dert_spacing.png,发现是265*199像素,正好⽔平⽅向32*8+1*7+1*2,竖直⽅向32*6+1*5+1*2
(1*2是图⽚四周的框)。其实我们希望没有这个间隔,这样好计算点。
下⾯是运⾏的截图
以下是代码
main.lua
tilemap=require('tilemap')
require('tutor4')
--地图在屏幕上显⽰的x,y坐标
mapX,mapY=100,100
怎么说分手quadtable={}
--那些注释是我试验坐标时⽤的,坐标不易确定啊
function love.load()
wImage("asts/" .. tilemap["tilets"][1].name ..tilemap["properties"]["format"])
makeQuad(tilemap)
--wQuad(1,1,32,32,265,199)
--wQuad(34,1,32,32,265,199)
end
function love.draw()
drawMap(tilemap,image)
--aphics.drawq(image,quad1,100,100)
--aphics.drawq(image,quad2,132,100)
end
function love.update(dt)
--按键检测
if(love.keyboard.isDown("up")) then
mapY=mapY-20
end
if(love.keyboard.isDown("down")) then
mapY=mapY+20
end
if(love.keyboard.isDown("left")) then
mapX=mapX-20
end
if(love.keyboard.isDown("right")) then
mapX=mapX+20
end
--边界检测省略
end
function love.keypresd(key)
end
tutor4.lua ,不好意思代码错了,以下标有红⾊的是更正的. --2012.12.16
--计算⼀个长为width的矩阵中第num个数所在的x列,y⾏
function calcXY(num,width)
local x=num%width
local y=num/width
if(x~=0) then
il(y)
el
x=width
end
return x,y
end
--从⼤图⽣成quad表
function makeQuad(map)
--⼤图的⾼和宽
local imageheight=map["tilets"][1].imageheight
local imagewidth=map["tilets"][1].imagewidth
--⼤图⽔平和竖直⽅向图块的数⽬
local numx=tonumber(map["properties"]["numx"])
local numy=tonumber(map["properties"]["numy"])
--⽔平及竖直间距
local spacing= map["tilets"][1].spacing
德国世界杯冠军local margin=map["tilets"][1].margin
--图块的宽和⾼
local blockx=tonumber(map["properties"]["blockx"])狗打呼噜怎么回事
local blocky=tonumber(map["properties"]["blocky"])
--⽔平及竖直⽅向图块的个数
local width=map["layers"][1].width
local height=map["layers"][1].height
--图块排列表
local array=map["layers"][1].data
--统计不同的图块数⽬
local j=1
for i=1,#array do
if(array[i]~=array[i-1]) then
local x,y=calcXY(array[i],numx)
--创建⼀个quad图像参数需要显⽰的⼩图的左顶点在⼤图中的x,y坐标,每个⼩图的宽、⾼,⼤图的宽、⾼
quadtable[j]=wQuad((x-1)*blockx+x*spacing,(y-1)*blocky+y*margin,blockx,blocky,imagewidth,imageheight) j=j+1
end
end
end
--画地图
function drawMap(map,image)
--图块排列表
local array=map["layers"][1].data
--⽔平⽅向图块的个数
local width=map["layers"][1].width
--图块的宽和⾼
local blockx=tonumber(map["properties"]["blockx"])
local blocky=tonumber(map["properties"]["blocky"])
local j=0
for i=1,#array do
local x,y=calcXY(i,width)
if(array[i]~=array[i-1]) then
j=j+1
end
end
end