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
Related
I tried to add jumping physics to my game but it is necessary that after the player jumps, the Jump-Key has to be disabled until the player lands again.
Now, there isn't any problem with the gravity, but if the player keeps holding K_UP he could fly forever and the he can fly in a paarabola as he should, so I need to disable jump until the character lands and the jump Loop loops out as expected.
I tried pygame.event.set_blocked(pygame.K_UP) but when I jump the window crashes and there is an error code: "pygame.event.set_blocked(pygame.K_UP) ValueError: event type out of range".
As I couldn't find anything about this command expect that it exists I probablay did an mistake in the Game-Loop using .block().
Here is the Game-Loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#player1 buttons
if event.type == pygame.KEYDOWN:
#move
if event.key == pygame.K_LEFT:
playerX_change = -1
if event.key == pygame.K_RIGHT:
playerX_change = 1
#Jump
if event.key == pygame.K_UP:
playerY_change = -3
player_jump = True
pygame.event.set_blocked(pygame.K_UP)
if player_jump == True:
playerY_change += gravity
# for X player 1
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
#for Y player 1
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
if playerY == 900:
playerY_change = 0
player_jump = False
pygame.event.set_allowed(pygame.K_UP)
I'm new to Pygame (and programming in general) and treid a lot of things and this is the result, so maybe I have also unnecessary code in it. My problem is the part with pygame.event.set_blocked and pygame.event.set_allowed which I don't know how to use.
pygame.event.set_blocked cannot block a key, it can just block an event such as KEYDOWN or KEYUP.
Anyway, you don't have to "block" anything. Uses the Boolean state variable player_jump instead:
if not player_jump and event.key == pygame.K_UP:
playerY_change = -3
player_jump = True
playerY_change += gravity
This question already has answers here:
How to get keyboard input in pygame?
(11 answers)
Closed 2 years ago.
I am learning Python in Python Crashcourse and am making the Alien Invasion game.
This is what I have in ship.py file to control the Spaceship's X position
# Movement flag
self.moving_right = False
self.moving_left = False
def update(self):
"""Update the ship''s position based on the movement flag"""
if self.moving_right:
self.rect.x += 1
if self.moving_left:
self.rect.x -= 1
And here is the main alien_invasion.py file using pygame.KEYLEFT and KEYRIGHT
def _check_events(self):
# Watch for keyboard and mouse movements.
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
self.ship.moving_right = True
elif event.key == pygame.KEYLEFT:
self.ship.moving_left = True
elif event.type == pygame.KEYUP:
if event.key == pygame.KEYRIGHT:
self.ship.move_right = False
elif event.key == pygame.KEYLEFT:
self.ship.moving_left = False
And I keep getting the error
AttributeError: module 'pygame' has no attribute 'KEYLEFT' when I run the game and press the left key. Sorry if this is an overload of stuff for a small problem, not sure how much info is needed to help fix. Thank you
There is a KEYUP and KEYDOWN, but no KEYRIGHT and KEYLEFT. You are looking for K_LEFT and K_RIGHT.
def _check_events(self):
# Watch for keyboard and mouse movements.
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
self.ship.moving_right = True
elif event.key == pygame.K_LEFT:
self.ship.moving_left = True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
self.ship.move_right = False
elif event.key == pygame.K_LEFT:
self.ship.moving_left = False
This question already has an answer here:
Python Pygame press two direction key and another key to shoot there's no bullet
(1 answer)
Closed 2 years ago.
I'm making my first pygame project and it has been going smoothly. I wrote the following code to check for inputs and so far it was working ok.
def check_events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running, self.playing = False, False
self.curr_menu = False
self.curr_level.run_level = False
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN:
self.DOWN_KEY = True
if event.key == pygame.K_UP:
self.UP_KEY = True
if event.key == pygame.K_RETURN:
self.START_KEY = True
if event.key == pygame.K_BACKSPACE or event.key == pygame.K_ESCAPE:
self.BACK_KEY = True
if event.key == pygame.K_LEFT:
self.LEFT_KEY = True
if event.key == pygame.K_RIGHT:
self.RIGHT_KEY = True
if event.key == pygame.K_SPACE:
self.SPACE_KEY = True
if event.key == pygame.K_RSHIFT or event.key == pygame.K_LSHIFT:
self.SHIFT_KEY = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_DOWN:
self.DOWN_KEY = False
if event.key == pygame.K_UP:
self.UP_KEY = False
if event.key == pygame.K_RETURN:
self.START_KEY = False
if event.key == pygame.K_BACKSPACE or event.key == pygame.K_ESCAPE:
self.BACK_KEY = False
if event.key == pygame.K_LEFT:
self.LEFT_KEY = False
if event.key == pygame.K_RIGHT:
self.RIGHT_KEY = False
if event.key == pygame.K_SPACE:
self.SPACE_KEY = False
if event.key == pygame.K_RSHIFT or event.key == pygame.K_LSHIFT:
self.SHIFT_KEY = False
I wanted to add a sprinting for the x (SHIFT) and y (SPACE) axis it doesn't work properly. Whenever hold down SPACE and RIGHT, pygame doesn't register the UP key getting pressed and whenever I hold SPACE and LEFT, pygame doesn't register both UP and DOWN.
Somehow, holding shift doesn't mess with the registration of the arrow keys.
Because of the issues I was experiencing with the sprinting I started investigating further and realized that pygame doesn't recognize me pressing the UP key when LEFT and RIGHT are pressed simultaneously, but recognizes the DOWN key press.
Is the problem in my code?
If you want to deal with pressed events you need to use:
pygame.key.get_pressed()
It returns the state of the key is pressed or not (True, False)
Example:
key_pressed = pygame.key.get_pressed()
if key_pressed[pygame.K_LSHIFT]:
sprintX()
if key_pressed[pygame.K_SPACE]:
sprintY()
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 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.