パソコン活用研究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