Jump to content

  • Log In with Google      Sign In   
  • Create Account

FantasyVII

Member Since 13 Jul 2012
Offline Last Active Today, 04:35 AM

Topics I've Started

How to scale UI without losing image quality?

07 December 2014 - 09:25 AM

Hello everyone,

 

So I have been making my own UI library for my game engine in XNA and I have been having a lot of fun with it. Anyway, I have been looking for a better way to scale UI in real time just like Windows or QT, and I have found a nice simple solution to scale UI without losing much or any image quality for that matter. However it works only on specific kind of UI. I will show you what I mean.

 

So in my UI library, I load the window or button (or whatever I want to scale) UI image which would be in a PNG format and would look something like this.

 

UI image:-

WmbQBUg.png?1

 

 

 

 

 

I take the image and cut it into nine separate pieces and save each peace in a separate texture:-

  • I cut the four corners which will never be scaled.
  • I cut the four lines of the image that are on the Top, Left, Bottom and right which they will be scaled.
  • I cut the background image which will be scaled.

 

 

 

How I cut it:-

cVAMbXv.png

 

 

 

After that I just resize the background and the four lines on the sides. By doing that I can scale the UI perfectly to any resolution I want without losing the UI image quality.

 

Now that works great for simple UI image like the one above. However if I have something more complicated like this UI image, its not possible to scale it using this method. Because there is a lot of details on that image and it will not scale correctly.

 

TrvTx9i.png

 

 

So my question is. Is there another way to take something like the image above and scale it without losing any quality?

 

 

Here is my UI library working in action :)

 

 

 

 

Sorry for the long post.

 

Thank you happy.png


Weird stuff happening when stepping through a threaded code

03 December 2014 - 07:13 AM

Update 1:-

Problem solved I was calling the Thread twice. I'm so stupid. happy.png

 

Update 2:- as it turns out my code is not thread safe. working to fix it and will post new code soon.

 

Hello all,

 

I have very little experience in Multi-threaded programming, but from what I understand is you can create a thread to solve a problem and when its done it spits out the answer for your problem.

 

So that's what I did. I have a thread that starts and never dies until the software exits. in this thread I try to solve pathfinding problems. I have a Job class and a result class. In my main class I have a list of both the job class and the result class. So basically what I do is, I add new jobs to the list and the UpdateThread takes these jobs and solve them. When its done solving them, it spits out the answer in the results list and then deletes the old job from the job list.

 

My problem is sometimes I get random null errors inside my Astar class which is very weird. However there is another weird problem which is better demonstrated in the video below.

 

So when I try to step into my update code which is the threaded code, I seem to step in it twice. meaning I have to press F11 twice to get to the next line. which is really strange. Can someone please explain why is this happening?

 

 

 

 

and Here is the code:-

namespace Engine.AI.Pathfinding
{
    class AstarJob
    {
        internal Astar aStar;
        internal int JobNumber;

        internal AstarJob(Node StartingNode, Node TargetNode, Map map, bool DisableDiagonalPathfinding, int JobNumber)
        {
            this.JobNumber = JobNumber;
            aStar = new Astar(StartingNode, TargetNode, map, DisableDiagonalPathfinding);
        }
    }

    class AstarResult
    {
        internal List<Vector2> Path;
        internal int JobNumber;

        internal AstarResult(List<Vector2> Path, int JobNumber)
        {
            this.Path = Path;
            this.JobNumber = JobNumber;
        }
    }

    public class AstarManager
    {
        static List<AstarJob> AstarJobsList;
        static List<AstarResult> AstarResultList;

        Thread UpdateThread;

        public AstarManager()
        {
            AstarJobsList = new List<AstarJob>();
            AstarResultList = new List<AstarResult>();

            UpdateThread = new Thread(new ThreadStart(Update));
            UpdateThread.IsBackground = true;
            UpdateThread.Priority = ThreadPriority.Highest;
            UpdateThread.Start();
        }

        public static void AddNewPath(Node StartingNode, Node TargetNode, Map map, bool DisableDiagonalPathfinding, int JobNumber)
        {
            for (int i = 0; i < AstarJobsList.Count; i++)
                if (AstarJobsList[i].JobNumber == JobNumber)
                    throw new ArgumentException("A job already exist with this JobNumber: " + JobNumber, "JobNumber");

            AstarJobsList.Add(new AstarJob(StartingNode, TargetNode, map, DisableDiagonalPathfinding, JobNumber));
        }

        public static List<Vector2> GetPath(int JobNumber)
        {
            for (int i = 0; i < AstarResultList.Count; i++)
                if (AstarResultList[i].JobNumber == JobNumber)
                    return AstarResultList[i].Path;
                    
            return new List<Vector2>();
        }

        public static bool IsJobDone(int JobNumber)
        {
            for (int i = 0; i < AstarResultList.Count; i++)
                if (AstarResultList[i].JobNumber == JobNumber)
                    return true;

            return false;
        }

