bueno aqui les dejare un buen codigo de este juego desarrollado en java con apariencia 2D de disparos niveles y puntaje  en el cual se maneja con el teclado y el click del mouse tanto izquierdo como derecho aqui un pantallaso del juego:

juego 2D java sencillo disparos niveles puntaje


primero todo el juego lo desarrolle dentro de un pakete llamado game_atack  dentro de este pakete habran 6 clases incluyendo la principal una imagen para que se orienten:











luego vamos a crear una clase llamada Controller y colocamos el siguiente codigo:




import java.awt.Desktop;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.logging.Level;
import java.util.logging.Logger;

/*
 * Controller klassen, som har alle objekter i brugerfladen og styrer mus- og keyboard hændelser og main-tråden som kører hele programmet.
*/
public class Controller implements java.awt.event.KeyListener, java.awt.event.MouseListener, java.awt.event.MouseMotionListener{
 //opretter alle variabler der skal bruges
 Window w; //window klassen som bruges til at tegne med
 Player p; //Playeren, som man styrer rundt
 java.util.Vector e; //en vektor til fjenderne. en vektor er et dynamisk array
 java.util.Vector s; //en vektor til skudene
 javax.swing.JFrame f; //reference til vinduet
 java.awt.Point mouse_pos; //point er et objekt med en x og y variabel
 int health; //holder hvor meget liv man har tilbage
 int shaking; //en nedtæller til når skærmen skal ryste
 int level; //variabel til ens level
 int xp; //variabel til xp, som man bruger til at stige i level
 int levelup; //nedtæller til "level up"-animationen
 int score; //variabel til ens score
 int cooldown; //variabel til nedtælling, indtil man kan bruge super-angreb
 int waittime; //variabel til at tælle hvor lang tid siden der er der sidst kom en fjende
 boolean pause; //boolean om spillet er pauset
 //konstruktøreren til klassen, tager en JFrame som argument, som er selve vinduet programmet skal tegnes i.
 Controller(javax.swing.JFrame f){
  mouse_pos = new java.awt.Point(0, 0); //opretter et point til musens positioner og sætter det til position (0, 0)
  w = new Window(this); //opretter en window instans, og giver denne instans som argument for at kunne referere til det
  p = new Player(this); //opretter palyer instansen og giver denne instans som argument
  e = new java.util.Vector(); //Opretter en ny vektor til fjenderne
  s = new java.util.Vector(); //opretter en ny vektor til skudene
  //sætter standartværdier på alle variablerne
  health = 450;
  shaking = 0;
  level = 1;
  xp = 0;
  levelup = 0;
  score = 0;
  cooldown = 0;
  waittime = 0;
  this.f = f; //sætter denne klasse's f variabel til den som blev givet som argument. F er så en reference til selve vinduet.
  this.f.getContentPane().add(w, java.awt.BorderLayout.CENTER); //tilføjer window instansen i midten af JFrame vinduet
  this.f.pack(); //pakker vinduet, gør at det får en optimal størrelse til indholdet
  this.f.addMouseListener(this); //sætter en musselytter i gang til vinduet
  this.f.addMouseMotionListener(this); //sætter en mussebevægelseslytter i gang til vinduet
  this.f.addKeyListener(this); //sætter en tasteturlytter i gang til vinduet
  run(); //starter spillet's løkke
 }
 // spillet's hovedløkke, som kører hele tiden, og sørger for at alting bevæger sig rigtigt. Er void da den ikke returnerer noget.
 void run(){
  while(true){ //kører altid
   //hvis spillet er pauset
   if(pause){
    //tegn skærmen
    w.repaint();
    //vent i 100 millisekunder
    try{
     Thread.sleep(100);
    }catch(Exception e){}
    //starter løkken igen
    continue;
   }
   //hvis cooldown-variablen er større end 0, så sæt den en tak ned
   if(cooldown > 0){
    cooldown--;
   }
   //dette er koden som opretter nye fjender på tilfældige tidspunkter
   //chancen bliver højere med waittime
   if(Math.random() < ((0.002*level*level)/10)+0.0001*waittime && !p.dead){ //hvis der ved en chance skulle oprettes en ny fjende, og at spillet ikke er slut
    e.add(new Enemy(this)); //opret ny fjende og læg den i vektoreren
    //nulstiller waittime
    waittime = 0;
    if(Math.random() < 0.66){ //2/3 chance
     //sæt fjendens position til en tilfældig ude i siderne af skærmen
     e.get(e.size()-1).x = (Math.random() < 0.5? -50: 550);
     e.get(e.size()-1).y = (int)(Math.random()*400);
    }else{ //ellers
     //sæt fjendens position til et tilfældigt sted over skærmen
     e.get(e.size()-1).x = (int)(Math.random()*400);
     e.get(e.size()-1).y = -50;
    }
    e.get(e.size()-1).health = 5*level*level; //sæt fjendens liv i forhold til sværhedsgraden
   }else{
    //hvis der ikke kommer en fjende, sæt waittime en tak op
    waittime++;
   }
   //kører spiller-objektet's hovedløkke, som syrer bl.a. bevægelse
   p.run();
   //kører igennem hele fjende-vektoren
   for(int i = 0; i < e.size(); i++){
    //kører fjenden's hovedlykke
    e.get(i).run();
    //hvis fjenden er blevet skudt
    if(e.get(i).dead){
     //hvis y er over 500 (den er fløjet ud af skærmen)
     if(e.get(i).y > 500){
      //fjern den fra vektoren
      e.remove(i);
      //gå en tilbage i vektoren (da den er blevet forskubbet en plads)
      i--;
     }
    }
   }
   //kører igennem skud-vektoren
   for(int i = 0; i < s.size(); i++){
    //kører hovedløkken for skudet
    s.get(i).run();
    //hvis skudet er fløjet ud for skærmen
    if(s.get(i).x > 500 || s.get(i).y > 500 || s.get(i).x < 0 || s.get(i).y < 0){
     //fjern skuddet
     s.remove(i);
     //gå en tilbage i vektoren
     i--;
    //hvis skuddet stadig er på skærmen, og det er en fjende som har skudt det af sted
    }else if(!s.get(i).friendly){
     //beregn x og y forskellen på skuddet og spilleren
     int xdiff = (p.x+p.cox)-(s.get(i).x);
     int ydiff = (p.y+p.coy)-(s.get(i).y);
     //hvis både x og y forskellen er mindre end 50
     if(Math.abs(xdiff) < 50 && Math.abs(ydiff) < 50){
      //fjern skuddet
      s.remove(i);
      //gå en tilbage i vektoren
      i--;
      //sæt skade nedtælleren til 20 frames
      p.damage = 20;
      //fjerner 25 liv
      health -= 25;
      //sætter ryste effekten til at køre 20 frames
      shaking = 20;
      //hvis man ikke har mere liv tilbage
      if(health <= 0){
       //spillet er slut
       p.dead = true;
       //få spilleren til at lave en hoppeeffekt
       p.vy = -10;
       //sæt horisontalbevægelse til 0
       p.vx = 0;
      }
     }
    //hvis skuddet er på skærmen, og man selv har skudt det af
    }else{
     //kør igennem alle fjende-objekterne
     for(int j = 0; j < e.size(); j++){
      //hvis fjenden ikke er død
      if(!e.get(j).dead){
       //beregn x og y forskellen
       int xdiff = (e.get(j).x+e.get(j).cox)-(s.get(i).x);
       int ydiff = (e.get(j).y+e.get(j).coy)-(s.get(i).y);
       //hvis både x og y forskellen er mindre end 50
       if(Math.abs(xdiff) < 50 && Math.abs(ydiff) < 50){
        //fjern skuddet
        s.remove(i);
        //gå en tilbage i vektoren
        i--;
        //sat skade nedtælleren på fjenden til 20
        e.get(j).damage = 20;
        //fjern 10 af fjendens liv
        e.get(j).health -= 10;
        //hvis fjenden ikke har mere liv tilbage
        if(e.get(j).health <= 0){
         //fjenden er død
         e.get(j).dead = true;
         //sæt den til at lave et lille hop
         e.get(j).vy = -10;
         //tilføj 250 point ganget med hvilket level man er i
         score += 250*level;
         //giv en op i xp
         xp++;
         //hvis man har nok xp til at stige i level
         if(xp > level*6){
          //nulstil xp tælleren
          xp -= level*6;
          //sæt level en op
          level++;
          //sætter "level up"-animationen til at køre 150 frames
          levelup = 150;
          //giver en masse point
          score += 10000*level;
         }
        }
        //stopper med at loope igennem fjender
        break;
       }
      }
     }
    }
   }
   //gentegner skærmen
   w.repaint();
   //venter i 20 millisekunder før løkken kører igen, for at få spillet til ikke at køre for hurtigt og for at computeren skal kunne følge med og køre mere flydene
   try{
    Thread.sleep(20);
   }catch(Exception e){}
  }
 }
 //funktion som bliver kaldt når en tasteturtast bliver sluppet. Implementeret fra KeyListener
 public void keyReleased(java.awt.event.KeyEvent e){
  //hvis man ikke har tabt
  if(!p.dead){
   //hvis man har sluppet A (keycode 65) eller D (keycode 68)
   if(e.getKeyCode() == 65 || e.getKeyCode() == 68){
    //sætter den horisontale hastighed til 0
    p.vx = 0;
   }
  }
 }
 //funktion som bliver kaldt når en tasteturtast bliver trykket ned. Implementeret fra KeyListener
 public void keyPressed(java.awt.event.KeyEvent e){
  //hvis man ikke har tabt
            System.out.println(""+e.getKeyCode());
            System.out.println("keyPressed="+KeyEvent.getKeyText(e.getKeyCode())+"y su numero es"+e.getKeyCode());
  if(!p.dead){
   //hvis man har trykket A
   if(e.getKeyCode() == 65||e.getKeyCode() == 37){
    //sætter horisontalhastigheden til -4 (4 til venstre)
    p.vx = -4;
   //hvis man har trykket D
   }else if(e.getKeyCode() == 68||e.getKeyCode() == 39){
    //sætter horisontalhastigheden til 4 (til højre)
    p.vx = 4;
   //hvis man har trykket mellemrum (keycode 32)
   }else if(e.getKeyCode() == 32||e.getKeyCode() == 38){
    //hvis man står på jorden
    if(p.y == 400-p.h){
     //løfter en 10 op
     p.y -= 10;
     //sætter vertikalhastigheden til -10 (10 opad)
     p.vy = -10;
    }
   //hvis man har trykket på P
   }else if(e.getKeyCode() == 80){
    //hvis spillet er pauset, stop pause, ellers start pause
                            System.out.println("P");
    if(pause){
     pause = false;
    }else{
     pause = true;
    }
   }
  }
 }
 //funktionerne keyTyped, mouseExited, mouseEntered og mouseClicked bruger vi ikke, men skal implementeres alligevel. Kommer fra KeyListener og MouseListener
 public void keyTyped(java.awt.event.KeyEvent e){}
 public void mouseExited(java.awt.event.MouseEvent e){}
 public void mouseEntered(java.awt.event.MouseEvent e){}
 public void mouseClicked(java.awt.event.MouseEvent e){}
 //funktion som bliver kaldt når en musetast bliver sluppet. Implementeret fra MouseListener
 public void mouseReleased(java.awt.event.MouseEvent e){
  //hvis personens y er over 2000 (altså at game over-skærmen er vist)
  if(p.y > 2000){
                    System.out.println("    mayor a 2000");
   //hvis man har klikket på venste musetast
   if(e.getButton() == e.BUTTON1){
                            System.out.println("boton "+e.getButton());
    //hvis musens position er indenfor knappen på game over-skærmen
    if(mouse_pos.x > 150 && mouse_pos.x < 350 && mouse_pos.y > 300 && mouse_pos.y < 350){
                                try {
                                    // System.exit(0);
                                    // System.exit(0);
                                    ventana();
                                } catch (IOException ex) {
                                    Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
                                } catch (URISyntaxException ex) {
                                    Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
                                }
    }
   }
  }
 }
        
