elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Únete al Grupo Steam elhacker.NET


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  Java
| | | |-+  Consulta sobre Timer y Garbage Collector
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Consulta sobre Timer y Garbage Collector  (Leído 2,085 veces)
zonahurbana

Desconectado Desconectado

Mensajes: 178

RS, JC.


Ver Perfil WWW
Consulta sobre Timer y Garbage Collector
« en: 2 Agosto 2013, 23:53 pm »

Bueno, la verdad es que hasta antes sólo he creado programas pequeños en C++ en consola y algunos otros con interfaz en Windows Forms (Visual Studio 2010).

Como me enteré que en el ciclo entrante llevaré Java pues me he puesto a practicar un poco.
No conozco con exactitud cómo funcionan las clases en Java y tampoco las funciones de las bibliotecas que más suelen usarse... pero apoyado de las advertencias que me daba Netbeans he ido puliendo lo que vendría a ser un juego de la "Snake". Y también basándome un poco en lo que se describe en algunas páginas de referencia.

He conseguido que el programa funcione, es decir, usando las flechas puedo cambiar el sentido de la snake, y esta se desplaza a donde le indique.
Cuando consume un "plus" aumenta su tamaño y reproduce un pequeño sonido (lo mismo hace cuando se estrella contra sí misma). Tiene un sonido de fondo en todo momento, también ...

El .jar puede descargarse de acá:
http://www.mediafire.com/download/e1jvhvph3fa4d38/Snake.jar

