Sprite not being properly drawn to where rect is [duplicate] - python

I am new to pygame and python in general. Today I was trying to code a simplified TopDown movement. I did it and it runs without any issues. But i've got a problem anyways: The "player" is a rectangle but I want him to be an image or something like that. Is there a way to 'convert' a rect to an image?
Oh, and here's the code if you need it, I made it from another question I asked a week ago (or a bit longer):
import pygame
pygame.init()
win = pygame.display.set_mode((700, 700))
pygame.display.set_caption("TopDown")
clock = pygame.time.Clock()
player = pygame.Rect(350, 350, 40, 60)
vel = 1
run = True
while run:
clock.tick(50)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
player.x += (keys[pygame.K_d] - keys[pygame.K_a]) * vel
player.y += (keys[pygame.K_s] - keys[pygame.K_w]) * vel
win.fill((0, 0, 0))
pygame.draw.rect(win, (255, 255, 255), player)
pygame.display.update()
pygame.quit()

Load the image with pygame.image.load(). This function returns a pygame.Surface object:
player_image = pygame.image.load("player_image.png").convert_alpha()
player_rect = player_image.get_rect(center = (350, 350))
Put the Surface onto the display with pygame.Surface.blit:
win.blit(player_image, player_rect)
Minimal example:
import pygame
pygame.init()
win = pygame.display.set_mode((700, 700))
pygame.display.set_caption("TopDown")
clock = pygame.time.Clock()
player_image = pygame.image.load("player_image.png").convert_alpha()
player_rect = player_image.get_rect(center = (350, 350))
vel = 5
run = True
while run:
clock.tick(50)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
player_rect.x += (keys[pygame.K_d] - keys[pygame.K_a]) * vel
player_rect.y += (keys[pygame.K_s] - keys[pygame.K_w]) * vel
win.fill((64, 238, 255))
win.blit(player_image, player_rect)
pygame.display.update()
pygame.quit()

Related

Is there a way to remove the red outline from a rect? [duplicate]

I am new to pygame and python in general. Today I was trying to code a simplified TopDown movement. I did it and it runs without any issues. But i've got a problem anyways: The "player" is a rectangle but I want him to be an image or something like that. Is there a way to 'convert' a rect to an image?
Oh, and here's the code if you need it, I made it from another question I asked a week ago (or a bit longer):
import pygame
pygame.init()
win = pygame.display.set_mode((700, 700))
pygame.display.set_caption("TopDown")
clock = pygame.time.Clock()
player = pygame.Rect(350, 350, 40, 60)
vel = 1
run = True
while run:
clock.tick(50)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
player.x += (keys[pygame.K_d] - keys[pygame.K_a]) * vel
player.y += (keys[pygame.K_s] - keys[pygame.K_w]) * vel
win.fill((0, 0, 0))
pygame.draw.rect(win, (255, 255, 255), player)
pygame.display.update()
pygame.quit()
Load the image with pygame.image.load(). This function returns a pygame.Surface object:
player_image = pygame.image.load("player_image.png").convert_alpha()
player_rect = player_image.get_rect(center = (350, 350))
Put the Surface onto the display with pygame.Surface.blit:
win.blit(player_image, player_rect)
Minimal example:
import pygame
pygame.init()
win = pygame.display.set_mode((700, 700))
pygame.display.set_caption("TopDown")
clock = pygame.time.Clock()
player_image = pygame.image.load("player_image.png").convert_alpha()
player_rect = player_image.get_rect(center = (350, 350))
vel = 5
run = True
while run:
clock.tick(50)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
player_rect.x += (keys[pygame.K_d] - keys[pygame.K_a]) * vel
player_rect.y += (keys[pygame.K_s] - keys[pygame.K_w]) * vel
win.fill((64, 238, 255))
win.blit(player_image, player_rect)
pygame.display.update()
pygame.quit()

trouble with pygame's colliderect

