public override void Update(float deltaTime)
        {
            //While the bullet hasnt hit anything, be a bullet
            if (!hasHit)
            {
                //Set Vector3 to forward
                MthLib.Vector3 move = new MthLib.Vector3(0f, -speed * deltaTime, 0f);

                //Create a rotation matrix
                MthLib.Matrix3 rotMatrix = new MthLib.Matrix3();
                //MathLibrary uses radians, while Raylib uses degrees
                rotMatrix.SetRotateZ(local.rotation * (float)(Math.PI / 180f));

                //Rotate movement to be in the dirrection the bullet is facing, and update local
                local.point += rotMatrix * move;
                //Check for collision
                Collision();
            }
            else
            {
                //Display smoke for set amount of time, then delete object
                count += deltaTime;
                if (count >= 0.1f)
                {
                    //Destroy the bullet
                    FreeMemory();
                    return;
                }
            }
        }
        public static bool PointOBBcolliding(MthLib.Vector3 point, MthLib.Matrix3 obb)
        {
            //Find nessesary values
            MthLib.Vector3 diff    = point - new MthLib.Vector3(obb.m3, obb.m6, 0);
            MthLib.Vector3 xExtent = new MthLib.Vector3(obb.m1, obb.m4, 0);
            MthLib.Vector3 yExtent = new MthLib.Vector3(obb.m2, obb.m5, 0);
            //Check if the point is within the extents
            bool insideX = Math.Abs(diff.Dot(xExtent)) > xExtent.Magnitude();
            bool insideY = Math.Abs(diff.Dot(yExtent)) > yExtent.Magnitude();

            //If it is within both, it is inside the OBB
            return(insideX && insideY);
        }
        public override void Update(float deltaTime)
        {
            //***** Look with mouse *****

            /*
             * //Get the difference between the mouse and the turret
             * MthLib.Vector3 diff = new MthLib.Vector3(rl.Raylib.GetMouseX(), rl.Raylib.GetMouseY(), 0f);
             * diff -= global.point;
             * //Remove the parents rotation and add the rotation of the mouse relative to the tank. 90 is added because Atan2 starts at 90 degrees
             * local.rotation = 90 - (global.rotation - local.rotation) + (float)Math.Atan2(diff.y, diff.x) * (float)(180/Math.PI);
             */

            //***** Look with keys *****
            //Turn left
            if (rl.Raylib.IsKeyDown(left))
            {
                local.rotation -= rotSpeed * deltaTime;
            }
            //Turn right
            if (rl.Raylib.IsKeyDown(right))
            {
                local.rotation += rotSpeed * deltaTime;
            }

            //Fix rotation to not loop around
            if (local.rotation < 0f)
            {
                local.rotation += 360f;
            }
            else if (local.rotation > 360f)
            {
                local.rotation -= 360f;
            }


            //Create bullet at the top of the barrel
            if (rl.Raylib.IsKeyPressed(shoot) /* || rl.Raylib.IsMouseButtonPressed(rl.MouseButton.MOUSE_LEFT_BUTTON)*/)
            {
                GameObject bullet = new BulletClass(null, bulletImg, 700f, global.rotation);

                //Multiply imgSize by a small amount to keep bullet from colliding with the tank
                MthLib.Vector3 offset = new MthLib.Vector3(0f, imgSize.y * 1.2f, 0f);
                //Create rotation matrix
                MthLib.Matrix3 rot = new MthLib.Matrix3();
                rot.SetRotateZ(global.rotation * (float)(Math.PI / 180f));
                //Rotate the length of the barrel by its rotation to find the offset
                offset = rot * offset;

                bullet.SetLocation(global.point.x - offset.x, global.point.y - offset.y);
            }
        }
        /// <summary>
        /// Returns the corner locations of an OBB
        /// </summary>
        private static Rect GetCorners(MthLib.Matrix3 obb)
        {
            //Get nessesary values
            MthLib.Vector3 center  = new MthLib.Vector3(obb.m3, obb.m6, 0);
            MthLib.Vector3 xExtent = new MthLib.Vector3(obb.m1, obb.m4, 0);
            MthLib.Vector3 yExtent = new MthLib.Vector3(obb.m2, obb.m5, 0);

            return(new Rect
            {
                FL = center - xExtent + yExtent,
                FR = center + xExtent + yExtent,
                BL = center - xExtent - yExtent,
                BR = center + xExtent - yExtent
            });
        }
        private static bool IsOverlapping(MthLib.Vector3 normal, Rect rect1, Rect rect2)
        {
            //Project the rect's corners onto the normal
            float dot1 = normal.Dot(rect1.FL);
            float dot2 = normal.Dot(rect1.FR);
            float dot3 = normal.Dot(rect1.BL);
            float dot4 = normal.Dot(rect1.BR);
            //Find the furthest points
            float min1 = Math.Min(dot1, Math.Min(dot2, Math.Min(dot3, dot4)));
            float max1 = Math.Max(dot1, Math.Max(dot2, Math.Max(dot3, dot4)));

            //Repeat for the second rect
            dot1 = normal.Dot(rect2.FL);
            dot2 = normal.Dot(rect2.FR);
            dot3 = normal.Dot(rect2.BL);
            dot4 = normal.Dot(rect2.BR);
            float min2 = Math.Min(dot1, Math.Min(dot2, Math.Min(dot3, dot4)));
            float max2 = Math.Max(dot1, Math.Max(dot2, Math.Max(dot3, dot4)));

            //Are the projections overlapping?
            return(min1 <= max2 && min2 <= max1);
        }
        public static bool OBBcolliding(MthLib.Matrix3 obj1, MthLib.Matrix3 obj2)
        {
            //Get the corners of both colliders
            Rect rect1 = GetCorners(obj1);
            Rect rect2 = GetCorners(obj2);

            //4 axis have to be tested to know if they are colliding
            //If a single axis is not overlapping, they are not colliding

            //Get the normal for the axis, then check for overlap on it
            MthLib.Vector3 normal = GetNormal(rect1.BL, rect1.FL);
            if (!IsOverlapping(normal, rect1, rect2))
            {
                return(false);
            }

            normal = GetNormal(rect1.FL, rect1.FR);
            if (!IsOverlapping(normal, rect1, rect2))
            {
                return(false);
            }

            normal = GetNormal(rect2.BL, rect2.FL);
            if (!IsOverlapping(normal, rect1, rect2))
            {
                return(false);
            }

            normal = GetNormal(rect2.FL, rect2.FR);
            if (!IsOverlapping(normal, rect1, rect2))
            {
                return(false);
            }

            //If all of the axis overlapped, then they are colliding
            return(true);
        }
 public static bool PointAABBcolliding(MthLib.Vector3 point, AABB aabb)
 {
     //Return NOT outside the collider
     return(!(point.x < aabb.min.x || point.y < aabb.min.y ||
              point.x > aabb.max.x || point.y > aabb.max.y));
 }
 /// <summary>
 /// Get the normal of a line from start to end, pointing left relative to start
 /// </summary>
 private static MthLib.Vector3 GetNormal(MthLib.Vector3 start, MthLib.Vector3 end)
 {
     MthLib.Vector3 dir = end - start;
     //Return the normal by flipping x and y and making one negitive
     return(new MthLib.Vector3(-dir.y, dir.x, dir.z));
 }
 public Actor(Vector3 position) : this(position.X, position.Y, position.Z)
 {
 }
