TopPage > 演習課題 > 演習3-2 ネットワーク対戦ゲームクライアント

ネットワーク対戦ゲームクライアントの作成

まず,下記のプログラムと画像3枚を同じフォルダにダウンロードしてください.

fileMyClient.java ダウンロードソースコードファイルを見る

画像ファイルの保存は,画像ファイル上で右クリックし「名前をつけて画像を保存」をクリックします.
★保存先のフォルダが変わっている場合がありますので,注意してください.

White.jpg ... White.jpg

Black.jpg ... Black.jpg

GreenFrame.jpg ... GreenFrame.jpg

※この課題では,演習3-1-1の練習問題で作成したMyServer2.javaを使います!!

 

プログラムの実行

接続を確認するために,コマンドプロンプトを3つ起動させます.

  • 一つのコマンドプロンプトで,MyServer2.javaを起動させます.
  • あとの二つのコマンドプロンプトで,MyClient.javaを起動させます.
  • MyClientに表示されたコマを動かしてください.もう一方のクライアント画面にあるコマも動きましたよね?
    • 動かない場合は,MyServer2.javaのコンパイルからやり直してみてください.
multimove.png
図1. 2つのMyClient.java

プログラム(MyClient.java)の解説

MyClient.javaは大きく4つの部分に分かれています.

  1. MyClient
    ここは,MyClient()が起動したときに,最初に動く(実際はmain()が最初ですが,main()の中で最初に呼ばれている)部分です.
    • 名前の入力ダイアログの表示
    • メインのウィンドウの表示
    • サーバへの接続
      を行います.
  2. MesgRecvThread
    MyClient.javaでいつも動いている(監視している)ところは,この部分です. 具体的には「public void run()」が,プログラムの起動中ずーーっと動作をしています.
  3. main
    起動時には,ここの関数が呼ばれますが,実際には,すぐに,MyClientが呼び出され,その中で,MesgRecvThreadが呼び出されています.
  4. マウスイベント部(mouseClicked,mouseEntered,mouseExited,mousePressed,mouseReleased,mouseDragged,mouseMoved)
    マウスでオブジェクトに何かしたときに,発生します. このマウスの処理に応じたプログラムを書くことで,何かできます.
    上記のプログラムでは,mouseDraggedとmouseClickedに処理を記述しています.

プログラムの改良

プログラムの改良を通じて,動きを理解しましょう.しっかり読むことが重要です!!

改良1 - 複数のPC間で通信できるようにしましょう.

いずれ複数のPCを使ってテストするためにも,先にやっておきましょう.やり方はいくつかありますが,例えば下記の方法があります.

  • 名前の入力ダイアログのあとに,「サーバのIPアドレス」の入力のためのダイアログを表示し,IPアドレスを入力させます.
  • IPアドレスが空の場合には,"localhost"(自分のPCのサーバ)に接続します.それ以外は,入力したサーバに接続します
    • "localhost"は,IPアドレス127.0.0.1(自分のPC)を表す特別な名前です.
    • 自分のPCへのアクセスという操作はよくあるため,覚えやすい"localhost"という名前が付けられています.
  • この方法ではPCが最低2台必要になります.1台はサーバとクライアントが動作しており,もう一台は,クライアントだけ動作しています.

    PCのIPアドレスの調べ方は,IPアドレスを調べる方法を見てください.」
    複数のPC間で通信テストをやりたい場合,Q&Aを参考にしてください.

ヒント

  • 名前ダイアログを出すプログラムが,MyClientのどこかにあります.
    • それを参考にIPアドレスダイアログを出すようにしましょう.
  • 入力で得られた変数をどこで用いるか,についても考える必要があります.
    • "localhost"にしか接続できない状況を変更して,入力内容に従うようにしましょう.
  • 通信できるかどうかのチェックはIPアドレスを調べる方法Q&Aを参考に.

ポート番号とは

  • ポート番号とは,TCP/IPを用いた通信において,プログラムを区別するための番号です.
  • 同じ番号同士で通信をします.
  • 今回のサンプルでは,10000番をしています.0番〜65535番までつかえますが,0-1023番までは,ウェルノウンポートという番号で,特定のサービスに予約されています.

