draw rotated font with pygame - python

What's the best way to draw rotated text rendered with fonts with pygame? I can just draw the font then rotozoom it, but it seems better result would be gotten if it were possible to draw the glyphs directly rotated, especially taking AA into account?

Pygame does not have the functionality you are looking for.
You will have to use the method you mention, i.e rotozoom on an the already rendered font. The quality of this method isn't all that bad actually. And concerning speed, you don't want to be rendering the fonts all the time anyway.
If you are desperate for speed, and the text isn't dynamic, you can always make a cache of i.e 32 directions for each text you want displayed. Pyglet will allow you to rotate sprites for "free", i.e hardware accelerated.
Or you can go look at the raw SDL libraries pygame uses and see if you can find something that draws rotated fonts directly and hack pygame to use it.

You can use a pyOpenGL surface in pygame, if that simplifies it for you.
Pyglet also uses OpenGL.
(for pygame surfaces) You can cache the rendered text, using that to rotate. Or pre-cache all 32 directions. [ see other answer ]

Related

How to draw shapes directly on screen(framebuffer?) with python on windows

The title explains it self basically, I want to draw for example a rectangle on a specific coordinate on the screen, using Python, how to achieve this?
I hear PyGame mentioned frequently, but I need a solution that would allow me to click through the shape, and as far as I understand you definitely need a Pygame window to draw anything on the screen and that would prevent clicking on whatever it is underneath, am I correct?

Pygame draw behavior

I am currently designing basic pygame projects. Random projects actually, which are just random ideas pop into my head during common daytime. One of them is a wall clock. Where I use sin, cos functions to draw hour hand, minute hand etc..
As a result of these functions, I obtain float values. Which pygame does not allow. So I round and int() all values before using them in drawing functions. This makes sense because of pixels can't be partially filled. However, I think this results in bad drawings.
The Image above is the clock drawn by the pygame module. As you see the handles are somewhat leaning. Not straight.
I also implemented this in codeskulptor. Which is a python2 environment for basic game(or any graphical) programming. Has nice and clear functions, very easy to use indeed. The float values I use in that no needs conversion and accepted directly. I do not know how it handles it, but it is clearly better. Obviously not just rounding and integering(does this word exist ?) values. Let me show you the clock drawn in codeskuptor:
As you can see, the edges are more smooth. The lines does not end sloped, but straight. It is clearly a better drawing than the pygame one.
But the thing is, codeskuptor does not implement many modules and built-in functions that is harder than beginning level knowledge. Also it doesn't support a well-known compiler(basically not a python module). So can't work on computer and can not be compiled with py2exe, pyinstaller as such.
So I wan't to implement all this in pygame, and get smooth results just like in codeskulptor. Maybe a better way to handle float points for drawing. Any idea or knowledge in this area would be greatly appreciated.
My code for codeskuptor(Does not show realtime)
My code for pygame
The codes does not supply proper commenting because they were just a late-night fun nothing more. I'll explain any necessary parts.
To summarize the comments above, the issue you've noticed here is antialiasing. For the lines, pygame provides the aaline function, which can be used to draw a single line. Unfortunately, this does not support a varying thickness. Potential workarounds could be drawing a line of the correct thickness and drawing an aaline on either side of it, or drawing the line using an aapolygon (from the gfxdraw module).
The standard draw module does not include antialiased circles, but you can use another function from gfxdraw to draw an antialiased circle, aacircle.
It is important to note that the gfxdraw module is labeled "experimental", so the functions are not guaranteed to persist across versions of pygame. But for your quick projects that might not be a concern.
As for CodeSkulptor, they are rendering the lines on an HTML5 <canvas> element, which according to this question has anti-aliasing turned on by default.

How to optimize tile rendering in pygame?

