携帯LEDゲームmk2

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.07を出力に(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.07を出力に(row用)
	tris_re = 0	're.02を出力に(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