This may seem like a really easy question to answer, but I'm just a beginner in need of quick help.
I'm trying to create a program that when you click somewhere on the pyGame window, it'll print out that you hit it with the left button on the mouse, and also print out co-ordinates of where it was pressed. I've got this already. I'm having problems with making it plot the pixel on the pyGame window. Basically, I want it to draw a pixel where I pressed down on the pyGame window.
#!/usr/bin/env python
#import the module for use
import pygame
#setting up some variables
running = 1
LEFT = 1
#Set up the graphics area/screen
screen=pygame.display.set_mode((640,400))
#continuous loop to keep the graphics running
while running==1:
event=pygame.event.poll()
if event.type==pygame.QUIT:
running=0
pygame.quit()
elif event.type==pygame.MOUSEBUTTONDOWN and event.button==LEFT:
print "You pressed the left mouse button at (%d,%d)" %event.pos
elif event.type==pygame.MOUSEBUTTONUP and event.button==LEFT:
print "You released the left mouse button at (%d,%d)" %event.pos
Try setting the color of each pixel when you receive the mouse down event.
elif event.type==pygame.MOUSEBUTTONDOWN and event.button==LEFT:
print "You pressed the left mouse button at (%d,%d)" %event.pos
screen.set_at((event.pos.x, event.pos.y), pygame.Color(255,0,0,255))
Note that this will temporarily lock and unlock the Surface as needed.
I edited Aesthete's code to a working standalone example:
Depending what you are doing, get/setting individual pixels can be slow. ( There is Surfarray and Pixelarray if you need to. )
import pygame
from pygame.locals import *
class Game(object):
done = False
def __init__(self, width=640, height=480):
pygame.init()
self.width, self.height = width, height
self.screen = pygame.display.set_mode((width, height))
# start with empty screen, since we modify it every mouseclick
self.screen.fill(Color("gray50"))
def main_loop(self):
while not self.done:
# events
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT: self.done = True
elif event.type == KEYDOWN:
if event.key == K_ESCAPE: self.done = True
elif event.type == MOUSEMOTION:
pass
elif event.type == MOUSEBUTTONDOWN and event.button == 1:
print "Click: ({})".format(event.pos)
self.screen.set_at(event.pos, Color("white"))
# draw
pygame.display.flip()
if __name__ == "__main__":
g = Game()
g.main_loop()
Related
`from turtle import right
import pyautogui, time, random, pygame
from pygame.locals import *
time.sleep(3)
class Square(pygame.sprite.Sprite):
def __init__(self):
super(Square,self).__init__()
self.surf = pygame.Surface((20,20))
self.surf.fill((255,0,0))
self.rect = self.surf.get_rect()
width,height = 960,540
screen = pygame.display.set_mode((width,height))
cont = True
square1 = Square()
while cont:
time.sleep(0.4)
x,y=random.randrange(int(1920/2-
width/2),int(1920/2+width/2)),random.randrange(int(1080/2-height/2),int(1080/2+height/2))
screen.blit(square1.surf,(x,y))
pyautogui.click(x,y)
for event in pygame.event.get():
if event.type == QUIT:
cont=False
elif event.type == KEYDOWN:
if event.key == K_BACKSPACE:
cont=False
pygame.display.flip()`
Hi, so basically I am new to python, now learning the basic pyautogui usage and tried making this useless 'game' which was supposed to move the cursor to some point and draw a square at this point and everything is working completely fine when screen size is set to (1920,1080), but when I change the size to anything else it just fails, like cursor coordinates and square being drawn coordinates are not compatible. Does anybody have an explanation for this?
This happens because you draw a square in a pygame window that has its coordinates (0,0), but the cursor has the coordinates (0,0) of your entire screen. I solve it, that I draw first square with pygame window coordinates and then I couted shift.
Here is my code example:
while True:
time.sleep(0.4)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
exit()
elif event.type == KEYDOWN:
if event.key == K_BACKSPACE:
pygame.quit()
exit()
square1.rect.x = random.randint(0, width - square1.rect.w)
square1.rect.y = random.randint(0, height - square1.rect.h)
pyautogui.click((1920/2 - width/2) + square1.rect.centerx,
(1080/2-height/2) + square1.rect.centery)
screen.blit(square1.surf, square1.rect)
pygame.display.flip()
If you have pygame window size same like your entire size, it works becouse coordinates (0,0) are on the same place.
I hope it will help you, Adam
PS: If you move pygame window it not works, because in counting I presuppose, that pygame screen is in center your entire screen.
This code goes into infinite loop. I cant use A button on xbox 360 controller
import pygame
from pygame import joystick
pygame.init()
joystick = pygame.joystick.Joystick(0)
pygame.joystick.init()
print("start")
while True:
if joystick.get_button(0) == 1 :
print("stoped")
break
I cant use A button on xbox 360 controller
Personnaly, I can, so this seems to be possible. You are just missing that pretty much every user input needs to be updated by pygame through pygame.event.get().
From the pygame documentation:
Once the device is initialized the pygame event queue will start receiving events about its input.
So, apparently you need to get the events in the while loop like such to make the joystick work:
import pygame
from pygame.locals import *
pygame.init()
joystick = pygame.joystick.Joystick(0)
while True:
for event in pygame.event.get(): # get the events (update the joystick)
if event.type == QUIT: # allow to click on the X button to close the window
pygame.quit()
exit()
if joystick.get_button(0):
print("stopped")
break
Also,
In the line if joystick.get_button(0) == 1, you don't need to type == 1 because the statement is already True.
You are initializing pygame.joystick twice: through the line pygame.init() and pygame.joystick.init().
You don't need to type from pygame import joystick because you already already have it in the line import pygame.
You can take this as reference and use it in your own way.
import pygame
import sys
pygame.init()
pygame.joystick.init()
clock = pygame.time.Clock()
WIDTH,HEIGHT = 500,500
WHITE = (255,255,255)
BLUE = (0,0,255)
BLUISH = (75,75,255)
YELLOW =(255,255,0)
screen = pygame.display.set_mode((WIDTH,HEIGHT))
smile = pygame.image.load("smile.jpg")
smile = pygame.transform.scale(smile,(WIDTH,HEIGHT))
idle = pygame.image.load("idle.jpg")
idle = pygame.transform.scale(idle,(WIDTH,HEIGHT))
joysticks = [pygame.joystick.Joystick(x) for x in range(pygame.joystick.get_count())]
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.JOYBUTTONDOWN:
if event.button == 0: #press A button to smile
screen.fill(WHITE)
screen.blit(smile,(0,0))
pygame.display.update()
clock.tick(10)
elif event.type == pygame.JOYBUTTONUP:
if event.button == 0:
screen.fill(WHITE)
screen.blit(idle,(0,0))
pygame.display.update()
clock.tick(10)
I use this code to get a separate position of each left click on pygame:
for event in pygame.event.get():
if event.type==QUIT:
running=False
elif event.type == pygame.MOUSEBUTTONDOWN:
mouse_x, mouse_y = event.pos
I use mouse_x and mouse_y for drawing , but they are always change. So, how to get an exact position of each click on a screen in pygame and to use them to draw ?
Thank you
1. To get the position when the mouse is clicked
You can use pygame.event.get() to get the position at the exact frame when you begin to press the button like that:
import pygame
from pygame.locals import * # import constants like MOUSEBUTTONDOWN
pygame.init()
screen = pygame.display.set_mode((640, 480))
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
elif event.type == MOUSEBUTTONDOWN and event.button = 0: # detect only left clicks
print(event.pos)
pygame.display.flip()
pygame.quit()
exit()
2. To get the position each frame
In this case, you can use pygame.mouse.get_pos() like that:
import pygame
from pygame.locals import * # import constants like MOUSEBUTTONDOWN
pygame.init()
screen = pygame.display.set_mode((640, 480))
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
print(pygame.mouse.get_pos())
pygame.display.flip()
pygame.quit()
exit()
If you want to get the mouse position only if the left button is pressed:
Place the line print(pygame.mouse.get_pos()) in if pygame.mouse.get_pressed()[0]::
...
if pygame.mouse.get_pressed()[0]: # if left button of the mouse pressed
print(pygame.mouse.get_pos())
...
This code actually detects all kinds of mouse clicks, if you just want the left clicks you can add this to your if statement:
elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
You are also not getting the coordinates the right way, you need to write it like this:
mouse_x, mouse_y = pygame.mouse.get_pos()
If you need to use all the clicks that are happening you need to store the x_mouse and y_mouse to a log which you can do like this:
# This outside the pygame loop
mouse_clicks = []
# This inside the pygame loop
for event in pygame.event.get():
if event.type==QUIT:
running=False
elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
mouse_clicks.append(pygame.mouse.get_pos())
Now you have a list of tuples with all x,y coordinates for all clicks
This is my python code, using pygame. When I pressed my mouse down, scene 1 does not switch to scene 2. I am coming from Code HS, so the scene switch is from the Tell A Story project. I realized that code is not the same as pygame's. So I used pygame docs and see what I can learn from that, but nothing still. Please can any one help me. Thank you.
import pygame as pg
pg.init()
win = pg.display.set_mode((500,500))
pg.display.set_caption('Scene Switcher')
center_x = 250 - 130
center_y = 250
black= (0,0,0)
red = (255,0,0)
blue = (0,0,255)
def ct(font, size, text, color):
mf = pg.font.Font(font, size)
t = mf.render(text, True, color)
return t
def draw_scene1():
print("This is Scene 1")
txt = ct("SB.ttf", 40, "Hello World!", black)
win.blit(txt, (center_x,center_y))
def draw_scene2():
print("This is scene 2")
txt2 = ct("SB.ttf", 40, "scene2 ", black)
win.blit(txt2, (center_x,center_y))
while True:
win.fill(red)
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
quit()
mouses = pg.mouse.get_pressed()
scene_counter = 0
# When this function is called the next scene is drawn.
def draw_next_screen():
global scene_counter
scene_counter += 1
if scene_counter == 1:
draw_scene1()
else:
draw_scene2()
if mouses:
draw_next_screen()
pg.display.update()
You have to initialize scene_counter before the application loop rather than in the application loop.
The pygame.mouse.get_pressed() returns a list of Boolean values that represent the state (True or False) of all mouse buttons. The state of a button is True as long as a button is held down. Therefor the scene_counter is continuously incremented in each frame as long a mouse button is hold down.
The MOUSEBUTTONDOWN event occurs once when you click the mouse button and the MOUSEBUTTONUP event occurs once when the mouse button is released. Increment the counter when the MOUSEBUTTONDOWN event occurs:
scene_counter = 0
run = True
while run:
for event in pg.event.get():
if event.type == pg.QUIT:
run = False
elif event.type == pg.MOUSEBUTTONDOWN:
scene_counter += 1
win.fill(red)
if scene_counter == 0:
draw_scene1()
else:
draw_scene2()
pg.display.update()
pg.quit()
When I press a button, two buttons are being pressed.
I made images to act like a button but when I press the first button, the second button is pressed too.
I'm new to pygame and trying to make the buttons do separate things when I click each one.
import pygame
import time
pygame.init();
screen = pygame.display.set_mode((340,340));
img = pygame.image.load('3.gif')
iimg = pygame.image.load('2.gif')
mg = pygame.image.load('4.gif').convert()
g = pygame.image.load('5.gif')
waitingForInput = False
pygame.display.set_caption("SIMON");
BEEP1 = pygame.mixer.Sound('beep1.wav')
BEEP2 = pygame.mixer.Sound('beep2.wav')
BEEP3 = pygame.mixer.Sound('beep3.wav')
BEEP4 = pygame.mixer.Sound('beep4.wav')
screen.blit(img,(0,0))
screen.blit(mg,(150,0))
pygame.display.flip()
def main():
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
return False
if event.type == pygame.MOUSEBUTTONDOWN:
mouse_pos = event.pos
if img.get_rect().collidepoint(mouse_pos):
print ('button was pressed at {0}'.format(mouse_pos))
BEEP1.play()
screen.blit(iimg,(0,0))
pygame.display.flip()
time.sleep(.30)
screen.blit(img,(0,0))
pygame.display.flip()
if mg.get_rect().collidepoint(mouse_pos):
print ('button was pressed at {0}'.format(mouse_pos))
BEEP2.play()
screen.blit(g,(150,0))
pygame.display.flip()
time.sleep(.30)
screen.blit(mg,(150,0))
pygame.display.flip()
main()
If you call get_rect on a Surface, the resulting Rect that is returned will always have an x and y value of 0.
So when you run if img.get_rect().collidepoint(mouse_pos) in your event loop, you're NOT checking if the Surface was a clicked. You check if the mouse position is in the top left corner of the screen.
Maybe use some print statements to check for yourself.
What you can do is to create a Rect for each button outside of your main loop, and then use these rects for blitting:
...
img = pygame.image.load('3.gif')
img_rect = img.get_rect()
...
mg = pygame.image.load('4.gif').convert()
mg_rect = img.get_rect(topleft=(150,0))
...
while True:
...
if event.type == pygame.MOUSEBUTTONDOWN:
mouse_pos = event.pos
if img_rect().collidepoint(mouse_pos):
BEEP1.play()
if mg_rect ().collidepoint(mouse_pos):
BEEP2.play()
screen.blit(img, img_rect)
screen.blit(mg, mg_rect)
Note that you also should avoid time.sleep or multiple calls of pygame.display.flip() in your main loop.
Another solution is to use the pygame's Sprite class, which allows you to combine a Surface and a Rect.