ブロックを積む(10)
「はじめてのVectorScript」と題して連載を始めるわけですが、本連載は「Vectorworksは持っているけどVectorScriptって何?」、「プログラミングって難しいんでしょ?」「アイデアはあるんだけど...」という人が「それ、VectorScriptでやれば簡単だよね」と言えるくらいになるのが目標です。
VectorworksはMacintosh版とWindows版とのマルチプラットホーム環境でありながらも、VectorScriptはOSを意識することのなくプログラミングが可能で、どちらでプログラミングしてもソースコードの変更なしでMacintosh、Windowsどちらでも実行が可能です。そしてVectorworksを持っていればいますぐにでも始められます。
ゲーム機の場合、DQ7(ソフト)で遊びたいという理由で3DS(ハード)を選ぶと思います。「このソフト(あなたが書いたスクリプト)を使いたいためにVectorworksを選びました」と言わせるようなプログラムを目指してがんばりましょう。自分のアイデアをプログラム化しブログで公開なんてことも夢ではありません。
第10章 マウスクリックによる描画
VectorScriptには、ユーザが2D基準点を打つように、直線を引くように、四角形を描くように、マウスクリックの座標を取得できる手続きを用意しています。
例えば、2D基準点を打つようなマウスクリックを拾うことのできる、
手続きGetPt(VAR pX, pY : REAL);
を使うことで、ブロックを書類のどこから描くかを決めることができます。
PROCEDURE sample; LABEL 9999; VAR pX, pY : REAL; iX, iY : INTEGER; rX, rY, rZ : REAL; ii, jj : INTEGER; BEGIN IF NOT YNDialog( 'スクリプトを実行しますか?' ) THEN BEGIN GOTO 9999; END; GetPt( pX, pY ); iX := IntDialog( '横方向のブロック数?', '9' ); IF DidCancel OR ( ix = 0 ) THEN BEGIN GOTO 9999; END; iY := IntDialog( '縦方向のブロック数?', '5' ); IF DidCancel OR ( iy = 0 ) THEN BEGIN GOTO 9999; END; rX := RealDialog( 'ブロックのx方向の長さは?', '50' ); IF DidCancel OR ( rX = 0 ) THEN BEGIN GOTO 9999; END; rY := RealDialog( 'ブロックのy方向の長さは?', '30' ); IF DidCancel OR ( rY = 0 ) THEN BEGIN GOTO 9999; END; rZ := RealDialog( 'ブロックのz方向の長さは?', '30' ); IF DidCancel OR ( rZ = 0 ) THEN BEGIN GOTO 9999; END; FOR jj := 0 TO iy-1 DO BEGIN FOR ii := jj TO iX-1 DO BEGIN BeginXtrd( 0+jj*rZ, rZ+jj*rZ ); Rect( pX+ii*rX, pY, pX+rX+ii*rX, pY+rY ); IF ( jj MOD 2 = 0 ) AND ( ii MOD 2 <> 0 ) THEN BEGIN SetFillBack( LNewObj, 39321, 26214, 13107 ); END ELSE IF ( jj MOD 2 <> 0 ) AND ( ii MOD 2 = 0 ) THEN BEGIN SetFillBack( LNewObj, 39321, 26214, 13107 ); END; EndXtrd; END; END; AlrtDialog( '計算が終了しました。' ); 9999: END; Run( sample );
つぎに、 直線を引くようなマウスクリックを拾うことのできる、
手続きGetLine(VAR p1X, p1Y, p2X, p2Y : REAL);
手続きHRotate(h : HANDLE; centerX, centerY : REAL; rotationAngle : REAL);
を使って、四角形の位置と角度を変更してみましょう。
2点の座標から、計算による角度算出も可能ですが、
手続きMoveTo(pX, pY : REAL);
手続きLineTo(pX, pY : REAL);
関数HAngle(h : HANDLE):REAL;
を使って直線を引いてしまって、その図形から角度を取得するなんてことも可能です。
描いた直線は、
手続きDelObject(h : HANDLE);
を使って消すのをお忘れなく。
PROCEDURE sample; LABEL 9999; VAR p1X, p1Y, p2X, p2Y : REAL; rr : REAL; iX, iY : INTEGER; rX, rY, rZ : REAL; ii, jj : INTEGER; BEGIN IF NOT YNDialog( 'スクリプトを実行しますか?' ) THEN BEGIN GOTO 9999; END; GetLine( p1X, p1Y, p2X, p2Y ); MoveTo( p1X, p1Y ); LineTo( p2X, p2Y ); rr := HAngle( LNewObj ); DelObject( LNewObj ); iX := IntDialog( '横方向のブロック数?', '9' ); IF DidCancel OR ( ix = 0 ) THEN BEGIN GOTO 9999; END; iY := IntDialog( '縦方向のブロック数?', '5' ); IF DidCancel OR ( iy = 0 ) THEN BEGIN GOTO 9999; END; rX := RealDialog( 'ブロックのx方向の長さは?', '50' ); IF DidCancel OR ( rX = 0 ) THEN BEGIN GOTO 9999; END; rY := RealDialog( 'ブロックのy方向の長さは?', '30' ); IF DidCancel OR ( rY = 0 ) THEN BEGIN GOTO 9999; END; rZ := RealDialog( 'ブロックのz方向の長さは?', '30' ); IF DidCancel OR ( rZ = 0 ) THEN BEGIN GOTO 9999; END; FOR jj := 0 TO iy-1 DO BEGIN FOR ii := jj TO iX-1 DO BEGIN BeginXtrd( 0+jj*rZ, rZ+jj*rZ ); Rect( p1X+ii*rX, p1Y, p1X+rX+ii*rX, p1Y+rY ); HRotate( LNewObj, p1X, p1Y, rr ); IF ( jj MOD 2 = 0 ) AND ( ii MOD 2 <> 0 ) THEN BEGIN SetFillBack( LNewObj, 39321, 26214, 13107 ); END ELSE IF ( jj MOD 2 <> 0 ) AND ( ii MOD 2 = 0 ) THEN BEGIN SetFillBack( LNewObj, 39321, 26214, 13107 ); END; EndXtrd; END; END; AlrtDialog( '計算が終了しました。' ); 9999: END; Run( sample );