How do I get pygame collisions to work - python

I am making a flappy bird replica and I can't get a collision mechanism. At the moment i'm trying to use .coliderect() but i'm not 100% sure how to. Here is the two classes. I'd like the program to do something, or just print('x') when the bird and the pipe collide, but when they collide at the moment the program does not do or output anything.
import pygame
vec = pygame.math.Vector2
BLACK = (0,0,0)
WIDTH = 500
HEIGHT = 400
pygame.init()
window = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('Flappy Bird')
clock = pygame.time.Clock()
class Bird():
def __init__(self):
self.skin = pygame.image.load('bird2.png')
self.rect = self.skin.get_rect()
self.rect.center = (WIDTH / 2, HEIGHT / 2)
self.vx = 0
self.vy = 0
self.pos = vec(WIDTH / 2, HEIGHT / 2)
self.vel = vec(0, 0)
self.acc = vec(0, 0)
def update(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
window.fill(BLACK)
self.acc = vec(0, 0.7) #having 0.5 adds gravity
self.vy = 0
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE]:
self.vel.y = -7
if keys[pygame.K_LEFT]:
self.acc.x = -0.5 #change to y to add vertical motion
if keys[pygame.K_RIGHT]:
self.acc.x = 0.5 #change to y to add vertical motion
#applys friction
self.acc.x += self.vel.x * -0.08 #FRICTION
#motion equations
self.vel += self.acc
self.pos += self.vel + 0.5 * self.acc
self.rect.center = self.pos
window.blit(self.skin, self.pos)
class Pipe():
def __init__(self,x,y):
self.image = pygame.Surface((50,60))
self.image.fill(RED)
self.rect = self.image.get_rect()
self.pos = vec(x,y)
def blit_pipe(self):
window.blit(self.image, self.pos)
def border_check():
if (flappy.pos.y)+32 > HEIGHT: #this is the very top of the flappy
print("You are under\n")
pygame.quit()
quit()
if flappy.pos.y < 0:
print("You are over\n") #this is the very top of the flappy
pygame.quit()
quit()
pipey = Pipe(300,200)
pipey.blit_pipe()
pipey2 = Pipe(100,200)
pipey2.blit_pipe()
flappy = Bird()
window.blit(flappy.skin, flappy.pos)
while True:
border_check()
flappy.update()
pipey.blit_pipe()
pipey2.blit_pipe()
if flappy.rect.colliderect(pipey.rect):
print('x')
clock.tick(30)
pygame.display.update()

You never set the position of the rects of the Pipe instances so they are still positioned at the default coords (0, 0). There are several ways to set the coords, for example you can pass the coords as the topleft argument to get_rect.
self.rect = self.image.get_rect(topleft=(x, y))
If something is wrong with the collision detection, print the rects to see the actual positions.

Related

Bullet movement not working as expected when player sprite is moving