Exemple #10
0
        public override void Update(float deltaTime)
        {
            //Turn left
            if (rl.Raylib.IsKeyDown(left))
            {
                local.rotation -= rotSpeed * deltaTime;
            }
            //Turn right
            if (rl.Raylib.IsKeyDown(right))
            {
                local.rotation += rotSpeed * deltaTime;
            }

            //Fix rotation to not loop around
            if (local.rotation < 0f)
            {
                local.rotation += 360f;
            }
            else if (local.rotation > 360f)
            {
                local.rotation -= 360f;
            }


            //Forward
            if (rl.Raylib.IsKeyPressed(up))
            {
                accel -= acceleration;
            }
            if (rl.Raylib.IsKeyReleased(up))
            {
                accel += acceleration;
            }
            //Backward
            if (rl.Raylib.IsKeyPressed(down))
            {
                accel += acceleration;
            }
            if (rl.Raylib.IsKeyReleased(down))
            {
                accel -= acceleration;
            }

            //When accel is 0, reduce speed to 0
            if (accel == 0f && speed != 0f)
            {
                float temp = (speed > 0f) ? -acceleration : acceleration;
                speed += temp * deltaTime;
                //If close to 0, set to 0 to prevent jittering
                if (speed > -limit && speed < limit)
                {
                    speed = 0f;
                }
            }
            else if (speed > -maxSpeed && speed < maxSpeed)
            {
                //Update speed. deltaTime should be a small value, so speed should only go slightly over maxSpeed
                speed += accel * deltaTime;
            }

            //Put speed into a vector to rotate it to the dirrection the tank is facing
            MthLib.Vector3 move = new MthLib.Vector3(0f, speed, 0f);
            //Create a rotation matrix, converting to radians
            MthLib.Matrix3 rotMatrix = new MthLib.Matrix3();
            rotMatrix.SetRotateZ(local.rotation * (float)(Math.PI / 180f));

            //Rotate movement and update local
            local.point += rotMatrix * move;
            //Check for collision
            Collision();
        }
 public Actor()
 {
     LocalPosition = new Vector3();
     UpdateTransform();
 }
 public void SetScale(Vector3 scale)
 {
     _scale = Matrix4.CreateScale(scale);
 }
 public void Rotate(Vector3 radians)
 {
     _rotationAngle += radians;
     _rotation      *= Matrix4.CreateCombinedRotation(radians);
 }
 public void SetRotation(Vector3 radians)
 {
     _rotationAngle = radians;
     _rotation      = Matrix4.CreateCombinedRotation(radians);
 }
 public void SetTranslation(Vector3 position)
 {
     _translation = Matrix4.CreateTranslation(position);
 }
        public Actor(float x, float y, float z)
        {
            LocalPosition = new Vector3(x, y, z);

            UpdateTransform();
        }
