RetroAvatarsをHSPに移植する(3)
前回:RetroAvatarsをHSPに移植する(2)
だいたいできた。
- メイン処理は最後まで書いた。
- floodFillの勘違いⅡを修正。
- しっかりモジュール化。
- 入力部分はまだない。
途中経過(383行)
#define global W 12 #define global H 12 #define global PW 12 #define global PH 12 #define global EMPTY_COL 0 #define global SOLID_COL 255 #define global EYES_COL 1 #define global NOSE_COL 2 #define global MOUTH_COL 3 #define global WORK_COL 4 #define global MARGIN 30 #module retroAvatars // 画像の初期化 #deffunc init str name, local x, local y screen 0, 12*10+MARGIN*2, 12*10+MARGIN*2 titleStr = name size = strlen(titleStr) title titleStr code = 0 randomize(0) repeat 32 code = code + (peek(titleStr,cnt\size)*rnd(32768)\1024) loop randomize(code) col_r = rnd(32768)\192 + 64 col_g = rnd(32768)\192 + 64 col_b = rnd(32768)\192 + 64 dim g, 14, 14 for y, 0, 14, 1 for x, 0, 14, 1 g.y.x = -1 next next for y, 1, H+1, 1 for x, 1, W+1, 1 c = 158 if( rnd(32768)\356 > c ){ g.y.x = EMPTY_COL } else { g.y.x = SOLID_COL } next next return // 孤立したピクセルを除去 #deffunc removeNoise int type, local x, local y repeat 4 for y, 1, H+1, 1 for x, 1, W+1, 1 if( g.y.x == EMPTY_COL ){ x1 = x-1 : x2 = x+1 : y1 = y-1 : y2 = y+1 p = g.y1.x1 + g.y1.x + g.y1.x2 + g.y.x1 + g.y.x2 + g.y2.x1 + g.y2.x + g.y2.x2 if( ( type == 0 )&&( p >= SOLID_COL*8 ) ) : g.y.x = SOLID_COL if( ( type == 1 )&&( p >= SOLID_COL*7 ) ) : g.y.x = SOLID_COL if( ( g.y1.x == SOLID_COL )&&( g.y2.x == SOLID_COL ) ){ if( ( g.y.x1 != SOLID_COL )&&(g.y.x2 != SOLID_COL ) ){ if ( rnd(32768)\5 > 2 ) : g.y.x = SOLID_COL } } if( ( g.y1.x != SOLID_COL )&&( g.y2.x != SOLID_COL ) ){ if( ( g.y.x1 == SOLID_COL )&&( g.y.x2 == SOLID_COL ) ){ if ( rnd(32768)\5 > 2 ) : g.y.x = SOLID_COL } } } next next dim xt, 8 : dim yt, 8 xt = -1, 0, 1, -1, 1, -1, 0, 1 yt = -1, -1, -1, 0, 0, 1, 1, 1 for y, 1, H+1, 1 for x, 1, W+1, 1 if( g.y.x == SOLID_COL ){ p = 0 for i, 0, 8, 1 y0 = y+yt.i : x0 = x+xt.i p += g.y0.x0 next if( p <= 0 ) : g.y.x = EMPTY_COL } next next loop return //反転 #deffunc mirror local x, local y x_sym = 1 y_sym = 0 for y, 1, H+1, 1 for x, 1, W/2+1, 1 p = g.y.x if( x_sym == 1 ){ x0 = W-x+1 g.y.x0 = p } next next for y, 1, H/2+1, 1 for x, 1, W+1, 1 p = g.y.x if( y_sym == 1 ){ y0 = H-y+1 g.y0.x = p } next next return #defcfunc checkForFilledEdge local x, local y for y, 1, H+1, 1 if( ( EMPTY_COL < g.y.1 )&&( g.y.1 < SOLID_COL ) ) : return 1 if( ( EMPTY_COL < g.y.W )&&( g.y.W < SOLID_COL ) ) : return 1 next for x, 1, W+1, 1 if( ( EMPTY_COL < g.1.x )&&( g.1.x < SOLID_COL ) ) : return 2 if( ( EMPTY_COL < g.H.x )&&( g.H.x < SOLID_COL ) ) : return 2 next return 0 #deffunc outlineArea int col, local x, local y dim xt, 8 : dim yt, 8 xt = 0, 1, 0, -1, -1, 1, -1, 1 yt = -1, 0, 1, 0, -1, -1, 1, 1 for y, 1, H+1, 1 for x, 1, W+1, 1 if( g.y.x == col ){ for i, 0, 8, 1 y0 = y+yt.i : x0 = x+xt.i if( i < 4 ){ if( g.y0.x0 != col ) : g.y0.x0 = SOLID_COL } else { if( g.y0.x0 == EMPTY_COL ) : g.y0.x0 = SOLID_COL } next } next next return // 塗りつぶし #deffunc floodFill int startX, int startY, int col, local x, local y p = g.startY.startX g.startY.startX = col dim xt, 4 : dim yt, 4 xt = 0, 1, 0, -1 yt = -1, 0, 1, 0 for i, 0, 4, 1 x = startX + xt.i : y = startY + yt.i if( (1 <= x )&&( x <= W ) ){ if( ( 1 <= y )&&( y <= H ) ){ if( g.y.x == p ) : floodFill x, y, col } } next return #deffunc trimArea int col, int _w, int _h, local x, local y nx = -1 : ny = -1 for y, 1, H+1, 1 for x, 1, W/2+1, 1 if( col == EYES_COL ) : rx = x if( col > EYES_COL ) : rx = w/2 - x p = g.y.rx if( p == col ){ if( nx == -1 ) : nx = x if( ny == -1 ) : ny = y if( x >= nx + _w ) : g.y.rx = SOLID_COL if( y >= ny + _h ) : g.y.rx = SOLID_COL } next next return #deffunc enhanceFace local x, local y hx = W/2 eyes = 0 : nose = 0 : mouth = 0 for y, 2, H/2+1,1 x0 = hx-1 if( g.y.x0 == EMPTY_COL ){ floodFill x0, y, EYES_COL if( checkForFilledEdge() == 0 ) : _break floodFill x0, y, EMPTY_COL } x0 = hx-2 if( g.y.x0 == EMPTY_COL ){ floodFill x0, y, EYES_COL if( checkForFilledEdge() == 0 ) : _break floodFill x0, y, EMPTY_COL } next if( y == H/2+1 ){ for y, 2, H+1, 1 x0 = hx-1 if( g.y.x0 == SOLID_COL ){ if( g.y.hx == EMPTY_COL ){ g.y.x0 = EMPTY_COL g.y.hx = SOLID_COL y0 = y+1 g.y0.x0 = EMPTY_COL floodFill x0, y, EYES_COL if( checkForFilledEdge() == 0 ) : _break floodFill x0, y, EMPTY_COL } } next } ny = y + 1 if( y <= H ) : eyes = 1 if( eyes == 0 ){ y = 2 + rnd(32768)\(h/2) x0 = hx-1 g.y.x0 = EYES_COL outlineArea g, EYES_COL eyes = 1 ny = y + 1 } for y, 2, H+1, 1 if( g.y.hx == EYES_COL ){ x0 = hx-1 g.y.hx = SOLID_COL g.y.x0 = EYES_COL } else { x0 = hx-2 if( g.y.x0 == EYES_COL ) : g.y.hx = SOLID_COL x0 = hx-1 if( g.y.x0 == EYES_COL ) : g.y.hx = SOLID_COL } next mirror if( eyes == 1 ) : outlineArea 1 // 鼻 for y, ny, H+1, 1 if( g.y.hx == EMPTY_COL ){ floodFill hx, y, NOSE_COL if( checkForFilledEdge() == 0 ) : _break floodFill hx, y, EMPTY_COL } next if( y <= 10 ) : nose = 1 if( nose == 0 ){ for y, ny, H, 1 if( g.y.hx == EMPTY_COL ){ g.y.hx = NOSE_COL nose = 1 goto *skip } next for y, ny, H, 1 x0 = hx-1 if( g.y.x0 == EMPTY_COL ){ g.y.x0 = NOSE_COL g.y.hx = NOSE_COL nose = 1 goto *skip } next y = ny + 1 + rnd(32768)\(h/3) if( y >= H ) : y = H-1 g.y.hx = NOSE_COL nose = 1 ny = y + 1 goto *skip } ny = y + 1 //口 for y, ny, H+1, 1 if( g.y.hx == EMPTY_COL ){ floodFill hx, y, MOUTH_COL if( checkForFilledEdge() == 0 ) : _break floodFill hx, y, EMPTY_COL } next if( y <= H ) : mouth = 1 if( mouth == 0 ){ for y, ny, H, 1 x0 = hx-1 if( g.y.x0 == EMPTY_COL ){ g.y.hx = EMPTY_COL floodFill hx, y, MOUTH_COL if( checkForFilledEdge() == 0 ) : _break floodFill hx, y, EMPTY_COL } next } if( y <= H ) : mouth = 1 *skip if( mouth == 1 ) : outlineArea MOUTH_COL if( nose == 1 ) : outlineArea NOSE_COL if( eyes == 1 ) : trimArea EYES_COL, 3, 3 if( nose == 1 && mouth == 1 ) : trimArea NOSE_COL, 3, 3 mirror for y, 2, H, 1 for x, 2, W, 1 if( g.y.x == EMPTY_COL ){ floodFill x, y, WORK_COL c = checkForFilledEdge() if( c != 0 ){ floodFill x, y, EMPTY_COL } else { floodFill x, y, SOLID_COL } } next next return //画像を表示 #deffunc draw local x, local y mirror color : boxf for y, 1, H+1, 1 for x, 1, W+1, 1 if( g.y.x == SOLID_COL ){ color col_r, col_g, col_b } else { color 0, 0, 0 } boxf MARGIN+(x-1)*10, MARGIN+(y-1)*10, MARGIN+(x-1)*10+10, MARGIN+(y-1)*10+10 next next return // 画像を生成(メイン) #deffunc createGraph local x, local y init "TANINI" removeNoise 0 enhanceFace draw return #global createGraph