Register    Login    Forum    Search    FAQ

Board index » Everything




Post new topic Reply to topic  [ 39 posts ]  Go to page Previous  1, 2, 3, 4  Next
Author Message
 Post subject: Re: Attack on the Forest
 Post Posted: July 29th, 2017, 8:23 pm 
 

Joined: February 28th, 2013, 3:23 am
Posts: 2782
Location: Oklahoma, United States
Code:
bool User::Move( MainWindow& wnd, float dt )
{
   // More descriptive variable name
   bool isMoving = false;

   // Determine state
   if( wnd.kbd.KeyIsPressed( 'W' ) )
   {
      isMoving = true;
      if( wnd.kbd.KeyIsPressed( 'A' ) )
      {
         Direction = DIRSTATE::NORTHWEST;
      }
      else if( wnd.kbd.KeyIsPressed( 'D' ) )
      {
         Direction = DIRSTATE::NORTHEAST;
      }
      else
      {
         Direction = DIRSTATE::NORTH;
      }
   }
   else if( wnd.kbd.KeyIsPressed( 'S' ) )
   {
      isMoving = true;
      if( wnd.kbd.KeyIsPressed( 'A' ) )
      {
         Direction = DIRSTATE::SOUTHWEST;
      }
      else if( wnd.kbd.KeyIsPressed( 'D' ) )
      {
         Direction = DIRSTATE::SOUTHEAST;
      }
      else
      {
         Direction = DIRSTATE::SOUTH;
      }
   }
   else if( wnd.kbd.KeyIsPressed( 'A' ) )
   {
      isMoving = true;
      Direction = DIRSTATE::WEST;
   }
   else if( wnd.kbd.KeyIsPressed( 'D' ) )
   {
      isMoving = true;
      Direction = DIRSTATE::EAST;
   }

   // Early exit if not moving
   if( !isMoving ) return false;

   // Handle current state
   switch( Direction )
   {
      case User::DIRSTATE::WEST:
         usrvec.x -= ( Speed * dt );
         break;
      case User::DIRSTATE::EAST:
         usrvec.x += ( Speed * dt );
         break;
      case User::DIRSTATE::NORTH:
         usrvec.y -= ( Speed * dt );
         break;
      case User::DIRSTATE::SOUTH:
         usrvec.y += ( Speed * dt );
         break;
      case User::DIRSTATE::NORTHWEST:
      {
         const auto deltaMove = sqrtf( Speed * dt );
         usrvec.y -= deltaMove;
         usrvec.x -= deltaMove;
         break;
      }
      case User::DIRSTATE::NORTHEAST:
      {
         const auto deltaMove = sqrtf( Speed * dt );
         usrvec.y -= deltaMove;
         usrvec.x += deltaMove;
         break;
      }
      case User::DIRSTATE::SOUTHWEST:
      {
         const auto deltaMove = sqrtf( Speed * dt );
         usrvec.y += deltaMove;
         usrvec.x -= deltaMove;
         break;
      }
      case User::DIRSTATE::SOUTHEAST:
      {
         const auto deltaMove = sqrtf( Speed * dt );
         usrvec.y += deltaMove;
         usrvec.x += deltaMove;
         break;
      }
   }

   // If program makes it this far, isMoving will be true
   return isMoving;
}


I would do something like this really.

Separate the code that determines state and the handling of the current state.

With it separated, you could put all the "determine state" code in a private function that returns a bool and a "handle state" private function that handles the current state. I personally believe that separation of responsibilities is a good idea, especially for debugging.

_________________
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com


Top 
 Profile  
Reply with quote  
 Post subject: Re: Attack on the Forest
 Post Posted: July 29th, 2017, 8:28 pm 
 

Joined: February 28th, 2013, 3:23 am
Posts: 2782
Location: Oklahoma, United States
Ex:
Code:
ool User::Move( MainWindow& wnd, float dt )
{
   const bool isMoving = DetermineState( wnd.kbd );

   // Early exit if not moving
   if( !isMoving ) return false;

   HandleState( dt );

   // If program makes it this far, isMoving will be true
   return isMoving;
}

