Why is my character not appearing in my pygame window? - python

so i'm coding this pygame for fun just to test my knowledge in this area and i'm facing a minor problem. My character is not appearing on the pygame window except for like a second when i press the X button to close the tab, here is what i've coded so far.
import pygame
pygame.init
window = pygame.display.set_mode((700 , 700))
pygame.display.set_caption("practice")
#Character attributes
x = 50
y = 50
width = 30
height =30
velocity = 5
#quit
run = True
while run:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.draw.rect(window, (0, 0, 255), (x , y, width, height))
pygame.display.update()
pygame.quit()

It's a common problem when people forget to indent code inside nested loops right. Here drawing occurs only when event happens, but it should be done on every frame. To fix this unindent render code
while run:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.draw.rect(window, (0, 0, 255), (x , y, width, height))
pygame.display.update()

Related

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.

How can i give my image an initial position before it starts moving with the mouse?

I'm working on this pygame game and i'm just getting started but got a bit confused because i want the image to move in the x-axis along with the mouse but when i run the program i want the image to show up at the center or the 'floor' but appears at the left side instead. This is my code and a screenshot of what's happening.
import pygame
import sys
pygame.init()
pygame.mixer.init()
WIDTH, HEIGHT = 400, 500
FPS = 60
TITLE = 'FOOD DROP'
SIZE = 190
# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BLUE_SKY = (152, 166, 255)
# Display
SCREEN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption(TITLE)
# Surfaces
floor_surface = pygame.Surface((WIDTH, 100))
floor_surface.fill(BLUE_SKY)
floor_rect = floor_surface.get_rect(midbottom=(200, 500))
# Images
LOAD_DITTO = pygame.image.load('Graphics/ditto.png')
DITTO = pygame.transform.scale(LOAD_DITTO, (SIZE, SIZE))
# Time
CLOCK = pygame.time.Clock()
class Figure:
def draw_figure(self, mouse_x):
SCREEN.blit(DITTO, (mouse_x - 90, 330))
# Game loop
SCREEN_UPDATE = pygame.USEREVENT
# main_game = Main()
figure = Figure()
running = True
while running:
CLOCK.tick(FPS)
mx, my = pygame.mouse.get_pos()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
SCREEN.fill(WHITE)
SCREEN.blit(floor_surface, floor_rect)
figure.draw_figure(mx)
pygame.display.update()
When i run the program, this happens:
And i want the image to appear right at the center or the x-axis, not the border, i don't know why is this happening. Just to state, that screenshot was taken when the mouse hadn't been placed over the display.
If the mouse pointer is not in the window (out of focus), the initial position of the mouse pointer is (0, 0). Therefore pygame.mouse.get_pos returns (0, 0). It is also not possible to set the mouse position with pygame.mouse.set_pos if it is not in the window.
Initialize the variables mx and mx with the center of the window. Change the mouse position only when the mouse pointer is in the window (in focus). pygame.mouse.get_focused can be used to test whether the mouse is in the window.
mx, my = SCREEN.get_rect().center
running = True
while running:
CLOCK.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if pygame.mouse.get_focused():
mx, my = pygame.mouse.get_pos()
SCREEN.fill(WHITE)
SCREEN.blit(floor_surface, floor_rect)
figure.draw_figure(mx)
pygame.display.update()
pygame.quit()
sys.exit()

Why won't MOUSEBUTTONDOWN work in Pygame?

I an having an error with MOUSEBUTTONDOWN giving an error when used.
Here is the error:
if event.type == MOUSEBUTTONDOWN:
NameError: name 'MOUSEBUTTONDOWN' is not defined
Here is the code that is giving the error:
import pygame
import random
import sys
# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
pygame.init()
# Set the width and height of the screen [width, height]
size = (700, 500)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("game")
# 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:
# --- Main event loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# --- Game logic should go here
# --- Screen-clearing code goes here
# Here, we clear the screen to white. Don't put other drawing commands
# above this, or they will be erased with this command.
# If you want a background image, replace this clear with blit'ing the
# background image.
screen.fill(WHITE)
# --- Drawing code should go here
monospace = pygame.font.SysFont("Berlin Sans FB", 169)
label = monospace.render("test", 1, (0, 0, 0))
screen.blit(label, (100, 100))
button_rect = pygame.Rect(0, 0, 50, 50) # start button rectangle
abort = False
start = False
while not abort and not start:
for event in pygame.event.get():
if event.type == pygame.QUIT:
abort = True
if event.type == MOUSEBUTTONDOWN:
if button_rect.collidepoint(event.pos):
start = True
# draw title screen
# [...]
done = abort
while not done:
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# --- Go ahead and update the screen with what we've drawn.
pygame.display.flip()
# --- Limit to 60 frames per second
clock.tick(60)
# Close the window and quit.
pygame.quit()
All the other sources on Stack Overflow about this topic that I can find all talk about errors where MOUSEBUTTONDOWN already works.
Also note that I am using Pycharm.
Either pygame.MOUSEBUTTONDOWN instead of MOUSEBUTTONDOWN or from pygame.locals import *
You need only one application loop:
import pygame
from pygame.locals import *
import random
import sys
# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
pygame.init()
# Set the width and height of the screen [width, height]
size = (700, 500)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("game")
clock = pygame.time.Clock()
monospace = pygame.font.SysFont("Berlin Sans FB", 169)
label = monospace.render("test", 1, (0, 0, 0))
button_rect = pygame.Rect(0, 0, 50, 50) # start button rectangle
abort = False
start = False
while not abort:
for event in pygame.event.get():
if event.type == pygame.QUIT:
abort = True
if event.type == MOUSEBUTTONDOWN:
if not start and button_rect.collidepoint(event.pos):
start = True
screen.fill(WHITE)
if not start:
# draw title screen
pygame.draw.rect(screen, "red", button_rect)
else:
# draw game
# [...]
screen.blit(label, (100, 100))
pygame.display.flip()
clock.tick(60)
pygame.quit()
The typical PyGame application loop has to:
limit the frames per second to limit CPU usage with pygame.time.Clock.tick
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 (blit all the objects)
update the display by calling either pygame.display.update() or pygame.display.flip()
Solution found:
I did not have the needed libraries imported:
For MOUSEBUTTONDOWN to work you need to use:
from pygame.locals import *
Credit to #Rabbid76 for answering in comments.