         public  void ventana() throws IOException, URISyntaxException{
         Desktop.getDesktop().browse(new URI("http://andres2288.com/compras/juegobala.php"));
    
    }
 //funktion som bliver kaldt når en mustetast bliver trykket ned. Implementeret fra MouseListener
 public void mousePressed(java.awt.event.MouseEvent e){
  //hvis spillet ikke er slt og ikke på pause
  if(!p.dead && !pause){
   //hvis man har klikket på venste musetast
   if(e.getButton() == e.BUTTON1){
    //beregn x og y forskellen fra spilleren til musen's position
    int xdiff = mouse_pos.x-(p.x+p.cox);
    int ydiff = mouse_pos.y-(p.y+p.coy);
    //beregn afstanden fra spilleren til musen
    double length = Math.sqrt(xdiff*xdiff+ydiff*ydiff);
    //opretter et nyt skud, med position på spilleren, som bevæger sig mod musen, og lægger det i skud-vektoren
    s.add(new Shot(p.x+p.cox, p.y+p.coy, (int)(xdiff*(5/length)), (int)(ydiff*(5/length)), true));
   //ellers hvis men har højre-klikket (button2 er klik med scrollhjulet)
   }else if(e.getButton() == e.BUTTON3){
    //hvis der ikke er nedkøling på superangrebet
    if(cooldown == 0){
     //kører igennem 360 grader, og opretter et nyt skud 40 gange på vejen, hvilket giver 40 skud som bevæger sig i hver sin retning
     for(int i = 0; i < 360; i += 360/40){
      s.add(new Shot(p.x+p.cox, p.y+p.coy, (int)(Math.cos(i)*10), (int)(Math.sin(i)*10), true));
     }
     //sætter neddkøling på våbnet. Nedkølingstiden falder jo længere man kommer i spillet
     cooldown = 450-level*15;
    }
   }
  }
 }
 //funktion som bliver faldt når musen bevæges. Implementeret fra MouseMotionListener
 public void mouseMoved(java.awt.event.MouseEvent e){
  //sætter mouse_pos koordinaterne til musens koordinater
  mouse_pos.setLocation(e.getX(), e.getY());
 }
 //funktion som bliver kaldt når musen flyttes, mens en musetast holdes nede. Implementeret fra MouseMotionListener
 public void mouseDragged(java.awt.event.MouseEvent e){
  //sætter mouse_pos koordinaterne til musens koordinater
  mouse_pos.setLocation(e.getX(), e.getY());
 }
}



