How to print out background image using "blit" in pygame? [duplicate] - python

This question already has answers here:
Why is nothing drawn in PyGame at all?
(2 answers)
Closed 1 year ago.
import pygame
import os
pygame.font.init()
pygame.mixer.init()
WIDTH, HEIGHT = 900, 500
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("HELP ME")
WHITE = (255, 255, 255)
black = (0, 0, 0)
MENU_bg = pygame.transform.scale(pygame.image.load(os.path.join("menu.png")), (WIDTH, HEIGHT))
quiting = 0
def main_menu():
running = True
quiting = 0
clock = pygame.time.Clock()
FPS = 60
WIN.blit(MENU_bg, (0, 0))
while running:
clock.tick(FPS)
if quiting == 1:
exit()
WIN.blit(MENU_bg, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
quiting = 1
if event.type == pygame.MOUSEBUTTONUP:
mouse_pos = pygame.mouse.get_pos()
print(mouse_pos)
if mouse_pos[0] >= 0 and mouse_pos[0] <= 450 and mouse_pos[1] >= 200 and mouse_pos[1] <= 500:
running = False
# Here I will link to another function
I get no error messages when running the code, but the images don´t show up. The image files are available and their right names have been used. I have read several tutorials and don´t see what I´ve done wrong.

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():
def main_menu():
# [...]
while running:
clock.tick(FPS)
if quiting == 1:
exit()
WIN.blit(MENU_bg, (0, 0))
# [...]
pygame.display.flip()

Related

Pygame mouse hover [duplicate]

This question already has answers here:
Pygame mouse clicking detection
(4 answers)
How do I add a border to a sprite when the mouse hovers over it, and delete it after the mouse stops?
(1 answer)
Closed 5 months ago.
So im trying to remake a simple card game in pygame. Im trying to make it where whenever you hover over a card it will turn slightly transparent by changing the alpha of the card.
However I can't seem to get this to work and im genuinely confucious as to why my code doesnt work.
while running:
mX, mY = pygame.mouse.get_pos()
if 50 + 60 > mX > 50 and 500 + 84 > mY > 500:
hand[0].set_alpha(100)
else:
hand[0].set_alpha(255)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#Hover()
if printHand:
#print(hand)
#print(cardSize)
#print(hand[0].get_width())
#print(hand[0].get_height())
#print(hand[0].get_rect(center=(80, 542)))
printHand = False
if displayHand:
DisplayHand(hand)
DisplayBoard(pile1)
DisplayBoard(pile2)
displayHand = False
print(50 + 60 > mX > 50 and 500 + 84 > mY > 500)
pygame.display.update()
Where hand is an array of surfaces from image.load
As of right now this code doesnt do anything but the print statement at the end returns true
Here is a minimal example that creates a Card sprite with two images, swapping the image if the mouse is over the card.
import pygame
WIDTH = 640
HEIGHT = 480
FPS = 30
class Card(pygame.sprite.Sprite):
"""A playing card like sprite"""
def __init__(self, color="white", pos=(0, 0)):
pygame.sprite.Sprite.__init__(self)
self.color = pygame.Color(color)
# if you're loading an image, make sure to use .convert()
self.orig_image = pygame.Surface((50, 100), pygame.SRCALPHA)
self.orig_image.fill(self.color)
# create a copy of the image
self.alt_image = self.orig_image.copy()
self.alt_image.set_alpha(127) # make the copy transparent
self.image = self.orig_image
self.rect = self.image.get_rect(center=pos)
def update(self):
if self.rect.collidepoint(pygame.mouse.get_pos()):
self.image = self.alt_image
else:
self.image = self.orig_image
pygame.init()
window = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
cards = pygame.sprite.Group()
# create five cards distributed across the bottom of the screen
for x in range(5):
card = Card(pos=((x + 1) * (WIDTH // 6), HEIGHT - 90))
cards.add(card)
pygame.display.set_caption("♠♣♥♦ Cards")
paused = False
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYUP:
pass
# update game elements
cards.update()
# draw surface - fill background
window.fill("black")
## draw sprites
cards.draw(window)
# show surface
pygame.display.update()
# limit frames
clock.tick(FPS)
pygame.quit()
This will look like this, although the screenshot doesn't include the mouse cursor:

How can I limit the screen in pygame? [duplicate]

This question already has answers here:
Setting up an invisible boundary for my sprite
(1 answer)
Use vector2 in pygame. Collide with the window frame and restrict the ball to the rectangular area
(1 answer)
How to make ball bounce off wall with PyGame?
(1 answer)
Not letting the character move out of the window
(2 answers)
Closed 10 months ago.
I just started trying out pygame, so I watched a tutorial. When the guy showed, how to create edges left and right from the screen, it just didn't work when I did it, even though I've written it 100% equal as the tutorial guy. The tutorial is already two years old, so maybe pygame just has changed. Can somebody help me?
That's my code:
import pygame
import sys
pygame.init()
background = pygame.image.load("C:\Programmieren\Python\Grafiken\pygame test1 - background.png")
screen = pygame.display.set_mode([1200,595])
clock = pygame.time.Clock()
pygame.display.set_caption("pygame test1")
def draw():
screen.blit(background, (0, 0))
pygame.draw.rect(screen, (0, 0, 255), (x, y, width, height))
pygame.display.update()
x = 300
y = 300
speed = 3
width = 40
height = 80
left_wall = pygame.draw.rect(screen, (0,0,0), (-2,0,2,600), 0)
right_wall = pygame.draw.rect(screen, (0,0,0), (1201,0,2,600), 0)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()
character = pygame.Rect(x,y,width, height)
pressed = pygame.key.get_pressed()
if presses[pygame.K_UP] or pressed[pygame.K_w] or pressed[pygame.K_SPACE]:
y -= speed
if pressed[pygame.K_RIGHT] or pressed[pygame.K_d] and not character.colliderect(right_wall):
x += speed
if pressed[pygame.K_DOWN] or pressed[pygame.K_s]:
y += speed
if pressed[pygame.K_LEFT] or pressed[pygame.K_a] and not character.colliderect(left_wall):
x -= speed
draw()
clock.tick(60)
The following code works for me after replacing the background.png path with a picture that exists on my computer. I changed left_wall and right_wall to call pygame.Rect instead of pygame.draw.rect and copied the draw.rect calls that were previously assigned to left_wall and right_wall to draw() function, and added some needed parentheses in two of the if statements. Also fixed a typo where pressed was spelled presses.
Without the parentheses, the character would always move right when right key is pressed even past the right edge of the window. When "d" is pressed, it would check against colliderect. Same for left arrow and "a" keys. or short-circuits, so if K_RIGHT or K_LEFT is pressed, it doesn't check the right hand side of the or in the if statements. With the parentheses added, the "move right" if statement always checks colliderect when K_RIGHT or K_d is pressed, instead of only when K_d is pressed.
import pygame
import sys
pygame.init()
background = pygame.image.load("C:\Programmieren\Python\Grafiken\pygame test1 - background.png")
screen = pygame.display.set_mode([1200,595])
clock = pygame.time.Clock()
pygame.display.set_caption("pygame test1")
def draw():
screen.blit(background, (0, 0))
pygame.draw.rect(screen, (0, 0, 255), (x, y, width, height))
pygame.draw.rect(screen, (0,0,0), left_wall, 0)
pygame.draw.rect(screen, (0,0,0), right_wall, 0)
pygame.display.update()
x = 300
y = 300
speed = 3
width = 40
height = 80
left_wall = pygame.Rect(-2,0,2,600)
right_wall = pygame.Rect(1201,0,2,600)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()
character = pygame.Rect(x,y,width, height)
pressed = pygame.key.get_pressed()
if pressed[pygame.K_UP] or pressed[pygame.K_w] or pressed[pygame.K_SPACE]:
y -= speed
if (pressed[pygame.K_RIGHT] or pressed[pygame.K_d]) and not character.colliderect(right_wall):
x += speed
if pressed[pygame.K_DOWN] or pressed[pygame.K_s]:
y += speed
if (pressed[pygame.K_LEFT] or pressed[pygame.K_a]) and not character.colliderect(left_wall):
x -= speed
draw()
clock.tick(60)

Mouse coordinates not changing - python

I am trying to build a simple game, but I'm having trouble with the mouse as it's doesn't show that it's coordinates are changing.
Here's my code:
import pygame
pygame.init()
# Colors
white = (255, 255, 255)
black = (0, 0, 0)
blue = (0, 0, 255)
# Game Screen Dimensions
game_layout_length = 500
game_layout_width = 500
# Mouse Positions
pos = pygame.mouse.get_pos()
# Character Attributes
character_length = 10
character_width = 10
game_screen = pygame.display.set_mode((game_layout_width, game_layout_length))
game_close = False
game_lost = False
while not game_close:
while not game_lost:
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_close = True
game_lost = True
if event.type == pygame.MOUSEBUTTONDOWN:
print(pos)
game_screen.fill(black)
pygame.display.update()
pygame.quit()
quit()
This is the result after clicking on multiple different parts of the screen:
pygame 2.1.2 (SDL 2.0.18, Python 3.8.2)
Hello from the pygame community. https://www.pygame.org/contribute.html
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
Process finished with exit code 0
Also, is there a way to get a rectangle to follow my mouse? I tried doing pygame.mouse.rect(game_screen, blue, [pos, character_length, character_width]), but that just crashed my program.
So, the problem is that you are not refreshing the mouse position, because is not in the loop. All you need to do is to put the pos variable inside the loop.
Here is how should you do it:
if event.type == pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
print(pos)
game_screen.fill(black)
pygame.display.update()
This is the answer for your second question:
So, the issue there is that after you draw the rectangle, you are filling the screen with black, so, all the rectangles are covered up with the color black.
All you need to do is to delete game_screen.fill(black) and it will work.
Thanks, I successfully set a variable to my x and y coordinates but when I try to make something (like a rectangle) follow my mouse, it doesn't work or even show up. The program just executes a plain black screen.
Here's my code:
import pygame
pygame.init()
# Colors
white = (255, 255, 255)
black = (0, 0, 0)
blue = (0, 0, 255)
# Game Screen Dimensions
game_layout_length = 500
game_layout_width = 500
# Character Attributes
character_length = 10
character_width = 10
game_screen = pygame.display.set_mode((game_layout_width, game_layout_length))
game_close = False
game_lost = False
while not game_close:
while not game_lost:
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_close = True
game_lost = True
if event.type == pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
character_x = pos[0]
character_y = pos[1]
pygame.draw.rect(game_screen, blue, [character_x, character_y, character_length, character_width])
game_screen.fill(black)
pygame.display.update()
pygame.quit()
quit()
I used a debug line to see if it was an issue with the variables, but those seemed to be working just fine, so I'm unsure where the issue is.

I can't draw a circle with pygame in python 3.7.7 [duplicate]

This question already has answers here:
Why is my pygame application loop not working properly?
(1 answer)
Pygame window not responding after a few seconds
(3 answers)
Closed 2 years ago.
I've look for the docs, many video on YouTube, questions on stackoverflow but I still can't fix it.This is my code:
import pygame
pygame.init()
run = True
#color def
BK = (0, 0, 0)
WT = (255, 255, 255)
GY = (127, 127, 127)
#create screen
screen = pygame.display.set_mode((800,600))
#title, icon
pygame.display.set_caption("Clock")
icon = pygame.image.load("clock.png")
pygame.display.set_icon(icon)
#loop
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.draw.circle(screen, WT, (0, 0), 175, width=1)
You missed to update the display by by either pygame.display.update() or pygame.display.flip(). And you need to draw circle in the application loop. Care about the Indentation:
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#-->| INDENTATION
# clear display
screen.fill(0)
# draw scene (circle)
pygame.draw.circle(screen, WT, (0, 0), 175, width=1)
# update display
pygame.display.flip()

Pygame keeps crashing when I open it

I've have this dodging aliens game and it's not working. I can get the front begin screen to open but then when I hit enter to start it crashes and freezes. I've tried running it from python.exe instead of just IDLE but in that case it just pops up then closes right down. A few errors popped up the first few times I tried to run it but now there are no errors indicating what might be wrong. It just stops responding. What am I doing wrong here?
import pygame, random, sys
from pygame.locals import *
def startGame():
if event.type == K_ENTER:
if event.key == K_ESCAPE:
sys.exit()
return
def playerCollision():
for a in aliens:
if playerRect.colliderect(b['rect']):
return True
return False
pygame.init()
screen = pygame.display.set_mode((750,750))
clock = pygame.time.Clock()
pygame.display.set_caption('Dodge the Aliens')
font = pygame.font.SysFont(None, 55)
playerImage = pygame.image.load('')
playerRect = playerImage.get_rect()
alienImage = pygame.image.load('')
drawText('Dodge the Aliens!', font, screen, (750 / 3), (750 / 3))
drawText('Press ENTER to start.', font, screen, (750 / 3) - 45, (750 / 3) + 65)
pygame.display.update()
topScore = 0
while True:
aliens = []
score = 0
playerRect.topleft = (750 /2, 750 - 50)
alienAdd = 0
while True:
score += 1
pressed = pygame.key.get_pressed()
if pressed[pygame.K_LEFT]: x -=3
if pressed[pygame.K_RIGHT]: x += 3
if pressed[pygame.K_ESCAPE]: sys.exit()
alienAdd += 1
if alienAdd == addedaliens:
aliendAdd = 0
alienSize = random.randint(10, 40)
newAlien = {'rect': pygame.Rect(random.randint(0, 750 - alienSize), 0 -alienSize, alienSize, alienSize), 'speed': random.randint(1, 8), 'surface':pygame.transform.scale(alienImage, (alienSize, alienSize)), }
aliens.append(newAlien)
for a in aliens[:]:
if a['rect'].top > 750:
aliens.remove(a)
screen.fill(0,0,0)
drawText('Score %s' % (score), font, screen, 10, 0)
screen.blit(playerImage, playerRect)
for a in aliens:
screen.blit(b['surface'], b['rect'])
pygame.display.update()
if playerCollision(playerRect, aliens):
if score > topScore:
topScore = score
break
clock.tick(60)
drawText('Game Over!', font, screen, (750 / 3), ( 750 / 3))
drawText('Press ENTER To Play Again.', font, screen, ( 750 / 3) - 80, (750 / 3) + 50)
pygame.display.update()
startGame()
Here's my new code after modifying it some
import pygame, random, sys
from pygame.locals import*
alienimg = pygame.image.load('C:\Python27\alien.png')
playerimg = pygame.image.load('C:\Python27\spaceship.png')
def playerCollision(): # a function for when the player hits an alien
for a in aliens:
if playerRect.colliderect(b['rect']):
return True
return False
def screenText(text, font, screen, x, y): #text display function
textobj = font.render(text, 1, (255, 255, 255))
textrect = textobj.get_rect()
textrect.topleft = (x,y)
screen.blit(textobj, textrect)
def main(): #this is the main function that starts the game
pygame.init()
screen = pygame.display.set_mode((750,750))
clock = pygame.time.Clock()
pygame.display.set_caption('Dodge the Aliens')
font = pygame.font.SysFont("monospace", 55)
pressed = pygame.key.get_pressed()
aliens = []
score = 0
alienAdd = 0
addedaliens = 0
while True: #our while loop that actually runs the game
for event in pygame.event.get(): #key controls
if event.type == KEYDOWN and event.key == pygame.K_ESCAPE:
sys.exit()
elif event.type == KEYDOWN and event.key == pygame.K_LEFT:
playerRect.x -= 3
elif event.type == KEYDOWN and event.key == pygame.K_RIGHT:
playerRect.x += 3
playerImage = pygame.image.load('C:\\Python27\\spaceship.png').convert() # the player images
playerRect = playerImage.get_rect()
playerRect.topleft = (750 /2, 750 - 50)
alienImage = pygame.image.load('C:\\Python27\\alien.png').convert() #alien images
alienAdd += 1
pygame.display.update()
if alienAdd == addedaliens: # randomly adding aliens of different sizes and speeds
aliendAdd = 0
alienSize = random.randint(10, 40)
newAlien = {'rect': pygame.Rect(random.randint(0, 750 - alienSize), 0 -alienSize, alienSize, alienSize), 'speed': random.randint(1, 8), 'surface':pygame.transform.scale(alienImage, (alienSize, alienSize)), }
aliens.append(newAlien)
for a in aliens[:]:
if a['rect'].top > 750:
aliens.remove(a) #removes the aliens when they get to the bottom of the screen
screen.blit(screen, (0,0))
screenText('Score %s' % (score), font, screen, 10, 0)
screen.blit(playerImage, playerRect)
for a in aliens:
screen.blit(b['surface'], b['rect'])
pygame.display.flip()
if playerCollision(playerRect, aliens):
if score > topScore:
topScore = score
break
clock.tick(60)
screenText('Game Over!', font, screen, (750 / 6), ( 750 / 6))
screenText('Press ENTER To Play Again.', font, screen, ( 750 / 6) - 80, (750 / 6) + 50)
pygame.display.update()
main()
I still see several issues with your code and I think you're trying to do too much at once for the very beginning. Try to keep it as simple as possible. Try creating a display and draw some image:
import pygame
pygame.init()
display = pygame.display.set_mode((750, 750))
img = pygame.image.load("""C:\\Game Dev\\alien.png""")
display.blit(img, (0, 0))
pygame.display.flip()
You'll have to adjust the img path of course. Running this you should either get an explicit Error (which you should then post in another thread) or see your img on the screen. BUT the program will not respond as there's no event handling and no main loop at all.
To avoid this, you could introduce a main loop like:
import sys
import pygame
pygame.init()
RESOLUTION = (750, 750)
FPS = 60
display = pygame.display.set_mode(RESOLUTION)
clock = pygame.time.Clock()
img = pygame.image.load("""C:\\Game Dev\\alien.png""")
while True: # <--- game loop
# check quit program
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# clear the screen
display.fill((0, 0, 0))
# draw the image
display.blit(img, (0, 0))
# update the screen
pygame.display.flip()
# tick the clock
clock.tick(FPS)
This should result in a program that displays the same img over and over, and it can be quit properly using the mouse. But still it's like a script, and if someone imported this, it would execute immediately, which is not what we want. So let's fix that as well and wrap it all up in a main function like this:
import sys
import pygame
#defining some constants
RESOLUTION = (750, 750)
FPS = 60
def main(): # <--- program starts here
# setting things up
pygame.init()
display = pygame.display.set_mode(RESOLUTION)
clock = pygame.time.Clock()
img = pygame.image.load("""C:\\Game Dev\\alien.png""")
while True: # <--- game loop
# check quit program
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# clear the screen
display.fill((0, 0, 0))
# draw the image
display.blit(img, (0, 0))
# update the screen
pygame.display.flip()
# tick the clock
clock.tick(FPS)
if __name__ == "__main__":
main()
The 'if name == "main":' ensures that the program does not execute when it's imported.
I hope this helps. And remember: Don't try too much all at once. Take small steps, one after another, and try to keep the control over your program. If needed, you can even put a print statement after every single line of code to exactly let you know what your program does and in what order.

Categories

Resources