I'm trying to make a simple menu using Pygame but I found that whenever I use pygame.mouse.get_position, it does blit what i want but i have to keep move my mouse to make my picture keep blitting.
import pygame
import sys
pygame.init()
screen = pygame.display.set_mode((800,600))
pygame.display.set_caption('cursor test')
cursorPng = pygame.image.load('resources/images/cursor.png')
start = pygame.image.load('resources/images/menuStart.jpg')
enemy = pygame.image.load('resources/images/enemy-1.png')
white = (255,255,255)
black = (0,0,0)
clock = pygame.time.Clock()
FPS = 60
while True:
screen.fill(white)
pygame.mouse.set_visible(False)
x,y = pygame.mouse.get_pos()
x = x - cursorPng.get_width()/2
y = y - cursorPng.get_height()/2
screen.blit(cursorPng,(x,y))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEMOTION:
if x < 50 and y < 250:
screen.blit(enemy,(100,100))
clock.tick(FPS)
pygame.display.update()
what's wrong?
Take a look at your code:
for event in pygame.event.get():
...
elif event.type == pygame.MOUSEMOTION:
if x < 50 and y < 250:
screen.blit(enemy,(100,100))
You check for events, and if you detect that the mouse is being moved (and only then), you draw the image to the screen.
If you want to draw the image even if the mouse is not being moved, just stop checking for the MOUSEMOTION event and simply draw the image always:
while True:
screen.fill(white)
pygame.mouse.set_visible(False)
x,y = pygame.mouse.get_pos()
x = x - cursorPng.get_width()/2
y = y - cursorPng.get_height()/2
screen.blit(cursorPng,(x,y))
if x < 50 and y < 250:
screen.blit(enemy,(100,100))
for event in pygame.event.get():
...
You need to blit into the screen a Surface and a Rect.
First, use this snippet I use for loading images. It makes sure the image is loaded correctly:
def loadImage(name, alpha=False):
"Loads given image"
try:
surface = pygame.image.load(name)
except pygame.error:
raise SystemExit('Could not load image "%s" %s' %
(name, pygame.get_error()))
if alpha:
corner = surface.get_at((0, 0))
surface.set_colorkey(corner, pygame.RLEACCEL)
return surface.convert_alpha()
Second, when you get the Surface, get its rect like this:
cursorSurf = loadImage('resources/images/cursor.png')
cursorRect = cursorSurf.get_rect()
Then, inside the update do the following:
cursorRect.center = pygame.mouse.get_pos()
And finnally, blit to screen like this:
screen.blit(cursorSurf, cursorRect)
Now you will notice your Mouse is being rendered correctly without having to move your mouse.
Related
How would you run a function when you click on an image in pygame? In my program, I want to run a specific function when you click on a certain image. The problem is, I have no idea how to do that. Is it even possible to do that? Here is my code below...
import pygame
black = (0, 0, 0)
white = (255, 255, 255)
green = (0, 255, 0)
red = (255, 0, 0)
pygame.init()
size = (500, 400)
screen = pygame.display.set_mode(size)
pygame.draw.rect(screen, red,(150,450,100,50))
button1 = pygame.Rect(100,100,50,50)
button2 = pygame.Rect(200,200,50,50)
button3 = pygame.Rect(130,250,50,50)
pygame.display.set_caption("Yami no Game")
txt = pygame.image.load('txt.png')
Stxt = pygame.transform.scale(txt,(48,48))
exe = pygame.image.load('exe.jpg')
Sexe = pygame.transform.scale(exe,(48,48))
done = False
clock = pygame.time.Clock()
background_image=pygame.image.load('windows_background.jpg').convert()
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.MOUSEBUTTONDOWN:
100, 100 = event.pos
if Sexe.get_rect().collidepoint(100,100):
print('Runnig thing')
screen.blit(background_image, [0,0])
screen.blit(Stxt,[100,100])
screen.blit(Sexe,[250,250])
pygame.display.update()
clock.tick(60)
pygame.quit()
Detect for a mouseclick then check the position of the mouse when the click occurred and see whether it was within the image by using the collidepoint function:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.MOUSEBUTTONDOWN:
mousePos = pygame.mouse.get_pos()
if Sexe.get_rect().collidepoint(mousePos):
runFunction()
In general you speak of using a button to execute something. For this we need to know where the player clicked with the mouse, test if it is inside the area that depicts the image (our "button") and if so, execute a function. Here is a small example:
# get the mouse clicks
mouse = pygame.mouse.get_pos() # position
click = pygame.mouse.get_pressed() # left/right click
if img.x + img.width > mouse[0] > img.x and img.y + img.height > mouse[1] > img.y: # Mouse coordinates checking.
if click[0] == 1: # Left click
my_function_on_click()
It requires your image object to have an x and a y coordinate as well as a defined height and width. It is a lot easier if your image object has a rect the same size as you can call on that rect, or as the other answer pointed out use the collidepoint function.
Minimal example using the code you copied into the comments:
width = 48
height = 48
x = 100
y = 100
exe = pygame.image.load('exe.jpg')
Sexe = pygame.transform.scale(exe,(width,height))
while not done:
screen.blit(Sexe,[x,y]) # blit image
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
mouse = pygame.mouse.get_pos()
position click = pygame.mouse.get_pressed() # left/right click
# Mouse coordinates checking:
sexe_rect = Sexe.get_rect()
if sexe_rect.x + sexe_rect.width > mouse[0] > sexe_rect.x and sexe_rect.y + sexe_rect.height > mouse[1] > sexe_rect.y:
# if Sexe.get_rect().collidepoint(mousePos): # Alternative, A LOT shorter and more understandable
if click[0] == 1: # Left click
print("I GOT CLICKED!")
I am trying to get familiar with pygame so am starting with a simple program that draws a rectangle and moves it around with the mouse. The rectangle draws fine however it does not move with the mouse position and I cannot think why.
I found one other with this problem however this fix didnt work for me and was much more long winded than I felt it needed to be.
pygame.init()
screen = pygame.display.set_mode((500,300))
# --- mainloop / event loop ---
running = True
playerstartposX = 100
playerstartposY = 100
playerwidth = 50
playerheight = 50
screen.fill((30,30,30))
newrect = pygame.draw.rect(screen, (255,0,0) , ( playerstartposX ,
playerstartposY ,
playerwidth ,
playerheight))
pygame.display.update()
while running:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == 4: #if event is mouse motion
newrect.move(event.pos) #move the rectangle to mouse pos
pygame.display.update()
pygame.quit()
4 is not an event type. An event type is MOUSEMOTION (see pygame.event).
Create a pygame.Rect object:
newrect = pygame.Rect(playerstartposX, playerstartposY, playerwidth, playerheight)
Change its position when the event occurs:
if event.type == pygame.MOUSEMOTION:
newrect.center = event.pos
In the main application loop you've to continuously
handle the events
clear the display
draw the scene respectively rectangle
update the display
If you want to control the frames per second, then you can pass a parameter to the method .tick() of pygame.time.Clock rather than pygame.time.delay:
import pygame
pygame.init()
screen = pygame.display.set_mode((500,300))
clock = pygame.time.Clock()
running = True
playerstartposX = 100
playerstartposY = 100
playerwidth = 50
playerheight = 50
newrect = pygame.Rect(playerstartposX, playerstartposY, playerwidth, playerheight)
while running:
clock.tick(60)
# handle the events
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.MOUSEMOTION:
newrect.center = event.pos
# clear the display
screen.fill((30,30,30))
# draw the rectangle
pygame.draw.rect(screen, (255,0,0), newrect)
# update the display
pygame.display.update()
pygame.quit()
First, the event type you need to check against is pygame.MOUSEMOTION (I believe it's 1024?) and you are checking with 4.
Then you have to redraw the rect on every iteration of the main loop to reflect the updated position
import pygame
pygame.init()
display_width = (640)
display_height = (480)
title = pygame.display.set_caption("test")
IMG = pygame.image.load("image.png")
screen = pygame.display.set_mode((display_width,display_height))
screen.blit(IMG,(1,1))
pygame.display.update()
Whenever I use pygame, even simple displays like this are skewed for me. it shows 0,0 at around the middle of my display screen and i dont know why. Basically, it is showing - x values on the x axis help!
I am using python 2.7 and this seems to not be a coding issue, but rather something else. please help! ty
I've not been able to replicate your problem with the above code in Python 2.7.12, the image is a red, fifty-pixel square:
Here's an extended demo that will draw the image around the cursor position based on the mouse button clicked. Perhaps that'll help you get towards the behaviour you're after.
import pygame
if __name__ == "__main__":
pygame.init()
screen_width, screen_height = 640, 480
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('Blit Demo')
clock = pygame.time.Clock() #for limiting FPS
FPS = 10
exit_demo = False
# start with a white background
screen.fill(pygame.Color("white"))
img = pygame.image.load("image.png")
width, height = img.get_size()
pos = (1,1) # initial position to draw the image
# main loop
while not exit_demo:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit_demo = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
# fill the screen with white, erasing everything
screen.fill(pygame.Color("white"))
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1: # left
pos = (event.pos[0] - width, event.pos[1] - height)
elif event.button == 2: # middle
pos = (event.pos[0] - width // 2, event.pos[1] - height // 2)
elif event.button == 3: # right
pos = event.pos
# draw the image here
screen.blit(img, pos)
# update screen
pygame.display.update()
clock.tick(FPS)
pygame.quit()
quit()
i'm making a game by using pygame, and also tring to learn this. but i'm facing a little hickup.
how do i selectively move an image in pygame ?
i let the display be 800x600 and the point is all start at y 511
x at 62, 124. size of the image is 21x21
Tower1 = pygame.image.load('assets/Tower1.png')
Tower2 = pygame.image.load('assets/Tower2.png')
if i hit a box it will move the image in the box along with the mouse, and other
image doesn't move
form Pygame drag background image
i can get moving image, but i can't make it move one by one.
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
#gameExit = True
pygame.quit()
quit()
if event.type == pygame.MOUSEMOTION:
#event.buttons returns (0,0,0) <=> (left, mid, right)
print (event)
if event.buttons[LeftButton]:
rel = event.rel
pos = event.pos
#print (rel)
#print (pos)
if (rangeHitPoint(62,511,(21,21),pos)):
#moveImage()
if event.buttons[RightButton]:
pass
def rangeHitPoint(x,y,imgeSize,Musepos):
(w,h) = imgeSize
(musex, mousey) = Musepos
if x < musex and y < mousey:
if (x+w) > musex and (y+h) > mousey:
return True
else:
return False
def moveImage(image,pos):
imgPos = pygame.Rect(pos, (0, 0))
LeftButton = 0
gameExit = False
while not gameExit:
for e in pygame.event.get():
if e.type == pygame.QUIT:
#gameExit = True
pygame.quit()
quit()
if e.type == pygame.MOUSEMOTION:
if e.buttons[LeftButton]:
# clicked and moving
rel = e.rel
imgPos.x += rel[0]
imgPos.y += rel[1]
gameDisplay.blit(image, imgPos)
pygame.display.flip()
pygame.time.delay(60)
gameExit = True
def displayImage(image,x,y):
gameDisplay.blit(image,(x,y))
pygame.display.update()
by adding a boolean in the while loop, and set that when the range is clicked this boolean = true, then outside that if. set another if boolean: moveImage().
make sure let this equal False again.
how easy this is ....
I've written a little pygame program for moving an image by clicking and moving the mouse.
I struggle with making the moving function movableImg to work with my own x, y parameters and not with the predefined x, y parameters as it is now.
Here is my code:
import pygame
import time
pygame.init()
display_width = 800
display_height = 600
white = (255, 255, 255)
gameDisplay = pygame.display.set_mode((display_width, display_height))
clock = pygame.time.Clock()
drag = 0 #switch with which I am seting if I can move the image
x = 100 #x, y coordinates of the image
y = 100
img = pygame.image.load('button.png') #my image and then his width and height
imgWidth = 100
imgHeight = 100
def image(imgX,imgY): #function to blit image easier
gameDisplay.blit(img, (imgX, imgY))
def movableImg(): #function in which i am moving image
global drag, x, y
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
image(x, y)
if click[0] == 1 and x + imgWidth > mouse[0] > x and y + imgHeight > mouse[1] > y: #asking if i am within the boundaries of the image
drag = 1 #and if the left button is pressed
if click[0] == 0: #asking if the left button is pressed
drag = 0
if drag == 1: #moving the image
x = mouse[0] - (imgWidth / 2) #imgWidth / 2 because i want my mouse centered on the image
y = mouse[1] - (imgHeight / 2)
def main_loop():
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
gameDisplay.fill(white)
movableImg()
pygame.display.update()
clock.tick(60)
main_loop()
pygame.quit()
quit()
So here's the code that I found on the internet and which is working as I want to. SOURCE
import os,sys
import pygame as pg #lazy but responsible (avoid namespace flooding)
class Character:
def __init__(self,rect):
self.rect = pg.Rect(rect)
self.click = False
self.image = pg.Surface(self.rect.size).convert()
self.image.fill((255,0,0))
def update(self,surface):
if self.click:
self.rect.center = pg.mouse.get_pos()
surface.blit(self.image,self.rect)
def main(Surface,Player):
game_event_loop(Player)
Surface.fill(0)
Player.update(Surface)
def game_event_loop(Player):
for event in pg.event.get():
if event.type == pg.MOUSEBUTTONDOWN:
if Player.rect.collidepoint(event.pos):
Player.click = True
elif event.type == pg.MOUSEBUTTONUP:
Player.click = False
elif event.type == pg.QUIT:
pg.quit(); sys.exit()
if __name__ == "__main__":
os.environ['SDL_VIDEO_CENTERED'] = '1'
pg.init()
Screen = pg.display.set_mode((1000,600))
MyClock = pg.time.Clock()
MyPlayer = Character((0,0,150,150))
MyPlayer.rect.center = Screen.get_rect().center
while 1:
main(Screen,MyPlayer)
pg.display.update()
MyClock.tick(60)
You don't need the function. All you need is some events in your for loop. Instead of a messy, complicated function, you can simply figure out when the mouse is clicked:
for event in pygame.event.get():
if event.type == MOUSEBUTTONDOWN: #Remember to use: from pygame.locals import *
coordinates = pygame.mouse.get_pos()
#set x and y to respective values of coordinates
#Enter necessary code here after
Now coordinates is a pre-defined variable I made up here, in this case, it is used to store the coordinates of your mouse. When event.type is MOUSEBUTTONDOWN, it means that the mouse has been clicked and the program should begin to do the code under that if statement. The events will only activate once, whihc means you cannot drag. I recommend that you create a function that allows the event to continue if the user is holding down on the mouse like this:
def holding():
global held, coordinates
if held:
coordinates = pygame.mouse.get_pos()
#Enter code here
held will be a Boolean variable: it will be equal to True if the mouse if being clicked or to False if not. In this case to prevent the program to think you are clicking the mouse infinitely, add another if statement to check whether the mouse has been released and if so, change held to False:
if event.type == MOUSEBUTTONUP:
held = False
also, to make sure that the function will actually register the fact that the mouse is still being held down, put this line in the if statement for the MOUSEBUTTONDOWN event:
held = True
And finally, to run the function, add an if statement in front of your for loop to run the function when needed:
if held:
holding
TO move multiple images, change their positions to be equal to coordinates or somehow related to coordinates. The if statements do not have to move only one image at a time.