Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (488)
Games in Android Showcase (112)
games submitted by our members
Games in WIP (553)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  3D First Person Game with Networking  (Read 2926 times)
0 Members and 1 Guest are viewing this topic.
Offline Pauler
« Posted 2013-10-04 17:57:00 »

Well, a couple of days ago I decided to code a first person shooter-like game, in order to expand my knowledge some more. I tried to keep it clean, and flexible. (The opposite of my other opengl projects).

<a href="http://www.youtube.com/v/1PX790I1Dz0?version=3&amp;hl=en_US&amp;start=" target="_blank">http://www.youtube.com/v/1PX790I1Dz0?version=3&amp;hl=en_US&amp;start=</a>

The things that I was more interested about were the networking part and the shaders part. Sadly, I found time for first one only. I tried to give the feeling that there is light using glColor, but it caused a huge fps drop, and I removed it.

EDIT: Forgot to mention that currently I am using a really inefficient way to see at what object the player is looking/targeting at. I would really appreciate some help with the ray-casting.

Here is a list of some things I want to add but I haven't yet, due to limited time, boredom or due to lack of knowledge at some spots. (Lighting, ray-casting)

TO-DO List:
Add the networking part.
Add a chat.
Load maps from .txt file.
Actually kill other players.
Ray-casting.
Lighting.

Offline opiop65

JGO Kernel


Medals: 154
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #1 - Posted 2013-10-04 18:04:32 »

Looks nice! Are you using matrices and the such or are you still using old OpenGL? And are you using a networking library?

Offline Pauler
« Reply #2 - Posted 2013-10-04 18:06:10 »

I am using the old OpenGL, the network part is coded by me for the fun of knowledge.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline opiop65

JGO Kernel


Medals: 154
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #3 - Posted 2013-10-04 18:09:52 »

So you're just using Java's built in networking? What tutorials did you learn from?

Offline Pauler
« Reply #4 - Posted 2013-10-04 18:12:07 »

I am just using the built in Sockets and ServerSockets. I didn't really read any tutorials. I was looking at other sources to have a taste until I get the whole idea. I had made a 2d rpg game using swing some years ago and I had done some networking back then, so it wasn't a completely new world to explore.
Offline SHC
« Reply #5 - Posted 2013-10-05 02:52:18 »

Nice! Can you say how do you load levels from .txt files? I usually make the whole world as a .OBJ file with blender.

Offline Pauler
« Reply #6 - Posted 2013-10-05 06:50:56 »

Nice! Can you say how do you load levels from .txt files? I usually make the whole world as a .OBJ file with blender.

For example this is the map in the video:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
###################
#......#..........#
#..#......#....#..#
######.#####.######
#......#..........#
#......#.########.#
####...#.#........#
#......#.#.####...#
#..#...#.#....#####
#..#####...###.#..#
#........#.....##.#
#..##.########.##.#
#..##.#.....#..##.#
#..##.##.##.#.....#
#...........#..##.#
#..#####......###.#
#.......##.#......#
####.###...#.#.#..#
#..........#.#.#..#
###...#####..#.#..#
##############.####


Now after I load the file, I go through each character. If, for example, the character is a '.', then it adds a grass box and at some distance above it adds a box which is part of the roof. If it is a '#', then it adds a wall at that point.
Offline kpars

JGO Wizard


Medals: 77
Projects: 4
Exp: 3 years


Extreme Typist.


« Reply #7 - Posted 2013-10-05 06:59:43 »

To make it easier, you can use image-based loading.

You scan an image for every pixels' location and color, and if the color = X, then it will return a certain object at the location corresponding to the pixel's.

- Jev.

Offline SHC
« Reply #8 - Posted 2013-10-05 07:33:14 »

@Pauler
That reminds me of 2D levels I made a while back. Can you say how this can be used to create objects at a certain height?

@kpars
Loading from images is easier but creating them requires more time than writing text files.

Offline Pauler
« Reply #9 - Posted 2013-10-05 08:01:32 »

You don't control the height via the text file. You just say that if the character is a '#' create at y = 20, or whatever, a new object. It is something that you can preconfigured in your code.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Pauler
« Reply #10 - Posted 2013-10-14 17:49:57 »

