第11回 何か作ってみよう「3.ムシは無視して障害物」

11−3 ムシは無視して障害物

どちらから作ろう、と考えた時にメインから作って、周りは後から作れば良いんじゃない?って思いがちですが、それとこれとは話が違うようです。要は、ケースバイケース、良く考えて作りやすいほうから作りましょう。
「良く考えて」などと言うと難しそうですが、考えてみれば「自由に作れ」ってことですから気楽に行きましょう(文章はカタいですが・・・)

じゃあ、今回は、どっちから作れば良いか考えてみましょう。
今回のプログラムでは、メインとなる部分がムシの移動ですが、実際、ムシの移動は、たまに発生する障害物の有無に左右されるわけですね。
つまり、障害物があれば、ムシはそれ以上進めない訳ですから、動作上の主導権は、ムシより障害物にあると考えるのが自然でしょう。面白い事ですが、処理の重さや流れの位置付けとは無関係に、動作上の「土台」があるわけです。
難しそう?・・・いえいえ、このことは、プログラムの事を忘れて考えれば、スッキリします。障害物があるべき地面がなければムシは居られないでしょ?
ということで、ここでのタイトル通り、ムシを無視して障害物の処理から作り始める方が良さそうです(オヤジギャグですね。)

障害物、ま、作りやすいことを考えて、単なる四角い「ブロック」にしましょう。
さてと、画面をタップすることでブロックを置いたり消したりする、という処理は、実は、初登場ではありません。
Basic BASICの熱烈な読者の方なら、ピンと来るでしょうが、私は、書き始める直前まで忘れていました(汗)
第6回のイベントのお話の「6−3 画面をタップ その2」を参照して下さい。

で、手抜きなんですが、学習的意義として、ここでは、ソースの掲載を中心にしましょう。
必要な変数類や簡単な説明は「できるだけ」付けておきますので、しっかり解読して下さい。

最初は、画面回りをちょっと設定してみます。ま、キリのよいところで、10x10ピクセルのブロックにしましょう。

     10x10のブロック:画像ID 1005

ブロックを描いたら、消すものが要りますね。これは大抵セットです。

    白ブロックはここだよ〜!!" 10x10の白ブロック:画像ID 1004
    ↑(一応、ここにあるんですが見えないか・・・)

白と黒のブロックの画像IDを1005,1004になるように読み込んでみましたが、これは、後程出てくるプログラムのためです。

一方、土台となるスクリーンは、次のようなマス目を考えてそこに置くことにしましょう。
Palmのスクリーンが160x160ですから、単純に10分の1スケールになっただけですね。

    

このマス目をMaze(x,y)というグローバル変数に定義します。マス目(i,j)にブロックがあれば 1、なければ 0、とします。
まずは、Startupコードで、その変数を定義します。
    Sub Project_Startup()
        Global Maze(16,16) as Integer
    End Sub
配列を定義した初期値は、数値であれば 0 になるので、あえて数値を代入して初期化する必要はありませんね。

ブロックの処理は、画面をタップする、というイベントによって引き起こされますので、この時点で、After()には、何もコードは要りませんね。なので、フォーム(Form1003)のEvent()で、ブロックの処理をするだけです。
緑色部分は、ちょっと長いですが注釈です。本文はとても短いです。
    Sub Form1003_Event()

       'イベントは、ペンでタップした時です
       If GetEventType()=nsbPenDown Then
        
            Dim Xi as Integer
            Dim Yi as Integer
 
            'タップした座標を取得します      
            GetPen Xi,Yi,nsbPenDown
        
            'それを10分の1すれば、上のマスメになります
            Xi=Xi/10
            Yi=Yi/10
            'ただ、この時点では、Palmのスクリーンが0〜159ですので、Xi、Yiは0〜15になっています
            'Maze(i,j)を参照する場合、i,j=1〜16である点に注意して下さい

            '最初はこうしていたのですが、やや煩雑です。
            'If Maze(Xi+1,Yi+1)=0 Then
            '    DrawBitmap 1005,Xi*10,Yi*10
            '    Maze(Xi+1,Yi+1)=1
            'Else
            '    DrawBitmap 1004,Xi*10,Yi*10
            '    Maze(Xi+1,Yi+1)=0
            'End If
        
            'そこで、こうしてみました。こちらの方がスッキリしますね。
            '仕掛けは簡単。ABS(n)は絶対値を返します。変数Maze(i,j)には、ブロック無=0、有=1です
            '例えば、無しのときは、Maze(i,j)=0 → Maze(i,j)-1 = -1 → ABS(Maze(i,j)-1) = 1 ですね
            '一報の、有りの場合は、Maze(i,j)=1 → Maze(i,j)-1 = 0 → ABS(Maze(i,j)-1) = 0 ですね
            '上手い事、0と1を反転させる事が出来るので、上のようなIfを使わなくても良くなります
            Maze(Xi+1,Yi+1)=ABS(Maze(Xi+1,Yi+1)-1)
        
            'ブロックの描画処理も、適度にブロック画像の番号を考えればIfを使わなくても良くなります
            DrawBitmap 1004+Maze(Xi+1,Yi+1),Xi*10,Yi*10
        
        End If
        'このRedrawで、Formを再描画するので、After()に戻れます。定番ですね。
        Redraw            

    End Sub
ということで、白ブロックの画像IDを1004、黒ブロックの画像IDを1005にした訳ですが、こんなの、慣れないとわからないよ〜、という声が出そうです。確かにそうです、慣れと経験でしょう。それでも、自分のソースだけだと限界がありますので、人のソースを見る機会があれば、大事にしたいものですね。
一応、補足しておくと、Maze(i,j)でブロックの有無が、有=1、無=0、なので、有りの方の画像番号を大きくしておいた方が楽そうだ、という所に気がつくと良いですね。

手抜きといいつつ、結構な説明になってしまったかも知れませんが、これで、画面をタップしてブロックを表示したり消したりする部分は出来てしまいました。第11回にもなると、簡単に感じるでしょ? 次は、ムシの移動です。

戻る     目次へ     次へ

第11回 何か作ってみよう「3.ムシは無視して障害物」