Pygame's Message-multiple lines? - python

I am using pygame and livewires (though I don't think that part is relevant here) to create a game. I've got the game working, but I'm trying to make something akin to a title screen before the game starts. However, it doesn't recognize when I try to make a new line appear. Here is what I have:
begin_message=games.Message(value=""" Destroy the Bricks!\n
In this game, you control a paddle,\n
controlled by your mouse,\n
and attempt to destroy all the rows of bricks.\n
Careful though, you only have 1 life.\n
Don't mess up! The game will start in\n
5 seconds.""",
size=30,
x=games.screen.width/2,
y=games.screen.height/2,
lifetime=500,
color=color.white,
is_collideable=False)
games.screen.add(begin_message)
The message appears on the screen, but the newline doesn't happen, so I can only read the first part of the message. Is there a way to make this message actually appear, or can I not use the 'Message' for this?

The livewires games.Message class cannot do this.
Going through the source code for games.Message shows that it inherits from games.Text, which has a method _create_surface(). Finally, this calls pygame.font.Font.render() to draw the text to a surface. If you look at the documentation for render(), it states
"The text can only be a single line:
newline characters are not rendered."
As for how you'd do what you want, I'd suggest making several Message objects, one for each line. Then display them on the screen one after the other.

There are several text rendering projects for pygame, on the site. Some are python modules ( that you can include the file locally, without installing. )
A more advanced one is Glyph.

Related

Making a game overlay in python

So I am trying to make a python script that when I do a certain hotkey combination, It shows a text box as an overlay like what "Geforce Experience" and "Windows Gamebar" do.
the problem is that in the game when I interact with the text-area loses focus and goes minimized as opposed to the 2 programs I spoke about before, for example windows game bar allows you interact with a lot of options while the game is still on foreground and you close the bar you are left with whatever you were with before...
I'm using tkinter for now, and if there are solution not including tkinter it is Ok as long as it achives the goal.
As far as I understand what you are trying to do is create a overlay for a game and the overlay should be created using tkinter object. Here is a library that can do that, however as far as I remember you needed to change something in it's python file, however this might have already been fixed.

Pygame window wont move or close after using tkinter

I have had this problem for ages now with many different projects now, so I really want to find out how to fix it. For example, in one of my projects, I created a level editor for a game. The level editor had the option to save and load different levels from a file using tkinter.filedialog.
Now after I select the file, the game will still work, but the 'X' close button doesn't work anymore, and I can't move the window.
The game itself works as usual, and I can still interact with everything inside of the window, but I can't move or close the window.
Thanks in advance.
Ok. I figured this one out. The problem went away when I called the tkinter functions from a key press, not a mouse press.

GtkSourceView/Buffer crash: Gtk-ERROR: Byte index is off the end of the line

I have been working on text editor for writing stories. I am using Python, GTK+ 3 and GtkSourceView 3. The main point of the editor is folding certain regions. While there is no - not yet? - built-in support for folding in GTK TextView / SourceView, I have been using tags with invisible=True and SourceView's source marks to implement the feature.
Source code available here: https://github.com/mkoskim/mawe
The core editor (SourceBuffer and SourceView) is located here: https://github.com/mkoskim/mawe/blob/master/gui/gtk/SceneView.py
https://github.com/mkoskim/mawe/blob/master/gui/gtk/SceneBuffer.py
For testing purposes, you can clone the repo, and run the app with:
mawe$ ./mawe.py test/test.txt
Now, the application keeps frequently and randomly crashing to errors like this:
(mawe.py:10556): Gtk-WARNING **: /build/gtk+3.0-2Ut_nl/gtk+3.0-3.18.9/./gtk/gtktextbtree.c:4034: byte index off the end of the line
(mawe.py:10556): Gtk-ERROR **: Byte index 1362 is off the end of the line
Trace/breakpoint trap
There is no other error or warning logs. I have been googling the error without any success.
Other symptoms seem to be:
Crashes happen even if the editor is idling
Today I figured out that strangely I can get the crash very quickly by moving mouse over the hidden section :o
I can't be 100% sure, but I think this is related to invisible regions.
Question: Does anyone happen to know if this is some known bug?
Question: Does anyone have any ideas where I could look for possible solutions? Any ideas what can cause the crash, and what I could explore more deeply?
Update: I made some more extensive testing with tags. No other properties seem to react to mouse moves, but when turning invisibility on, mouse moves across the region crash the application. I have been searching for reports mouse events crashing gtktextbtree, but without success so far. Looks like this applies to several v3.x GTK versions.
UPDATE: I think I have almost found a workaround for this: filtering out motion-notify events from GtkSource.View seems working, like this:
def filter_event(widget, event, *args):
# Allow these
if event.type == Gdk.EventType.KEY_PRESS: return False
if event.type == Gdk.EventType.KEY_RELEASE: return False
# Block these
if event.type == Gdk.EventType.LEAVE_NOTIFY: return True
if event.type == Gdk.EventType.MOTION_NOTIFY: return True
# Print & allow the rest
print(event)
return False
self.text.connect("event", filter_event)
Application still crashes, if you press mouse button near the hidden lines, but seemingly it does not crash to mouse movements anymore.
UPDATE: More investigations. Although blocking mouse events will prevent crashes, it also causes quirks, e.g. it is not possible to use mouse to place cursor, select areas, DnD, ... Also, mouse cursor can disappear because it is not updated correctly every time. I am pretty sure there is a bug in algorithm converting mouse/window coordinates to buffer positions (when there is larger hidden blocks in the text), and thus any mouse event can crash the application.
UPDATE: I have been trying to create simple test case for the subject. Good things: hiding seems to be working. Bad things: Can't yet reproduce the problem. The test script can be found here:
https://github.com/mkoskim/mawe/blob/master/gui/gtk/test/hidecrash/hidecrash.py
UPDATE: Trying to figure it out - test case works, editor does not work. The difference to test case is at least that editor puts hidden tags in event loop(*). Trying to make a test case for that...
(*) There is definitely many different solutions to implement folding with the current Gtk SourceView/TextView. I chose the approach to use "markup" language and applying the folding while editing, as it works with undo/redo. I have tried also other solutions, like:
Cut folded scene & insert a widget to text buffer, containing the text itself. Idea: "text [part chosen for folding] text" -> "text [anchor + widget with cut text] text" - Sadly, it does not work with undo/redo.
Cut text, give it an ID, and place a specifially marked part containing the ID in the buffer. Idea "text [part chosen for folding] text" -> "text [ID w/ hidden + protected tags] text" - does not work, because cut'n'paste nor undo/redo do not apply tags, so user can destroy the marks.
Plain marks: It is just unbelievably hard to try to keep marks with the folding indicators. You would need something like "[char][mark][char]" with protected tags and such to make sure that you don't loose the mark somewhere.
Anyways, I'll keep investigating.
UPDATE: Still can't reproduce the problem in my test script, but found something possibly interesting: folding the last scene does not cause the crash - only when folding scenes that follow another scene (folded or not).
I have a fix to the problem. I just don't understand why it works, and why I can't reproduce the problem with test script. Here is the snippet that performs the folding:
fold_start = at.copy()
fold_start.forward_to_line_end()
fold_start.forward_char() # Comment this line -> crash
fold_end = self.scene_end_iter(end)
self.apply_tag(self.tag_fold_hide, fold_start, fold_end)
at is derived at insert-text or delete-range callback and pointing to the line start. fold_end is TextIter to either next scene mark or end of file. If we look the buffer content, it is something like this:
<mark 1><at>Scene 1 heading<eol>
Line
Line
<mark 2>Scene 2 heading
Applying hide tag from <eol> to <mark 2> causes crash. Applying tag from <eol + 1> to <mark 2> works as intended. If folded to the end of file (<mark 2> == buffer.get_end_iter()), folding works. In certain cases it also works, if there is just line feed to be hidden, but not in every case.
As said, I don't understand why this works and why I can't reproduce the problem with simpler script, but I keep investigating more, although now when having a fix, it is not that urgent.
OK, so yesterday I did so, that both the visible and invisible parts are formatted with similar font descriptions. I can't still reproduce this problem with simple test script, but it seems that if visible and hidden part are too far from themselves, something goes wrong with the offset calculations. So far I know that:
The error message, like Byte index 1362 is off the end of the line
Trace/breakpoint trap is about 5-7 bytes off from the length of the part that was hidden.
When the visible and invisible parts are "close enough" to each other in terms of font size, padding and weight, the error does not appear. In my working example, I format the invisible part with the exactly same font, weight, size and so on, and the program does not crash anymore.

How to get rectangle to appear on screen (pygame) for a set amount of time?

How do you get a rectangle (rect) to appear on the output screen for a set amount of time, for example 2 seconds, before disappearing? I am making a version of wormy a nibbles clone. I would also like to know how to make an apple disappear when the worm "eats" it.
You don't delete objects, you draw over them in Pygame. Concerning your disappearing rectangles, a simple Timer will suffice. Now, we can't write code for you here without you providing any info so I've just stated some basic information, so the next time you post a question, provide some info and read the How to ask page, and welcome to SO.

Pygame help needed

I am new to PyGame and need some help!
Let me start of by saying that I have a basic understanding of the Python language, I recently started learning how to use PyGame as well as it was something new to me. However I do get stuck quite a lot when trying to code for PyGame. Just so that you know I have read and watched a lot of tutorials but none of them helps me in the way I need it to.
My problem is that I am trying to get a box to appear on the screen that has a word written on it, such as: "Hello". Once that button is clicked then hello should appear.
Here is my plan:
I make a class named pane
Properties of that class would be things like: xpos, ypos, text, width height
Methods of that class would be things like: add(textToDisplay), delete(textToDisplay) - (The delete function is currently not all that important), displayPane()
If possible could you please tell me if this is actually doable using python and pygame/sort of hint to me how I would do it (Like with some useful links because Google has not been my friend for when it has come down to the searching. XD )? and if it isn't what language would you recommend I do it in?
Take a look at:
http://pygame.org/docs/ref/mouse.html#pygame.mouse.get_pos
http://pygame.org/docs/ref/rect.html#pygame.Rect.collidepoint
http://pygame.org/docs/ref/draw.html#pygame.draw.rect
http://pygame.org/docs/ref/font.html#pygame.font.SysFont
My suggestion is a procedural approach if you're dealing with only one shape:
Use pygame.draw.rect to draw a rectangle on a point.
Use a function to capture mouse clicks and their positions.
Collide mouse clicks
with you rectangle position (use a list of objects if you have
several).
Create a function to draw text on the screen and associate
it with the function which collides mouse clicks to rectangles.
Otherwise I'd take an object-oriented approach and use the pygame.sprite.Sprite class for each shape, or custom classes if you have special needs. The click capture-and-colide part would still be procedural, of course.
I adapted a project I'm working on to do what I think is what you want:
You can't actually see the cursor but I'm clicking with the middle mouse button to create the circles and with the main button to display the text.
Source: http://pastebin.com/jycEFAtX
Note: It's a circle and not a rectangle because I was working with circles, but that should be easy for you to change. Everything is a mess because I just adapted what I had and put it all together on a single file (it's probably better to separate it into different files). Use it just to get an idea of how to do what you want.
You can delete the text by setting obj.text as None, for example when event.button == SECONDARY_BUTTON, that way you can delete the text by clicking with the secondary mouse button on the circles.
P.S.: Notice I have a function that collides objects with mouse position (because it's needed for what I'm working with), but you don't need that. You can use pygame.Rect and pygame.Rect.collidepoint, as suggested above.

Categories

Resources