パソコン活用研究5番街(Visual Basic、Excel(VBA)、BASIC プログラミング研究)
Pongゲーム (Quick Basic)
==========================================================================================
PongゲームをQuick Basicで作成してみます。
大元はChatGPTで作成したC言語のPongゲーム(->Pongゲームを作ってみた)です。これは全画面消去―>全画面
再描画を繰り返しているので、時々画面がちらつくことがありました。
このちらつき解消のため、変化のあった部分だけ消去、描画するようにプログラムを少しだけ変更してたのがC言語の
改良版Pongゲーム(->Pongゲーム)です。
ました。
これをさらにQuick Basicに移植してみました。
==========================================================================================
Pongゲームは左右のパドルでボールを打ち返すというシンプルなゲームです。
Pongゲームの画面

@メインルーチンと関数
メインルーチンはDo ... Loopのループの中でぐるぐる回っており、
押されたキーの取得 -> プレーヤのパドルの移動と再描画 -> ボールを消す -> コンピュータ側のパドルの
移動と再描画 -> ボールの描画 -> 衝突判定
を繰り返しています。
プレーヤの再描画、ボールを消す、コンピュータ側のパドルの移動と再描画、ボールの描画
は関数を作り、関数をコールして処理しています。
関数
erasePaddle パドルの消去
drawPaddle パドルの描画
eraseBall ボールの消去
drawBall ボールの描画
movepaddle2 コンピュータ側のパドルの移動
setup ゲームの初期設定
A LOCATE
スクリーンの座標位置はLOCATEで指定している。
Quick BasicのLOCATEはちょっと変わっていて、LOCAT Y座標, X座標 の順で座標位置を指定する。
B キー入力
BASICのINKEY$はキーの値をキーバッファから読み込むので、リアルタイムキー入力の必要なプログラム
を作ろうとすると、オートリピートでキーバッファにたまったキー入力の値をどうするかという問題が発生します。
詳しくはリアルタイムキースキャン(INPを使う)をご参照下さい。
このためプレーヤ側のパドル移動のためのキー入力の最初のところでオートリピートによる不用意な動きを
防止するため、キーバッファにたまったキーをクリアし、最後のキーだけを取り出す工夫をしています。
k$ = INKEY$
IF k$ <> "" THEN key$ = k$: GOTO keyin
C スピード調整
Quick Basic(ver2〜5)にあるSLEEPは1秒単位での指定しかできないため、Forループをかましてゲームスピード
の調整をしている。
pong.bas
DECLARE SUB erasePaddle (x!, y!)
DECLARE SUB drawPaddle (x!, y!)
DECLARE SUB eraseBall (x!, y!)
DECLARE SUB drawBall (x!, y!)
DECLARE SUB setup ()
DECLARE SUB movePaddle2 ()
SCREEN 12
CONST PADDLEHEIGHT = 5
DIM SHARED ballX, ballY, ballDirX, ballDirY, paddle1Y, paddle2Y, score
CLS
setup
DO
' Move the paddles
keyin:
k$ = INKEY$
IF k$ <> "" THEN key$ = k$: GOTO keyin
IF key$ = "w" AND paddle1Y > 2 THEN
erasePaddle 2, paddle1Y
paddle1Y = paddle1Y - 1
drawPaddle 2, paddle1Y
END IF
IF key$ = "s" AND paddle1Y < 24 THEN
erasePaddle 2, paddle1Y
paddle1Y = paddle1Y + 1
drawPaddle 2, paddle1Y
END IF
key$ = ""
eraseBall ballX, ballY
' Update the ball's position
ballX = ballX + ballDirX
ballY = ballY + ballDirY
movePaddle2
' Draw ball and score
drawBall ballX, ballY
LOCATE 30, 30
PRINT "Score "; score;
' Ball collision with top and bottom walls
IF ballY >= 28 OR ballY <= 2 THEN
ballDirY = -ballDirY
END IF
' Ball collision with paddles
IF ballX = 3 AND (ballY >= paddle1Y AND ballY <= paddle1Y + PADDLEHEIGHT) THEN
ballDirX = -ballDirX
score = score + 1
END IF
IF ballX = 76 AND (ballY >= paddle2Y AND ballY <= paddle2Y + PADDLEHEIGHT) THEN
ballDirX = -ballDirX
END IF
' Ball out of bounds (scoring)
IF ballX <= 1 OR ballX >= 79 THEN
EXIT DO
END IF
' delay to control the game speed
FOR m = 0 TO 100
FOR n = 0 TO 1000
NEXT n
NEXT m
' SLEEP 1 ' Sleep to control the game speed
LOOP
LOCATE 14, 40: PRINT "MIss!"; " Your Score "; score;
SUB drawBall (x, y)
LOCATE y, x
PRINT "O";
END SUB
SUB drawPaddle (x, y)
FOR i = 0 TO PADDLEHEIGHT - 1
LOCATE y + i, x
PRINT "|";
NEXT i
END SUB
SUB eraseBall (x, y)
LOCATE y, x
PRINT " ";
END SUB
SUB erasePaddle (x, y)
FOR i = 0 TO PADDLEHEIGHT - 1
LOCATE y + i, x
PRINT " ";
NEXT i
END SUB
SUB movePaddle2
' Simple AI: Match the ball's vertical position
IF ballY < paddle2Y + PADDLEHEIGHT / 2 AND paddle2Y > 2 THEN
erasePaddle 77, paddle2Y
paddle2Y = paddle2Y - 1
drawPaddle 77, paddle2Y
ELSEIF ballY > paddle2Y + PADDLEHEIGHT / 2 AND paddle2Y < 24 THEN
erasePaddle 77, paddle2Y
paddle2Y = paddle2Y + 1
drawPaddle 77, paddle2Y
END IF
END SUB
SUB setup
ballX = 40
ballY = 12
ballDirX = -1
ballDirY = 1
paddle1Y = 10
paddle2Y = 10
score = 0
LOCATE 1, 3: PRINT "##########################################################################";
LOCATE 29, 3: PRINT "##########################################################################";
' Draw paddles
' FOR i = 0 TO PADDLEHEIGHT - 1
drawPaddle 2, paddle1Y + i
drawPaddle 77, paddle2Y + i
' NEXT i
END SUB