Pygame help needed - python

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.

Related

Create Resizable and Moveable Object on the Desktrop Screen in Python

Hey Guys. Hope you are all doing well.
Right now, I need to create a moveable and resizeable circle object with Python. I need to be able to resize the object by dragging my mouse over its corners (just like I would do on Paint), and move it by dragging my mouse on it. And I do not want this circle object to appear on an external app screen/window. Let me show you what I mean by that:
Above image is what I want. This circle needs to be moveable and resizeable.
I though about using Tkinter, however, I do not have many knowledge on it. I do not know if I would be able to remove the Tkinter app screen, and make the object moveable. Can you help me with that?

Is there a way to take a "screenshot" in pygame, and then save it as a sprite so as to reduce code complexity?

The title says it all, although in my instance, the reason I wish to use this feature is I plan on having a all this stuff moving around, until I call this "dialogue()" function, when everything will stop, and I will have dialogue options moving about the screen. However, I don't want to continually render everything in the background, so is there some way of going about taking a screenshot in pygame?
You can capture the contents of the Pygame.Surface by making a copy with screen.copy() then when you want to redraw you use screen.blit(copy, (0,0)). And then you draw on top of that.
Another option is to change your code so that you render the background into a separate surface rather than copying it from the screen and then combine the foreground with the dialogue with it by bliting the background and then the foreground to the screen.
If this isn't right for you, please share more about your program. I haven't used Pygame in a while so this is mostly based on the documentation https://www.pygame.org/docs/ref/surface.html

python read controller button's velocity

i need to get a joystick's velocity data, but pygame (also my os) only tells me if a button on a specified controller is pressed or else..
i'm trying to convert guitar hero drum controller signals into midi, the controller is seen by the os as a normal joystick and the pads are buttons. i know for sure that the controller sends out informations about the velocity at wich a button is pressed but i cannot find a way to get that info.
i'm writing my "translator" in python, but it's not a big piece of code so i can easily switch to another language that provides me the right libraries, is there a way to get the buttons' velocities?
I found this on a site i used to use.
Using horiz_axis_pos= my_joystick.get_axis(0) and vert_axis_pos= my_joystick.get_axis(1) , i think you can read the velocity, because it reads both horizontal and vertical velocity, which you can get an angle from.
Try it! (Honestly, this seemed to work for me, but idk for you)

Python + Qt -> 2D overlay over other full screen app?

Backgroud:
I play Grand Strategy Games a lot. Part of addcition comes out of AARs (After Action Reports). Stories players write about games. Ofc. that require save games cause "quick" game is longer than 10 hours.
Problem:
Game do not support automatic save games other than 3 autosaves that get overridden every time. So I want to write app that will use Qt for tracking file changes. Every time game auto saves, this app will rename and move to choosen location savegame.
But since its full screen game, players may forgot to turn on my app I need way to indicate state of my app.
Question:
How can I make 2D overlay over portion of full screen 3D app, given that I use Python and Qt?
Alternative
I do not think that sound warnings would solve my problem, since it would work if someone forgotten to choose save game to track, but it would not work if someone completely forgot to turn on my app. While lack of icon would be enough to inform about such mistake.
But if you can find any other way to indicate that my app is not turned on or configured, post your ideas in answers.
Very old post, but I will let this reply here for others looking for something similar.
Check PyWinCtl. If you are able to build a frameless, semi-transparent window using Python and Qt, alwaysOnTop(True) and acceptInput(False) methods will make the trick, but only with games based on CGI calls, not if they use DirectDraw Exclusive Mode (for this, I'm also searching for a Python solution, this is why I ended here!)
In the meantime, you can try this on Qt when initializing your window (it's a piece of code, not reproduceble, sorry):
# Make it transparent to input
self.setFocusPolicy(QtCore.Qt.NoFocus)
if "Linux" in platform.platform():
self.setAttribute(QtCore.Qt.WA_X11DoNotAcceptFocus, True)
self.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents, True)
self.setAttribute(QtCore.Qt.WA_InputMethodTransparent, True)
self.setAttribute(QtCore.Qt.WA_ShowWithoutActivating, True)
# Make it semi-transparent
self.setWindowOpacity(128)
# Setting flags: on top, frameless and no focus
self.setWindowFlags(QtCore.Qt.Tool| QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowStaysOnTopHint | QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowDoesNotAcceptFocus)
I think the name of the functions and parameters are self-explicative (let me know if they are not).
The part of making your window transparent to input methods is important, otherwise the window can be eventually clicked and the game will lose focus. This effect on the window is permanent.
The part of making your window semi-transparent will not work as is. You need to implement a custom paintEvent for your window, like this (again, not reproducible, sorry):
def paintEvent(self, event=None):
# This is required to draw a semi-transparent window
# https://stackoverflow.com/questions/33982167/pyqt5-create-semi-transparent-window-with-non-transparent-children
painter = QtGui.QPainter(self)
painter.setOpacity(0.4) # or your desired opacity level
painter.setBrush(QtCore.Qt.black) # or your desired background color
painter.setPen(QtGui.QPenQtCore.Qt.black)) # or your desired background color
painter.drawRect(self.rect())
The part of making it always on top might not be permanent, this is why using pywinctl's alwaysOnTop() is recommended, furthermore, it's better to recall it, for instance every second, to bring your window back to top in case it's obscured by any reason.

Pygame's Message-multiple lines?

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.

Categories

Resources