http://nicotak.com/picbasic/
PIC-BASIC本で「携帯LEDゲームmk2」として紹介されている落ちゲーを改良してみました。
・画面のワクを取り外し、6ドット幅だった空きスペースを8ドット幅に広げました。
・表示のチカチカが低減しました。プログラムのムダを削って表示ムラをできるだけ抑えています。
・ゲームオーバー時に「得点」が表示されるようになりました。「0」〜「9」のオリジナルフォントを搭載しました。
・プログラムリストが1.5倍に増えました。
空きスペースが増えたら面白くなる、、、と思ったんですが、ボタンのタッチが増えちゃってプレイの緊張感が薄れてしまったような気もします。ゲームバランスは好みに合わせて改造してください。BASICですので書き換えも簡単です。
フラッシュの使用量はまだ3割程度ですので、もっともっと凄いゲームが作れるんじゃないでしょうか。
'64DOTGAME(LEDゲームmk2) for PIC-BASIC 'ブロック落ちゲー8ドット幅バージョン ' 8x8=64ドットマトリックスLED表示器 ' 2色(赤・緑)タイプ「BU5004-RG」使用 ' 'by 松原拓也 '動作無保証 Dim col As Byte 'ダイナミック点灯 Dim x As Byte 'ブロック座標 Dim y As Byte Dim cx As Byte '衝突チェック座標 Dim cy As Byte Dim hit As Byte '衝突フラグ Dim col2 As Byte Dim level As Byte 'ゲームレベル Dim dropcnt As Byte '落下カウンタ Dim block(3) As Byte 'マイブロック情報 Dim blockbak(3) As Byte 'バックアップ用マイブロック情報 Dim i As Byte Dim sx As Byte 'スクロール座標 Dim sy As Byte Dim tx As Byte '文字表示座標 Dim ty As Byte Dim plane As Byte 'プレーン番号 Dim score As Word Dim cnt As Byte Dim data As Byte Dim delay As Byte Dim temp As Byte Dim mask As Byte Dim vram(32) As Word 'vram tris_ra = 0 'ra.0〜7を出力に(col用) tris_rb = &b00001111 'rb.Bit0-3を入力(sw/PGM用) 'rb.Bit4-7を出力(row用) tris_rc = &b10110000 'rc.0-3を出力(row用) 'rc.4-5を入力(sw用) 'rc.6を出力(シリアル送信用) 'rc.7を入力(シリアル受信用) tris_rd = 0 'rd.0〜7を出力に(row用) tris_re = 0 're.0〜2を出力に(row用) newgame: ' 0123456789ABCDEF vram(0+16)= &b0001000000001000 ' vram(1+16)= &b0001000000001000 ' vram(2+16)= &b0001000000001000 ' vram(3+16)= &b0001000000001000 ' vram(4+16)= &b0001000000001000 ' vram(5+16)= &b0001000000001000 ' vram(6+16)= &b0001000000001000 ' vram(7+16)= &b0001000000001000 ' vram(8+16)= &b0001111111111000 ' Gosub newblock '新規マイブロック Gosub block2vram dropcnt=0 level=20 'ゲームレベル sx=4 sy=0 score=0 main: Gosub putvram delay=(delay+1)Mod 60 If (delay=10) Then Gosub move:Goto main If (delay=20) Then Gosub turn:Goto main If (delay=30) Then Gosub drop:Goto main Goto main move: If (rc.Bit4 = 0) Then 'sw2:右ボタン cx=x-1 cy=y Gosub hitcheck 'ブロック衝突チェック If (hit=0) Then x=x-1 Gosub block2vram Return Endif If (rc.Bit5 = 0) Then 'sw3:左ボタン cx=x+1 cy=y Gosub hitcheck 'ブロック衝突チェック If (hit=0) Then x=x+1 Gosub block2vram Return Endif If (rb.Bit3 = 0) Then 'sw5:下ボタン dropcnt = level 'ブロック落下 Endif Return turn: If (rb.Bit0 = 0) Then 'sw1:回転ボタン Gosub turnblock 'マイブロック回転 cx=x cy=y Gosub hitcheck 'ブロック衝突チェック If (hit>0) Then For i=0 To 2 block(i) = blockbak(i) '元に戻す Next Endif Gosub block2vram Endif Return drop: '---------マイブロックの落下、衝突判定 dropcnt=dropcnt+1 If (dropcnt > level) Then dropcnt=0 cx=x cy=y+1 Gosub hitcheck 'ブロック衝突チェック If (hit>0) Then Gosub fixblock 'ブロックを定着 '------------最上段の場合、ゲームオーバー If (vram(0+16) & &b0000111111110000)>0 Then Gosub putscore Goto newgame Endif Else y =y+1 Endif Gosub block2vram Endif Return putvram: '---------vramからLEDに出力 col = (col+1) Mod 8 mask = (1 << col) ^ &b11111111 ra = &b00111111 '表示クリア re = &b00000011 rd = vram(col+sy+16)>>(8-sx) '緑LED temp=vram(col+sy)>>(8-sx) rc = temp & &b1111 '赤LED rb = temp & &b11110000 ra = mask & &b00111111 re = (mask >> 6) & &b00000011 ' ra = &b00111111 ' re = &b00000011 '表示クリア Return '------------------------------ putscore: For i = 0 To 31 vram(i)=0 Next plane=16 tx=0 ty=2 cnt=(score / 1000) Mod 10:Gosub numchar cnt=(score / 100) Mod 10:Gosub numchar cnt=(score / 10) Mod 10:Gosub numchar cnt=score Mod 10 :Gosub numchar For sx=0 To 8 For delay=0 To 250 Gosub putvram Next Next sx=8 For i = 0 To 15 vram(i)=vram(i+16) Next For i=0 To 4 For delay=0 To 250 Gosub putvram Next Next Return '---------------------- numchar: col2=0 '---------16dotデータ(4x5)をvramに転送 Lookup cnt,data,&b0100,&b0100,&b1100,&b1100,&b0010,&b1110,&b0110,&b1110,&b0100,&b0100:Gosub txtsub Lookup cnt,data,&b1010,&b1100,&b0010,&b0010,&b0110,&b1000,&b1000,&b0010,&b1010,&b1010:Gosub txtsub Lookup cnt,data,&b1010,&b0100,&b0100,&b0100,&b1010,&b1100,&b1100,&b0100,&b0100,&b0110:Gosub txtsub Lookup cnt,data,&b1010,&b0100,&b1000,&b0010,&b1111,&b0010,&b1010,&b1000,&b1010,&b0010:Gosub txtsub Lookup cnt,data,&b0100,&b0100,&b1110,&b1100,&b0010,&b1100,&b0100,&b1000,&b0100,&b1100:Gosub txtsub tx=tx+4 Return txtsub: vram(ty+col2+plane) = vram(ty+col2+plane) &(&hffffffff ^ (&b11111 << (12-tx))) vram(ty+col2+plane) = vram(ty+col2+plane) |(data << (12-tx)) col2=col2+1 Return '------------------- block2vram: '---------ブロックをvramに転送 vram(0)=0 ' vram(1)=0 ' vram(2)=0 ' vram(3)=0 ' vram(4)=0 ' vram(5)=0 ' vram(6)=0 ' vram(7)=0 ' '---------マイブロックをvramに転送 vram(y) = block(0) << x ' vram(1+y) = block(1) << x ' vram(2+y) = block(2) << x ' Return '------------------マイブロック回転 turnblock: For i=0 To 2 blockbak(i) = block(i) block(i)=0 Next For i=0 To 2 For col2=0 To 2 block(i) = block(i) << 1 block(i) = block(i) | ((blockbak(col2) >> i) & 1) Next Next Return '-------------------ブロック衝突チェック hitcheck: i=0 hitcheck2: If (vram(i+cy+16) & (block(i)<< cx))<>0 Then hit=1 Return Endif i=i+1 If i<=2 Then Goto hitcheck2 hit=0 Return '-------------------ブロックを定着 fixblock: For i = 0 To 2 vram(i+y+16) = vram(i+y+16) | (block(i)<<x) Next '---------そろった列のブロックを消す For col2 = 0 To 7 If vram(col2+16)=&b0001111111111000 Then For i=col2 To 1 Step -1 vram(i+16)=vram(i-1+16) Next vram(0+16)=&b0001000000001000 If level>0 Then level=level-1 score=score+1 Endif Next Gosub newblock '新規マイブロック Return '---------------------新規マイブロック newblock: i = Peek(&h101) Mod 7 If i=0 Then block(0) = &b010 block(1) = &b010 block(2) = &b010 Endif If i=1 Then block(0) = &b010 block(1) = &b010 block(2) = &b110 Endif If i=2 Then block(0) = &b010 block(1) = &b010 block(2) = &b011 Endif If i=3 Then block(0) = &b000 block(1) = &b111 block(2) = &b010 Endif If i=4 Then block(0) = &b110 block(1) = &b011 block(2) = &b000 Endif If i=5 Then block(0) = &b011 block(1) = &b110 block(2) = &b000 Endif If i=6 Then block(0) = &b110 block(1) = &b110 block(2) = &b000 Endif If (Peek(&h101) Mod 4)=0 Then Gosub turnblock 'マイブロック回転 If (Peek(&h101) Mod 4)=0 Then Gosub turnblock 'マイブロック回転 If (Peek(&h101) Mod 4)=0 Then Gosub turnblock 'マイブロック回転 x=2+4 'ブロック座標 y=0 Return