Exemple #17
0
        private void Collision()
        {
            //Update collider location and rotation
            UpdateColliderLoc();
            //Rotation matrix of the difference in rotation
            MthLib.Matrix3 rotMatrix = new MthLib.Matrix3();
            rotMatrix.SetRotateZ((local.rotation - global.rotation) * (float)(Math.PI / 180f));
            //Rotate the extents, then put them back in the matrix
            MthLib.Vector3 x = new MthLib.Vector3(collider.m1, collider.m4, 0);
            x           = rotMatrix * x;
            collider.m1 = x.x;
            collider.m4 = x.y;
            MthLib.Vector3 y = new MthLib.Vector3(collider.m2, collider.m5, 0);
            y           = rotMatrix * y;
            collider.m2 = y.x;
            collider.m5 = y.y;


            //Get an AABB for rough collision before using OBB
            AABB aabb = CollisionFuncs.OBBtoAABB(collider);

            //Check if going out of bounds. Because the tank needs to stay inside, just AABB needs to be tested
            if (!CollisionFuncs.AABBwithin(aabb, GameManager.screenBox))
            {
                //Tank is out of bounds; reset transform
                local = global;
                return;
            }

            //Go through all core objects and check for collision with other tanks
            foreach (GameObject obj in GameManager.coreObjects)
            {
                //If it isnt a tank, move on
                if (obj.tag != "Tank")
                {
                    continue;
                }

                TankClass tank = obj as TankClass;
                //If the tank is this tank, move on
                if (tank == this)
                {
                    continue;
                }


                //At this point, the tank must be a different tank, so it can be collided with
                //The collider is OBB, so it needs to be made an AABB
                AABB otherAABB = CollisionFuncs.OBBtoAABB(tank.collider);

                if (CollisionFuncs.AABBcolliding(aabb, otherAABB))
                {
                    //If they are colliding, check OBB collision
                    if (CollisionFuncs.OBBcolliding(collider, tank.collider))
                    {
                        //They are colliding, so reset transform
                        local = global;
                        return;
                    }
                }
            }
        }