How can I move a sprite image in pygame with my mouse? - pygame

Okay, I was given this project two weeks ago to create a simple chess game with the same rules as you would play in real life, and the project is due in a week. I really need help on how do I move the pawn or any chess piece up a space by using the mouse (not the keyboard).

Okay, so if you want to make the (lets just take a pawn for this example) move up y pixels, you will want your code to be something like this.
screen.blit(pawn,(x,y))
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# key goes down? look for that
if event.type == pygame.MOUSEBUTTONDOWN:
if event.key == pygame.K_UP:
keys[0] = True
then later in your code all of this of course in the main game loop
if keys[0]
y += 10
This requires some variables/images such as pawn, keys, and x/y to be defined. Cheers! also always check the docs before posting here.

Related

Pygame screen initialisation odd artefacts

I want to learn pygame and code small fun games with it. So I have started learning this library.
After running this code;
import pygame
from sys import exit
pygame.init()
display_surface = pygame.display.set_mode((800, 400))
pygame.display.set_caption("My Game")
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
# draw all our elements
# update everything
pygame.display.update()
I see a black screen but there are some artefacts in the screen, like this;
The screen I am talking about
In the Youtube tutorial I am following, the screen is solid black. I don't understand why my screen is different and has some green points in it. My computer works normally and if I restart the program or the computer nothing changes. The pattern is always the same. I can of course fill the display surface black with extra code, and then it works.
My question is, why do I have these points on the display surface in the first place? If someone is knowledgeable about the topic; what do these green lines mean?
I am just curious : )
MacOS Mojave 10.14.6
You must clear the screen with display_surface.fill(0):
run = True
while run :
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
display_surface.fill(0)
# draw all our elements
# update everything
pygame.display.update()
pygame.quit()
exit()

How to preserve what is on the old screen after rescaling a pygame window?

I am trying to make a pygame window that can be resized but after resizing it just deletes everything on it. So I thought of a solution on my own.
pygame.init()
screen=pygame.display.set_mode((640,360),pygame.RESIZABLE)
clock=pygame.time.Clock()
screen.blit(somesurface,(0,0))
pygame.display.flip()
while True:
clock.tick(100)
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
sys.exit()
if event.type==pygame.VIDEORESIZE:
old=screen
screen=pygame.display.set_mode(event.size,pygame.RESIZABLE)
screen.blit(old,(0,0))
del old
pygame.display.flip()
But this doesnt work. The blitted surface just disappears after resizing.
I'm using python 3.8.5 and pygame 1.9.6
The main issue is that pygame.display.set_mode does not create a new surface object. It just resets the existing one. When you're 'saving' the old surface, you're just creating another reference to the same object. If you want to save the current screen surface, use surface.copy().
I updated your code to copy the screen then redraw the saved screen surface centered on the new screen. I also print the screen memory address before and after set_mode. You can see the screen address doesn't change.
import pygame
pygame.init()
screen=pygame.display.set_mode((640,360),pygame.RESIZABLE)
clock=pygame.time.Clock()
somesurface = pygame.Surface((640,360)) # new surface
somesurface.fill((255,255,255)) # fill white
pygame.draw.circle(somesurface,(100,100,255),(320,190),50) # draw blue circle
screen.blit(somesurface,(0,0)) # draw surface onto screen
pygame.display.flip()
while True:
clock.tick(100)
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
exit()
if event.type==pygame.VIDEORESIZE:
print(id(screen)) # memory address of screen object
old=screen.copy() # copy current screen to temp surface
screen=pygame.display.set_mode(event.size,pygame.RESIZABLE) # reset screen
print(id(screen)) # memory address of 'new' screen object, same address :(
screen.blit(old,((event.w-old.get_width())//2,(event.h-old.get_height())//2)) # draw back temp surface centered
del old # delete temp surface
pygame.display.flip()

Why does my code for closing a pygame program behave differently in different programs?

I made a game in snake that closes the window, but not the shell when you lose. I copy-pasted the same code into another program that allows you to do this by pressing a button (note that I'm not using the tkinter module for the button, just pygame). When I press the button, the window closes but pops back up. There is no difference in the code between the two programs, so I don't understand what's wrong.
Here's the code I used in my snake game to close the window without closing the shell:
if (x,y) in path:
print("You lose. Your length was", length)
pygame.quit()
break
What's even stranger is that in my button program, the break command makes no difference regardless of if its there or not. With the snake game, I had to put that in there to stop the shell from throwing out an error message, which the button program doesn't have a problem with. I don't understand why this one function would behave differently in the two programs. There is nothing else that could be affecting it!
edit: I should note that, obviously, I remove the 'print' line which pulls a variable from my snake game. So the code in my button program is just:
for event in pygame.event.get():
cx,cy=pygame.mouse.get_pos()
if event.type==pygame.QUIT:
pygame.quit()
quit()
if event.type==pygame.MOUSEBUTTONDOWN:
if cx>(windowWidth-buttonWidth)/2 and\
cx<(windowWidth-buttonWidth)/2+buttonWidth and\
cy>(windowHeight-buttonHeight)/2 and\
cy<(windowHeight-buttonHeight)/2+buttonHeight:
pygame.quit()
break
As for the strange variables, I used those to center my button the screen. The program is just a test I was running to figure out how to make buttons for another program I'm planning.
pygame.quit() doesn't end program but only "close" pygame's modules so code is still running. If you have ie. pygame.display.flip(), screen.blit(), etc few lines later in for-loop then it may still try to execute it and get error because modules are closed - values are deleted, window is closed, etc.
break exits for-loop and it may skip line which makes problem. This is why there is quit() which ends program.
You can also use pygame.quit() after exiting mainloop when there is no other command which uses pygame.

My screen's black after I tried to implement collision and gravity in my game [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

a white grid over a black background in pygame [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