失敗例(MyServer2が起動しない!)

  • 「ソケットへの接続エラー」のようなエラーメッセージがでます.
  • 「ソケット」というのは,インターネット(TCP/IP)の考え方の一つです.
  • エラーの原因ですが,「MyServer2」が2つ立ち上がっていませんか?
  • 「MyServer」と「MyServer2」が2つ立ち上がっていませんか?
  • MyServer2は,サーバーです.特定のポート(このプログラム例では,10000番ポートで待ちます)
  • すでに先に一つのMyServer2が立ち上がっていると,もう一つのMyServer2は起動時に,すでにポートが使われているためにエラーとなります!


改良2 - 特定の番号のコマは動かないようにしてみましょう.

例えば,配列の1番目だけは,動かないようにしてみましょう.mouseDraggedのところの,theArrayIndex(ボタン番号)をうまく使います.

ヒント1

  • theArrayIndexは文字列なので,比較する時は注意してください.

ヒント2

  • 配列の0番目は動かない=配列の0番目以外は動く とかけばいいですね!

ヒント3:下記のプログラムは,0以外の場合には,x=x+1;が動く例です.

注意:このコードをMyClient.javaに書き加えるわけではないです!

if(x != 0){
  x = x + 1;
}



改良3 - 自動的に,黒と白を決めてみましょう.

MyServer2では,演習3-1-1の練習問題(MyServer2.java)では,接続してきたクライアントに対して,

1

と接続番号を送信していますね.
この接続番号「1」(2回目は2,3回目は3...)の数字を使うと例えば,偶数は黒,奇数は白とすると,つないだプログラムごとに黒と白が判定できます.

 

MyClientの受信部分は

public void run()

です.そこで,

out.println(myName);//名前を送る

の後に,

String myNumberStr = br.readLine();

を追加します. これで,サーバが送った番号を受け取れますが,このままだとまだ,単なる文字なので, Integer.parseIntを使って数値にします.
また,この数値を奇数が偶数かを判定するには, %(モジュロ)演算子を使います.
例えば,下記は偶数の時にif文の条件を満たします.

if(myNumberInt % 2 == 0){
}

自分が黒か白かの情報は,他の場所でも使いますので,どこでも使えるように,

public class MyClient extends JFrame implements MouseListener,MouseMotionListener { 
    private JButton buttonArray[];

のようなところに,

private int myColor;

と宣言しておいて,

