Saturday, February 23, 2013

Mouse Scrolling and Terrain

I’ve added mouse scrolling.  One thing to be careful of when using OIS is to ensure you initialise the window size to the mouse input object as well as on resizing the window (you can make your class a listener and then implement the SetWindowExtent method).  Generally, I’m not intending this blog to be a tutorial but I’ll just say for Ogre 1.8x and the associated OIS plugin:

//set up mouse state properly
//make sure to set up mouse state for all other listeners as well
unsigned int width, height, depth;
int top, left;
m_hWnd->getMetrics(width, height, depth, left, top);
const OIS::MouseState &ms = m_nMouse->getMouseState();
ms.width = width;
ms.height = height;


Do that in your init function (or constructor, it depends if your coding paradigm is that you try to do less in the constructor out of fear of throwing an exception there because that would totally hose any C++ code).

Anyway, it detects whether you’re at the edge of the screen and then moves the camera if so.  Nothing terribly difficult.

I’m using the absolute position of the mouse in order to determine the distance of the point to any particular edge.  So my code looks something like...

if( evt.state.Y.abs > (m_iWndHeight - edgeDistance) )
{
m_bIsMouseGoingDown = true;
}
else
{
m_bIsMouseGoingDown = false;
}


So from here what I can tell you is that... OIS is a bit confusing to me because it doesn’t seem to use cartesian coordinates the way you should be using it.  A higher Y value is more “down”, so the 0,0 point is in the top left corner and it goes more positive as you move toward the bottom right corner.  Not very intuitive but oh well.


Note: I ran into an interesting issue with OIS on Ogre 1.8 sdk. Basically I would get to the gameplay state and then the slightest hand twitch would cause mouse scrolling to occur and then after a few moments of this, the problem would go away.

The issue? I think that the absolute value coordinates somehow get reset to 0,0 which causes all sorts of havoc for my cameraManager. At the very beginning of execution it believes that it is at 0,0 and thus scrolls.

Solution? I basically "injected" the mouse position when I switched into the gameplay state so that it had a known value.


if(STATE_GAME == gameState)
{
OIS::MouseState &mutableMouseState = const_cast<OIS::MouseState &>(m_nMouse->getMouseState());
mutableMouseState.X.abs = m_nCamera->getViewport()->getActualWidth() / 2;
mutableMouseState.Y.abs = m_nCamera->getViewport()->getActualHeight() / 2;
}

Now it does what I call "scrollgood".

***

Abusing the z-order rendering of Ogre3d.

The Cultura game world consists of water, people, resources, structures and so on.  The question is how to render it to look “nice”.  For instance, if you build a hut in front of a tree but there is another tree in front of it then it should be rendered such that the house blocks the back tree and the front tree blocks a bit of the view of the house.

For now, let’s forgot occlusion culling (where completely blocked objects are not rendered but actually this one is tricky because units should have outlines visible, whereas non-units aren’t important except maybe resources).

Basically, after a little thought and discussion with a friend (he’s working on a Megaman-style game), what is important is the y-coordinate.  The higher value the y-coordinate in the visible area, the lower the z-coordinate to utilise Ogre3d’s automatic rendering according to z-plane ordering.  And similarly, I will have layers per square, where water is the lowest and so on, so that grass is blocked by bushes which is blocked by trees etc.  

The idea is that any object is placed in a square such that the coordinates are (actual numbers used aren't the same):

(x, y, -y * 0.005 + layer * 0.001)

And the layers are:

  • Layer 0: Water or Terrain
  • Layer 1: Grass
  • Layer 2: Bushes
  • Layer 3: Trees
  • Layer 4: Units
  • Layer 5: Structures

This should render all objects in the correct order and uses the z-plane to put stuff in front of each other properly.  Textures will probably be 32-bit png files with transparency so that I can just slap quads on top of each other to draw out a person, their clothing and equipment.


***

Okay so what point is the game at now?

Visually speaking, it is still donkey balls. I created a few new textures by hand in Gimp for testing use. Basically, I have coded out the terrain portion of the game state. ResourceManager loads up all necessary meshes for my test run. Then I start up a new game it creates a new map for me.

There's nothing but grass, trees and bushes there. Oh and a small pool of water. Those are all actual resources, they just look somewhat flat. Now, I took a look at what Gnomoria looks like (and I'm aiming for that level of graphics for the first release whenever that is), and their trees appear to "breach" into 4 squares of terrain. I may do the same to get a similar look (in addition to rotating the land to look nice and isometric).

Here is a picture of the resources in all of its glory. Normally most professional game studios try to refrain from showing these earliest images of game development because it makes the game look bad. Meh.


Just to tell you what you are looking at. The yellow worm things are "wild wheat". The red dotted green blobs are "strawberry bushes". And then the malformed trees are... "trees". Oh and the blue splotch is a pool of water. All of these are resources that you can collect, and they all do have values here. There's just no units yet to collect anything.

1 comment: