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
Related
This question already has answers here:
How to rotate an image(player) to the mouse direction?
(2 answers)
How do I make my player rotate towards mouse position?
(1 answer)
Closed 9 months ago.
This post was edited and submitted for review 9 months ago and failed to reopen the post:
Original close reason(s) were not resolved
so im making a top down shooter game and i want to make the player face the mouse at all times. whenever i search it up, i cant figure out what the answer actually means. ive tried:
mouseY, mouseX = pygame.mouse.get_pos()
angle_to_pointer = math.degrees(math.atan2(T_rect.y - mouseY, T_rect.x - mouseX)) + 180
but that only makes it spin uncontrollably off the screen.
heres my main loop:
run = True
while run:
screen.blit(Tonk,(T_rect))
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
pr_l = True
if event.key == pygame.K_RIGHT:
pr_r = True
if event.key == pygame.K_UP:
pr_u = True
if event.key == pygame.K_DOWN:
pr_d = True
if event.key == pygame.K_SPACE:
pr_s = True
elif event.type == pygame.KEYUP: # check for key releases
if event.key == pygame.K_LEFT: # left arrow turns left
pr_l = False
elif event.key == pygame.K_RIGHT: # right arrow turns right
pr_r = False
elif event.key == pygame.K_UP: # up arrow goes up
pr_u = False
elif event.key == pygame.K_DOWN: # down arrow goes down
pr_d = False
elif event.key == pygame.K_SPACE:
pr_s = False
elif event.type == pygame.MOUSEMOTION:
m_m = True
if pr_l == True:
screen.fill(colour)
T_rect.x -= speed
screen.blit(Tonk,(T_rect))
if pr_r == True:
screen.fill(colour)
T_rect.x += speed
screen.blit(Tonk,(T_rect))
if pr_u == True:
screen.fill(colour)
T_rect.y -= speed
screen.blit(Tonk,(T_rect))
if pr_d == True:
screen.fill(colour)
T_rect.y += speed
screen.blit(Tonk,(T_rect))
if m_m == True:
screen.fill(colour)
screen.blit(Tonk,(T_rect))
pygame.display.flip()
clock.tick(60)
please help?
Edit: answered on my previous question: how can i make an image point towards the mouse in python
im new to programming so im following some tutorials online to make a basic game. in order to create the movement for my character, i followed this tutorial
https://www.youtube.com/watch?v=4aZe84vvE20&t=692s&ab_channel=ClearCode
after following the rotation part of the video, i tried testing it out. however, it does not work for some reason. im not sure why this is. i do not get an error, but the character stays in one place and does not rotate once i press the left and right arrow keys. could somebody have a look at my code and let me know what i have done wrong? thanks a lot
import pygame
pygame.init()
window = pygame.display.set_mode((650, 650))
pygame.display.set_caption ("Game")
green = (0,255,0)
window.fill(green)
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.og_image = pygame.image.load("player1.png")
self.image = self.og_image
self.rect = self.image.get_rect (center = (345,345))
self.angle = 0
self.rotate_speed = 1
self.direction = 0
def rotate(self):
if self.direction == 1:
self.angle -= self.rotate_speed
print(self.angle)
elif self.direction == -1:
self.angle += self.rotate_speed
print(self.angle)
self.image = pygame.transform.rotozoom(self.og_image, self.angle, 1)
self.rect = self.image.get_rect(center = (self.rect.center))
def update(self):
self.rotate()
player_1 = Player()
players = pygame.sprite.GroupSingle()
players.add(player_1)
players.draw(window)
run = True
while run == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
players.sprite.direction += 1
if event.key == pygame.K_LEFT:
players.sprite.direction -= 1
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
players.sprite.direction -= 1
if event.key == pygame.K_LEFT:
players.sprite.direction += 1
players.update()
pygame.display.update()
pygame.quit()
You have to draw the Sprites in the Group (players.draw(window)) and you have to clear the display (window.fill(green)) before drawing the objects. Note, you have to do this in the application loop rather than the event loop (It's a matter of Indentation):
run = True
while run == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
players.sprite.direction += 1
if event.key == pygame.K_LEFT:
players.sprite.direction -= 1
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
players.sprite.direction -= 1
if event.key == pygame.K_LEFT:
players.sprite.direction += 1
# INDENTATION
#<--|
players.update()
window.fill(green)
players.draw(window)
pygame.display.update()
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.
This question already has answers here:
Image rotation while moving
(2 answers)
Move Character with Vector
(2 answers)
Closed 2 years ago.
I'm attempting to move a character so that they face the mouse when I move it; I understand the concept but am completely at a loss at how to code it. At the moment, I understand how to rotate the character separately and how to move the character separately. Is it possible for me to merge the two so that I may both move and rotate my character with keys and my mouse?
These are my defined variables:
xPlayer = 25
yPlayer = 25
dxPlayer = 0
dyPlayer = 0
playerPosition = (25,25)
This is the portion that allows the image to rotate in the direction of the mouse:
go = True
while go:
position = pygame.mouse.get_pos()
screen.blit(nightBackground, (0,0))
mousePosition = pygame.mouse.get_pos()
angle = math.atan2(mousePosition[1]-(playerPosition[1]+32),mousePosition[0]-(playerPosition[0]+26))
playerRotate = pygame.transform.rotate(peterPlayer, 360-angle*57.29)
playerpos1 = (playerPosition[0]-playerRotate.get_rect().width/2, playerPosition[1]-playerRotate.get_rect().height/2)
screen.blit(playerRotate, playerpos1)
pygame.display.update()
And this is the portion for controlling my character with the keys:
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
dxPlayer = -15
elif event.key == pygame.K_RIGHT:
dxPlayer = 15
elif event.key == pygame.K_UP:
dyPlayer = -15
elif event.key == pygame.K_DOWN:
dyPlayer = 15
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
dxPlayer = 0
elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
dyPlayer = 0
xPlayer = xPlayer + dxPlayer
yPlayer = yPlayer + dyPlayer
pygame.display.update()
Any help is greatly appreciated!
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.