Visual Basic 中学校 投稿プログラム |
ステップアップパズル
投稿者:カズさん
ステップアップパズルはいろいろな形のブロックを組み合わせて木箱の隙間を埋めるゲームです。
ゲーム自体もシンプルなルールで楽しめますし、プログラムも図形のドラッグ&ドロップや、回転・裏返しのアニメーションなど参考になるテクニックでいっぱいです。ソースコードもダウンロードできますので是非中を覗いて見てください。
ダウンロード
StepupPuzzle.lzh(30.1KB)
VB2005で作成されたソースコード。プログラマ向けです。 ソースコードを編集するためにはVB2005が必要です。Express Editionでも大丈夫です。 改変したプログラムの公開は可能ですが、末尾にあるメッセージの趣旨に従ってください。
ダウンロード HPG 46a.lzh(25.5KB) exeファイルのみ。遊んで見たい人向けです。実行するには.NET Framework 2.0以上が必要です。 |
V太:博士!やりましたよ!ゲームの投稿です!
■画像1:「開始」直後
B子:マウスでブロックをドラッグして隙間を埋めるのね。
■画像2
なかなか面白いですよ。レベルが選択できるからぼくでも何とかなります。
それにしても、このゲームもVBでできているんでしょう?回転とか裏返しのアニメーションまであるし、どうやっているのかしら?
ついに噂のDirectX登場ですか?!
博士:いやいや。このゲームは標準のVBの機能だけでつくってあるぞ。DirectXなどは一切使っておらん。
ふーん…。じゃあプログラムを開いてフォームを見てみようかな…。
あれれ!なにこれ?!
実行するといろいろな形のブロックに見えるのに、フォームに張り付いているのは普通のPictureBoxなのね。博士、これはどういうことかしら?
ふむ。PictureBoxの変形にはRegionを利用しておるのじゃ。Regionは知っておるかな?Regionはただ単に図形を描画しているだけではなく、PictureBoxそのものを変形させていると考えた方が良いじゃろう。
たとえば、次のプログラムではマウスに反応してPictureBoxの色が変わるのじゃが、Regionを使ってPictureBoxを三角形に変形させると、ちゃんと三角形の領域内にマウスが入らないと色が変わらないようにできる。
この例を試すにはフォームにPictureBoxを1つとButtonを1つ貼り付けるのね。
Private Sub
Button1_Click(ByVal sender
As System.Object,
ByVal e As System.EventArgs)
Handles Button1.Click '三角形の頂点を定義 Dim Points(2) As Point Points(0) = New Point(100, 0) '上 Points(1) = New Point(0, 173) '左下 Points(2) = New Point(200, 173) '右下 '三角形を生成 Dim Path As New Drawing2D.GraphicsPath Path.AddLines(Points) 'PictureBoxを変形 PictureBox1.Region = New Region(Path) End Sub |
Private Sub PictureBox1_MouseEnter(ByVal
sender As Object,
ByVal e As
System.EventArgs) Handles
PictureBox1.MouseEnter PictureBox1.BackColor = Color.SeaGreen End Sub |
Private
Sub PictureBox1_MouseLeave(ByVal
sender As Object,
ByVal e As
System.EventArgs) Handles
PictureBox1.MouseLeave PictureBox1.BackColor = Color.Lime End Sub |
■リスト1:三角形を生成するサンプル。
博士〜。これはこれで面白いんですけど、ゲームの方がもっとすごいですよ。図形を回転させたり、裏返したするときにアニメみたいに動きます。これは、どうやっているか想像もできないんですけど…。
ふむふむ。じゃがの。上の例が理解できれば工夫次第で何でもできるのじゃよ。今回のゲームではTimerを使って少しずつ図形の形を変えることで回転や裏返しを実現していおる。ゲームのプログラムで言うとTimer2のTickイベントが回転、Timer3のTickイベントが裏返しじゃ。
実際のゲームでは複数の図形を扱うし他にも考えなければいけないこともあるので「少しずつ図形の形を変える」という処理が複雑になっておる。そこで、ここでは話を単純にして、さっきの三角形のプログラムで裏返しの例を示すと次の通りじゃ。
この例を試すにはフォームにPictureBoxを1つとTimerを1つ貼り付けるのね。
'''
<summary>Timer作動回数(=Tickイベントが実行された回数)</summary> Dim TickCount As Integer ''' <summary> ''' 何回の描画で裏返しが終了するか。 ''' この値が大きいほどなめらかなアニメーションになるが、 ''' 実行時間が長くなる。 ''' </summary> Const TotalTickCount As Integer = 101 '何回の描画で裏返しが終了するか。 ''' <summary>X座標算出に使用する基本角度(ラジアン)。※高校数学の知識が必要</summary> Dim Theta As Double = Math.PI / TotalTickCount |
Private Sub Form1_Load(ByVal
sender As System.Object,
ByVal e As
System.EventArgs) Handles
MyBase.Load 'Timer起動 Timer1.Interval = 20 '0.02秒ごとにTickイベントを実行。 Timer1.Enabled = True '※実行総時間= Timer1.Interval ×TotalTickCount ミリ秒 End Sub |
Private
Sub Timer1_Tick(ByVal
sender As System.Object,
ByVal e As
System.EventArgs) Handles Timer1.Tick 'Tickイベント作動回数を記録 TickCount += 1 '変形途中の三角形を定義 Dim Points(2) As Point Points(0) = New Point(100, 0) Points(1) = New Point(100 * Math.Cos(Theta * TickCount) + 100, 173) Points(2) = New Point(200 - Points(1).X, 173) '三角形を生成 Dim Path As New Drawing2D.GraphicsPath Path.AddLines(Points) 'PictureBoxを変形 PictureBox1.Region = New Region(Path) '表面と裏面とで色を変える。 If TickCount < TotalTickCount / 2 Then PictureBox1.BackColor = Color.Lime Else PictureBox1.BackColor = Color.SeaGreen End If '裏返しが完了したらTimerを停止 If TickCount = TotalTickCount Then TickCount = 0 Timer1.Enabled = False End If End Sub |
■リスト2:三角形を裏返すアニメーション
なんか全然単純に見えないんですけど…。
座標を計算している式が難しいわ。特にPoints(1)の計算が全然わからない。
うーーん。そこをつかれると弱いのぉ。回転移動を自分でプログラムすると、どうしても高校数学の知識が必要になってしまうのじゃ。ここでは三角関数のCos(コサイン)を使用しておる。ただCosが魔法の関数なのではなく足し算や引き算と同じで単に座標を計算するのに使っているだけと言うことは分かっておいてほしい。
この方法でのアニメーションの本質は座標を少しずつずらしてあたかも動いているように見せることにある。パラパラ漫画の原理じゃ。
本当に少しずつ座標を変えた値をセットしてもよいのじゃが、そうするとプログラムの大部分が座標の指定になってしまう上に後から座標を変更するのが大変になる。そこで、計算で座標を求めておるのじゃ。
上の例ではおおよそ50個の形の違う三角形を連続して描画することにより動いているように見せかけておる。そして、50個の三角形の座標を求めるのにCosを使用しているというわけじゃ。
僕も自分で計算したいからCos(コサイン)を教えてくださ〜い。
V太は小学校の算数もよく間違えるのに、いきなり高校で習う数学なんてわかるわけないじゃないの!
いやいや。そんな風にあきらめる前にCosがどういうものか調べてみるのも悪くないじゃろう。
http://www.musashino.ac.jp/m/1/no5/05.htm
それにしてもこのプログラムってなんか日本語が多いわね。
ぼくにも読みやすくてありがたいです。きっと小学生向けなんですよ!コメントもちゃんと入っています。
小学生向けかどうかはわからんが…。
日本語はまぁ良いのじゃが、このプログラムには課題もある。わかるかな?
えっと。フォームのタイトルが「Form1」のままになっていたり、使っていないTextBoxがフォームに張り付いたりしているみたいです。
ほほ。なるほどの。それも良くはないが、いつでも簡単に修正できるから大きな課題ではないのぉ。
全体的に変数が整理されていない感じがするわ。2次元配列や3次元配列を使ってまとめてはあるんだけど、図形ごとにまとめる形をとった方がわかりやすいんじゃないかしら?
うむ。いいところに目をつけたの。まぁプログラマの趣向もさまざまだから一概には言えんのじゃが、VBではオブジェクトに着目してオブジェクトごとにデータと振舞いをまとめるプログラムの方がしっくりくることが多い。
わかった!オブジェクト指向ですね!
方向性としてはまさにそのとおり。
となると、図形をあらわすクラスを作ってそこに頂点の座標や色をプロパティとして実装するのね。
それに回転するRotateメソッドや、裏返しするReverseメソッドを作るとかっこいいや。回転するにはMyPolygon.Rotateみたいに書くんだ。
2人の言う通りじゃ。じゃが、このプログラムが「完成している」という点にも注意してほしい。どんなにオブジェクト指向や最新の技術を使っても完成していないプログラムは役に立たないのじゃ。
それに引き替え、このプログラムはオブジェクト指向的ではないが、ちゃんと整理されていて、完成していて、ちゃんとゲームで遊ぶことができる。「完成」しているというこは素晴らしいことなのじゃ。
投稿していただいた カズさん、楽しくて参考になるプログラムを送っていただいて本当にありがとうございます!今後もみなさんからのプログラムの投稿をお待ちしています。
カズさんからのメッセージにも目を通してみてください。
カズさんからのメッセージ著作権ですが、これもあまりこだわりません。 それより、Visual Basic 中学校の参加者の皆様の学習の参考になればと思います。例えば、レベルアップするのに、クリア条件を自分で考えて織り込んだりするように、面白い仕様を考えて改善することなど、楽しんで学習していただければ幸いです。 そうすることにより、ソフトを読んだり、作ったりすることにより勉強になると思います。 ソフトを改善した場合の希望は、原作者の名前として「カズ」を入れてもらえることです。そして、改善者1、その改善者2と言うように、改善者の名前を入れることにより、改善意欲が高まれば、意欲的にVisual Basicの学習でると思います。そうするために、ソースを公開する必要があります。 |