  • myNumberIntが偶数のときはmyColorを0(黒)にする
  • myNumberIntが奇数のときはmyColorを1(白)にする

などと決めておくと良いでしょう.


これで,プログラム中のどこでも自分の色を参照できるようになります. 試しに,コマをクリックしたら,myColorの色に変えるよう修正してください.


もう少し改良!:これまでの改良では,特に画面上に変化はありませんので,もう一つ改良します.

コマをクリックしたら,myColorの色に変えるよう修正してください.
この修正は,

public void mouseClicked(MouseEvent e)

の中を修正します.

最初のmouseClickedのプログラムは,白がおかれていたら,黒に, それ以外が置かれていたら,白にするプログラムです.

そのプログラムを,白の人は白だけ,黒の人は黒だけおけるように修正してください.
先ほど作成した,myColorを使って,if文を書いてみましょう.

修正ができたら,実行してみて,
一方のMyClientは黒だけしかおけないことを
一方のMyClientは白だけしかおけないことを確認してください.

改良4 - 自分のコマをクリックしたときに,相手のコマも変わるようにしましょう.

現在は,コマをクリックしたら,自分のコマしか色が変わりません.

まず,(1)mouseClickedのところで,mouseDraggedの中身を参考にしながら送信部分を作ります.
mouseDraggedの中身を参考にしてください.
mouseDraggedの中身をみるとわかるのですが,
(1)自分自身の設定する
(2)相手(サーバ経由で相手に)にその情報を送る
という流れです.
mouseDraggedの場合は,移動先の座標を計算して, その座標を,サーバに送っています.

mouseClickedの場合には,まず,自分のコマを置いて, そのコマの位置と色をサーバにおくるという形にすればよいです.

では実際に書いてみましょう.
mouseClickedを見ると,すでにひっくり返す部分は書き終わっていますね.
あとはサーバに送るところを書くだけです.
ここでは,「MOVE」の代わりに「PLACE」(コマを置く)という命令を出してみましょう.
MOVEでは位置を送信情報としていますが,ここでは自分の色(myColor)を送る必要があります.

次に,(2)MesgRecvThreadのrun()の中に,if(cmd.equals("MOVE")){...という部分がありますね.
この中身を参考にしましょう.「PLACE」の命令を受け取った場合を考え,このif文の中に,コマの色を変えるプログラムを書きます.
ここに書くのは,情報を送った自分も,受け取った相手も動作する内容です.要注意ですよ!

今から書くのは,PLACEなので,コピーしたif文のMOVEをPLACEにしましょう.
次に,送信したmyColorを受け取る部分が必要です.
int x = を int theColor = として,myColorをうけとりましょう.
ここで,int myColorとすると,おかしなことになるので,しないように注意してください.

次に,buttonArrayに送られた色のコマを設定しましょう.
if文で書くと,色に応じて変更できますね.

サーバとクライアントの関係_key_pdf__page_1_of_2_.jpg
図.MyClientからMyServerへの流れ1(プログラム)

サーバとクライアントの関係_key_pdf__page_2_of_2_.jpg
図.MyClientからMyServerへの流れ2(プログラムのイメージ)

ヒント

  • 通信相手には"文字列"(msg)の情報しか送れません.
    • したがって,msgに入れられる情報は"文字列"か"数字(の文字列)"に限られます.
    • "MOVE 2 23 27"という文字列からは,1個の文字列と3個の数字の情報が得られますね.

下記を忘れるとサーバーにデータを送られないので,忘れないように.

//サーバに情報を送る
out.println(msg);//送信データをバッファに書き出す
out.flush();//送信データをフラッシュ(ネットワーク上にはき出す)する


  • (1)の送信部分では,クリックした直後の処理と送信情報の準備・送信を行います.
  • (2)の受信部分では,送信で受け取った情報を使って,両方のクライアントで処理を行います.

以上から,ネットワークを利用したプログラミングでは,書きたい操作が

  • 相手の画面にも反映させたい場合→受信部分に書く
  • 自分の画面のみに反映させたい場合→送らず,その場で書く

とする必要がある,ということですね.詳しい動きは,演習4-1も参考にしてください.


補足

MyServer.javaには,接続数の制限があります.つまり接続数が100を超えるとサーバが止まってしまいます.
maxConnection = 100で制限していますので,気になる人は数を増やしておくと良いでしょう.

※本来なら,socketは使い回せるのですが,プログラムの簡略化のため,このような書き方をしています.

 

なお,MyClientの名前は変えても構いませんが,ファイル名を変えるとプログラムの中も変える必要があります.
ある程度動いたら,名前を変えたり,バックアップをとったりすると,あとで動かなくなったときに,おかしいところを探すのに便利です.

※配布しているソースコードに記述してある「マウスが入った」などの表示を止めたいとき…

  • 演習2-2 イベント処理を参考にしてみてください.
  • 全部消してしまう(コメントアウトも)と,エラーが出ます
     

バックアップのコツ

  • ちゃんと動いているプログラムを大きく変更するときには,バックアップを取っていると便利です.
  • ただし,Javaは,ファイル名を変更すると,なかのクラス名の変更も必要になります.ですので,フォルダに入れる形にしましょう.
  • フォルダ名は日付やファイル名,バージョンなどで区別すると,いいと思います.

next.gif 演習ページ


添付ファイル: fileサーバとクライアントの関係_key_pdf__page_2_of_2_.jpg 365件 [詳細] fileサーバとクライアントの関係_key_pdf__page_1_of_2_.jpg 541件 [詳細] fileGreenFrame.jpg 1346件 [詳細] fileWhite.jpg 1607件 [詳細] filemultimove.png 446件 [詳細] fileMyClient.java 3098件 [詳細] fileBlack.jpg 1288件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   一覧 単語検索 最終更新     最終更新のRSS
Last-modified: 2018-10-25 (木) 10:13:03 (2003d)