python-sfml icon indicating copy to clipboard operation
python-sfml copied to clipboard

Some bugs I found.

Open shredder004 opened this issue 11 years ago • 3 comments

First off, this is my first time in GitHub and I am not sure if this is the right way to do this. Second, I am very thankful for pySfml. Here are (I think) bugs that I found.

  1. Rectangle(1, 1, 1, 1) fails. I believe the doc says i can pass a tuple with 4 values. If this i not a bug, it would be nice to have this as an option to create a Rectangle.
  2. Rectangle.intersects(other_rect) does not work.
  3. Every time I subclass Sprite and I create a new SpriteSublcass instance, Sprite.cinit() is called before SpriteSubclass.init(), which means that to create a SpriteSubclass object, I have to pass it a texture. It would be nice if I can subclass Sprite without having to pass a texture to the subclass constructor.
  4. Sprite.position seems to be read-only. I believe this should be read and write. So is true with some sprite.rectangle.attribute

Hope this helps, really hoping for an update.

shredder004 avatar Jan 24 '14 12:01 shredder004

UPDATE: 5. I had a class subclass drawable and the same has a sprite attribute. Then inside my class' draw(), I wrote target.draw(self.sprite, stat) where "stat" should have been states. But there was not error message, the code kept running but the sprite was also not displayed in the window. 6. When I call Vector2((0, 0)), it sets x to (0, 0) and y to 0. Should this give an error or at least set x and y to 0? 7. For some reason, there are times that sf.Sprite.position does not have the same value as sf.Sprite.global_bounds.position.

shredder004 avatar Jan 25 '14 14:01 shredder004

@shredder004: I apologize for the horrible delay in responding to your concerns. I've been a bit inactive over the last couple of years, and as such am only now noticing this. If you notice a delay of more than a few days in the future, feel free to email me directly. In that case, I'll at least be able to explain why I'm unable to work on the issues, rather than leave you empty handed and wondering if you're being heard at all.

Ideally, unrelated issues should be separate issues, but as this is a smaller project, it isn't as much of a problem. Going forward, however, it'd be great if you could file separate issues so that we can track them separately.

Now onto your issues :-) :

1.This is b design and maps the official API, which takes vectors. In fact, allowing tuples to begin with was part of making the API easier to use from Python. That rectangle takes two tuples is covered in more detail in both the rectangle tutorial.

As for providing a version without tuples, I think we experimented with that a couple of years ago and decided on what you see today. Once @Sonkun is available we could re-evaluate and see if the cost of deviating from SFML's API even further for the sake of convenience is truly a benefit or detriment.

Until we're able to have that conversation, it shouldn't be too difficult to write a factory function or lambda to accomplish something similar:

rectangle = lambda x, y, w, h = Rectangle((x, y), (w, h))

2.Could you be more specific about what doesn't work? The following code works as the pysfml documentation suggests it should:

>>> import sfml as sf
>>> a = sf.Rectangle((0, 0), (50, 50))
>>> b = sf.Rectangle((25, 25), (50, 50))
>>> a.intersects(b)
Rectangle(left=25, top=25, width=25, height=25)

In other words, given two rectangles of the same size where rectangle a starts at (0, 0) and b starts at (25, 25), the intersection of those rectangles is a smaller rectangle that begins at (25, 25) and ends at (50, 50) (50 - 25 = 25, thus a width and height of 25).

3.This isn't my area of expertise, so forgive my ignorance here: is it not enough to call super after any customization you'd like to have? Even better, if you aren't needing to customize the initialization of your Sprite subclass, then by simply not overriding __init__, you should have the default behavior. If you you are meaning to have a default texture for each sprite, I'd suggest (again) using a factory function, which would be cleaner than sub-classing. If I've missed the point, then it might help if you provide a solid example (in a gist, perhaps), I could better understand your concerns.

4.Position is read-write. I just tested with the following which works fine on my system (Linux, 64bit, Python 2):

import sfml as sf

texture = sf.Texture.from_file("foo.jpg")

sprite = sf.Sprite(texture)
sprite.texture_rectangle = sf.Rectangle((10, 10), (50, 30))
sprite.color = sf.Color(255, 255, 255, 200)
sprite.position = sf.Vector2(100, 25)

window = sf.RenderWindow(sf.VideoMode(640, 480), "test")

while window.is_open:
    window.clear(sf.Color.BLUE)
    window.draw(sprite)
    window.display()
    sf.sleep(sf.seconds(2))
    sprite.position += sf.Vector2(20, 20)

Note that tuples may be passed where Vectors are used, so sprite.position += (20, 20) works as well.

5.I'd need a full code snippet to troubleshoot that properly. Please attach a minimal code example that produces the unexpected behavior.

6.This is expected behavior, though I'll agree that it's perhaps confusing. The Vector2 constructor essentially has defaults of 0, and otherwise passes it's first argument to x and its second argument to y. In your example, you've essentially declared a Vector2 of (Vector2, int), which, while uncommon, is valid. I think in the past I talked with @Sonkun about doing something similar to what you are requesting before understanding what I just explained.

With Python being a dynamic language, there is a general conconsensus that we are all consenting adults, I'm reluctant to add any type-specific constructors (such as Vector2i and Vector2f which were in the original Python bindings and are present in the C++ API), but I could be convinced otherwise. I'd even be willing to compromise by restricting input to numeric values, so long as an argument could be made that proved that other value types within Vectors are either non-existent or rare.

7.What you're experiencing could either be a result of the fact that Sprite.position is relative to the object's origin where as Sprite.global_bounds.position (as I understand it), is relative to the global coordinate system, or it could be a result of the fact that Sprite.global_bounds takes transformations into consideration, where as (I don't think), position does.

Thanks again for the report, and I'm sorry again about the delay.

AphonicChaos avatar Jun 29 '14 07:06 AphonicChaos

I know this issue is old af, but regarding 2, I get a segmentation fault when trying to use intersects with global_bounds in sprites:

>>> tex = sf.Texture.from_file('image.png')
>>> sprite1 = sf.Sprite(tex)
>>> sprite2 = sf.Sprite(tex)
>>> sprite1.global_bounds.intersects(sprite2.global_bounds)
Segmentation fault (core dumped)

Whereas the C++ implementation is like this:

sprite1.getGlobalBounds().intersects(sprite2.getGlobalBounds())

A temporary fix is to make two rects based on sprite.position, sprite.global_bounds.width, and sprite.global_bounds.height for both sprites and check if those intersect..

Update 2017-06-08, here's an example where it doesn't work with Rects:

>>> a = sf.Rect((-64.0, 0.0), (16.0, 24.0))
>>> a = sf.Rect((0.0, 0.0), (16.0, 24.0))
>>> b = sf.Rect((-64.0, 0.0), (16.0, 24.0))
>>> a.intersects(b)
Segmentation fault (core dumped)

So, yeah..

Necklaces avatar Jun 07 '17 15:06 Necklaces