123
-=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- (c) WidthPadding Industries 1987 0|24|0 -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=-
Socoder -> C/C++/C#/Other -> Math woes, again!

Fri, 04 Mar 2022, 15:26
Afr0

Math woes, again!


So, a long time ago I made some hardcoded calculations in my code, which now have apparently come back to bite me.

Is there any reason why this:



would work with textures that have the dimention 100x25 but not with textures that have the dimention 560x210, where m_SourcePosition is used like this?



I'll try to explain - m_SourcePosition is passed to the Draw function in order to create a rectangle that determines which part of the image is being drawn. Clear?

Please help!

-=-=-
Afr0 Games

Project Dollhouse on Github - Please fork!
Fri, 04 Mar 2022, 15:48
Jayenkai
I'm struggling to follow.
What exactly are you trying to do?

In my head I'm assuming you have a texture "spritesheet" of, let's say 1024x1024, and you need the 0.0-1.0 floats of the position from say 256 pixels across to 512 pixels across..? Is that sort of what you're after?

-=-=-
''Load, Next List!''
Fri, 04 Mar 2022, 16:13
Afr0
Yes, I have spritesheets with 4 sprites on them, one for each button state.
The problem is that (of course, because Maxis made inconsistency into an art form) most of the sprite sheets are 100x25 pixels, but now I’ve run across one that is 560x210.
As you can see I’m using m_SourcePosition to determine which part of the image is being drawn at any given time.

-=-=-
Afr0 Games

Project Dollhouse on Github - Please fork!
Fri, 04 Mar 2022, 16:58
Jayenkai
Is the "sprite"/tile/whatever on the sheet always the same size, or is it always the same percentage of the sheet?

As in, when the sheet is larger, are the sprites bigger, too, or is it made up of more of the same sized smaller sprites?

-=-=-
''Load, Next List!''
Fri, 04 Mar 2022, 17:17
Afr0
The sprites are bigger in the larger sheet!
Fri, 04 Mar 2022, 18:10
Jayenkai
Woot!

All you should have to do then, is split the co-ords into floating point numbers. (Eg U/V texture co-ords)
Your first button should be 0 to 0.2499
The next 0.25 to 0.4999
And so on..
Essentially (1/Frames) * WhichImage to ( (1/Frames) * (WhichImage+1))-0.0001

If you need those as pixel co-ords, then take that floating point value and multiply it by the width.

So, if you have 5 frame on a 1024 sheet, the third icon would be at 3*(1/5) * 1024, giving you 614.4
You'll have to decide on how best to cope with the floating point values, more than likely do a Floor(float).

If you're still having issues, double check that floats are floats and ints are ints. Those will likely be the points they're tripping up.

-=-=-
''Load, Next List!''
Sun, 06 Mar 2022, 15:06
Afr0
Ok so I tried your suggestion, it doesn't seem to work



-=-=-
Afr0 Games

Project Dollhouse on Github - Please fork!
Sun, 06 Mar 2022, 15:17
Afr0
I tried this too, but it doesn't appear to be working either



-=-=-
Afr0 Games

Project Dollhouse on Github - Please fork!
Sun, 06 Mar 2022, 15:29
Jayenkai
Are your co-ordinates in pixels, or a floating 0.0->1.0f amount? (Sprites tend to use pixels, whilst textures typically use a float amount)
If it's 0.0->1.0, then leave out the * Image.Texture.Width

Also, experiment with it a bit. My Maths is almost never correct on the first go, especially when I don't have a way to play about with it!

-=-=-
''Load, Next List!''
Mon, 07 Mar 2022, 13:09
shroom_monk
I'm not a C# expert, but if its handling of numeric types works anything like C++, then the problem could be that you're trying to do fractional maths with integers and getting caught out by rounding.

Consider your most recent code snippet:


Looking at the (1 / 4) bit: both 1 and 4 are integers, so dividing them will also give an integer. So (1 / 4) will evaluate to 0, *not* 0.25. Thus your code is equivalent to:


Which simplifies to:


So will always calculate as, regardless of the value of Image.Texture.Width:


Which doesn't seem like what you want!

To fix this, make sure the values themselves are the types you want to use. Note that casting to double on the outside doesn't help: that just casts the final integer result to a double, but the rounding error has already occurred at that point!

Does the following work, which is mathematically equivalent but should avoid problems with types?


-=-=-
A mushroom a day keeps the doctor away...

Keep It Simple, Shroom!
Mon, 07 Mar 2022, 13:27
shroom_monk
All that being said, given that the code I've given at the end is similar to the code you started with, presumably that alone isn't the solution.

I'm struggling to follow what your code is intending to do, but questions that jump out at me are:

What is the initial value of m_SourcePosition before the Update function is called? Several branches of your code adjust its value with += or -= rather than assigning a value directly, so the behaviour there will depend on the value of m_SourcePosition beforehand. If nothing is setting that value beforehand, then you'll be changing the value every frame, which doesn't seem like the intended behaviour!

What does m_Size represent? It's a pretty vague name. Size of the spritesheet? Size of a single sprite? Size of something else? Maybe this would be obvious in the context of the entire class, but for the snippet provided it makes it hard to tell whether what is being done is intentional or not.

Have you tried stepping through the code in a debugger line by line, inspecting the variables, and seeing if they contain the values you expect? Alternatively, draw their values to the screen as some kind of debug overlay? In my experience that's a very quick way of determining where the calculations you've programmed aren't meeting your expectations.

-=-=-
A mushroom a day keeps the doctor away...

Keep It Simple, Shroom!
Tue, 08 Mar 2022, 14:16
Afr0
Thanks for the help shroom!
I should have been more specific!
Jay's code works, it displays the frame of the sprite sheet when it is initialized. But the "animation" isn't working. I suspect that's because I'm doing this in the update method:



Any idea how to fix this?




shroom_monk. m_Size is, as the name suggests, the size of the button itself. I.E the size of a single sprite in the spritesheet, so it's being initialized to Image.Texture.Width / 4

-=-=-
Afr0 Games

Project Dollhouse on Github - Please fork!
Wed, 09 Mar 2022, 17:25
shroom_monk
My main suspicion is your various m_SourcePosition.X += m_Size.X; and m_SourcePosition.X -= m_Size.X; lines. The results of these calculations depend on whatever the previous value of m_SourcePosition was, which makes it hard to reason about the behaviour as the behaviour is affected by previous frames. Hence why I was asking what the value of m_SourcePosition is before each call to Update.

The many possible branching paths in this function also make it hard to reason about, so I'm not sure whether there is a way you could get multiple additions or subtractions in a way that would give invalid values. But even if there isn't, that complexity is a problem in-and-of-itself because it's hard to debug!

So, to make this code more robust and easier to narrow down the problem, I'd suggest replacing all the m_SourcePosition.X += m_Size.X; and m_SourcePosition.X -= m_Size.X; lines with m_SourcePosition.X = whatever - i.e. set the value explicitly to a known good value, rather than assuming that the old value can safely be accumulated upon.

If that still doesn't fix it then that probably means that your many branching paths aren't doing what you want them to. There's nothing obviously wrong by eye, but I'm not familiar with the button behaviour you're trying to emulate. In that case, you best bet is to stick logging in each branch and see what that reports as you interact with the button.

-=-=-
A mushroom a day keeps the doctor away...

Keep It Simple, Shroom!