My game is a top down shooter. When the player is stationary and is shooting in any direction, the bullet goes in the same direction as the mouse. However, when I move diagonally whilst shooting the bullet is no longer in the direction of the mouse position. So basically it works when the player is stationary, but not when I'm moving.
Edit: I will keep trying to fix this but here is a video to better understand the issue https://imgur.com/a/8QRr1PO
Here is the code:
import pygame
from sys import exit
import math
pygame.init()
# window and text
WIDTH = 1280
HEIGHT = 720
FPS = 60
screen = pygame.display.set_mode((WIDTH,HEIGHT))
pygame.display.set_caption('Shooting problem demo')
game_font = pygame.font.Font('freesansbold.ttf', 50)
clock = pygame.time.Clock()
# loads imgs
background = pygame.image.load("background/gamemap.png").convert()
plain_bg = pygame.image.load("background/plain_bg.png").convert()
bullet_img = pygame.image.load("bullets/bluebullet.png").convert_alpha()
class Player(pygame.sprite.Sprite):
def __init__(self, pos):
super().__init__()
self.image = pygame.image.load("handgun/move/survivor-move_handgun_0.png").convert_alpha()
self.image = pygame.transform.rotozoom(self.image, 0, 0.35)
self.base_player_image = self.image
self.pos = pos
self.base_player_rect = self.base_player_image.get_rect(center = pos)
self.rect = self.base_player_rect.copy()
self.player_speed = 10 # was 4
self.shoot = False
self.shoot_cooldown = 0
def player_turning(self):
self.mouse_coords = pygame.mouse.get_pos()
self.x_change_mouse_player = (self.mouse_coords[0] - (WIDTH // 2))
self.y_change_mouse_player = (self.mouse_coords[1] - (HEIGHT // 2))
self.angle = int(math.degrees(math.atan2(self.y_change_mouse_player, self.x_change_mouse_player)))
self.angle = (self.angle) % 360
self.image = pygame.transform.rotate(self.base_player_image, -self.angle)
self.rect = self.image.get_rect(center=self.base_player_rect.center)
def player_input(self):
self.velocity_x = 0
self.velocity_y = 0
keys = pygame.key.get_pressed()
if keys[pygame.K_w]:
self.velocity_y = -self.player_speed
if keys[pygame.K_s]:
self.velocity_y = self.player_speed
if keys[pygame.K_d]:
self.velocity_x = self.player_speed
if keys[pygame.K_a]:
self.velocity_x = -self.player_speed
if self.velocity_x != 0 and self.velocity_y != 0: # moving diagonally
self.velocity_x /= math.sqrt(2)
self.velocity_y /= math.sqrt(2)
if keys[pygame.K_SPACE]:
self.shoot = True
self.is_shooting()
else:
self.shoot = False
if event.type == pygame.KEYUP:
if event.key == pygame.K_SPACE:
self.shoot = False
def move(self):
self.base_player_rect.centerx += self.velocity_x
self.base_player_rect.centery += self.velocity_y
self.rect.center = self.base_player_rect.center
def is_shooting(self):
if self.shoot_cooldown == 0 and self.shoot:
self.bullet = Bullet(self.base_player_rect.centerx, self.base_player_rect.centery, self.angle)
self.shoot_cooldown = 20
bullet_group.add(self.bullet)
all_sprites_group.add(self.bullet)
def update(self):
self.player_turning()
self.player_input()
self.move()
if self.shoot_cooldown > 0:
self.shoot_cooldown -= 1
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y, angle):
super().__init__()
self.image = bullet_img
self.image = pygame.transform.rotozoom(self.image, 0, 0.1)
self.image.set_colorkey((0,0,0))
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.x = x
self.y = y
self.speed = 10
self.angle = angle
self.x_vel = math.cos(self.angle * (2*math.pi/360)) * self.speed
self.y_vel = math.sin(self.angle * (2*math.pi/360)) * self.speed
self.bullet_lifetime = 750
self.spawn_time = pygame.time.get_ticks()
def bullet_movement(self):
self.x += self.x_vel
self.y += self.y_vel
self.rect.x = int(self.x)
self.rect.y = int(self.y)
if pygame.time.get_ticks() - self.spawn_time > self.bullet_lifetime:
self.kill()
def update(self):
self.bullet_movement()
class Camera(pygame.sprite.Group):
def __init__(self):
super().__init__()
self.offset = pygame.math.Vector2()
self.floor_rect = background.get_rect(topleft = (0,0))
def custom_draw(self):
self.offset.x = player.rect.centerx - (WIDTH // 2)
self.offset.y = player.rect.centery - (HEIGHT // 2)
#draw the floor
floor_offset_pos = self.floor_rect.topleft - self.offset
screen.blit(background, floor_offset_pos)
for sprite in all_sprites_group:
offset_pos = sprite.rect.topleft - self.offset
screen.blit(sprite.image, offset_pos)
# Groups
all_sprites_group = pygame.sprite.Group()
player = Player((900,900))
all_sprites_group.add(player)
bullet_group = pygame.sprite.Group()
camera = Camera()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
screen.blit(plain_bg, (0,0))
camera.custom_draw()
all_sprites_group.update()
pygame.display.update()
clock.tick(FPS)
Actually, there is no problem at all. It is just an optical illusion. The projectile does not move relative to the player, but relative to the camera. The player is always in the center of the screen, because the player doesn't move, but the camera does. When the camera moves, all objects move with the camera.
For example, if you shoot a bullet to the right and move the player up, it will look like the bullet is moving diagonally to the right and down. To the right because it changes position, to the right and down because the player moves upwards.
To illustrate this, I reduced the speed of the player (self.player_speed = 2) and the speed of the bullet (self.speed = 4) and drew the scene on a checkered background:
if event.type == pygame.KEYUP: only makes sens in the event loop, but not in player_input. Shooting only one bullet at once just needs another condition (and not self.shoot):
if keys[pygame.K_SPACE] and not self.shoot:
self.shoot = True
self.is_shooting()
else:
self.shoot = False

Why am i getting invalid syntax when adding a def?

import pygame
import math
#initialise pygame
pygame.init()
#game window
WINDOW_WIDTH = 1200
WINDOW_HEIGHT = 750
#create game window
win = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption('Castle Defender')
clock = pygame.time.Clock()
FPS = 60
#load images
background_img = pygame.image.load('Animations/BG.png').convert_alpha()
background = pygame.transform.scale(background_img,(1200,750))
castle_img = pygame.image.load('Animations/Castle.png').convert_alpha()
bullet_img = pygame.image.load('Animations/SmallBullet.png').convert_alpha()
b_w = bullet_img.get_width()
b_h = bullet_img.get_height()
bullet_img = pygame.transform.scale(bullet_img, (int(b_w * 0.075), int(b_h * 0.075)))
WHITE =(255,255,255)
#Castle class
class Castle():
def __init__(self, image, x, y, scale):
self.health = 1000
self.max_health = self.health
width = image.get_width()
height = image.get_height()
self.image = pygame.transform.scale(image, (int(width * scale), int(height * scale)))
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def shoot(self):
pos = pygame.mouse.get_pos()
x_dist = pos[0] - self.rect.midleft[0]
y_dist = -(pos[1] - self.rect.midleft[1])
self.angle = math.degrees(math.atan2(y_dist, x_dist))
#mouseclick
if pygame.mouse.get_pressed()[0] and self.fired == False:
self.fired = True
bullet = Bullet(bullet_img, self.rect.right[0], self.rect.right[1], self.angle)
bullet_group.add(bullet)
#reset mouseclick
if pygame.mouse.get_pressed()[0] == False:
self.fired = False
#Method
def draw(self):
self.image = self.image
win.blit(self.image, self.rect)
class Bullet(pygame.sprite.Sprite):
def __init__(self, image, x, y, angle):
pygame.sprite.Sprite.__init__(self)
self.image = image
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.angle = math.radians(angle)
self.speed = 10
self.dx = math.cos(self.angle) * self.speed
self.dy = -(math.sin(self.angle) * self.speed)
def update(self):
#check if bullet has gone off the screen
if self.rect.right < 0 or self.rect.left > SCREEN_WIDTH or self.rect.bottom < 0 or self.rect.top > SCREEN_HEIGHT:
self.kill()
#move bullet
self.rect.x += self.dx
self.rect.y += self.dy
castle = Castle(castle_img, WINDOW_WIDTH - 1350, WINDOW_HEIGHT - 400, 0.7)
bullet_group = pygame.sprite.Group()
run = True
while run:
clock.tick(FPS)
win.blit(background, (0, 0))
castle.draw()
castle.shoot()
#bullet drawing
bullet_group.update()
bullet_group.draw(win)
print(len(bullet_group))
#event handler
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#update display window
pygame.display.update()
pygame.quit()
I am trying to see the line from my base and my mouse. However I get an error of the following
bullet = Bullet(bullet_img, self.rect.right[0], self.rect.right[1], self.angle)
(My end goal is for bullets to come out of the castle and i am relatively new to coding and this will be my first project) . Also i keep getting an error when trying to submit this saying it is mostly code so the parenthisis was me rambling on
The issue the code is trying to use self.rect.right as if it was a python list. But self.rect.right is an integer.
self.rect.right[0]
self.rect.right[1]
Probably this should be self.rect.right and self.rect.top (since it deals with the y-dimension).
Then you also need to correct references to SCREEN_WIDTH and SCREEN_HEIGHT. It looks like these should be WINDOW_ etc.
After these changes are made, your program does not exit with an error when the mouse is clicked.

Pygame Curve Movement Problem How To Fix?

VIDEO < I'm trying to make the white rectangle curve slowly and smoothly towards the red rectangle and then stop but for some reason the white rectangle isn't curving right and its moving way to fast I want it to move smoothly and curve smoothly that the eyes can see and also alawys curve to the red rectangle is there a way i could change up my code and get it to work like that?
in my curvemove rect class I have a
self.yspeed = 0.05 self.xspeed = -0.5 self.gravity = -0.01 the x and y speed the rect will move in and the gravity effecting it
then on my redraw on the curvemove class
this is how my rect is moving if the key V is pressed then it should mave the self.move true after that it should run the code which curves the object
if keys[pygame.K_v]:
curve_move1.move = True
if self.move:
curve_move1.x += curve_move1.xspeed
curve_move1.y += curve_move1.yspeed
curve_move1.yspeed += curve_move1.gravity
# curve it towards the red rectangle
else:
curve_move1.move2 = True
class curvemove:
def __init__(self,x,y,height,width,color):
self.x = x
self.y = y
self.height = height
self.width = width
self.color = color
self.rect = pygame.Rect(x,y,height,width)
self.yspeed = 0.05
self.xspeed = -0.5
self.gravity = -0.01
self.move = False
def draw(self):
self.rect.topleft = (self.x,self.y)
pygame.draw.rect(window,self.color,self.rect)
# -------------- curve_move1 is our curving rectangle
if keys[pygame.K_v]:
curve_move1.move = True
if self.move:
curve_move1.x += curve_move1.xspeed
curve_move1.y += curve_move1.yspeed
curve_move1.yspeed += curve_move1.gravity
# curve it towards the red rectangle
else:
curve_move1.move2 = True
full code its all rectangles so you can test it out
import pygame
pygame.init()
# our window
window = pygame.display.set_mode((500,500))
pygame.display.set_caption("test map")
# our class
class curvemove:
def __init__(self,x,y,height,width,color):
self.x = x
self.y = y
self.height = height
self.width = width
self.color = color
self.rect = pygame.Rect(x,y,height,width)
self.yspeed = 0.05
self.xspeed = -0.5
self.gravity = -0.01
self.move = False
def draw(self):
self.rect.topleft = (self.x,self.y)
pygame.draw.rect(window,self.color,self.rect)
# -------------- curve_move1 is our curving rectangle
if keys[pygame.K_v]:
curve_move1.move = True
if self.move:
curve_move1.x += curve_move1.xspeed
curve_move1.y += curve_move1.yspeed
curve_move1.yspeed += curve_move1.gravity
# curve it towards the red rectangle
else:
curve_move1.move2 = True
white = 255,255,255
red = 205,0,10
curve_move1 = curvemove(250,400,50,50,white)
touched = curvemove(250,200,50,50,red)
# our game fps
fps = 60
clock = pygame.time.Clock()
# d redraw()
def redraw():
window.fill((0,0,0))
curve_move1.draw()
touched.draw()
# our main loop
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if curve_move1.rect.colliderect(touched.rect):
curve_move1.move = False
redraw()
pygame.display.update()
pygame.quit()
I want a way to make this rect smooth curve towards the red rectangle not fast but normal this is my best try
The gravitational force must act in the direction of the target.
I recommend to use pygame.math.Vector2 for the calculations. Calculate the direction vector from the object to the target and scale it to the size of the gravitational force. Change the motion vector depending on gravity in each frame:
dir_vec = pygame.math.Vector2(target_pos) - self.rect.center
v_len_sq = dir_vec.length_squared()
if v_len_sq > 0:
dir_vec.scale_to_length(self.gravity)
self.speed = (self.speed + dir_vec) * self.friction
self.pos += self.speed
Minimal example:
import pygame
pygame.init()
class curvemove:
def __init__(self, x, y, height, width, color):
self.pos = pygame.math.Vector2(x, y)
self.color = color
self.rect = pygame.Rect(x, y, height, width)
self.speed = pygame.math.Vector2(-5.0, 0)
self.gravity = 0.5
self.friction = 0.99
def draw(self):
self.rect.center = (self.pos.x, self.pos.y)
pygame.draw.circle(window, self.color, (self.pos.x, self.pos.y), self.rect.width//2)
def update(self, target_pos):
dir_vec = pygame.math.Vector2(target_pos) - self.rect.center
v_len_sq = dir_vec.length_squared()
if v_len_sq > 0:
dir_vec.scale_to_length(self.gravity)
self.speed = (self.speed + dir_vec) * self.friction
self.pos += self.speed
window = pygame.display.set_mode((500,500))
pygame.display.set_caption("test map")
clock = pygame.time.Clock()
white = 255, 255, 255
red = 205, 0, 10
curve_move1 = curvemove(250, 400, 20, 20, white)
touched = curvemove(250, 200, 20, 20, red)
fps = 60
move = False
def redraw():
window.fill((0,0,0))
curve_move1.draw()
touched.draw()
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_v:
move = True
if event.key == pygame.K_r:
move = False
curve_move1 = curvemove(250, 400, 20, 20, white)
if (curve_move1.pos - touched.pos).length() < 10:
move = False
if move:
curve_move1.update(touched.rect.center)
redraw()
pygame.display.update()
clock.tick(fps)
pygame.quit()
exit()
Play around with the values of speed, gravity and friction to get different effects.
e.g.:
self.speed = pygame.math.Vector2(-10.0, 0)
self.gravity = 1
self.friction = 0.95
e.g.:
self.speed = pygame.math.Vector2(-10.0, 0)
self.gravity = 1
self.friction = 0.91

Collision on air [duplicate]

This question already has answers here:
How to detect collisions between two rectangular objects or images in pygame
(1 answer)
How do I detect collision in pygame?
(5 answers)
Closed 2 years ago.
I'm making a platform game and I've got collisions working, however with the platforms there seems to be an extra cube area on the left side which the player can walk on. I can't seem to figure out how to remove it. Below is some of the code I believe is the cause of it however I'm not sure exactly.
. I've trimmed down the image for the platforms etc but the problem persists.
background_image = pygame.image.load("JungleBackground.png")
done = False
clock = pygame.time.Clock()
black = ( 0, 0, 0)
white = ( 255, 255, 255)
x = 300
y = 88
class Character(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((100,100))
self.image.set_colorkey(black)
self.rect = self.image.get_rect(center=(50, 300))
self.rect.x = 50
self.rect.y = 300
self.pos = vec(50, 300)
self.vel = vec(0,0)
self.acc = vec(0,0)
self.image.blit(pygame.image.load("TheoHillsS.png"),(0,0))
def characterJump(self):
self.rect.y += 1
hits = pygame.sprite.spritecollide(self, platforms, False)
self.rect.y -= 1
if hits:
self.vel.y = -13
def update(self):
self.acc = vec(0, 0.5)
keys = pygame.key.get_pressed()
if keys[pygame.K_a]:
self.acc.x = -PLAYER_ACC
if keys[pygame.K_d]:
self.acc.x = PLAYER_ACC
# apply friction
self.vel.x *= PLAYER_FRICTION
self.vel += self.acc
self.pos += self.vel
self.rect.midbottom = self.pos
class Platform(pygame.sprite.Sprite):
def __init__(self, x, y, w, h):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((100, 88))
self.image.fill(black)
self.image = pygame.image.load("Platform1.png")
self.rect = self.image.get_rect(topleft=(x, y))
all_sprites = pygame.sprite.Group()
platforms = pygame.sprite.Group()
character = Character()
all_sprites.add(character)
p1 = Platform(-80, 350, WIDTH - 400, HEIGHT - 10)
p2 = Platform(175, 220, WIDTH - 400, HEIGHT - 10)
p3 = Platform(500, 350, WIDTH - 400, HEIGHT - 10)
all_sprites.add(p1, p2, p3)
platforms.add(p1, p2, p3)
# Main Game
running = True
while running:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
character.characterJump()
all_sprites.update()
hits = pygame.sprite.spritecollide(character, platforms, False)
for platform in hits:
if character.vel.y > 0:
character.rect.bottom = platform.rect.top
character.vel.y = 0
elif character.vel.y < 0:
character.rect.top = platform.rect.bottom
character.vel.y = 3
character.pos.y = character.rect.bottom
screen.blit(background_image,[0,0])
all_sprites.draw(screen)
pygame.display.flip()
game_intro()
game_loop()
pygame.quit()
quit()
The collision is tested against the bounding rectangle of the image, not the area drawn on the image. Make sure the platforms and player fill almost the entire area of the pygame.Surface.
Instead of drawing the player on a transparent Surface that is much larger than the player, use the Surface created by pygame.image.load directly:
class Character(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("TheoHillsS.png")
self.rect = self.image.get_rect(topleft = (50, 300))
self.pos = vec(50, 300)
self.vel = vec(0,0)
self.acc = vec(0,0)
# [...]

How to jump only when standing on the ground? (Python)

As of now, I jump whenever I press space. How can I make it so I only jump when standing on something? Would I create some variables such as STANDING and JUMPING? And if I do, how to I reference to them in my class Player? Here is my code, all help is appreciated. Thanks everyone.
import pygame as pg
import os
# create a variable for pg.math.Vector2
vec = pg.math.Vector2
TITLE = "Jumping 1"
WIDTH = 800
HEIGHT = 600
clock = pg.time.Clock()
FPS = 60
GREEN = (0, 255, 0)
LIGHTBLUE = (50, 200, 250)
RED = (255, 0, 0)
# Player properties
PLAYER_ACC = 0.5
PLAYER_FRICTION = -0.12
PLAYER_GRAVITY = 0.8
game_folder = os.path.dirname(__file__)
img_folder = os.path.join(game_folder, "img")
class Player(pg.sprite.Sprite):
def __init__(self):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((50, 50))
self.image.fill(GREEN)
self.rect = self.image.get_rect()
self.rect.center = ((WIDTH / 2, HEIGHT / 2))
# position, velocity, acceleration
self.pos = vec(WIDTH / 2, HEIGHT / 2)
self.vel = vec(0, 0)
self.acc = vec(0, 0)
def update(self):
self.acc = vec(0, PLAYER_GRAVITY)
keystate = pg.key.get_pressed()
if keystate[pg.K_LEFT]:
self.acc.x = -PLAYER_ACC
if keystate[pg.K_RIGHT]:
self.acc.x = PLAYER_ACC
# apply friction
self.acc.x += self.vel.x * PLAYER_FRICTION
# equations of motion
self.vel += self.acc
self.pos += self.vel + 0.5 * self.acc
# wrap around the sides of the screen
if self.pos.x > WIDTH:
self.pos.x = 0
if self.pos.x < 0:
self.pos.x = WIDTH
self.rect.midbottom = self.pos
def jump(self):
self.vel.y = -20
player = Player()
class Platform(pg.sprite.Sprite):
def __init__(self):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((WIDTH, 50))
self.image.fill(RED)
self.rect = self.image.get_rect()
self.rect.center = ((WIDTH / 2, HEIGHT - 25))
platform = Platform()
def game_loop():
pg.init()
screen = pg.display.set_mode((WIDTH, HEIGHT))
pg.display.set_caption(TITLE)
all_sprites = pg.sprite.Group()
all_sprites.add(player, platform)
ground_sprite = pg.sprite.Group()
ground_sprite.add(platform)
running = True
while running:
for event in pg.event.get():
if event.type == pg.QUIT:
running = False
if event.type == pg.KEYDOWN:
if event.key == pg.K_SPACE:
player.jump()
all_sprites.update()
hits = pg.sprite.spritecollide(player, ground_sprite, False)
if hits:
player.pos.y = hits[0].rect.top or platform.rect.top
player.vel.y = 0
screen.fill(LIGHTBLUE)
all_sprites.draw(screen)
pg.display.flip()
clock.tick(FPS)
pg.quit()
game_loop()
In your Player class add a standing flag. Then when space is pressed before performing the jump check if standing is true. If standing is false then do not allow the jump to happen, essentially:
onSpaceBar() {
if(standing) {
\\ perform jump
standing = false;
}
}
Then also make sure after the jump is completed (i.e. you land on something) set the standing flag back to true.

Categories

Resources