〜 マルチメディア編 〜
19.画像を反時計回りに徐々に表示させる (要hspext.as)
26.カラオケのように表示した文字を一文字ずつ違う色に変えていく
28.ウェーブフォームサウンドを鳴らすモジュール (要llmod.as)
29.タイトルバー内のアイコン画像を変更する (要llmod.as)
01.グラデーションを作成する
背景が一色では物足りないのでグラデーションの画像を読み込んでいる方はいないでしょうか。
グラデーションとは徐々に色が変化していくモノ(虹等)を指します。
コレを画像として用意しなくてもlineやboxfで作成することが出来ます。
(例)グラデーション作成
randomize
rnd red,256
repeat winx
color red,cnt/3,255-(cnt/4) ; 何でもよい、ただしcntを入れないとグラデーションにはならない
line cnt,0,cnt,winy
loop
stop
02.グラデーション文字を作成
01を応用すれば文字もグラデーションに出来ます。
「gmode 2」は黒色(0,0,0)は透過色となります。
つまり黒色で描いた文字をグラデーション画像の上に貼り付けると
文字の部分だけ透過されバックのグラデーションになると言うわけです。
(例)文字と画像を合成させてグラデーション化させる
screen 0,256,50,0,0,0
title "グラデーションパターン"
redraw 0 ; 一時的に画面に描画するのをストップ(高速化)
repeat 256
color cnt,255-cnt,cnt
line cnt,0,cnt,winy
loop
redraw
screen 2,256,50,0,0,70
title "表示させる文字"
color
font "",18,1
mes "abcdefghijklmnopqrstuvwxyz\n1234567890"
screen 3,256,50,0,0,130
title "合成"
gmode 2 ; 黒色部分を透過させる
pos 0,0 : gcopy 0,0,0,256,100
pos 0,0 : gcopy 2,0,0,256,100
stop
03.文字に飾り付けをする
ただ単に文字を配置するだけではつまりません。
かといって文字の書いた画像を用意するのはサイズが・・・と言う方には下記のサンプルをどうぞ。
そのまま表示するよりかはずっとおしゃれでしょう。
(例)立体文字
font "MS ゴシック",30,1
moji="うまく立体的に見えるカナ?"
color 50,100,100
repeat 5
if cnt=4 : color 100,255,255
pos 10+cnt,10+cnt : mes moji
loop
color 150,50,50
repeat 10
if cnt=9 : color 255,100,100
pos 10+(cnt*2),60-cnt : mes moji
loop
stop
(例)袋文字
font "MS ゴシック",30,1
moji="袋文字は中がくりぬかれた様な文字です"
redraw 0
color 0,150,50
repeat 9
pos cnt\3+10,cnt/3+10 : mes moji
loop
color 100,255,200
pos 11,11 : mes moji
color 200,0,200
repeat 49
pos cnt\7+10,cnt/7+50 : mes moji
loop
color 255,255,0
pos 13,53 : mes moji
redraw
stop
04.数値を画像で表示する
数値を一桁ずつ取り出して、数値にあった部分の画像を切り取り貼り付けてやります。
たとえば1つの数値が50*50ドットの「0」〜「9」までを横に並べた画像の場合、
「0」は座標(50*0,0)から50*50ドット取り出してやればよいわけです。
「3」は座標(50*3,0)から50*50ドット取り出せばうまくいきます。
(例)現在の時刻を画像を使用して表示する 先にコチラの画像をDLしてください
sdim tm,2,6
buffer 2
picload "suuji.jpg"
gsel 0
cls 4
*main
repeat 3
a=cnt*2
b=cnt*2+1
gettime tmp,cnt+4; 時・分・秒を取得
str tmp,2; 2桁の数値にする
strmid tm.a,tmp,0,1 ; 取り出した数値の1桁目を入れる
strmid tm.b,tmp,1,1 ; 取り出した数値の2桁目を入れる
int tmp ; 次のgettime用に数値型に戻す
loop
repeat 6 ; 表示処理
tmp=tm.cnt ; 時の1桁目〜秒の2桁まで(計6個)を取り出していく
int tmp
pos cnt*12+50,50 : gcopy 2,tmp*8,0,8,11
loop
color 255,255
pos 68,46 : mes": :"
wait 100
goto *main
05.画像の反転をする
拡大縮小をする命令「gzoom」を使用して読み込んだ画像を上下・左右反転させることが可能です。
変倍するサイズのパラメータを等倍のマイナス値を指定することで反転させます。
(例)鏡文字を表示させる。
pos 100, 50 : mes "鏡文字を表示します"
pos 240,100 : gzoom -200, 20,0,100,50,200,20 ; 左右反転
pos 100,160 : gzoom ; 200,-20,0,100,50,200,20 ;上下反転
pos 240,210 : gzoom -200,-20,0,100,50,200,20 ;上下・左右反転
stop
06.自作フォント(画像)を表示する
04では数値を画像で表示させました。
今回はその応用で文字をpeekでアスキーコードに変換し、出てきた数値に対する位置をスクリーンに貼り付けます。
下記のサンプルは半角英数記号のみに対応しています。かなや漢字に対応させるのはちょっと面倒です。
自作フォントを作るのが面倒だったので書体「impact」を使っています。
横1列に16個表示させています。下記のスクリプトを使ってご自分の画像のフォントを使用する場合、
横20*16,高さ24*6の320*144ドットの画像をご用意してください。
(例)オリジナルフォントでキメる(?)
#define fontx 20 ; 1つのフォント画像の横幅
#define fonty 24 ; 1つのフォント画像の高さ
buffer 2 ; ここからはフォントの作成です。bufferをscreenに変えるとフォント画像が見れます
color 255
font "impact",fontx,1
b=""
repeat 96
pos cnt\16*fontx,cnt/16*fonty
a=cnt+32
poke b,0,a
mes b
loop ; ここまでフォントの作成
gsel 0
buf=""
input buf,200,25,20
button"表示",*show
stop
*show
a=0
color 255,255,255 : boxf ; 前回表示した文字を消す
strlen len,buf ; 何文字あるか調べる
repeat len ; 文字数分繰り返す
peek a,buf,cnt ; 変数aにアスキーコードを取り出す
pos cnt*fontx,100 :
gcopy 2,a-32\16*fontx,a-32/16*fonty,fontx,fonty
loop
stop
ちょっとコメントが不足していたようなので追加します。
始めの方の「ここから・・・ここまで」とついたコメントの部分はフォント画像を使用する場合は削除してください。
下から3行目の「gcopy 2,a-32\16*fontx,a-32/16*fonty,fontx,fonty」について解説いたします。
「a-32\16」の「a-32」というのはコード32(NULL)を一番初めの文字(0番目)とするためです。
初めに説明したように横1列に16個表示させているので、
例えば17番目(0からなので18個目)だと「17÷16=1余り1」なので左から1番目の場所を取り出すわけです。
これだけだとコードの33を取り出してしまうので、y座標も変更する為「a-32/16」を使うわけです。
ご存知の通り除算結果の余りは切捨てなので
「17÷16=1」となり上から1番目の場所を取り出すのです。
07.よく使いそうなMCIコマンド
mciのよく使いそうなコマンドをヘルプに載っているものも合わせて紹介します。
sprocketさんのページに下記より詳しいMCIコマンドが掲載されています。
mci "open cdaudio alias cd" ; CDオーディオデバイスを開いて、cdというエイリアス(名前)にする
mci "play cd from 1to 2" ; cdのトラック1の始まり〜トラック2の始まりまで再生
mci "stop cd" ; cdの再生を停止(一時停止としても使えます)
mci "close cd" ; cdのデバイスをクローズする
mci "seek cd to 4" ; をトラック4へシーク。形式はsetでTMSFに設定しておくこと
mci "set cd time format ms" ; 時刻形式をミリ秒に設定(ms,millisecondsどちらでも可能)
mci "set cd time format tmsf" ; cdの時刻形式をTMSF(トラック、分、秒、フレーム)に設定
mci "set cd audio all off" ; オーディオ出力をオフ(offの部分をonに換えると出力オンになる)
mci "set cd door open" ; cdデバイスをオープンし、トレイをイジェクト(自動で開けるトレイのみ)
mci "set cd door closed" ; cdデバイスのトレイを収納(閉じられるトレイのみ)
mci "status cd current track" ; 現在のトラックをstatに返す
mci "status cd number of tracks"; cdのディスク上のすべてのトラックの数をstatに返す
mci "status cd time format" ; 現在の時刻形式をstatに返します
mci "status cd length" ; ディスク全体の長さをstatに返す
mci "status cd length track" ; 指定されたトラックの長さをstatに返す
mci "status cd position" ; 現在の位置をstatに返す
mci "status cd position track" ; 指定されたトラックの開始位置をstatに返す
08.AVI形式以外のムービー再生
07のMCIコマンドの中に書いてもよかったのですがコチラで説明していきます。
sndは再生・停止といった基本的なことしか出来ないmciの簡易版とでも思っていてください。
mciはムービーについて説明すると再生サイズ、再生位置、リピートと様々なことが出来るのです。
(例)多形式再生可能な簡易プレイヤー(リピートのみ)
gsel 0,-1
dialog"mpg;*.vob;*.wmv;*.avi",16
if stat==0 : end ; キャンセル又はエラーで終了
mci "open \""+refstr+"\" alias video type mpegvideo2"
onexit *exit
mci "play video repeat"
stop
*exit
mci "close video" ; 終了させるとき必ず忘れずに付ける
end
09.画像の合成(フェードイン・アウト)
HSPver2.55からgmodeにタイプが新しく増えて、半透明合成というものが出来るようになりました。
これにより2枚以上の画像をブレンド率を指定して重ね合わせが手軽に出来ます。
フェードイン・アウトと書いたのは、これらも同じやり方のためです。
(例)徐々に変化する画像
color 0,0,255 : boxf
a=255
*main
buffer 2
color a,b,c : boxf
gsel 0
repeat 128
redraw 0
gmode 3,winx,winy,cnt*2
pos 0,0 : gcopy 2,0,0,winx,winy
redraw
wait 1
loop
if c=255 : c=0 : a=255
if b=255 : b=0 : c=255
if a=255 : a=0 : b=255
goto *main
10.画像の一部分を●や★の形に切り取る
文字を使用することで●や■や▲や★といった形に画像を切り出すことが簡単に出来ます。
02のグラデーション文字の方法で、黒色を透過させることで実現させます。
仮想の画面内にcolorをすべて0にして(黒色)任意の大きさで好きな形の文字を表示させます。
これをメイン画面に張り付けることでメイン画面の一部分だけを表示させることが出来ます。
(例)星型に切り抜く
buffer 2
color 255,255,0 : boxf 0,0,320,240 ; 左上を黄色で塗りつぶす
color 0,255,0 : boxf 320,0,640,240 ; 右上を緑色で塗りつぶす
color 0,0,255 : boxf 0,240,320,480 ; 左下を青色で塗りつぶす
color 255,0,0 : boxf 320,240,640,480 ; 右下を赤色で塗りつぶす
gsel 0
pos 0,0 : gcopy 2,0,0,640,480
dialog "★型に切り抜きます\n元の絵を確認しましたか?"
buffer 3
font "MS ゴシック",400 ; 任意の大きさにする
pos 0,0 : mes "★"
gsel 2
gmode 2
pos 120,40 : gcopy 3,0,0,400,400 ; 切り抜きたい位置を指定
gsel 0,1
width 400,400
pos 0,0 : gcopy 2,120,40,400,400
stop
11.カーソルキーに合わせてキャラが動く
ゲームで主人公を操る一般的な方法ですね。
カーソルキーを監視し、押された方へキャラを決められた分(歩幅等)移動させます。
ここでは、歩くようなアニメーション(右足・左足を交互に出す)は行いません。
(例)主人公「■」が画面内を歩き回る
x=200 ; キャラの初期x座標
y=100 ; キャラの初期y座標
font "",40 ; キャラの大きさ
repeat
redraw 0 ; チラツキ防止
color 0,200,0 : boxf ; 先に背景を描く
color 0,0,100
pos x,y : mes "■" ; 次にキャラを描く
stick key
if key&1 : x-=40 ; ←が押されたかチェック
if key&2 : y-=40 ; ↑が押されたかチェック
if key&4 : x+=40 ; →が押されたかチェック
if key&8 : y+=40 ; ↓が押されたかチェック
if x<0 : x=0 ; 画面左はみ出し防止
if x>(winx-40) : x=winx-40 ; 画面右はみ出し防止
if y<0 : y=0 ; 画面上はみ出し防止
if y>(winy-40) : y=winy-40 ; 画面下はみ出し防止
redraw
wait 1 ; 必ずウェイトを入れる
loop
12.ワイプ処理で画像表示
ワイプ処理を知っているでしょうか?
一気に画像が表示されるのではなく徐々に表示する方法のひとつです。
端から逆端をめがけて表示していくカーテンを下ろすような方法もありますが、それとはまた少し違います。
実行していただければどういう表示のされ方なのかわかると思います。
スクリーンセイバーやホームページを開くときにJAVAで徐々に開かれるなどこの処理は良く見かけます。
(例)ワイプしながら画像表示
buffer 3,400,300
color 255 : boxf : color ; この行を画像に変えて試してください
wx=winx
wy=winy
wipe=wx/10
screen 0,wx,wy
gmode 2
buffer 2,wx,wy
repeat 10
redraw 0
repeat wipe
line wx/wipe*cnt+ichi,0,wx/wipe*cnt+ichi,wy
loop
ichi+
gsel 0
pos 0,0 : gcopy 3,0,0,wx,wy
pos 0,0 : gcopy 2,0,0,wx,wy
gsel 2
redraw
wait 10
loop
stop
13.画像自動スクロール
背景画像が自動でスクロールするゲームよく見かけると思いますが、全然違う画像をスクロールさせるのではなく
同じ画像が何度も回るのが多いようです。
画像をつなげるのではなく端まで来たらまた最初の位置からスクロールして行けば繋がった一枚絵の様になりますが
画像を2枚分つなげておかなければ、端まで来たときに最初の位置に画像が飛んでしまって
滑らかなスクロールではなくなってしまいます。
(例)グルグルスクロールさせてみる
buffer 3
color 255 : boxf : color ; この行を画像に変えて試してください
wx=winx*2
wy=winy
buffer 2,wx,wy
pos 0,0 : gcopy 3,0,0,wx/2,wy
pos wx/2,0 : gcopy 3,0,0,wx/2,wy
gsel 0
width wx/2,wy
repeat 200
gcopy 2,cnt\50*wx/100,0,wx/2,wy
wait 5
loop
end
14.マウスを押している間直線を引く
ペイントソフトでよくある処理をテストしてみたいと思います。
それは、マウスを押してから放すまで直線を引くというものです。
引く位置はマウスを押した座標から放す座標までとします。
(例)マウスを押して離すまでの位置に直線を引く
;*start
repeat
stick k,256,1
if k&256 : mx=mousex : my=mousey : break
wait 1
loop
repeat
redraw 0
color 255,255,255 : boxf : color
line mx,my,mousex,mousey
redraw
stick k,256,1
if k&256 {
wait 1
loop }
goto *start
15.四角形の枠線を描画するモジュール
画面上に、(p1,p2)と(p3,p4)を左上、右下の点として、外枠だけの四角形を描画します。
簡単ですけど毎回lineで指定するのは面倒ですので、ひとつの命令(モジュール)にしてしまおうと言うものです。
(例)線で四角形を描く
;************** 命令説明 **************
;
; box p1,p2,p3,p4
;
; p1,p2 : 左上X,Y座標
; p3,p4 : 右下X,Y座標
;
;*************************************
#module "drowbox"
#deffunc box int,int,int,int
mref p1,0
mref p2,1
mref p3,2
mref p4,3
line p1,p2,p3,p2
line p1,p4,p1,p2
line p1,p4,p3,p4
line p3,p2,p3,p4
return
#global ; ***** ここまでがモジュール ここから下がサンプル *****
box 100,50,300,150
color 255
box 250,200,500,230
stop
16.ウィンドウ内に表示した画像をドラッグ移動する
本家掲示板であった質問に答えたものです(ちょっと拡張してますが...)。
画像をD&Dで移動するにはどのようにするか、と言うサンプルです。
本家掲示板で答えた回答とは違いウィンドウ外へ画像がはみ出さないようにしています。
(例)ドラッグで画像移動
buffer 2
picload "sample\\demo\\hsp2ttl.jpg"
wx=winx/2 ; 画像の幅
wy=winy/2 ; 画像の高さ
gzoom wx,wy,2,0,0,winx,winy
px=10 ; 初期X座標
py=50 ; 初期Y座標
gsel 0
color 255,255,255
repeat
redraw 0
boxf
pos px,py : gcopy 2,0,0,wx,wy
redraw
stick key,256,1
if key&256 {
mx=mousex ; マウスX座標
my=mousey ; マウスY座標
px.1=px-mx ; 画像左上とクリック位置とのX座標差
py.1=py-my ; 画像左上とクリック位置とのY座標差
}
wait 1
if mx>=px&(mx<=(px+wx))&(my>=py)&(my<=(py+wy))&(key==256) { ; クリック位置が画像内
mx=mousex ; 移動後マウスX座標
my=mousey ; 移動後マウスY座標
px=mx+px.1 : if px<0 : px=0 : else : if px>(winx-wx) : px=winx-wx ; X座標のはみ出し防止
py=my+py.1 : if py<0 : py=0 : else : if py>(winy-wy) : py=winy-wy ; Y座標のはみ出し防止
}
loop
17.RPGでよく見るキャラ周りを暗くして見えなくする
11や13の応用になるのかな?
RPGの洞窟のシーンでよく見るキャラ周りしか見えない状態をしてみましょう。
ホントは「通常中心でキャラを足踏みさせ背景のスクロール、背景の端のほうに来たら背景ストップでキャラを移動」と
させるのが一般的かと思いますが、このTIPSではそれがメインではないので省略し背景を大きめに取っています。
(例)キャラ周り以外見えない
sdim map,512
map ="11111111111111111111111111111111"
map+="10001100001100000000000001000111"
map+="10100001100100111111111111030101"
map+="10110111101100000011000001000101"
map+="10100111000110111011101101011101"
map+="10100000001100111000001101000001"
map+="11111001111000010011111111100111"
map+="10101011100011001110110010001111"
map+="10000011001111000110110110100101"
map+="10101111000001110000000000111101"
map+="10101101011100001111111111100001"
map+="10100000001111000001111000110111"
map+="10002011101101111000011101110011"
map+="11100011000000001011000000000001"
map+="11111111111111111111111111111111"
px=4
py=12
wx=640
wy=480
redraw 0
buffer 3,wx,wy
buffer 2,40*48,40*27
color 240,220,150 : boxf
repeat 15
repeat 32
strmid mapinfo,map,mapy*32+cnt,1
if mapinfo=="1" : color 80,30,30 : boxf cnt+8*40,mapy+6*40,cnt+8*40+40,mapy+6*40+40
if mapinfo=="2" : color 180,255,180 : boxf cnt+8*40,mapy+6*40,cnt+8*40+40,mapy+6*40+40
if mapinfo=="3" : color 255,180,255 : boxf cnt+8*40,mapy+6*40,cnt+8*40+40,mapy+6*40+40
loop
mapy+
loop
gsel 0
gmode 2
repeat
gsel 3
color 1,1,1 : boxf : color
;font "MS ゴシック",cnt\2*10+100
pos winx-(cnt\2*10+100)/2,winy-(cnt\2*10+100)/2 : mes "●"
gsel 0
pos 0,0 : gcopy 2,px+8*40-300,py+6*40-220,wx,wy
pos 0,0 : gcopy 3,0,0,wx,wy
color ,,255 : boxf wx-32/2,wy-32/2,wx+32/2,wy+32/2
redraw
wait 10
redraw 0
stick key,15,1
if key==1&(px>0) : strmid tmp,map,py*32+px-1,1 : if tmp!=1 : px-
if key==2&(py>0) : strmid tmp,map,py-1*32+px,1 : if tmp!=1 : py-
if key==4&(px<31) : strmid tmp,map,py*32+px+1,1 : if tmp!=1 : px+
if key==8&(py<14) : strmid tmp,map,py+1*32+px,1 : if tmp!=1 : py+
loop
18.文字「●」を利用して徐々に視野を広げていく
10の応用(?)で視野(見える所)が徐々に広がっていくのをHSP標準命令だけでやってみましょう。
車などでトンネルを抜けていくような感じです(ちょっと違いますが...)。
コレのポイントは「●」をどんどんと拡大していくわけですが中心点がずれないようにすることですね。
(例)視野を拡大していく
buffer 2
picload "sample\\demo\\hsp2ttl.jpg"
wx=winx
wy=winy
screen 0,wx,wy
gmode 2
buffer 3,wx,wy
repeat 50
;font "MS ゴシック",18*cnt+1
pos wx/2-(cnt*9),wy/2-(cnt*9) : mes "●"
gsel 0
redraw 0
pos 0,0 : gcopy 2,0,0,wx,wy
pos 0,0 : gcopy 3,0,0,wx,wy
redraw
wait 5
gsel 3
loop
stop
19.画像を反時計回りに徐々に表示させる (要hspext.as)
これも18と同じく徐々に画像を表示させていくエフェクトですが
コチラは9時の方向(画面の真左)から反時計回りに表示されていくものです。
言葉で書くより実行していただいた方がすぐにわかるかと思います。
画像を標準付属の「hsp2ttl.jpg」を使用しているため表示角をあれくらいずつ増やして行って大丈夫ですが、
もっと大きい画像になると、表示ウィンドウの角の方に表示されるはずの画像が表示されなくなってきます。
コレはlineで徐々に角度を増やしていっているため、精度が低い(前回からの角度が大きい)と隙間が出来てしまうのです。
大きい画像を使用する場合にはemathのパラメータを増やしてやりましょう。
ループ内のredrawを消してしまうと極端に遅くなってしまいますので消さないでください。
(例)視野を拡大していく(反時計回り,hspext.as)
#include"hspext.as"
buffer 2
picload "sample\\demo\\hsp2ttl.jpg"
wx=winx
wy=winy
screen 0,wx,wy
gmode 2
t=winx/2 ; 中点X
t2=winy/2 ; 中点Y
c=12 ; 小数点精度
d=c-8*4 ; 360度回転するのに必要な繰り返し数
emath c ; 精度設定
buffer 3,wx,wy
gmode 2
repeat 256*d
emcos a,cnt ; X
emsin b,cnt ; Y
line a+t,b+t2,t,t2
if cnt\64=63 {
gsel 0 : redraw : wait 1 : redraw 0 : gcopy 2,0,0,wx,wy : gcopy 3,0,0,wx,wy : gsel 3
}
loop
gsel 0
redraw
stop
20.ボリュームコントロールを開く
HSPから音量を制御するボリュームコントロールを開いてみましょう。
また全体の音量を制御する(音量バーひとつだけのもの)も開いてみます。
(例)ボリュームコントロール開く
exec "sndvol32.exe" ; ボリュームコントロール
exec "sndvol32.exe /t" ; 全体の音量変更バー
21.画像回転モジュール
HSP標準命令では画像を回転させて表示する命令がありません(反転はありますが)。
ないなら自分でやってしまおうということで90度単位で何度回転させるかというモジュールを作成してみました。
モジュールではpget,pset命令で書き換えているため非常に遅いです。
mrefを使いVRAMを直接いじれば高速な処理をすることができます。
また90度単位だけでなく微妙な角度(1度単位又はそれ以下)にすることもできますが、それなりの技量が必要となります。
(例)画像を回転させてみる
;************** 命令説明 **************
;
; turn p1,p2,p3,p4,p5,p6
;
; p1 : 回転コピー元画像ID
; p2 : コピー先ウィンドウID
; p3 : 一時使用ウィンドウID
; p4,p5 : 貼り付け位置(X,Y)
; p6 : 何度回転させるか(0=そのまま貼り付け,1=90度時計回り,2=180度時計回り,3=270度時計回り)
;
;**************************************
#module"rotation"
#deffunc turn int,int,int,int,int,int
mref orign,0
mref attachment,1
mref tmpwin,2
mref px,3
mref py,4
mref direction,5
gsel orign
wx=winx
wy=winy
if direction<0|(direction>3) : direction=0
if direction\2=0 : buffer tmpwin,wx,wy : else : buffer tmpwin,wy,wx
repeat wy
repeat wx
gsel orign
pget cnt,num
gsel tmpwin
color rval,gval,bval
if direction=0 : pset cnt,num
if direction=1 : pset wy-num-1,cnt
if direction=2 : pset wx-cnt-1,wy-num-1
if direction=3 : pset num,wx-cnt-1
loop
num+
loop
gsel attachment
pos px,py
if direction\2=0 : gcopy tmpwin,0,0,wx,wy : else : gcopy tmpwin,0,0,wy,wx
return
#global ; ***** ここまでがモジュール ここから下がサンプル *****
buffer 2
picload "sample\\demo\\hsp2ttl.jpg"
screen 0,dispx,dispy,,0,0
title "処理中..."
turn 2,0,3,100,20,3
title "完了"
stop
22.標準命令でgifファイルやプログレッシブjpgを開く
picloadではGIFファイルやプログレッシブJPGファイルが開けません。
では標準だけで開くことが出来ないのかというとそうではないようです。
表示することはできますがソレをどのようにして使用できるかはわかりません(ぉ
7で紹介したmciを使うことによって開けます。
試していないのでわからないですが16bitBMPとかも開けたりするかもしれません…。
(例)画像をmci命令で開く
mci "open 開きたい画像 type MPEGVideo2 alias picture" ; 開きたい画像の選択
mci "play picture" ; 開く
stop
23.ウィンドウ内に自前のスクロールバー作成
ウィンドウID1(厳密には2)以上のウィンドウにはスクロールバーを付けることが出来ます。
しかしウィンドウ内にスクロールバーを表示することができません(ladlib.dll等のDLLを使用すれば可能)。
…ということで自前で作ってしまおうということで作成してみたものです。
以前は非常に使い勝手の悪いものでしたが今回修正を施しましたので大分マシにはなったと思います。
スクロールする元画像の方が描画エリアより小さい場合はスクロールできなくもしてみました。
(例)スクロールバーを付加
#define gx 200 ; 表示するXサイズ
#define gy 100 ; 表示するYサイズ
#define gsx 100 ; 表示左上X座標
#define gsy 100 ; 表示左上Y座標
#define scrsize 16 ; スクロールボタンサイズ
#define scrwaku 1 ; スクロールボタン縁の太さ
#define gosa 1000 ; 誤差軽減用
dim sx, 1 : dim sy, 1 ; スクロールボタンXY座標
dim wx, 1 : dim wy, 1 ; 元画像XYサイズ
dim mx, 3 : dim my, 3 ; ドラッグXY座標(0:現在 1:ドラッグ開始)
dim disabled, 2 ; ボタン1と2使用可能フラグ
dim key, 1 ; キー取得変数
dim click, 1 ; ドラッグ中にスクロールボタンから外れても移動可能にする
button "Load", *load
buffer 2, scrsize * 2, scrsize
; シャドウカラー
color : boxf 0, 0, scrsize - 1, scrsize - 1
; ライトカラー
color 255, 255, 255 : boxf 0, 0, scrsize - scrwaku - 1, scrsize - scrwaku - 1
; ボタン表面
color 192, 192, 192 : boxf scrwaku, scrwaku, scrsize - scrwaku - 1, scrsize - scrwaku - 1
; 使用不可
pos scrsize * 2 -1, scrsize - 1 : gzoom -scrsize, -scrsize, 2, 0, 0, scrsize, scrsize
buffer 3
*load ; ロード
dialog "bmp;*.jpg", 16
if stat = 0 : goto *main
gsel 3
picload refstr
wx = winx : if wx > gx : disabled.0 = 0 : else : disabled.0 = 1
wy = winy : if wy > gy : disabled.1 = 0 : else : disabled.1 = 1
gsel 0
sx = 0 ; 横スクロールボタンポジション
sy = 0 ; 縦スクロールボタンポジション
goto *main
*main ; メイン
gosub *draw
goto *drag
*draw; 描画
redraw 0
; スクロールエリア(外枠用)
color 128, 128, 128
boxf gsx, gsy + gy, gsx + gx - 1, gsy + gy + scrsize - 1
boxf gsx + gx, gsy, gsx + gx + scrsize - 1, gsy + gy - 1
; スクロールエリア(中用)
color 230, 230, 230
boxf gsx + 1, gsy + gy + 1, gsx + gx - 2, gsy + gy + scrsize - 2
boxf gsx + gx + 1, gsy + 1, gsx + gx + scrsize - 2, gsy + gy - 2
; スクロールバー描画
pos gsx + sx, gsy + gy : gcopy 2, disabled.0 * scrsize, 0, scrsize, scrsize
pos gsx + gx, gsy + sy : gcopy 2, disabled.1 * scrsize, 0, scrsize, scrsize
; 描画エリア
color 210, 210, 210
boxf gsx, gsy, gsx + gx - 1, gsy + gy - 1
; 画像描画
pos gsx, gsy : gcopy 3, wx - gx * sx / (gx - scrsize), wy - gy * sy / (gy - scrsize), gx, gy
redraw
return
*drag ; スクロールバー移動チェック
mx.1 = mousex : my.1 = mousey
wait 5 ; ココでウェイトを掛ける(ポイント!)
stick key, 256, 1
if key & 256 = 0 : click = 0 : goto *main
mx.0 = mousex : my.0 = mousey
if (gsx + sx <= mx) & (gsy + gy <= my) & (gsx + sx + scrsize > mx) & (gsy + gy + scrsize > my) & (click ! 2) : click = 1
if (gsx + gx <= mx) & (gsy + sy <= my) & (gsx + gx + scrsize > mx) & (gsy + sy + scrsize > my) & (click ! 1) : click = 2
on click goto *main, *btn1, *btn2
*btn1 ; 横スクロールバー移動
sx += mx - mx.1
if (0 > sx) | (gx - scrsize < sx) | (wx - gx * sx / (gx - scrsize) < sx) : sx -= mx - mx.1
goto *main
*btn2 ; 縦スクロールバー移動
sy += my - my.1
if (0 > sy) | (gy - scrsize < sy) | (wy - gy * sy / (gy - scrsize) < sy): sy -= my - my.1
goto *main
24.らせん状に画像を表示していく
らせん状にするのに数値の増減に何か規則性はないのかと私なりに考えたものです。
ネットで調べれば出てきたのかも知りませんが…。
(例)画像を螺旋状に表示していく
#define size 16 ; 一度に表示するサイズ
buffer 2
picload "sample\\demo\\hsp2ttl.jpg"
wx=winx/size
wy=winy/size
screen 0,wx*size,wy*size
repeat wx*wy
if cont=0 : cont.1=wx-1 : tmp.1=wy : direction=0
repeat cont.1
redraw 0
pos cont.2,cont.3 : gcopy 2,cont.2,cont.3,size,size
redraw
if direction=0 : cont.2+=size
if direction=1 : cont.3+=size
if direction=2 : cont.2-=size
if direction=3 : cont.3-=size
wait 1
loop
if cont\2=0 : tmp=cont.1 : cont.1=tmp.1
if cont\2=1 : tmp.1=cont.1 : cont.1=tmp
cont+
if cont!=2 : cont.1- : ; 解決法不明なので修正用(^^;
if cont.1<0 : break
direction+
if direction>3 : direction=0
loop
stop
25.市松模様状に画像を表示していく
市松模様をご存知でしょうか…?名前を知らなくても模様ぐらいは見たことあると思います。
チェック柄と言ったほうが馴染み深いでしょうかね。実行していただければ形がすぐにわかると思います(^^;
(例)市松模様状に表示していく
#define panel 16 ; 1ブロックの大きさ
buffer 2
picload "sample\\demo\\hsp2ttl.jpg"
wx=winx
wy=winy
screen 0,wx,wy
size=0
repeat wx/panel
count=0
redraw 0
repeat wy/panel+1
if cnt\2=0 {
repeat panel
pos wx/panel*cnt+size,count*panel : gcopy 2,wx/panel*cnt+size,count*panel,panel,panel
loop
} else {
repeat panel+1
pos wx/panel*cnt+size-(wx/panel/2),count*panel : gcopy 2,wx/panel*cnt+size-(wx/panel/2),count*panel,panel,panel
loop
}
count+
loop
redraw
wait 3
size+
loop
stop
26.カラオケのように表示した文字を一文字ずつ違う色に変えていく
現在話している・歌っている位置がわかるように表示した文字色を変えていきましょう。
カラオケツールやサウンドノベルゲームのリアルタイム発声等に利用できそうですね。
(例)表示文字を一文字ずつ違う色に変えていく(ネコスキーさん提供)
font "MS 明朝",30,1
redraw 0
text 1 ; 9X系では必要らしい
mes "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
redraw
pos 0,0
color 255,0,0
text 100
mes "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
stop
NT系では2行目のtextがなくても特に問題はありませんが9X系では1ドットずつ塗り替える位置がずれていくそうですので
サンプルでは「text 1」を入れていますが初めの描画が見られないようにする為redrawredrawでごまかしています。
27.文字をフェードイン・フェードアウトする
画像をフェードイン・アウトする場合は、palfade命令やgmode・gcopyを使って出来ますが、
表示させた文字だけフェードイン・アウトはできません。
実現させるには、color命令で少しずつ背景色に近づけていけば、フェードアウトになり、
背景色から違う色に変えていけばフェードインになります。
(例)フェードイン・アウト
repeat 128 ; フェードアウト
redraw 0
color 255,cnt*2,cnt*2 ; 背景色に近づけていく
pos 100,50 : mes "文字のフェードアウト"
redraw
wait 1
loop
repeat 128 ; フェードイン
redraw 0
color 255,255-(cnt*2),255-(cnt*2) ; 背景色から遠ざけていく
pos 100,50 : mes "文字のフェードイン"
redraw
wait 1
loop
stop
例ではredrawを使って仮想画面だけ書き変え、後でまとめて更新していますが、
このくらいのサイズならredrawがないほうが速いと思います。
ただチラツキが目立つという人はredrawを入れてみてください。
28.ウェーブフォームサウンドを鳴らすモジュール (要llmod.as)
ダイアログが出現した時に音がなりますよね。ココでいうのサウンドはソレを指します。
その音を鳴らしてみようというモジュールです。用途は…各自でお考えください(^^;
一応switch命令を使用していますのでHSP2.6でご利用ください。
(例)サウンドを鳴らす
#include "llmod.as"
;************************** 概要説明 ************************
;
; beep n1
;
; n1=数値 : サウンドの種類 0 : 一般の警告
; 1 : システムエラー
; 2 : メッセージ(問い合わせ)
; 3 : メッセージ(警告)
; 4 : メッセージ(情報)
; それ以外はスピーカー標準のビープ
;
;***********************************************************
#module "beep"
#deffunc beep int
mref tone,0
switch tone
case 0 : prm=0 : swbreak
case 1 : prm=$10 : swbreak
case 2 : prm=$20 : swbreak
case 3 : prm=$30 : swbreak
case 4 : prm=$40 : swbreak
default : prm=$ffffffff
swend
dllproc "MessageBeep",prm,1,D_USER@
return
#global ; ***** ここまでがモジュール ここから下がサンプル *****
beep 1
29.タイトルバー内のアイコン画像を変更する (要llmod.as)
タイトルバーのアイコンを変えたいと言う質問が他所であって、ソレを答えた時のものです。
実行ファイルアイコンを変更することでタイトルバーアイコンも変更されるのですが、
ソレとは別に用意したいといった時に利用するなどしてください。
(例)タイトルバーアイコンの変更(メモ帳)
#include "llmod.as"
file=windir+"\\notepad.exe" ; 変更するアイコン
mref bmscr,67
prm.0=bmscr.14
getptr prm.1,file
prm.2=no
dllproc "ExtractIconA",prm,3,D_SHELL
if stat=0 : dialog"失敗しました"
prm=bmscr.13,-14,stat
dllproc "SetClassLongA",prm,3,D_USER
dllproc "DrawMenuBar",bmscr.13,1,D_USER
stop
30.画像をグレースケールにして表示する
ここで紹介する方法を使えば別に白と黒だけの濃淡だけでなくとも、
赤調や青調などなど様々なグラデーションにすることができることを予め書いておきます。
…で、どのようにするかと言うと、どこでこの方法見たのかは覚えていないのですが、
パレットを使用すると簡単に出来る、というものです。
方法が1つしかないというわけではないのですが、見た目的にも分かりやすい作りですし、
速度的にも問題はないでしょう。一度お試しあれ。
(例)表示させる画像をグレー調する
dialog "bmp;*.jpg", 1631.HSPウィンドウに高速ブラッシング
HSPにはpsetというHSPウィンドウ内に1ピクセル任意の色を設定する命令が用意されています。
しかし、このpsetや1ピクセル分の色を取得できるpgetは処理速度が遅いことで有名です。
以前掲示板で、画像編集の際に全ての色を取得する質問があった時に
あんすこえむさんがVRAMの操作で面白いサンプルを提示してくださいました。
そのサンプルとは少し違いますがVRAM操作のみに焦点を当てたサンプルを下記に載せておきます。
マウス左クリック周辺にランダムで赤色を設定します。
右クリックで白色(クリア)をします。
分かりにくい点、及び関連事項がございますので説明しておきましょう。
ご存知のことと思いますが、HSPのウィンドウにはパレットとフルカラーの2モードが用意されています。
パレットだと1ピクセル分の情報が1バイトで収まるのに対し、
フルカラーだと赤緑青の3輝度(各1バイト)で1ピクセル3バイト要します。
また、メモリに格納される並びも少し変わっていて、X軸は右に行くほど大きいのは同じですが、
Y軸は上に行くほど大きい(通常のグラフ軸と同様)です。
つまり3×3ピクセルの並びを例にすると、
|
|---|
(例)ペイントの疑似ブラシ効果
; 初期化; メイン
*main
stick key,768,1
if key & 256 : gosub *paint
if key & 512 : gosub *clear
wait 1
goto *main
; 塗る
*paint
col.0 = 0 : col.1 = 0 : col.2 = 255 ; 赤色にしてみる
gosub *brush
return
; 消す
*clear
col.0 = 255 : col.1 = 255 : col.2 = 255 ; 白色にしてみる
gosub *brush
return
; ブラシ
*brush
repeat drops
rnd rx , r : rx = mousex + rx - (r / 2)
rnd ry , r : ry = mousey + ry - (r / 2)
if 0 > rx | (winx - 1 < rx) | (0 > ry) | (winy - 1 < ry) : continue
addr = ((winy - 1 - ry) * winx * 3) + (rx * 3)
repeat 3
poke vram , addr + cnt , col.cnt
loop
loop
redraw ; 操作後に必要
return
32.途切れない線を描く
ブラシ機能について書いたということでペイントつながりでペン機能も書いておこうかな、と。
私もSIC内でペイント機能が入っていたりするのですが、psetで頑張っていたりしました。
このpsetでマウス座標位置に点を落としていけば確かに線のようにはなるのですが、
マウスを高速に動かすと、いくらウェイト時間を短くしても隙間が空いてしまうという問題があります。
簡単に連続した線が描けるのを知らなかったわけなのですが、皆さんが同じ過ちをしないためにココに残しておきます。
その途切れない線の描き方というのは、lineを使うということです。
時間が出来たら私もSICを直さないとダメだ、と思っているですがねぇ。
(例)ペイントの疑似ブラシ効果
repeat*click
line x,y,mousex,mousey
return
33.ウィンドウ内で独自のスクロール処理を行う
ウィンドウにスクロールバーを付加して、スクロールするのではなく、
ウィンドウ内のクリック(ドラッグ)位置を検出し、独自にスクロールを行う方法第二弾(第一弾はコチラ)です。
第一弾は後日書き直しますが、現状試した所うまく動きませんでした^^;
今回は別の方が作られたもので許可を得て提供スクリプトをそのまま公開させていただいております。
あくまで、標準(API除く)だけで作成を試みたもの、ということのようです。
スクロールバー内の針の位置をもとにオフセットを割合計算していて
スクロール領域より画像の方の幅、もしくは高さが短い場合、
短い方の軸の移動方向が反転してしまうという仕様となっています。
(例)ウィンドウ内でスクロールする あんすこえむさん提供
; 配列sbの1次元目要素番号*afc ; 窓選択
sbw=-1 ;操作窓ID初期化
repeat sbnum
gosub *sbinf ;窓情報取得
if (iparam=0)&(xx0<=gmx)&(xx2>gmx)&(yy0<=gmy)&(yy2>gmy) { ;範囲内なら
sb.EFHV.cnt=((gmy<yy1)*SBVM)+((gmx<xx1)*SBHM) ; scrollの種類を求める
sbw=cnt ; 操作窓IDを有効な値に
break ; ループを抜ける
}
loop
*xloop ; ここからスクロール操作
gsel 0
redraw 1 : redraw 0
wait 3
stick ky ,-1
gmx=mousex : gmy=mousey
repeat sbnum
gosub *sbinf ;窓情報取得
if sbw=cnt{
if ky&256!0 { ;左マウスボタンが押されたままなら
gosub *sbdsp ; 窓のスクロールを操作
}else{
sbw=-1 ; 左マウスボタンが押されなくなったら操作窓なし
}
}else{
if sb.EANI.cnt {sbtype=0:gosub *sbdsp}
}
loop
gosub *buf4
goto *xloop
*sbinf
dup XX, sb.EXX.cnt ; スクロール値Xは更新対象なのでdup
dup YY, sb.EYY.cnt ; スクロール値Yは更新対象なのでdup
bid=sb.EBID.cnt ; 表示バッファ
sbtype=sb.EFHV.cnt ; 現スクロールモード
xwsz=sb.EXWSZ.cnt-1 : ywsz=sb.EYWSZ.cnt-1 ; 針位置計算 -1は針の幅を考慮
xbsz=sb.EXBSZ.cnt : ybsz=sb.EYBSZ.cnt ; 元画像サイズを取得
xx0=sb.EXXP.cnt : xx1=xx0+xwsz : xx2=xx1+10 ; 窓左端、縦スクロールバー左端、同右端
yy0=sb.EYYP.cnt : yy1=yy0+ywsz : yy2=yy1+10 ; 窓上端、縦スクロールバー上端、同下端
return
*sbdsp
if sbtype&SBHM { ; 横スクロール
if sbtype&SBINI=0:XX=gmx ; 初期化でなければ、マウスポインタにあわせる
if XX<xx0 : XX=xx0
if xx1-1<XX : XX=xx1-1
}
if sbtype&SBVM {
if sbtype&SBINI=0 : YY=gmy ; 初期化でなければ、マウスポインタにあわせる
if YY<yy0 : YY=yy0
if yy1-1<YY : YY=yy1-1
}
sbxp=(xbsz-xwsz)*(XX-xx0)/xwsz ; コピー元画像の左上X
sbyp=(ybsz-ywsz)*(YY-yy0)/ywsz ; コピー元画像の左上Y
color 100,128,128 : boxf xx0,yy1,xx1,yy2 ; 縦スクロールバーの下地
color 100,128,128 : boxf xx1,yy0,xx2,yy1 ; 横スクロールバーの下地
color 80,80,80 : boxf xx0-1,yy0-1,xx1,yy1 ; 窓本体枠
color 255,0,0 : boxf XX,yy1,XX,yy2 ; 横スクロールバーの針
color 255,0,0 : boxf xx1,YY,xx2,YY ; 縦スクロールバーの針
pos xx0,yy0 : gcopy bid,sbxp,sbyp,xwsz,ywsz ; 窓本体に画像をコピー
return
*buf4 ; おまけ
gsel 4
rnd cr,256 : rnd cg,256 : rnd cb,256
rnd cx,winx : rnd cy,winy
color cr,cg,cb : line cx,cy
return