[pygame] Joystick no longer global in Pygame2?

7 views
Skip to first unread message

Alec Bennett

unread,
Jan 10, 2022, 1:05:21 PM1/10/22
to pygame...@seul.org
I'm testing Pygame 2 (under Ubuntu), and noticed a big change: the Pygame window now needs to have focus to catch joystick events. This wasn't the case in the previous Pygame version I was using (1.9.3).

For example if I run this script with Pygame 1.9.3, it catches all joystick events no matter what window has focus:


And if I have multiple Pygame windows, they all catch all the joystick events.

But with Pygame 2 the window needs focus to catch the joystick events.

If anyone wants to confirm, you can install Pygame 1.9.3 with the following command:

pip install pygame==1.9.3

Then to go back to latest version:

pip install pygame

Is there some way to make Pygame 2 catch joystick events globally? 

This was a very useful feature for me.



Charlie Hayden

unread,
Jan 11, 2022, 12:15:48 AM1/11/22
to pygame...@seul.org
Alec, this is actually a recent change I believe (after pygame 2.1), and comes from our SDL backend.

It's been discussed in this Github issue, and I believe they've got an environment variable that will do it. 

Irv Kalb

unread,
Feb 2, 2022, 12:58:15 AM2/2/22
to pygame...@seul.org
After about four years of work, my new book "Object-Oriented Python" is finally out!  It's now available at major booksellers including Amazon and through the publisher, No Starch Press. 

The purpose of the book is to explain the techniques involved in Object-Oriented Programming (OOP) but in a unique way. I use games and graphical user interface elements all built in pygame to demonstrate the key concepts. 

The book is an expanded version of a course that I developed and teach at two local universities (University of California Santa Cruz Extension and University of Silicon Valley). The book also includes links to two packages of code that readers and students can use in the development of Python programs. 



Irv

Nicholas H.Tollervey

unread,
Feb 2, 2022, 3:20:53 AM2/2/22
to pygame...@seul.org
Congratulations on the new book. I've done a few titles for O'Reilly and
know what hard work it is to get such stuff into print.

N.
> <https://lnkd.in/gf6aUQbe>
> <https://nostarch.com/object-oriented-python>
>
> Irv
OpenPGP_signature

René Dudfield

unread,
Feb 20, 2022, 12:47:09 PM2/20/22
to pygame...@seul.org
Yes, congrats!

Sounds like a fun way to learn/teach OO :)

Al Sweigart

unread,
Feb 24, 2022, 10:13:20 PM2/24/22
to pygame...@seul.org
Congratulations, Irv!

Irv Kalb

unread,
Mar 1, 2022, 6:10:01 PM3/1/22
to pygame...@seul.org
I am developing a game but I'm running into some cases where the game slows down too much. A few details ...

The game lives in a world whose size is much larger than what the user can see in the window. (For now, the world is 3000 x 3000, but the window is 640 x 640 - I could decide to change these later). There is a central player who is controlled by arrow keys. When the user presses a key or keys to move in a direction, the player is an animation that looks like its walking, but always stays in the center of the screen - the view in the window scrolls in the opposite direction. There are "enemies" that live in this world, new ones are generated all the time, and each moves semi-randomly in every frame. There are also a number of additional elements that must be drawn every frame (e.g., walls in a maze and more).

The game is complicated by the fact that the world wraps around both horizontally and vertically. If you move off the top, you show up at the bottom, go off the left and you appear on the right, etc. In my current version, in every frame I iterate through all drawable elements, and go through some coordinate checking code to determine if the element is visible within the window. This code is more complicated than a simple "colliderect()" because I have to account for the potential wrapping in all directions. If the element is within the viewable screen area, I draw it (blit), otherwise, I don't do the draw. I thought this would be a great optimization. But, I'm finding that as the number of enemies grows, the overall game slows down. I'm sure this has to do with the fact that in every frame I check their movement (they cannot go through walls), move each to a new location, and then decide whether to draw them or not.

I'm wondering if my code to check if an element is within the viewable area, is actually doing more work than not bothering to check at all. My question is really about the efficiency of a call to blit in pygame when the thing being drawn is outside the viewable area. I actually have done some minor tests, and the game seems to work a little better without doing the checking, but I want to get opinions from anyone who might really know.

I will probably wind up limiting the number of enemies, but it would be good to know about how efficiently pygame deals with potentially drawing outside the window.

Thanks in advance,

Irv



Andrew Baker

unread,
Mar 1, 2022, 8:11:38 PM3/1/22
to pygame...@seul.org
Typically, entities outside of the viewable area may not be updates or may update at a much reduced frequency.  This is true of even C++ games.

Greg Ewing