trying to use pygames collide rect method to detect collision for the x axis of the player.
the collisions are not registering at all... which is my problem
im trying to mave a square to the right when i hold down the d button, and when i reach the platform, the program below should restrict me from passing through it
player_x = 400
player_y = 300
pygame.init()
player = pygame.image.load(the player)
player_rect = player.get_rect(midbottom = (player_x,player_y))
platform=pygame.image.load(the platform)
platform_rect=platform.get_rect(midbottom = (500,320))
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit
exit()
keys = pygame.key.get_pressed()
if keys[pygame.K_d]:
player_x += 1
platforms = [platform_rect]
x_collision = False
new_player_rect = player.get_rect(midbottom = (player_x,player_y))
for p in platforms:
if p.colliderect(new_player_rect):
x_collision = True
break
if not x_collision:
current_player_x = player_x
screen.blit(BACKGROUND, (0,0))
screen.blit(platform,platform_rect)
screen.blit(player,(current_player_x, player_y))
pygame.display.flip()
You need to set player_x = current_player_x before you change player_x, becuase If the plyer collides with the platform player_x needs to set to its previous position:
current_player_x = player_x
run = True
while run:
# [...]
player_x = current_player_x
if keys[pygame.K_d]:
player_x += 1
However you can simplify the code using new_player_rect. Minimal example:
import pygame
pygame.init()
screen = pygame.display.set_mode((600, 400))
clock = pygame.time.Clock()
BACKGROUND = pygame.Surface(screen.get_size())
player_x = 400
player_y = 300
player = pygame.Surface((20, 20))
player.fill((255, 0, 0))
player_rect = player.get_rect(midbottom = (player_x,player_y))
platform = pygame.Surface((20, 100))
platform.fill((128, 128, 128))
platform_rect=platform.get_rect(midbottom = (500,320))
current_player_x = player_x
run = True
while run:
clock.tick(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit
exit()
keys = pygame.key.get_pressed()
new_player_rect = player.get_rect(midbottom = (player_x, player_y))
if keys[pygame.K_d]:
new_player_rect.x += 1
platforms = [platform_rect]
x_collision = False
for p in platforms:
if p.colliderect(new_player_rect):
print("collide")
x_collision = True
break
if not x_collision:
player_x = new_player_rect.centerx
screen.blit(BACKGROUND, (0,0))
screen.blit(platform,platform_rect)
screen.blit(player, player.get_rect(midbottom = (player_x, player_y)))
pygame.display.flip()

Move two rects seperately with wasd and arrow keys in pygame?

I am new to programming with pygame and python itself. I was trying to make a simple local multiplayer game using pygame. I wrote my code while watching a tutorial on moving only one rectangle because I did not find anything on what I am trying to do. When I finished, I copied the part of the script with the variables and the movement for the rectangle and then pasted it and changed the variable names so it does not crash or something. Now, here comes my problem: because the movement is simple, it would print a new rectangle, if I press the buttons to move. Because of that, the background is refreshing its color all the time (or something like that) so only the one rectangle I want to move is shown. But if there is a second rect, the color covers it, and only one is visible all the time. How can I fix that?
Here is the code:
import pygame
pygame.init()
win = pygame.display.set_mode((500, 500))
pygame.display.set_caption("local multiplayer")
#variables player 1
X = 200
Y = 200
Width = 40
Height = 60
Vel = 5
#variables player 2
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
keys = pygame.key.get_pressed()
#player 1
if keys[pygame.K_a]:
X -= Vel
if keys[pygame.K_d]:
X += Vel
if keys[pygame.K_w]:
Y -= Vel
if keys[pygame.K_s]:
Y += Vel
win.fill((0, 0, 0))
pygame.draw.rect(win, (255, 255, 255), (X, Y, Width, Height))
pygame.display.update()
#player 2
if keys[pygame.K_LEFT]:
x -= vel
if keys[pygame.K_RIGHT]:
x += vel
if keys[pygame.K_UP]:
y -= vel
if keys[pygame.K_DOWN]:
y += vel
win.fill((0, 0, 0))
pygame.draw.rect(win, (255, 255, 255), (x, y, width, height))
pygame.display.update()
pygame.quit()
When you call win.fill((0, 0, 0)) the entire display is cleared. You have to draw the rectangles at once after clearing the display.
Update of the display at the end of the application loop. Multiple calls to pygame.display.update() or pygame.display.flip() cause flickering (see Why is the PyGame animation is flickering).
Simplify the code and use pygame.Rect objects to represent the players. Use pygame.Rect.clamp_ip to prevent the player from leaving the screen.
import pygame
pygame.init()
win = pygame.display.set_mode((500, 500))
pygame.display.set_caption("local multiplayer")
clock = pygame.time.Clock()
player1 = pygame.Rect(200, 200, 40, 60)
vel1 = 1
player2 = pygame.Rect(50, 40, 40, 60)
vel2 = 1
run = True
while run:
clock.tick(50)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
player1.x += (keys[pygame.K_d] - keys[pygame.K_a]) * vel1
player1.y += (keys[pygame.K_s] - keys[pygame.K_w]) * vel1
player2.x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * vel2
player2.y += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * vel2
player1.clamp_ip(win.get_rect())
player2.clamp_ip(win.get_rect())
win.fill((0, 0, 0))
pygame.draw.rect(win, (255, 255, 255), player1)
pygame.draw.rect(win, (255, 255, 255), player2)
pygame.display.update()
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()
You are doing win.fill((0, 0, 0)) right after displaying player 1. Remove this code before you display the second character. Also, keep the fill line at the top of your app loop. This would give:
pygame.init()
win = pygame.display.set_mode((500, 500))
pygame.display.set_caption("local multiplayer")
#variables player 1
X = 200
Y = 200
Width = 40
Height = 60
Vel = 5
#variables player 2
x = 50
y = 50
width = 40
height = 60
vel = 5
run = True
while run:
win.fill((0, 0, 0))
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
#player 1
if keys[pygame.K_a]:
X -= Vel
if keys[pygame.K_d]:
X += Vel
if keys[pygame.K_w]:
Y -= Vel
if keys[pygame.K_s]:
Y += Vel
pygame.draw.rect(win, (255, 255, 255), (X, Y, Width, Height))
#player 2
if keys[pygame.K_LEFT]:
x -= vel
if keys[pygame.K_RIGHT]:
x += vel
if keys[pygame.K_UP]:
y -= vel
if keys[pygame.K_DOWN]:
y += vel
pygame.draw.rect(win, (255, 255, 255), (x, y, width, height))
pygame.display.update()
pygame.quit()
It is also good practice to only update the screen once per loop. Another thing I would do is put the input all in the same if block (but that is not necessary). To further improve your code- consider making a player class that has a render function to display itself, along with an update function to handle control.

x position of bullet in pygame [duplicate]

This question already has answers here:
How can i shoot a bullet with space bar?
(1 answer)
How do I stop more than 1 bullet firing at once?
(1 answer)
Pygame: problems with shooting in Space Invaders
(1 answer)
Closed 1 year ago.
code:
import pygame
import sys
from pygame.locals import *
count = 0
moving = False
def blast1():
blast.y -= bl
def player_animation():
global player_speed
player.x = player_speed
pygame.init()
running = True
clock = pygame.time.Clock()
bl = 1
player_speed = 1
player = pygame.Rect(250, 450, 50, 50)
blast = pygame.Rect(player.x, player.y , 10, 10)
screen = pygame.display.set_mode((500, 500))
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
player_animation()
blast1()
screen.fill((255, 255, 255)) #color
pygame.draw.ellipse(screen, [0, 0, 255], player)
pygame.draw.ellipse(screen, [0, 255, 0], blast)
keys=pygame.key.get_pressed()
if keys[K_LEFT] and player.x != -4 :
player_speed -= 5
if keys[K_RIGHT] and player.x != 451:
player_speed += 5
pygame.display.flip()
clock.tick(30)
blast.x = player.x
pygame.quit()
My objective is pretty simple. I want to create a ball that you can move to the right and left. Then I want to create a bullet that is fired from the position of the "player". I'm having some trouble with this, I don't know why but when I declare the position of the bullet blast = pygame.Rect(player.x, player.y , 10, 10) only the y position works. The x position is somehow in the middle of the screen instead of on the player. How can I fix this?
The line
blast = pygame.Rect(player.x, player.y , 10, 10)
assigns a Rect to blast, with the position of the player at this moment. This blast will stay still until you edit its position. You only change the y position here:
blast.y -= bl
But you don't update the x position when you launch the bullet. You could do this like that:
def launch_blast(): # call this function when you create the bullet.
# At this point in the program, just call it at the beginning.
blast.x = player.x + player.width / 2 - blast.width / 2
def blast1():
blast.y -= bl
To launch several bullets, you can use this code:
import pygame
from pygame.locals import *
pygame.init()
class Bullet:
def __init__(self):
self.rect = Rect(player.rect.x - 5 + player.rect.width / 2, player.rect.y , 10, 10)
def move(self):
self.rect.y -= 10 # move up
pygame.draw.ellipse(screen, [0, 255, 0], self.rect) # draw on screen
class Player:
def __init__(self):
self.rect = pygame.Rect(250, 450, 50, 50)
def move(self):
# move
keys = pygame.key.get_pressed()
if keys[K_LEFT]:
self.rect.x -= 5
if keys[K_RIGHT]:
self.rect.x += 5
# don't go out of the screen
self.rect.x = min(max(self.rect.x, 0), 500 - self.rect.width)
# draw on screen
pygame.draw.ellipse(screen, [0, 0, 255], self.rect)
player = Player()
bullets = []
clock = pygame.time.Clock()
screen = pygame.display.set_mode((500, 500))
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
if event.type == KEYDOWN and event.key == K_SPACE:
bullets.append(Bullet()) # generate a new bullet when space pressed
screen.fill((255, 255, 255)) # white
for bullet in bullets: # draw each bullet generated
bullet.move()
if bullet.rect.x < bullet.rect.height: # if out of the screen,
bullets.remove(bullet) # then remove it
player.move() # draw the player
pygame.display.flip()
clock.tick(30)

How to attach an image to a rect in pygame?

I need help attaching an image to a rectangle in pygame.. I am trying to make a snake game in python(you know, the one that eats the apples and grows lol) and I wanna attach my teacher's face to head of the snake.
I've already tried defining a variable to import the image and then renaming the rectangle to be that image, but nothing seems to work.
snakeFace = pygame.image.load("Morrison.jpg").convert_alpha()
rect = snakeFace.get_rect()
screenWidth = 500
X=50
y= 50
height = 20
vel = 20
run = True
lastKey = None
while run:
pygame.time.delay(10) #1/2 milisecond delay
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False #this controls the "X" button
if event.type == pygame.KEYDOWN:
lastKey = event.key
keys = pygame.key.get_pressed()
if lastKey == pygame.K_LEFT and x > vel:
x-=vel
if lastKey == pygame.K_RIGHT and x< screenWidth - width -vel:
x+=vel
if lastKey == pygame.K_DOWN and y < screenWidth - height - vel:
y+= vel
if lastKey == pygame.K_UP and y > vel:
y-=vel
win.fill((0,0,0))
pygame.draw.rect(win, (255, 0, 0), (x, y, width, height))
pygame.display.update()
I expected there to be a square with my teachers face on it that runs around on the screen after a particular key is pressed on the screen but its just the regular old red square.
It's a red square because the code is drawing a red square:
pygame.draw.rect(win, (255, 0, 0), (x, y, width, height))
Paint the snakeFace bitmap instead:
win.blit(snakeFace, (x, y))
Here is the full example code that I use to add images to rect objects.
import pygame
vel = 5
pygame.init()
screen = pygame.display.set_mode((800,600))
pygame.display.set_caption('captions')
icon = pygame.image.load('test123.jpg')
pygame.display.set_icon(icon)
playerimg = pygame.image.load('test123.jpg')
playerx = 370
playery = 480
def player():
screen.blit(playerimg,(playerx,playery))
running = True
while running:
screen.fill((0, 0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and playerx > vel:
playerx += vel
player()
pygame.display.update()

Categories