bool User::DetermineState( Keyboard & kbd )
{
   // More descriptive variable name
   bool isMoving = false;

   // Determine state based on input
   if( kbd.KeyIsPressed( 'W' ) )
   {
      isMoving = true;
      if( kbd.KeyIsPressed( 'A' ) )
      {
         Direction = DIRSTATE::NORTHWEST;
      }
      else if( kbd.KeyIsPressed( 'D' ) )
      {
         Direction = DIRSTATE::NORTHEAST;
      }
      else
      {
         Direction = DIRSTATE::NORTH;
      }
   }
   else if( kbd.KeyIsPressed( 'S' ) )
   {
      isMoving = true;
      if( kbd.KeyIsPressed( 'A' ) )
      {
         Direction = DIRSTATE::SOUTHWEST;
      }
      else if( kbd.KeyIsPressed( 'D' ) )
      {
         Direction = DIRSTATE::SOUTHEAST;
      }
      else
      {
         Direction = DIRSTATE::SOUTH;
      }
   }
   else if( kbd.KeyIsPressed( 'A' ) )
   {
      isMoving = true;
      Direction = DIRSTATE::WEST;
   }
   else if( kbd.KeyIsPressed( 'D' ) )
   {
      isMoving = true;
      Direction = DIRSTATE::EAST;
   }

   return isMoving;
}

void User::HandleState( float dt )
{
   switch( Direction )
   {
      case User::DIRSTATE::WEST:
         usrvec.x -= ( Speed * dt );
         break;
      case User::DIRSTATE::EAST:
         usrvec.x += ( Speed * dt );
         break;
      case User::DIRSTATE::NORTH:
         usrvec.y -= ( Speed * dt );
         break;
      case User::DIRSTATE::SOUTH:
         usrvec.y += ( Speed * dt );
         break;
      case User::DIRSTATE::NORTHWEST:
      {
         const auto deltaMove = sqrtf( Speed * dt );
         usrvec.y -= deltaMove;
         usrvec.x -= deltaMove;
         break;
      }
      case User::DIRSTATE::NORTHEAST:
      {
         const auto deltaMove = sqrtf( Speed * dt );
         usrvec.y -= deltaMove;
         usrvec.x += deltaMove;
         break;
      }
      case User::DIRSTATE::SOUTHWEST:
      {
         const auto deltaMove = sqrtf( Speed * dt );
         usrvec.y += deltaMove;
         usrvec.x -= deltaMove;
         break;
      }
      case User::DIRSTATE::SOUTHEAST:
      {
         const auto deltaMove = sqrtf( Speed * dt );
         usrvec.y += deltaMove;
         usrvec.x += deltaMove;
         break;
      }
   }
}

_________________
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com


Top 
 Profile  
Reply with quote  
 Post subject: Re: Attack on the Forest
 Post Posted: July 29th, 2017, 8:46 pm 
User avatar

Joined: February 14th, 2017, 7:32 pm
Posts: 170
Will definitely do that!. Separating what causes states and what states cause is probably a good idea.

I've got a question on that, should I have the functions that cause states and those where states cause stuff both be called in Update, or should I separate that into two subfunctions. If anything, the changes to states should happen first though. Some functions might need to work in pairs though, because some states might need the output from other states to be triggered, which means they have to be called first.

Thanks for the feedback and for writing the example code, I really appreciate it! :D


Top 
 Profile  
Reply with quote  
 Post subject: Re: Attack on the Forest
 Post Posted: July 29th, 2017, 10:32 pm 
 

Joined: February 28th, 2013, 3:23 am
Posts: 2782
Location: Oklahoma, United States
Yes, usually determining state will come first. There are probably going to instances where during handling state, you'll want to change state, or better yet make those conditions part of determining the current state.

My advice would be, write the code in a way that makes sense, then refactor the code to fit with using states.

Edited because the original post was done on phone.

_________________
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com


Top 
 Profile  
Reply with quote  
 Post subject: Re: Attack on the Forest
 Post Posted: July 29th, 2017, 11:05 pm 
 

Joined: February 28th, 2013, 3:23 am
Posts: 2782
Location: Oklahoma, United States
Here's an example of needing to rely on external state.

Say you want to write an AI that obeys traffic lights. In the US, Red is Stop, Yellow is proceed with caution ( not speed up like some believe lol ) and Green means Go. The AI would need to know the color of the light to determine it's own state. There could be other factors that the AI would need to stop for, not just the Red light, like pedestrian crossing the road or player cutting the AI off or just maybe a long line of cars even after the light is green.

You could write a function that takes in a trafficlight, another function that takes in a vector of pedestrians and another function that takes in a vector of cars and other functions that take in whatever else you want the AI to consider. You could make things more abstract by having the AI aware of all objects it needs to interact with and hold a Car object. The AI would call a Car::ChangeState function passing in a Car::State enum that says whether the car should be in the drive state or the stopped state. Then you just call car.Update( dt ) and let the car do whatever it needs for the current state.

