powered by hsp3dish.js / OpenHSP
YouTube - PONGプレイ動画
Atari の PONG を意識して作りました。
画面の解像度が違ったり、
跳ね返す角度が変わらなかったりとお粗末な点はありますが、
それっぽく出来たんじゃないかなと思います。
Z ボタン - パドルを上に移動
X ボタン - パドルを下に移動
ステップ数 10000 ランタイムバージョン HSP3.5b5
#include "hsp3dish.as" //************************************************************** // // ボールモジュール // //************************************************************** #module mod_ball x, y, spd, rad, dx, dy, flg_collision //============================== // 初期処理、解放処理 //============================== #modinit x = 320.0 y = 0.0 spd = 4.0 rad = M_PI * 5 / 6 dx = spd * cos(rad) dy = spd * sin(rad) flg_collision = 0 return #modterm return //============================== // setter, getter //============================== #modcfunc ballLeft return x #modcfunc ballTop return y #modcfunc ballRight return x+4 #modcfunc ballBottom return y+4 #modcfunc ballCollision return flg_collision #modfunc ballSet double _x, double _y, double _spd, double _rad x = _x y = _y spd = _spd rad = _rad dx = spd * cos(rad) dy = spd * sin(rad) return //============================== // 描画処理 //============================== #modfunc ballDraw boxf x, y, x+4, y+4 return //============================== // 更新処理 //============================== #modfunc ballUpdate var _paddleL, var _paddleR, int _state x += dx y += dy flg_collision = 0 // プレイ状態の場合、パドル衝突処理をする if _state == 1 { // ボールが左パドルに当たる場合 if isCollisionL(_paddleL,thismod) { flg_collision = 1 ballSet thismod, x, y, spd+0.1, M_PI-rad } // ボールが右パドルに当たる場合 if isCollisionR(_paddleR,thismod) { flg_collision = 2 ballSet thismod, x, y, spd+0.1, M_PI-rad } } // 上壁に当たる場合 if y <= 0 { flg_collision = 4 if _state == 0 { ballSet thismod, x, y, spd, -rad } else { ballSet thismod, x, y, spd+0.1, -rad } } // 下壁に当たる場合 if y >= 476 { flg_collision = 8 if _state == 0 { ballSet thismod, x, y, spd, -rad } else { ballSet thismod, x, y, spd+0.1, -rad } } // 左壁に当たる場合 if x <= 0 { flg_collision = $10 ballSet thismod, x, y, spd, M_PI-rad } // 右壁に当たる場合 if x >= 636 { flg_collision = $20 ballSet thismod, x, y, spd, M_PI-rad } return #modfunc ballSpeedUp spd += 0.1 return #global ; パドルモジュール #module mod_paddle x, y //============================== // 初期処理、解放処理 //============================== #modinit int _x, int _y x = _x y = _y return #modterm return //============================== // setter, getter //============================== #modcfunc paddleLeft return x #modcfunc paddleTop return y #modcfunc paddleRight return x+4 #modcfunc paddleBottom return y+40 #modcfunc paddleCenter return y+20 #modfunc paddleSet int _x, int _y x = _x y = _y return //============================== // 描画処理 //============================== #modfunc paddleDraw boxf x, y, x+4, y+40 return //============================== // 移動処理 //============================== #modfunc paddleUp y = limit(y-2,0,440) return #modfunc paddleDown y = limit(y+2,0,440) return //============================== // 左パドルにボールが当たったか判定 //============================== #modcfunc isCollisionL var _ball if ballLeft(_ball) <= paddleRight(thismod) { if ballTop(_ball) <= paddleBottom(thismod) { if ballBottom(_ball) >= paddleTop(thismod) { return 1 } } } return 0 //============================== // 右パドルにボールが当たったか判定 //============================== #modcfunc isCollisionR var _ball if ballRight(_ball) >= paddleLeft(thismod) { if ballTop(_ball) <= paddleBottom(thismod) { if ballBottom(_ball) >= paddleTop(thismod) { return 1 } } } return 0 #global //************************************************************** // // ゲームモジュール // //************************************************************** #module mod_game //============================== // 点数表示 //============================== #deffunc gameDrawSeg int _x, int _c // 点数が負の場合何もしない if _c < 0 : return // switch _c \ 10 case 0 : code = $3f : swbreak case 1 : code = $06 : swbreak case 2 : code = $5b : swbreak case 3 : code = $4f : swbreak case 4 : code = $66 : swbreak case 5 : code = $6d : swbreak case 6 : code = $7d : swbreak case 7 : code = $07 : swbreak case 8 : code = $7f : swbreak case 9 : code = $6f : swbreak swend // クリア color : boxf _x, 40, _x+40, 128 : hsvcolor ,,$ff // 7セグメント表示 if code & $01 : boxf _x, 40, _x+40, 48 ; A if code & $02 : boxf _x+32, 40, _x+40, 80 ; B if code & $04 : boxf _x+32, 72, _x+40, 128 ; C if code & $08 : boxf _x, 120, _x+40, 128 ; D if code & $10 : boxf _x, 72, _x+8, 128 ; E if code & $20 : boxf _x, 40, _x+8, 80 ; F if code & $40 : boxf _x, 72, _x+40, 80 ; G // 10の位 if _c / 10 { if _x == 200 : gameDrawSeg 112, _c/10 if _x == 488 : gameDrawSeg 400, _c/10 } return #global //************************************************************** // // メイン // //************************************************************** *maininit ; gameInit screen 0, 640, 480 // 効果音 mmload "bounce0.wav", 0, 0 mmload "bounce1.wav", 1, 0 mmload "bounce2.wav", 2, 0 mmplay 0 // モジュール型変数宣言 newmod paddleL, mod_paddle, 16, -100 ; 最初は画面外に隠しておく newmod paddleR, mod_paddle, 620, -100 ; newmod ball, mod_ball // ゲーム状態 0:デモ 1:プレイ中 state = 0 *mainset ; gameReset cnt_frame = -2147483648 // 点数リセット cntL = 0 cntR = 0 // ボールとパドルをリセット if state == 0 { // デモ状態の場合 ballSet ball, 320, 0, 4.0, M_PI*5/6 paddleSet paddleL, 16, -100 paddleSet paddleR, 620, -100 } else { // プレイ中の場合 ballSet ball, 320, 0, 1.0, M_PI*5/6 paddleSet paddleL, 16, 0 paddleSet paddleR, 620, 0 } *mainloop //============================== // 出力 //============================== ; gameDraw // 画面クリア color : boxf : hsvcolor ,,$ff // センターライン repeat 32 line 320, 15*cnt, 320, 15*cnt+7 loop // パドルと点数 if state != 0 { // パドル paddleDraw paddleL paddleDraw paddleR // 点数 gameDrawSeg 200, cntL gameDrawSeg 488, cntR } // ボール表示 ballDraw ball // 画面更新 redraw 1 : await 16 : redraw 0 //============================== // 入力 //============================== ; gameInput getkey key, 27 ; ESCキー if key : goto *mainterm if state != 2 { getkey key, 'Z' if key { paddleUp paddleL if state == 0 { state = 1 goto *mainset } } getkey key, 'X' if key { paddleDown paddleL if state == 0 { state = 1 goto *mainset } } } getkey key, ' ' if key : stop //============================== // 更新処理 //============================== ; gameUpdate cnt_frame ++ // ボール更新処理 if state != 2 { ballUpdate ball, paddleL, paddleR, state } // プレイ状態の場合、効果音を再生 if state == 1 { // ボールが左パドルに当たった場合 if ballCollision(ball) & $1 { mmplay 0 } // ボールが右パドルに当たった場合 if ballCollision(ball) & $2 { mmplay 0 } // 上壁に当たる場合 if ballCollision(ball) & $4 { mmplay 1 } // 下壁に当たる場合 if ballCollision(ball) & $8 { mmplay 1 } } // 左壁に当たる場合 if ballCollision(ball) & $10 { if state == 1 { state = 2 cntR ++ cnt_frame_pre = cnt_frame mmplay 2 ballSet ball, 320.0, 0.1, 1.0, M_PI/5*6 } } // 右壁に当たる場合 if ballCollision(ball) & $20 { if state == 1 { state = 2 cntL ++ cnt_frame_pre = cnt_frame mmplay 2 ballSet ball, 320.0, 0.1, 1.0, M_PI/6 } } // COM処理 if state == 1 { if ballBottom(ball) >= paddleCenter(paddleR) { paddleDown paddleR } else : if ball_y <= bar2_y+20 { paddleUp paddleR } } // 停止処理 180フレーム(3秒)分停止 if state == 2 and (cnt_frame - cnt_frame_pre > 180) { state = 1 } // 終了処理 if state == 1 and (cntL >= 11 or cntR >= 11 ) { state = 0 goto *mainset } // *mainまで戻る goto *mainloop *mainterm ; gameTerm delmod ball delmod paddleR delmod paddleL end