I am making a tile based game, and the map needs to be rendered every frame. Right now, each tile is 32X32, and the visible map is 28X28 tiles. The performance is dreadful. I recently made it only render the visible tiles, but this still did not improve the FPS much. Right now I'm looking for a way to speed up the rendering. I attribute the slowness to the way I am rendering ; every tile is individually blitted to the screen. What would be a more effective was of doing this?
In pygame (afaik), updating the screen is always one hell of a bottle neck. Since I could not see your code, I don't know, how you are updating the screen. Only blitting the the sprites that changed is a start, but you need to only update those parts that changed, on the screen.
Basically it is the difference between using display.flip() or using update_rects() with only the changed rects. I know, that does not help at all, when you are scrolling the map.
Take a look at this question: Why is this small (155 lines-long) Pacman game on Python running so slow?, it has a similiar topic.
One thing I tried when I had a map compiled of tiles and some sprites on it, I tried always having a precompiled image of the map for an area containing the currently displayed part and some 200 or so pixels around that, so that I could blit the prepared "ground" (still only in updated parts) without the need of blitting all those tiles contained in it. That, of course, is quite some thinking you have to put into that, espacially if you have multiple layers and parts of the map that can be above your active sprites. It is interesting to think and work that through, but I cannot tell you, how much you will gain by that.
One totally different possible solution: I began with pygame once (since I did SDL in C++ prior to that). Recently I was directed to another python gaming library: pyglet. This does not suffer from the problems of updating the whole screen as much as pygame (I think it's because of usage of OpenGL acceleration; it still works on my not at all accelerated eee-Netbook). If you are not bound to pygame in any way, it might be interesting to take a look at pyglet.

Native PyGame method for automatically scaling inputs to a surface resolution?

This question is related to this other one.
In my program (which uses pygame to draw objects on the video) I have two representation of my world:
A physical one that I use to make all the calculations involved in the simulation and in which objects are located on a 1000x1000 metres surface.
A visual one which I use to draw on the screen, in which my objects are located in a window measuring 100x100 pixels.
What I want to achieve is to be able to pass to my pygame drawing functions (which normally accept inputs in pixels) my physical/real-word coordinates. In other words, I would like to be able to say:
Draw a 20m radius circle at coordinates (200m, 500m)
using the precise pygame syntax:
pygame.draw.circle(surface, (255,255,255), (200,500), 20)
and get my circle of 2px radius at centred on pixels (20,50).
Please note that this question is about a native pygame way to do this, not some sort of workaround to achieve that result (if you want to answer that, you should take a look to the question I already mentioned) instead.
Thanks in advance for your time and support.
There is no native pygame way to do this.
You may be misunderstanding the function of pygame. It is not for drawing vector objects. It is for writing pixels into video surfaces.
Since you have vector objects, you must define how they will be converted into pixels. Doing this is not a workaround - it's how you are intended to use pygame.
Since it seems that PyGame developers do not hang around here too much, I brought the question to the Pygame mailing list where it originated a monster thread and the issue has been debated at large.
The summary would be:
At present there is not such a feature.
There is interest to implement it, or at least to try to implement it...
...although is not a priority of the core devs in any way
There is more than one way to skin a cat:
should be the scaling happen both ways (inputting coordinates and reading them)?
how to deal with lines that have no thickness but that should be visible?
how to deal with visibility of objects at the edge of the image? which of their points should be taken as reference to know if a pixel should be lit or not for them?
and more (see linked thread).

Recommendations for a simple 2D graphics python library that can output to screen and pdf?

I'm looking for an easy-to-use graphics lib for python that can output to screen as well as pdf. So, I would use code to draw some stuff (simple prims like ovals, rectangles, lines and points) to screen and then when things look good, have it output to pdf.
If you use Tkinter, you can draw on a Canvas widget, then use its .postscript method to save the contents as a PostScript file, which you can convert to PDF using ps2pdf.
postscript(self, cnf={}, **kw)
Print the contents of the canvas to a postscript
file. Valid options: colormap, colormode, file, fontmap,
height, pageanchor, pageheight, pagewidth, pagex, pagey,
rotate, witdh, x, y.
Matplotlib should be able to do it. See event handling here: http://matplotlib.sourceforge.net/examples/event_handling/index.html
You can use the Python Imaging Library for drawing images which can easily be displayed in various UIs, e.g. by displaying a jpg. Then, use ReportLab. Here's an example which shows how to use ReportLab with an image.
I'm not sure what you mean by drawing to "screen", i.e. if you're working with a specific UI toolkit. But if it's acceptable to draw and display PDFs without using an intermediate image (jpg, etc), then you might consider the PyX library, which makes it quite simple to do graphics with PDFs.
You could look into matplotlib, which is mainly for plotting but you could probably do some basic drawing.
Then there is pygame. But I'm not so sure if it can generate a pdf, however you can do 2D graphics with it.
There is something called ReportLab that can generate pdf's. Here is a bunch of tutorials using it.
This is a tricky question, because there are so many libraries available - there is a trade-off between beauty/easiness.
What I've done and works great is to produce the Postscript directly, it is not difficult at all, and you can preview it using Ghostview; converting tyo PDF is trivial (ps2pdf). Learning how to tell Postscript to create lines and circles is extremely simple.
If you want more extensibility, then go to Matplotlib, but beware of the many times when it will "decide for you what looks best" even if you don't like it.
Good luck.
Creating PDFs is always a pain, it doesn't make sense if you do not aim to lose sanity.
With that said, you are aiming to do two completely different things: when you draw to screen you draw into a raster bitmap, while PDFs are mostly dynamic, like HTML. (unlike HTML they are more prone to be the same over different platforms, but that's beside the point)
If you really want to do that, the solution might be finding something that outputs PDFs, and then showing the generated PDF on screen at every step.
I guess that's the only way to have WYSIWYG results.

Categories