1. 요구 사항 설명
1. 기능 요구 사항
기능 요구 사항 분석 단계에서 우리의 주요 작업은 시스템이 제공 해야하는 서비스를 지정하고 소프트웨어가 완료 한 기능을 정의하고 해당 사람들에게 제공하는 것입니다. 기능 요구 사항은 소프트웨어 개발의 기본 요구 사항이며 수요 분석의 필수 부분입니다. 탱크 전쟁은 고전적인 게임입니다. 이 게임은 전임자의 경험을 배웠습니다. 전반적으로, 게임은 적과 우리의 양쪽으로 나뉩니다. 주로 전투에 참여하는 탱크는 플레이어가 통제합니다. 적 탱크는 화면에 지능적이고 무작위로 나타날 수 있으며 특정 수의 총알을 발사합니다. 플레이어는 지정된 지역에서 탱크를 마음대로 움직일 수 있습니다. 총알이 플레이어를 때리면 플레이어가 죽고 게임이 끝납니다. 적 탱크는 지능적으로 운행됩니다. 그들은 어느 정도의 지능이 필요하기 때문에 화면에 무작위로 나타나고 다음과 같이 자유롭게 회전합니다. 경계에 직면 할 때 스티어링을 아는 것; 총알 런 : 탱크는 다른 탱크 위치에 따라 플레이어와 화재 총알에 의해 제어됩니다. 그들이 목표에 부딪히면 폭발 효과가 생성 될 것입니다. 화면에서도 사라집니다.
2. 시스템 성능 요구 사항
컴퓨터 시스템을 기반으로하는 게임의 성능 구성 요구 사항은 프로그램이 빠르고 안정적으로 실행될 수 있으며 실행할 때 적시에 응답 할 수 있도록하는 것입니다. 게임에서 플레이어의 탱크가 파괴되면 게임의 실패에 대한 정보를 즉시 신속하게보고 게임의 규칙 요구 사항을 충족시키기 위해 적시에 응답하십시오. 또한 게임을 할 때 기본 창의 크기를 마음대로 변경할 수 없어 플레이 가능성을 보장해야합니다.
3. 기능적 솔루션
코드 활용률은 게임에서 매우 좋습니다. 결국, 그것은 실시간 작업입니다. 밀리 초마다 총알이 많이 발사되고 많은 탱크의 좌표 이동이있을 것입니다. 나는 탱크에 셀 수없이 많은 총알의 수와 키보드 모니터링 이벤트를 비교하고 스레드 인터페이스를 구현하고 다시 그리기 및 상쾌한 그리기; 논리의 감각은 강력해야하며 객체 지향 디스플레이가 완전히 표시됩니다. 그들 사이의 관계조차 불분명하며 예상치 못한 상황을 쉽게 갖추기가 쉽습니다. 게임에서 아름다움을 추가하고 폭발을 더하기 위해서는 적 탱크가 죽을 때 고정 된 고정 된 회전 목마가 외부 패널에 그림을 배치하여 폭발 효과를 달성해야합니다.
일반적으로 탱크 전투에서 완료해야 할 기본 기능에는 다음이 포함됩니다. 그래픽 인터페이스, 적대 탱크 스타일의 차이, 탱크는 총알을 발사하여 상대방을 공격 할 수 없지만 팀원을 공격 할 수는 없으며 탱크는 특정 건강 지점을 설정합니다.
2. 주요 기능 분석
탱크 전쟁 게임 개발 과정에서 주요 기능은 사용하기 위해 사용자에게 제공되므로 먼저 탱크를 그려야합니다.
1. 플레이어 탱크를 그리십시오 : JPANEL 패널에 페인트 ()를 설정하고 브러시로 탱크의 대략적인 모양을 그립니다.
2. 플레이어의 탱크는 움직일 수 있습니다 : 탱크가 움직이면 탱크의 좌표를 변경하고 패널을 지속적으로 다시 칠해야합니다. 그러나 탱크가 이동하면 이벤트 모니터링 메커니즘 (키보드 모니터링) 인터페이스를 패널 클래스에서 구현할 수 있습니다. 플레이어가 w/d/s/a 키를 누르면 위, 아래로, 왼쪽과 오른쪽으로 이동할 수 있습니다.
3. 그리고 내 그림 종이 페인트 ()에 적 탱크를 그립니다. 적 탱크와 플레이어 탱크는 동일한 인터페이스에 있기 때문에 동일한 드로잉 보드에 그려야합니다.
4. 플레이어의 탱크는 총알을 발사 할 수 있습니다. 플레이어가 총알을 발사하려면 이벤트 소스가 필요합니다. 사용자가 J 키를 누르면 이벤트 모니터링이 즉시 총알을 발사하지만 효과를보기 위해 사용자의 눈 앞에 표시해야하므로 Paint ()는 패널에 총알을 그립니다. 총알이 출시되고 발사를 향해 지속적으로 움직이기 때문에 총알의 좌표는 지속적으로 변경되어야하며 총알 속도는 적절해야하므로 스레드로 구현해야하며 패널은 지속적으로 다시 그려져 효과를 확인해야합니다.
5. 플레이어는 총알을 연속으로 발사하고 최대 5 개까지 발사 할 수 있습니다. 플레이어가 총알 수를 제어하려면 플레이어가 J 키를 누를 때 현재 생존하는 총알의 수가 5 미만인지 알아야합니다. 조건이 충족되면 총알 하나가 생성됩니다. 플레이어가 5 개 이상의 총알을 발사하면 시스템의 화재 기능이 더 이상 호출되지 않습니다. 총알을 발사하는 것은 총알 하나를 발사 할뿐만 아니라 총알 세트를 설정하여 한 번에 총알 하나를 생성하여 총알이 경계에 부딪히고 죽을 때 죽는다는 것을 알기 위해 총알을 생성합니다.
6. 플레이어의 탱크가 적 탱크에 부딪히면 사라지고 폭발 효과가 발생합니다. 첫째, 플레이어의 탱크의 총알이 적을 때리는 지 여부를 결정해야하므로 적을 끊임없이 판단하는 기능이 있습니다. 총알이 적 탱크에서 달리면 탱크의 생명이 끝나고 폭탄이 생겨나고 폭탄이 페인트 ()에 그려집니다.
7. 적의 탱크는 지능적으로 움직일 수 있습니다. 탱크가 움직일 수 있다면 무작위로 움직이는 방향을 생성해야합니다. 일정한 움직임으로 인해이 방법은 스레드의 실행 함수에 기록되며 스레드는 이동 속도 문제를 달성하기 위해 수면으로 제어됩니다.
8. 적 탱크는 총알을 발사 할 수 있습니다. 적을 끌어들이는 동안 실에 특정 휴면을 설정하여 다른 방향과 다른 수의 탱크를 생성하고 패널에 각 총알을 꺼내어 그립니다.
9. 적의 총알이 플레이어를 때리면 플레이어가 사라집니다. 적의 각 총알을 계속 꺼내어 플레이어의 탱크와 비교하십시오. 총알이 플레이어에게 닿으면 플레이어의 폭발이 사라집니다.
3. 요약 설계
• 역할 속성 설정
탱크 : 탱크가 생성되는 위치, 다양한 유형의 탱크의 색상, 탱크의 수명 식별자, 탱크 이동 속도 및 다른 방향으로 탱크;
플레이어 탱크 : 탱크의 기본 속성을 물려받은 후, 두 번째 기준으로 실현되며 플레이어 탱크는 자유롭게 위아래로 움직이며 왼쪽과 오른쪽으로 이동합니다. 그리고 플레이어 탱크는 총알을 발사하고 발사하는 기능을 가지고 있습니다.
적 탱크 : 기본 탱크 속성을 물려받은 후에는 적 탱크의 지능적인 움직임을 실현해야하며 동시에 다른 위치에서 탱크에서 총알 실을 발사해야합니다.
총알 : 총알은 좌표 위치, 속도, 건강 및 총알이 움직일 수 있어야하며 총알은 또한 사망 기능 방법을 구현해야합니다.
폭탄 : 폭탄, 생명 및 점차 사라지는 삶의 효과 방법 기능;
• 기능적 속성 설정
그리기 용지 : Paint ()는 플레이어 탱크, 적 탱크를 끌고 죽음의 탱크의 폭발 효과를 표시해야합니다.
이벤트 모니터링 : 사용자가 WDSA를 누르면 해당 플레이어 탱크가 방향을 변경해야합니다. 사용자가 J를 발사하면 발사 방향에 총알이 있으며 적을 때리지 않는 한 죽음까지 실행해야합니다.
탱크에 부딪히십시오 : 총알이 적의 탱크에 부딪히면 폭발이 발생하여 폭발 세트에 추가되고 폭발 정보가 표면에 그려집니다.
적들이 플레이어를 때렸다 : 게임에서 소위 적을 꺼내고 각 적의 총알이 내 탱크와 일치하여 그것을 때릴지 여부를 결정한다.
플레이어는 적을 때렸다. 지속적인 동시 판단을하기 위해 탱크를 실행 ()에 치는 것과 관련된 판단을 두십시오.
특정 기능 분석 다이어그램은 다음과 같습니다.
• 탱크 문자 속성 분석 다이어그램
기능적 드로잉 보드 분석 다이어그램
탱크 Xmind 전체 분석 다이어그램
탱크 문자 속성 xmind 다이어그램
탱크 기능 속성 xmind 다이어그램
IV. 시스템 구현
• 회원. 자바
//members.javapackage myTank9; import java.util.*; 클래스 폭탄 {// 폭탄 정의 int x, y; // 폭탄의 수명은 int life = 9입니다. 부울 islive = true; 공개 폭탄 (int x, int y) {this.x = x; this.y = y; } // 건강 감소 공개 void lifedown () {if (life> 0) {life-; } else {this.islive = false; }}} 클래스 샷은 실행 가능한 {int x; in y; int Direct; int 속도 = 1; 부울 islive = true; 공개 샷 (int x, int y, int direct) {this.x = x; this.y = y; this.direct = direct; } public void run () {while (true) {try {thread.sleep (50); } catch (예외 e) {e.printstacktrace (); } 스위치 (직접) {case 0 : y- = 속도; 부서지다; 사례 1 : x+= 속도; 부서지다; 사례 2 : y+= 속도; 부서지다; 사례 3 : X- = 속도; 부서지다; } // (x <0 || x> 400 || y <0 || y> 300) if 필드가 가장자리에 닿는 지 여부를 결정합니다. {this.islive = false; 부서지다; }}}} 클래스 탱크 {// 탱크 수평 좌표 int x = 0; // g 수직 좌표 in y = 0; // 탱크 방향 // 0은 상단을 나타냅니다. 1은 오른쪽을 나타냅니다. 부울 islive = true; public int getColor () {return color; } public void setColor (int color) {color = color; } public int getSpeed () {반환 속도; } public void setSpeed (int speed) {this.speed = 속도; } public int getDirect () {return Direct; } public void setDirect (int direct) {this.direct = direct; } 공공 탱크 (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; // 적의 총알 벡터 <shot> ss = new 벡터 <shot> (); // 적의 탱크가 방금 만들어지고 적의 탱크가 공개적으로 죽었다. } @override public void run () {// todo 자동 생성 메소드 스튜브 (true) {true) {switch (this.direct) {case 0 : // 탱크가 (int i = 0; i <30; i ++)로 이동하고 있음을 나타냅니다. (y> 0) {y- = 속도; } try {thread.sleep (50); } catch (InterruptedException e) {// todo 자동 생성 캐치 블록 e.printstacktrace (); } } 부서지다; 사례 1 : for (int i = 0; i <30; i ++) {if (x <400) {x+= 속도; } try {thread.sleep (50); } catch (InterruptedException e) {// todo 자동 생성 캐치 블록 e.printstacktrace (); } } 부서지다; 사례 2 : (int i = 0; i <30; i ++) {if (y <300) {y+= 속도; } try {thread.sleep (50); } catch (InterruptedException e) {// todo 자동 생성 캐치 블록 e.printstacktrace (); } } 부서지다; 사례 3 : for (int i = 0; i <30; i ++) {if (x> 0) {x- = 속도; } try {thread.sleep (50); } catch (InterruptedException e) {// todo 자동 생성 캐치 블록 e.printstacktrace (); } } 부서지다; } // 탱크에 새 총알을 추가 해야하는지 결정 this.times ++; if (times%2 == 0) {if (iSlive) {if (ss.size () <5) {shot s = null; 스위치 (Direct) {case 0 : // 총알 생성 s = new shot (x+10, y, 0); // 총알을 벡터에 추가합니다. 부서지다; 사례 1 : S = 새로운 샷 (x+30, y+10, 1); ss.add (s); 부서지다; 사례 2 : s = 새로운 샷 (x+10, y+30, 2); ss.add (s); 부서지다; 사례 3 : s = 새로운 샷 (x, y+10, 3); ss.add (s); 부서지다; } // 총알 스레드를 시작합니다 스레드 T = 새 스레드 (S); t.start (); }}} // 탱크가 새로운 방향을 무작위로 생성하도록하십시오 .Direct = (int) (math.random ()*4); // 적의 탱크가 죽는 지 확인하십시오 (this.islive == false) {// 탱크가 죽게 된 후 프로세스 중단을 종료하십시오. }}}} // 내 탱크 클래스 영웅은 탱크를 확장합니다. shot s = null; 공개 영웅 (int x, int y) {super (x, y); } // fire public void shotenemy () {switch (this.direct) {case 0 : // 총알 생성 s = new shot (x+10, y, 0); // 벡터 ss.add (s)에 총알을 추가합니다. 부서지다; 사례 1 : S = 새로운 샷 (x+30, y+10, 1); ss.add (s); 부서지다; 사례 2 : s = 새로운 샷 (x+10, y+30, 2); ss.add (s); 부서지다; 사례 3 : s = 새로운 샷 (x, y+10, 3); ss.add (s); 부서지다; } 스레드 t = 새 스레드; t.start (); } // 탱크 이동으로 이동하여 공개 무효 이동 moveup () {y- = 속도; } // Tank Moveright () {x+= 속도; } public void movenown () {y+= 속도; } public void moveleft () {x- = 속도; }} • myTankGame4.java
//mytankgame4.java/* * 1 : 탱크 게임 2.0 * 1 : 탱크 드로우 * 2 : 내 탱크가 위아래로 움직일 수 있습니다 * 3 : 적의 탱크를 그릴 수 있습니다 * 3 : 내 탱크는 총알을 불러 일으 킵니다 * 5 : 총알이 5 번 연속 샷을 때릴 수 있습니다. 폭발 : 1 적 탱크 벡터를 때릴 때 3 장의 사진을 정의하십시오. 7 : 적의 탱크는 총알을 발사 할 수 있습니다. java.awt.event myTankGame4 () {mp = new myPanel (); t.start (); this.add (mp); // this.addkeylistener (mp); this.setsize (400, 300); this.setDefaultCloseOperation (jframe.exit_on_close); this.set -Visible (true); }} Class MyPanel은 jpanel을 확장합니다. jpanel 구현 Keylistener, Runnable {// my 탱크 영웅을 정의합니다. 폭탄 이미지를 형성하기 위해 세 가지 이미지의 스위칭을 정의하십시오. 이미지 1 = null; image image2 = null; image image3 = null; // public mypanel () {hero = new Hero (100,100); // 적의 탱크 초기화 (int i = 0; i <ensrize; i ++) {// 적 탱크 개체를 만듭니다. et.setcolor (0); et.setDirect (2); // 적 탱크 스레드 시작 t = new Thread (et); t.start (); // 적의 탱크 샷에 대한 총알을 협상합니다. et.ss.add (s); 스레드 t2 = 새 스레드; t2.start (); // join ets.add (et); } try {image1 = imageio.read (새 파일 ( "bomb_1.gif")); image2 = imageio.read (새 파일 ( "bomb_2.gif")); image3 = imageio.read (새 파일 ( "bomb_3.gif")); } catch (예외 e) {e.printstacktrace (); } // 3 개의 이미지 초기화 // image1 = thoolkit.getDefaultToolKit (). getImage (panel.class.getResource ( "/bomb_1.gif")); // image2 = toolkit.getDefaultToolKit (). getImage (panel.class.getResource ( "/bomb_2.gif"); // image3 = =); Toolkit.getDefaultToolKit (). getImage (panel.class.getResource ( "/bomb_3.gif")); } // public void Paint (그래픽 g) {super.paint (g); g.fillRect (0, 0, 400, 300); // 자신의 탱크를 그 자체 탱크를 그립니다 (hery.islive == true) {this.drawtank (hero.getx (), hero.gety (), g, this.hero.direct, 1); } // ss에서 각 총알을 제거하고 (int i = 0; i <hero.ss.size (); i ++) {// 총알 촬영 myshot = hero.s.get (i); // 총알을 그려 총알 하나를 그립니다. 여러 총알을 그리는 방법? traversal 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의 건강 가치를 줄입니다. }} // (int i = 0; i <ets.size (); i ++) {EnemyTank et = ets.get (i); if (et.islive) {this.drawtank (et.getx (), et.gety (), g, et.getDirect (), 0); // (int j = 0; if (empershot.islive) {g.draw3drect (emperyshot.x, empyshot.y, 1, 1, false); } else {// 적 탱크가 죽었다. }}}}}}}}}}}}}}}}}}}}}}}}} // 적의 총알이 나에게 대중 무효화 hitme ()를 때리기 if (et.islive == true) {for (int j = 0; if (empershot.islive == true) {this.hittank (Enmyshot, Hero); }}}}}}}}}}}}}}}}}}}} {// 적의 탱크 공개 void hitenemytank () {// 적의 탱크가 (int i = 0; i <hero.ss.size (); i ++) {shot myshot = 영웅. 각 탱크를 꺼내서 판단하려면 (int j = 0; if (et.islive == true) {this.hittank (myshot, et); } } } } } } } } } } }// To write a function specifically to determine whether the bullet hits the tank public void hitTank(Shot s, Tank et) { switch(et.direct) { // If the enemy tank direction is the upper or lower case 0: case 2: if (sx> et.x && s.x <et.x+20 && s.y> et.y && s.y && s.y <et.y+30) {// death s.islive = false; // tank death et.islive = false; // 벡터 폭탄에 넣고 새로운 폭탄 (et.x, et.y); 폭탄 (b); } 사례 1 : 사례 3 : if (sx> et.x && s.x <et.x+30 && s.y> et.y && s.y <et.y+20) {{// death s.islive = false; // 적 탱크 데스 et.islive = false; 폭탄 B = 새로운 폭탄 (ET.X, et.y); 폭탄 (b); }}}}}}}} // 탱크 공개 void drawtank (int x, int y, graphics g, int direct, int type) {// 탱크 유형 스위치 (type) {case 0 : g.setColor (color.cyan); 부서지다; 사례 1 : G.SetColor (Color.Yellow); 부서지다; } // 탱크 방향 스위치 (Direct) {// UP CASE 0 : // 왼쪽 g.fill3drect (x, y, 5, 30, false)에 탱크를 그립니다 (x+10, y+15, y+15, 5, 30, false); // 중간 사각형 g.fill3drect (x+5, y+5, 10, 20, 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) 부서지다; 사례 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+30, y+10); // 탱크를 오른쪽 g.fill3drect (x+15, y 5, 30, false); 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, false)를 그립니다. 드로 라인 (x+15, y+10, x, y+10); 부서지다; }} // 키를 누르고 처리합니다. 왼쪽 아래로 d에서 오른쪽으로 w 위로. @override public void keytyped (keyevent e) {// todo 자동 생성 메소드 스터브} @override public void keypressed (keyevent e) {// todo auto-reconeated method stub if (e.getKeyCode () == keyEvent.vk_w) {this.hero.setIbrect (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.s.size () <= 4 && this.hero.islive == true) {this.hero.shotenemy (); }} // 패널을 다시 칠해야합니다. repaint (); } @override public void keyreleased (keyevent e) {// todo 자동 생성 메소드 스터브} public void run () {while (true) {try {thread.sleep (100); } catch (예외 e) {e.printstacktrace (); } this.hitenemyTank (); // 함수는 적의 총알이 나에게 this.hitme ()를 때리는지를 결정합니다. this.repaint (); }}}5. 테스트 결과
노란색은 플레이어이고 플레이어를 때렸습니다
적의 총알
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.