PyGame any touchscreen - python

I am trying to create a simple program in which a user can move a shape on the screen using his finger (on a touchscreen).
this is my code so far:
import pygame
def main():
pygame.init()
DISPLAY = pygame.display.set_mode((1000,500),0,32)
WHITE = (255,255,255)
blue = (0,0,255)
DISPLAY.fill(WHITE)
pygame.mouse.set_visible(False)
pygame.draw.rect(DISPLAY, blue,(480,200,50,250))
pygame.display.update()
pygame.mouse.set_pos(480, 200)
while True:
for event in pygame.event.get():
pos = pygame.mouse.get_pos()
pygame.draw.rect(DISPLAY, blue, (pos[0]-25,pos[1], 50, 250))
pygame.display. update()
DISPLAY.fill(WHITE)
main()
The problem is that when I touch the screen, nothing will happen until I move my finger. If I print the events I can see that there is no event listed until I start moving my finger, so that is probably the reason.
I want to be able to register the finger press (as an event I guess) on the screen even before it starts to move, is there anyway to do this using PyGame?
Thanks.

In case anyone is stumbling across this later, in pygame 2 there is much better touch support. You can install with
pip install pygame==2.0.0.dev6
(check the pygame github for the most recent version) And there are three new event types. pygame.FINGERDOWN, pygame.FINGERUP, and pygame.FINGERMOTION. The pygame.FINGERUP event registers the touch input right when the screen is touched instead of when the screen is released like pygame.MOUSEBUTTONDOWN

I have made a game that utilises a computer touch screen and manages the touch quite well by handling two types of events. One is pygame.MOUSEMOTION and the other one is pygame.MOUSEBUTTONDOWN. Both of them contain the attribute event.pos. Problem is, at least when it comes to my touch screen (Lenovo), that the initial touch is not registered by the event handler of pygame.
You can confirm this by printing all the events to the terminal while touching your screen. I get nothing until I release or move my finger but on release I get the event pygame.MOUSEBUTTONDOWN rapidly followed by pygame.MOUSEBUTTONUP.
I know that this doesn't really solve your problem, but it might perhaps help you in some way. Otherwise, check out Kivy. There might be a solution there.
import pygame
def main():
pygame.init()
DISPLAY = pygame.display.set_mode((1000,500),0,32)
WHITE = (255,255,255)
blue = (0,0,255)
DISPLAY.fill(WHITE)
pygame.mouse.set_visible(False)
pygame.draw.rect(DISPLAY, blue,(480,200,50,250))
pygame.display.update()
pygame.mouse.set_pos(480, 200)
while True:
for event in pygame.event.get():
if event.type == MOUSEBUTTONDOWN or event.type == MOUSEMOTION:
pos = event.pos
pygame.draw.rect(DISPLAY, blue, (pos[0]-25,pos[1], 50, 250))
pygame.display. update()
DISPLAY.fill(WHITE)
main()

Related

Problems making a UI, i cant make it work [duplicate]

i have started a new project in python using pygame and for the background i want the bottom half filled with gray and the top black. i have used rect drawing in projects before but for some reason it seems to be broken? i don't know what i am doing wrong. the weirdest thing is that the result is different every time i run the program. sometimes there is only a black screen and sometimes a gray rectangle covers part of the screen, but never half of the screen.
import pygame, sys
from pygame.locals import *
pygame.init()
DISPLAY=pygame.display.set_mode((800,800))
pygame.display.set_caption("thing")
pygame.draw.rect(DISPLAY, (200,200,200), pygame.Rect(0,400,800,400))
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
You need to update the display.
You are actually drawing on a Surface object. If you draw on the Surface associated to the PyGame display, this is not immediately visible in the display. The changes become visibel, when the display is updated with either pygame.display.update() or pygame.display.flip().
See pygame.display.flip():
This will update the contents of the entire display.
While pygame.display.flip() will update the contents of the entire display, pygame.display.update() allows updating only a portion of the screen to updated, instead of the entire area. pygame.display.update() is an optimized version of pygame.display.flip() for software displays, but doesn't work for hardware accelerated displays.
The typical PyGame application loop has to:
handle the events by calling either pygame.event.pump() or pygame.event.get().
update the game states and positions of objects dependent on the input events and time (respectively frames)
clear the entire display or draw the background
draw the entire scene (draw all the objects)
update the display by calling either pygame.display.update() or pygame.display.flip()
limit frames per second to limit CPU usage with pygame.time.Clock.tick
import pygame
from pygame.locals import *
pygame.init()
DISPLAY = pygame.display.set_mode((800,800))
pygame.display.set_caption("thing")
clock = pygame.time.Clock()
run = True
while run:
# handle events
for event in pygame.event.get():
if event.type == QUIT:
run = False
# clear display
DISPLAY.fill(0)
# draw scene
pygame.draw.rect(DISPLAY, (200,200,200), pygame.Rect(0,400,800,400))
# update display
pygame.display.flip()
# limit frames per second
clock.tick(60)
pygame.quit()
exit()
repl.it/#Rabbid76/PyGame-MinimalApplicationLoop See also Event and application loop
simply change your code to:
import pygame, sys
from pygame.locals import *
pygame.init()
DISPLAY=pygame.display.set_mode((800,800))
pygame.display.set_caption("thing")
pygame.draw.rect(DISPLAY, (200,200,200), pygame.Rect(0,400,800,400))
pygame.display.flip() #Refreshing screen
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
it should help