luego de la clase Controller seguimos con la clase del enemigo o del rival para esto creamos una clase llamada Enemy y colocamos el siguiente codigo:




public class Enemy extends Player{
 //deklarer nødvendige variabler (de fleste er allerede i palyer klassen og behøver ikke også at initialiseres her)
 int health; //liv tilbage
 //konstruktøren med controllerreference som argument
 public Enemy(Controller parent){
  //kalder player klassens konstruktør
  super(parent);
  //sætter gp1 til en anden farve, for at man kan se forskel fra dem og en selv
  gp1 = new java.awt.GradientPaint(x, y, new java.awt.Color(255, 50, 0), x, y+h, new java.awt.Color(150, 50, 0), true);
  //sætter standartværdier
  x = 0;
  y = 0;
  health = 1;
 }
 //overrider target funktionen, da kannonen skal pege på spilleren i stedet for musen
 public int target(int i){
  if(i == 0){
   //returnerer spillerens x-position
   return parent.p.x+parent.p.cox;
  }else{
   //returnerer spillerens y-position
   return parent.p.y+parent.p.coy;
  }
 }
 //kører run funktionen som bliver kørt i hvert frame
 public void run(){
  //hvis død
  if(dead){
   //sæt tyngdekraft og bevæg efter tyndgekraften
   vy += 0.2;
   y += vy;
  //ellers
  }else{
   //hvis spillet er slut
   if(parent.p.dead){
    //stop funktionen
    return;
   }
   //beregner x og y forskellen fra spilleren og fjenden
   int xdiff = (parent.p.x+parent.p.cox)-(x+cox);
   int ydiff = (parent.p.y+parent.p.coy)-(y+coy);
   //hvis fjenden er til højre for spilleren
   if(xdiff > 0){
    //bevæg til venstre
    x += 2;
   //ellers hvis fjenden er til venstre for spilleren
   }else if(xdiff < 0){
    //flyt til højre
    x -= 2;
   }
   //hvis fjenden er over spilleren
   if(ydiff > 0){
    //flyt nedad
    y += 2;
   //ellers hvis fjenden er under spilleren
   }else if(ydiff < 0){
    //flyt opad
    y -= 2;
   }
   //hvis både x og y forskellen er under 50
   if(Math.abs(xdiff) < 50 && Math.abs(ydiff) < 50){
    //mister ét liv
    parent.health--;
    //sætter 10 frames rysteeffekt
    parent.shaking = 10;
    //sætter 10 frames skade effekt
    parent.p.damage = 10;
    //hvis spilleren ikke har mere liv
    if(parent.health <= 0){
     //spillet er slut
     parent.p.dead = true;
     //få spilleren til at lave en hoppeeffekt
     parent.p.vy = -10;
     //sæt horisontalbevægelse til 0
     parent.p.vx = 0;
    }
   }
   //med en chance baseret på level, og hvis spillet ikker slut
   if(Math.random() < ((0.002*parent.level*parent.level)/10)+0.005 && !parent.p.dead){
    //beregn x og y forskellen på fjenden og spilleren
    xdiff = (parent.p.x+parent.p.cox)-(x+cox);
    ydiff = (parent.p.y+parent.p.coy)-(y+coy);
    //beregn afstenden mellem spilleren og fjenden
    double length = Math.sqrt(xdiff*xdiff+ydiff*ydiff);
    //opret et fjendtligt skud på fjendens position med retning mod spilleren.
    parent.s.add(new Shot(x+cox, y+coy, (int)(xdiff*(5/length)), (int)(ydiff*(5/length)), false));
   
                        }
  }
 }
}