Once again I am stuck and I cannot move the project on, because I fail at implementing an actual ray-casting script. Even though, I have pretty much understood the whole concept I keep failling at actually making it work. Right now, I am just generating points until a specified distance and I check if there is any kind of intersection between them and the objects. It turns out it is completely inaccurate and inefficient.
Offline Longor1996
« Reply #11 - Posted 2013-10-14 17:57:48 »

Once again I am stuck and I cannot move the project on, because I fail at implementing an actual ray-casting script. Even though, I have pretty much understood the whole concept I keep failling at actually making it work. Right now, I am just generating points until a specified distance and I check if there is any kind of intersection between them and the objects. It turns out it is completely inaccurate and inefficient.

I could give you a (kind-of fast and) simple raytracing code for your game.
(Raytracing is somehow the same thing as raycasting for me...)
(I really need to pimp up my knowledge of 3D math.)

Well at least my raytracing code can raytrace a image at 400x300px with 40 FPS,
even the fact that the scene consits only of 5 triangles, its still fast enough for most things.

EDIT:
I am just going to put this here, so you can use it.
The entire class is completely mathematically correct, so if the code fails to detect a hit for some odd reason, its your fault, not the fault of this code.

(Btw: I just copied this without changes from my utility library)
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  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
// Copyright @Longor1996
package de.L19.math2;

// All methods in this class are not fully optimized.
// Optimize where needed (Both Memory and CPU wise).
/**Defines a 3D ray with an Origin and a Direction.**/
public class Ray {

   /**The Origin of this Ray Object.**/
   public Vector4D Origin;

   /**The Direction of this Ray Object.**/
   public Vector4D Direction;

   /**
    * Constructs a new Ray instance pointing forward (Positive Z).
    **/

   public Ray(){
      this.Origin = new Vector4D(0,0,0,1);
      this.Direction = new Vector4D(0,0,1,1);
   }

   /**
    * Returns the Point at the given Distance from this ray's PointOfView.
    *
    * Use this to get the intersection-point from the intersection-distance returned by the methods in this class.
    **/

   public Vector4D getPoint(double t) {
      return this.Origin._doAdd(this.Direction._doMultiplyBy(t));
   }

   /**
    * Fastest possible Ray/Plane intersection method.
    * This method calculates the intersection-distance between a ray and a infinite plane (/hyperplane).
    *
    * @return The intersection-distance between the ray and the plane.
    **/

   public double RayIntersectionPlane(Ray ray,Vector4D Position,Vector4D Normal){
      return -((Normal.doDotProduct(ray.Origin) + (-Normal.doDotProduct(Position))) / Normal.doDotProduct(ray.Direction));
   }

   /**
    * Fastest possible Ray/Plane intersection method.
    * This method calculates the intersection-distance between a ray and a infinite plane (/hyperplane).
    *
    * @return The intersection-point between the ray and the plane.
    **/

   public Vector4D RayIntersectionPlane(Vector4D Position,Vector4D Normal){
      return this.getPoint(this.RayIntersectionPlane(this,Position, Normal));
   }

   /**
    * Untested, probably buggy, method.
    **/

   public double RayIntersectionPlaneInAABB(Vector4D Position,Vector4D Normal,double ax,double ay,double az,double bx,double by,double bz,boolean invertPlane){
      // Inverts the plane if told so. Creates a negated copy of the normal vector. (Waste of Memory, don't do that too often)
     if(invertPlane)
         Normal = Normal._doNegate();
     
      // Calculates the intersection between this ray and the given AABB side-plane.
     final double d = this.RayIntersectionPlane(this, Position, Normal) + 0.0001D;
      final Vector4D v = this.getPoint(d);
     
      // check if the intersection-point is inside the AABB...
     if(v.x < ax)return Double.POSITIVE_INFINITY;
      if(v.y < ay)return Double.POSITIVE_INFINITY;
      if(v.z < az)return Double.POSITIVE_INFINITY;
      if(v.x > bx)return Double.POSITIVE_INFINITY;
      if(v.y > by)return Double.POSITIVE_INFINITY;
      if(v.z > bz)return Double.POSITIVE_INFINITY;
     
      // Point is inside the AABB from the view of the given Box-Side, done calculating.
     return d;
   }

   /**
    * This method calculates the intersection-distance between a ray and a sphere (with the given radius and position).
    *
    * @return The intersection-point between the ray and the sphere.
    *
    **/