Y el código lo copiaré todo a continuación. De seguro se verá un tanto amontonado, porque también incluyo el código generado por el Netbeans cuando se crea un proyecto de Java nuevo y se le agrega un JFrame (y el código que se ha generado mientras yo hacía modificaciones en vista de diseño):
Código
  1. package SnakePackage;
  2.  
  3. import java.applet.AudioClip;
  4. import java.awt.event.ActionEvent; // Complemento para ActionListener.
  5. import java.awt.event.ActionListener; // Para agrupar acciones a desarrollarse.
  6. import java.awt.event.KeyEvent; // Para controlar las pulsaciones del teclado.
  7. import java.util.ArrayList; // Para crear un arreglo dinámico.
  8. import javax.swing.ButtonGroup;
  9. import javax.swing.ImageIcon; // Para añadir imágenes a los JLabel.
  10. import javax.swing.JLabel;
  11. import javax.swing.JOptionPane; // Para mostrar un cuadro de diálogo.
  12. import javax.swing.Timer; // Para controlar el tiempo de desplazamiento.
  13.  
  14. /**
  15.  * @author JCarlos
  16.  */
  17. public class MyMain extends javax.swing.JFrame {
  18.  
  19.    /**
  20.      * Creates new form MyMain
  21.      */
  22.    public MyMain() {
  23.        this.Sonido_Eat = java.applet.Applet.newAudioClip( getClass().getResource("/SnakePackage/sound/eat.wav") );
  24.        this.Sonido_Fondo = java.applet.Applet.newAudioClip( getClass().getResource("/SnakePackage/sound/music.wav") );
  25.        this.Sonido_Impacto = java.applet.Applet.newAudioClip( getClass().getResource("/SnakePackage/sound/choque.wav") );
  26.        initComponents();
  27.    }
  28.  
  29.    /**
  30.      * This method is called from within the constructor to initialize the form.
  31.      * WARNING: Do NOT modify this code. The content of this method is always
  32.      * regenerated by the Form Editor.
  33.      */
  34.    @SuppressWarnings("unchecked")
  35.    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
  36.    private void initComponents() {
  37.  
  38.        opt1 = new javax.swing.JRadioButton();
  39.        opt2 = new javax.swing.JRadioButton();
  40.        opt3 = new javax.swing.JRadioButton();
  41.  
  42.        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
  43.        setTitle("Snake - By JCRS");
  44.        setMaximumSize(new java.awt.Dimension(350, 280));
  45.        setMinimumSize(new java.awt.Dimension(350, 280));
  46.        setName("MarcoPrincipal"); // NOI18N
  47.        setResizable(false);
  48.        addWindowListener(new java.awt.event.WindowAdapter() {
  49.            public void windowOpened(java.awt.event.WindowEvent evt) {
  50.                formWindowOpened(evt);
  51.            }
  52.        });
  53.        addKeyListener(new java.awt.event.KeyAdapter() {
  54.            public void keyPressed(java.awt.event.KeyEvent evt) {
  55.                formKeyPressed(evt);
  56.            }
  57.        });
  58.  
  59.        opt1.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
  60.        opt1.addActionListener(new java.awt.event.ActionListener() {
  61.            public void actionPerformed(java.awt.event.ActionEvent evt) {
  62.                opt1ActionPerformed(evt);
  63.            }
  64.        });
  65.  
  66.        opt2.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
  67.        opt2.addActionListener(new java.awt.event.ActionListener() {
  68.            public void actionPerformed(java.awt.event.ActionEvent evt) {
  69.                opt2ActionPerformed(evt);
  70.            }
  71.        });
  72.  
  73.        opt3.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
  74.        opt3.addActionListener(new java.awt.event.ActionListener() {
  75.            public void actionPerformed(java.awt.event.ActionEvent evt) {
  76.                opt3ActionPerformed(evt);
  77.            }
  78.        });
  79.  
  80.        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
  81.        getContentPane().setLayout(layout);
  82.        layout.setHorizontalGroup(
  83.            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
  84.            .addGroup(layout.createSequentialGroup()
  85.                .addGap(18, 18, 18)
  86.                .addComponent(opt1)
  87.                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 104, Short.MAX_VALUE)
  88.                .addComponent(opt2)
  89.                .addGap(92, 92, 92)
  90.                .addComponent(opt3)
  91.                .addGap(73, 73, 73))
  92.        );
  93.        layout.setVerticalGroup(
  94.            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
  95.            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
  96.                .addContainerGap(244, Short.MAX_VALUE)
  97.                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
  98.                    .addComponent(opt3)
  99.                    .addComponent(opt2)
  100.                    .addComponent(opt1))
  101.                .addGap(15, 15, 15))
  102.        );
  103.  
  104.        pack();
  105.    }// </editor-fold>                        
  106.  
  107. {   @Override
  108.    public void actionPerformed(ActionEvent e)
  109.    {
  110.        Body.setLocation(Body.getX()-10, Body.getY());
  111.        ActualizarPosiciones();
  112.        VerificarColision();            
  113.        if(Body.getX()==-10) Body.setLocation(340, Body.getY());
  114.    }
  115. };
  116.  
  117. {   @Override
  118.    public void actionPerformed(ActionEvent e)
  119.    {
  120.        Body.setLocation(Body.getX()+10, Body.getY());
  121.        ActualizarPosiciones();
  122.        VerificarColision();
  123.        if(Body.getX()==350) Body.setLocation(0, Body.getY());
  124.    }
  125. };
  126.  
  127. {   @Override
  128.    public void actionPerformed(ActionEvent e)
  129.    {
  130.        Body.setLocation(Body.getX(), Body.getY()+10);
  131.        ActualizarPosiciones();
  132.        VerificarColision();
  133.        if(Body.getY()==280) Body.setLocation(Body.getX(), 0);
  134.    }
  135. };
  136.  
  137. {   @Override
  138.    public void actionPerformed(ActionEvent e)
  139.    {
  140.        Body.setLocation(Body.getX(), Body.getY()-10);
  141.        ActualizarPosiciones();
  142.        VerificarColision();
  143.        if(Body.getY()==-10) Body.setLocation(Body.getX(), 270);
  144.    }
  145. };
  146.  
  147. void ActualizarPosiciones()
  148. {
  149.    for(int x=Bloques.size()-1; x>0; --x)
  150.        Bloques.get(x).setLocation(Bloques.get(x-1).getLocation());
  151.    if(Bloques.size()>0)
  152.        Bloques.get(0).setLocation( Body.getLocation() );
  153.    repaint();
  154. }
  155.  
  156. // ¡Sonidos! Sus direcciones están en el constructor arriba.
  157. AudioClip Sonido_Fondo, Sonido_Eat, Sonido_Impacto;
  158.  
  159. void VerificarColision()
  160. {
  161.    if(Body.getX() == Plus.getX() && Body.getY() == Plus.getY())
  162.    {
  163.        Sonido_Eat.play();
  164.        JOptionPane.showMessageDialog(new MyMain(), "Ahora el tamaño de la serpiente aumentará, ¡ten cuidado!", "Has conseguido comer un plus.", JOptionPane.INFORMATION_MESSAGE);
  165.        randomizar(Plus);
  166.        CrecerSnake();
  167.    }
  168.  
  169.    for(int i=0; i<Bloques.size()-1; ++i)
  170.        for(int j=i+1; j<Bloques.size(); ++j)
  171.            if(Bloques.get(i).getX()==Bloques.get(j).getX() && Bloques.get(i).getY()==Bloques.get(j).getY())
  172.            {
  173.                Sonido_Impacto.play();
  174.                Perdiste();
  175.            }
  176. }  
  177.  
  178. void Perdiste()
  179. {
  180.    JOptionPane.showMessageDialog(new MyMain(), "¡Lo siento mucho! Has perdido.\n\tPuntuación: "+Bloques.size(), "Game Over.", JOptionPane.INFORMATION_MESSAGE);
  181.    // randomizar(Plus);
  182.    Temporizador.stop();
  183.    for(int i=0; i<Bloques.size(); ++i)
  184.        this.getContentPane().remove(Bloques.get(i));
  185.    Bloques.clear();
  186.    this.getContentPane().remove( Body );
  187.    this.getContentPane().remove( Plus );
  188.    Menu.setVisible(true);
  189.    opt1.setVisible(true);
  190.    opt2.setVisible(true);
  191.    opt3.setVisible(true);
  192.  
  193. }
  194.  
  195.        ArrayList<JLabel> Bloques = new ArrayList<>(); // Creamos el arreglo vacío.
  196.  
  197. void CrecerSnake()
  198. {
  199.    JLabel Nuevo = new JLabel( new ImageIcon(getClass().getResource("/SnakePackage/imgs/body.gif")) );
  200.    //Nuevo.setLocation(0, 0);
  201.    Nuevo.setSize(10, 10);
  202.    Bloques.add( Nuevo );
  203.    this.getContentPane().add( Bloques.get( Bloques.size()-1 ) );        
  204. }
  205.  
  206. Timer Temporizador = new Timer(1000, null); // int delay, ActionListener listener
  207.  
  208.    private void formKeyPressed(java.awt.event.KeyEvent evt) {                                
  209.        if(
  210.             (evt.getKeyCode() == KeyEvent.VK_LEFT
  211.             || evt.getKeyCode() == KeyEvent.VK_RIGHT
  212.             || evt.getKeyCode() == KeyEvent.VK_DOWN
  213.             || evt.getKeyCode() == KeyEvent.VK_UP
  214.             || evt.getKeyCode() == KeyEvent.VK_V)
  215.             && Temporizador.getActionListeners().length > 0
  216.           )
  217.            Temporizador.removeActionListener(Temporizador.getActionListeners()[0]);
  218.        if(evt.getKeyCode() == KeyEvent.VK_LEFT)
  219.        {
  220.            Temporizador.addActionListener(MoverIzq);
  221.            //JOptionPane.showMessageDialog(this, "Has presionado la tecla con una flecha hacia la izquierda.", "Tecla presionada.", JOptionPane.INFORMATION_MESSAGE);
  222.        }
  223.        if(evt.getKeyCode() == KeyEvent.VK_RIGHT)
  224.        {
  225.            Temporizador.addActionListener(MoverDer);
  226.        }
  227.        if(evt.getKeyCode() == KeyEvent.VK_DOWN)
  228.        {
  229.            Temporizador.addActionListener(MoverAba);
  230.        }
  231.        if(evt.getKeyCode() == KeyEvent.VK_UP)
  232.        {
  233.            Temporizador.addActionListener(MoverArr);
  234.        }
  235.        if(evt.getKeyCode() == KeyEvent.VK_V)
  236.        { // Muestra las posiciones.
  237.            JOptionPane.showMessageDialog(new MyMain(), "Posición de Body: "+Body.getX()+", "+Body.getY()+"\nPosición de Plus: "+Plus.getX()+", "+Plus.getY(), "Game Over.", JOptionPane.CLOSED_OPTION);
  238.        }
  239.    }                              
  240.  
  241. int XAleatorio()
  242. {
  243.    return (int)(Math.random() * (34 + 1))*10;
  244. }
  245. int YAleatorio()
  246. {
  247.    return (int)(Math.random() * (27 + 1))*10;
  248. }
  249.  
  250. void randomizar(JLabel L)
  251. {
  252.    L.setLocation(XAleatorio(), YAleatorio());
  253. }
  254.  
  255.    JLabel Body = new JLabel( new ImageIcon(getClass().getResource("/SnakePackage/imgs/body.gif")) );
  256.    JLabel Plus = new JLabel( new ImageIcon(getClass().getResource("/SnakePackage/imgs/plus.png")) );
  257.  
  258.    void EmpezarJuego(int velocidad)
  259.    {    
  260.        // Limpiamos componentes del menú.
  261.        Menu.setVisible(false);
  262.        opt1.setVisible(false);
  263.        opt2.setVisible(false);
  264.        opt3.setVisible(false);
  265.  
  266.        Temporizador.setDelay(velocidad);
  267.        Temporizador.start();
  268.  
  269.        Body.setSize(10, 10); Plus.setSize(10, 10);
  270.  
  271.        this.getContentPane().add( Body );
  272.        this.getContentPane().add( Plus );
  273.  
  274.        randomizar(Body);
  275.        randomizar(Plus);
  276.    }
  277.  
  278.    JLabel Menu = new JLabel( new ImageIcon(getClass().getResource("/SnakePackage/imgs/Start.jpg")) );
  279.  
  280.    private void formWindowOpened(java.awt.event.WindowEvent evt) {                                  
  281.        Sonido_Fondo.loop();
  282.  
  283.        Menu.setSize(350, 280);
  284.        this.getContentPane().add(Menu);
  285.        Menu.setLocation(0, 0); repaint();
  286.  
  287.        ButtonGroup grupoBotonesOpcion = new ButtonGroup();
  288.        grupoBotonesOpcion.add( opt1 );
  289.        grupoBotonesOpcion.add( opt2 );
  290.        grupoBotonesOpcion.add( opt3 );
  291.    }                                
  292.  
  293.    private void opt1ActionPerformed(java.awt.event.ActionEvent evt) {                                    
  294.        if( JOptionPane.showConfirmDialog(null, "¿Desea jugar en modo fácil?", "Confirme su petición.", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.YES_OPTION)
  295.        {
  296.            EmpezarJuego(120);
  297.        }
  298.    }                                    
  299.  
  300.    private void opt2ActionPerformed(java.awt.event.ActionEvent evt) {                                    
  301.        if( JOptionPane.showConfirmDialog(null, "¿Desea jugar en modo medio dificultoso?", "Confirme su petición.", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.YES_OPTION)
  302.        {
  303.            EmpezarJuego(80);
  304.        }
  305.    }                                    
  306.  
  307.    private void opt3ActionPerformed(java.awt.event.ActionEvent evt) {                                    
  308.        if( JOptionPane.showConfirmDialog(null, "¿Desea jugar en modo difícil?", "Confirme su petición.", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.YES_OPTION)
  309.        {
  310.            EmpezarJuego(60);
  311.        }        // TODO add your handling code here:
  312.    }                                    
  313.  
  314.    /**
  315.      * @param args the command line arguments
  316.      */
  317.    public static void main(String args[]) {
  318.        /* Set the Nimbus look and feel */
  319.        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
  320.        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
  321.          * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
  322.          */
  323.        try {
  324.            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
  325.                if ("Nimbus".equals(info.getName())) {
  326.                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
  327.                    break;
  328.                }
  329.            }
  330.        } catch (ClassNotFoundException ex) {
  331.            java.util.logging.Logger.getLogger(MyMain.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
  332.        } catch (InstantiationException ex) {
  333.            java.util.logging.Logger.getLogger(MyMain.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
  334.        } catch (IllegalAccessException ex) {
  335.            java.util.logging.Logger.getLogger(MyMain.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
  336.        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
  337.            java.util.logging.Logger.getLogger(MyMain.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
  338.        }
  339.        //</editor-fold>
  340.  
  341.        /* Create and display the form */
  342.        java.awt.EventQueue.invokeLater(new Runnable() {
  343.            public void run() {
  344.                new MyMain().setVisible(true);
  345.            }
  346.        });
  347.    }
  348.    // Variables declaration - do not modify                    
  349.    private javax.swing.JRadioButton opt1;
  350.    private javax.swing.JRadioButton opt2;
  351.    private javax.swing.JRadioButton opt3;
  352.    // End of variables declaration                  
  353. }

¿Cuál es el problema?
Bueno quisiera que me ayuden a entender las razones de por qué el programa se detiene repentinamente luego que se han consumido unas 12-14 veces el plus (la canción de fondo sigue reproduciéndose pero la Snake no obedece, es decir, no se desplaza por más que presione las flechas del teclado).
En el título he puesto Garbage Collector porque no se me ocurría otra cosa que pudiera detener el funcionamiento... pero la verdad es que tampoco estoy muy seguro de esto, pues C++ no tiene un recolector de basura por defecto. ¿Será que el recolector termina por borrar el Timer y por ello ya no ejecuta las acciones? Porque el programa no es que se haya "colgado", sino que las acciones de desplazamiento es como si hubiera dejado de existir.

Gracias y espero puedan orientarme un poco.


« Última modificación: 5 Agosto 2013, 14:57 pm por zonahurbana » En línea

Nunca dejar de aprender es importante, más allá del ritmo que se siga ...
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
duda sobre Timer
Programación Visual Basic
fraktal 6 1,859 Último mensaje 13 Noviembre 2006, 19:33 pm
por Pitoniso
AYUDA!! Sobre un programa de numeros Random y Timer ??
Programación Visual Basic
Laura_12 1 1,662 Último mensaje 4 Junio 2007, 23:26 pm
por Jareth
Metasploit email collector
Hacking
Bhior 1 2,858 Último mensaje 29 Mayo 2010, 23:06 pm
por Søra
Tengo una duda con la recolección de basura (Garbage Collector)
Java
DarkSorcerer 2 2,006 Último mensaje 20 Enero 2013, 19:40 pm
por Gallu
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines