Well, I think it's not going to be implemented officialy, but I would appreciate ideas on how to do it.
The first thing is the automatic layering or something like that. If I could just select part of the grh and change it to foreground and the other part to background, would be great. If I could make all grhs with a property on, to be foreground only on the first bottom 32 pixels, would be great too.
Another cool thing would be the shadows from vbgore
!
And it's possible to do something like "partitioning" textures on grhs, like on vbgore? Or better, select part of a image to put on the game, like rpg maker XP? (this would solve the layering problem too) I know it's not really a topdown improvement btw.
It would be cool if we could "fill" a map with a grh too, like on rpg maker.
If I discover how to do something, I will try to make a tutorial with my strange english
!
Thanks.
The devkit aPhRo is making will have a Topdown map editor but he told me it won't be ready until September.
Hahaha, that's really great! Thanks, I will try.
Hmmm, great too. If I get it working, maybe the tutorial can help aPhRo too (but don't expect too much from me ^^').
Edit:
Well, I added a property for the auto layering on map editor and on mapgrh class, and I believe the grhs are sent to be drawed here:
protected virtual void HandleDrawing(ISpriteBatch sb)
{
_grh.Draw(sb, Position, Color, SpriteEffects, Rotation, Origin, Scale);
}
on mapgrh class.
Then I was thinking... if I put an if on this function, that sees if the auto layering property is true, then I just need to draw 2 sprites, each with a different layer. The problem is that it's not senting the layer or the size of the sprite. The "origin", I believe, sets where the sprite start on the texture, but there is no parameter that send the height/width of the grh (so I cannot split it). Then I believe that I'm targeting the wrong function, maybe this only draws and there is another to set the grh to a layer? like the public void Draw(ISpriteBatch sb) on Map.cs? But where this function get's the layer to draw the grhs layer to layer? From that "ISpriteBatch sb"? The SpriteBatch is something like an array of mapgrhs D:?
I'm trying to understand the code, but it's really confusing o-O, and I'm guessing almost all the time. Someone can try to explain a little where the grhs are draw, where they are set to a layer, and maybe, how I can split a image on more than one grh?
I will keep trying anyway (but I'm going to study now).
Origin is the point on the sprite to rotate on. Position is the world (not screen!) position of the sprite and size is the... size.
What I was referring to was something more like on line 594 of the client's map:
http://www.netgore.com/docs/d1/d5d/a02503_source.html#l00594
That major loop in there loops over each layer:
foreach (var layer in _drawableSorter.GetSorted(drawableInView))
Then there is the inner loop that loops over each item in the layer:
foreach (var drawable in layer.Value)
Oh, it looks like I guessed it all wrong xD! Except about the public void Draw(ISpriteBatch sb) being related to the layers.
Thanks, I will keep trying.
Edit: Ok, IDK what to do o-o. My approach to split the grh isn't good, I think, because the map editor will start to see the autolayered grh as 2 different grhs. But I don't know what to do on the draw from the Map class, or on the layer sorter. Like, the sorter gets a "drawable" and add it to a layer, but how do I make this "drawable" be splitted to draw part on back and part on foreground? I think I'm not getting the concept.
I know, I'm really noob D:.
Sorry for keep bothering >_<
What I'd suggest is to just add a new layer and combine the character and item layers into that - say, the "Dynamic" layer. Then, instead of sorting those by depth, sort them on the Y-axis.
Oh, it makes sense now. I'm an idiot, I thought that the maps were draw just one time.
Thank you \o/!
Edit: Ok, I don't really understand, I think u-u. If I merge the items and characters layer, these layers will not keep in front of the background layer anyway? I tried to do something a little different then. I know, it's a really dirty code o-o
// Add all the drawables to their appropriate layer foreach (var drawable in drawables) { if ((int)drawable.MapRenderLayer == 1 || (int)drawable.MapRenderLayer == 2 || (int)drawable.MapRenderLayer == 3) { _layers[1].Add(drawable); }else{ _layers[(int)drawable.MapRenderLayer].Add(drawable); } } // Return the results for each layer, making sure to sort them as we return them for (var i = 0; i < _layers.Length; i++) { if (i == 1) { yield return new KeyValuePair<MapRenderLayer, IEnumerable<IDrawable>>((MapRenderLayer)i, _layers[i].OrderBy(x =>/*get the drawable y pos*/)); } else { yield return new KeyValuePair<MapRenderLayer, IEnumerable<IDrawable>>((MapRenderLayer)i, _layers[i].OrderBy(x => x.LayerDepth)); } }
What I'm trying to do, is put everything from character, item and background layers on the background layer, and then if the layer is 1 (the background, if the enum start with 0 o-o) it will sort by y. But there is no way to get the y pos of a drawable. And doing this, two background will "conflict" if they are on the same place and if I do not consider the depth (or maybe not, I just don't know).
I know that it probably is not going to work even if I find a way to find the drawable y anyway. I think the right way is merging only the character and item layers, but I don't understand how it will affect the background layer (and I will need to find the drawable y anyway, I think).
I will keep trying different strategies later \o/!
Leave the background layer there as it is already - you will want stuff to always be in the background (such as tiles).
I forgot IDrawable doesn't expose the position. You can probably cast it to ISpatial and get the position that way or something.
Understood now, so I just need to add the auto-layer tiles to the character+item layer, so I sort by y.
I will take a look on the ISpatial.
I hope this will be my last post before finishing it.
Thanks
OH GOSH!
IT WORKED!
Spodi, you are genius, I love you <3!
I'm going to make a tutorial, later, because nothing I do work as expected, so I'm expecting a bug or two o-o.
Like, the character y is a little bigger than where it's his foot, maybe that's because there is a empty space on the bottom of the character grh, but I'm just guessing, I will take a look.
And I was surprised that I could use (ISpatial)drawable and still could find the Y. I really don't understand how these conversion things works.
Thanks, thanks, thanks!
Edit: Ok, I think the y problem occurs because the y counts until the HP bar on the bottom of the character. It's not really a problem, I think, anyway.
Edit2: Like I said, nothing work as expected, and the old maps gives a "KeyNotFoundException". A XML error. I think that's because it's expecting to read a
No problem - glad you got it going.
For the conversion, what you are doing is casting to an interface. ISpatial is the interface for an object that takes up space on the map. Most all things you draw for the map will use this. But if it doesn't, it will crash. So to avoid that issue, what you will want to do is something like:
ISpatial s = myItem as ISpatial; if (s == null) { /* Does NOT implement ISpatial! Figure out some other way to handle this drawing. */ } else { /* Does implement ISpatial - "s" is valid */ }
The "as" casting operator is just like if you did:
ISpatial s = (ISpatial)myItem;
The difference is that "as" will give you a null value if myItem does not implement ISpatial, while the casting will throw an exception.
On a related note, there is the "is" operator, which returns a boolean value of whether or not the object implements the interface.
if (myItem is ISpatial) { /* myItem implements ISpatial */ } else { /* myItem does not implement ISpatial */ }
But like I said, most likely everything you are concerned about drawing in this dynamic layer will implement ISpatial. If it doesn't, a safe way to handle it without crashing randomly for the client would be to put a Debug.Fail(), which only shows errors in debug builds, and just don't draw it. That way, in debug mode, it gives you an error while in release mode it just shows nothing instead of taking down the whole program.
Oh, interesting, thanks for the explanation. In this case, do I need to be sure that the IDrawable implements the ISpatial or something like that?
And can I post a tutorial on how to do this here (editing this post)? Altought it works, I'm not sure that what I did is right and I'm sure there are more bugs, so I don't think it's a good idea to put on the wiki yet.
Yeah, you will want to check to make sure the object you are drawing implements ISpatial, since it is not guaranteed that IDrawable implements ISpatial. You'll want to do that any time you cast an object to a class or interface that you cannot be sure it implements.
And its fine if you put it on the wiki - just add a note stating that it is not fully stable and still being worked on.
Done, I updated the code to avoid the exception and created the tutorial ^^! Thanks again Spodi.
Oh, and don't be scared with my poorly written code =(! I need to read something about good programming practices.
Ooh, autolayer, thank you! I'll be adding this to SVO as well and let you know if we encounter any bugs ![]()
Ohh, that's great, glad I helped ^^. Btw, SVO is on the GBATemp news, congratz o/.
Now I changed the way the GrhCursor works, so when you press ctrl+alt it makes a selection box don't matter if you clicked on a grh. And so if you simply click on the grh it will show that list on the side with all grhs on that position too. I overrided the MapGrh ToString so the list shows the folder.grhname instead of the folder, so my major problems are almost fixed I think *-*. The problem is that it's hard to keep pressing cltr+alt everytime I want to select all the grhs on a position, but when I press shift and click, the code simply don't reach the MouseDown event, even the first line, even if I don't change anything.
Now I will try to think on how I can do the shadows, but I really appreciate some ideas ^^'. I will take a look on how the lights works btw.
I just realized - SFML might make the shadows a bit tough to do since SFML doesn't natively support the kind of transformations you'll want. That is, you just shift the top two points of the rectangle over about 50% (vbGORE style). Not sure how you'd do that in SFML without making a mess...
Oh gosh, if even you aren't sure on how to do this, nobody will D:!
I will forget the shadows, at last for a while, it's the least important thing anyway.
Thanks for all the help, I think that's all for now.
Oh, that's sad. But as I said, it's not really important I think, just a cool little thing. And it looks like that the developers are working on the library, so maybe on the future, like he said *-*!
Glad you cared about it, thanks as always.
The auto-shadows in vbGore looked terrible anyways. For 2d the shadows really need to be sprited, like in RMXP.
That's beside the point i guess, can't you access the OpenGL library directly in SFML?
The auto-shadows in vbGore looked terrible anyways. For 2d the shadows really need to be sprited, like in RMXP.
Other than the obvious issue it had with overlapping and improper placement, how was it bad? When it was working fine, I thought it looked fine.
That's beside the point i guess, can't you access the OpenGL library directly in SFML?
Yeah, and that is a possibility if you want it immediately, but its best to avoid those kinds of hacks when possible. Laurent seems fine with adding it to SFML 2.0, so its just a matter of waiting for it to come around.
Ok fair enough, it's just that sfml 2 doesn't seem like a "just around the corner" thing.
The shadows just looked really ugly from an artistic point of view. I dunno if a better algorithm could fix it, maybe it can.
Well all I could think of is if you applied a blur to it - that'd be simple enough.
And NetGore already uses SFML 2 dev builds, so its not a matter of when its released, but when it just gets added, which will likely be before anyone actually needs it in their game (that is, before public testing).
Ah I see.
It's more than that. This is what I mean by spriting shadows. I just think the programmed shadows look unnatural, you will never get light going through at the right angles and what not because its 2D. Like with VBgore its like the sun is setting 24/7, where as the suns rays should be shined from above, which means you can never get the right shadows, because you can't calculate factors in the image that don't exist.

I agree, that's only possible with 3D games I think. But I thought the vbGore shadows were good enough. They weren't perfect, they were just simulated shadows, and no matter what you do, on a 2d game they will never be "real" (only if you paint it yourself, but so the shadows will not change with the light positions). So "simulated" shadows are fine and the only type of shadows posible with programming, I think. And they are "unreal" on just a few cases and nobody will keep looking, because they don't even know how the shadows were suppose to be (they cannot see the sprite on more than one angle o-o').
some loq aulity shadows that react to camp fires etc, or fireballs dynamically would FULLY fulfill my needs...
and probably most peoples.
It gives quite some special effect, and that together with the dynamic lighting, well...
although shadows wouldnt even be a must for me.
dynamic lighting was a must though, and some cool shadows would really support it.
=> Dont go for shadows if its too much work that can be fixed by the SFML devs.
I would rather advance in othger areas in your position.
The shadows can be done later, and they mustn't even be too complex.
Shadows can be done, and unlike vbGORE, done properly. In fact, NetGore already uses a light map, so adding shadows would be pretty easy.
The layering thing would be easy enough, too, since NetGore sorts before rendering every frame. Just look for where the map's drawing takes place, and find the part where the sorter is called. Then just apply your own sorting to see how it works.