-- gen_all.lua : draws EVERY pixel asset for 蜜糖村 from scratch (Aseprite Lua API). -- No external art, no imported palettes. Run: aseprite -b --script-param outdir=... --script gen_all.lua local outdir = app.params["outdir"] if not outdir then error("need --script-param outdir=") end local function pack(t) return app.pixelColor.rgba(t[1], t[2], t[3], t[4] or 255) end local function px(img,x,y,c) if x>=0 and y>=0 and x tileset.png ============ do local s, img = newImg(128,144) local function grassBase(ox,oy) rect(img,ox,oy,16,16,P.grass1); speck(img,ox,oy,16,16,P.grass2,5,0); speck(img,ox,oy,16,16,P.grass3,7,2) end local T = {} T[0]=function(ox,oy) grassBase(ox,oy) end T[1]=function(ox,oy) grassBase(ox,oy); px(img,ox+4,oy+5,P.yellow2); px(img,ox+11,oy+10,P.pink1); px(img,ox+8,oy+13,P.pink1) end T[2]=function(ox,oy) rect(img,ox,oy,16,16,P.path1); speck(img,ox,oy,16,16,P.path2,6,1); speck(img,ox,oy,16,16,P.path3,9,3); hline(img,ox,oy,16,P.path2); vline(img,ox,oy,16,P.path2) end T[3]=function(ox,oy) grassBase(ox,oy); rect(img,ox+4,oy,8,16,P.path1); speck(img,ox+4,oy,8,16,P.path2,6,1) end T[4]=function(ox,oy) rect(img,ox,oy,16,16,P.water1); speck(img,ox,oy,16,16,P.water2,5,0); hline(img,ox+2,oy+4,5,P.foam); hline(img,ox+9,oy+10,4,P.foam) end T[5]=function(ox,oy) rect(img,ox,oy,16,16,P.water1); speck(img,ox,oy,16,16,P.water3,7,2); hline(img,ox+1,oy+2,14,P.foam); hline(img,ox+3,oy+8,10,P.water2) end T[6]=function(ox,oy) grassBase(ox,oy); rect(img,ox+2,oy+6,12,8,P.canopy2); speck(img,ox+2,oy+6,12,8,P.canopy1,4,0); px(img,ox+4,oy+7,P.pink1); px(img,ox+9,oy+8,P.yellow2); px(img,ox+7,oy+11,P.pink2); px(img,ox+12,oy+11,P.pink1) end T[7]=function(ox,oy) grassBase(ox,oy); rect(img,ox+2,oy+5,12,9,P.canopy2); speck(img,ox+2,oy+5,12,9,P.canopy1,3,0); for _,p in ipairs({{5,7},{9,7},{6,10},{11,9},{8,12}}) do px(img,ox+p[1],oy+p[2],P.red1); px(img,ox+p[1],oy+p[2]-1,P.red2) end end T[8]=function(ox,oy) rect(img,ox+2,oy+1,12,12,P.canopy2); rect(img,ox+3,oy,10,2,P.canopy2); rect(img,ox+1,oy+3,14,8,P.canopy2); speck(img,ox,oy,16,14,P.canopy1,4,0); speck(img,ox,oy,16,14,P.canopy3,6,3) end T[9]=function(ox,oy) grassBase(ox,oy); rect(img,ox+6,oy+2,4,13,P.trunk); vline(img,ox+6,oy+2,13,P.trunkD); px(img,ox+7,oy+7,P.trunkD) end T[10]=function(ox,oy) rect(img,ox,oy,16,16,P.wall1); speck(img,ox,oy,16,16,P.wall2,7,2); hline(img,ox,oy+8,16,P.wallD); for i=0,3 do vline(img,ox+i*4+2,oy,8,P.wallD) end; for i=0,3 do vline(img,ox+i*4,oy+8,8,P.wallD) end end T[11]=function(ox,oy) rect(img,ox,oy,16,16,P.roof1); for j=0,15 do hline(img,ox,oy+j,16,(j%3==0) and P.roof2 or P.roof1) end; speck(img,ox,oy,16,16,P.roof3,8,4) end T[12]=function(ox,oy) rect(img,ox,oy,16,16,P.wall2); rect(img,ox+3,oy+2,10,14,P.door1); rect(img,ox+4,oy+3,8,13,P.door2); px(img,ox+10,oy+9,P.knob) end T[13]=function(ox,oy) grassBase(ox,oy); rect(img,ox+1,oy+4,2,10,P.wood2); rect(img,ox+7,oy+4,2,10,P.wood2); rect(img,ox+13,oy+4,2,10,P.wood2); hline(img,ox,oy+6,16,P.wood1); hline(img,ox,oy+10,16,P.wood1) end T[14]=function(ox,oy) rect(img,ox,oy,16,16,P.soilD); rect(img,ox+1,oy+1,14,14,P.soil); for _,p in ipairs({{3,3},{8,4},{12,6},{5,9},{10,11},{3,12}}) do px(img,ox+p[1],oy+p[2],P.pink1); px(img,ox+p[1]+1,oy+p[2],P.pink2); px(img,ox+p[1],oy+p[2]-1,P.yellow2) end end T[15]=function(ox,oy) grassBase(ox,oy); rect(img,ox+2,oy+4,12,11,P.path2); rect(img,ox+3,oy+5,10,9,P.path1); rect(img,ox+5,oy+7,6,6,P.black); rect(img,ox+5,oy+7,6,3,P.waterDeep); vline(img,ox+2,oy+1,5,P.wood2); vline(img,ox+13,oy+1,5,P.wood2); hline(img,ox+2,oy+1,12,P.wood1) end T[16]=function(ox,oy) rect(img,ox,oy,16,16,{225,228,232,235}); speck(img,ox,oy,16,16,{240,242,245,255},4,0); speck(img,ox,oy,16,16,{205,210,216,220},5,2) end T[17]=function(ox,oy) rect(img,ox+1,oy+2,14,11,P.wood2); rect(img,ox+2,oy+3,12,9,P.paper); px(img,ox+4,oy+5,P.ink); px(img,ox+6,oy+5,P.ink); px(img,ox+8,oy+5,P.ink); hline(img,ox+4,oy+7,7,P.ink); hline(img,ox+4,oy+9,5,P.ink); rect(img,ox+2,oy+13,2,3,P.wood1); rect(img,ox+12,oy+13,2,3,P.wood1) end T[18]=function(ox,oy) grassBase(ox,oy); rect(img,ox+7,oy+6,2,9,P.wood2); rect(img,ox+4,oy+2,8,6,P.red1); rect(img,ox+4,oy+2,8,2,P.red2); hline(img,ox+5,oy+5,6,P.black); rect(img,ox+11,oy+1,1,4,P.red2) end T[19]=function(ox,oy) grassBase(ox,oy); for j=0,9 do for i=0,13 do local red=((i//2)+(j//2))%2==0; px(img,ox+1+i,oy+3+j, red and P.red1 or P.clothW) end end end T[20]=function(ox,oy) grassBase(ox,oy); rect(img,ox+1,oy+7,14,3,P.wood1); rect(img,ox+1,oy+4,14,2,P.wood2); vline(img,ox+2,oy+9,5,P.wood2); vline(img,ox+13,oy+9,5,P.wood2) end T[21]=function(ox,oy) grassBase(ox,oy); rect(img,ox+7,oy+4,2,11,P.metalD); rect(img,ox+5,oy+1,6,4,P.yellow3); rect(img,ox+6,oy+2,4,2,P.yellow2) end T[22]=function(ox,oy) grassBase(ox,oy); rect(img,ox+4,oy+8,8,6,P.canopy2); speck(img,ox+4,oy+8,8,6,P.canopy1,3,0) end T[23]=function(ox,oy) rect(img,ox,oy,16,16,P.wall1); speck(img,ox,oy,16,16,P.wall2,4,1); speck(img,ox,oy,16,16,P.wallD,9,3) end T[24]=function(ox,oy) rect(img,ox,oy,16,16,P.ifloor1); for j=0,3 do hline(img,ox,oy+j*4,16,P.ifloor2) end; speck(img,ox,oy,16,16,P.ifloor2,11,4) end T[25]=function(ox,oy) rect(img,ox,oy,16,16,P.ifloor1); for i=0,3 do vline(img,ox+i*4,oy,16,P.ifloor2) end end T[26]=function(ox,oy) rect(img,ox,oy,16,16,P.iwall1); speck(img,ox,oy,16,16,P.iwall2,7,3); hline(img,ox,oy,16,P.iwall2) end T[27]=function(ox,oy) rect(img,ox,oy,16,16,P.iwall1); rect(img,ox,oy,16,5,P.iwallTrim); hline(img,ox,oy+5,16,P.iwall2) end T[28]=function(ox,oy) rect(img,ox,oy,16,16,P.wood2); rect(img,ox+1,oy+4,14,11,P.pink1); rect(img,ox+1,oy+4,14,4,P.clothW); rect(img,ox+2,oy+4,5,3,P.clothW); hline(img,ox+1,oy+9,14,P.pinkD) end T[29]=function(ox,oy) rect(img,ox,oy,16,16,P.iwall1); rect(img,ox+3,oy+2,10,12,P.paper); hline(img,ox+3,oy+2,10,P.red1); px(img,ox+5,oy+6,P.ink); px(img,ox+7,oy+6,P.ink); px(img,ox+9,oy+6,P.ink); hline(img,ox+5,oy+9,6,P.ink); px(img,ox+7,oy+11,P.red2); px(img,ox+8,oy+11,P.red2) end T[30]=function(ox,oy) rect(img,ox,oy+3,16,12,P.wood2); rect(img,ox,oy+3,16,3,P.wood3); hline(img,ox,oy+9,16,P.wood1); rect(img,ox+2,oy+11,3,3,P.wood1); rect(img,ox+11,oy+11,3,3,P.wood1) end T[31]=function(ox,oy) rect(img,ox,oy+1,16,14,P.metalD); rect(img,ox+2,oy+3,12,8,P.black); rect(img,ox+3,oy+7,10,4,P.orange1); rect(img,ox+4,oy+8,8,2,P.yellow2); hline(img,ox+2,oy+2,12,P.metal); px(img,ox+11,oy+4,P.red1) end T[32]=function(ox,oy) rect(img,ox,oy,16,16,P.wood1); rect(img,ox+2,oy+2,12,12,P.paper); hline(img,ox+4,oy+5,8,P.ink); hline(img,ox+4,oy+7,8,P.ink); hline(img,ox+4,oy+9,5,P.ink); px(img,ox+12,oy+11,P.red1) end T[33]=function(ox,oy) rect(img,ox,oy,16,16,P.wood2); hline(img,ox,oy+5,16,P.wood1); hline(img,ox,oy+10,16,P.wood1); rect(img,ox+2,oy+1,3,3,P.orange1); rect(img,ox+7,oy+1,3,3,P.red1); rect(img,ox+11,oy+1,3,3,P.sky); rect(img,ox+2,oy+6,3,3,P.pink1); rect(img,ox+7,oy+6,3,3,P.yellow2) end T[34]=function(ox,oy) rect(img,ox,oy,16,16,P.wood2); hline(img,ox,oy+8,16,P.wood1); rect(img,ox+3,oy+2,4,5,P.orange1); rect(img,ox+3,oy+2,4,2,P.orange2); rect(img,ox+9,oy+2,4,5,P.orange1); rect(img,ox+9,oy+2,4,2,P.orange2); rect(img,ox+3,oy+10,4,5,P.orange1); rect(img,ox+9,oy+10,4,5,P.orange1) end T[35]=function(ox,oy) rect(img,ox+1,oy+4,14,4,P.wood3); rect(img,ox+1,oy+4,14,2,P.wood1); vline(img,ox+2,oy+8,6,P.wood2); vline(img,ox+13,oy+8,6,P.wood2) end T[36]=function(ox,oy) rect(img,ox+4,oy+2,8,3,P.wood2); rect(img,ox+4,oy+7,8,3,P.wood3); vline(img,ox+4,oy+5,2,P.wood2); vline(img,ox+5,oy+10,4,P.wood2); vline(img,ox+10,oy+10,4,P.wood2) end T[37]=function(ox,oy) rect(img,ox+1,oy+5,14,4,P.wood3); rect(img,ox+3,oy,10,7,P.paper); hline(img,ox+3,oy,10,P.water3); hline(img,ox+4,oy+2,8,P.ink); hline(img,ox+4,oy+4,5,P.ink); rect(img,ox+9,oy+1,4,3,P.wood3) end T[38]=function(ox,oy) rect(img,ox,oy,16,16,P.iwall1); rect(img,ox+2,oy+2,12,10,P.glass); rect(img,ox+2,oy+2,12,4,P.sky); vline(img,ox+8,oy+2,10,P.iwall2); hline(img,ox+2,oy+7,12,P.iwall2); rect(img,ox+1,oy+1,14,1,P.iwallTrim) end T[39]=function(ox,oy) rect(img,ox,oy,16,16,P.iwall1); rect(img,ox+3,oy+2,10,14,P.door1); rect(img,ox+4,oy+3,8,13,P.door2); px(img,ox+10,oy+9,P.knob) end T[40]=function(ox,oy) rect(img,ox,oy,16,16,P.wwall); speck(img,ox,oy,16,16,P.wwallD,9,4); hline(img,ox,oy+11,16,P.wwallD) end T[41]=function(ox,oy) rect(img,ox,oy,16,16,P.wfloor); hline(img,ox,oy,16,P.wline); vline(img,ox,oy,16,P.wline); speck(img,ox,oy,16,16,P.wfloorL,13,3) end T[42]=function(ox,oy) rect(img,ox,oy,16,16,P.wfloorL); hline(img,ox+8,oy,8,P.wline); vline(img,ox,oy+8,8,P.wline) end T[43]=function(ox,oy) rect(img,ox,oy,16,16,P.wfloor); rect(img,ox+1,oy+3,14,11,P.wbed); rect(img,ox+1,oy+3,14,3,P.wdark); hline(img,ox+1,oy+9,14,P.wline); rect(img,ox,oy+2,2,13,P.metal); rect(img,ox+14,oy+2,2,13,P.metal) end T[44]=function(ox,oy) rect(img,ox,oy,16,16,P.wwall); rect(img,ox+3,oy+1,10,15,P.wfloorL); rect(img,ox+4,oy+2,8,14,P.wfloor); px(img,ox+10,oy+9,P.metalD) end T[45]=function(ox,oy) rect(img,ox,oy,16,16,P.wwall); rect(img,ox+2,oy+2,12,10,{212,224,230}); vline(img,ox+8,oy+2,10,P.wdark); hline(img,ox+2,oy+7,12,P.wdark) end T[46]=function(ox,oy) for i=0,15 do local j=math.floor(2*math.sin(i*0.9)+6); px(img,ox+i,oy+j,P.pink2); px(img,ox+i,oy+j+1,P.pink1) end; px(img,ox+3,oy+3,P.yellow2); px(img,ox+11,oy+9,P.sky) end T[47]=function(ox,oy) rect(img,ox,oy+6,16,10,P.wood2); rect(img,ox,oy+6,16,2,P.wood3); rect(img,ox+2,oy,12,6,P.red1); for i=0,3 do px(img,ox+2+i*4,oy+5,P.yellow2) end end T[48]=function(ox,oy) grassBase(ox,oy); for _,p in ipairs({{4,6},{9,4},{11,10},{6,11}}) do px(img,ox+p[1],oy+p[2],P.red1); px(img,ox+p[1]+1,oy+p[2],P.red2); px(img,ox+p[1],oy+p[2]+1,P.yellow2) end end T[49]=function(ox,oy) grassBase(ox,oy); for _,p in ipairs({{5,5},{10,7},{7,11},{12,12}}) do px(img,ox+p[1],oy+p[2],P.sky); px(img,ox+p[1]+1,oy+p[2],P.water2); px(img,ox+p[1],oy+p[2]+1,P.yellow2) end end T[50]=function(ox,oy) grassBase(ox,oy); rect(img,ox+6,oy+9,3,4,P.wall1); rect(img,ox+4,oy+6,7,4,P.red1); px(img,ox+5,oy+7,P.yellow3); px(img,ox+8,oy+8,P.yellow3) end T[51]=function(ox,oy) grassBase(ox,oy); rect(img,ox+3,oy+7,10,6,P.gray); rect(img,ox+3,oy+7,10,2,{150,150,154}); px(img,ox+5,oy+10,P.metalD) end T[52]=function(ox,oy) grassBase(ox,oy); rect(img,ox+4,oy+7,8,6,P.trunk); rect(img,ox+5,oy+6,6,2,P.wood3); px(img,ox+7,oy+7,P.trunkD); px(img,ox+8,oy+7,P.trunkD) end T[53]=function(ox,oy) rect(img,ox,oy,16,16,P.water1); speck(img,ox,oy,16,16,P.water2,5,0); rect(img,ox+4,oy+5,8,6,P.canopy1); px(img,ox+7,oy+7,P.pink1); px(img,ox+8,oy+7,P.pink2) end T[54]=function(ox,oy) rect(img,ox,oy,16,16,P.water1); speck(img,ox,oy,16,16,P.water2,5,0); vline(img,ox+5,oy+2,10,P.canopy2); vline(img,ox+9,oy+1,11,P.canopy2); rect(img,ox+4,oy+1,3,3,P.trunk); rect(img,ox+8,oy,3,3,P.trunk) end T[55]=function(ox,oy) rect(img,ox+4,oy+4,8,10,P.orange1); rect(img,ox+4,oy+4,8,3,P.orange2); rect(img,ox+5,oy+1,6,3,P.wood2); rect(img,ox+6,oy+8,4,4,P.yellow2) end T[56]=function(ox,oy) rect(img,ox+1,oy+2,14,13,P.wood2); rect(img,ox+2,oy+3,12,11,P.wood1); vline(img,ox+8,oy+3,11,P.wood2); hline(img,ox+2,oy+8,12,P.wood2) end T[57]=function(ox,oy) rect(img,ox+3,oy+1,10,14,P.wood1); rect(img,ox+3,oy+1,10,2,P.wood2); hline(img,ox+3,oy+5,10,P.wood2); hline(img,ox+3,oy+10,10,P.wood2); vline(img,ox+7,oy+1,14,P.wood3) end T[58]=function(ox,oy) rect(img,ox,oy,16,16,P.wood2); hline(img,ox,oy+8,16,P.wood1); for i=0,4 do vline(img,ox+1+i*3,oy+1,6,({P.red1,P.sky,P.canopy1,P.orange1,P.pink2})[i+1]) end; for i=0,4 do vline(img,ox+1+i*3,oy+9,6,({P.canopy1,P.pink2,P.red1,P.sky,P.yellow2})[i+1]) end end T[59]=function(ox,oy) rect(img,ox,oy,16,16,P.iwall1); rect(img,ox+4,oy+3,8,8,P.wall1); rect(img,ox+5,oy+4,6,6,P.paper); vline(img,ox+8,oy+5,3,P.ink); hline(img,ox+8,oy+7,3,P.ink) end T[60]=function(ox,oy) rect(img,ox,oy,16,16,P.iwall1); rect(img,ox+2,oy+2,12,10,P.wood2); rect(img,ox+3,oy+3,10,8,P.sky); rect(img,ox+3,oy+8,10,3,P.canopy1); px(img,ox+10,oy+5,P.yellow3) end T[61]=function(ox,oy) rect(img,ox+5,oy+10,6,5,P.orange2); rect(img,ox+4,oy+9,8,2,P.orange1); rect(img,ox+5,oy+4,6,6,P.canopy2); speck(img,ox+5,oy+4,6,6,P.canopy1,3,0) end T[62]=function(ox,oy) rect(img,ox,oy,16,16,P.ifloor1); rect(img,ox+2,oy+3,12,10,P.pink2); rect(img,ox+4,oy+5,8,6,P.pink1); px(img,ox+7,oy+7,P.yellow2); px(img,ox+8,oy+8,P.yellow2) end T[63]=function(ox,oy) rect(img,ox,oy,16,16,P.grass2); speck(img,ox,oy,16,16,P.canopy2,5,0); speck(img,ox,oy,16,16,P.grass1,7,2) end T[64]=function(ox,oy) grassBase(ox,oy); px(img,ox+3,oy+3,P.orange1); px(img,ox+7,oy+6,P.pink2); px(img,ox+12,oy+4,P.yellow2); px(img,ox+9,oy+12,P.red1); px(img,ox+4,oy+11,P.sky) end T[65]=function(ox,oy) rect(img,ox,oy,16,16,P.waterDeep); speck(img,ox,oy,16,16,P.water3,5,0); hline(img,ox+3,oy+6,8,P.water2) end T[66]=function(ox,oy) rect(img,ox,oy,16,16,P.path1); speck(img,ox,oy,16,16,P.path2,6,1); rect(img,ox,oy,6,6,P.grass1); speck(img,ox,oy,6,6,P.grass2,4,0) end T[67]=function(ox,oy) rect(img,ox,oy,16,16,P.roof1); rect(img,ox,oy+11,16,5,P.roof2); hline(img,ox,oy+11,16,P.wall1); speck(img,ox,oy,16,11,P.roof3,8,4) end T[68]=function(ox,oy) rect(img,ox,oy,16,16,P.wall1); speck(img,ox,oy,16,16,P.wall2,7,2); rect(img,ox+3,oy+3,10,9,P.glass); rect(img,ox+3,oy+3,10,4,P.sky); vline(img,ox+8,oy+3,9,P.wallD); hline(img,ox+3,oy+7,10,P.wallD); rect(img,ox+2,oy+2,12,1,P.wallD) end T[69]=function(ox,oy) rect(img,ox,oy,16,16,P.sky); rect(img,ox+7,oy+4,3,3,P.yellow2); px(img,ox+8,oy+3,P.yellow3); px(img,ox+8,oy+8,P.yellow3); px(img,ox+4,oy+6,P.yellow3); px(img,ox+12,oy+6,P.yellow3) end T[70]=function(ox,oy) grassBase(ox,oy); vline(img,ox+7,oy+8,5,P.canopy2); rect(img,ox+6,oy+5,4,4,P.clothW); px(img,ox+7,oy+6,P.yellow2) end T[71]=function(ox,oy) rect(img,ox,oy,16,16,P.path2); for j=0,3 do for i=0,3 do local c=((i+j)%2==0) and P.path1 or P.path3; rect(img,ox+i*4,oy+j*4,4,4,c) end end end for idx=0,71 do T[idx]((idx%8)*16,(idx//8)*16) end save(s,"tileset.png"); s:close(); print("tileset done") end -- ============ PLAYER walk sheet 64x96 (4 dir x 4 frame) ============ do local skin=P.skin; local skinD=P.skinD; local hair=P.hair local shirt={92,152,212}; local shirtD={64,116,176} local pants={78,96,128}; local pantsD={56,72,102}; local shoe={70,58,58} local s, img = newImg(64,96) local function person(ox,oy,dir,frame) local sw=0; if frame==1 then sw=1 elseif frame==3 then sw=-1 end rect(img,ox+5,oy+10,6,7,shirt); hline(img,ox+5,oy+10,6,shirtD); vline(img,ox+5,oy+10,7,shirtD) vline(img,ox+4,oy+11,4,skin); vline(img,ox+11,oy+11,4,skin) rect(img,ox+5,oy+3,6,6,skin); hline(img,ox+5,oy+8,6,skinD) rect(img,ox+4,oy+1,8,3,hair); px(img,ox+4,oy+4,hair); px(img,ox+11,oy+4,hair) local lx,rx=ox+6,ox+9 if dir==0 then px(img,ox+6,oy+5,P.black); px(img,ox+9,oy+5,P.black); px(img,ox+7,oy+7,skinD) rect(img,lx,oy+17,2,4,pants); rect(img,rx,oy+17,2,4,pants) rect(img,lx,oy+21+(sw>0 and 1 or 0),2,1,shoe); rect(img,rx,oy+21+(sw<0 and 1 or 0),2,1,shoe) elseif dir==3 then rect(img,ox+4,oy+1,8,5,hair) rect(img,lx,oy+17,2,4,pants); rect(img,rx,oy+17,2,4,pants) rect(img,lx,oy+21+(sw>0 and 1 or 0),2,1,shoe); rect(img,rx,oy+21+(sw<0 and 1 or 0),2,1,shoe) else px(img,ox+9,oy+5,P.black); px(img,ox+11,oy+6,skinD); rect(img,ox+4,oy+1,7,3,hair) rect(img,ox+6+sw,oy+17,2,4,pants); rect(img,ox+8-sw,oy+17,2,4,pantsD) rect(img,ox+6+sw,oy+21,2,1,shoe); rect(img,ox+8-sw,oy+21,2,1,shoe) end end for f=0,3 do person(f*16,0,0,f); person(f*16,72,3,f); person(f*16,48,2,f) end for f=0,3 do for yy=0,23 do for xx=0,15 do img:drawPixel(f*16+(15-xx), 24+yy, img:getPixel(f*16+xx, 48+yy)) end end end save(s,"player.png"); s:close(); print("player done") end -- ============ PLAYER PORTRAITS 64x32 (smile / real face) ============ do local s, img = newImg(64,32) local function drawPortrait(ox,tired) local sk = tired and {216,199,185} or P.skin local skd = tired and {186,170,158} or P.skinD local hr = tired and {104,98,92} or P.hair rect(img,ox+8,4,16,20,sk) rect(img,ox+7,3,18,7,hr); px(img,ox+7,10,hr); px(img,ox+24,10,hr) if tired then rect(img,ox+11,13,2,2,P.black); rect(img,ox+19,13,2,2,P.black) hline(img,ox+10,16,4,skd); hline(img,ox+18,16,4,skd) hline(img,ox+13,20,6,skd); px(img,ox+12,21,skd); px(img,ox+19,21,skd) else rect(img,ox+11,12,2,3,P.black); rect(img,ox+19,12,2,3,P.black); px(img,ox+12,12,P.glass) px(img,ox+12,19,skd); hline(img,ox+13,20,6,skd); px(img,ox+19,19,skd) px(img,ox+14,13,{255,150,160}); px(img,ox+18,13,{255,150,160}) end rect(img,ox+15,16,2,2,skd) end drawPortrait(0,false); drawPortrait(32,true) save(s,"portraits.png"); s:close(); print("portraits done") end -- ============ NPCS 48x24 (smile/flat/off) ============ local function drawAnimal(img, ox, expr, spec) local body=spec.body; local bodyD=spec.bodyD; local muzzle=spec.muzzle or {250,244,232} -- torso rect(img,ox+3,9,10,12,body); rect(img,ox+3,9,10,2,bodyD) rect(img,ox+5,13,6,7,muzzle) -- belly -- feet rect(img,ox+4,21,3,2,bodyD); rect(img,ox+9,21,3,2,bodyD) -- head rect(img,ox+4,2,8,8,body) rect(img,ox+5,5,6,5,muzzle) -- face patch -- ears if spec.ears=="floppy" then rect(img,ox+2,3,2,5,bodyD); rect(img,ox+12,3,2,5,bodyD) elseif spec.ears=="long" then rect(img,ox+4,-0+0,2,4,body); rect(img,ox+10,0,2,4,body); px(img,ox+4,1,P.pink1); px(img,ox+10,1,P.pink1) rect(img,ox+4,0,2,3,body); rect(img,ox+10,0,2,3,body) elseif spec.ears=="round" then rect(img,ox+3,1,3,3,body); rect(img,ox+10,1,3,3,body); px(img,ox+4,2,bodyD); px(img,ox+11,2,bodyD) elseif spec.ears=="pointy" then px(img,ox+4,1,body); rect(img,ox+3,2,3,2,body); px(img,ox+11,1,body); rect(img,ox+10,2,3,2,body); px(img,ox+4,2,P.pink1); px(img,ox+11,2,P.pink1) elseif spec.ears=="antler" then px(img,ox+4,0,P.wood2); px(img,ox+4,1,P.wood2); px(img,ox+3,0,P.wood2); px(img,ox+11,0,P.wood2); px(img,ox+11,1,P.wood2); px(img,ox+12,0,P.wood2) end -- eyes (base y=6). off lowers RIGHT eye by 1px. local ey=6 px(img,ox+6,ey,P.black) px(img,ox+9, expr=="off" and ey+1 or ey, P.black) -- nose px(img,ox+7,8,bodyD); px(img,ox+8,8,bodyD) -- mouth: smile curve / flat line / off = smile + 1px corner if expr=="flat" then hline(img,ox+6,10,4,bodyD) else px(img,ox+5,9,bodyD); hline(img,ox+6,10,4,bodyD); px(img,ox+10,9,bodyD) if expr=="off" then px(img,ox+11,9,bodyD) end -- 1px extra corner end -- extras if spec.whiskers then hline(img,ox+1,7,3,P.gray); hline(img,ox+12,7,3,P.gray) end if spec.glasses then rect(img,ox+5,5,3,3,P.metal); rect(img,ox+8,5,3,3,P.metal); px(img,ox+6,6,P.glass); px(img,ox+9, expr=="off" and 7 or 6,P.glass) end if spec.shell then rect(img,ox+3,10,10,9,{86,140,80}); rect(img,ox+5,12,6,5,{110,168,100}); px(img,ox+7,14,{70,116,66}); px(img,ox+8,15,{70,116,66}); rect(img,ox+5,13,6,7,muzzle,{}); rect(img,ox+3,10,10,9,{86,140,80}); px(img,ox+6,13,{70,116,66}); px(img,ox+9,16,{70,116,66}) end if spec.coat then rect(img,ox+3,11,10,10,P.clothW); rect(img,ox+3,11,10,2,{230,230,236}); rect(img,ox+7,13,2,7,P.red1); rect(img,ox+6,15,4,2,P.red1); rect(img,ox+4,20,3,1,bodyD); rect(img,ox+9,20,3,1,bodyD) end if spec.head then rect(img,ox+4,0,8,3,spec.head) end end do local specs = { afu ={body={168,120,72}, bodyD={128,90,52}, ears="floppy"}, -- 狗 村长 yuan ={body={244,236,222}, bodyD={206,196,180}, ears="long"}, -- 兔 面包师 dabao ={body={128,90,60}, bodyD={98,68,44}, ears="round"}, -- 熊 邮差 mimi ={body={236,152,80}, bodyD={200,120,56}, ears="pointy", whiskers=true}, -- 猫 杂货 fu ={body={216,176,124}, bodyD={176,138,92}, ears="antler", coat=true}, -- 鹿 医生 gui ={body={120,180,110}, bodyD={90,140,84}, ears=nil, shell=true, glasses=true}, -- 龟 老者 afu2 =nil, } local order = {"afu","yuan","dabao","mimi","fu","gui"} for _,name in ipairs(order) do local s, img = newImg(48,24) local exprs = {"smile","flat","off"} for i,e in ipairs(exprs) do drawAnimal(img,(i-1)*16,e,specs[name]) end save(s,"npc_"..name..".png"); s:close() end print("npcs done") end -- ============ TWIN BIRDS 32x24 (beak closed / open) ============ do local s, img = newImg(32,24) local function drawBird(ox,open) local body={110,170,220}; local bodyD={78,132,186} rect(img,ox+4,6,8,10,body); rect(img,ox+4,6,8,2,{150,200,240}) rect(img,ox+3,9,3,5,bodyD) -- wing rect(img,ox+5,3,6,5,body) -- head px(img,ox+7,5,P.black); px(img,ox+8,5,P.black) -- eyes -- beak if open then px(img,ox+11,6,P.orange2); px(img,ox+12,6,P.orange2); px(img,ox+11,8,P.orange2); px(img,ox+12,8,P.orange2); px(img,ox+13,7,P.orange1) else px(img,ox+11,7,P.orange2); px(img,ox+12,7,P.orange2); px(img,ox+13,7,P.orange1) end -- feet px(img,ox+6,16,P.orange2); px(img,ox+9,16,P.orange2) -- little tuft px(img,ox+7,2,bodyD); px(img,ox+8,2,body) end drawBird(0,false); drawBird(16,true) save(s,"birds.png"); s:close(); print("birds done") end -- ============ EXTRAS (群演) 32x80 = 5 critters x 2 frames, 16x16 ============ do local s, img = newImg(32,80) local function critter(ox,oy,f,spec) local bob = (f==1) and 1 or 0 local b=spec.body; local bd=spec.bodyD rect(img,ox+4,oy+7+bob,8,6,b); rect(img,ox+4,oy+7+bob,8,2,bd) -- body rect(img,ox+5,oy+3+bob,6,5,b) -- head px(img,ox+6,oy+5+bob,P.black); px(img,ox+9,oy+5+bob,P.black) if spec.tail=="bushy" then rect(img,ox+11,oy+4+bob,3,7,b); rect(img,ox+12,oy+3+bob,2,3,bd) end if spec.tail=="thin" then vline(img,ox+12,oy+9+bob,3,bd) end if spec.spikes then for i=0,4 do px(img,ox+4+i*2,oy+6+bob,bd); px(img,ox+5+i*2,oy+8+bob,bd) end end if spec.ears=="mouse" then px(img,ox+5,oy+2+bob,b); px(img,ox+10,oy+2+bob,b); rect(img,ox+4,oy+2+bob,2,2,b); rect(img,ox+10,oy+2+bob,2,2,b) end if spec.ears=="pointy" then px(img,ox+5,oy+2+bob,b); px(img,ox+10,oy+2+bob,b) end rect(img,ox+5,oy+13+bob,2,2,bd); rect(img,ox+9,oy+13+bob,2,2,bd) -- feet end local specs = { {body={214,142,72}, bodyD={176,108,52}, tail="bushy", ears="pointy"}, -- squirrel {body={150,120,90}, bodyD={110,86,64}, spikes=true, ears="pointy"}, -- hedgehog {body={200,160,100}, bodyD={160,120,70}, tail="bushy", ears="pointy"}, -- squirrel2 {body={188,190,196}, bodyD={150,152,158},tail="thin", ears="mouse"}, -- mouse {body={230,200,120}, bodyD={196,164,90}, tail="thin", ears="pointy"}, -- chipmunk } for k=0,4 do critter(0,k*16,0,specs[k+1]); critter(16,k*16,1,specs[k+1]) end save(s,"extras.png"); s:close(); print("extras done") end -- ============ SPARROW (E3 real bird) 16x16 gray ============ do local s, img = newImg(16,16) local g1={128,124,118}; local g2={98,94,90}; local g3={160,156,150}; local beak={90,80,60} rect(img,4,6,8,6,g1); rect(img,4,6,8,2,g3) rect(img,3,8,3,4,g2) -- wing rect(img,10,4,4,4,g1) -- head px(img,12,5,P.black); px(img,13,6,beak); px(img,14,6,beak) px(img,5,12,beak); px(img,8,12,beak) -- feet speck(img,4,6,8,6,g2,3,0) save(s,"sparrow.png"); s:close(); print("sparrow done") end print("ALL ASSETS DONE")