Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 7 of 7

Thread: Simple Game Physics & Animation (Air Hockey)

  1. #1
    Junior Member
    Join Date
    Oct 2011
    Posts
    4
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Simple Game Physics & Animation (Air Hockey)

    Hey.

    What I have here is a crude animation setup using labels and a timer. It is just an oblique collision test, eventually to become something similar to Air Hockey.

    Every 1000/FPS miliseconds it updates the positions of the labels according to the velocities as specified by the Puck class. This class contains the data to be later used by the CollisionHandler class such as mass and CoR and also functions to update positions and velocity.

    I don't suppose any function leaving 'update' is important:

    //The Puck class is associated with a label, velocites in x and y directions are velx, vely
    public void update()
        {
            if (Math.abs(velx) > velrest) //velrest is an arbitrarily decided value to cease updates for low velocities
            {
                posx += velx/FPS;
                if (frictionEnabled) velx -= Math.signum(velx) * mu / FPS;
                label.setBounds((int)posx, (int)posy, width, height);
            }
     
            if (Math.abs(vely) > velrest)
            {
                posy += vely/FPS;
                if (frictionEnabled) vely -= Math.signum(vely) * mu / FPS;
                label.setBounds((int)posx, (int)posy, width, height);
            }
     
        }

    The CollisionHandler Class runs a continuous loop to check if any puck is in contact with any other puck and if so, makes calculations to redirect each puck's velocity.

    The 'update' function of the CollisionHandler:

    public void update()
        {
            for(int i = 0; i < counter; i++) //Counter = Total number of pucks
            {
                Puck t = plist[i]; //Array of pucks added to the Handler
     
     
     
                /*Boundary checks omitted, inter-puck collisions:*/
     
                for (int j = i + 1; j < counter; j++) //Checks remaining pucks
                {
                    Puck t2 = plist[j];
                    int coll = (int)distance(t, t2) - (t.width + t2.width)/ 2; //this is where I talked about messing with distance parameters
     
     
                    if (coll == 0)  //setting coll = 0, or defining limits like -1 < coll < 1 etc.
                    {
                        /*Calculations snipped, new velocities applied*/
     
                    }
                }
     
            }
     
        }

    The timer event handler just executes the aforementioned update functions for each puck and one common CollisionHandler instance.


    Most of it works fine, butI have a few questions. Pardon me if some of them are generic but I'm new to this:
    • Right off the bat, my collision detector is screwed up. I've tried several ways; at first I simply checked whether the distance between said pucks was less than zero and updated it as required. That caused the pucks to stick together because often (especially for high velocities) a single collision was read as 40 continuous ones.

      Then I tried equating it to zero, but obviously that failed whenever the distance was not exactly that much and caused them to pass through each other most of the time.

      I then made a small contact-distance limit, trying various values from 1 pixel difference to 10 but encountered the same problem of passing through half the time, and reacting too soon the other half.

      I thought maybe I could set it up so as to ignore any collisions for a small time period after each collision, but that would cause it to also ignore any collisions happening between other pucks at the same time.

      How should I go about doing this? I'm completely baffled.

    • I'm concerned that it tends to slow down for FPS above 80 -I understand that my methods might be inefficient, but surely most modern games have to do many more complicated calculations and update a lot more in far less time - how do they manage this?

    • Regarding the above problem, would it be wise/feasible to work with Event Listeners to notify the appropriate functions for contact between two pucks? I'm not sure if that'd help my case; I'm guessing they run the same way, i.e. a continuous loop to check given condition?

    • For when I get around to the coding for the mouse - how do I lock the mouse from exiting the specified area, like in most games? Google led me to the Robot class, but that appears cumbersome. Is there some easier way?

    • Lastly, is my particular method of animating the labels also inconvenient/inefficient? Most examples I saw on the internet ran separate threads for animating (as far as I could tell) but I don't have much experience with threads. I need to know whether to invest my time looking it up and implementing it.

    Thanks.
    Last edited by Spaces Allowed?; October 31st, 2011 at 01:11 PM.


  2. #2
    Crazy Cat Lady KevinWorkman's Avatar
    Join Date
    Oct 2010
    Location
    Washington, DC
    Posts
    5,424
    My Mood
    Hungover
    Thanks
    144
    Thanked 636 Times in 540 Posts

    Default Re: Simple Game Physics & Animation (Air Hockey)

    Quote Originally Posted by Spaces Allowed? View Post
    //The Puck class is associated with a label, velocites in x and y directions are velx, vely
    Why are you using a JLabel instead of simply drawing the puck to a JPanel directly? Recommended reading: Lesson: Performing Custom Painting (The Java™ Tutorials > Creating a GUI With JFC/Swing)

    Quote Originally Posted by Spaces Allowed? View Post
    The CollisionHandler Class runs a continuous loop to check if any puck is in contact with any other puck and if so, makes calculations to redirect each puck's velocity.
    A continuous loop seems like a bad idea. It should only check collision once per frame.

    Quote Originally Posted by Spaces Allowed? View Post
    Right off the bat, my collision detector is screwed up. I've tried several ways; at first I simply checked whether the distance between said pucks was less than zero and updated it as required. That caused the pucks to stick together because often (especially for high velocities) a single collision was read as 40 continuous ones.

    Then I tried equating it to zero, but obviously that failed whenever the distance was not exactly that much and caused them to pass through each other most of the time.

    I then made a small contact-distance limit, trying various values from 1 pixel difference to 10 but encountered the same problem of passing through half the time, and reacting too soon the other half.

    I thought maybe I could set it up so as to ignore any collisions for a small time period after each collision, but that would cause it to also ignore any collisions happening between other pucks at the same time.

    How should I go about doing this? I'm completely baffled.
    I can't really tell without seeing your code, and I can't really look at anything except an SSCCE- something simple, just a few lines, without anything extra.


    Quote Originally Posted by Spaces Allowed? View Post
    I'm concerned that it tends to slow down for FPS above 80 -I understand that my methods might be inefficient, but surely most modern games have to do many more complicated calculations and update a lot more in far less time - how do they manage this?
    80 fps is huge! Are you sure you need something that high? For simple games, you can usually get away with 30 fps, let alone something as high as 60 fps. And there are a ton of ways to gain efficiency, all depending on the game, the system, etc.

    Quote Originally Posted by Spaces Allowed? View Post
    Regarding the above problem, would it be wise/feasible to work with Event Listeners to notify the appropriate functions for contact between two pucks? I'm not sure if that'd help my case; I'm guessing they run the same way, i.e. a continuous loop to check given condition?
    Again, this all really depends on a lot of things. At first, keep everything on the EDT- use a Timer that updates everything periodically (30 fps or so) and calls repaint. That means you can have some kind of Event Listener dealing with the collisions. But as things get more complicated, you'll want to take more and more stuff off the EDT, making sure to handle updates and painting correctly. I honestly don't really see the point of using a handler for collisions though, to be honest.

    Quote Originally Posted by Spaces Allowed? View Post
    For when I get around to the coding for the mouse - how do I lock the mouse from exiting the specified area, like in most games? Google led me to the Robot class, but that appears cumbersome. Is there some easier way?
    The Robot class is probably the way to go. Or you could consider using a fullscreen application. But really, you should consider not doing it at all. Restricting what the user can do usually annoys the user more than it enhances the program.

    Quote Originally Posted by Spaces Allowed? View Post
    Lastly, is my particular method of animating the labels also inconvenient/inefficient? Most examples I saw on the internet ran separate threads for animating (as far as I could tell) but I don't have much experience with threads. I need to know whether to invest my time looking it up and implementing it.
    How did they use threads? Like I said, at first, keep everything on the EDT using a Swing Timer. But yeah, I don't know why you're using JLabels at all. Just do the painting yourself, and save yourself the overhead.
    Useful links: How to Ask Questions the Smart Way | Use Code Tags | Java Tutorials
    Static Void Games - Play indie games, learn from game tutorials and source code, upload your own games!

  3. #3
    Junior Member
    Join Date
    Oct 2011
    Posts
    4
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Simple Game Physics & Animation (Air Hockey)

    Why are you using a JLabel instead of simply drawing the puck to a JPanel directly?
    While I could use the experience, I need to put in images in place of pucks and labels appear to be the only option.

    A continuous loop seems like a bad idea. It should only check collision once per frame.
    I did mean every frame.

    I can't really tell without seeing your code, and I can't really look at anything except an SSCCE- something simple, just a few lines, without anything extra.
    Well, what I posted up there in the first post was pretty much stripped of anything else. All the pertinent code was up there too. What I need is some implementable way to check for collisions, and I just need some ideas, but my code is up there. I've snipped the calculations too (check first post), so those are just 10 lines each (and the first one has 5 almost repeated anyway).

    80 fps is huge...
    I guess you're right. I did realize that it didn't matter much, and I set it to 40 FPS.

    ...But really, you should consider not doing it at all...
    I agree, it might seem to be an annoyance, but I want to leave paddle control to the mouse - so you can see why I wouldn't want them to be able to access all the parts of the screen. I'm leaning towards dealing with it internally now, i.e. just disable paddle movement when it leaves the area. That should work well.


    Thanks a lot for your help and interest by the way. I'd appreciate it if you'd look at the coding above again now, I've stripped it to bare minimum.

  4. #4
    Crazy Cat Lady KevinWorkman's Avatar
    Join Date
    Oct 2010
    Location
    Washington, DC
    Posts
    5,424
    My Mood
    Hungover
    Thanks
    144
    Thanked 636 Times in 540 Posts

    Default Re: Simple Game Physics & Animation (Air Hockey)

    Quote Originally Posted by Spaces Allowed? View Post
    While I could use the experience, I need to put in images in place of pucks and labels appear to be the only option.
    Nah, there are Graphics.drawImage() functions you might want to check out.

    Quote Originally Posted by Spaces Allowed? View Post
    Well, what I posted up there in the first post was pretty much stripped of anything else. All the pertinent code was up there too. What I need is some implementable way to check for collisions, and I just need some ideas, but my code is up there. I've snipped the calculations too (check first post), so those are just 10 lines each (and the first one has 5 almost repeated anyway).
    I'd love to check it out, if you wouldn't mind throwing together an SSCCE. You've got a good length, but it should also be runnable if we just copy and paste it- just a simple program with two pucks. Maybe move one with the arrow keys and either a print statement or a color change when you detect a collision? There are a bunch of ways to do collision detection, and it really depends on your setup.

    Quote Originally Posted by Spaces Allowed? View Post
    I agree, it might seem to be an annoyance, but I want to leave paddle control to the mouse - so you can see why I wouldn't want them to be able to access all the parts of the screen. I'm leaning towards dealing with it internally now, i.e. just disable paddle movement when it leaves the area. That should work well.
    That seems reasonable. Or you could make the paddle move slower than the mouse, so it's playing catch up (that might be a fun thing to play with). So if you leave the screen and reenter the screen somewhere else, the paddle will still have to catch up to the mouse.
    Useful links: How to Ask Questions the Smart Way | Use Code Tags | Java Tutorials
    Static Void Games - Play indie games, learn from game tutorials and source code, upload your own games!

  5. #5
    Junior Member
    Join Date
    Oct 2011
    Posts
    4
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Simple Game Physics & Animation (Air Hockey)

    Or you could make the paddle move slower than the mouse, so it's playing catch up
    Wow, that sounds brilliant. I do have something similar to that already implemented (was doing a 'magnetism powerup' ) and should be easy to implement, yet fun.

    Nah, there are Graphics.drawImage() functions you might want to check out.
    Will that make much difference, as compared to moving labels around I mean? I'll still check it out I guess.

    SSCCE
    About that - I use Netbeans (yeah, you hate it I know) so is it okay if I just copy that auto-generated stuff?

    I'm working on making a compilable version now, will post soon.

    EDIT: Also, I'm guessing you don't want it in separate classes, i.e., want a single file? It would save some time for me if I could give you the three files (with non-vital stuff omitted, ofc), and would be neater, but whatever you're more comfortable with.

    EDIT2: What about the images? This is hard work :/
    Could you just take a look at my code and see what we can do from there?
    Just throw in the "bunch of ways" of detection. All the relevant code (to understand my 'system') is already in the first post. and it is incredibly difficult for me assembling code I do not understand (the GUI part).
    Last edited by Spaces Allowed?; October 31st, 2011 at 02:23 PM.

  6. #6
    Crazy Cat Lady KevinWorkman's Avatar
    Join Date
    Oct 2010
    Location
    Washington, DC
    Posts
    5,424
    My Mood
    Hungover
    Thanks
    144
    Thanked 636 Times in 540 Posts

    Default Re: Simple Game Physics & Animation (Air Hockey)

    I appreciate the work you're putting into it, but I'm not that much of a nazi! Just throw together something I can copy and paste (if it's multiple classes, that's not the end of the world). Don't worry about the images (honestly most games I write start out as a single circle drawn using Graphics.fillOval() that's controlled by the arrow keys), and just focus on collision between two pucks. Don't make it more work than it has to be!
    Useful links: How to Ask Questions the Smart Way | Use Code Tags | Java Tutorials
    Static Void Games - Play indie games, learn from game tutorials and source code, upload your own games!

  7. #7
    Junior Member
    Join Date
    Oct 2011
    Posts
    4
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Simple Game Physics & Animation (Air Hockey)

    I don't get it - what would you do with a compilable version? My code doesn't need debugging, I just need a suggestion of how to do it. I don't see how running the actual program might help your case, but here is something you can copy and paste:

    Main:
    import java.awt.Cursor;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.Timer;
     
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
     
     
    public class NewJFrame extends javax.swing.JFrame {
     
        /** Creates new form NewJFrame */
        public NewJFrame() {
            initComponents();
            myinit();
            getContentPane().setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
            //myinit();
     
        }
     
     
        double speed = 1;
        double globalFPS = 60;
     
        boolean magnetism = false;
     
     
        Timer t = new Timer((int)(1000/(speed*globalFPS)), new ActionListener() {public void actionPerformed(ActionEvent e) {timerfunc3();}});
        void timerfunc3()
        {
            ch.update();
     
            puck1.update();
            //puck2.update();
            puck3.update();
            puck4.update();
     
     
            if (magnetism)
            {
                double dist = ch.distance(puck1, puck4);
                puck1.velx += 200/globalFPS * (puck4.posx - puck1.posx)/dist;
                puck1.vely += 200/globalFPS * (puck4.posy - puck1.posy)/dist;
            }
        }
     
     
     
     
        /** This method is called from within the constructor to
         * initialize the form.
         * WARNING: Do NOT modify this code. The content of this method is
         * always regenerated by the Form Editor.
         */
        @SuppressWarnings("unchecked")
        // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
        private void initComponents() {
     
            l1 = new javax.swing.JLabel();
            l2 = new javax.swing.JLabel();
            jButton1 = new javax.swing.JButton();
            jButton2 = new javax.swing.JButton();
            jButton3 = new javax.swing.JButton();
            l3 = new javax.swing.JLabel();
            l4 = new javax.swing.JLabel();
     
            setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
            setMinimumSize(new java.awt.Dimension(400, 500));
            setResizable(false);
            addMouseListener(new java.awt.event.MouseAdapter() {
                public void mouseClicked(java.awt.event.MouseEvent evt) {
                    formMouseClicked(evt);
                }
                public void mouseEntered(java.awt.event.MouseEvent evt) {
                    formMouseEntered(evt);
                }
                public void mousePressed(java.awt.event.MouseEvent evt) {
                    formMousePressed(evt);
                }
                public void mouseReleased(java.awt.event.MouseEvent evt) {
                    formMouseReleased(evt);
                }
            });
            addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
                public void mouseMoved(java.awt.event.MouseEvent evt) {
                    formMouseMoved(evt);
                }
            });
            addKeyListener(new java.awt.event.KeyAdapter() {
                public void keyPressed(java.awt.event.KeyEvent evt) {
                    formKeyPressed(evt);
                }
                public void keyReleased(java.awt.event.KeyEvent evt) {
                    formKeyReleased(evt);
                }
            });
            getContentPane().setLayout(null);
     
            l1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/transp.png"))); // NOI18N
            l1.setText("jLabel1");
            getContentPane().add(l1);
            l1.setBounds(160, 130, 40, 40);
     
            l2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/transp.png"))); // NOI18N
            l2.setText("jLabel1");
            getContentPane().add(l2);
            l2.setBounds(340, 10, 40, 40);
     
            jButton1.setText("Start Tmer");
            jButton1.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    jButton1ActionPerformed(evt);
                }
            });
            getContentPane().add(jButton1);
            jButton1.setBounds(40, 20, 83, 23);
     
            jButton2.setText("Stop Timer");
            jButton2.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    jButton2ActionPerformed(evt);
                }
            });
            getContentPane().add(jButton2);
            jButton2.setBounds(130, 20, 90, 23);
     
            jButton3.setText("Debug");
            jButton3.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    jButton3ActionPerformed(evt);
                }
            });
            getContentPane().add(jButton3);
            jButton3.setBounds(240, 20, 63, 23);
     
            l3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/30ps.png"))); // NOI18N
            l3.setText("jLabel1");
            getContentPane().add(l3);
            l3.setBounds(60, 260, 30, 30);
     
            l4.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/transp.png"))); // NOI18N
            l4.setText("jLabel1");
            getContentPane().add(l4);
            l4.setBounds(160, 250, 40, 40);
     
            pack();
        }// </editor-fold>//GEN-END:initComponents
     
     
        private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
            // TODO add your handling code here:
            t.start();
     
        }//GEN-LAST:event_jButton1ActionPerformed
     
        private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
            // TODO add your handling code here:
            t.stop();
        }//GEN-LAST:event_jButton2ActionPerformed
     
        private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed
            // TODO add your handling code here:
        }//GEN-LAST:event_jButton3ActionPerformed
     
     
     
     
     
        private void formMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMousePressed
            magnetism = true;
        }//GEN-LAST:event_formMousePressed
     
     
     
        private void formMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseReleased
            // TODO add your handling code here:
            magnetism = false;
        }//GEN-LAST:event_formMouseReleased
     
        /**
        * @param args the command line arguments
        */
        public static void main(String args[]) {
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    new NewJFrame().setVisible(true);
                }
            });
        }
     
        void myinit()
        {
            puck1 = new Puck(l1, 100, 0, globalFPS);
            puck2 = new Puck(l2, 120, 80, globalFPS);
            puck3 = new Puck(l3, -120, 0, globalFPS);
            puck4 = new Puck(l4, 0, 0, globalFPS);
     
            puck1.frictionEnabled = false;
            puck2.frictionEnabled = false;
            puck3.frictionEnabled = false;
            puck4.frictionEnabled = false;
     
            ch = new CollisionHandler(0, 0, 400, 470);
     
            ch.add(puck1);
            //ch.add(puck2);
            ch.add(puck3);
            ch.add(puck4);    }
     
        // Variables declaration - do not modify//GEN-BEGIN:variables
        private javax.swing.JButton jButton1;
        private javax.swing.JButton jButton2;
        private javax.swing.JButton jButton3;
        private javax.swing.JLabel l1;
        private javax.swing.JLabel l2;
        private javax.swing.JLabel l3;
        private javax.swing.JLabel l4;
        // End of variables declaration//GEN-END:variables
     
        Puck puck1;
        Puck puck2;
        Puck puck3;
        Puck puck4;
        CollisionHandler ch;
    }

    The CH class:

    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
     
    public class CollisionHandler {
     
        int minx;
        int miny;
     
        int maxx;
        int maxy;
        int plimit = 10;
     
        //double velrest = 0.7;
        //double ebound = 0.8;
        double epuck = 0.9;
     
        private Puck[] plist = new Puck[10];
        private int counter = 0;
     
        public CollisionHandler(int lx, int ly, int ux, int uy)
        {
            minx = lx;
            miny = ly;
            maxx = ux;
            maxy = uy;
        }
     
        public boolean add(Puck p)
        {
            if (counter > plimit) return false;
     
            for (int i = 0; i < counter; i++)
            {
                if (plist[i] == p)
                    return false;
            }
     
            plist[counter] = p;
            counter++;
            return true;
        }
     
        public double distance(Puck a, Puck b)
        {
            return Math.sqrt( (a.getCentreX()- b.getCentreX()) * (a.getCentreX()- b.getCentreX()) + (a.getCentreY()- b.getCentreY()) * (a.getCentreY()- b.getCentreY()) );
        }
     
        //If colls get jittery with top and left, change to: posx = minx + some_offset
     
        public void update()
        {
            for(int i = 0; i < counter; i++)
            {
                Puck t = plist[i];
     
                if (Math.abs(t.velx) > t.velrest)
                {
                    if(t.posx > maxx - t.width)
                    {
                        t.posx = maxx - t.width;
                        t.velx *= -t.ebound;
                    }
     
                    if (t.posx < minx)
                    {
                        t.posx = minx;
                        t.velx *= -t.ebound;
                    }
                }
     
                if (Math.abs(t.vely) > t.velrest)
                {
                    if(t.posy > maxy - t.height)
                    {
                        t.posy = maxy - t.height;
                        t.vely *= -t.ebound;
                    }
     
                    if (t.posy < miny)
                    {
                        t.posy = miny;
                        t.vely *= -t.ebound;
                    }
                }
     
                /*inter-puck collisions: TODO*/
                if (counter <= 1) return; //No collisions for less than 1
     
                for (int j = i + 1; j < counter; j++)
                {
                    Puck t2 = plist[j];
                    int coll = (int)distance(t, t2) - (t.width + t2.width) / 2;
     
     
                    if (coll < 0) //&& !(t.velx < t.velrest && t2.velx < t2.velrest && t.vely < t.velrest && t2.vely < t2.velrest))
                    {
                        double cos = Math.abs(t.getCentreX() - t2.getCentreX())/((t.width + t2.width) / 2);
                        double sin = Math.abs(t.getCentreY() - t2.getCentreY())/((t.width + t2.width) / 2);
     
                        double u1 = t.velx*cos + t.vely*sin;
                        double u2 = t2.velx*cos + t2.vely*sin;
     
                        double v1 = (t.mass*u1 + t2.mass*u2 + epuck * t2.mass * (u2 - u1) ) / (t.mass + t2.mass);
                        double v2 = (t.mass*u1 + t2.mass*u2 + epuck * t.mass * (u1 - u2) ) / (t.mass + t2.mass);
     
                        t.velx = v1*cos + t.velx*sin*sin - t.vely*cos*sin;
                        t.vely = v1*sin + t.vely*cos*cos - t.velx*sin*cos;
     
                        t2.velx = v2*cos + t2.velx*sin*sin - t2.vely*cos*sin;
                        t2.vely = v2*sin + t2.vely*cos*cos - t2.velx*sin*cos;
     
                        System.out.println("Bam! " + i + j);// + distance(t, t2) + ", And width- " + (t.width + t2.width) / 2);
     
                    }
                }
     
                //End outer for*/
            }
     
        }
    }

    And the Puck class:

    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
     
    public class Puck {
     
        double mass = 1;
     
        double posx = 0;
        double posy = 0;
     
        double velx;
        double vely;
        double velrest = 0.7;
     
        double ebound = 0.9;
        double mu = 3; //Actually, mu*g
        boolean frictionEnabled = true;
     
        double FPS;
     
        javax.swing.JLabel label;
        int width = 40;
        int height = 40;
     
     
        /*public Puck(javax.swing.JLabel a)
        {
     
        }*/
     
        public Puck(javax.swing.JLabel lbl, double vx, double vy, double f)
        {
            label = lbl;
     
            posx = label.getX();
            posy = label.getY();
     
            width = label.getWidth();
            height = label.getHeight();
     
            velx = vx;
            vely = vy;
     
            FPS = f;
     
        }
     
        public double getCentreX()
        {
            return posx + width/2;
        }
     
        public double getCentreY()
        {
            return posy + width/2;
        }
     
        public void update()
        {
            if (Math.abs(velx) > velrest)
            {
                posx += velx/FPS;
                if (frictionEnabled) velx -= Math.signum(velx) * mu / FPS;
                label.setBounds((int)posx, (int)posy, width, height);
            }
     
            if (Math.abs(vely) > velrest)
            {
                posy += vely/FPS;
                if (frictionEnabled) vely -= Math.signum(vely) * mu / FPS;
                label.setBounds((int)posx, (int)posy, width, height);
            }
     
        }
     
        public void setpos(int x, int y)
        {
            posx = x;
            posy = y;
            label.setBounds((int)posx, (int)posy, width, height);
        }
    }

    Note - You will have to change the image stuff in initComponents() in the main NewJFrame class, add some random image if you want.

    Also, you can set initial velocities in the myInit() function towards the end in the main NewJFrame class. (The second and third arguments while defining Pucks).

Similar Threads

  1. Programming AI for simple game?
    By YouGoLast in forum Java Theory & Questions
    Replies: 3
    Last Post: September 27th, 2024, 02:33 AM
  2. Having trouble with a simple animation
    By knightmetal in forum AWT / Java Swing
    Replies: 2
    Last Post: September 24th, 2011, 02:40 PM
  3. Blender file with animation, how to import OBJ(w/ animation) into Java?
    By cr80expert5 in forum Object Oriented Programming
    Replies: 0
    Last Post: May 12th, 2011, 03:11 AM
  4. Simple GUI/Animation question...
    By teslatrain in forum AWT / Java Swing
    Replies: 3
    Last Post: April 29th, 2011, 04:10 PM
  5. [SOLVED] Physics Program
    By pwngrammer in forum Algorithms & Recursion
    Replies: 36
    Last Post: June 15th, 2009, 08:32 AM