luego de esto creamos la clase del jugador para esto creamos una clase llamada Player donde colocaremos el siguiente codigo:



/*
 * Player klassen, spilleren
*/
public class Player{
 //deklarerer nødvendige variabler
 public int x, y, w, h, cox, coy; //position, højde/bredde, kanonens position
 public double vx, vy; //hastighed
 java.awt.GradientPaint gp1; //gradient
 java.awt.geom.Ellipse2D e1, e2, e3; //ellipser
 java.awt.geom.Rectangle2D r1; //rektangel
 java.awt.BasicStroke bs1; //basicstroke
 java.awt.geom.Line2D l1, l2, l3, l4, l5, l6; //linier
 Controller parent; //reference til controlleren
 int damage; //nedtæller når man tager skade
 boolean dead; //om man har tabt
 //konstruktøren med controller referencen
 Player(Controller parent){
  //sætter standartværdier til alle variablerne
  x = 200;
  y = 100;
  w = 75;
  h = 75;
  cox = 30;
  coy = 45;
  damage = 0;
  //sætter referencevariablen
  this.parent = parent;
  //opretter alle tegneobjekterne
  gp1 = new java.awt.GradientPaint(x, y, new java.awt.Color(255, 200, 0), x, y+h, new java.awt.Color(255, 75, 0), true);
  e1 = new java.awt.geom.Ellipse2D.Double(0, 0, w, h);
  e2 = new java.awt.geom.Ellipse2D.Double(0, 0, 20, 30);
  e3 = new java.awt.geom.Ellipse2D.Double(0, 0, 8, 8);
  r1 = new java.awt.geom.Rectangle2D.Double(-25, -10, 75, 25);
  bs1 = new java.awt.BasicStroke(2);
  l1 = new java.awt.geom.Line2D.Double(0, 0, 40, 20);
  l2 = new java.awt.geom.Line2D.Double(0, 20, 40, 0);
  l3 = new java.awt.geom.Line2D.Double(0, 20, 20, 0);
  l4 = new java.awt.geom.Line2D.Double(0, 0, 20, 20);
  l5 = new java.awt.geom.Line2D.Double(20, 20, 40, 0);
  l6 = new java.awt.geom.Line2D.Double(20, 0, 40, 20);
 }
 //funktion som returnerer koordinater til det punkt kanonen skal pege på
 public int target(int i){
  //hvis i er lig 0
  if(i == 0){
   //returner musens x, da kanonen skal peje mod musen
   return parent.mouse_pos.x;
  //ellers
  }else{
   //returner musens y
   return parent.mouse_pos.y;
  }
 }
 //paint funktionen, tegner spilleren
 public void paint(java.awt.Graphics2D g){
  //opretter lokale variabler til positionsvariablerne, da disse kan blive ændret imens funktionen kører
  int tx = x, ty = y, tcox = cox, tcoy = coy;
  //sæt tegneudgangspunkt til spillerens position
  g.translate(tx, ty);
   //tegner med gradient gp1
   g.setPaint(gp1);
   //tegner e1 udfyldt
   g.fill(e1);
   //sætter steg til bs1
   g.setStroke(bs1);
   //sætter farve til sort
   g.setPaint(java.awt.Color.BLACK);
   //tegner kanten til e1;
   g.draw(e1);
   //flytter tegneudgangspunket lidt ind
   g.translate(17, 10);
    //hvis spilleren er død
    if(dead){
     //tegn strejerne l3, l4, l5 og l6
     g.draw(l3);
     g.draw(l4);
     g.draw(l5);
     g.draw(l6);
    //ellers hvis skadenedtælleren er i gang
    }else if(damage > 0){
     //sæt den til én mindre
     damage--;
     //tegn stregerne l1 og l2
     g.draw(l1);
     g.draw(l2);
    //ellers
    }else{
     //tegn med hvidt
     g.setPaint(java.awt.Color.WHITE);
     //tegner e2 udfyldt
     g.fill(e2);
     //sætter farven til sort
     g.setPaint(java.awt.Color.BLACK);
     //tegn kanten til e2
     g.draw(e2);
     //flyt tegneudgangspunktet lidt ind
     g.translate(6, 10);
      //tegn e3 udfyldt
      g.fill(e3);
     //flyt tegneudgangspunktet tilbage
     g.translate(-6, -10);
     //flyt tegneudgangspunket ind (til næste øje)
     g.translate(22, 0);
      //sæt farven til hvid
      g.setPaint(java.awt.Color.WHITE);
      //tegn e2 udfyldt
      g.fill(e2);
      //sæt farven til sort
      g.setPaint(java.awt.Color.BLACK);
      //tegn kanten til e2
      g.draw(e2);
      //flyt tegneudgangspunktet lidt ind
      g.translate(6, 10);
       //tegn e3 udfyldt
       g.fill(e3);
      //flyt tegneudgangspunktet tilbage
      g.translate(-6, -10);
     //flyt tegneudgangspunktet tilbage
     g.translate(-22, 0);
    }
   //flyt tegneudgangspunktet tilbage
   g.translate(-17, -10);
   //flyt tegneudgangspunktet til kannonens position
   g.translate(tcox, tcoy);
    //beregn x og y forskellen mellem positionen kannonen pejer mod og kannonens position
    double xdiff = target(0)-(tx+tcox);
    double ydiff = target(1)-(ty+tcoy);
    //hvis y forskellen ikke er lig 0 (hvilket ville dividere med 0)
    if(ydiff != 0){
     //rotér så kanonnen pejer mod målet
     g.rotate(Math.atan(ydiff/xdiff));
     //hvis den pejer mod venstre
     if(xdiff < 0){
      //roter 180 grader mere (180 grader = PI radianer)
      g.rotate(Math.PI);
     }
    }
    //sæt farven til grå
    g.setPaint(java.awt.Color.GRAY);
    //tegn r1 udfyldt
    g.fill(r1);
    //sæt farven til sort
    g.setPaint(java.awt.Color.BLACK);
    //tegn kanten til r1
    g.draw(r1);
    //gentag rotationen, bare omvendt, for at rotere alt andet tilbage
    if(ydiff != 0){
     g.rotate(-Math.atan(ydiff/xdiff));
     if(xdiff < 0){
      g.rotate(-Math.PI);
     }
    }
   //flyt tegneudgangspunktet tilbage
   g.translate(-tcox, -tcoy);
  //flyt tegneudgangspunktet tilbage
  g.translate(-tx, -ty);
 }
 //run funktionen, bliver kaldet hvert frame
 public void run(){
  //hvis men har tabt
  if(dead){
   //fald nedad
   vy += 0.2;
  //ellers
  }else{
   //hvis man er i luften
   if(y+h < 400){
    //sæt tyngekraft til
    vy += 0.2;
   //ellers
   }else if(y+h > 400){
    //sæt tyngdekraften til 0
    vy = 0;
    //fastsæt positionen
    y = 400-h;
   }
  }
  //bevæg spilleren
  x += Math.ceil(vx);
  y += Math.ceil(vy);
  //hvis man er gået ud for vinduet
  if(x > 500-h){
   //sæt en tilbage
   x = 500-h;
  //og det samme for den anden side af vinduet
  }else if(x < 0){
   x = 0;
  }
 }
}



