Horizontal collisions when colliding with a block [duplicate] - python
This question already has answers here:
how to know pygame.Rect's side that collide to other Rect?
(1 answer)
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 successfully got my player sprite to detect where this is a block and stop falling. However, i cant seem to do the same for the its colliding side of with a block. If i do the same thing i did with vspeed and to it to hspeed it messes up the game and the characters zooms off the screen. I was trying to get my sprite to recognize the collision and then not go through the block. Any help would be appreciated. Thanks.
class Player(pygame.sprite.Sprite):
def __init__(self,x,y,width = 65, height = 35):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.hspeed,self.vspeed = 0,0
self.speed = 2
self.Jump = 10
self.images=[]
r0 = pygame.image.load("Images\Player\i1.png")
r1 = pygame.image.load("Images\Player\i2.png")
r2 = pygame.image.load("Images\Player\i3.png")
r3 = pygame.image.load("Images\Player\i4.png")
self.hurt = pygame.image.load("Images\Player\Hurt.png")
self.images.append(r0)
self.images.append(r1)
self.images.append(r2)
self.images.append(r3)
self.rotatedimages = []
rr0 = pygame.transform.flip(r0 ,True, False)
rr1 = pygame.transform.flip(r1 ,True, False)
rr2 = pygame.transform.flip(r2 ,True, False)
rr3 = pygame.transform.flip(r3 ,True, False)
self.rotatedimages.append(rr0)
self.rotatedimages.append(rr1)
self.rotatedimages.append(rr2)
self.rotatedimages.append(rr3)
self.deadimages = [self.hurt]
self.gravity = 0.35
self.index = 0
self.image = self.images[self.index]
self.rect = pygame.Rect(self.x,self.y,width,height)
self.TimeNum=0
self.TimeTarget=10
self.Timer = 0
self.power_up_timer = 0
self.running = False
def update(self):
self.calcgravity()
self.rect.x += self.hspeed
self.rect.y += self.vspeed
def level_3_collisions(self, BlockListDirt2):
PlatformCollision = pygame.sprite.spritecollide(self, BlockListDirt2, False )
for each_block in PlatformCollision:
if self.vspeed > 0:
self.rect.bottom = each_block.rect.top
self.vspeed = 0
if self.vspeed <0:
self.rect.top = each_block.rect.bottom
self.vspeed = 0
def move(self, hspeed, vspeed):
self.hspeed += hspeed
self.vspeed += vspeed
class Level3:
def __init__(self):
self.level3 = [
[1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1],
[1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1],
[1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1],
[1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1],
[1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1],
[1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
]
for y in range(0,len(self.level3)):
for x in range(0,len(self.level3[y])):
if self.level3[y][x] == 1:
BlockListDirt2.add(Block(x*40,y*40))
def update(self):
for block in BlockListDirt2:
block.render2(screen)
def main3():
TrapList.empty()
TrapList.add(trap4)
player.hspeed = 0
player.rect.x,player.rect.y = 50,0
player.Timer = 0
bullet_list_v.empty()
bullet_list_h.empty()
FiringBullet = pygame.USEREVENT + 1
pygame.time.set_timer(FiringBullet, 1500)
GameExit = False
while GameExit==False:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player.move(-player.speed,0)
if event.key == pygame.K_RIGHT:
player.move(player.speed,0)
if event.key == pygame.K_UP:
player.move(0,-player.Jump)
JumpSound.play()
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
player.move(player.speed,0)
if event.key == pygame.K_RIGHT:
player.move(-player.speed,0)
if event.key == pygame.K_UP:
player.move(0,0)
if event.type == FiringBullet:
bullet = VerticalBullets(400,200)
bullet2 = VerticalBullets(500,200)
bullet3 = VerticalBullets(625,200)
hbullet = HorizontalBullets(700,400)
bullet_list_v.add(bullet)
bullet_list_v.add(bullet2)
bullet_list_v.add(bullet3)
bullet_list_h.add(hbullet)
screen.fill(BLACK)
level3.update()
for eachbullet in bullet_list_v:
bullet_list_v.draw(screen)
bullet_list_v.update()
for eachbullet in bullet_list_h:
bullet_list_h.draw(screen)
bullet_list_h.update()
if player.rect.x > 600 and player.rect.y < 0:
NextLevel3()
TrapList.draw(screen)
trampoline.render()
playergroup.update()
playergroup.draw(screen)
player.level_3_collisions(BlockListDirt2)
pygame.display.update()
clock.tick(60)
Related
Why does rotated image move by itself?
I rotate an image and I adjust the rect to the rotated image. When I start the program, the image starts moving, without any order by the program. There are, for testing, some pictures needed. I hope, as more experienced users, can take some standards. import pygame import sys from pygame.constants import KEYUP from pygame.constants import KEYDOWN import math import random pygame.init() cell_size = 40 cell_number = 20 breite = int(cell_size * cell_number ) hoehe = int( cell_size * cell_number ) screen = pygame.display.set_mode((breite,hoehe)) clock = pygame.time.Clock() anzahl_gegenstaende = 10 # gehört zu landschaft class MeinAuto(pygame.sprite.Sprite): def __init__(self,x,y): pygame.sprite.Sprite.__init__(self) self.image = pygame.transform.scale(auto_img,(30,66)).convert_alpha() self.rect = self.image.get_rect(center=(x,y)) self.rect.x = x self.rect.y = y self.mask = pygame.mask.from_surface(self.image ) self.wagen_winkel = 0 self.speed = 5 self.links = False self.rechts = False self.vor = False self.zurueck = False self.lenk_winkel = 0 self.block_vor = False self.block_zurueck = False def update(self): for event in events: if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: if self.vor or self.zurueck: self.links = True if event.key == pygame.K_RIGHT: if self.vor or self.zurueck: self.rechts = True if event.key == pygame.K_UP: self.vor = True if event.key == pygame.K_DOWN: self.zurueck = True elif event.type == pygame.KEYUP: if event.key == pygame.K_LEFT: self.links = False if event.key == pygame.K_RIGHT: self.rechts = False if event.key == pygame.K_UP: self.vor = False if event.key == pygame.K_DOWN: self.zurueck = False self.winkel_berechnung(1) dx = math.cos(math.radians(self.wagen_winkel)) dy = math.sin(math.radians(self.wagen_winkel)) if self.vor and self.block_vor == False: self.rect.y -= int(self.speed * dx) self.rect.x -= int(self.speed * dy) self.block_zurueck = False elif self.zurueck and self.block_zurueck == False: self.rect.y += int(self.speed * dx) self.rect.x += int(self.speed * dy) self.block_vor = False if self.links: self.lenk_winkel +=5 self.lenk_winkel=min(self.lenk_winkel,120) elif self.rechts: self.lenk_winkel -=1 self.lenk_winkel=max(self.lenk_winkel,-120) if not self.links and not self.rechts: self.lenk_winkel = 0 def winkel_berechnung(self,dt): if self.rechts: self.wagen_winkel += self.lenk_winkel while self.wagen_winkel < 0: self.wagen_winkel += 360 elif self.links: self.wagen_winkel += self.lenk_winkel while self.wagen_winkel > 359: self.wagen_winkel -= 360 class Lenkung(pygame.sprite.Sprite): def __init__(self,x,y): pygame.sprite.Sprite.__init__(self) self.image = pygame.transform.scale(lenkrad_img,(120,120)).convert_alpha() self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y self.wagen_winkel = 0 class Landschaft(pygame.sprite.Sprite): def __init__(self,image): pygame.sprite.Sprite.__init__(self) self.image = image self.mask = pygame.mask.from_surface(self.image ) x=random.randrange(60, breite -60) y=random.randrange(200, hoehe - 200) self.rect = self.image.get_rect(center =(x,y)) def zeichne_hintergrund(): background = pygame.image.load("Bilder/background_gelb.jpg") screen.blit(background,(0,0)) def blitRotateCenter(image, left, top, angle): rotated_image = pygame.transform.rotate(image, angle) new_rect = rotated_image.get_rect(center = image.get_rect(center = (left, top)).center) screen.blit(rotated_image, new_rect) return new_rect ########## Bilder laden auto_img = pygame.image.load("Bilder/car.png") lenkrad_img = pygame.image.load("bilder/lenkrad.png") ######### Gruppen bilden auto = MeinAuto(breite/2,hoehe-100) auto_sprite = pygame.sprite.Group() auto_sprite.add(auto) lenkung = Lenkung(breite/2,60) lenkung_sprite = pygame.sprite.Group() lenkung_sprite.add(lenkung) land = pygame.sprite.Group() while len(land) < anzahl_gegenstaende: ii = len(land) img = pygame.image.load(f"Bilder/Gegenstaende/geg{ii}.png") img = pygame.transform.scale(img,(100,100)) m = Landschaft(img) if not pygame.sprite.spritecollide(m, land, False): land.add(m) while True: clock.tick(6) zeichne_hintergrund() events = pygame.event.get() for event in events: if event.type == pygame.QUIT: pygame.quit() sys.exit() hits = pygame.sprite.spritecollide( auto, land, False, pygame.sprite.collide_mask) for hit in hits: pass auto_sprite.update() land.draw(screen) new_auto_rect =blitRotateCenter(auto.image, auto.rect.x, auto.rect.y, auto.wagen_winkel) auto.rect=new_auto_rect new_auto_rect = new_auto_rect.inflate(-80,-50) blitRotateCenter(lenkung.image, lenkung.rect.x, lenkung.rect.y, auto.lenk_winkel) pygame.draw.rect(screen,(0,250,0),auto.rect,4) pygame.draw.rect(screen,(250,250,0),new_auto_rect,1) pygame.display.flip()
Instead of the upper left corner of the image, you have to pass the center of the image to the blitRotateCenter function: new_auto_rect = blitRotateCenter(auto.image, auto.rect.x, auto.rect.y, auto.wagen_winkel) new_auto_rect = blitRotateCenter(auto.image, auto.rect.centerx, auto.rect.centery, auto.wagen_winkel) Simplify the code using the asterisk(*) operator: new_auto_rect = blitRotateCenter(auto.image, *auto.rect.center, auto.wagen_winkel)
How to i make an sprite rotate smoothly
I neew help with making my sprites rotate smoothly. Right now i have to press the botton multiple times to rotate the sprites. When I rotate the sprites it also warps the sprites in a weird way. if you go down to the main loop you can see how i tried to implement the rotation in my code right now. I am new to programming so i would appreciate if anyone could ELI5. import pygame as pg import sys x, y = 0, 0 class Rocket(pg.sprite.Sprite): def __init__(self, picture_path, x, y): super().__init__() self.image = pg.image.load(picture_path) self.image = pg.transform.scale(self.image, (120, 100)) self.angle_change = 0 self.angle = 90 + self.angle_change self.image = pg.transform.rotate(self.image, self.angle) self.rect = self.image.get_rect() self.rect.x = 900 self.rect.y = 400 self.pressed_w = False self.pressed_a = False self.pressed_s = False self.pressed_d = False self.speed = 3 self.gravity = False def update(self): if self.pressed_a: self.rect.x -= self.speed if self.pressed_d: self.rect.x += self.speed if self.pressed_w: self.rect.y -= self.speed if self.pressed_s: self.angle_change += 3 if self.gravity: self.rect.y += self.speed if self.rect.left < 0: self.rect.left = 0 if self.rect.right > width: self.rect.right = width if self.rect.top < 0: self.rect.top = 0 if self.rect.bottom > height: self.rect.bottom = height class Rocket1(pg.sprite.Sprite): def __init__(self, picture_path, x, y): super().__init__() self.image = pg.image.load(picture_path) self.image = pg.transform.scale(self.image, (120, 100)) self.rotate = 90 self.image = pg.transform.rotate(self.image, self.rotate) self.rect = self.image.get_rect() self.rect.x = 900 self.rect.y = 400 self.pressed_up = False self.pressed_left = False self.pressed_down = False self.pressed_right = False self.speed = 3 self.gravity = False def update(self): if self.pressed_left: self.rect.x -= self.speed if self.pressed_right: self.rect.x += self.speed if self.pressed_up: self.rect.y -= self.speed if self.pressed_down: self.rect.y += self.speed if self.gravity: self.rect.y += self.speed if self.rect.left < 0: self.rect.left = 0 if self.rect.right > width: self.rect.right = width if self.rect.top < 0: self.rect.top = 0 if self.rect.bottom > height: self.rect.bottom = height pg.init() clock = pg.time.Clock() width = 1920 height = 1080 screen = pg.display.set_mode((width, height)) background = pg.image.load("bg.jpg") #rocket player_rect = Rocket("rocket.png", x, y) player_rect1 = Rocket1("rocketflames.png", x, y) rocket_group = pg.sprite.Group() rocket_group.add(player_rect,player_rect1) while True: rocket_rotate = 0 for event in pg.event.get(): if event.type == pg.QUIT: pg.quit() sys.exit() if event.type == pg.KEYDOWN: if event.key == pg.K_w: player_rect.pressed_w = True player_rect.gravity = False if event.type == pg.KEYDOWN: if event.key == pg.K_s: rocket_rotate += 1 for rocket in rocket_group: rocket.image = pg.transform.rotate(rocket.image, rocket_rotate) if event.type == pg.KEYDOWN: if event.key == pg.K_d: player_rect.pressed_d = True if event.type == pg.KEYDOWN: if event.key == pg.K_a: player_rect.pressed_a = True if event.type == pg.KEYUP: if event.key == pg.K_w: player_rect.pressed_w = False player_rect.gravity = True if event.type == pg.KEYUP: if event.key == pg.K_s: rocket_rotate += 0 for rocket in rocket_group: rocket.image = pg.transform.rotate(rocket.image, rocket_rotate) if event.type == pg.KEYUP: if event.key == pg.K_d: player_rect.pressed_d = False player_rect.gravity = True if event.type == pg.KEYUP: if event.key == pg.K_a: player_rect.pressed_a = False player_rect.gravity = True ### if event.type == pg.KEYDOWN: if event.key == pg.K_UP: player_rect1.pressed_up = True player_rect1.gravity = False if event.type == pg.KEYDOWN: if event.key == pg.K_DOWN: player_rect1.pressed_down = True if event.type == pg.KEYDOWN: if event.key == pg.K_RIGHT: player_rect1.pressed_right = True if event.type == pg.KEYDOWN: if event.key == pg.K_LEFT: player_rect1.pressed_left = True if event.type == pg.KEYUP: if event.key == pg.K_UP: player_rect1.pressed_up = False player_rect1.gravity = True if event.type == pg.KEYUP: if event.key == pg.K_DOWN: player_rect1.pressed_down = False player_rect1.gravity = True if event.type == pg.KEYUP: if event.key == pg.K_RIGHT: player_rect1.pressed_right = False player_rect1.gravity = True if event.type == pg.KEYUP: if event.key == pg.K_LEFT: player_rect1.pressed_left = False player_rect1.gravity = True pg.display.flip() screen.blit(background, (0, 0)) rocket_group.draw(screen) rocket_group.update() clock.tick(120)
You have to use the pygame.key.get_pressed() instead of the keybord events. The keyboard events (see pygame.event module) occur only once when the state of a key changes. The KEYDOWN event occurs once every time a key is pressed. KEYUP occurs once every time a key is released. Use the keyboard events for a single action or a step-by-step movement. pygame.key.get_pressed() returns a list with the state of each key. If a key is held down, the state for the key is True, otherwise False. Use pygame.key.get_pressed() to evaluate the current state of a button and get continuous movement. Additionally I recommend reading How do I rotate an image around its center using PyGame?.
My Simple Platformer Character Drifts Left but not Right and I Can't Find the Bug That Causes It [duplicate]
This question already has answers here: Pygame doesn't let me use float for rect.move, but I need it (2 answers) Simple drag physics, acting differently when moving left or right [duplicate] (1 answer) Closed 2 years ago. Basically I am working on a simple platformer and I have all of the basics like the gravity, acceleration, and platforms, but for some reason the character will decelerate going right, but when it goes left it will continue moving slowly instead of stopping. I even printed the value of my variable "changeX" to see what was going on, and it showed me the values I that should be happening rather than what was displayed. Sorry my comments are very limited in their helpfulness. The code regarding variables rect.x , changeX, and accelX are likely the most relevant. BLACK = (0, 0, 0) WHITE = (255, 255, 255) BLUE = (50, 50, 255) # Screen dimensions SCREEN_WIDTH = 800 SCREEN_HEIGHT = 600 COLOR = BLUE #Top Speed tSpeedX = 7 tSpeedY = 20 #gravity constant gConstant = 1 #acceleration X variable accelX = 0 #acceleration Y variable accelY = 0 #whether you can jump or not jumpB = True class player(pygame.sprite.Sprite): def __init__(self, x, y): super().__init__() #iniatilized values for rect self.image = pygame.Surface([50, 50]) self.image.fill(COLOR) self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y self.changeX = 0 self.changeY = 0 self.walls = None #the velocity function. X and Y values are assigned based on the accelX #and Y constants and added to the points of the rectangle def velocity(self,x,y): #change in speed self.changeX += x self.changeY += y if abs(self.changeX) >= tSpeedX: self.changeX = self.changeX/abs(self.changeX) * tSpeedX if abs(self.changeY) >= tSpeedY: self.changeY = self.changeY/abs(self.changeY) * tSpeedY #standard update function. Will update rectangles position and deaccelerate it if no key held def jump(self,y): self.changeY = y def update(self): if accelX == 0: self.changeX *= 0.92 if accelY == 0: self.changeY *= .95 self.rect.x += self.changeX print(self.changeX) block_hit_list = pygame.sprite.spritecollide(self, self.walls, False) for block in block_hit_list: if self.changeX > 0: self.rect.right = block.rect.left else: self.rect.left = block.rect.right self.rect.y += self.changeY + (9*gConstant) block_hit_list = pygame.sprite.spritecollide(self, self.walls, False) for block in block_hit_list: if self.changeY >= -5: global jumpB jumpB = True COLOR = WHITE self.rect.bottom = block.rect.top else: self.rect.top = block.rect.bottom class wall(pygame.sprite.Sprite): def __init__(self, sx, sy,px,py): super().__init__() #iniatilized values for walls collision = False self.image = pygame.Surface([sx, sy]) self.image.fill(WHITE) self.rect = self.image.get_rect() self.rect.x = px self.rect.y = py pygame.init() screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT]) spriteList = pygame.sprite.Group() wallList = pygame.sprite.Group() Player = player(100,100) spriteList.add(Player) Wall1 = wall(1000, 30, 0, 400) Wall2 = wall(100, 30, 150, 350) wallList.add(Wall2) spriteList.add(Wall2) wallList.add(Wall1) spriteList.add(Wall1) Player.walls = wallList clock = pygame.time.Clock() #Allows program to exit quit = False while not quit: for event in pygame.event.get(): if event.type == pygame.QUIT: quit = True #Sets accel values if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: accelX = -.25 if event.key == pygame.K_RIGHT: accelX = .25 if event.key == pygame.K_UP and jumpB == True: Player.jump(-20) jumpB = False COLOR = BLUE if event.key == pygame.K_DOWN: accelY = .25 #reverses accel values to allow for deaccleration if event.type == pygame.KEYUP: if event.key == pygame.K_LEFT: accelX = 0 if event.key == pygame.K_RIGHT: accelX = 0 if event.key == pygame.K_UP: accelY = 0 if event.key == pygame.K_DOWN: accelY = 0 #calls function to move rectangle Player.velocity(accelX, accelY) spriteList.update() screen.fill(BLACK) spriteList.draw(screen) pygame.display.flip() clock.tick(60)
How to make a brake function for a car pygame [closed]
Closed. This question needs to be more focused. It is not currently accepting answers. Want to improve this question? Update the question so it focuses on one problem only by editing this post. Closed 4 years ago. Improve this question i am new to python and i wanted to know how to make the car have a braking function by pressing spacebar. I have put controls to make the car go left right forward and reverse, but slowing down is what i need using the spacebar. I don't know if my code is required to answer the question but here it is anyways. Thanks import math import random import pygame WHITE = pygame.Color('white') VEHICLE1 = pygame.Surface((40, 70), pygame.SRCALPHA) VEHICLE1.fill((130, 180, 20)) #blitting car onto 'rectangle car' VEHICLE1 = pygame.image.load("YellowLambo.png") screen.blit(VEHICLE1,(0,0)) pygame.display.update() VEHICLE2 = pygame.Surface((40, 70), pygame.SRCALPHA) VEHICLE2.fill((200, 120, 20)) #blitting computer's car VEHICLE2 = pygame.image.load("RedLambo.png") screen.blit(VEHICLE2,(0,0)) pygame.display.update() BACKGROUND = pygame.Surface((1280, 800)) BACKGROUND.fill((127, 69, 2)) BACKGROUND = pygame.image.load("track2.png").convert() screen.blit(BACKGROUND,(0,0)) pygame.display.update() class Entity(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) class VehicleSprite(Entity): MAX_FORWARD_SPEED = 10 MAX_REVERSE_SPEED = 2 ACCELERATION = 0.05 TURN_SPEED = 0.000000000001 def __init__(self, image, position): Entity.__init__(self) self.src_image = image self.image = image self.rect = self.image.get_rect(center=position) self.position = pygame.math.Vector2(position) self.velocity = pygame.math.Vector2(0, 0) self.speed = self.direction = 0 self.k_left = self.k_right = self.k_down = self.k_up = 0 def update(self, time): # SIMULATION self.speed += self.k_up + self.k_down # To clamp the speed. self.speed = max(-self.MAX_REVERSE_SPEED, min(self.speed, self.MAX_FORWARD_SPEED)) # Degrees sprite is facing (direction) self.direction += (self.k_right + self.k_left) rad = math.radians(self.direction) self.velocity.x = -self.speed*math.sin(rad) self.velocity.y = -self.speed*math.cos(rad) self.position += self.velocity self.image = pygame.transform.rotate(self.src_image, self.direction) self.rect = self.image.get_rect(center=self.position) class Background(pygame.sprite.Sprite): def __init__(self, image, location): pygame.sprite.Sprite.__init__(self) self.image = image self.rect = self.image.get_rect(topleft=location) def game_loop(): bike = VehicleSprite(VEHICLE1, rect.center) ball = VehicleSprite(VEHICLE2, rect.center) bike_group = pygame.sprite.Group(bike) ball_group = pygame.sprite.Group(ball) all_sprites = pygame.sprite.Group(bike_group, ball_group) background = Background(BACKGROUND, [0, 0]) camera = pygame.math.Vector2(0, 0) done = False while not done: time = clock.tick(60) for event in pygame.event.get(): if event.type == pygame.QUIT: done = True elif event.type == pygame.KEYDOWN: # Bike Input (Player 1) if event.key == pygame.K_d: bike.k_right = -5 elif event.key == pygame.K_a: bike.k_left = 5 elif event.key == pygame.K_w: bike.k_up = 2 elif event.key == pygame.K_s: bike.k_down = -2 elif event.key == pygame.K_ESCAPE: done = True elif event.type == pygame.KEYUP: if event.key == pygame.K_d: bike.k_right = 0 elif event.key == pygame.K_a: bike.k_left = 0 elif event.key == pygame.K_w: bike.k_up = 0 elif event.key == pygame.K_s: bike.k_down = 0 camera -= bike.velocity #screen.blit(background.image, background.rect) all_sprites.update(time) screen.fill(WHITE) screen.blit(background.image, background.rect.topleft+camera) for sprite in all_sprites: screen.blit(sprite.image, sprite.rect.topleft+camera) pygame.display.flip() game_loop() pygame.quit()
Just add a self.k_break attribute, set it to True when the player breaks and then decrease the self.speed if it's greater than 0 and increase it if it's less than 0. Use max and min, so that it stops at 0. def update(self, time): self.speed += self.k_up + self.k_down if self.k_break: if self.speed > 0: self.speed = max(0, self.speed-0.5) elif self.speed < 0: self.speed = min(0, self.speed+0.5)
Pygame player movement stops when too many keys are pressed at the same time
When I try to move my character and press any other key at the same time, the movement suddenly stops. For example, the space key in my code is used to shoot a tiny orb out of the spaceship. Every time I press space and I am moving left and right quickly, the orb will shoot out but the player movement will be frozen for a second or two. I have tried to switch to different ways of handling the way keys are input, but all of them seem to lead to this same problem. pygame.key.get_pressed() also has this problem when in my code. I am not quite sure if this is a problem with my laptop keyboard or something in the code, so the code for the entire file is below. import pygame, sys, decimal # Screen Size SCREEN_X = 400 SCREEN_Y = 400 # Loading Images backgroundImg = pygame.image.load('StarBackground.png') menuBar = pygame.image.load('Menu_Bar.png') shipImg = pygame.image.load('PowerShip.png') orb = pygame.image.load('Orb00.png') class Ship(pygame.sprite.Sprite): # Movement rate of change change_x = 0 # Methods def __init__(self): pygame.sprite.Sprite.__init__(self) self.image = shipImg.convert_alpha() self.rect = self.image.get_rect() self.rect.x = SCREEN_X / 2 - 8 self.rect.y = SCREEN_Y - 40 def move(self, speed): self.change_x = speed def stop(self): self.change_x = 0 def update(self, screen): self.rect.x += self.change_x if self.rect.x < 0: self.rect.x = 0 elif self.rect.right > SCREEN_X: self.rect.x -= 1 screen.blit(self.image, self.rect) class MenuBar(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.image = menuBar.convert_alpha() self.rect = self.image.get_rect() self.rect.x = 10 self.rect.y = 0 def update(self, screen): screen.blit(self.image,self.rect) class Bullet1(pygame.sprite.Sprite): def __init__(self,x,y): pygame.sprite.Sprite.__init__(self) self.image = orb.convert_alpha() self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y self.alive = True def update(self): if self.alive == True: self.rect.y -= 1 if self.alive == False: self.rect.y = -10000 class HealthBar(pygame.sprite.Sprite): pass class EnergyBar(pygame.sprite.Sprite): pass class PointsBar(pygame.sprite.Sprite): pass class Background(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.image = backgroundImg.convert_alpha() self.rect = self.image.get_rect() self.rect.x = 0 self.rect.y = 0 def update(self, screen): if self.rect.top > 0: self.rect.y = SCREEN_Y * -1 self.rect.y += 1 screen.blit(self.image, self.rect) def main(): pygame.init() size = [SCREEN_X, SCREEN_Y] screen = pygame.display.set_mode(size, pygame.DOUBLEBUF) # Set the height and width of the screen pygame.display.set_caption("Space Adventure") # Setting the game name in the title bar background = Background() # Creating the game objects menubar = MenuBar() ship = Ship() finished = False # Close button exit code bullet1Enabled = True bullet1Count = 1 spacePressed = False clock = pygame.time.Clock() # Manages the frames per second lastkey = None # Variable that stores the last key pressed bulletlist = [] # Game loop while not finished: for event in pygame.event.get(): print(lastkey) if event.type == pygame.QUIT: finished = True pygame.event.set_blocked(pygame.MOUSEMOTION) if event.type == pygame.KEYDOWN: if lastkey != pygame.K_SPACE: lastkey = event.key if event.key == pygame.K_SPACE: spacePressed = True if bullet1Enabled == True: bullet1 = Bullet1(ship.rect.x, ship.rect.y) bulletlist.append(bullet1) bullet1Count = 1 else: spacePressed = False if event.type == pygame.KEYUP: if event.key == pygame.K_RIGHT and lastkey != pygame.K_LEFT: lastkey = None ship.move(0) if event.key == pygame.K_LEFT and lastkey != pygame.K_RIGHT: lastkey = None ship.move(0) if event.key == pygame.K_RIGHT or lastkey == pygame.K_LEFT: spacePressed = False if event.key == pygame.K_LEFT or lastkey == pygame.K_RIGHT: spacePressed = False #Bullet Delay if spacePressed == True: bullet1Count = True if spacePressed == False: bullet1Count = False if lastkey == pygame.K_RIGHT: ship.move(1) if lastkey == pygame.K_LEFT: ship.move(-1) clock.tick(240) # Frames per second background.update(screen) # Background update # Menu Bar update ship.update(screen) # Ship update for b in bulletlist: if b.rect.bottom <= 0: b.alive = False b.update() screen.blit(b.image, b.rect) menubar.update(screen) pygame.display.flip() # Updates the display for everything pygame.quit() # Clean shutdown on IDLE if __name__ == "__main__": main()
The problem occurs because you don't reset lastkey to None after you release the space bar, so you have to press left or right twice. if event.type == pygame.KEYUP: if event.key == pygame.K_SPACE: lastkey = None I don't see why you need the lastkey variable at all. I'd remove these lines from the main loop, if lastkey == pygame.K_RIGHT: ship.move(1) if lastkey == pygame.K_LEFT: ship.move(-1) insert them in the event loop and change lastkey to event.key: if event.type == pygame.KEYDOWN: if event.key == pygame.K_RIGHT: ship.move(1) if event.key == pygame.K_LEFT: ship.move(-1) Now you should be able to remove the lastkey completely.