PyGame - Can't hide mouse

I've read everything I could find about the mouse in pygame and yet I miss something.
The device has (and will not) have a mouse attached so I need to remove the cursor from the game surface, ideally even before it draws the first screen.
But no matter what I try I always have a big oppalin cursor in the middle of the screen.
My current function is this :
# initialize the pygame module
pygame.init()
# create a surface on screen that has the size of 240 x 180
screen = pygame.display.set_mode((160,80))
# define a variable to control the main loop
running = True
pygame.display.flip()
# main loop
while running:
screen.fill((0, 0, 0))
# hide cursor
pygame.mouse.set_pos((160,80)) # my screen is actually 160 x 80 px so this should hide it by pushing it over the edge
pygame.mouse.set_visible(False) # this should hide the mouse plain and simple
# Here I do other unrelated (but working) stuff, like displaying images and text
# event handling, gets all event from the event queue
for event in pygame.event.get():
# only do something if the event is of type QUIT
if event.type == pygame.QUIT:
# change the value to False, to exit the main loop
running = False
pygame.display.flip()
And the mouse is still on screen, sometimes after a while it disappears.
I tried other method like making the cursor transparent, but that crash the app.
Note that I'm running Pygame on an Alpine Linux with direct output to the framebuffer on a Raspberry Pi. There's no mouse attached to the device but if I connect one I can move the cursor around.
Pygame is Version 2.1.2 (compiled and installed by pip)
Python is 3.10.0
Any help or pointer would be greatly appreciated.
(sorry if it's a dumb question; I'm a total noob with python/pygame)
Just write the set_visible(False) outside the main loop, you don't need to call this every frame:
pygame.init()
screen = pygame.display.set_mode((160,80))
pygame.mouse.set_visible(False) # Hide cursor here
running = True
pygame.display.flip()
# main loop
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# unrelated with your question but I also suggest that you clear your background inside the loop, at the contrary you likely will need this at each frame
screen.fill((0, 0, 0))
# ... your code, blitting images etc
pygame.display.flip()

How do I start a pygame app in maximized mode on Linux?

Before I start, this is not a duplicate of How do you start Pygame window maximized?
I am on Linux which the win32gui and win32con libraries do not run on.
What I'm trying to do as stated by the title is maximize my pygame window when it is run. I do not want the game to be fullscreen by using the pygame.FULLSCREEN tag in pygame.display.set_mode(). I want it to be maximized.
My current way of getting it maximized is by creating the window with the pygame.RESIZEABLE flag which allows me to get the pygame.VIDEOEXPOSE event as shown in the example below.
import pygame, sys
SCREEN_WIDTH,SCREEN_HEIGHT = 1280,720
SCREEN = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.RESIZABLE, 32, vsync=1)
objects = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.VIDEORESIZE:
SCREEN.blit(pygame.transform.scale(objects, event.dict['size']), (0, 0))
pygame.display.update()
elif event.type == pygame.VIDEOEXPOSE: # handles window minimising/maximising
SCREEN.fill((0, 0, 0))
SCREEN.blit(pygame.transform.scale(objects, SCREEN.get_size()), (0, 0))
pygame.display.update()
pygame.display.update()
The objects surface is simply a surface I draw my game objects to in order to scale them when the window is resized. If you're wondering why I'm not just setting the screen width and height to the size of the screen by getting it using system info is because that way my objects aren't scaled properly. The only way I've been able to get my objects scaled properly is by using the VIDEORESIZE and VIDEOEXPOSE events. If there is a way to automatically press the maximize button or just start maximized in pygame that would be great.
Just found this issue on the pygame github for anyone who needs this. Essentially just use the library that pygame uses to draw windows which is cross platform.
This is the code snippet on the issue which worked for me.
import sys
import pygame
import pygame._sdl2
import time
pygame.init()
screen = pygame.display.set_mode((400, 400), pygame.RESIZABLE)
window = pygame._sdl2.Window.from_display_module()
clock = pygame.time.Clock()
window.maximize()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
screen.fill((255, 255, 255))
pygame.display.flip()
clock.tick(30)
I hope this helps anyone having similar issues.

