More ... | シンプルなアナログ時計SSシンプルなアナログ時計SS
; シンプルなアナログ時計スクリーンセーバー for HSP 3.0β7 or later ; ; HISTORY ; Shark++ ; 2005-04-16 HSPのβ版を試したくなり、 ; アナログ時計スクリーンセーバーを作り始める ; 2005-04-17 アナログ時計部分は完成 ; 2005-04-21 針の形を変更 ; ※HSPwikiからDL #include "typeutil.as" ; ddim #include "math.as" ; deg2rad #module #uselib "gdi32.dll" ; #func PolyPolygon "PolyPolygon" int, int, var, int #func PolyPolygon "PolyPolygon" int, var, var, int #func CreatePen "CreatePen" int, int, int #func CreateSolidBrush "CreateSolidBrush" int #func SelectObject "SelectObject" int, int #func DeleteObject "DeleteObject" int #func GetStockObject "GetStockObject" int #define PS_SOLID 0 #define NULL_BRUSH 5 #deffunc porygon array ptpos, int count, int border_color, int fill_color ; porygon ptpos, count, border_color, fill_color ; 指定された描画頂点位置・線の色・背景色で多角形を描きます ; ptpos = 描画頂点位置 ; ※メモリ上では、X,Y の順に並んでいなければならない ; dim ptpos,4,2 ではダメで、dim ptpos,2,4 にしなければいけない ; また閉じた図形(頂点の最初と最後が同じ)でなければ描画されない ; count = 頂点の数 ; border_color = 線の色 ; fill_color = 塗りつぶす色 mref bmscr,67 dim _count,1 : _count = count ; if (-1 = border_color) & (-1 = fill_color) : return if -1 = border_color : border_color = fill_color CreatePen PS_SOLID, 1, border_color SelectObject bmscr.4, stat hOldPen = stat if -1 = fill_color { GetStockObject NULL_BRUSH } else { CreateSolidBrush fill_color } SelectObject bmscr.4, stat hOldBrush = stat PolyPolygon bmscr.4, ptpos, _count, 1 SelectObject bmscr.4, hOldPen DeleteObject stat if -1 != fill_color { SelectObject bmscr.4, hOldBrush DeleteObject stat } return #deffunc box int x1, int y1, int x2, int y2 ; box x1,y1,x2,y2 ; 画面上に、(p1,p2)と(p3,p4)を左上、右下の点として、 ; 現在の描画色で矩形(四角形)を描画します。 line x2, y1, x1, y1 line x2, y2 line x1, y2 line x1, y1 return #global #define ctype RGB(%1,%2,%3) ((%1*65536)+(%2*256)+%3) #define rgbcolor(%1) color (%1/$10000)&$ff,(%1/$100)&$ff,%1&$ff ; パッケージオプション #packopt name "sstime" #packopt type 2 ; スクリーンセーバー #packopt xsize 320 ; 設定画面の横サイズ #packopt ysize 200 ; 設定画面の縦サイズ #packopt hide 1 ;----------------------------------------------------------------- ; 引数評価 ;----------------------------------------------------------------- s = dir_cmdline : type = peek(s,1) ; コマンドラインの2文字目を取り出す if ('A'<=type)&(type<='Z') : type+=32 ; 大文字を小文字に変換する if type='p' : goto *sspre ; プレビュー if type='s' : goto *ssproc ; フルスクリーン if type='c' : goto *sscfg ; コンフィグ if type=0 : goto *sscfg ; コンフィグ ; ; コマンドラインがどれでもない時はエラーを表示。 ; HSPスクリプトエディタでためしに実行してみる場合には、 ; HSPメニュー「起動オプション」を選んで、「/s」や「/p」などの ; スイッチを指定してコンパイル+実行をしてください。 ; dialog "Unknown switch ["+s+"]" end *sscfg dialog "", 0, "シンプルなアナログ時計" end *sspre ; 描画範囲指定 sx = ginfo_winx - 10 sy = ginfo_winy - 10 dx = 5 dy = 5 goto *ssinit *ssproc ; 描画範囲指定 sx = ginfo_dispx - 20 sy = ginfo_dispy - 20 dx = 10 dy = 10 bgscr 0, ginfo_dispx, ginfo_dispy, , 0, 0 *ssinit cls 4 title "シンプルなアナログ時計" crFill = $006600 crBorder = $00ff00 ; 幅・高さを小さいほうにあわせる→正方形に if sy < sx : dx += (sx - sy) / 2 : sx = sy if sx < sy : dy += (sy - sx) / 2 : sy = sx cx = sx / 2 cy = sy / 2 n = 100.0 gosub *init_sincos_table ; 範囲は 〜 100 nn = 100.0 ; 時計の針の位置(時) ddim clock_h,6,2 clock_h.0.0 = -5.0 : clock_h.0.1 = -3.0 clock_h.1.0 = -8.0 : clock_h.1.1 = 50.0 clock_h.2.0 = 0.0 : clock_h.2.1 = 60.0 clock_h.3.0 = 8.0 : clock_h.3.1 = 50.0 clock_h.4.0 = 5.0 : clock_h.4.1 = -3.0 clock_h.5.0 = 0.0 : clock_h.5.1 = -5.0 count_h = 6 ; 時計の針の位置(分) ddim clock_m,6,2 clock_m.0.0 = -4.0 : clock_m.0.1 = -2.0 clock_m.1.0 = -4.0 : clock_m.1.1 = 80.0 clock_m.2.0 = 0.0 : clock_m.2.1 = 85.0 clock_m.3.0 = 4.0 : clock_m.3.1 = 80.0 clock_m.4.0 = 4.0 : clock_m.4.1 = -2.0 clock_m.5.0 = 0.0 : clock_m.5.1 = -4.0 count_m = 6 ; 時計の針の位置(秒) ddim clock_s,5,2 clock_s.0.0 = -1.0 : clock_s.0.1 = -8.0 clock_s.1.0 = -1.0 : clock_s.1.1 = 87.0 clock_s.2.0 = 0.0 : clock_s.2.1 = 90.0 clock_s.3.0 = 1.0 : clock_s.3.1 = 87.0 clock_s.4.0 = 1.0 : clock_s.4.1 = -8.0 count_s = 5 ; 文字盤のポッチ potti1_size = 2.0, 2.0 ; 文字盤のポッチ(5分ごと) potti5_size = 2.0, 2.0 ; 針の留め金のポッチ center_size = 1.0, 1.0 ; 文字盤ポッチの半径 potti_r = 95.0, 95.0 ; 実際の描画範囲に拡大処理 ; ※clock_h.cnt.0 ではエラーが起きる #define ctype ZOOM_SX(%1) %1=(%1)*cx/nn #define ctype ZOOM_SY(%1) %1=(%1)*cy/nn repeat count_h : ZOOM_SX(clock_h(cnt,0)) : ZOOM_SY(clock_h(cnt,1)) : loop repeat count_m : ZOOM_SX(clock_m(cnt,0)) : ZOOM_SY(clock_m(cnt,1)) : loop repeat count_s : ZOOM_SX(clock_s(cnt,0)) : ZOOM_SY(clock_s(cnt,1)) : loop ZOOM_SX(potti1_size.0) : ZOOM_SY(potti1_size.1) ZOOM_SX(potti5_size.0) : ZOOM_SY(potti5_size.1) ZOOM_SX(center_size.0) : ZOOM_SY(center_size.1) ZOOM_SX(potti_r.0) : ZOOM_SY(potti_r.1) dim hpos,2,(count_h + 1) dim mpos,2,(count_m + 1) dim spos,2,(count_s + 1) gsel 0,2 *main ; メインループ gosub *draw wait 1 goto *main *draw ; dx = 描画位置(横) ; dy = 〃 (縦) ; sx = 描画サイズ(幅) ; sy = 〃 (高さ) ; cx = 描画サイズ 1/2 (幅) ; cy = 〃 1/2 (高さ) redraw 0 gosub *draw_potti gosub *draw_time redraw 1 return *draw_potti ; dx = 描画位置(横) ; dy = 〃 (縦) ; sx = 描画サイズ(幅) ; sy = 〃 (高さ) ; cx = 描画サイズ 1/2 (幅) ; cy = 〃 1/2 (高さ) ; 文字盤のポッチ repeat 60 rr = 1 * (cnt * 6 * n + 0.5) px = dx + cx + (t_sin.rr * potti_r.0) py = dy + cy + (t_cos.rr * potti_r.1) if cnt \ 5 { rgbcolor crFill circle px-potti1_size.0, py-potti1_size.1, px+potti1_size.0, py+potti1_size.1, 1 rgbcolor crBorder circle px-potti1_size.0, py-potti1_size.1, px+potti1_size.0, py+potti1_size.1, 0 } else { ; 5分ごと rgbcolor crFill boxf px-potti5_size.0, py-potti5_size.1, px+potti5_size.0, py+potti5_size.1 rgbcolor crBorder box px-potti5_size.0, py-potti5_size.1, px+potti5_size.0, py+potti5_size.1 } loop return *draw_time ; dx = 描画位置(横) ; dy = 〃 (縦) ; sx = 描画サイズ(幅) ; sy = 〃 (高さ) ; cx = 描画サイズ 1/2 (幅) ; cy = 〃 1/2 (高さ) ; 前に描画した針を消す porygon hpos, count_h, RGB(0,0,0), RGB(0,0,0);crFill porygon mpos, count_m, RGB(0,0,0), RGB(0,0,0);crFill porygon spos, count_s, RGB(0,0,0), RGB(0,0,0);crFill _time = gettime(4), gettime(5), gettime(6), gettime(7) ; DEBUG ; _time = gettime(5), gettime(6), gettime(7) / 16, 0 ; 時 r = 360.0 * ((_time.0 \ 12) * 3600 + _time.1 * 60 + _time.2) / 43200 gosub *get_rotation_matrix repeat count_h hpos(0,cnt) = dx + cx + (clock_h(cnt,0) * rm.0.0 + clock_h(cnt,1) * rm.0.1) hpos(1,cnt) = dy + cy + (clock_h(cnt,0) * rm.1.0 + clock_h(cnt,1) * rm.1.1) loop hpos.0.count_h = hpos.0.0 hpos.1.count_h = hpos.1.0 porygon hpos, count_h, crBorder, crFill ; 分 ; ミリ秒まで計算しないでも十分だろう r = 360.0 * (_time.1 * 60 + _time.2) / 3600 gosub *get_rotation_matrix repeat count_m mpos(0,cnt) = dx + cx + (clock_m(cnt,0) * rm.0.0 + clock_m(cnt,1) * rm.0.1) mpos(1,cnt) = dy + cy + (clock_m(cnt,0) * rm.1.0 + clock_m(cnt,1) * rm.1.1) loop mpos.0.count_m = mpos.0.0 mpos.1.count_m = mpos.1.0 porygon mpos, count_m, crBorder, crFill ; 秒 r = 360.0 * (_time.2 * 1000 + _time.3) / 60000 gosub *get_rotation_matrix repeat count_s spos(0,cnt) = dx + cx + (clock_s(cnt,0) * rm.0.0 + clock_s(cnt,1) * rm.0.1) spos(1,cnt) = dy + cy + (clock_s(cnt,0) * rm.1.0 + clock_s(cnt,1) * rm.1.1) loop spos.0.count_s = spos.0.0 spos.1.count_s = spos.1.0 porygon spos, count_s, crBorder, crFill ; 針の留め金 px = dx + cx py = dy + cy rgbcolor crFill circle px-center_size.0, py-center_size.1, px+center_size.0, py+center_size.1, 1 rgbcolor crBorder circle px-center_size.0, py-center_size.1, px+center_size.0, py+center_size.1, 0 return *init_sincos_table ; SIN・COS 計算用テーブルを作成 ; [IN] ; n = 1度あたりの分割数 ; [OUT] ; t_sin = SINテーブル ; t_cos = COSテーブル ddim t_sin,360*n ddim t_cos,360*n repeat 360*n t_sin(cnt) = sin(deg2rad(1.0 * cnt / n)) t_cos(cnt) = cos(deg2rad(1.0 * cnt / n)) loop ; 大して速度が変わらない ; repeat 899 ; m = cnt ; t_cos( 899-cnt) = t_sin(1+cnt) ; t_cos( 900+cnt) = -t_sin(cnt) ; t_cos(1800+cnt) = -t_sin(900-cnt) ; t_cos(2700+cnt) = t_sin(cnt) ; loop return *get_rotation_matrix ; 回転行列を取得(角度を180度変える) ; [IN] ; r = 取得角度 ; n = SIN・COS 計算用テーブルの1度あたりの分割数 ; [OUT] ; rm = 回転行列(2*2) ; 時計の針用に角度を180度変える r += 180.0 : if 360 <= r : r -= 360 rr = 1 * (r * n + 0.5) ; 回転行列 ; X = x * cosβ - y * sinβ ; Y = x * sinβ + y * cosβ ddim rm,2,2 rm.0.0 = t_cos.rr rm.0.1 = -t_sin.rr rm.1.0 = t_sin.rr rm.1.1 = t_cos.rr return |