I am trying to delete the previous image after moving. This is the code of how i am moving the image (unit0
def Move(x, y):
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
Background.blit(RedInfantry,(-x*64, 0))
if event.key == pygame.K_RIGHT:
Background.blit(RedInfantry,(x*64, 0))
if event.key == pygame.K_UP:
Background.blit(RedInfantry,(0, -y*64))
if event.key == pygame.K_DOWN:
Background.blit(RedInfantry,(0, y*64))
The starting place is in the top left corner instead of where the image is . Furthermore i don't know how to delete the previous image once it has been moved. If i move twice in different directions it creates to separate images instead of deleting the last one.
How can i delete the previous image?
Base on one of your previous questions (Image loading using pygame), you have to change the position of the image in the grid:
if event.type == pygame.KEYDOWN:
new_x, new_y = x, y
if event.key == pygame.K_LEFT:
new_x -= 1
if event.key == pygame.K_RIGHT:
new_x += 1
if event.key == pygame.K_UP:
new_y -= 1
if event.key == pygame.K_DOWN:
new_x += 1
grid[new_x][new_y] = grid[x][y]
grid[x][y] = None
Of course you have to redraw the entire scene (the grid and the images) in every frame.
(Like in the answer to Image loading using pygame)
Related
This question already has answers here:
How to detect collisions between two rectangular objects or images in pygame
(1 answer)
Pygame - How to make hitbox work with enemy movement? [duplicate]
(1 answer)
Closed 2 years ago.
I was wondering how to do collision detection in pygame. My game doesn't use sprites, it just blits 2 images. How could I check if they are colliding? I know there is sprite.collide, but it doesn't use sprites. Is there some way to check collision by comparing the x and y values of each image?
def fish(x,y):
gameDisplay.blit(fishImg,(x,y))
def enemy(enemyX,enemyY):
gameDisplay.blit(enemyImg,(enemyX,enemyY))
def main():
x = displayWidth/2
y = displayHeight/2
enemyX = random.randint(0,displayWidth)
enemyY = random.randint(0,displayHeight)
xChange = 0
yChange = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
xChange = -5
elif event.key == pygame.K_d:
xChange = 5
elif event.key == pygame.K_w:
yChange = -5
elif event.key == pygame.K_s:
yChange = 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_a or event.key == pygame.K_d:
xChange = 0
elif event.key == pygame.K_w or event.key == pygame.K_s:
yChange = 0
x += xChange
y += yChange
gameDisplay.fill(red)
fish(x,y)
enemy(enemyX,enemyY)
if
pygame.display.update()
clock.tick(30)
main()
pygame.quit()
quit()
Use pygame.Rect and colliderect() to check for collision.
Create pygame.Rect objects, with the size of the image and the location, where you have blit the images.
pygame.Surface.get_rect() creates a pygame.Rect object at position (0, 0), but the top left position can be set by the keyword argument topleft:
fishRect = fishImg.get_rect(topleft = (x, y))
enemyRect = enemyImg.get_rect(topleft = (enemyX, enemyY))
if fishRect.colliderect(enemyRect):
# [...] collision detected
I have been creating a game where an image moves according to player input with Keydown and Keyup methods. I want to add boundaries so that the user cannot move the image/character out of the display (I dont want a game over kind of thing if boundary is hit, just that the image/character wont be able to move past that boundary)
import pygame
pygame.init()#initiate pygame
black = (0,0,0)
white = (255,255,255)
red = (255,0,0)
display_width = 1200
display_height = 800
display = pygame.display.set_mode((display_width,display_height))
characterimg_left = pygame.image.load(r'/Users/ye57324/Desktop/Make/coding/python/characterimg_left.png')
characterimg_right = pygame.image.load(r'/Users/ye57324/Desktop/Make/coding/python/characterimg_right.png')
characterimg = characterimg_left
def soldier(x,y):
display.blit(characterimg, (x,y))
x = (display_width * 0.30)
y = (display_height * 0.2)
pygame.display.set_caption('No U')
clock = pygame.time.Clock()#game clock
flip_right = False
x_change = 0
y_change = 0
bg_x = 0
start = True
bg = pygame.image.load(r'/Users/ye57324/Desktop/Make/coding/python/bg.png').convert()
class player:
def __init__(self, x, y):
self.jumping = False
p = player(x, y)
while start:
for event in pygame.event.get():
if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
start = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change += -4
if flip_right == True:
characterimg = characterimg_left
flip_right = False
x += -150
elif event.key == pygame.K_RIGHT:
x_change += 4
if flip_right == False:
characterimg = characterimg_right
flip_right = True
x += 150
elif event.key == pygame.K_UP:
y_change += -4
elif event.key == pygame.K_DOWN:
y_change += 4
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
x_change += 4
elif event.key == pygame.K_RIGHT:
x_change += -4
elif event.key == pygame.K_UP:
y_change += 4
elif event.key == pygame.K_DOWN:
y_change += -4
x += x_change
y += y_change
display.fill(white)
soldier(x,y)
pygame.display.update()
clock.tick(120)#fps
pygame.quit()
I have tried several times including switching to the key pressed method but they all failed. Help please, thank you.
Basically you want to limit the player's movement.
So everytime you want to "move" the player (I'm guessing this is "x_change" / "y_change") you need to check whether they would still be inside your boundaries after the move.
Example: Your display x boundary is 0 pixels on the left of your screen and 500 to the right. I only allow the actual movement if the result of the movement is within my boundaries.
boundary_x_lower = 0
boundary_x_upper = 500
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
if boundary_x_lower < (x_change - 4):
# I allow the movement if I'm still above the lower boundary after the move.
x_change -= 4
elif event.key == pygame.K_RIGHT:
if boundary_x_upper > (x_change +4):
# I allow the movement if I'm still below the upper boundary after the move.
x_change += 4
PS: I am confused by your code as you subtract when you move to the right... I am used to 2D games where you increment the player's position if you move to the right... and subtract if you go to the left.
Feel free to adapt the code to fit your project. The basic principle applies also to the y-axis movement: with boundary_y_lower & _y_upper. if you have further questions, just ask!
Just clamp the x and y values between 0 and the display width and height.
# In the main while loop after the movement.
if x < 0:
x = 0
elif x + image_width > display_width:
x = display_width - image_width
if y < 0:
y = 0
elif y + image_height > display_height:
y = display_height - image_height
I also recommend checking out how pygame.Rects work. You could define a rect with the size of the display,
display_rect = display.get_rect()
and a rect for the character which will be used as the blit position:
rect = characterimg_left.get_rect(center=(x, y))
Then move and clamp the rect in this way:
rect.move_ip((x_change, y_change))
rect.clamp_ip(display_rect)
display.fill(white)
# Blit the image at the `rect.topleft` coordinates.
display.blit(characterimg, rect)
So I'm just making a simple game that allows a red rectangle to move around the screen, but the boundaries that should make the red rectangle stop before it gets off the screen won't work. Can someone tell me what I'm doing wrong?
while Game:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_1:
gameDisplay = pygame.display.set_mode((display_width,display_height), pygame.FULLSCREEN)
if event.key == pygame.K_2:
gameDisplay = pygame.display.set_mode((display_width,display_height))
if event.key == pygame.K_RIGHT:
x_change = 5
if event.key == pygame.K_LEFT:
x_change = -5
if event.key == pygame.K_UP:
y_change = -5
if event.key == pygame.K_DOWN:
y_change = 5
if x > display_width - 100 or x < 0 and event.key == pygame.K_RIGHT:
if event.key == pygame.K_LEFT:
x_change = -5
else:
x_change = 0 #I did this for all directions
x += x_change
y += y_change
Just so you know, clock.tick is 80 and I have imported pygame and did the pygame.init() thing. Also, movement and every thing else works, just not this.
Try this code:
def clamp(value, minimum=0, maximum=1): return max(minimum, min(value, maximum))
maxX = display_width-rectangle_width
maxY = display_height-rectangle_height
if x not in range(maxX): x_change = 0
if y not in range(maxY): y_change = 0
x = clamp(x, maximum=maxX)
y = clamp(y, maximum=maxY)
However, you are changing the velocity and not the position, when it is out of the screen, the velocity is not moving it back, it keeps there or the speed from the pressed key in the next frame moves it again.
This question already has answers here:
Pygame how to fix 'trailing pixels'?
(4 answers)
Closed 5 years ago.
I'am building a simple game using pygame ,the function of this game is to control an image and make it move up/down left/right but i got this problem, the image repeats itself when moving down or aside
import pygame
pygame.init()
display_width = 1080
display_height = 1080
screen = pygame.display.set_mode((display_width,display_height))
Clock = pygame.time.Clock()
pygame.display.set_caption('DEMO')
black=(0,0,0)
white=(255,255,255)
red=(255,0,0)
green=(0,255,0)
blue=(0,0,255)
screen.fill(white)
face=pygame.image.load('H:\\brain.jpg')
def brain(x,y):
screen.blit(face,(x,y))
x1 =(display_width*0.5)
y1 =(display_height*0.5)
x_change =0
y_change =0
gameExit = False
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -5
elif event.key == pygame.K_RIGHT:
x_change = 5
elif event.key == pygame.K_DOWN:
y_change = 5
elif event.key == pygame.K_UP:
y_change = -5
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_change = 0
if event.type == pygame.KEYUP:
if event.key == pygame.K_DOWN or event.key == pygame.K_UP:
y_change = 0
x1 += x_change
y1 += y_change
print(event)
brain(x1,y1)
pygame.display.update()
Clock.tick(100)
pygame.quit()
quit()
You have to blit your background at every iteration of the while-loop:
while True:
for event in pygame.event.get():
#get keyboard input
screen.fill((255, 255, 255)) #or, you can draw a background image
x1 += x_change
y1 += y_change
print(event)
brain(x1,y1)
pygame.display.update()
You need to blank out the old image, as well as drawing the new one. What you see is the residue: the portion of the previous images that wasn't covered by the white (background color) of the new image.
One easy way to handle this is to expand your drawn image to include a white border at least as large as the size of the motion.
I am messing around with pygame and I am eventually working towards a pong clone. I implemented player movement with the arrow keys and when ever I switch from going up to immediately going down, my player freezes and won't move again until I press that direction key again. Here is my code:
import sys, pygame
pygame.init()
display_width = 640
display_height = 480
display = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption("Test Game")
black = (0,0,0)
white = (255,255,255)
clock = pygame.time.Clock()
running = True
class Player:
def __init__(self,x,y,hspd,vspd,color,screen):
self.x = x
self.y = y
self.hspd = hspd
self.vspd = vspd
self.color = color
self.screen = screen
def draw(self):
pygame.draw.rect(self.screen,self.color,(self.x,self.y,32,32))
def move(self):
self.x += self.hspd
self.y += self.vspd
player = Player(0,0,0,0,black,display)
while running:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
player.hspd = 0
if event.key == pygame.K_LEFT:
player.hspd = 0
if event.key == pygame.K_UP:
player.vspd = 0
if event.key == pygame.K_DOWN:
player.vspd = 0
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
player.hspd = 4
if event.key == pygame.K_LEFT:
player.hspd = -4
if event.key == pygame.K_UP:
player.vspd = -4
if event.key == pygame.K_DOWN:
player.vspd = 4
#Clear the screen
display.fill(white)
#Move objects
player.move()
#Draw objects
player.draw()
#Update the screen
pygame.display.flip()
print "I made it!"
pygame.quit()
sys.exit()
I suggest you work with key.get_pressed() to check for the current set of pressed keys.
In your scenario - when you press down and release up (in that order) - the speed is set to 0, so you need to inspect the keys pressed not just by the current event.
Here is a working version of the relevant part:
def current_speed():
# uses the fact that true = 1 and false = 0
currently_pressed = pygame.key.get_pressed()
hdir = currently_pressed[pygame.K_RIGHT] - currently_pressed[pygame.K_LEFT]
vdir = currently_pressed[pygame.K_DOWN] - currently_pressed[pygame.K_UP]
return hdir * 4, vdir * 4
while running:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
player.hspd, player.vspd = current_speed()
#Clear the screen
display.fill(white)
#Move objects
player.move()
#Draw objects
player.draw()
#Update the screen
pygame.display.flip()
To expand on LPK's answer, your key down (for event.key == pygame.K_DOWN) is likely being processed before your key up (from event.key == pygame.K_UP) is processed. So while both are down (and you can confirm this), you may experience movement, until you release the up key.
your problem is here:
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
player.hspd = 0
if event.key == pygame.K_LEFT:
player.hspd = 0
if event.key == pygame.K_UP:
player.vspd = 0
if event.key == pygame.K_DOWN:
player.vspd = 0
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
player.hspd = 4
if event.key == pygame.K_LEFT:
player.hspd = -4
if event.key == pygame.K_UP:
player.vspd = -4
if event.key == pygame.K_DOWN:
player.vspd = 4
I am guessing that your key event down is still consumed when u switch the keys immediately, meaning no other key down event is getting triggered as long as the first event didn't fire its key up event yet.
EDIT: maybe its better to check if the player is moving and if so just reverse speed . Then you would only need to check the down event.
Otherwise your event will be consumed and not checked properly.
For your method you would need to store the occurred key events since the last frame and check that list.