通信対戦プログラム プログラムの概要 Winsock コントロールを使用すると リモートコンピュータに接続し データを交換出来る事を利用して 通信対戦ゲームを作成する ゲームに関する処理は 既に標準モジュールに グローバルなプロシージャとして 入力されて居るので 此れを追加して 使用する ( ファイル名は othello.bas で有る ) 相手のアドレス (IP アドレス 又は コンピュータ名 ) と双方のポート ( 互いに逆に設定 ) を指定して 設定ボタンをクリックすると 通信が確立し メッセージ欄の指示に従いゲームを開始する事が出来る 今回の課題項目 単純変数の宣言 (Public Dim) 配列変数の宣言 (Public) 標準コントロールの利用 (Label Picture Command Text Frame) プロパティの値の取得と設定 (Standard: BackColor Text Caption Image) プロパティの値の取得と設定 (Winsock: State RemoteHost RemotePort LocalIP) メソッドの利用 (Line PaintPicture Close Bind SendData GetData) イベントの利用 (Load Click MouseDown DataArrival) 組込関数の利用 (Val Abs Left Mid Right RGB MsgBox) 演算子 ( 代入演算子 算術演算子 比較演算子 結合演算子 論理演算子 ) 制御構造構文 ( 条件分岐 ループ処理 ) サブルーチン ( 新規プロシージャ 引数 ) 標準モジュールの追加 ( プロジェクト 標準モジュールの追加 既存のファイル ) ActiveX コントロールの利用 ( プロジェクト コンポーネント コントロール ) 今回の重点項目 標準モジュールの利用 ( 共通のコード :Public 変数 Public プロシージャ ) Winsock コンポーネントの利用 (Protocol RemoteHost RemotePort Bind 等 ) 今回の応用項目 対戦中にオプションボタンをクリック出来ない様にする (Fool Proof) コンピュータの思考ルーチンを強化する TCP を利用して一対複数の通信対戦ゲームを考えて見る -1-
オブジェクト プロパティ一覧 ラベル 1 Winsock ラベル 7 ピクチャーボックス ラベル 6 ラベル7 ラベル8 ラベル2 テキスト1 ラベル 3 テキスト 2 オプションボタン フレーム 1 ラベル 4 テキスト 3 ラベル 5 テキスト 4 フレーム 2 コマンドボタン 3 コマンドボタン 2 コマンドボタン 1 コントロールの種類 プロパティ プロパティの設定値 フォーム オブジェクト名 Form1 Caption 通信対戦ゲーム ScaleMode 3 ピクセル ピクチャーボックス オブジェクト名 picboard ScaleMode 3 ピクセル Appearance 0 フラット AutoRedraw True Height 320 Width 322 BackColor &h0000c000&( 濃緑 ) フレーム1 オブジェクト名 fracommunication Caption 空白 フレーム2 オブジェクト名 frarival Caption 対戦相手 オプションボタン オブジェクト名 optrival Index 0~1( コントロール配列 ) Caption 人間 (0) 電脳(1) Value True(0) ラベル1 オブジェクト名 lbltitle Caption 通信対戦チェッカー Font HG 創英角ポップ体 標準 26-2-
コントロールの種類 プロパティ プロパティの設定値 ラベル2 オブジェクト名 lbladdressr Caption Font 相手のアドレス (MSゴシック 太字 11) ラベル3 オブジェクト名 lbladdressl Caption Font 自分のアドレス (MSゴシック 太字 11) ラベル4 オブジェクト名 lblportr Caption Font 相手のポート (MSゴシック 太字 11) ラベル5 オブジェクト名 lblportl Caption Font 自分のポート (MSゴシック 太字 11) ラベル6 オブジェクト名 lblmessage Caption Font 空白 (MSゴシック 太字 12) Alignment 2 中央揃え ラベル7 オブジェクト名 lblscore Caption Font 0(MSゴシック 太字 16) Alignment 1 右揃え Index 0~1( コントロール配列 ) ForeColor 白 (0) 黒 (1) BackColor 黒 (0) 白 (1) ラベル8 オブジェクト名 lblstate Caption Font 未受信 (MSゴシック 太字 14) Alignment 2 中央揃え BorderStyle 1 実線 ForeColor &H00FFFFFF&( 白 ) BackColor &H000000FF&( 赤 ) テキストボックス1 オブジェクト名 txtaddressr Text 192.168.1.1(MSゴシック 太字 11) テキストボックス2 オブジェクト名 txtaddressl Text 192.168.1.2(MSゴシック 太字 11) テキストボックス3 オブジェクト名 txtportr Text 1001(MSゴシック 太字 11) テキストボックス4 オブジェクト名 txtportl Text 1002(MSゴシック 太字 11) コマンドボタン1 オブジェクト名 cmdset Caption Font 設定 (MSゴシック, 太字,14) コマンドボタン2 オブジェクト名 cmdfinish Caption Font 終了 (MSゴシック, 太字,14) コマンドボタン3 オブジェクト名 cmdpass Caption Font パス (MSゴシック, 太字,14) ソケット オブジェクト名 sckcom Protocol 1 - sckudpprotocol -3-
ピクチャーボックスビットマップ アイコン メタファイル JPEG ファイル GIF フィル等の画像を表示するコントロール 描画メソッドを用いて 円や直線等のグラフィックを描画する事も出来る 亦 他のコントロールを内包するコンテナに成る事も出来る フレーム他のコントロールをグループ化するコントロール 通常 チェックボックスやオプションボタンと共に使用し フレーム自体は 特定の機能を持たない ラベルテキストを表示するコントロール 此のテキストは ユーザーが直接入力したり変更したりする事は出来ない テキストボックステキストの入力や表示を行うコントロール 此のテキストは ユーザーが直接入力したり変更したりする事が出来る コマンドボタンユーザーが選択したコマンド ( 命令 ) や操作を実行するコントロール OK ボタンや実行ボタン等 処理の開始や中断 終了の合図に用いられ 最も良く利用されるコントロールです ソケット (Winsock) TCP ネットワークサービス 及び UDP ネットワークサービスへアクセスする機能を提供する ActiveX コントロール 此のコントロールを使用すると TCP 又は UDP を使用してリモートコンピュータに接続し 送受信双方向のデータ交換を行う事が出来る 孰れのプロトコルでも クライアント及びサーバーアプリケーションを作成出来る 中央のサーバーに送るユーザー情報を集めるクライアントアプリケーションの作成 複数のユーザーから集めたデータの中央コレクションポイントとして機能するサーバーアプリケーションの作成 チャットアプリケーションの作成等に利用される TCP(Transmission Control Protocol) TCP プロトコルは コネクション型のプロトコルで有り 電話に例える事が出来る ユーザーは 接続を確立してから処理を行う必要が有る 亦 一旦接続が確立すると TCP プロトコルでは 接続が持続され 非常に大きなファイル等でもデータの完全性が保証されるが 多くのリソースが使用される UDP(User Datagram Protocol) UDP プロトコルは コネクションレス型のプロトコルで有り メモ伝言に例える事が出来る 1 台のコンピュータから別のコンピュータにメッセージが送られるが 両者は明示的に接続されて居ない 亦 各送信データの最大サイズは ネットワークに依り決まる 此処では UDP プロトコルを用いた双方向通信を主題として居る為 ゲーム部分は 標準モジュール othello.bas に既に入力された物を組み込んで使用する 標準モジュールをプロジェクトに追加するには メニューバーの プロジェクト より 標準モジュール の追加を選択し ダイアログボックスの 既存のファイル タブから当該ファイルを指定する 標準モジュールは 通常 アプリケーションの他のモジュールで共通に使う為の宣言やプロシージャを記述する為に使用する -4-
プログラムリスト ( フォームモジュール部分 ) Option Explicit ' フォームが読み込まれた時の処理 Private Sub Form_Load() ' 盤面データを設定する Call GetData ' 盤面を初期化する Call GameInit Call TurnDisp Call BoardInit ' 自機の IP アドレスを取得する txtaddressl.text = sckcom.localip ' コマンドボタン ( 終了 ) がクリックされた時の処理 Private Sub cmdfinish_click() ' ソケットを閉じる sckcom.close ' プログラムをメモリから消去して終了する Unload Me End ' コマンドボタン ( 設定 ) がクリックされた時の処理 Private Sub cmdset_click() ' ソケットが閉じて居ない場合は一旦閉じる If sckcom.state <> sckclosed Then sckcom.close ' リモートホスト ( 相手 ) を設定する sckcom.remotehost = txtaddressr.text ' リモートポート ( 相手 ) に整数を設定する sckcom.remoteport = Val(txtPortR.Text) ' ローカルポート ( 自分 ) に結合する sckcom.bind Val(txtPortL.Text) ' 送信する sckcom.senddata "OK" ' 盤面でマウスボタンが押し下げられた時の処理 Private Sub picboard_mousedown(button As Integer, Shift As Integer, X As Single, Y As Single) ' 着目座標を求める CX = X 40: CY = Y 40 ' 駒の置く位置を指定する Call PointPlace ' 終了判定を行う If Not ED < 0 Then Call GameOver -5- Call は Sub プロシージャ等に制御を渡すステートメント 引数が必要なプロシージャを呼び出す場合は 引数リストを括弧で囲む必要が有る アプリケーションを終了する場合 ソケットは閉じ 正しくプログラムをメモリから消去して終了する事が望ましい RemoteHost プロパティには接続するコンピュータの名前か IP アドレスを指定する RemotePort プロパティには接続するポートを指定する Bind メソッドは ポート番号にコントロールに結合して ローカルポートを使用出来る様に予約する SendData メソッドは データをリモートコンピュータに送信する 左右孰れかのマウスボタンを押すと MouseDown イベントが発生する マウスボタンが押された時のマウスの当該オブジェクト内での座標は 引数 X と Y に格納されて居る
' パスがクリックされた時の処理 Private Sub cmdpass_click() ' パス処理を行う Call PassTurn ' 終了判定を行う If Not ED < 0 Then Call GameOver ' 通信データを受信した時の処理 Private Sub sckcom_dataarrival(byval bytestotal As Long) ' サブプロシージャレベルでローカルな変数を宣言する Dim S As String Dim D As Boolean ' 現在のデータブロックを取得する sckcom.getdata S ' 接続データの場合の処理を行う If lblstate.caption = " 未受信 " Then If S = "OK" Then Call FirstDisp(0) TN = 0 sckcom.senddata "RV" Call FirstDisp(1) TN = 1 ' 対戦データの場合の処理を行う If Left$(S, 7) = "OTHELLO" Then If Mid$(S, 8, 1) = "P" Then Call PassDisp CX = Val(Mid$(S, 8, 1)): CY = Val(Right$(S, 1)) D = JudgePlace Call ScoreDisp If Not ED < 0 Then Call GameOver BA = BA Xor 1 Call TurnDisp If Left$(S, 5) = "AGAIN" Then If Mid$(S, 7) = "YES" Then Call GameInit Call TurnDisp Call BoardInit Call は Sub プロシージャ等に制御を渡すステートメント 引数が必要なプロシージャを呼び出す場合は 引数リストを括弧で囲む必要が有る DataArrival イベントは 新しいデータが送信されて来た時に発生する GetData メソッドは 現在のデータブロック ( 受信データ ) を取得し 其れを変数に格納する 此の場合のイコール (=) 記号は 比較演算子で有る A=B : AとBは等しい 此等の場合のイコール (=) 記号は 代入演算子で有り 右辺の値を左辺に代入する働きをする 此の様に 複数のステートメントをコロン (:) で区切り 1 行に複数記述する事も出来る ユーザーが Function プロシージャで定義した関数は 組込関数と同様に使用する事が出来る Function プロシージャは Sub プロシージャと異なり戻り値を利用する事が出来る 此の場合の Xor は ビット演算子で 1 と排他的論理和を取る事に依り 1 は 0 に 0 は 1 に成る -6-
Call FirstDisp(1) TN = 1 sckcom.close Unload Me End ' 終了処理を行うジェネラルサブプロシージャ Private Sub GameOver() ' サブプロシージャレベルでローカルな変数を宣言する Dim I As Integer Dim J As Integer Dim K As Integer アプリケーションを終了する場合 ソケットは閉じ 正しくプログラムをメモリから消去して終了する事が望ましい 此の様に条件分岐等が多重にネストして居る時は 正しくインデントを付けて 対応を明確にして置く事が望ましい 此処で宣言した変数は宣言したサブプロシージャ内でしか値の参照と設定を行う事が出来ない lblmessage.caption = PR If Not TN = ED Then K = MsgBox(" もう一度?", vbyesno + vbquestion, " 通信対戦ゲーム ") If K = vbyes Then Call GameInit Call TurnDisp Call BoardInit Call FirstDisp(0) TN = 0 If optrival(0).value = True Then sckcom.senddata "AGAIN:YES" If optrival(0).value = True Then sckcom.senddata "AGAIN:NO" sckcom.close Unload Me End MsgBox 関数の第 2 引数はビット処理が行われる為 複数の値を加える事で 複数の効果を与える事が出来る 送信データの先頭に識別の為の文字列を付加する事に依り 受信したデータの種類を判別し易くして居る プログラムと同じフォルダに 素材の標準モジュール (othello.bas) とデータファイル (othello.dat) を格納して置く必要が有る -7-
Close メソッドに依るソケットのクローズ (Winsock) 機能 書式 解説 ソケットをクローズするメソッド Object.Close TCP 接続 又は 接続要求を受け付けて居るソケットを閉じる クライアントアプリケーションでもサーバーアプリケーションでも使用出来る オブジェクトには Winsock コントロールを指定する Bind メソッドに依るポートの結合 (Winsock) 機能 書式 解説 ポートを結合するメソッド Object.Bind 引数 1, 引数 2 TCP 接続に使用するローカルポート 及び ローカル IP を指定する オブジェクトには Winsock コントロールを指定する 引数 1 には 接続に使用するポートを指定し 必ず指定する 引数 2 には 接続に使用するローカルインターネットアドレスを指定し 省略する事が出来る 他のアプリケーションが 当該ポートを使用出来ない様にする時に便利で有る SendData メソッドに依るデータの送信 (Winsock) 機能 書式 解説 データをリモートコンピュータに送信するメソッド Object.SendData 引数 引数で指定したデータをリモートコンピュータに送信する オブジェクトには Winsock コントロールを指定する 引数には 送信するデータ ( 数値 又は 文字列 ) を指定し 必ず指定する GetData メソッドに依るデータの受信 (Winsock) 機能 書式 解説 現在のデータブロックを取得し変数に格納するメソッド Object.Bind 引数 1, 引数 2, 引数 3 リモートコンピュータより受信したデータを引数 1 で指定した変数に格納する オブジェクトには Winsock コントロールを指定する 引数 1 には 取得したデータを格納する変数を指定し 必ず指定する 引数 2 には 取得するデータの型を指定し 省略する事が出来る 引数 3 には 取得するデータのサイズを指定し 省略する事が出来る -8-
Winsock メソッド Accept 送信されて来た接続要求の受入 (TCPサーバーアプリケーション而巳) Bind ポートの結合 Close ソケットのクローズ Listen ソケットの作成と接続要求受付モードへの移行 (TCP 接続而巳 ) PeekData データブロックの取得 ( 入力キューからデータを削除しない ) SendData データの送信 GetData データブロックの取得 ( 入力キューからデータを削除する ) Winsock イベント Close ConnectionRequest DataArrival SendComplete SendProgress Error Connect リモートコンピュータが接続を閉じた時に発生リモートコンピュータが接続を要求して来た時に発生新しいデータが送られて来た時に発生送信処理が完了した時に発生データの送信中に発生バックグラウンド処理でエラーが発生した時に発生接続処理が完了した時に発生 Winsock プロパティ BytesReceived 受信したデータのサイズ LocalHostName ローカルコンピュータのホスト名 LocalIP ローカルコンピュータのIPアドレス LocalPort 接続するローカルポート RemoteHost リモートコンピュータのホスト名 ( ホスト名 IPアドレスの孰れも可 ) RemoteHostIP リモートコンピュータのIPアドレス RemotePort 接続するリモートポート State コントロールの状態 Protocol 使用するプロトコル (TCPかUDP) 算術演算子 比較演算子 論理演算子 1.^ 冪乗 1.= 等しい 1.Not 否定 2.- 負数 2.<> 等しくない 2.And 論理積 3.* / 乗算と除算 3.< より小さい 3.Or 論理和 4. 整数除算 4.> より大きい 4.Xor 排他的論理和 5.Mod 剰余 5.<= 以下 5.Eqv 同値 6.+ - 加算と減算 6.>= 以上 6.Imp 包合 算術演算子と論理演算子では 複数の演算子が使用されて居る場合には 頭に付けた番号の順序で演算が行われる ( 上に書かれて居る演算子程優先順位が高い ) -9-
Line メソッドに依る直線の描画 機能 書式 解説 直線 又は, 矩形を描画するメソッド Line Step( 引数 1, 引数 2)- Step( 引数 3, 引数 4), 引数 5, 引数 6 フォーム, ピクチャーボックス, プリンタの各オブジェクトに対して, 指定した 2 点間を結ぶ直線 又は, 矩形 ( 四角形 ) を描く 引数 1 には 直線 / 矩形が描画されるオブジェクト内の始点の X 座標を指定し 省略する事が出来る 引数 2 には 直線 / 矩形が描画されるオブジェクト内の始点の Y 座標を指定し 省略する事が出来る 引数 3 には 直線 / 矩形が描画されるオブジェクト内の終点の X 座標を指定し 必ず指定する 引数 4 には 直線 / 矩形が描画されるオブジェクト内の終点の Y 座標を指定し 必ず指定する 引数 6 には 描画色を指定し 省略する事が出来る 引数 7 には オプション ( 矩形 :B 塗り潰し矩形 :BF) を指定し 省略する事が出来る Step は 描画位置を相対位置で指定する場合に使用し 省略する事が出来る 始点を省略した場合は CurrentX 及び CurrentY に依り示される位置が描画の開始点に成る Line メソッドが実行されると CurrentX 及び CurrentY プロパティは 引数に依り指定された終点に設定される 此れを利用して 始点を省略し 連続線を描く事が出来る グラフィックメソッド Cls グラフィックのクリア PSet 点の描画 ( ピクセル単位での色の設定 ) Point 色の取得 ( 指定したピクセルの色の値の取得 ) Line 線の描画 ( 線 矩形 塗り潰し矩形の描画 ) Circle 円の描画 ( 円 楕円 円弧の描画 ) PaintPicture 任意位置へのグラフィックの描画 ) 描画用プロパティ DrawWidth グラフィックメソッドで描画する線の太さや点の大きさを設定する DrawStyle グラフィックメソッドで描画する線のパターンを設定する DrawMode グラフィックを重ねる時の描画方法を設定する BorderWidth ラインコントロールやシェイプコントロールの外形線の太さを設定する BorderStyle ラインコントロールやシェイプコントロールの外形線のパターンを設定する -10-