Consulte las notas para obtener más detalles. No entraré en demasiadas tonterías aquí, solo realizaré un clásico de la infancia.
sangre.java
package com.hkm.TankWar;import java.awt.*;/** * Clase de coágulo de sangre, nuestro tanque puede recuperar sangre al comerla * @author Hekangmin * */public class Blood { private int x,y,w, h; // La posición, el ancho y la altura del coágulo de sangre; private TankWarClient tc; private int step=0;// Registre el número de pasos que mueve el coágulo de sangre private boolean live=true; live; } public void setLive(boolean live) { this.live = live } /** * Registre la ubicación del coágulo de sangre */ private int[][] pos={{400,300},{400,320},{420,320},{440,300},{440,330},{480,400},{520,400},{540,400}} sangre pública() { x=pos[0][0] ; y=pos[0][1]; } public void draw(Gráficos g) { if(!live) return; color c=g.getColor(); g.setColor(Color.CYAN); (c); mover(); } /** * Mover el coágulo de sangre*/ public void move() { paso++ if(paso>=pos.length) paso=0; ]; y=pos[paso][1]; } } Rectángulo público getRect() { return nuevo Rectángulo(x,y,w,h);
Explotar.java
package com.hkm.TankWar;import java.awt.*;/** * Clase de explosión* @author Hekangmin * */public class Explode { private int x,y;//La ubicación donde ocurrió la explosión private boolean Live=true ; int dia[]={4,8,12,16,32,40,20,14,4} // Usa la simulación de círculo para representar el diámetro del círculo; step=0;//La diferencia se mueve al diámetro private TankWarClient tc;//Manteniendo la referencia public Explode(int x,int y,TankWarClient tc) { this.x=x; this.y=y; =tc; } public void draw(Gráficos g) { if(!Live) { tc.explodes.remove(this }); if(step==dia.length)//Si alcanza el último diámetro, explotará y morirá; { Live=false; .AMARILLO); g .fillOval(x, y, dia[paso], dia[paso]); g.setColor(c);
Misil.java
paquete com.hkm.TankWar;importar java.awt.*;importar java.awt.Event.*;importar java.awt.event.KeyEvent;importar java.util.List;/** * Clase de bala* @author Hekangmin * */ public class Missile { private int x,y;// La posición de la bala private Tank.Direction dir;// La dirección del tanque private static final int XSPEED=10;//La velocidad de movimiento del tanque en la dirección x, private static final int YSPEED=10;//La velocidad de movimiento del tanque en la dirección y, public static final int WIDTH=10; HEIGHT=10; private boolean Live= true; // Determinar si la bala está viva private boolean good; // Distinguir entre balas enemigas y nuestras propias balas private TankWarClient tc; 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;//Establece los atributos buenos y malos del tanque y el atributo de devolución de daño de la bala al mismo tiempo; this.tc=tc; g es el pincel*/ public void draw(Gráficos g) { if(!Live) { tc.missiles.remove(this } return; Color .AZUL); } /** * Mueve la bala según la dirección del tanque */ private void move() { switch(dir) { case L: x-=XSPEED; break case LU: x-=XSPEED; ; romper; caso U: y-=YSPEED; romper caso RU: x+=XSPEED; y-=YSPEED; romper caso R: x+=XSPEED; y+=YSPEED; caso D: y+=YSPEED; caso LD: x-=XSPEED; y+=YSPEED } if(x<0||y<0||x>TankWarClient.GAME_WIDTH; >TankWarClient.GAME_HEIGHT)//Si la bala cruza el límite, déjala morir; { Live=false } } public boolean isLive() { return; Live; } public Rectángulo getRect()//Obtener el área rectangular de la viñeta; { return new Rectángulo(this.x, this.y, this.WIDTH, this.HEIGHT } /** * Determinar si); la bala choca con el tanque; * @param t es el tanque* @return devuelve verdadero para indicar una colisión; de lo contrario, no hay colisión */ 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(falso); this.Live=false;/// Mata la bala; Explode e=new Explode(x,y,tc);//Se produce una explosión; tc.explodes.add(e); } /** * Determinar si la bala chocó con el tanque enemigo; * @param tanks tanque enemigo* @returntrue significa colisión, false no choca */ public boolean hitTanks(List<Tank> tanks) { for(int i=0;i<tanks.size();i++) { if(hitTank(tc.tanks.get(i))) { return true } } return false } /** * Determinar si la bala; golpea la pared * @param w wall* @returntrue, hit, false, not hits */ public boolean hitsWall(Wall w) { if(this.Live&&this.getRect().intersects(w.getRect())) { Live=false; devuelve verdadero;
tanque.java
paquete com.hkm.TankWar;import java.awt.*;import java.awt.event.KeyEvent;import java.util.*;/** * Clase de tanque* @author Hekangmin * */public class Tank { public static final int XSPEED=5;// velocidad del tanque en dirección x public static final int YSPEED=5; public static final int WIDTH=30; BloodBar bb=new BloodBar();// barra de sangre 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;//Define un número para representar el número de pasos que toma el tanque enemigo para moverse aleatoriamente private boolean; bL=false,bU=false,bR=false,bD=false; enum Direction{L,LU,U,RU,R,RD,D,LD,STOP};//Utilice el tipo de enumeración para definir la dirección del tanque privado; int x,y; private int oldX,oldY;// registra la posición del tanque en el paso anterior; private boolean live=true;// determina si está vivo public boolean isLive() { return live } public void setLive (booleano live) { this.live = live; } private boolean good;// ¿El tanque es bueno o malo? public boolean isGood() { return good; private Direction ptDir=Direction.D;//Agrega la dirección del cañón; TankWarClient tc ;// Para mantener la referencia de la otra parte para facilitar el acceso a sus variables miembro; Direction dir=Direction.STOP;// Establecer la dirección del tanque para que se detenga al principio; int y, booleano bueno, Dirección dir,TankWarClient tc) { this.x=x; this.y=y; this.oldX=x; this.oldY=y; this.dir=dir;// Mantenga la referencia de la otra parte; } public void draw(Graphics g) { if(!live)// Si muere, ya no dibujará { if(!good) { tc.tanks.remove(this); if(tc.tanks.size()<5)//Agregar tanques cuando haya menos de 5 tanques; { 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));//Hacer que la ubicación del tanque parezca aleatoria} } } return } Color c=g.getColor(); if(good) { g.setColor(Color.RED); bb.draw(g } else g.setColor(Color.BLACK); x, y, WIDTH, HEIGHT); g.setColor(c); switch(ptDir)//Dibuja la dirección del cañón { case L: g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x-10, y+Tank.HEIGHT/2);//Dibuja el cañón del arma y dibuja una línea recta en su lugar; : g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x-7, y-7); g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x+Tank.WIDTH/2, y-10 caso RU: g.drawLine(x+Tank.WIDTH/2, y+Tanque.ALTURA/2, x+Tanque.ANCHO+7, y-7); caso R: g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x+Tank.WIDTH+10, y+Tank.HEIGHT/2 caso de ruptura RD: g.drawLine(x+Tank. ANCHO/2, y+ALTURA.Tanque/2, x+ANCHO.Tanque+7, y+ALTURA.Tanque+7); caso de ruptura D: g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x+Tank.WIDTH/2, y+Tank.HEIGHT+10 case LD: g.drawLine(x+Tank. ANCHO/2, y+Tanque.ALTURA/2, x-7, y+ALTURA+7 } movimiento() } movimiento vacío público(); oldX=x;//Registra la posición anterior del tanque oldY=y; switch(dir) { case L: x-=XSPEED; break; case LU: x-=XSPEED; y -=YSPEED; caso RU: x+=XSPEED; y-=YSPEED; caso R: x+=XSPEED caso RD; y+=YSPEED; case D: y+=YSPEED; break; case LD: x-=XSPEED; y+=YSPEED; break case } if(this.dir!=Direction.STOP) this.dir; /** * Evitar que los tanques crucen el límite */ 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) { Dirección[] dirs; =Direction.values();//Convierte el tipo de enumeración en una matriz; if(step==0) { step=r.nextInt(12)+3; int rn=r.nextInt(dirs.length);// Genera un número entero aleatorio dentro de la longitud dir=dirs[rn]; -; if(r.nextInt(40)>20) this.fire(); // Hacer que el tanque enemigo dispare balas; } } /** * Manejar pulsaciones de teclas* @param e evento de teclado */ public void KeyPressed(KeyEvent e) { int key=e.getKeyCode(); switch(key) { case KeyEvent.VK_LEFT: bL=true; case KeyEvent.VK_RIGHT: bR=true; =verdadero; caso KeyEvent.VK_DOWN: bD=verdadero } ubicaciónDir() } vacío público; keyReleased(KeyEvent e) { int key=e.getKeyCode(); switch(key) { case KeyEvent.VK_CONTROL: fire(); case KeyEvent.VK_LEFT: bL=false; ; romper; caso KeyEvent.VK_UP: bU=falso; caso KeyEvent.VK_DOWN: bD=false; case KeyEvent.VK_A: superFire(); case KeyEvent.VK_F2: reBorn() } locationDir() } /** * Disparar una bala* @return Devuelve el tipo de bala*/ lanzamiento de misiles públicos() { if(!live) return null; mx=this.x+Tank.WIDTH/2-Missile.WIDTH/2;//Calcular la posición del lanzamiento de la bala; int my=this.y+Tank.HEIGHT/2-Missile.HEIGHT/2; new Missile (mx,my,good,ptDir,this.tc);////Lanza balas según la dirección del cañón tc.missiles.add(m) public Missile fire(Dirección 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);//Lanza balas según la dirección del tanque; tc.missiles.add(m); public void superFire() { Dirección[] dirs=Direction.values(); for(int i=0;i<8;i++) { fire(dirs[i]); ) dir=Dirección.L; else if(bL&&bU&&!bR&&!bD) dir=Dirección.LU; if(!bL&&bU&&!bR&&!bD) dir=Dirección.U; else if(!bL&&bU&&bR&&!bD) dir=Dirección.RU; else if(!bL&&!bU&&bR&&!bD) dir=Dirección.R; !bU&&bR&&bD) dir=Dirección.RD; if(!bL&&!bU&&!bR&&bD) dir=Dirección.D; else if(bL&&!bU&&!bR&&bD) dir=Dirección.STOP } public Rectángulo getRect()//Obtener el área rectangular del tanque{ return new Rectángulo(this.x,this.y,this.WIDTH,this.HEIGHT); } /** * El tanque chocó contra la pared* @param w wall* @returntrue golpeó, false no golpeó */ public boolean colliedsWithWall( Muro w ) { if(this.live&&this.getRect().intersects(w.getRect())) { this.stay() return true } return false } /** * Manejar las colisiones entre tanques para evitar que se crucen entre sí; * @param tanks tanques enemigos; * @return true si chocan, false si no lo hacen */ public boolean colliedsWithTanks(java.util.List<; Tanque> tanques) { for(int i=0;i<tanks.size();i++) { Tanque t=tanks.get(i); if(this!=t) { if(this.live&&this.isLive()&&this.getRect().intersects(t.getRect())) { this.stay();//Regresar a la posición del paso anterior t.stay();// //Devuelve la posición del paso anterior return true; } } } return false } private void estancia() { x=oldX; Es la clase interna de Tank; la barra de sangre se muestra en la parte superior de la cabeza de nuestro tanque; * @author Hekangmin * */ private class BloodBar { public void draw(Graphics g) { Color c=g.getColor(); .setColor( Color.RED); g.drawRect(x,y-10,WIDTH,10); g.fillRect(x,y-10,w,10); } } /** * Comer coágulos de sangre y agregar sangre; * @param b coágulos de sangre* @returntrue si se come, false si no se come */ public boolean eat; (Sangre b) { if(this.live&&b.isLive()&&this.getRect().intersects(b.getRect())) { this.life=100; b.setLive(false); return true; } return false } /** * Nuestro tanque resucitará después de la muerte */ public void reBorn() { if(this.isGood()&!this.isLive()) { this.setLive(verdadero); this.setLife(100);
TankWarClient.java
paquete com.hkm.TankWar;import java.awt.*;import java.awt.event.*;import java.util.List;import java.util.ArrayList /** * Esta es la ventana de ejecución del juego; * @ autor Hekangmin * */public class TankWarClient extends Frame{/** * Ancho de la ventana del juego */ public static final int GAME_WIDTH=800; La altura de la ventana del juego; */ public static final int GAME_HEIGHT=600; Tank MyTank=new Tank(700,400,true,Tank.Direction.STOP,this List<Tank> tanks=new ArrayList<Tank>(); Lista<Explosión> explota=nueva ArrayList<Explosión>(); Lista<Misiles> misiles=nueva ArrayList<Misil>Muro w1=nueva Wall(300,200,20,200,this); Wall w2=new Wall(600,300,30,150,this); Blood b=new Blood();** * Dibujar una imagen virtual */ Image OffScreenImage=null; nombre)//Establecer texto { super(nombre } /** * Ejecutar ventana */ public void launchFrame() { for(int) i=0;i<10;i++)//Agrega diez tanques enemigos { tanks.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()//Clase anónima { public void windowClosing(WindowEvent e) { System.exit(0); } }); this.addKeyListener(new KeyMonitor());//Agregar monitor de teclado; //El tamaño de la ventana no se puede cambiar; this.setVisible(true); new Thread(new PaintThread()).start();//Crea un nuevo hilo } public void; paint(Graphics g) { g.drawString("Recuento de misiles: "+missiles.size(), 10, 50);//Mostrar cadena; g.drawString("Recuento de explosiones: "+explodes.size(),10, 70); g.drawString("recuento de tanques: "+tanks.size(),10,90); "+MyTank.getLife(),10,110); /** * Dibujar la pared; */ w1.draw(g); w2.draw(g); /** * Detectar balas y varios eventos; */ for (int i=0;i<misiles.size();i++) { Misil m=misiles.get(i); m.hitsWall(w1); m.hitTanks(tanques); m.hitTank(MyTank); m.draw(g); //if(!m.isLive()) //misiles.remove(m); ; } /** * Dibujar explosiones */ for(int i=0;i<explodes.size();i++) { Explotar e=explodes.get(i); for(int i=0;i<tanks.size();i++) { Tanque t=tanks.get(i); t.colliedsWithWall(w1); t.colliedsWithWall(w2); .draw(g); } b.draw(g); MiTanque.eat(b); MiTanque.draw(g); * Utilice tecnología de doble almacenamiento en búfer para eliminar el fenómeno del parpadeo del tanque */ public void update(Graphics g) //g es el pincel dibujado en la pantalla { if(OffScreenImage==null) OffScreenImage=this.createImage(GAME_WIDTH, GAME_HEIGHT; ); gOffScreen=OffScreenImage.getGraphics();//gOffScreen es el pincel de OffScreenImage Color c=gOffScreen.getColor(); gOffScreen.setColor(Color.GREEN). gOffScreen.setColor(c); paint(gOffScreen);//Dibuja en la imagen virtual; g.drawImage(OffScreenImage,0,0,null);//Usa el pincel g para dibujar cosas en la imagen virtual en la pantalla} la clase privada PaintThread implementa Runnable{ public void run() { while(true) { repaint();// El método de repintado aquí es el try{ de la clase Frame Thread.sleep(100); }catch(InterruptedException e){ e.printStackTrace(); } } } } clase privada KeyMonitor extiende KeyAdapter { public void keyReleased(KeyEvent e) { MyTank.keyReleased(e } public void keyPressed( KeyEvent e) { MyTank.KeyPressed(e); } } vacío estático público; main(String[] args) { new TankWarClient("Mi mundo de tanques").launchFrame();
pared.java
package com.hkm.TankWar;import java.awt.*;/** * Generar la clase de muro de obstáculos * @author Hekangmin * */ public class Wall { /** * x, y es la posición del muro, w , h es el ancho y el alto */ int x,y,w,h; /** * contiene la referencia*/ TankWarClient tc; tc) { this.x = x; this.y = y; this.w = w; this.h = h; this.tc = tc } public void draw(Gráficos g) { Color c=g.getColor() ; g.setColor(Color.GRAY); g.fillRect(x,y,w,h); g.setColor(c) /** * Obtener el área rectangular de la pared; público Rectángulo getRect() { return nuevo Rectángulo(x,y,w,h);
Lo anterior es el contenido completo de este artículo, espero que les guste a todos.