In this case, you have a controller (the AI or the player) and the model ( the car ). The contoller handles external state, the model handles internal state. In this configuration, you can have a Human controller that handles the mouse/keyboard/gamepad inputs and changes the state of the car like, ChangeState( Car::State::Stop ) which will internally, the Car::Update for that Stop state apply the breaks ( acceleration in reverse direction ) and when the car speed is 0, changes the state to Car::Stopped.

_________________
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com


Top 
 Profile  
Reply with quote  
 Post subject: Re: Attack on the Forest
 Post Posted: July 30th, 2017, 5:35 pm 
User avatar

Joined: February 14th, 2017, 7:32 pm
Posts: 170
Thank you for the info!
I tried adding your modified framework to my stuff Albino, but it only removed my User.cpp file for some reason and conflicted with my Vec2 class. I can store my Vec2 class in a different file, so that shouldn't be a problem anymore. Also, would _Vec2 and Vec2 as class names conflict with eachother? I've heard some technical stuff happens with _ before variable names as such. Anyways will try again and then report back.

Edit: It just destroyed my "MyVector.cpp" file. Dragging the files in engine from Albino's thing to mine didn't seem to quite do it. I should probably retarget Albino's version before sliding it over to mine.


Last edited by Zedtho on July 30th, 2017, 8:01 pm, edited 4 times in total.

Top 
 Profile  
Reply with quote  
 Post subject: Re: Attack on the Forest
 Post Posted: July 30th, 2017, 5:49 pm 
 

Joined: February 28th, 2013, 3:23 am
Posts: 2782
Location: Oklahoma, United States
Nah, it's just a prefix. nothing special about the under score. Having a leading underscore for the template version allows you to alias the class with the more familiar Vec2.

You cam alias a type like so:
Old way, typedef _Vec2<float> Vec2;
New way, using Vec2 = _Vec2<float>;

_________________
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com


Top 
 Profile  
Reply with quote  
 Post subject: Re: Attack on the Forest
 Post Posted: July 30th, 2017, 6:11 pm 
 

Joined: February 28th, 2013, 3:23 am
Posts: 2782
Location: Oklahoma, United States
Just wanted to add that if you look at the bottom of Vec2.h, you'll see the aliases for _Vec2.

Code:
typedef _Vec2<float> Vec2;
typedef _Vec2<double> Ved2;
typedef _Vec2<int> Vei2;

using Vec2f = Vec2;
using Vec2i = Vei2;
using Vec2d = Ved2;

The typedefs are part of chili's implementation, and the bottom three are ones I added. The bottom three should have been
Code:
using Vec2f = _Vec2<float>;
using Vec2d = _Vec2<double>;
using Vec2i = _Vec2<int>;

Instead of replacing the originals, I kept them, so I could be lazy and wouldn't have to find and replace places where they were used.

_________________
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com


Top 
 Profile  
Reply with quote  
 Post subject: Re: Attack on the Forest
 Post Posted: July 31st, 2017, 7:52 am 
User avatar

Joined: February 14th, 2017, 7:32 pm
Posts: 170
Oh ok, thanks for clearing that up.

By the way, I added your stuff! Next up is exploring how to use it :D.

Just something I noticed, my character square moves very slowly all of the sudden in Debug mode, even though it's not using any of the new files I added (yet). I should rephrase that, it seems like it's skipping frames, and my square teleports to where it should be (thank goodness for chrono support :D). I'm not sure why this is happening, because I have only added your files to my solution, not embedded it in to my program (yet), so it shouldn't change anything to make it slower. I should add that this wasn't happening before I added the files in Debug mode.


Top 
 Profile  
Reply with quote  
 Post subject: Re: Attack on the Forest
 Post Posted: July 31st, 2017, 10:12 am 
 

Joined: February 28th, 2013, 3:23 am
Posts: 2782
Location: Oklahoma, United States
Yes, the issue is the BeginFrame that I changed in Graphics.
In the original chili framework, he uses a function called memset. Everything is set to 0, really fast. The downside is you aren't able to clear the background to a specific color, only shades of grey ( from 0 to 255 ). If you want to go back to more performance:
Code:
void Graphics::BeginFrame( Color C )
{
   // clear the sysbuffer
   //pSysBuffer.Fill( C );
   pSysBuffer.Clear();
}

Change the code to what you see here. This uses the original memset, though it uses my aligned_ptr class to do so. This will clear the background to black ( all 0's ). If you wanted to clear to a specific color, you'd use the Fill function.

_________________
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com


Top 
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
 
Post new topic Reply to topic  [ 39 posts ]  Go to page Previous  1, 2, 3, 4  Next

Board index » Everything


 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
cron