   public double RayIntersectionSphere(final Ray ray,final Vector4D position,final double radius){
      final Vector4D s = position._doSubtract(ray.Origin);  //s=Sphere Center Translated into Coordinate Frame of Ray Origin

      //Intersection of Sphere and Line     =       Quadratic Function of Distance
     final double A = ray.Direction.doDotProduct(ray.Direction);// Remember This From High School? :
     final double B = -2.0F * s.doDotProduct(ray.Direction);    //    A x^2 +     B x +               C  = 0
     final double C = s.doDotProduct(s) - (radius*radius);      // (r'r)x^2 - (2s'r)x + (s's - radius^2) = 0
     final double D = (B*B) - (4F*A*C);                             // Precompute Discriminant

      //Solution Exists only if sqrt(D) is Real (not Imaginary)
     if (D > 0.0){
         final double sign = (C < -0.00001) ? 1 : -1;               //Ray Originates Inside Sphere If C < 0
        final double lDist = (-B + (sign * Math.sqrt(D))) / (2 * A); //Solve Quadratic Equation for Distance to Intersection

         return lDist;
      } else
         return Float.POSITIVE_INFINITY;
   }

   /**
    * Calculates the intersection-distance between a ray and a triangle.
    * This method is REALLY slow, but you can still call it 2.700 times per second without problems.
    *
    * @return The intersection-distance between the given ray and the given triangle.
    **/

   public double RayIntersectionTriangle(Ray ray,Vector4D point1,Vector4D point2,Vector4D point3){
      Vector4D edge1 = point2._doSubtract(point1);
      Vector4D edge2 = point3._doSubtract(point1);

      // Find the cross product of edge2 and the ray direction
     Vector4D s1 = ray.Direction._getCrossProduct(edge2);

      // Find the divisor, if its zero, return false as the triangle is
     // degenerated
     final double divisor = s1.doDotProduct(edge1);
      if (divisor == 0.0)
         return Double.POSITIVE_INFINITY;

      // A inverted divisor, as multiplying is faster then division
     final double invDivisor = 1 / divisor;

      // Calculate the first barycentic coordinate. Barycentic coordinates
     // are between 0.0 and 1.0
     final Vector4D distance = ray.Origin._doSubtract(point1);
      final double barycCoord_1 = distance.doDotProduct(s1) * invDivisor;

      if ((barycCoord_1 < 0.0) || (barycCoord_1 > 1.0))
         return Double.POSITIVE_INFINITY;

      // Calculate the second barycentic coordinate
     final Vector4D s2 = distance._getCrossProduct(edge1);
      final double barycCoord_2 = ray.Direction.doDotProduct(s2) * invDivisor;

      if ((barycCoord_2 < 0.0) || ((barycCoord_1 + barycCoord_2) > 1.0))
         return Double.POSITIVE_INFINITY;

      // After doing the barycentic coordinate test we know if the ray hits or
     // not. If we got this far the ray hits.
     // Calculate the distance to the intersection point
     final double intersectionDistance = edge2.doDotProduct(s2) * invDivisor;

      return intersectionDistance >= 0 ? intersectionDistance : Double.POSITIVE_INFINITY;
   }

   /**
    * Calculates the intersection-distance between this ray and the given AABB.
    * Probably buggy, may fail in some cases.
    **/

   public double RayIntersectionAABB(double ax,double ay,double az,double bx,double by,double bz){
      final double plane_top   = this.RayIntersectionPlaneInAABB(new Vector4D(0,by,0),new Vector4D(0,+1,0), ax, ay, az, bx, by, bz, false);
      final double plane_bottom= this.RayIntersectionPlaneInAABB(new Vector4D(0,ay,0),new Vector4D(0,-1,0), ax, ay, az, bx, by, bz, false);

      final double plane_left  = this.RayIntersectionPlaneInAABB(new Vector4D(ax,0,0),new Vector4D(-1,0,0), ax, ay, az, bx, by, bz, false);
      final double plane_right = this.RayIntersectionPlaneInAABB(new Vector4D(bx,0,0),new Vector4D(+1,0,0), ax, ay, az, bx, by, bz, false);

      final double plane_front = this.RayIntersectionPlaneInAABB(new Vector4D(0,0,az),new Vector4D(0,0,+1), ax, ay, az, bx, by, bz, false);
      final double plane_back  = this.RayIntersectionPlaneInAABB(new Vector4D(0,0,bz),new Vector4D(0,0,-1), ax, ay, az, bx, by, bz, false);

      double t = Double.POSITIVE_INFINITY;
      t = Math.min(t, plane_top);
      t = Math.min(t, plane_bottom);
      t = Math.min(t, plane_left);
      t = Math.min(t, plane_right);
      t = Math.min(t, plane_front);
      t = Math.min(t, plane_back);
      return t;
   }
}