luego seguimos con la clase Shot donde colocaremos el siguiente codigo:




/*
 * Shot klassen, som er skuddene, både ens egne og fjendens
*/
public class Shot{
 //deklarerer nødvendige variabler
 public int x, y; //position
 double vx, vy; //hastighed
 boolean friendly; //om man selv har skudt den af eller ej
 java.awt.geom.Ellipse2D e; //en ellipse til at tegne den med
 //konstruktøren
 public Shot(int x, int y, int vx, int vy, boolean friendly){
  //sætter variablerne, som er givet som argumenter
  this.x = x;
  this.y = y;
  this.vx = vx;
  this.vy = vy;
  this.friendly = friendly;
  //opretter ellipseobjektet
  e = new java.awt.geom.Ellipse2D.Double(-8, -8, 16, 16);
 }
 //tegnefunktionen, tegner skuddet
 public void paint(java.awt.Graphics2D g){
  //sætter tegneudgangspunktet til x og y posiionen
  g.translate(x, y);
   //hvis det er ens eget skud
   if(friendly){
    //sæt farven til gul
    g.setPaint(java.awt.Color.YELLOW);
   //ellers
   }else{
    //sæt farven til orange
    g.setPaint(java.awt.Color.ORANGE);
   }
   //tegner skuddet udfyldt
   g.fill(e);
  //nulstiller tegneudgangspunktet
  g.translate(-x, -y);
 }
 //run funktionen, bliver kaldt i hvert frame
 public void run(){
  //flytter skuddet i forhold til hastigheden
  x += vx;
  y += vy;
 }
}


