Java-Gaming.org Hi !
 Featured games (84) games approved by the League of Dukes Games in Showcase (575) Games in Android Showcase (154) games submitted by our members Games in WIP (622) games currently in development
 News: Read the Java Gaming Resources, or peek at the official Java tutorials
Pages: [1]
 ignore  |  Print
 Need a bit of help with networked physics in 2d  (Read 1427 times) 0 Members and 1 Guest are viewing this topic.
mlaux

Junior Devvie

Medals: 3

 « Posted 2012-06-08 05:19:48 »

I'm trying to revive a long-forgotten project.

Basically, each player in this game will control an object that can be represented as a circle in 2D. The players will be moving around a playing area and they can bounce off each other with (hopefully) some semblance of realism. Having studied physics in high school this past year (woo hoo!) I can pretty confidently say this is a case of an inelastic collision, since /some/ energy will be lost. But, for simplicity's sake, I'll probably simulate it as an elastic collision.

I've heard networked physics is really, really hard, but I'm sure there are some shortcuts I can take because it's circles in 2D?!

I guess my question is 2 parts:

1. Since kinetic energy and momentum are both conserved in an elastic collision, the sum of the momenta of the 2 objects involved in the collision will be the same before and after the collision. The equation we were given to solve elastic collisions is:

 1 m1v1i + m2v2i = m1v1f + m2v2f

In my game, for now, I'm assuming all objects have a mass of 1. So,

 1 v1i + v2i = v1f + v2f

Solving for v1f and v2f,

 1  2 v1f = v1i + v2i - v2fv2f = v1i + v2i - v1f

(where v1 and v2 are <x, y> velocities, 'i' means initial, and 'f' means final)

Each solution depends on the other... I need more information? What other information? In all the types of problems we were given to solve in school, they always gave us one of the final velocities.

2. What is the best way to communicate player physics updates to all the rest of the clients?

The old implementation just fired off packets from the client to the server every 30 milliseconds with the player's new position, and the server would then spam everybody else with the new data. Needless to say, this didn't work too well.

How hard can a good implementation be?

Sorry this post is pretty scatterbrained, it's late here.

65K
 « Reply #1 - Posted 2012-06-08 08:25:03 »

2. What is the best way to communicate player physics updates to all the rest of the clients?

The old implementation just fired off packets from the client to the server every 30 milliseconds with the player's new position, and the server would then spam everybody else with the new data. Needless to say, this didn't work too well.
- provide the very same code parts for movement and physics on client and server
- receive input, update client entities, send only input to server
- process client input on server, update entities, send updated positions to client
- on client, inspect server response and call your smart algorithm to correct client positions if they differ
- optionally, send a hard entity snapshot to the client every x ms
- optimize traffic by reducing packet sizes like by sending bytes instead of integers if possible, etc.

How hard can a good implementation be?
To me, it's the most challenging part - for a good implementation

mlaux

Junior Devvie

Medals: 3

 « Reply #2 - Posted 2012-06-08 19:34:12 »

Alright, I spent a couple hours trying to figure out the physics, and this is what I came up with. A friend and I researched the concept of the coefficient of restitution (giving us another equation to use), and after much simplifying, we found out that for 2 objects of equal mass in an elastic collision, they just swap velocities.

I then came up with this algorithm to perform the collision response:

http://i45.tinypic.com/2ld7tzp.jpg (page 1)
http://i49.tinypic.com/1w9j4.jpg (page 2)