Example Usage:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
 Ray yourRay = ...;
 SomeObjectType someObject = null;
 double lastClosestDistance = Double.POSITIVE_INFINITY;
 
 // go trough each of the object to check...
for(SomeObjectType objectToCheck)
 {
   double dist = RayIntersectionXXXX(yourRay, ...);
 
   // check if the intersection is closer
  if(dist < lastClosestDistance){
     someObject = objectToCheck;
     lastClosestDistance = dist;
   }
 }
 
 // result is in the 'lastClosestDistance' and 'someObject' variables!


- Longor1996

Sorry for my bad English! That's because i am from Germany.
Offline Pauler
« Reply #12 - Posted 2014-01-31 11:40:25 »

I apologise for bringing up this topic after a couple of months of inactivity, but now that I found time to code again, I decided to work on the ray picking part that it used to hold me back and it's still does. I thought of an no-so-efficient way to do the ray-picking but I decided to give it a try anyway. The engine kinda generates many points in a fixed distance direction he is looking at and checks each time if the points intersects to a rectangle. If it does it removes the rectangle. The problem is that when the camera starts to have a big angle, sometimes it starts removing wrong rectangles. I re-wrote the code in a different way but I keep getting the same malfunction.

<a href="http://www.youtube.com/v/sZUqfNx-fJU?version=3&amp;hl=en_US&amp;start=" target="_blank">http://www.youtube.com/v/sZUqfNx-fJU?version=3&amp;hl=en_US&amp;start=</a>

The following function returns the nearest object that players looks.

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  
public Rectangle getTargetedObject() {      
      double cameraPitchInRadians = Math.toRadians(Game.getCamera().pitch);
      double cameraYawInRadians = Math.toRadians(Game.getCamera().yaw);

      for (float x = 1; x < 15; x++) {
         for (float y = 1; y < 15; y++) {
            for (float z = 1; z < 15; z++) {
               float newX = (x * (float)Math.sin(cameraYawInRadians));
               float newZ = (z * (float)Math.cos(cameraYawInRadians));
               float newY = (y * (float)Math.sin(cameraPitchInRadians));
               
               float pointX = 0, pointY = 0, pointZ = 0;
               
               pointX = getX() + newX;
               pointY = getY() - newY;
               pointZ = getZ() - newZ;
               
               for (Rectangle rect:MapManager.getCurrentMap().getObjects()) {
                  if (rect.isCollidingWithPoint(pointX, pointY, pointZ)) {
                     return rect;
                  }
               }
            }
         }
      }

      return null;
   }


This one actually checks if the point that is generated using the function above is actually interesting with a rectangle.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
   public boolean isCollidingWithPoint(float x, float y, float z) {
      if (width == 0) width++;
      if (height == 0) height++;
      if (length == 0) length++;
     
      if(Math.abs((getX() + width / 2) - x) < width / 2)
      {
         if(Math.abs((getY() + height / 2) - y) < height / 2)
         {
            if (Math.abs((getZ() + length / 2) - z) < length / 2) {
               if (width == 1) width--;
               if (height == 1) height--;
               if (length == 1) length--;

               return true;
            }
         }
      }        
      if (width == 1) width--;
      if (height == 1) height--;
      if (length == 1) length--;

      return false;
   }


If anyone can see anything, that I cannot, please let me know.

Regards.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

TehJavaDev (17 views)
2014-08-28 18:26:30

CopyableCougar4 (26 views)
2014-08-22 19:31:30

atombrot (39 views)
2014-08-19 09:29:53

Tekkerue (36 views)
2014-08-16 06:45:27

Tekkerue (33 views)
2014-08-16 06:22:17

Tekkerue (22 views)
2014-08-16 06:20:21

Tekkerue (33 views)
2014-08-16 06:12:11

Rayexar (69 views)
2014-08-11 02:49:23

BurntPizza (46 views)
2014-08-09 21:09:32

BurntPizza (37 views)
2014-08-08 02:01:56
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
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
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!