leugo creamos la clase Window donde mostrara toda la interfaz de la ventana del juego colocamos el siguiente codigo:


/*
 * Window klassen, som extender JPanel, er den som tegner spillet
*/
public class Window extends javax.swing.JPanel{
 //initialiserer alle nødvendige variabler
Controller parent; //reference til controlleren
 java.awt.GradientPaint gp1, gp2; //to gradiente farver
 java.awt.geom.Rectangle2D r1, r2, r3, r4; //fire rektangler
 java.awt.BasicStroke bs1; //et basicstroke objekt
 java.awt.geom.Line2D s1, s2; //to linier
 java.awt.Font f1, f2; //to skrifttyper
 java.awt.geom.RoundRectangle2D rr1, rr2; //to afrundede rektangler
 //konstruktøren, som tager en reference til controlleren som argument
 public Window(Controller c){
  //sætter parent til referencen
  parent = c;
  //sætter fortrukne størrelse på panelet, som bliver dens størrelse når vinduet pakkes
  setPreferredSize(new java.awt.Dimension(500, 500));
  //himlens farve
  gp1 = new java.awt.GradientPaint(0, 0, new java.awt.Color(50, 200, 255), 0, 400, java.awt.Color.BLUE);
  //jordens farve
  gp2 = new java.awt.GradientPaint(0, 100, new java.awt.Color(150, 255, 150), 0, 500, new java.awt.Color(50, 200, 50));
  //himlens figur
  r1 = new java.awt.geom.Rectangle2D.Double(0, 0, 500, 400);
  //jordens figur
  r2 = new java.awt.geom.Rectangle2D.Double(0, 400, 500, 100);
  //helbredsmåler
  r3 = new java.awt.geom.Rectangle2D.Double(0, 0, 450, 50);
  //cooldownmåler
  r4 = new java.awt.geom.Rectangle2D.Double(0, 0, 450, 5);
  //cursors streg
  bs1 = new java.awt.BasicStroke(1);
  //cursors figur
  s1 = new java.awt.geom.Line2D.Double(-16, 0, 16, 0);
  s2 = new java.awt.geom.Line2D.Double(0, -16, 0, 16);
  //skriftyper
  f1 = new java.awt.Font("Arial", 0, 40);
  f2 = new java.awt.Font("Arial", 0, 20);
  //vindue efter spillet
  rr1 = new java.awt.geom.RoundRectangle2D.Double(100, 100, 300, 300, 10, 10);
  rr2 = new java.awt.geom.RoundRectangle2D.Double(150, 300, 200, 50, 10, 10);
 }
 //paint funktionen bliver kaldt når vinduet skal gentegnes. Ved at tegne alting i update funktionen og kalde den fra paint får man en meget nem og simpel form for souble buffering
 public void paint(java.awt.Graphics g){
  update(g);
 }
 //update funktionen, tegner alting
 public void update(java.awt.Graphics g2){
  //opretter et graphics2d objekt ud fra det normale graphics objekt
  java.awt.Graphics2D g = (java.awt.Graphics2D) g2;
  //sætter graphics objektet til at tegne alting med anti-aliasing
  g.setRenderingHint(java.awt.RenderingHints.KEY_ANTIALIASING, java.awt.RenderingHints.VALUE_ANTIALIAS_ON);
  //hvis rysteeffekt er i gang
  if(parent.shaking > 0){
   //sæt tælleren en tak ned
   parent.shaking--;
   //flyt hele billedet som tegnes lidt i en tilfælfig retning
   g.translate(Math.random()*5, Math.random()*5);
  }
  //sætter g til at tegne med gradient1 objektet
  g.setPaint(gp1);
  //tegner himlen udfyldt
  g.fill(r1);
  //sætter g til at tegne med gradient2 objektet
  g.setPaint(gp2);
  //tegner jorden udfyldt
  g.fill(r2);
  //kører igennem alle fjenderne
  for(int i = 0; i < parent.e.size(); i++){
   //tegner fjenden
   parent.e.get(i).paint(g);
  }
  //tegner spilleren
  parent.p.paint(g);
  //kører igennem alle skuddene
  for(int i = 0; i < parent.s.size(); i++){
   //tegner skuddet
   parent.s.get(i).paint(g);
  }
  //hvis spillet ikke er slut
  if(!parent.p.dead){
   //tegner alting relativt til punkt (25, 25)
   g.translate(25, 25);
    //sætter r3's længde til det antal liv man har tilbage
    r3.setRect(0, 0, parent.health, 25);
    //hvis man har mere end 225 liv tilbage
    if(parent.health > 225){
     //tegn grønt
     g.setPaint(java.awt.Color.GREEN);
    //ellers hvis man har mere end 100 liv tilbage
    }else if(parent.health > 100){
     //tegn gult
     g.setPaint(java.awt.Color.YELLOW);
    //ellers
    }else{
     //tegn rødt
     g.setPaint(java.awt.Color.RED);
    }
    //tegn r3 udfyldt
    g.fill(r3);
    //tegner med sort
    g.setPaint(java.awt.Color.BLACK);
    //tegn kanten til r3
    g.draw(r3);
    //hvis der er nedkøling på supervåbnet
    if(parent.cooldown > 0){
     //tegn 25 pixels længere nede
     g.translate(0, 25);
      //tegn med rødt
      g.setPaint(java.awt.Color.RED);
      //sætter r4's længde til at passe med nedkøling tilbage
      r4.setRect(0, 0, parent.cooldown, 5);
      //tegn r4 udfyldt
      g.fill(r4);
      //tegn med sort
      g.setPaint(java.awt.Color.BLACK);
      //tegn kanten til r4
      g.draw(r4);
     //sæt tegneudgangspunktet tilbage
     g.translate(0, -25);
    }
    //tegn relativt til midten af liv-måleren
    g.translate(225, 33);
     //sæt skrifttypen til f2
     g.setFont(f2);
     //opret et fontmetrics objekt til f2
     java.awt.FontMetrics fm = g.getFontMetrics();
     //tegn en streng med score og level midt på liv-måleren
     g.drawString("Score: "+parent.score+"   Level: "+parent.level, -fm.stringWidth("Score: "+parent.score+" : Level: "+parent.level)/2, -fm.getHeight()/2);
    //sæt tegneudgangspunkt tilbage
    g.translate(-225, -37);
   //sæt tegneudgangspunkt tilbage
   g.translate(-25, -25);
  }
  //hvis levelup nedtælleren er i gang
  if(parent.levelup > 0){
   //få en tilfældig værdi for rotation af teksten
   double rot = (Math.random()-0.5)/3;
   //hvis der er mindre end 50 frames tilbage af animationen
   if(parent.levelup < 50){
    //sæt positionen så at teksten i animationen kører op
    g.translate(250, 250-(-parent.levelup+50)*5);
   }else{
    //sæt tegneudgangspunktet midt på skærmen
    g.translate(250, 250);
   }
   //sæt skrifttypen til f1
   g.setFont(f1);
   //opret et fontmetrics objekt til f1
   java.awt.FontMetrics fm = g.getFontMetrics();
   //rotér rot grader
   g.rotate(rot);
    //skriv "LEVEL UP" midt på skærmen
    g.drawString("LEVEL UP", -fm.stringWidth("LEVEL UP")/2, -fm.getHeight());
   //rotér tilbage
   g.rotate(-rot);
   //sætter tegneudgangspunktet tilbage
   if(parent.levelup < 50){
    g.translate(-250, -(250-(-parent.levelup+50)*5));
   }else{
    g.translate(-250, -250);
   }
   //går en frame videre i animationen
   parent.levelup--;
  }
  //hvis spillet er helt slut og slutskærmen skal vises (når spillerens position er mere end 2000)
  if(parent.p.y > 2000){
   //sæt bevægelseshastigheden i y til 0
   parent.p.vy = 0;
   //sæt positionen til mere end 2000
   parent.p.y = 2001;
   //tegn hvidt
   g.setPaint(java.awt.Color.WHITE);
   //tegn rr1 fyldt
   g.fill(rr1);
   //tegn med sort
   g.setPaint(java.awt.Color.BLACK);
   //tegn kanten til rr1
   g.draw(rr1);
   //sætter skrifttypen til f1
   g.setFont(f1);
   //opretter et fontmetrics objekt
   java.awt.FontMetrics fm = g.getFontMetrics();
   //tegner strengen "GAME OVER!"
   g.drawString("GAME OVER!", 250-fm.stringWidth("GAME OVER!")/2, 175-fm.getHeight()/2);
   //tenger ens score
   g.drawString(""+parent.score, 250-fm.stringWidth(""+parent.score)/2, 275-fm.getHeight()/2);
   //sætter skrifttypen til f2
   g.setFont(f2);
   //ændrer fm til at tælle for den nye skrifttype
   fm = g.getFontMetrics();
   //tegner strengen "Final Score:"
   g.drawString("Final Score:", 250-fm.stringWidth("final Score:")/2, 220-fm.getHeight()/2);
   //tegner strengen "Quit" som står på knappen
   g.drawString("Comprar Con Paypal", 250-fm.stringWidth("Quit")/2-75, 345-fm.getHeight()/2);
   //tegner kanten til rr2
   g.draw(rr2);
  }
  //hvis spillet er på pause
  if(parent.pause){
   //sæt farven til hvid
   g.setPaint(java.awt.Color.WHITE);
   //tegner rr2 udfyldt
   g.fill(rr2);
   //sætter farven til sort
   g.setPaint(java.awt.Color.BLACK);
   //tegner kanten på rr2
   g.draw(rr2);
   //sætter skrifttypen til f2
   g.setFont(f2);
   //laver et fontmetricsobjekt
   java.awt.FontMetrics fm = g.getFontMetrics();
   //skriver "pause" på skærmen
   g.drawString("Pause", 250-fm.stringWidth("Pause")/2, 345-fm.getHeight()/2);
  }
  //sætter tegneudgangspunktet til musens position
  g.translate(parent.mouse_pos.x, parent.mouse_pos.y);
  //sætter stregtype til bs1
  g.setStroke(bs1);
  //sætter farven til sort
  g.setPaint(java.awt.Color.BLACK);
  //tegner de to linier til cursoren
  g.draw(s1);
  g.draw(s2);
 }
}



