? about mousing over objects in tile engine

Started by
6 comments, last by MarcusLM 23 years, 11 months ago
I am developing a pretty simple tile-based RPG game and I have a question about clicking on objects. My questions is what is the best way to check what the user is actually clicking on when you have several different layers? For example say I have a tile location 2,2, and in 2,2 there is the ground, a tree and an object that can be picked up. How should I determine what the has the mouse cursor over when the cursor moves into that location? Should I start at the highest layer and work my way down each time a tile location has the mouse cursor over it? Would this be too cumbersome?? I am trying to get the effect of when the mouse is over an object the object is outlined in a color. Like when you have the mouse over a creature or item in Diablo. Marcus
Advertisement
My method might sound ludicrous, but it works:

When drawing, I draw first the ground plane in one pass. Then I draw the objects in a second pass. (I do this because the objects roam free and are pixel placed, not tile placed). When I draw the objects, I draw them back to from. With each draw, I store the destination rect and a ptr to the sprite in a linked list. When someone clicks in the viewport, I go backwards (starting at the front of the viewport) through the list until I find a rectange that includes my mouse click point. When I do, I then go through the sprite that list node points to and check it pixel for pixel to see if my mouse click has hit it. If it hasn''t, I keep looking through the list until either I do find a hit or I find none. If I find none, I then assume the user was trying to click the "ground plane" and deal with that.

Every frame I reset my linked list (actually, I use a static array with a terminator so that I never have to new/delete during the frame) so that the items draw from back to front again.

Make sense?

If anyone has any ideas on improving this I''d like to hear them.

quote:Original post by Sphet
If anyone has any ideas on improving this I''d like to hear them.


One improvement might be to create this list only if necessary, e.g. after the map was scrolled. This might increase your FPS a bit.

Matt

quote:Original post by Sphet

If anyone has any ideas on improving this I''d like to hear them.



My guess is that the ting that takes time in your method is all the searching to be done in the lists. So why not use multiple smaller lists?

For example you could divide the screen into four quardrons. When the player clicks the mouse you can easily determine which quadron the cursor is in, and you only have to search through the list for that quadron. By doing this your list would be, by average, four times smaller.

Maybe you could take this to the extremes and have a list for each tile in the map? Or would that create to much memory overhead? Or too much trouble when moving objects from tile to tile?

Regards

nicba
the ideas brought forth by sphet are fine ideas, and similar to the way i do things myself.

i do have one suggestion for enhancing your solution, however.

you might also want to implement an array of pointers into your object list. this array would be filled each time the viewing area changes(by scrolling or whatever), and would contain pointers to objects that are ON SCREEN. this would make finding objects much faster, since you dont have to check through ALL of the objects (a mouse cannot be on an object that is not on screen, afterall)

also, you may want to divide your map into screen sized(or view area sized) "zones". you can then have an array for all of the objects in each of these "zones", and since your viewing area looks at no more than 4 zones at a time, you have to draw (or check for drawing) fewer objects.

Get off my lawn!

Just wondering, why don''t you use a binary search tree? The insertion takes a bit longer than a list, but the searching is far, far quicker.

Another idea, if you don''t mind doing the work for it... is to store object according to y-planes. For example, lets say you were drawing a huge tree that covered 4 tiles. Just insert the object into each y-plane list (probably 2). That way, when a user clicks on the map, you can immediately query which tile and look up the y-plane list for that y-plane only. If you have a 256x256 map, the searching would be astronomically faster (I think...), but the downside is the code is larger and harder to write. I guess the real question is... do you really want to put that much work into a simple "am i clicking on it?" event?

Just a couple ideas

random

---
Wait, you mean I have to actually... THINK?!
---Wait, you mean I have to actually... THINK?!
Thanks for some of the ideas.

With regards to using BSP''s to speed up the search, I thought through the needs and decided that, for once, insertion speed was more important than search speed. The player can only click in the viewport at a certain speed, certainly less than the time it takes to render the viewport. For that reason I would rather insert the objects faster than I can search for them.

With regards to storing only the on-screen objects, thats all I do. I guess I am going about things in a different order, but I "cull" the non-visible objects further upstream then my blitting engine, so non-visible objects never make it into my "object search list".

With regards to multiple zones, I do something similiar - my project uses a GUI to display the "world" in windows. When the player clicks anywhere, it first determines which window is being clicked in (a "zone" if you will) and then does the object search within that window.

Thanks for the ideas.
You might want to weight the selection mechanism. Arbitarly assign weights to objects (more imporant objects get picked when multiple object overlap, objects have bounding radius perhaps more than one if they are odd shaped, so players dont have to be so pixel perfect, etc). This will grealty increase the user appeal. The more intutive and flexbile the picking selection the less the user will have to think about it and it will speed up your game over all. Good luck.

-ddn

This topic is closed to new replies.

Advertisement