        public static void RemoveJobResultAt(int JobNumber)
        {
            for (int i = 0; i < AstarResultList.Count; i++)
                if (AstarResultList[i].JobNumber == JobNumber)
                    AstarResultList.RemoveAt(i);
        }

        void Update()
        {
            while (true)
            {
                for (int i = 0; i < AstarJobsList.Count; i++)
                {
                    AstarJobsList[i].aStar.FindPath();
                    AstarResultList.Add(new AstarResult(AstarJobsList[i].aStar.GetFinalPath(), AstarJobsList[i].JobNumber));
                    AstarJobsList.RemoveAt(i);
                }
            }
        }
    }
}


Best way to follow a moving object

30 November 2014 - 07:27 AM

Hello everyone,

 

I have implemented an A* algorithm to find the shortest path between two static none moving points, and that works great. However if I use the same algorithm to find the shortest path between one point and another moving point(example of that is an enemy and a moving player) for multiple enemies, my FPS tanks from ~2000+ to 15 FPS or lower and the game starts to freeze every once and a while.

 

So what am I doing? and What is the problem?

 

Well, what i'm doing is I'm re-calculating the shortest path using A* every time the player moves from one node or cell to another. (I have a grid that contains 100X100 cells or nodes where each node or cell is 32x32 pixels). So each time the player moves by 32 pixels I re-calculate the path, which is very taxing and unnecessary. 

 

So that's what I am doing.

 

I did find one possible solution which is, I would only calculate the path from the enemy to the player once, and then whenever the player moves one node or cell I just add that node or cell to the already existing way point list. However that solution has one problem. Imagine if the player is not walking in a straight line, imaging he is walking in a zig-zag motion, if I add the same way points to the enemy path, the enemy will do the same zig-zag motion and will not walk in the shortest possible path which would be a straight line.

 

Like so:-

 

W4HrCY7.jpg

 

 

 

 

So Here is my question, What is the best possible way to make an enemy follow a player using the shortest path possible? And does it work on more than one enemy? by that I mean will your solution work in case of 10 enemies that are all following the player? will there be no massive FPS drop?

 

 

Thank you.


Collision detection problem

20 August 2014 - 09:59 AM

Hello, 
 
So I have two boxes, a blue box and a red box. The blue represents a player and the red box represent a wall. What I'm trying to do is, when the blue collide with the red box, the blue box should stop moving. This is working for the most part when the blue box collide with the red box from the left side. However its not working from the right side. I don't know how to fix it. Here is a video showing the problem.
 
 
and here is my code in the update function

if (PlayerRectangle.Intersects(BoxRectangle))
{
    if (Position.X + 32 >= BoxRectangle.X )
       Position.X = BoxRectangle.X - 32;
    else if (Position.X <= BoxRectangle.X + BoxRectangle.Width)
       Position.X = BoxRectangle.X + BoxRectangle.Width;
}

KeyboardState keyboardState = Keyboard.GetState();

if (keyboardState.IsKeyDown(Keys.W))
    Position.Y -= (float)(Speed * gameTime.ElapsedGameTime.TotalMilliseconds);

if (keyboardState.IsKeyDown(Keys.S))
    Position.Y += (float)(Speed * gameTime.ElapsedGameTime.TotalMilliseconds);

if (keyboardState.IsKeyDown(Keys.D))
    Position.X += (float)(Speed * gameTime.ElapsedGameTime.TotalMilliseconds);

if (keyboardState.IsKeyDown(Keys.A))
    Position.X -= (float)(Speed * gameTime.ElapsedGameTime.TotalMilliseconds);

PlayerRectangle = new Rectangle((int)Position.X, (int)Position.Y, (int)32, (int)32);

 

 

--------------------------------------------------------------------------------------------------------------------------------

[Update 22/8/2014]

Ok so I updated my code and I used this method to detect collision. But I still can not get rid of the stutter problem where the player goes into the wall if the user holds the keyboard key. Also there is another problem where if the player collide from the upper or bottom side of wall and then the user presses the right or left key, the player will jump in the opposite direction instead of sliding to the right or left.

 

here is the code:-

Vector2 Position;
Rectangle PlayerRectangle, BoxRectangle;
float Speed = 0.25f;

enum Direction { Up, Right, Down, Left };
Direction direction;

protected override void Update(GameTime gameTime)
{
    // Allows the game to exit
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
        this.Exit();

    KeyboardState keyboardState = Keyboard.GetState();

   if (keyboardState.IsKeyDown(Keys.Up))
   {
       Position.Y -= (float)(Speed * gameTime.ElapsedGameTime.TotalMilliseconds);
       direction = Direction.Up;
   }

   if (keyboardState.IsKeyDown(Keys.Down))
   {
       Position.Y += (float)(Speed * gameTime.ElapsedGameTime.TotalMilliseconds);
       direction = Direction.Down;
   }

   if (keyboardState.IsKeyDown(Keys.Right))
   {
       Position.X += (float)(Speed * gameTime.ElapsedGameTime.TotalMilliseconds);
       direction = Direction.Right;
   }

   if (keyboardState.IsKeyDown(Keys.Left))
   {
        Position.X -= (float)(Speed * gameTime.ElapsedGameTime.TotalMilliseconds);
        direction = Direction.Left;
    }

    if (PlayerRectangle.Intersects(BoxRectangle))
    {
         if (direction == Direction.Right)
             Position.X = BoxRectangle.Left - PlayerRectangle.Width;
         else if (direction == Direction.Left)
             Position.X = BoxRectangle.Right;

         if (direction == Direction.Down)
             Position.Y = BoxRectangle.Top - PlayerRectangle.Height;
         else if (direction == Direction.Up)
             Position.Y = BoxRectangle.Bottom;
     }

     PlayerRectangle = new Rectangle((int)Position.X, (int)Position.Y, (int)32, (int)32);

     base.Update(gameTime);
}

and here is the video

 

--------------------------------------------------------------------------------------------------------------------------------

[Update 23/8/2014]

 

finally I fixed all my issues, I just wanted to share my final code.

Vector2 Velocity, Position;
Rectangle PlayerRectangle, BoxRectangle;
float Speed = 0.01f;

protected override void Update(GameTime gameTime)
{
     // Allows the game to exit
     if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
         this.Exit();

     KeyboardState keyboardState = Keyboard.GetState();

     if (keyboardState.IsKeyDown(Keys.Up))
         Velocity.Y -= (float)(Speed);
     else if (keyboardState.IsKeyDown(Keys.Down))
         Velocity.Y += (float)(Speed);
     else
         Velocity.Y = 0;

     if (keyboardState.IsKeyDown(Keys.Right))
         Velocity.X += (float)(Speed );
     else if (keyboardState.IsKeyDown(Keys.Left))
         Velocity.X -= (float)(Speed);
     else
         Velocity.X = 0;

     if (PlayerRectangle.Intersects(BoxRectangle))
     {
         float rightEdgeDistance = BoxRectangle.X - (Position.X + PlayerRectangle.Width);
         float leftEdgeDistance = BoxRectangle.X + BoxRectangle.Width - Position.X;

         float TopEdgeDistance = BoxRectangle.Y - (Position.Y + PlayerRectangle.Height);
         float BottomEdgeDistance = BoxRectangle.Y + BoxRectangle.Height - Position.Y;


         float Left_Right_SmallerDistance = Math.Min(Math.Abs(rightEdgeDistance), Math.Abs(leftEdgeDistance));
         float Top_Bottom_SmallerDistance = Math.Min(Math.Abs(TopEdgeDistance), Math.Abs(BottomEdgeDistance));

         float smallerDistance = Math.Min(Math.Abs(Left_Right_SmallerDistance), Math.Abs(Top_Bottom_SmallerDistance));

         if (smallerDistance == Math.Abs(leftEdgeDistance))
         {
              Position.X = BoxRectangle.X + BoxRectangle.Width;
              Velocity.X = 0;
         }
         else if (smallerDistance == Math.Abs(rightEdgeDistance))
         {
              Position.X = BoxRectangle.X - PlayerRectangle.Width;
              Velocity.X = 0;
         }
         else if (smallerDistance == Math.Abs(BottomEdgeDistance))
         {
              Position.Y = BoxRectangle.Y + BoxRectangle.Height;
              Velocity.Y = 0;
         }
         else if (smallerDistance == Math.Abs(TopEdgeDistance))
         {
              Position.Y = BoxRectangle.Y - PlayerRectangle.Height;
              Velocity.Y = 0;
         }
     }

     Position += new Vector2((float)(Velocity.X * gameTime.ElapsedGameTime.TotalMilliseconds), (float)(Velocity.Y * gameTime.ElapsedGameTime.TotalMilliseconds));
     PlayerRectangle = new Rectangle((int)Position.X, (int)Position.Y, (int)32, (int)32);

     base.Update(gameTime);
}

smoth fog of war

28 March 2014 - 03:51 AM

Hello everyone,

 

so for the past few days i have been implementing fog of war mechanics to my game. and i made it work, which is nice. But i did not feel satisfied with the way it looked.

 

So here is my question. how can I have a smother fog of war that looks like this?

 

81b3509eb5db0dcc2875a43f5e9f3989.jpg

 

this is how i implemented. I made a 512x512 map with a 32x32 tile size. i filled the map with a black tile and i set all the cells in my map to unexplored. when a unit moves through the map, I set that cell to explored and I stop rendering the black tile in that particle cell of the map.

 


PARTNERS