Hatena::Groupnadesiko

雪乃☆雫のなでしこ日和

2019-05-07

ぽん!

| 16:15

 皆様、長すぎる10連休はいかがお過ごしでしたか?

 めいっぱい羽を伸ばせた方、はあ? 何のことっすか?! 休みなんかねーよ!とゆう方、滅多にあることじゃないから有効活用しなきゃと頑張って、なんかもうむしろぐったり…な方などいらっしゃることでしょう。

 ワタシはこの季節は標準で、休日ごと山菜採ったり、畑耕したりと忙しいもので、今年は何気に肉体労働にいしむ忙しい日が増えたのでした(´д`)

 んな中、『押されたキー』『マウスX』『マウスY』のイベント値が取れるようになって以来、ゲームゲームと言い続けながらも放置していたゲームを頑張って完成させてみた。

 昔懐かしいPONG的なテーブルテニスゲームです。

#---宣言----------
画面w=640。画面h=480。マウス上マージン=80。
玉w=10。玉h=10。dx=0。dy=0。
玉初期x=画面w/2-玉w/2。玉初期y=画面h/2-玉h/2。
玉x=玉初期x。玉y=玉初期y。
玉タイマーID=。

パドルw=5。パドルh=50。パドル位置=25。
パドルx=配列。パドルy=配列。
パドルx[1]=パドル位置。パドルy[1]=画面h/2-パドルh/2。
パドルx[0]=画面w-パドル位置。パドルy[0]=画面h/2-パドルh/2。
COMパドルタイマーID=。COM早さ=4。
元y=画面h/2-パドルh/2。y=画面h/2-パドルh/2。

得点=配列。得点[1]=0。得点[0]=0。
勝点=5。ラリー=0。単ラリー=0。

側面音=「Pong_8_7F.mp3」
パドル音=「Pong_8_8F.mp3」
失点音=「Bu_71_2B.mp3」
得点音=「SE_16_7FGB.mp3URL=「15_Pong.html」

#---HTMLの設置----------
HTML=「<div id="base"><div id="main"><div id="msk"></div>
    <canvas id="court" width=640 height=480></canvas>
    <canvas id="Paddle1" width=5 height=50></canvas>
    <canvas id="Paddle0" width=5 height=50></canvas>
    <canvas id="ball" width=10 height=10></canvas>
    <div id="Player1"></div><div id="Player0"></div>
    <div id="Point1">0</div><div id="Point0">0</div>
    <span id="syohai"></span>
    <fieldset id="option">
    <legend>設定</legend>
      <fieldset id="P"> <!-- P(プレイヤー位置) -->
        <input type="radio" id="P1" name="Player">1P(左側)でプレイする<BR>
        <input type="radio" id="P0" name="Player">2P(右側)でプレイする
      </fieldset> <!-- P -->
      <fieldset id="S"> <!-- S(効果音有り無し) -->
        <input type="checkbox" id="SE">効果音を鳴らす?
      </fieldset> <!-- S -->
    </fieldset> <!-- option -->
</div></div> <!-- main / base -->
<div id="se0" style="height:80px"></div><div id="se1"></div><div id="se2"></div>」
「#nako3_div_1」にHTMLHTML設定。


#---画面描画----------
「#court」へ描画開始。黒色線色設定。黒色に塗色設定。[0,0,640,480]へ四角描画。
2に太設定。白色線色設定。

30
  A=画面h/30。
  [画面w/2,(回数-1)*A+5]から[画面w/2,(回数-1)*A+5+5]へ描画。
ここまで。

「#ball」へ描画開始。白色線色設定。白色に塗色設定。[5,5]へ4の描画。
「#Paddle1」へ描画開始。白色線色設定。白色に塗色設定。[0,0,5,50]へ四角描画。
「#Paddle0」へ描画開始。白色線色設定。白色に塗色設定。[0,0,5,50]へ四角描画。

#---CSS設定----------
「#base」に{
  "margin": "auto",
  "幅": "{画面w}px",
  "高さ": "{画面h}px",
  "border": "2px solid #999999",
}をDOMスタイル一括設定。

「#main」に{
  "position": "absolute",
}をDOMスタイル一括設定。

「#msk」に{
  "position": "absolute",
  "top":"{-1*マウス上マージン}px",
  "左":"{-360}px",
  "幅": "1360px",
  "高さ": "660px",
  "z-index": "-1",
}をDOMスタイル一括設定。

「#ball」に{
  "position": "absolute",
  "左": "{玉x}px",
  "top": "{玉y}px",
  "z-index": "-1",
}をDOMスタイル一括設定。

「#Paddle0」に{
  "position":"absolute",
  "左":"{パドルx[0]}px",
  "top":"{パドルy[0]}px",
  "z-index":"2",
}をDOMスタイル一括設定。
「#Paddle1」に{
  "position":"absolute",
  "左":"{パドルx[1]}px",
  "top":"{パドルy[1]}px",
  "z-index":"2",
}をDOMスタイル一括設定。

「#court」に{
  "position":"absolute",
  "z-index":"1",
}をDOMスタイル一括設定。

「#Player0」に{
  "position":"absolute",
  "top":"0px",
  "左":"{画面w/4*3-35}px",
  "z-index":"1",
  "font-size":"24px",
  "color":"#FFFFFF",
}をDOMスタイル一括設定。
「#Player1」に{
  "position":"absolute",
  "top":"0px",
  "左":"{画面w/4-35}px",
  "z-index":"1",
  "font-size":"24px",
  "color":"#FFFFFF",
}をDOMスタイル一括設定。

「#Point0」に{
  "position":"absolute",
  "z-index":"1",
  "top":"30px",
  "左":"{画面w/4*3-35}px",
  "幅":"50px",
  "width":"50px",
  "text-align":"center",
  "font-size":"38px",
  "font-weight":"bold",
  "color":"#FFFFFF",
}をDOMスタイル一括設定。
「#Point1」に{
  "position":"absolute",
  "z-index":"1",
  "top":"30px",
  "左":"{画面w/4-35}px",
  "幅":"50px",
  "text-align":"center",
  "font-size":"38px",
  "font-weight":"bold",
  "color":"#FFFFFF",
}をDOMスタイル一括設定。

「#syohai」に{
  "position":"absolute",
  "display":"table-cell",
  "top":"170px",
  "width":"640px",
  "padding":"30px 0px",
  "z-index":"-1",
  "background-color":"rgba(0, 0, 0, 0)",
  "text-align":"center",
  "vertical-align":"middle",
  "font-weight":"bold",
  "font-size":"42px",

  "transition": "opacity 0.5s, transform 0.5s",    /* 0.5秒かけて透明度とサイズの変化 */
  "opacity":"0",
  "transform": "scale(.1)",
}をDOMスタイル一括設定。

「fieldset#option」に{
  "position":"absolute",
  "top": "490px",
  "font-size": "small",
  "width": "400px",
  "height": "60px",
}をDOMスタイル一括設定。

「fieldset#P」に{
  "position":"absolute",
  "width": "200px",
  "border": "none",
  "padding": "0px",
}をDOMスタイル一括設定。

「fieldset#S」に{
  "position":"absolute",
  "left": "220px",
  "border": "none",
  "padding": "0px",
}をDOMスタイル一括設定。


#---ボタン作成----------
「#main」にDOM親要素設定。
「ゲームスタート」のボタン作成し、スタートボタン代入。
スタートボタンに{
  "position": "absolute",
  "幅": "150px",
  "top": "280px",
  "左": "{画面w/2-75}px",
  "padding":"5px 0px",
  "z-index": "3",
}をDOMスタイル一括設定。

「遊び方」のボタン作成し、説明ボタン代入。
説明ボタンに{
  "position": "absolute",
  "幅": "80px",
  "top": "490px",
  "左": "{画面w-80}px",
}をDOMスタイル一括設定。

#---ローカルストレージからオプション設定-----
もし、(「ぽんの設定」が存在)=いいえならば、
  #プレイヤーは、1P(左)を1、2P(右)を0としている。
  設定={"プレイヤー":1,"SE":1}
  設定を「ぽんの設定」に保存違えば、
  設定=「ぽんの設定」を開くここまで。

SE=設定["SE"]。
プレイヤー=設定["プレイヤー"]。
COM=(プレイヤー+1)%2。
サーブ権=プレイヤー。サーブ待ち=オフ。
打者=(サーブ権+1)%2。
プレイヤー表示変更。

「#P{プレイヤー}」の「checked」に「checked」をDOM属性設定。
もしSE=オンならば、「#SE」の「checked」に「checked」をDOM属性設定。


#---イベント設定---------
説明ボタンをクリックした時には
 「いわゆるテーブルテニス。
パドルをマウスで上下に動かしてボールを打ち返し、得点を狙うゲームです。
{勝点}点先取すれば勝ち。ジュース制度はありません。

サーブ権はユーザーからで、得点に関わりなく交互に入れ替わります。
サーブ権がある時は、パドルにボールが付いており、クリックでサーブ。
ボールの速度と角度はランダムです。

打ち返した時のパドルの動きでボールの動きが変化します。
(基本的に早く動かすほど加速し、角度が付く)
卓球と言うより、エアホッケーに近い感じですね。
」と言うここまで。

「#msk」をクリックした時には
 もし、(サーブ待ち=オン)かつ(サーブ権=プレイヤー)ならば、
  サーブ待ち=オフ。玉移動。COMパドル操作。
 ここまで。
ここまで。

「#msk」をマウス移動した時には
  もし、(マウスY<マウス上マージン)ならば、    #mskの上マージン
    パドルy[プレイヤー]=0。
  違えばもし、(マウスY<画面h+マウス上マージン-パドルh)ならば、
    パドルy[プレイヤー]=マウスY-マウス上マージン。
  違えばもし、(マウスY≧画面h+マウス上マージン-パドルh)ならば、
    パドルy[プレイヤー]=画面h-パドルh。
  ここまで。
  「#Paddle{プレイヤー}」の「top」に「{パドルy[プレイヤー]}px」をDOMスタイル設定。
  もし、(サーブ待ち=オン)かつ(サーブ権=プレイヤー)ならば、
    玉セット。     #パドルに玉がくっついて動くようにする。
  ここまで。
ここまで。

スタートボタンをクリックした時には
 もし、(得点[0]≠0)または(得点[1]≠0)ならば、
  URLブラウザ移動。
 違えば、
  スタートボタンの「z-index」に「-1」をDOMスタイル設定。
  「#syohai」の「opacity」に「0」をDOMスタイル設定。
  「#syohai」の「z-index」に「-1」をDOMスタイル設定。
  「#msk」の「z-index」に「3」をDOMスタイル設定。
  オプション無効化。
  サーブ待ち=オン。サーブ権=プレイヤー。
  得点[0]=0。「#Point0」に得点[0]をテキスト設定。
  得点[1]=0。「#Point1」に得点[1]をテキスト設定。
  サーブ。
 ここまで。
ここまで。

「#P1」の「onchange」に「左右変更」をDOMイベント設定。
「#P0」の「onchange」に「左右変更」をDOMイベント設定。
「#SE」の「onchange」に「効果音オフオン」をDOMイベント設定。

●左右変更
 もし、(「#P1」の「checked」をDOM属性取得)=オンならば、プレイヤー=1。
 違えば、プレイヤー=0。
 COM=(プレイヤー+1)%2。
 設定["プレイヤー"]=プレイヤー。
 設定を「ぽんの設定」に保存。
 プレイヤー表示変更。
ここまで。

●効果音オフオン
 もし、(「#SE」の「checked」をDOM属性取得)=オンならばSEオン。
 違えばSEオフ。
 設定["SE"]=SE。
 設定を「ぽんの設定」に保存ここまで。

#-----------------------------------------------------------------------
●サーブ
  COMパドルタイマーIDのタイマー停止。
  ラリー=0。単ラリー=0。
  r=2の乱数もし、r=0ならば、r=-1。
  dx=((30の乱数)+1)/10+2。dy=((20の乱数)+1)/10+2。dy=dy*r。
  玉セット。サーブ待ち=オン。打者=(サーブ権+1)%2。
  もし、打者=0ならば、dx=dx*-1。
  「#ball」の「z-index」に「2」をDOMスタイル設定。
  もし、サーブ権=COMならば、
   サーブ待ち=オフ。
   「玉移動」を1秒後。
  ここまで。
ここまで。

●玉セット
  もし、サーブ権=1ならば、
   玉x=パドルx[1]+パドルw。玉y=パドルy[1]+パドルh/2-玉h/2。
  違えば、
   玉x=パドルx[0]-玉w。玉y=パドルy[0]+パドルh/2-玉h/2。
  ここまで。
  「#ball」の「左」に「{玉x}px」をDOMスタイル設定。
  「#ball」の「top」に「{玉y}px」をDOMスタイル設定。
ここまで。

●玉動作設定
  ラリー=ラリー+1。
  py=y-元y。   //パドルの速さと向き。
  パドル速度=pyの絶対値。
  パドル方向=pyの符号。
  玉速度=dxの絶対値。
  玉角度=dyの絶対値。
  玉x方向=dxの符号。
  玉y方向=dyの符号。
  もし、打者=プレイヤーならば、
    速度補正値=(パドル速度/10)の整数部分。
  ここまで。

  もし、(打者=プレイヤー)かつ(パドル速度=0)ならば、
    単ラリー=単ラリー+1。
  違えばもし、(打者=プレイヤー)かつ(パドル速度≠0)ならば、
    単ラリー=0。
  ここまで。

  #COMの玉動作。
  もし、(打者=COM)ならば、
    もし、玉速度≦4ならば、玉速度=16/玉速度。
    違えばもし、玉速度≧6ならば、玉速度=玉速度/2。
    もし、単ラリー%4=3ならば、玉角度=玉角度-1。
    もし、ラリー%10=9ならば、玉角度=玉角度-1。
    もし、玉角度≦1ならば、
      玉角度=玉角度+2。玉速度=玉速度+3。
    違えばもし、玉角度≧5ならば、
      玉角度=玉角度-2。玉速度=玉速度-1。
    ここまで。
    dx=玉x方向*玉速度*-1。dy=玉y方向*玉角度。
  ここまで。

  #プレイヤーの玉動作。
  もし、(打者=プレイヤー)ならば、
   もし、(玉速度)<3ならば、
    玉速度=10/玉速度。
   ここまで。
   もし、(パドル速度=0)ならば、  #0ならのまま反射。
    dx=玉x方向*玉速度*-1。dy=玉y方向*玉角度。
   違えばもし、(パドル方向=玉y方向)ならば、      #符号が同じならスピードアップ。
    もし、速度補正値≦3ならば、
      dx=玉x方向*(玉速度+速度補正値)*-1。dy=玉y方向*(玉角度+速度補正値+0.5)
    違えば、
      dx=玉x方向*(玉速度+速度補正値/2)*-1。dy=玉y方向*(玉角度+速度補正値/2+1)
    ここまで。
   違えば、                           #符号が逆の時、
    もし、速度補正値≦1ならば、               #パドルが遅ければ減速して角度を少し戻す。
      もし、玉速度>1ならば、
        dx=玉x方向*(玉速度-1)*-1。dy=玉y方向*(玉角度-1.5)
      違えば、
        dx=玉x方向*玉速度*-1。dy=玉y方向*(玉角度-1)    #玉が遅ければ減速しない
      ここまで。
    違えばもし、速度補正値>3ならば、           #早ければ加速して逆向きに反射。
      dx=玉x方向*(玉速度+1)*-1。dy=玉y方向*(玉角度+1.5)*-1
    違えば、                         #こなら、
      dx=玉x方向*玉速度*-1。dy=玉y方向*玉角度*-1。     #逆向きに反射。
    ここまで。
   ここまで。
  ここまで。
  玉速度=dxの絶対値。角度=dyの絶対値ここまで。

#-----------------------------------------------
●絶対値(Aの)
  AのABS戻るここまで。

●符号(Aの)
  AのSIGN戻るここまで。

●整数部分(Aの)
  AのINTここまで。
#-----------------------------------------------

●玉移動
 玉動作設定。
 サーブ権=(サーブ権+1)%2。
 0.01秒タイマー開始した時には(ID)
  玉タイマーID=ID。
  y=パドルy[打者]。

  もし、(玉x+dx<玉w*-1)ならば、0の得点加算。
  もし、(玉x+dx+玉w>画面w+玉w)ならば、1の得点加算。
  もし、((玉x+dx≦パドルx[1]+パドルw)かつ(玉x+dx+玉w>パドルx[1])かつ(玉y+玉h>パドルy[1])かつ(玉y<パドルy[1]+パドルh))ならば、
   もしSE=オンならば、「#se0」に「<audio src="{パドル音}" autoplay></audio>」をDOM_HTML設定。
   玉動作設定。
   打者=(打者+1)%2。
   もし、プレイヤー=1ならば、COMパドル操作。
   違えば、COMパドルタイマーIDのタイマー停止。
  ここまで。
  もし、((玉x+dx+玉w≧パドルx[0])かつ(玉x+dx<パドルx[0]+パドルw)かつ(玉y+玉h>パドルy[0])かつ(玉y<パドルy[0]+パドルh))ならば、
   もしSE=オンならば、「#se0」に「<audio src="{パドル音}" autoplay></audio>」をDOM_HTML設定。
   玉動作設定。
   打者=(打者+1)%2。
   もし、プレイヤー=0ならば、COMパドル操作。
   違えば、COMパドルタイマーIDのタイマー停止。
  ここまで。
  もし、(玉y+dy<0)または(玉y+dy+玉h>画面h)ならば、
    もしSE=オンならば、「#se1」に「<audio src="{側面音}" autoplay></audio>」をDOM_HTML設定。
    dy=dy*-1。
  ここまで。
  玉x=玉x+dx。玉y=玉y+dy。
  「#ball」の「left」に「{玉x}px」をDOMスタイル設定。
  「#ball」の「top」に「{玉y}px」をDOMスタイル設定。
  元y=y。
 ここまで。
ここまで。

●COMパドル操作
 0.01秒タイマー開始した時には(ID)
  COMパドルタイマーID=ID。
  もし、玉y<パドルy[COM]+パドルh/2ならば、cy=-1*COM早さ。
  違えば、cy=COM早さ。
  パドルy[COM]=パドルy[COM]+cy。
  もし、(パドルy[COM]<0)ならば、
    パドルy[COM]=0。
  違えばもし、(パドルy[COM]+50>画面h)ならば、
    パドルy[COM]=画面h-50。      #パドル長さ
  ここまで。
  「#Paddle{COM}」の「top」に「{パドルy[COM]}px」をDOMスタイル設定。
 ここまで。
ここまで。

●得点加算(Pの)
 もしSE=オンならば、
  もし、P=COMならば、「#se2」に「<audio src="{失点音}" autoplay></audio>」をDOM_HTML設定。
  違えば、「#se2」に「<audio src="{得点音}" autoplay></audio>」をDOM_HTML設定。
 ここまで。
 玉タイマーIDのタイマー停止。
 COMパドルタイマーIDのタイマー停止。
 「#ball」の「z-index」に「-1」をDOMスタイル設定。
 得点[P]=得点[P]+1。
 「#Point{P}」に得点[P]をテキスト設定。
 もし、得点[P]=勝点ならば、Pの勝利。
 違えば、「サーブ」を1秒後。
ここまで。

●勝利(Pの)
  「#msk」の「z-index」に「-1」をDOMスタイル設定。
  もし、P=プレイヤーならば、
    「#syohai」に「YOU WIN!」をテキスト設定。
    「#syohai」の「色」に赤色DOMスタイル設定。
  違えば、
    「#syohai」に「YOU LOSE」をテキスト設定。
    「#syohai」の「色」に青色DOMスタイル設定。
  ここまで。
  「#syohai」の「z-index」に「3」をDOMスタイル設定。
  「#syohai」の「opacity」に「1」をDOMスタイル設定。
  「#syohai」の「transform」に「scale(1)」をDOMスタイル設定。
  1秒後には
    スタートボタンに「再戦する?」をテキスト設定。
    スタートボタンの「z-index」に「3」をDOMスタイル設定。
  ここまで。
ここまで。

●プレイヤー表示変更。
 もし、プレイヤー=1ならば、
  「#Player1」の「色」に赤色DOMスタイル設定。
  「#Player1」に「YOU」をテキスト設定。
  「#Player0」の「色」に青色DOMスタイル設定。
  「#Player0」に「COM」をテキスト設定。
 違えば、
  「#Player1」の「色」に青色DOMスタイル設定。
  「#Player1」に「COM」をテキスト設定。
  「#Player0」の「色」に赤色DOMスタイル設定。
  「#Player0」に「YOU」をテキスト設定。
 ここまで。
ここまで。

●オプション無効化
  「#SE」の「disabled」に「disabled」をDOM属性設定。
  「#P1」の「disabled」に「disabled」をDOM属性設定。
  「#P0」の「disabled」に「disabled」をDOM属性設定。
  説明ボタンの「disabled」に「disabled」をDOM属性設定。
ここまで。

●オプション有効化
  「#SE」の「disabled」にDOM属性設定。
  「#P1」の「disabled」にDOM属性設定。
  「#P0」の「disabled」にDOM属性設定。
  説明ボタンの「disabled」にDOM属性設定。
ここまで。
#-----------------------------------------------------------------------

http://snowdrops.starfree.jp/wnako3_test/15_Pong.html

 だいたい、こんな感じだったような?

 こうゆうのが下手なワタシが勝てるくらいのレベルなので、COMは弱いですw


 さて、しかし、問題が一つ発生。

 テキスト読み上げでは、Google ChromeまたはGoogle日本語に悩まされましたが、度はFire foxです。

 どうもね、長くゲームを続けると、効果音が再生されなくなっちゃう。

 しかも、そうなると、Windows Media Playerでもメモリが不足していますか何か言って、再生出来なくなってしまうんだから困ったもんだ。

 単に音を連続再生するだけのプログラムでお試ししたところ、120~130くらいで鳴らなくなっちゃうっぽい。

 ゲームの効果音を鳴らしていたら、のくらいあっというですって;

 しようがないので、1ゲームを5点先取と少なめに設定し、再戦時はページをリロードするようにしてみている。

 ちなみにコレは、chromeIEでは発生しないっぽい。3000くらい鳴らしっぱにしたけど平気だった。


 思うに、音を鳴らすというのは、なでしこの命令には無くて、audioタグをautoplayにして、DOM_HTML設定でぶっ込むという力業で行っています。

 をぶっ込めば音は止まるし、別の音をぶっこめば前の音はキャンセルされて新しい音が鳴るということを利用して音を鳴らしまくってますが、見た目はともかく実際にはどんどん新しいaudio要素を作っちゃってることになるんじゃないですかね?(@_@;

 して、Fire foxの場合はタブを閉じるか再読込するかまで、それがどんどん累されてメモリを解放してくれないんじゃないかとゆう;;;


 むじゅかし過ぎてよく分かんなかったけども、JavaScript的にはaudioやvideoを操作する的な命令もあるみたいなので、なでしこでも出来るようになるといいなぁ・・・

 (それで解決しなかったらもう完全にFire foxのせいなんで、どうしようもないw)

ゲスト



トラックバック - http://nadesiko.g.hatena.ne.jp/snowdrops89/20190507