자세한 내용은 메모를 참조하세요. 여기서는 너무 말도 안 되는 내용을 다루지 않고 어린 시절의 고전을 구현해 보겠습니다.
Blood.java
package com.hkm.TankWar;import java.awt.*;/** * 혈액 응고 클래스, 우리 탱크는 혈액을 먹어서 회복할 수 있습니다. * @author Hekangmin * */public class Blood { private int x,y,w, h; //혈전의 위치, 너비 및 높이; private int step=0;//혈전이 이동한 단계 수를 기록합니다. public boolean isLive(); live; } public void setLive(boolean live) { this.live = live; } /** * 혈전 위치 기록 */ private int[][] pos={{400,300},{400,320},{420,320},{440,300},{440,330},{480,400},{520,400},{540,400}} public Blood() { x=pos[0][0] ; y=pos[0][1]; } public void draw(그래픽 g) { if(!live) return; Color c=g.getColor(); g.fillOval(x, y, w, h); (c); move(); } /** * 혈전 이동*/ public void move() { step++; if(step>=pos.length) step=0; ]; y=pos[단계][1]; } } 공개 직사각형 getRect() { 반환 새 직사각형(x,y,w,h) } }
Explode.java
package com.hkm.TankWar;import java.awt.*;/** * Explode class* @author Hekangmin * */public class Explode { private int x,y;//폭발이 발생한 위치 private boolean Live=true ; int dia[]={4,8,12,16,32,40,20,14,4} // 원의 직경을 표현하기 위해 원 시뮬레이션을 사용합니다. step=0;//차이는 직경으로 이동합니다. private TankWarClient tc;//참조 유지 public Explode(int x,int y,TankWarClient tc) { this.x=x; =tc; } 공개 무효 draw(그래픽 g) { if(!Live) { tc.explodes.remove(this) } if(step==dia.length)//마지막 직경에 도달하면 폭발하여 죽습니다. { Live=false; step=0 } Color c=g.getColor(); .YELLOW); g .fillOval(x, y, dia[단계], dia[단계]) g.setColor(c) } }
Missile.java
package com.hkm.TankWar;import java.awt.*;import java.awt.Event.*;import java.awt.event.KeyEvent;import java.util.List;/** * Bullet 클래스* @author Hekangmin * */ public class Missile { private int x,y;//총알의 위치 private Tank.Direction dir;//탱크의 방향 private static final int XSPEED=10;//x 방향의 탱크 이동 속도, private static final int YSPEED=10;//y 방향의 탱크 이동 속도, public static final int WIDTH=10; HEIGHT=10; private boolean Live= true; // 총알이 살아 있는지 확인 private boolean good; // 적 총알과 우리 총알을 구별합니다. public Missile(int x, int y, Tank.Direction dir) { this.x = x; this.y = y; this.dir = dir; } public Missile(int x,int y,boolean good,Tank.Direction dir,TankWarClient tc) { this(x,y,dir ); this.good=good;//탱크의 좋은 속성과 나쁜 속성을 동일하게 설정합니다. this.tc=tc } /** * 총알 그리기* @param; g는 브러시입니다*/ public void draw(Graphics g) { if(!Live) { tc.missiles.remove(this); return; c=g.getColor() { g.setColor( Color .BLUE); } else g.setColor(Color.ORANGE); g.fillOval(x, y, WIDTH, HEIGHT); } /** * 탱크의 방향에 따라 총알을 이동합니다. */ private void move() { switch(dir) { case L: x-=XSPEED; break; ; 중단; 사례 U: y-=XSPEED; 사례 R: x+=XSPEED; y+=YSPEED; 중단; 사례 LD: x-=XSPEED; } if(x<0|y<0||x>TankWarClient. >TankWarClient.GAME_HEIGHT)//총알이 경계를 넘으면 죽도록 둡니다. { Live=false } } public boolean isLive() { return; Live; } public Rectangle getRect()//글머리 기호의 직사각형 영역을 가져옵니다. { return new Rectangle(this.x, this.y, this.WIDTH, this.HEIGHT) } /** * 총알이 탱크와 충돌합니다. * @param t는 탱크입니다.* @return은 충돌을 나타내기 위해 true를 반환합니다. 그렇지 않으면 충돌이 없습니다. */ public boolean hitTank(Tank t) { if(this.Live&&this.getRect().intersects(t.getRect())&&t.isLive()&&this.good!=t.isGood()) { if(t.isGood()) { t.setLife(t. getLife()-10); if(t.getLife()<=0) t.setLive(false) }else{ t.setLive(false) } this.Live=false;///총알을 죽도록 설정합니다. Explode e=new Explode(x,y,tc);//폭발이 발생합니다. return true; } /** * 총알이 적 탱크와 충돌했는지 확인합니다. * @param Tanks 적 탱크* @returntrue는 충돌을 의미하고 false는 충돌하지 않음 */ public boolean hitTanks(List<Tank> Tanks); for(int i=0;i<tanks.size();i++) { if(hitTank(tc.tanks.get(i))) { return true } } return false } /** * 글머리 기호 여부를 결정합니다. 벽에 닿음 * @param w wall* @returntrue, hit, false, not hit */ public boolean hitWall(Wall w) { if(this.Live&&this.getRect().intersects(w.getRect())) { Live=false; return true } }
Tank.java
package com.hkm.TankWar;import java.awt.*;import java.awt.event.KeyEvent;import java.util.*;/** * Tank 클래스* @author Hekangmin * */public class Tank { public static final int XSPEED=5;//탱크 x 방향 속도 public static final int YSPEED=5; public static final int WIDTH=30; public static final int HEIGHT=30; BloodBar bb=new BloodBar();//블러드 바 private int life=100; public int getLife() { return life; } public void setLife(int life) { this.life = life } private static Random r=new Random; (); private static int step=r.nextInt(12)+3;//적 탱크가 무작위로 이동하는 데 걸리는 단계 수를 나타내는 숫자를 정의합니다. bL=false,bU=false,bR=false,bD=false; enum Direction{L,LU,U,RU,R,RD,D,LD,STOP};//탱크 방향을 정의하려면 열거형을 사용하세요. int x,y; private int oldX,oldY;//이전 단계에서 탱크의 위치를 기록합니다. private boolean live=true;//탱크가 살아 있는지 확인합니다. public boolean isLive() { return live } public void setLive; (부울 live) { this.live = live; } private boolean good;//탱크가 좋은가요, 나쁜가요? public boolean isGood() { return good; } private Direction ptDir=Direction.D;//통의 방향을 추가합니다. TankWarClient tc ;//멤버 변수에 대한 액세스를 용이하게 하기 위해 상대방의 참조를 유지하기 위해; Direction dir=Direction.STOP;//처음에 멈출 탱크 방향을 설정합니다. public Tank(int x, int y, 부울 양호, 방향 dir,TankWarClient tc) { this.x=x; this.oldX=x; this.good=dir; 상대방의 참조를 유지합니다. } public void draw(Graphics g) { if(!live)//죽으면 더 이상 그릴 수 없습니다. if(tc.tanks.size()<5)//탱크가 5개 미만인 경우 탱크 추가 { for(int i=0;i<10;i++) { int posX=r.nextInt(800); posY =r.nextInt(600); tc.tanks.add(new Tank(posX,posY,false,Direction.D,tc));//탱크의 위치를 무작위로 표시} } } return; } Color c=g.getColor(); if(good) { g.setColor(Color.RED) } else g.setColor(Color.BLACK); x, y, WIDTH, HEIGHT); g.setColor(c); switch(ptDir)//통의 방향을 그립니다. g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x-10, y+Tank.HEIGHT/2);//총신을 그리고 대신 직선을 그립니다. break; : g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x-7, y-7) break; g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x+Tank.WIDTH/2, y-10) break; 케이스 RU: g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x+Tank.WIDTH+7, y-7) 케이스 R: g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x+Tank.WIDTH+10, y+Tank.HEIGHT/2) break; WIDTH/2, y+Tank.HEIGHT/2, x+Tank.WIDTH+7, y+Tank.HEIGHT+7); 사례 D: g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x+Tank.WIDTH/2, y+Tank.HEIGHT+10) break; WIDTH/2, y+Tank.HEIGHT/2, x-7, y+HEIGHT+7) break; } move() } public void move(); oldX=x;//탱크의 이전 위치 기록 oldY=y; switch(dir) { case L: x-=XSPEED; case LU: x-=XSPEED; y -=YSPEED; 케이스 RU: x+=XSPEED; 케이스 R: x+=XSPEED; y+=YSPEED; 중단; 케이스 LD: x-=XSPEED; 중단: 중단; this.dir; /** * 탱크가 경계를 넘어가는 것을 방지합니다. */ if(x<0) x=0; if(x+Tank.WIDTH>TankWarClient.GAME_WIDTH) x=TankWarClient.GAME_WIDTH-30; if(y+Tank.HEIGHT>TankWarClient.GAME_HEIGHT) y=TankWarClient.GAME_HEIGHT-30; if(!good) { 방향[] dirs =Direction.values();//열거형을 배열로 변환합니다. if(step==0) { step=r.nextInt(12)+3; int rn=r.nextInt(dirs.length);//길이 내에서 임의의 정수 생성 dir=dirs[rn]; -; if(r.nextInt(40)>20) this.fire(); // 적 탱크가 총알을 발사하도록 합니다. } } /** * 키 누름 처리* @param e 키보드 이벤트; 공개 void KeyPressed(KeyEvent e) { int key=e.getKeyCode(); 스위치(키) { case KeyEvent.VK_LEFT: bL=true; break; case KeyEvent.VK_RIGHT: bR=true; =true; 케이스 KeyEvent.VK_DOWN: bD=true } 공개 무효; keyReleased(KeyEvent e) { int key=e.getKeyCode(); switch(key) { case KeyEvent.VK_CONTROL: fire(); case KeyEvent.VK_LEFT: bL=false; ; 중단; 케이스 KeyEvent.VK_UP: bU=false; bD=false; break; case KeyEvent.VK_F2: reBorn(); } locationDir() } /** * 글머리 기호 유형을 반환합니다. 공개 미사일 발사() { if(!live) return null; mx=this.x+Tank.WIDTH/2-Missile.WIDTH/2;//총알 발사 위치를 계산합니다. int my=this.y+Tank.HEIGHT/2-Missile.HEIGHT/2; new Missile (mx,my,good,ptDir,this.tc);////총열 방향에 따라 총알을 발사합니다. tc.missiles.add(m) return m(방향 dir); { if(!live) return null; int mx=this.x+Tank.WIDTH/2-Missile.WIDTH/2; int my=this.y+Tank.HEIGHT/2-Missile.HEIGHT/2; new Missile(mx,my,good,dir,this.tc);//탱크의 방향에 따라 총알을 발사합니다. tc.missiles.add(m) return m; 방향[] dirs=Direction.values(); for(int i=0;i<8;i++) { fire(dirs[i]) } } public void locationDir() { if(bL&&!bU&&!bR&&!bD ) dir=방향.L; else if(bL&&bU&&!bR&&!bD) dir=방향.LU; if(!bL&&bU&&!bR&&!bD) dir=방향.U; else if(!bL&&bU&&bR&&!bD) dir=방향.RU; else if(!bL&&!bU&&bR&&!bD) dir=방향.R; !bU&&bR&&bD) dir=방향.RD; if(!bL&&!bU&&!bR&&bD) dir=방향.D; else if(bL&&!bU&&!bR&&bD) dir=방향.LD; else if(!bL&&!bU&&!bR&&!bD) dir=방향.STOP; Rectangle getRect()//탱크의 직사각형 영역을 가져옵니다{ return new Rectangle(this.x,this.y,this.WIDTH,this.HEIGHT) } /** * 탱크가 벽에 부딪혔습니다* @param w wall* @returntrue hit, false not hit; 벽 w ) { if(this.live&&this.getRect().intersects(w.getRect())) { this.stay() return true }; /** * 서로 교차하는 것을 방지하기 위해 탱크 간 충돌을 처리합니다. * @param Tanks 적 탱크가 충돌하면 true를 반환하고, 충돌하지 않으면 false를 반환합니다. */ public boolean colliedsWithTanks(java.util.List< 탱크> 탱크) { for(int i=0;i<tanks.size();i++) { 탱크 t=tanks.get(i) if(this!=t) { if(this.live&&this.isLive()&&this.getRect().intersects(t.getRect())) { this.stay();//이전 단계의 위치로 돌아갑니다. t.stay();// //Return 이전 단계의 위치 return true; } } } return false } private void stay() { x=oldX } /** * Tank의 내부 클래스입니다. 탱크 머리 상단에 블러드 바가 표시됩니다. * @author Hekangmin * */ private class BloodBar { public void draw(Graphics g) { Color c=g.getColor() g .setColor(Color.RED); g.drawRect(x,y-10,WIDTH,10) int w=WIDTH*life/100; g.fillRect(x,y-10,w,10); } } /** * 혈전을 먹고 혈액을 추가합니다. * @param b 혈전* 먹으면 @returntrue, 먹지 않으면 false */ public boolean eat; (블러드 b) { if(this.live&&b.isLive()&&this.getRect().intersects(b.getRect())) { this.life=100; b.setLive(false); return true; } return false; } /** * 우리 탱크는 사망 후 부활합니다. */ public void reBorn() { if(this.isGood()&&!this.isLive()) { this.setLive(true); this.setLife(100) } }
TankWarClient.java
package com.hkm.TankWar;import java.awt.*;import java.awt.event.*;import java.util.List;import java.util.ArrayList /** * 게임 실행 창입니다. * @ 작성자 Hekangmin * */public class TankWarClient 확장 프레임{/** * 게임 창의 너비 */ public static final int GAME_WIDTH=800 /** * 게임 창의 높이; */ public static final int GAME_HEIGHT=600; Tank MyTank=new Tank(700,400,true,Tank.Direction.STOP,this) List<Tank> Tank=new ArrayList<Tank>(); List< Explode>explodes=new ArrayList<Explode>(); List<Missile> 미사일=new ArrayList<Missile>(); Wall(300,200,20,200,this); Wall w2=new Wall(600,300,30,150,this); Blood b=new Blood(); /** * 가상 그림 그리기 */ Public TankWarClient( String name)//텍스트 설정 { super(name) } /** * 실행 창 */ public void launchFrame() { for(int) i=0;i<10;i++)//적 탱크 10개 추가 { Tank.add(new Tank(50+40*(i+1),50,false,Tank.Direction.D,this) } this .setBounds(200,100,GAME_WIDTH,GAME_HEIGHT); this.setBackground(Color.GREEN); WindowAdapter()//Anonymous class { public void windowClosing(WindowEvent e) { System.exit(0) } }); this.addKeyListener(new KeyMonitor());//키보드 모니터 추가; //창의 크기는 변경할 수 없습니다. this.setVisible(true); new Thread(new PaintThread()).start();//새 스레드 생성 } public void; 페인트(그래픽 g) { g.drawString("미사일 개수: "+missiles.size(), 10, 50);//표시 문자열 g.drawString("폭발 개수: "+explodes.size(),10 , 70); g.drawString("탱크 수: "+tanks.size(),10,90) g.drawString("내 탱크 수명: "+MyTank.getLife(),10,110); /** * 벽 그리기; */ w1.draw(g); w2.draw(g); /** * 총알 및 다양한 이벤트 감지; */ for (int i=0;i<missiles.size();i++) { 미사일 m=missiles.get(i) m.hitsWall(w1); m.hitTanks(탱크); m.draw(g); //if(!m.isLive()) //missiles.remove(m); ; } /** * 폭발 그리기; */ for(int i=0;i<explodes.size();i++) { Explode e=explodes.get(i) } for(int i=0;i<tanks.size();i++) { 탱크 t=tanks.get(i); t.colliedsWithWall(w1); t.colliedsWithTanks(tanks); .draw(g); } b.draw(g); MyTank.eat(b) } /** * 탱크 깜박임 현상을 제거하기 위해 이중 버퍼링 기술을 사용합니다. */ public void update(Graphics g) //g는 화면에 그려진 브러시입니다. { if(OffScreenImage==null) OffScreenImage=this.createImage(GAME_WIDTH, GAME_HEIGHT; ); gOffScreen=OffScreenImage.getGraphics();//gOffScreen은 OffScreenImage의 브러시입니다. Color c=gOffScreen.getColor(); gOffScreen.setColor(Color.GREEN)(0, 0, GAME_WIDTH, GAME_HEIGHT); gOffScreen.setColor(c); 페인트(gOffScreen);//가상 그림에 그리기 g.drawImage(OffScreenImage,0,0,null);//g 브러시를 사용하여 화면의 가상 그림에 사물을 그립니다. private class PaintThread Implements Runnable{ public void run() { while(true) { repaint();//여기서 다시 그리기 메서드는 Frame 클래스의 try{입니다. Thread.sleep(100); }catch(InterruptedException e){ e.printStackTrace(); } } } } private class KeyMonitor는 KeyAdapter { public void keyReleased(KeyEvent e) { MyTank.keyReleased(e) } public void keyPressed( KeyEvent e) { MyTank.KeyPressed(e) } } 공개 정적 무효; main(String[] args) { new TankWarClient("내 탱크 월드").launchFrame() } }
Wall.java
package com.hkm.TankWar;import java.awt.*;/** * 장애물 벽 클래스 생성 * @author Hekangmin * */ public class Wall { /** * x, y는 벽의 위치, w , h는 너비와 높이입니다. */ int x,y,w,h; /** * 참조 보유*/ TankWarClient tc; tc) { this.x = x; this.y = y; this.h = h; this.tc = tc } 공개 void draw(그래픽 g) { 색상 c=g.getColor() ; g.setColor(Color.GRAY); g.fillRect(x,y,w,h); g.setColor(c) } /** * 벽의 직사각형 영역을 가져옵니다 */ 공공의 Rectangle getRect() { return new Rectangle(x,y,w,h) } }
이상이 이 글의 전체 내용입니다. 모두 마음에 드셨으면 좋겠습니다.