Pygame Display Position While Running

I am making a pygame project, and have an issue where the window sets itself in the corner of the screen when I back out of full screen mode. Normally, this wouldn't be an issue but it hides the toolbar off screen, making it impossible to drag the screen around or resize it. I have found pygame.display.toggle_fullscreen() to be far to unreliable and breaks whenever I use it, so I made my own method of toggling fullscreen:
import pygame, tkinter
fullscr = False
scrw, srch = tkinter.Tk().winfo_screenwidth(), tkinter.Tk().winfo_screenheight()
while True:
for event in pygame.event.get():
if event.type == pygame.KEYUP:
if event.key == pygame.K_F11:
if fullscr:
screen = pygame.display.set_mode((scrw, scrh), pygame.RESIZABLE)
screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
else:
screen = pygame.display.set_mode((980, 720), pygame.RESIZABLE)
fullscr = not fullscr
For those curious, I set the window to fill the screen before setting it to fullscreen because the window will maintain its aspect ratio, breaking my game and causing weird glitches. I am already aware of os.environ['SDL_VIDEO_CENTERED'] = '1' as a way to center the screen, but this does not work after running pygame.init(). Are there any other ways I can change the windows position, or at least prevent it from hiding the toolbar off screen when toggling out of fullscreen?
This is a pygame 2 bug.
It's reported on github here: https://github.com/pygame/pygame/issues/2360,
and the author there realized that you can get around this for now by calling pygame.quit() and then reinitializing to have the SDL_VIDEO_CENTERED work.
Hopefully this will be fixed in pygame 2.0.2. I've written a patch for it at https://github.com/pygame/pygame/pull/2460

Window resize example from Pygame wiki not working

I took this tutorial from pygame.org which should show how to resize the window properly (image has to be supplied to it, you can use for instance my gravatar). The image should resize to the window, but this doesn't happen with me. Only one VideoResize event is created as soon as I resize the window even so slightly:
<Event(16-VideoResize {'h': 500, 'w': 501, 'size': (501, 500)})>
No other VideoResize events are created (other things like mouse movement or keypresses work). So is the tutorial wrong? Is my computer wrong? What is the proper way of doing it?
I'm running: Python 2.7.5, Pygame 1.9.1, Fedora 20, MATE 1.8.1, Toshiba Satellite.
Here's the code (slightly modified to print the event, but neither the original nor this one work):
import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((500,500), RESIZABLE)
pic = pygame.image.load("example.png")
screen.blit(pygame.transform.scale(pic, (500,500)), (0,0))
pygame.display.flip()
done = False
while not done:
pygame.event.pump()
for event in pygame.event.get():
if event.type == QUIT:
done = True
elif event.type == VIDEORESIZE:
print event # show all VIDEORESIZE events
screen = pygame.display.set_mode(event.dict['size'], RESIZABLE) # A
screen.blit(pygame.transform.scale(pic, event.dict['size']), (0,0))
pygame.display.flip()
pygame.display.quit()
If I comment the line # A, then I get plenty of events, but this is the line which resizes the window.
Well I ran the tutorial example with only one change which is I used a pic of a cat called cat.png and it worked fine. The resize is working you just grab a corner and it allows me to adjust it freely with dragging. The picture fills the window whatever size I make it. Have you done other scripts with pygame successfully?

Categories