Pycharm displays an anomally when running a pygame code

I am having a weird display when I run a simple Pygame. The game runs perfectly but the screen is weird.
Here's the code:
import pygame
pygame.init()
window = pygame.display.set_mode((500, 500))
pygame.display.set_caption('First Game')
pygame.display.update()
x = 50
y = 50
width = 40
height = 60
vel = 5
run = True
while run:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.draw.rect(window, (255, 0, 0), (x, y, width, height))
pygame.quit()
You need to update the screen every frame. Put pygame.display.update() inside your main_loop, and remove it from original positon:
while run:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.draw.rect(window, (255, 0, 0), (x, y, width, height))
pygame.display.update()
This should work

Values of variables don't update properly for new loop in pygame

Using pygame and python 3.7, I have created a game in which an image at the center (250, 250) can be dragged around the screen and collide with a radius, in which case a break happens and the next image in the next loop spawns at the exact center, where the first image was located, as well. Despite the game working the way I intended, in principle, it behaves weirdly for fast mouse speed. In my minimal example code, the colored circles are supposed to reappear at the exact center, for every while-loop, however, they somehow don't update properly and therefore reappear not at the center of the screen, most of the time (they only do when I release the mouse-button really early / well-timed). I tested the game on windows and mac and noticed that on my mac, the "lag" seems to be even worse. If anybody knows how I could work around that, I'd be really thankful. Also, the game starts lagging and jumping to the next loop right away for really fast mouse movement, with which I have dealt by changing the speed of my external mouse. Is there an inherent fix for too fast mouse-movement in pygame? Thanks for all suggestions and maybe also other improvements to the idea of my code.
import pygame
import time
from time import sleep
import math
pygame.init()
gameDisplay = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()
background_surface = pygame.Surface((500, 500))
background_surface.fill((255, 255, 255))
colors = [(0,0,0), (253, 45, 0), (249, 253, 0), (32, 201, 5), (0, 210, 235)]
for color in colors:
done = False
a, b = 250, 250
u, v = 250, 250
while not done:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEMOTION:
if event.buttons[0]:
a += event.rel[0]
b += event.rel[1]
rect = pygame.Rect(u, v, 0.001, 0.001)
radius = 200
corners = [rect.bottomleft, rect.bottomright, rect.topleft, rect.topright]
dist = [math.sqrt((p[0] - a) ** 2 + (p[1] - b) ** 2) for p in corners]
p_out = [i for i, d in enumerate(dist) if d > radius]
if any(p_out):
break
gameDisplay.blit(background_surface, (0, 0))
pygame.draw.circle(gameDisplay, color, (a,b), 50, 0)
pygame.draw.circle(gameDisplay, (0,0,0), (250,250), 200, 2)
pygame.display.flip()
sleep(0.7)
pygame.quit()
quit()
[...] they somehow don't update properly and therefore reappear not at the center of the screen, most of the time (they only do when I release the mouse-button really early / well-timed) [...]
Of course, investigate your code. The 1st thing what happens in your code is, that a and b are modified:
while not done:
# [...]
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEMOTION:
if event.buttons[0]:
a += event.rel[0]
b += event.rel[1]
If the pygame.MOUSEMOTION event is in the queue, then it is handled before the circle is drawn. So the position of the circle is modified and it does not appear in the center.
Note, an event does not reflect the current state of the mouse. It is a notification, which is stored in a queue when it happens, but then event handling may done later. What you actually do is to handle an event, which possibly occurred in the past.
Use a state dragging, which is False at the start of each loop. Set the state when the button is pressed (pygame.MOUSEBUTTONDOWN event) and reset it when the button is released (pygame.MOUSEBUTTONUP event):
for color in colors:
# [...]
dragging = False
while not done:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
dragging = True
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
dragging = False
elif event.type == pygame.MOUSEMOTION:
if dragging:
a += event.rel[0]
b += event.rel[1]
# [...]

Categories

Resources