Player1 control keys work, player2 keys don't work in pygame, any fixes?
Question:
There are zero errors that pop up although, the keys work for player1 yet they don’t for player2. Class player1 and player2 were copy and pasted which is most likely the problem. Any fixes? The classes set up the movement and set up some variables, while in the function ‘main’ is where the problem most likely is in.
import math
import pygame as pg
from pygame.math import Vector2
class Player1(pg.sprite.Sprite):
def __init__(self, pos=(420, 420)):
super(Player1, self).__init__()
self.image = pg.Surface((70, 50), pg.SRCALPHA)
pg.draw.polygon(self.image, (50, 120, 180), ((0, 0), (0, 50), (70, 25)))
self.original_image = self.image
self.rect = self.image.get_rect(center=pos)
self.position = Vector2(pos)
self.direction = Vector2(1, 0)
self.speed = 2
self.angle_speed = 0
self.angle = 0
def update(self):
if self.angle_speed != 0:
self.direction.rotate_ip(self.angle_speed)
self.angle += self.angle_speed
self.image = pg.transform.rotate(self.original_image, -self.angle)
self.rect = self.image.get_rect(center=self.rect.center)
self.position += self.direction * self.speed
self.rect.center = self.position
class Player2(pg.sprite.Sprite):
def __init__(self, pos=(420, 420)):
super(Player2, self).__init__()
self.image = pg.Surface((70, 50), pg.SRCALPHA)
pg.draw.polygon(self.image, (50, 120, 180), ((0, 0), (0, 50), (70, 25)))
self.original_image = self.image
self.rect = self.image.get_rect(center=pos)
self.position = Vector2(pos)
self.direction = Vector2(1, 0)
self.speed = 2
self.angle_speed = 0
self.angle = 0
def update(self):
if self.angle_speed != 0:
self.direction.rotate_ip(self.angle_speed)
self.angle += self.angle_speed
self.image = pg.transform.rotate(self.original_image, -self.angle)
self.rect = self.image.get_rect(center=self.rect.center)
self.position += self.direction * self.speed
self.rect.center = self.position
def main():
pg.init()
screen = pg.display.set_mode((1280, 720))
player1 = Player1((420, 420))
player2 = Player2((1000, 100))
playersprite1 = pg.sprite.RenderPlain((player1))
playersprite2 = pg.sprite.RenderPlain((player2))
clock = pg.time.Clock()
done = False
while not done:
clock.tick(60)
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.KEYDOWN:
if event.key == pg.K_UP:
player1.speed += 1
elif event.key == pg.K_DOWN:
player1.speed -= 1
elif event.key == pg.K_LEFT:
player1.angle_speed = -4
elif event.key == pg.K_RIGHT:
player1.angle_speed = 4
elif event.type == pg.KEYUP:
if event.key == pg.K_LEFT:
player1.angle_speed = 0
elif event.key == pg.K_RIGHT:
player1.angle_speed = 0
elif event.type == pg.KEYDOWN:
if event.key == pg.K_w:
player2.speed += 1
elif event.key == pg.K_s:
player2.speed -= 1
elif event.key == pg.K_a:
player2.angle_speed = -4
elif event.key == pg.K_d:
player2.angle_speed = 4
elif event.type == pg.KEYUP:
if event.key == pg.K_a:
player2.angle_speed = 0
elif event.key == pg.K_d:
player2.angle_speed = 0
playersprite1.update()
playersprite2.update()
screen.fill((30, 30, 30))
playersprite1.draw(screen)
playersprite2.draw(screen)
pg.display.flip()
if __name__ == '__main__':
main()
pg.quit()
Answers:
You have constructed something like
if a:
# [...] code block 1
elif b:
# [...] code block 2
elif a:
# [...] code block 3
elif b:
# [...] code block 4
The "code block 3" and "code block 4" will never be executed.
Combine the key evaluation in a single elif event.type == pg.KEYDOWN
and a single elif event.type == pg.KEYUP:
block:
def main():
# [...]
done = False
while not done:
clock.tick(60)
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.KEYDOWN:
if event.key == pg.K_UP:
player1.speed += 1
elif event.key == pg.K_DOWN:
player1.speed -= 1
elif event.key == pg.K_LEFT:
player1.angle_speed = -4
elif event.key == pg.K_RIGHT:
player1.angle_speed = 4
elif event.key == pg.K_w:
player2.speed += 1
elif event.key == pg.K_s:
player2.speed -= 1
elif event.key == pg.K_a:
player2.angle_speed = -4
elif event.key == pg.K_d:
player2.angle_speed = 4
elif event.type == pg.KEYUP:
if event.key == pg.K_LEFT:
player1.angle_speed = 0
elif event.key == pg.K_RIGHT:
player1.angle_speed = 0
elif event.key == pg.K_a:
player2.angle_speed = 0
elif event.key == pg.K_d:
player2.angle_speed = 0
However, you can greatly simplify the code by using pygame.key.get_pressed()
:
def main():
# [...]
done = False
while not done:
clock.tick(60)
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
keys = pygame.key.get_pressed()
player1.speed = keys[pg.K_UP] - keys[pg.KEYDOWN]
player1.angle_speed = (keys[pg.K_RIGHT] - keys[pg.K_LEFT]) * 4
player2.speed = keys[pg.K_w] - keys[pg.K_s]
player2.angle_speed = (keys[pg.K_d] - keys[pg.K_a]) * 4
# [...]
There are zero errors that pop up although, the keys work for player1 yet they don’t for player2. Class player1 and player2 were copy and pasted which is most likely the problem. Any fixes? The classes set up the movement and set up some variables, while in the function ‘main’ is where the problem most likely is in.
import math
import pygame as pg
from pygame.math import Vector2
class Player1(pg.sprite.Sprite):
def __init__(self, pos=(420, 420)):
super(Player1, self).__init__()
self.image = pg.Surface((70, 50), pg.SRCALPHA)
pg.draw.polygon(self.image, (50, 120, 180), ((0, 0), (0, 50), (70, 25)))
self.original_image = self.image
self.rect = self.image.get_rect(center=pos)
self.position = Vector2(pos)
self.direction = Vector2(1, 0)
self.speed = 2
self.angle_speed = 0
self.angle = 0
def update(self):
if self.angle_speed != 0:
self.direction.rotate_ip(self.angle_speed)
self.angle += self.angle_speed
self.image = pg.transform.rotate(self.original_image, -self.angle)
self.rect = self.image.get_rect(center=self.rect.center)
self.position += self.direction * self.speed
self.rect.center = self.position
class Player2(pg.sprite.Sprite):
def __init__(self, pos=(420, 420)):
super(Player2, self).__init__()
self.image = pg.Surface((70, 50), pg.SRCALPHA)
pg.draw.polygon(self.image, (50, 120, 180), ((0, 0), (0, 50), (70, 25)))
self.original_image = self.image
self.rect = self.image.get_rect(center=pos)
self.position = Vector2(pos)
self.direction = Vector2(1, 0)
self.speed = 2
self.angle_speed = 0
self.angle = 0
def update(self):
if self.angle_speed != 0:
self.direction.rotate_ip(self.angle_speed)
self.angle += self.angle_speed
self.image = pg.transform.rotate(self.original_image, -self.angle)
self.rect = self.image.get_rect(center=self.rect.center)
self.position += self.direction * self.speed
self.rect.center = self.position
def main():
pg.init()
screen = pg.display.set_mode((1280, 720))
player1 = Player1((420, 420))
player2 = Player2((1000, 100))
playersprite1 = pg.sprite.RenderPlain((player1))
playersprite2 = pg.sprite.RenderPlain((player2))
clock = pg.time.Clock()
done = False
while not done:
clock.tick(60)
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.KEYDOWN:
if event.key == pg.K_UP:
player1.speed += 1
elif event.key == pg.K_DOWN:
player1.speed -= 1
elif event.key == pg.K_LEFT:
player1.angle_speed = -4
elif event.key == pg.K_RIGHT:
player1.angle_speed = 4
elif event.type == pg.KEYUP:
if event.key == pg.K_LEFT:
player1.angle_speed = 0
elif event.key == pg.K_RIGHT:
player1.angle_speed = 0
elif event.type == pg.KEYDOWN:
if event.key == pg.K_w:
player2.speed += 1
elif event.key == pg.K_s:
player2.speed -= 1
elif event.key == pg.K_a:
player2.angle_speed = -4
elif event.key == pg.K_d:
player2.angle_speed = 4
elif event.type == pg.KEYUP:
if event.key == pg.K_a:
player2.angle_speed = 0
elif event.key == pg.K_d:
player2.angle_speed = 0
playersprite1.update()
playersprite2.update()
screen.fill((30, 30, 30))
playersprite1.draw(screen)
playersprite2.draw(screen)
pg.display.flip()
if __name__ == '__main__':
main()
pg.quit()
You have constructed something like
if a:
# [...] code block 1
elif b:
# [...] code block 2
elif a:
# [...] code block 3
elif b:
# [...] code block 4
The "code block 3" and "code block 4" will never be executed.
Combine the key evaluation in a single elif event.type == pg.KEYDOWN
and a single elif event.type == pg.KEYUP:
block:
def main():
# [...]
done = False
while not done:
clock.tick(60)
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.KEYDOWN:
if event.key == pg.K_UP:
player1.speed += 1
elif event.key == pg.K_DOWN:
player1.speed -= 1
elif event.key == pg.K_LEFT:
player1.angle_speed = -4
elif event.key == pg.K_RIGHT:
player1.angle_speed = 4
elif event.key == pg.K_w:
player2.speed += 1
elif event.key == pg.K_s:
player2.speed -= 1
elif event.key == pg.K_a:
player2.angle_speed = -4
elif event.key == pg.K_d:
player2.angle_speed = 4
elif event.type == pg.KEYUP:
if event.key == pg.K_LEFT:
player1.angle_speed = 0
elif event.key == pg.K_RIGHT:
player1.angle_speed = 0
elif event.key == pg.K_a:
player2.angle_speed = 0
elif event.key == pg.K_d:
player2.angle_speed = 0
However, you can greatly simplify the code by using pygame.key.get_pressed()
:
def main():
# [...]
done = False
while not done:
clock.tick(60)
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
keys = pygame.key.get_pressed()
player1.speed = keys[pg.K_UP] - keys[pg.KEYDOWN]
player1.angle_speed = (keys[pg.K_RIGHT] - keys[pg.K_LEFT]) * 4
player2.speed = keys[pg.K_w] - keys[pg.K_s]
player2.angle_speed = (keys[pg.K_d] - keys[pg.K_a]) * 4
# [...]