1。要件の説明
1。機能要件
機能要件分析段階では、主なタスクは、システムが提供する必要があるサービスを指定し、ソフトウェアが完了する機能を定義し、それらをそれらの人々に提供することです。機能要件は、ソフトウェア開発の基本的な要件であり、需要分析の不可欠な部分です。タンクウォーは古典的なゲームです。このゲームは、前任者の経験のいくつかを学びました。全体として、ゲームは敵と私たちの両側に分かれています。主に戦闘に参加する戦車は、プレイヤーによって制御されます。敵の戦車は、画面上でインテリジェントかつランダムに表示されて移動し、一定数の弾丸を発射することができます。プレイヤーは、指定されたエリアで自由にタンクを移動できます。弾丸がプレーヤーに当たると、プレーヤーは死に、ゲームは終了します。敵のタンクは知的に実行されます。彼らはある程度の知性を持っている必要があるので、彼らは画面上にランダムに現れ、次のように自由に回転します。弾丸の実行:戦車は、さまざまなタンクの位置に応じて、プレイヤーと火の弾丸によって制御されます。彼らがターゲットにヒットした場合、爆発効果が生成されます。また、画面上で消えます。
2。システムのパフォーマンス要件
コンピューターシステムに基づいたゲームのパフォーマンス構成要件は、プログラムが迅速かつ安定して実行され、実行時にタイムリーに応答できるようにすることです。プレイヤーのタンクがゲームで破壊されたら、ゲームの失敗に関する情報を迅速に迅速に迅速に迅速に迅速に迅速に、ゲームのルール要件を満たすためにタイムリーに対応します。さらに、ゲームをプレイするときにメインウィンドウのサイズを自由に変更できないようにすることも必要です。
3。機能ソリューション
コード利用率はゲームで非常に優れています。結局のところ、それはリアルタイムの仕事です。ミリ秒ごとに、多くの弾丸が発射され、多くのタンクの座標運動があります。タンクに数え切れない時間に衝突した弾丸の数と、キーボードの監視イベントを比較し、スレッドインターフェイスを実装し、再描画とリフレッシュを描画しました。ロジックの感覚は強力である必要があり、オブジェクト指向のディスプレイは完全に表示されます。それらの間の関係でさえ不明であり、予期しない状況を持つことは簡単です。美しさを追加し、ゲームに爆発を追加するために、敵のタンクが死ぬと、爆発効果を達成するために外側のパネルに固定された場所の短くて高速なカルーセルが必要です。
一般に、タンクバトルで完了する基本的な機能には次のものが含まれます。グラフィカルインターフェイス、敵と私のタンクスタイルの違い、タンクは弾丸を発射して相手を攻撃することができますが、チームメイトを攻撃することはできません。
2。主な関数分析
タンクウォーゲームの開発の過程で、主な機能が使用するためにユーザーに提供されるため、最初にタンクを描く必要があります。
1。プレイヤータンクを描画します:jpanelパネルにペイント()を設定し、ブラシでタンクのおおよその形状を描画する必要があります。
2。プレイヤーのタンクは移動できます:タンクが動く場合、タンクの座標を変更し、常にパネルを塗り直す必要があります。ただし、タンクが移動すると、イベント監視メカニズム(キーボード監視)インターフェイスをパネルクラスに実装できます。プレイヤーがw/d/s/aキーを押すと、上に移動し、下、左と右に移動できます。
3。そして、私の描画用紙ペイントに敵のタンクを描きます();敵の戦車とプレーヤータンクは同じインターフェイスにあるため、同じ図面に描画する必要があります。
4。プレイヤーの戦車は弾丸を発射できます:プレイヤーが弾丸を発射したい場合、イベントソースが必要です。ユーザーがJキーを押すと、イベントの監視はすぐに弾丸を発射しますが、ユーザーの目の前に表示する必要があります。弾丸が発射され、発射に常に向かっているため、弾丸の座標は絶えず変更する必要があり、弾丸の速度は適切でなければならないため、スレッドで実装する必要があり、パネルは常に再描画されます。
5。プレイヤーは弾丸を連続して発射して5つまで発射できます。プレイヤーが弾丸の数を制御したい場合、プレイヤーがJキーを押すと、現在生存している弾丸の数が5未満かどうかを調べる必要があります。条件が満たされると、1つの弾丸が作成されます。プレイヤーが5つ以上の弾丸を発射すると、システムの火災はもはや呼び出されません。弾丸を発射すると、弾丸が1つだけ発射されるだけでなく、弾丸を一度に1つの弾丸を生成するために弾丸のセットを設定して、弾丸が境界にぶつかって死ぬときに死ぬことを知ることができます。
6.プレイヤーのタンクが敵のタンクに当たると、消滅し、爆発効果が生じます。まず、プレーヤーのタンクの弾丸が敵に当たったかどうかを判断する必要があるため、敵を絶えず判断する機能があります。弾丸が敵のタンクで実行されると、タンクの寿命が終了する必要があり、爆弾が生成され、爆弾が塗料に描かれます()。
7.敵のタンクは賢く動くことができます。タンクのみが移動できる場合、動きの方向をランダムに生成する必要があります。一定の動きにより、メソッドはスレッドの実行関数に書き込まれ、スレッドは睡眠を制御して移動速度の問題を実現します。
8。敵の戦車は弾丸を発射することができます:敵を描く間、糸に一定の休眠を設定して、異なる方向と異なる数の戦車の弾丸を生成し、パネルの各弾丸を取り出して描きます。
9。敵の弾丸がプレーヤーに当たると、プレイヤーは姿を消します。敵の各弾丸を取り出して、それをプレイヤーのタンクと比較します。弾丸がプレーヤーに触れると、プレイヤーの爆発は消えます。
3。サマリーデザイン
•役割属性設定
タンク:タンクが生成される場所、異なるタイプのタンクの色、タンクの寿命識別子、タンクの動きの速度、異なる方向のタンク。
プレーヤータンク:タンクの基本的な属性を継承した後、それは秒に基づいて実現され、プレイヤータンクは自由に上下に動きます。そして、プレイヤータンクには弾丸の発射と発射の機能があります。
敵のタンク:基本的なタンク属性を継承した後、敵のタンクのインテリジェントな動きを実現する必要があり、同時に、異なる位置からタンクに弾丸スレッドを起動する必要があります。
弾丸:弾丸には、座標位置、速度、健康、および弾丸が移動できる必要があり、弾丸も死機能方法を実装する必要があります。
爆弾:爆弾、生命、および徐々に消滅する命の効果方法関数の座標。
•機能プロパティ設定
描画用紙:ペイント()は、プレイヤータンク、敵のタンクを描き、死タンクの爆発効果を表示する必要があります。
イベント監視:ユーザーがWDSAを押すと、対応するプレーヤータンクが方向を変更する必要があります。ユーザーがJを発射すると、打ち上げの方向に弾丸があり、敵に当たらない限り、死ぬまで走る必要があります。
タンクに当たる:弾丸が敵のタンクに当たると、爆発が生成され、爆発セットに追加され、爆発情報が表面に描かれます。
敵はプレイヤーを襲います:ゲームでいわゆる敵を取り出し、各敵の弾丸は私のタンクと一致して、それを打つかどうかを判断します。
プレイヤーが敵を襲う:プレイヤーの各弾丸を取り出し、各敵のタンクを一致させて、それを打つかどうかを判断します。そして、タンクをスレッドrun()に打つことに関連する判断を、継続的な同時判断を行います。
特定の機能分析図は次のとおりです。
•タンク文字属性分析図
機能的な図面分析図
タンクXmind全体的な分析図
タンク文字属性xmind図
タンク関数属性xmind図
IV。システムの実装
•Member.java
//members.javapackage mytank9; import java.util。*; class bomb {// bomb座標int x、y; //爆弾の寿命はint life = 9; boolean islive = true; public bomb(int x、int y){this.x = x; this.y = y; } //健康のpublic public void lifedown(){if(life> 0){life--; } else {this.islive = false; }}} class shot runnable {int x; int y; int direct; int速度= 1; boolean islive = true;パブリックショット(int x、int y、int direct){this.x = x; this.y = y; this.direct = direct; } public void run(){while(true){try {shood.sleep(50); } catch(Exception e){e.printstacktrace(); } switch(direct){case 0:y- = speed;壊す;ケース1:x+=速度;壊す;ケース2:y+=速度;壊す;ケース3:x- =速度;壊す; } // if(x <0 || x> 400 || y <0 || y> 300){this.islive = false;壊す; }}}} classタンク{//タンク水平座標int x = 0; // g垂直座標int y = 0; //タンクの方向// 0は上部を示し、1は右に示す、2は左int = 0; boolean islive = true; public int getColor(){return color; } public void setColor(int color){color = color; } public int getSpeed(){return speed; } public void setSpeed(int速度){this.speed = speed; } public int getDirect(){return direct; } public void setDirect(int direct){this.direct = direct; } public tank(int x、int y){this.x = x; this.y = y; } public int getX(){return x; } public void setx(int x){this.x = x; } public int gety(){return y; } public void sety(int y){this.y = y; }} //敵のタンククラス敵のタンク拡張タンクの実装{int times = 0; //敵の弾丸を保存できるベクトルを定義しますvector <shot> ss = new vector <shot>(); } @Override public void run(){// todo auto-fienated method stub while(true){switch(this.direct){case 0://は、タンクが(int i = 0; i <30; i ++){//私の範囲内の敵のタンクが移動していることを示します(y> 0){y- =速度; } try {thread.sleep(50); } catch(arturnedexception e){// todo auto-fenated catch block e.printstacktrace(); } } 壊す;ケース1:for(int i = 0; i <30; i ++){if(x <400){x+= speed; } try {thread.sleep(50); } catch(arturnedexception e){// todo auto-fenated catch block e.printstacktrace(); } } 壊す;ケース2:for(int i = 0; i <30; i ++){if(y <300){y+= speed; } try {thread.sleep(50); } catch(arturnedexception e){// todo auto-fenated catch block e.printstacktrace(); } } 壊す;ケース3:for(int i = 0; i <30; i ++){if(x> 0){x- = speed; } try {thread.sleep(50); } catch(arturnedexception e){// todo auto-fenated catch block e.printstacktrace(); } } 壊す; } //タンクに新しい弾丸をタンクに追加する必要があるかどうかを判断します。 if(times%2 == 0){if(islive){if(ss.size()<5){shot s = null; switch(direct){case 0:// bullet s = new Shot(x+10、y、0)を作成します。 //弾丸をベクトルss.add(s)に追加します。壊す;ケース1:s = new Shot(x+30、y+10、1); ss.add(s);壊す;ケース2:s = new Shot(x+10、y+30、2); ss.add(s);壊す;ケース3:s = new Shot(x、y+10、3); ss.add(s);壊す; } //弾丸スレッドを起動しますt = newスレッド(s); t.start(); }}} //タンクがランダムに新しい方向を生成します。 }}}} //私のタンククラスのヒーローはタンクを拡張します{vector <shot> s = new vector <shot>();ショットS = null;パブリックヒーロー(int x、int y){super(x、y); } // fire public void shotenemy(){switch(this.direct){case 0:// bullet s = new Shot(x+10、y、0); // bector ss.add(s)に弾丸を追加します。壊す;ケース1:s = new Shot(x+30、y+10、1); ss.add(s);壊す;ケース2:s = new Shot(x+10、y+30、2); ss.add(s);壊す;ケース3:s = new Shot(x、y+10、3); ss.add(s);壊す; }スレッドt = newスレッド; t.start(); } //タンクの上昇public void moveup(){y- = speed; } // tank moveright(){x+= speed; } public void moveown(){y+= speed; } public void moveleft(){x- = speed; }} •mytankgame4.java
//mytankgame4.java/* *機能:タンクゲーム2.0 * 1:タンクを描く * 2:私のタンクは上下に移動できます * 3:敵のタンクを描く * 4:私のタンクは弾丸を発射できる * 5:弾丸は最大5つのショットを発射できます * 6:6:私のタンクが敵のタンクにぶつかるかどうかにかかわらず、敵は爆発:最初に3枚の写真を準備します。3爆弾を定義します。 java.awt.event。*; Import java.io.file; import java.util mytankgame4(){mp = new mypanel(); t.start(); this.add(mp); //登録してthis.addkeylistener(mp); this.setsize(400、300); this.setDefaultCloseoperation(jframe.exit_on_close); this.setVisible(true); }} class mypanel拡張jpanel explention keylistener、runnable {// myタンクヒーロー= null; //敵のタンクvector <eminetank> ets = new vector <eminetank>(); // // bombs vector <bomb> bombs = new vector <bomb>//fum///fruniseのセットを定義する3つの画像の切り替えを定義して爆弾画像を形成します1 = null;画像image2 = null; Image Image3 = null; // public myPanel(){Hero = new Hero(100,100); //敵タンクの初期化(int i = 0; i <entize; i ++){//敵タンクオブジェクトEnemytank et = new EmineTank((i+1)*50、0); et.setcolor(0); et.setDirect(2); //敵タンクスレッドT = new Thread(et)を起動します。 t.start(); //敵のタンクショットs = new Shot(et.x+10、et.y+30,2)に弾丸を交渉します。 et.ss.add(s);スレッドT2 =新しいスレッド; t2.start(); // eets.add(et);に参加してください。 } try {image1 = imageio.read(new file( "bomb_1.gif")); image2 = imageio.read(new file( "bomb_2.gif")); Image3 = imageio.read(new file( "bomb_3.gif")); } catch(Exception e){e.printstacktrace(); } // 3つの画像の初期化// image1 = toolkit.getDefaultToolkit()。getImage(Panel.class.getResource( "/bomb_1.gif")); // image2 = toolkit.getDefaultToolkit()。 toolkit.getDefaultToolkit()。getImage(panel.class.getResource( "/bomb_3.gif")); } // public public void paint(graphics g){super.paint(g); g.fillrect(0、0、400、300); //独自のタンクを描画するif(hero.islive == true){this.drawtank(hero.getx()、hero.gety()、g、this.hero.direct、1); } //各弾丸をssから削除し、(int i = 0; i <hero.ss.size(); i ++){//弾丸を取り出して、myshot = hero.ss.get(i); //弾丸を描き、弾丸を描きます。複数の弾丸を描く方法は?トラバーサルif(myshot!= null && myshot.islive == true){g.draw3drect(myshot.x、myshot.y、1、1、false); } if(myshot.islive == false){// ss vector hero.ss.remove(myshot)から弾丸を削除します。 }} //(int i = 0; i <bombs.size(); i ++){bomb b = bombs.get(i); if(b.life> 6){g.drawimage(image1、bx、by、30,30、this); } else if(b.life> 4){g.drawimage(image2、bx、by、30,30、this); } else {g.drawimage(image3、bx、by、30、30、this); } // Bの健康価値を低下させるb.lifedown(); //爆弾の健康値== 0の場合、(b.life == 0){bombs.remove(b); }} //敵のタンクを描画します(int i = 0; i <ets.size(); i ++){emenytank et = ets.get(i); if(et.islive){this.drawtank(et.getx()、et.gety()、g、et.getdirect()、0); //敵の弾丸を(int j = 0; j <et.s.size(); j ++){shot enemyshot = et.s.s. if(enemyshot.islive){g.draw3drect(enemyshot.x、enemyshot.y、1、1、false); } else {//敵のタンクが死亡したet.ss.remove(enemyshot); }}}}}}}}}} //敵の弾丸が私にヒットしたかどうか(){//各敵のタンクを削除してください(int i = 0; i <this.ets.size(); i ++){//敵のタンクを取り出します敵tank et = eTs.get(i); if(et.islive == true){for(int j = 0; j <et.ss.size(); j ++){//弾丸ショットenemyshot = et.ss.get(j); if(enemyshot.islive == true){this.hittank(enemyshot、hero); }}}}}}}}}} //私の弾丸が敵のタンクにヒットするかどうかパブリックhitenemytank(){//敵のタンクが(int i = 0; i <hero.ssize(); i ++){shot myshot = hero.s.s.s.sget(i); // bullet frut.islise frive(i)を決定するかどうかを決定するかどうかを決定します(各タンクを取り出して、(int j = 0; j <ets.size(); j ++){emenytank et = ets.get(j); if(et.islive == true){this.hittank(myshot、et); }}}}}}}}}}}}} //弾丸がタンクにヒットするかどうかを判断するために関数を記述するには、弾丸がヒタンク(ショットS、タンクET){スイッチ(et.direct){//敵タンクの方向が上または下部の場合は0:ケース2:ケース2: if(sx> et.x && s.x <et.x+20 && s.y> et.y && s.y <et.y+30){// hit death s.islive = false; // tank death et.islive = false; //爆弾を作成してベクター爆弾に入れて、新しい爆弾(et.x、et.y); bombs.add(b); }ケース1:ケース3:if(sx> et.x && s.x <et.x+30 && s.y> et.y && s.y <et.y+20){// hit death s.islive = false; //敵タンク死et.islive = false;爆弾b = new bomb(et.x、et.y); bombs.add(b); }}}}}}}} //タンクを描画しますpublic public void drawtank(int x、int y、graphics g、int direct、int type){//タンクタイプスイッチ(タイプ){ケース0:g.setcolor(color.cyan);壊す;ケース1:g.setcolor(color.yellow);壊す; } //タンクの方向スイッチ(直接){//ケース0://左のタンクを描くg.fill3drect(x、y、5、30、false); // drawline(x+10、y+15、y+15、5、30、false); y+10、10、10); //直線G.drawline(x+10、y+15、x+10、y)を描画します。壊す;ケース1://右に//上部長方形G.fill3drect(x、y、30、5、falseを描画); //下部長方形G.fill3drect(x、y+15、30、5、false); //下方長方形G.fill3drect(x、y+15、30、5、y+15、x+15、x壊す;ケース2:// g.fill3drect(x+15、y+10、x+30、y+10)の下のタンクを描く; //右のg.fill3drect(x+15、y+10、x+30、y+10); //右のg.fill3drect(x+15、y、y(x+15、y); y+5、10、20、false); //長方形g.fill3drect(x+5、y+5、10、20、false); // drawline(x+10、y+10、10、10); //直線G.drawline(x+10、y+15、x+10、y+30)壊す;ケース3://左に//上部長方形G.fill3DRECT(x、y、30、5、falseを描画); //下方の長方形G.fill3drect(x、y+15、30、5、false); //中央長方形G.fill3drect(x+5、y+5、20、10、fals(fals); 10); //ドローライン(x+15、y+10、x、y+10);壊す; }} //キーを押して処理します。左下dから右にwを上げます。 @Override public void keytyped(keyevent e){// todo auto-fide method stub} @override public void keypressed(keyevent e){// todo auto-enerated method stub if(e.getkeycode()== keyevent.vk_w){this.hero.hero.setdirect(0); this.hero.moveup(); } else if(e.getkeycode()== keyevent.vk_d){this.hero.setDirect(1); this.hero.moveright(); } else if(e.getkeycode()== keyevent.vk_s){this.hero.setDirect(2); this.hero.movedown(); } else if(e.getkeycode()== keyevent.vk_a){this.hero.setdirect(3); this.hero.moveleft(); } if(e.getkeycode()== keyevent.vk_j){//プレーヤーがj // fireを押すかどうかを判断します(this.hero.ss.size()<= 4 && this.hero.islive == true){this.hero.shotenemy(); }} //パネルはthis.repaint(); } @Override public void keyReleased(keyevent e){// todo auto-enerated method stub} public void run(){while(true){try {thread.sleep(100); } catch(Exception e){e.printstacktrace(); } this.hitenemytank(); //関数敵の弾丸が私にヒットしたかどうかを決定します。hitme(); this.repaint(); }}}5。テスト結果
黄色がプレイヤーで、プレーヤーを打ってください
敵は弾丸を発射します
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。