luego por ultimo la clase Main donde colocamos el siguiente codigo:





/*
 * Main klassen, holder main metoden som bliver kaldt når programmet starter
 */
public class Main{
    public static void main(String[] args){
        
        
       
  //opretter en ny JFrame, til vinduet, og giver det titlen "Java spil"
  javax.swing.JFrame f = new javax.swing.JFrame("http://javayotros.blogspot.com/");
  //sætter vinduet til at kunne ses
  f.setVisible(true);
  //gør at programmet afslutter når vinduet lukkes
  f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
  //sætter at vinduet ikke kan ændre størrelse
  f.setResizable(false);
  /* transperant cursor script fra http://www.izyt.com/freode/viewcode.php?code=43 */
  int[] pixels = new int[16 * 16];
  java.awt.Image image = java.awt.Toolkit.getDefaultToolkit().createImage(new java.awt.image.MemoryImageSource(16, 16, pixels, 0, 16));
  java.awt.Cursor transparentCursor = java.awt.Toolkit.getDefaultToolkit().createCustomCursor(image, new java.awt.Point(0, 0), "invisiblecursor");
  f.setCursor(transparentCursor);
  /* end of script */
  //sætter layout til borderlayout
  f.getContentPane().setLayout(new java.awt.BorderLayout());
  //sætter vinduet til hele tiden at være over andre vinduer
  f.setAlwaysOnTop(true);
  //opretter en ny controller instans med vores frame som argument
  new Controller(f);
    }
}


ya eso es todo ejecutamos el main y a jugar :) comparta esta entrada por favor ;)