I want to move the apple image to a random position whenever i click it.The first time i click it , it works well but next time i try to do it , it gives me no response.
Here is the code:
import pygame
pygame.init()
foodimg=pygame.image.load("food.png")
foodrect=foodimg.get_rect()
white = (255,255,255)
#Game Display
display_width = 1080
display_height = 720
gameDisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('Click It! ~ Snapnel Productions')
gameDisplay.fill((white))
running=True
while running:
gameDisplay.fill((white))
for event in pygame.event.get():
if event.type==pygame.QUIT:
running=False
pygame.quit()
quit()
if event.type == pygame.MOUSEBUTTONDOWN:
# Set the x, y postions of the mouse click
x, y = event.pos
if foodimg.get_rect().collidepoint(x, y):
foodrect.center=(random.randint(5,1060),random.randint(5,700))
print "Hi",
continue
gameDisplay.blit(foodimg,foodrect)
pygame.display.flip()
is the food image.
Change the line
if foodimg.get_rect().collidepoint(x, y):
to
if foodrect.collidepoint(x, y):
Your code didn't work because the rectangle of the picture never moves, it's always going to be <rect(0, 0, 30, 30)>. Foodrect actually represents where your rectangle is located and it's the rect whos values you change when you run foodrect.center =. You want to check if the mouse click is colliding with the real rect, not the rect of the image.
Related
I was trying to make a code that moves a rect object (gotten with the get_rect function) but I need its coordinates to make it move 1 pixel away (if there are any other ways to do this, let me know.)
Here is the code:
import sys, pygame
pygame.init()
size = width, height = 1920, 1080
black = 0, 0, 0
screen = pygame.display.set_mode(size)
ball = pygame.image.load("ball.png")
rectball = ball.get_rect()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()
rectball.move()
screen.fill(black)
screen.blit(ball, rectball)
pygame.display.flip()
You will notice that on line 11 the parameters are unfilled. This is because I was going to make it coords + 1.
If I am correct I think it is rect.left or rect.top that gives it. Another method is to create another rectangle and check if the rectangle is in that.
This question already has answers here:
Pygame mouse clicking detection
(4 answers)
Closed 4 months ago.
I'm trying to make a cookie clicker clone, but my code can't detect when the grandma button is pressed.
Here is my code:
import pygame
pygame.init()
display_width = 800
display_height = 600
gameDisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('Cookie Clicker')
black = (0,0,0)
white = (255,255,255)
clock = pygame.time.Clock()
crashed = False
cookie = pygame.image.load('cookie.png')
grandma = pygame.image.load('grandma.png')
cookies = 0
def car(x,y):
gameDisplay.blit(cookie, (x,y))
def grandshop(x,y):
gameDisplay.blit(grandma, (xx,yy))
x = 0
y = 0
xx = 450
yy = 20
while not crashed:
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
if event.type == pygame.MOUSEBUTTONDOWN:
# Set the x, y postions of the mouse click
mouse_pos = pygame.mouse.get_pos()
if cookie.get_rect().collidepoint(mouse_pos):
if event.button == 1:
cookies += 1
pygame.display.set_caption(f'Cookies: {cookies}')
else:
break
if grandma.get_rect().collidepoint(mouse_pos):
print("It actually worked! :)")
gameDisplay.fill(white)
car(x,y)
grandshop(xx,yy)
pygame.display.update()
clock.tick(60)
pygame.quit()
quit()
I had expected it to print out "It actually worked! :)" when the grandma image was clicked.
Change appropriate lines in your code to:
if cookie.get_rect(topleft=(x,y)).collidepoint(mouse_pos):
and
if grandma.get_rect(topleft=(xx,yy)).collidepoint(mouse_pos):
The .get_rect() method called without parameter gives you the rectangle of the loaded image with the left upper corner set to (0, 0) and not to the actual position of the image on the screen. This was the reason why a click on cookie was also hconsidered to be a click on grandma and a click on grandma gave False as result of .collidepoint().
The .get_rect() method allows passing of a keyword parameter to obtain the rectangle coordinates of the rectangle moved to a with (x,y) specified screen position. The keyword used for this purpose in the code above is ,topleft=(xx,yy). Another known to me keyword parameter allowed in .get_rect() are center and bottomright.
I use Pygame in this code. This is like a game that when user hit mouse button, from the mouse position comes a laser image that will go up, and eventually go out of the screen. I am trying to blit an image when the user hit mouse button. This code I am using does not work and I do not know why. My problem starts at the main for loop
import pygame
# Initialize Pygame
pygame.init()
#___GLOBAL CONSTANTS___
# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
# Set the height and width of the screen
screen_width = 500
screen_height = 500
screen = pygame.display.set_mode([screen_width, screen_height])
#Load Laser image of spaceship
laser_image = pygame.image.load('laserRed16.png').convert()
#Load sound music
sound = pygame.mixer.Sound('laser5.ogg')
# Loop until the user clicks the close button.
done = False
# Used to manage how fast the screen updates
clock = pygame.time.Clock()
# -------- Main Program Loop -----------
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEBUTTONDOWN:
# Get the current mouse position. This returns the position
# as a list of two numbers.
sound.play()
#Get the mouse position
mouse_position = pygame.mouse.get_pos()
mouse_x = mouse_position[0]
mouse_y = mouse_position[1]
# Set the laser image when the spaceship fires
for i in range(50):
screen.blit(laser_image,[mouse_x + laser_x_vector,mouse_y + laser_x_vector])
laser_x_vector += 2
laser_x_vector += 2
# Clear the screen
screen.fill(WHITE)
#Limit to 20 sec
clock.tick(20)
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
pygame.quit()
You fill the screen after you blit the lazer, so the lazer will not appear. You should fill before you blit the lazer so the lazer appears.
The others have already explained why you don't see the laser. Here's a working solution for you. First I suggest to use pygame.Rects for the positions of the lasers and put them into a list (rects can also be used for collision detection). Then iterate over these positions/rects in the main while loop, update and blit them. I also show you how to remove rects that are off screen.
import pygame
pygame.init()
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
screen_width = 500
screen_height = 500
screen = pygame.display.set_mode([screen_width, screen_height])
laser_image = pygame.Surface((10, 50))
laser_image.fill(GREEN)
done = False
clock = pygame.time.Clock()
laser_rects = []
laser_velocity_y = -20
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEBUTTONDOWN:
# Turn the mouse position into a rect with the dimensions
# of the laser_image. You can use the event.pos instead
# of pygame.mouse.get_pos() and pass it as the `center`
# or `topleft` argument.
laser_rect = laser_image.get_rect(center=event.pos)
laser_rects.append(laser_rect)
remaining_lasers = []
for laser_rect in laser_rects:
# Change the y-position of the laser.
laser_rect.y += laser_velocity_y
# Only keep the laser_rects that are on the screen.
if laser_rect.y > 0:
remaining_lasers.append(laser_rect)
# Assign the remaining lasers to the laser list.
laser_rects = remaining_lasers
screen.fill(WHITE)
# Now iterate over the lasers rect and blit them.
for laser_rect in laser_rects:
screen.blit(laser_image, laser_rect)
pygame.display.flip()
clock.tick(30) # 30 FPS is smoother.
pygame.quit()
I am trying to make a game in which you have to click the apple and then it goes off to random position.You have 5 seconds (for now), and you have to click the apple image many times as you cant.My game works but i have two problems:
1)After the game ends , the program does not respond.
2)The time keeps on updating itself (it keeps on flickering) i do not want that.
How do I correct these two bugs?
Here is my code:
import pygame
import time
import random
pygame.init()
foodimg=pygame.image.load("food.png")
foodrect=foodimg.get_rect()
#Colours
white = (255,255,255)
black = (0,0,0)
red = (255,0,0)
#Game Display
display_width = 1080
display_height = 720
gameDisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('Click It! ~ Snapnel Productions')
gameDisplay.fill((white))
font=pygame.font.SysFont("Arial",30)
a=6
running=True
while running:
gameDisplay.fill((white))
time=pygame.time.get_ticks()/1000
if a==time:
print "Game over"
break
for event in pygame.event.get():
if event.type==pygame.QUIT:
running=False
pygame.quit()
quit()
if event.type == pygame.MOUSEBUTTONDOWN:
# Set the x, y postions of the mouse click
x, y = event.pos
if foodrect.collidepoint(x, y):
foodrect.center=(random.randint(5,1060),random.randint(5,700))
print "New Position: ",foodrect.center
continue
gameDisplay.blit(foodimg,foodrect)
pygame.display.flip()
showtime=font.render("Time: "+str(time),0,(0,0,0))
gameDisplay.blit(showtime,(950,10))
pygame.display.flip()
Here is my food image.
For me the program exits normally (i ran it on linux, python 2.6).
To remove flockering:
gameDisplay.blit(foodimg,foodrect)
#pygame.display.flip() < -- remove that
showtime=font.render("Time: "+str(time),0,(0,0,0))
gameDisplay.blit(showtime,(950,10))
pygame.display.flip() # because you should do it after the text is drawed
Flip is used to update surface. You need to update surface after you have everything drawed. What you do is fill everything white, update and then draw a text, update. So you have text drawed and filled white every tick
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.