unread,
Mar 2, 2022, 1:19:20 AM3/2/22
to pygame...@seul.org
On 2/03/22 12:02 pm, Irv Kalb wrote:> I'm wondering if my code to check
if an element is within the viewable area, is actually doing more work
than not bothering to check at all.

If the drawing of each object is just a blit call, then your checks are
probably just duplicating what pygame is already doing itself much more
efficiently.

The only way to find out for sure is to try it, which it sounds like
you've already done and found it only makes a small difference.

To do better you'll need some kind of spatial index to quickly find
objects that might be in view. A simple way would be to divide the
world into a grid of cells, each one about the size of the window,
and maintain a collection of objects in each cell. Then you can
draw just the objects in cells that overlap the window.

--
Greg

Jasper Phillips

unread,
Mar 2, 2022, 2:05:37 AM3/2/22
to pygame...@seul.org
I've dealt with this in my own game, handling thousands of such drawn elements. Based on that I have two general suggestions:

1) If you've got performance bottlenecks, very often they aren't where one first suspects! Better to break out a profiler and measure. That said, I don't have any experience with Python profilers because I don't have speed issues, largely because of the next point...

2) The sort of optimizations you're trying are laborious, fragile, and error prone. It sounds like you're using Pygame directly for 2D? If so, you can vastly simplify things by switching to PyOpenGL underneath, using 3D with a 2D "orthographic" projection. This both takes advantage of the GPU, and simplifies your code because the paradigm handles all the things you're worried about -- you simply set up what needs to be drawn, change their position when needed... and that's it. Blitting is expensive, and with OpenGL you can just avoid it.

There's a bit of up front learning cost if you're not familiar with these tools, but the payoff comes quickly and is well worth it.

-Jasper

Rick van der Meiden

unread,
Mar 2, 2022, 2:43:13 AM3/2/22
to pygame...@seul.org
As your world gets bigger and has more objects, your game will slow down even more. (Even if you directly use openGL, I suspect, although I haven't used it myself). You will need a spatial index. I have some code that i'm willing to share, if you're interested (or anyone else here, drop me a line). You can probably find some other code on the web or you can code your own spatial index, it's not that hard and it's a good exercise. 

Rick.

Yann Thorimbert

unread,
Mar 2, 2022, 3:47:29 AM3/2/22
to pygame...@seul.org

If the ennemies are generated randomly, and if you are sure they are the bottleneck of the FPS, you could generate them dynamically as the character progresses through the world.


Otherwise, you can divide your world in multiples rects the size of the screen, and link each ennemy to the "screen" to which it belongs. Ennemies are then woke up when the actual screen approaches the rect of the ennemy, allowing you to double-loop over a domain with side size 600 times smaller approximately.


(well I wrote "ennemies" but of course this applies to any element that is more or less static with respect to the map)


De : owner-pyg...@seul.org <owner-pyg...@seul.org> de la part de Rick van der Meiden <rickvand...@gmail.com>
Envoyé : mercredi, 2 mars 2022 08:42
À : pygame...@seul.org
Objet : Re: [pygame] Drawing efficiency question
 

rockachu2

unread,
Mar 2, 2022, 5:47:56 AM3/2/22
to pygame...@seul.org
Perhaps you should reconsider your decision not to use a simple
colliderect. It'd be much more efficient (as the general case is
certainly not a high number of entities on the edge of the screen) to
.colliderect() with the edges of the map, and process those specially.

Also beware drawing very large amounts that you do not need to.
Blit()ing onto a large surface, which you then display, will draw all
the pixels each frame even if they are not visible. blit() accepts a
rect argument to limit drawing, which you can take advantage of. You can
also get away with not drawing a very large amount of pixels each frame
by "erasing" underneath moving sprites.

I would also second the request for you to profile. Often, performance
bottlenecks in python are nonobvious. Lots of code that might look
expensive is fast because it operates in optimized C, and code that
looks innocent is actually slow because it is doing something behind the
scenes that you do not expect.

Wall collision code is often complicated and suspect.

Paul Vincent Craven

unread,
Mar 2, 2022, 11:36:57 AM3/2/22
to pygame...@seul.org
Drawing thousands of sprites is pretty quick with OpenGL, but much harder with Pygame. If you draw stationary sprites to a surface once, then draw that surface to the screen each frame you can avoid a lot of drawing calls.

If collision detection is slowing you down, you can use something like a SpatialHash to only check sprites that are near you.

The Arcade library has this stuff baked in, and as it is open source you could always look at it to get ideas.

Paul Vincent Craven

Irv Kalb

unread,
Mar 2, 2022, 8:33:00 PM3/2/22
to pygame...@seul.org
Hi,

Thanks to everyone for the suggestions. Many different things to try out. I'll probably start by eliminating all my checks and see how that goes first.

Irv
Reply all
Reply to author
Forward
0 new messages