But, it only works for certain angles. For others, the 2 objects just stick together, collide for a couple of game ticks, and then stop. Here's a compilable example to show the problem:

 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96  97  98  99  100  101  102  103  104  105  106  107  108  109  110  111  112  113  114  115  116  117  118  119  120  121  122  123  124  125  126  127  128  129  130  131  132  133  134  135  136  137  138  139  140  141  142  143  144  145  146  147  148  149  150  151  152  153  154  155  156  157 import java.awt.Color;import java.awt.Dimension;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.RenderingHints;import javax.swing.JFrame;import javax.swing.JPanel;public class CollisionTest extends JPanel implements Runnable {   private Ball b1 = new Ball(25, 25, 1, 1, 25);   private Ball b2 = new Ball(225, 0, -1, 1, 25);      public CollisionTest() {      setDoubleBuffered(true);      setPreferredSize(new Dimension(400, 400));   }      public void run() {      // normalise input??      //double v1 = Math.sqrt(b1.vx * b1.vx + b1.vy * b1.vy);      //double v2 = Math.sqrt(b2.vx * b2.vx + b2.vy * b2.vy);            //b1.vx /= v1;      //b1.vy /= v1;      //b2.vx /= v2;      //b2.vy /= v2;            try {         while(true) {            updatePhysics();            repaint();            Thread.sleep(10);         }      } catch(InterruptedException e) {         Thread.currentThread().interrupt();      }   }      public void updatePhysics() {      double b1x = b1.x + b1.vx; // new x pos of ball 1      double b1y = b1.y + b1.vy; // new y pos of ball 1      double b2x = b2.x + b2.vx; // etc.      double b2y = b2.y + b2.vy;            double r2 = b1.r + b2.r;            // distance between centers      double dist = (b2x - b1x) * (b2x - b1x) + (b2y - b1y) * (b2y - b1y);            // if distance between circles is less than sum of radii      if(dist < r2 * r2) {                  double v1 = Math.sqrt(b1.vx * b1.vx + b1.vy * b1.vy);         double v2 = Math.sqrt(b2.vx * b2.vx + b2.vy * b2.vy);                  System.out.println("initial velocity sum: " + (v1 + v2));                  double ratio = b1.r / (b1.r + b2.r);         System.out.println("r1/sum: " + ratio);                  // calculate collision point         double px = ratio * (b1x + b2x);         double py = ratio * (b1y + b2y);         System.out.println("point of collision: " + px + ", " + py);                  // slope of radius at collision point: (py - b1y) / (px - b1x)         // slope of tangent line is negative reciprocal of that         // mt = (b1x - px) / (py - b1y)         double angle = Math.atan2(b1x - px, py - b1y);         System.out.println("collision angle: " + Math.toDegrees(-angle));                  double b1xr = b1x * Math.cos(-angle); // transformed centers not used         double b1yr = b1y * Math.sin(-angle);         double b1vxr = b1.vx * Math.cos(-angle);         double b1vyr = b1.vy * Math.sin(-angle);                  double b2xr = b2x * Math.cos(-angle);         double b2yr = b2y * Math.sin(-angle);         double b2vxr = b2.vx * Math.cos(-angle);         double b2vyr = b2.vy * Math.sin(-angle);                  // swap velocities         System.out.println("ball 1 transformed position: " + b1xr + " " + b1yr);         System.out.println("ball 2 transformed position: " + b2xr + " " + b2yr);         System.out.println("ball 1 transformed velocity: " + b1vxr + ", " + b1vyr);         System.out.println("ball 2 transformed velocity: " + b2vxr + ", " + b2vyr);                  b1.vx = b2vxr;         b1.vy = b2vyr;                  b2.vx = b1vxr;         b2.vy = b1vyr;                  v1 = Math.sqrt(b1.vx * b1.vx + b1.vy * b1.vy);         v2 = Math.sqrt(b2.vx * b2.vx + b2.vy * b2.vy);                  System.out.println("final velocity sum: " + (v1 + v2));                  System.out.println();      } else {                  // set new positions         b1.x = b1x;         b1.y = b1y;                  b2.x = b2x;         b2.y = b2y;      }   }      public void paintComponent(Graphics _g) {      super.paintComponent(_g);            Graphics2D g = (Graphics2D) _g;      g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);      g.setColor(Color.black);      b1.draw(g);      b2.draw(g);   }      public static void main(String[] args) {      JFrame f = new JFrame();      CollisionTest ct = new CollisionTest();      f.setResizable(false);      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);      f.add(ct);      f.pack();      f.setLocationRelativeTo(null);      f.setVisible(true);            ct.run();   }      static class Ball {      public double x;      public double y;            public double vx;      public double vy;            public double r;            public Ball(double _x, double _y, double _vx, double _vy, double _r) {         x = _x;         y = _y;         vx = _vx;         vy = _vy;         r = _r;      }            public void draw(Graphics2D g) {         g.setColor(Color.black);         g.drawOval((int) (x - r), (int) (y - r), (int) (2 * r), (int) (2 * r));      }   }}

Any ideas?

Pages: [1]
 ignore  |  Print

You cannot reply to this message, because it is very, very old.

 BurntPizza (27 views) 2015-04-23 03:42:11 theagentd (30 views) 2015-04-22 16:23:07 Riven (44 views) 2015-04-16 10:48:47 Duke0200 (52 views) 2015-04-16 01:59:01 Fairy Tailz (38 views) 2015-04-14 20:13:12 Riven (41 views) 2015-04-12 21:36:37 bus hotdog (58 views) 2015-04-10 02:39:32 CopyableCougar4 (61 views) 2015-04-10 00:51:04 BurntPizza (62 views) 2015-04-06 22:06:58 ags1 (62 views) 2015-04-02 10:58:48
 theagentd 26x BurntPizza 16x wessles 15x 65K 11x Rayvolution 11x alwex 11x kingroka123 11x KevinWorkman 9x kevglass 8x phu004 8x Roquen 7x chrislo27 7x Hanksha 7x Riven 7x Olo 7x ra4king 7x
 How to: JGO Wikiby Mac702015-02-17 20:56:162D Dynamic Lighting2015-01-01 20:25:42How do I start Java Game Development?by gouessej2014-12-27 19:41:21Resources for WIP gamesby kpars2014-12-18 10:26:14Understanding relations between setOrigin, setScale and setPosition in libGdx2014-10-09 22:35:00Definite guide to supporting multiple device resolutions on Android (2014)2014-10-02 22:36:02List of Learning Resources2014-08-16 10:40:00List of Learning Resources2014-08-05 19:33:27
 java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org