HSP3 プログラミングの基礎X | |
◆ 虫さん(1匹バージョン)
複数の円がつながって移動する、虫のようなアニメーションでスクリーンセーバーを制作する。
円はグラフィックスで描画するcircle命令を使う。
(ssaver13.hsp)
次のリストは、スクリーンセーバー本体となるものである。
;ssaver13.hsp randomize kosu = 20 ;長さ dim x, kosu : dim y, kosu win_x = 640 win_y = 480 rr = 10 ;直径 dx = rr : dy = rr ;移動量 x(0) = rnd(win_x / 2) : y(0) = rnd(win_y / 2) ;先頭位置 repeat kosu - 1, 1 x(cnt) = x(cnt - 1) + rr : y(cnt) = y(0) ;水平に並べる loop *mainlp redraw 0 color 0, 0, 0 boxf color 153, 0, 0 repeat kosu - 1, 1 circle x(cnt), y(cnt), x(cnt) + rr, y(cnt) + rr ;描画 loop color 255, 0, 0 circle x(0), y(0), x(0) + rr, y(0) + rr ;先頭描画 redraw 1 repeat kosu - 1, 1 ;2番目以降を移動 x(kosu - cnt) = x(kosu - cnt - 1) y(kosu - cnt) = y(kosu - cnt - 1) loop rd = rnd(100) *retry if rd = 0 : dx = 0 : dy = -rr ;上 if rd = 1 : dx = 0 : dy = rr ;下 if rd = 2 : dx = -rr : dy = 0 ;左 if rd = 3 : dx = rr : dy = 0 ;右 if rd = 4 : dx = rr : dy = -rr ;右上 if rd = 5 : dx = rr : dy = rr ;右下 if rd = 6 : dx = -rr : dy = -rr ;左上 if rd = 7 : dx = -rr : dy = rr ;左下 xx = x(0) + dx : yy = y(0) + dy ;先頭仮移動 if xx = x(2) & yy = y(2) : rd = rnd(8) : goto *retry if xx < 0 | xx >= win_x - rr { ;壁 dx = -dx if dy = 0 : if rnd(2) = 0 : dy = rr : else : dy = -rr } if yy < 0 | yy >= win_y - rr { ;壁 dy = -dy if dx = 0 : if rnd(2) = 0 : dx = rr : else : dx = -rr } x(0) = x(0) + dx : y(0) = y(0) + dy ;先頭移動 await 100 goto *mainlp end
HSPスクリプトエディタで実行してみる。20個の円が先頭の円の後を連なって移動する。
次に、このサンプルプログラムをスクリーンセーバに作り替えていく。スクリーンセーバーの元になるプログラムは、前の説明で一応完成し、【参考】として示したssaver07.hapを利用する。
(手順1) 次のリストが元になるスクリーンセーバーのプログラムである。
;ssaver07.hsp #packopt name "screensaver" ;実行ファイル名 #packopt type 2 ;スクリーンセーバー #packopt xsize 320 #packopt ysize 120 scrname = "screensaver" para = dir_cmdline ;パラメータ取得 para = strmid(para, 0, 2) if para = "/p" | para = "/P" : goto *preview ;プレビュー if para = "/s" | para = "/S" : goto *ssaver ;フルスクリーン if para = "/c" | para = "/C" : goto *config ;コンフィグ dialog "無効なオプションです。" + "[" + para + "]" end ;設定画面 ----- *config title "スクリーンセーバー" gosub *dataread ;設定データファイル読み込み pos 10, 8 : mes "表示回数" ;設定画面作成 pos 100, 8 : input skaisu pos 10, 40 : mes "メッセージ" pos 100, 40 :input moji, 200 pos 240, 80 : button "OK", *settei stop *settei noteadd skaisu, 0, 1 noteadd moji, 1, 1 notesave scrname + ".dat" ;設定データファイル書き込み end ;プレビュー画面 ----- *preview win_x = ginfo_winx ;ウィンドウサイズ(幅) win_y = ginfo_winy ;ウィンドウサイズ(高さ) ;font "MS ゴシック", 12 goto *ssmain stop ;スクリーンセーバー本体 ----- *ssaver win_x = ginfo_dispx ;ディスプレイサイズ(幅) win_y = ginfo_dispy ;ディスプレイサイズ(高さ) bgscr 1, win_x, win_y ;枠なしのウィンドウ *ssmain gosub *dataread ;設定データファイル読み込み *ssmain2 randomize color 0, 0, 0 ;黒色 boxf ;画面消去(四角塗りつぶし) repeat kaisu color rnd(255), rnd(255), rnd(255) ;文字色 pos rnd(win_x), rnd(win_y) mes moji stick key ;test if key = 128 : end ;test await 500 loop goto *ssmain2 end ;設定データファイル読み込み ----- *dataread notesel cfg exist scrname + ".dat" ;設定データファイル if strsize = -1 { ;ファイルなし kaisu = 20 skaisu = "20" moji = "SCREEN SAVER" } else { ;ファイルあり noteload scrname + ".dat" noteget skaisu, 0 ;回数(文字型) noteget moji, 1 ;文字列 kaisu = 0 + skaisu ;整数変換 } return
(手順2) スクリーンセーバー本体の動作部分(マゼンタ色の部分)を先のサンプルssaver13.hspに置き換える。
また、長さと直径をコンフィグで設定できるようにするため、不要な部分を削除する(太字青色)。
;ssaver14.hsp <<省 略>> ;スクリーンセーバー本体 ----- *ssaver win_x = ginfo_dispx ;ディスプレイサイズ(幅) win_y = ginfo_dispy ;ディスプレイサイズ(高さ) bgscr 1, win_x, win_y ;枠なしのウィンドウ *ssmain gosub *dataread ;設定データファイル読み込み randomize ;kosu = 20 ;長さ dim x, kosu : dim y, kosu ;win_x = 640 ;win_y = 480 ;rr = 10 ;直径 dx = rr : dy = rr ;移動量 x(0) = rnd(win_x / 2) : y(0) = rnd(win_y / 2) ;先頭位置 repeat kosu - 1, 1 x(cnt) = x(cnt - 1) + rr : y(cnt) = y(0) ;水平に並べる loop *mainlp redraw 0 color 0, 0, 0 boxf color 153, 0, 0 repeat kosu - 1, 1 circle x(cnt), y(cnt), x(cnt) + rr, y(cnt) + rr ;描画 loop color 255, 0, 0 circle x(0), y(0), x(0) + rr, y(0) + rr ;先頭描画 redraw 1 repeat kosu - 1, 1 ;2番目以降を移動 x(kosu - cnt) = x(kosu - cnt - 1) y(kosu - cnt) = y(kosu - cnt - 1) loop rd = rnd(100) *retry if rd = 0 : dx = 0 : dy = -rr ;上 if rd = 1 : dx = 0 : dy = rr ;下 if rd = 2 : dx = -rr : dy = 0 ;左 if rd = 3 : dx = rr : dy = 0 ;右 if rd = 4 : dx = rr : dy = -rr ;右上 if rd = 5 : dx = rr : dy = rr ;右下 if rd = 6 : dx = -rr : dy = -rr ;左上 if rd = 7 : dx = -rr : dy = rr ;左下 xx = x(0) + dx : yy = y(0) + dy ;先頭仮移動 if xx = x(2) & yy = y(2) : rd = rnd(8) : goto *retry if xx < 0 | xx >= win_x - rr { ;壁 dx = -dx if dy = 0 : if rnd(2) = 0 : dy = rr : else : dy = -rr } if yy < 0 | yy >= win_y - rr { ;壁 dy = -dy if dx = 0 : if rnd(2) = 0 : dx = rr : else : dx = -rr } x(0) = x(0) + dx : y(0) = y(0) + dy ;先頭移動 await 100 goto *mainlp end ;設定データファイル読み込み ----- *dataread <<省 略>>
(手順3) 設定データファイル読み込みのサブルーチンを修正する。設定データは長さ(kosu)と直径(rr)である。
;設定データファイル読み込み ----- *dataread notesel cfg exist scrname + ".dat" ;設定データファイル if strsize = -1 { ;ファイルなし kosu = 20 skosu = "20" rr = 10 srr = "10" } else { ;ファイルあり noteload scrname + ".dat" noteget skosu, 0 ;文字型 noteget srr, 1 ;文字型 kosu = 0 + skosu ;整数変換 rr = 0 + srr } return
(手順4) コンフィグ画面を修正する。
;ssaver14.hsp <<省 略>> ;設定画面 ----- *config title "スクリーンセーバー" gosub *dataread ;設定データファイル読み込み pos 10, 8 : mes "虫の長さ" ;設定画面作成 pos 80, 8 : input skosu pos 10, 40 : mes "直 径" pos 80, 40 :input srr pos 240, 80 : button "OK", *settei stop *settei noteadd skosu, 0, 1 noteadd srr, 1, 1 notesave scrname + ".dat" ;設定データファイル書き込み end ;プレビュー画面 -----
以上で修正は完了である。
スクリーンセーバーとして実行する前に、設定データファイル"screensaver.dat"は削除しておくこと。ファイル名を同じものにしているので、前のデータが残っていると正しく動作しない可能性があるためである。それぞれのファイル名を変えておけばよかったが・・・。
2007 © Hiroshi Masuda |