Make Character Keep Moving While Key Held Down - python

I'm trying to make a quick animation where if a key is held down the character will keep moving, however my code doesn't seem to be doing that. I press the key and moves once but doesn't move any further. Any help to fix this. Any other suggestions are appreciated and keep in mind this isn't near final product form.
import pygame
import os
import sys
from pygame.locals import *
pygame.init()
WIN = pygame.display.set_mode(display)
pygame.display.set_caption('The Game')
width = 500
height = 500
display = (width, height)
WHITE = (255, 255, 255)
left = [
pygame.image.load(os.path.join('assets', 'main', 'left_walk1.png')),
pygame.image.load(os.path.join('assets', 'main', 'left_walk2.png'))
]
right = [
pygame.image.load(os.path.join('assets', 'main', 'right_walk1.png')),
pygame.image.load(os.path.join('assets', 'main', 'right_walk2.png'))
]
up = [
pygame.image.load(os.path.join('assets', 'main', 'up_walk1.png')),
pygame.image.load(os.path.join('assets', 'main', 'up_walk2.png'))
]
down = [
pygame.image.load(os.path.join('assets', 'main', 'down_walk1.png')),
pygame.image.load(os.path.join('assets', 'main', 'down_walk2.png'))
]
standing_left = (os.path.join('assets', 'main', 'down_walk2.png'))
standing_right = (os.path.join('assets', 'main', 'down_walk2.png'))
standing_up = (os.path.join('assets', 'main', 'down_walk2.png'))
standing_down = (os.path.join('assets', 'main', 'down_walk2.png'))
class Player:
def __init__(self, x, y):
self.x = x
self.y = y
self.health = 100
self.inv = []
self.left = False
self.right = False
self.up = False
self.down = False
self.walking_count = 0
self.facing = 'down'
def draw_player(self, win):
if self.walking_count == 3:
self.walking_count = 1
if self.left:
WIN.blit(left[self.walking_count // 2], (self.x, self.y))
elif self.right:
WIN.blit(right[self.walking_count // 2], (self.x, self.y))
player = Player(100, 100)
FPS = 40
fpsClock = pygame.time.Clock()
while True:
fpsClock.tick(FPS)
WIN.fill(WHITE)
player.draw_player(WIN)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == KEYDOWN:
if event.key == K_UP and player.y <= 0:
player.up = True
elif event.key == K_DOWN:
player.down = True
elif event.key == K_LEFT:
player.left = True
elif event.key == K_RIGHT:
player.right = True
elif event.type == KEYUP:
if event.key == K_UP:
player.up = False
if event.key == K_DOWN:
player.down = False
if event.key == K_LEFT:
player.left = False
if event.key == K_RIGHT:
player.right = False
if player.left:
player.x -= 5
player.walking_count += 1
if player.right:
player.x += 5
player.walking_count += 1
if player.up:
player.y -= 5
player.walking_count += 1
if player.down:
player.y += 5
player.walking_count += 1
pygame.display.update()

It is a matter of Indentation. You've to apply the movement in the application loop rather than the event loop:
while True:
fpsClock.tick(FPS)
WIN.fill(WHITE)
player.draw_player(WIN)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == KEYDOWN:
if event.key == K_UP and player.y <= 0:
player.up = True
elif event.key == K_DOWN:
player.down = True
elif event.key == K_LEFT:
player.left = True
elif event.key == K_RIGHT:
player.right = True
elif event.type == KEYUP:
if event.key == K_UP:
player.up = False
if event.key == K_DOWN:
player.down = False
if event.key == K_LEFT:
player.left = False
if event.key == K_RIGHT:
player.right = False
#<--| INDENTATION
if player.left:
player.x -= 5
if player.right:
player.x += 5
if player.up:
player.y -= 5
if player.down:
player.y += 5
pygame.display.update()
Alternatively you can use pygame.key.get_pressed() rather than the KEYDOWN and KEYUP event:
while True:
fpsClock.tick(FPS)
WIN.fill(WHITE)
player.draw_player(WIN)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
keys = pygame.key.get_pressed()
player.left, player.right, player.up, player.down = False, False, False, False
if keys[K_LEFT]:
player.x -= 5
player.left = True
if keys[K_RIGHT]:
player.x += 5
player.right = True
if keys[K_UP]:
player.y -= 5
player.up = True
if keys[K_DOWN]:
player.y += 5
player.down = True
pygame.display.update()
To control the animation speed, add an attribute self.animation_frames = 10. This attributes controls how many frames each image of the animation is shown. Compute the image index dependent on the attribute.
walking_count has to be incremented in Player.draw_player rather than the application loop.
To ensure that the correct "standing" image is displayed, you have to add an attribute self.standing. Set the attribute dependent on the current direction in draw_player. If the player is not moving, the display the current standing image:
class Player:
def __init__(self, x, y):
# [...]
self.animation_frames = 10
self.standing = standing_left
def draw_player(self, win):
# get image list
if self.left:
image_list = left
self.standing = standing_left
else self.right:
image_list = right
self.standing = standing_right
else:
image_list = [self.standing]
# increment walk count and get image list
image_index = self.walking_count // self.animation_frames
if image_index >= len(image_list):
image_index = 0
self.walking_count = 0
self.walking_count += 1
WIN.blit(image_list[image_index], (self.x, self.y))

Related

Player1 control keys work, player2 keys don't work in pygame, any fixes?

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
# [...]

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?.

How to add a boundary on areas inside the screen in pygame

I've been trying to create a game screen but I can't seem to add a boundary around the houses on the screen so that the player doesn't walk over them. Below is my code
import pygame
import sys
from pygame import mixer
pygame.init()
playerImg = pygame.image.load('player.png')
WalkFront = [pygame.image.load('B1.png'), pygame.image.load('B2.png'),pygame.image.load('B3.png'),
pygame.image.load('B4.png')]
WalkBack = [pygame.image.load('F1.png'), pygame.image.load('F2.png'), pygame.image.load('F3.png'),
pygame.image.load('F4.png')]
WalkRight = [pygame.image.load('R1.png'), pygame.image.load('R2.png'), pygame.image.load('R3.png'),
pygame.image.load('R4.png')]
WalkLeft = [pygame.image.load('L1.png'), pygame.image.load('L2.png'), pygame.image.load('L3.png'),
pygame.image.load('L4.png')]
walkcount = 0
clock = pygame.time.Clock()
scr = pygame.display.set_mode((800, 600))
pygame.display.set_caption('Pokemon: Red')
logo = pygame.image.load('logo.png')
pygame.display.set_icon(logo)
background = pygame.image.load('BG.png')
pallet = pygame.image.load('pallet town.png')
mixer.music.load('Start menu.mp3')
mixer.music.play(100, 0, 0)
playerX = 200
playerY = 200
up = False
down = False
left = False
right = False
def redrawgamewindow():
global walkcount
scr.fill((0, 0, 0))
scr.blit(pallet, (60, 0))
if walkcount + 1 >= 29:
walkcount = 0
if up:
scr.blit(WalkFront[walkcount // 7], (playerX, playerY))
walkcount += 1
elif down:
scr.blit(WalkBack[walkcount // 7], (playerX, playerY))
walkcount += 1
elif left:
scr.blit(WalkLeft[walkcount // 7], (playerX, playerY))
walkcount += 1
elif right:
scr.blit(WalkRight[walkcount // 7], (playerX, playerY))
walkcount += 1
else:
player(playerX, playerY)
pygame.display.update()
def player(x, y):
scr.blit(playerImg, (x, y))
def start_menu():
while True:
scr.fill((255, 255, 255))
scr.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
game()
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
sys.exit()
pygame.display.update()
def game():
global playerX
global playerY
clock.tick(12)
mixer.music.pause()
mixer.music.load('pallet_music.mp3')
mixer.music.play(100)
playerX_change = 0
playerY_change = 0
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
global up
global down
global left
global right
up = True
down = False
playerY_change = -0.8
elif event.key == pygame.K_DOWN:
up = False
down = True
playerY_change = 0.8
else:
up = False
down = False
walkcount = 0
if event.key == pygame.K_LEFT:
playerX_change = -1
left = True
right = False
elif event.key == pygame.K_RIGHT:
playerX_change = 1
right = True
left = False
else:
left = False
right = False
walkcount = 0
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
playerY_change = 0
up = False
down = False
left = False
right = False
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
up = False
down = False
left = False
right = False
playerX += playerX_change
playerY += playerY_change
if playerX <= 90:
playerX = 90
elif playerX >= 670:
playerX = 670
if playerY <= 40:
playerY = 40
elif playerY >= 540:
playerY = 540
redrawgamewindow()
start_menu()
the background image has an area on it with a house in the top left. See the background image below so you can get a better idea. what I want is for the player to not be able to walk on the house so he gets blocked at the edge.
I recommend to define a rectangular area for the house. Use pygame.Rect. You have to find the values for hx, hy, hw and hh:
house_rect = pygame.Rect(hx, hy, hw, hh)
Create a rectangle for the player after the position of the player is changed. The size of the rectangle can be get from the pygame.Surface object which represents the player by get_rect(). The position has to be set by an keyword argument (topleft = (playerX, playerY)).
Use pygame.Rect.colliderect to evaluate if the player collides with the house and restrict the position of the player to the area outside the house:
playerX += playerX_change
player_rect = playerImg.get_rect(topleft = (playerX, playerY))
if player_rect.colliderect(house_rect):
if playerX_change > 0:
player_rect.right = house_rect.left
elif playerX_change < 0:
player_rect.left = house_rect.right
playerX = player_rect.x
playerY += playerY_change
player_rect = playerImg.get_rect(topleft = (playerX, playerY))
if player_rect.colliderect(house_rect):
if playerY_change < 0:
player_rect.top = house_rect.bottom
elif playerY_change > 0:
player_rect.bottom = house_rect.top
playerY = player_rect.y
I guess you have to patiently make the boundaries with x and y like this:
if x > boundaryX and y > boundaryY:
xOfThePlayer -= moving
It is an example you have to change this according to your needs.

Problem with my instance's functions not working (Python3, Pygame), check my code?

Been trying to turn my main character into a class that I can call in my game. This is because I know it will get a lot more complex later in the development due to plans to implement enemies and spawn-able power-ups.
For some reason, my sprite will be drawn but the methods to get make it detect my key and then move (getkey, animandmove) don't seem to work as pressing any of the inputs does not move it. Please help?
import pygame
from pygame.locals import *
import sys
import pyganim # used for animations
pygame.init()
pygame.mixer.init()
WINDOWWIDTH = 1600
WINDOWHEIGHT = 900
# x = 100
# y = 100
# vel = 10
# width = 64
# height = 64
# moveleft = moveright = moveup = movedown = False
# direction = 'left'
background = pygame.image.load('sprites/background1.png')
leftidle = pygame.image.load("sprites/left.png")
rightidle = pygame.image.load("sprites/right.png")
upidle = pygame.image.load("sprites/up.png")
downidle = pygame.image.load("sprites/down.png")
charanim = {"walkleft": pyganim.PygAnimation(
[("sprites/left2.png", 100), ("sprites/left.png", 100), ("sprites/left3.png", 100), ("sprites/left.png", 10)]),
"walkright": pyganim.PygAnimation(
[("sprites/right2.png", 100), ("sprites/right.png", 100), ("sprites/right3.png", 100),
("sprites/right.png", 10)]), "walkup": pyganim.PygAnimation(
[("sprites/up2.png", 100), ("sprites/up.png", 100), ("sprites/up3.png", 100), ("sprites/up.png", 10)]),
"walkdown": pyganim.PygAnimation(
[("sprites/down2.png", 100), ("sprites/down.png", 100), ("sprites/down3.png", 100), ("sprites/down.png", 10)])}
moveConductor = pyganim.PygConductor(charanim)
mainmenuanim = {"splashscreen": pyganim.PygAnimation([("sprites/splash1.png", 500), ("sprites/splash2.png", 500)])}
mainmenuConductor = pyganim.PygConductor(mainmenuanim)
muzzleflashanim = {"fire": pyganim.PygAnimation(
[("sprites/muzzleflash.png", 100), ("sprites/muzzleflash2.png", 100), ("sprites/muzzleflash3.png", 100),
("sprites/muzzleflash4.png", 100)])}
mainwin = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.set_caption("2084 Ver 0.1.1.1")
def mainmenu():
global running
menulive = True
pygame.mixer.music.load('track0.ogg')
pygame.mixer.music.play(-1)
while menulive:
mainmenuConductor.play()
mainmenuanim["splashscreen"].blit(mainwin, (0, 0))
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_RETURN:
pygame.mixer.music.stop()
mainloop()
if event.type == pygame.QUIT:
running = False
pygame.quit()
pygame.display.update()
def mainloop():
global running
running = True
char1 = Character()
pygame.mixer.music.load("track1.ogg")
pygame.mixer.music.play(-1)
char1.__init__()
while running:
mainwin.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
char1.getkey()
char1.animandmove()
pygame.display.update()
class Character:
def __init__(self):
self.x = 100
self.y = 100
self.vel = 10
self.width = 64
self.height = 64
self.moveleft = False
self.moveright = False
self.moveup = False
self.movedown = False
self.direction = 'left'
def animandmove(self):
if self.moveleft or self.moveright or self.moveup or self.movedown:
moveConductor.play()
# draws animations for each of the directions
if self.direction == "left":
charanim["walkleft"].blit(mainwin, (self.x, self.y))
elif self.direction == "right":
charanim["walkright"].blit(mainwin, (self.x, self.y))
elif self.direction == "up":
charanim["walkup"].blit(mainwin, (self.x, self.y))
elif self.direction == "down":
charanim["walkdown"].blit(mainwin, (self.x, self.y))
# moving the physicial character
if self.moveleft and self.x > 0:
self.x -= self.vel
if self.moveright and self.x < (WINDOWWIDTH - 64):
self.x += self.vel
if self.moveup and self.y > 0:
self.y -= self.vel
if self.movedown and self.y < (WINDOWHEIGHT - 64):
self.y += self.vel
else:
moveConductor.stop()
if self.direction == "left":
mainwin.blit(pygame.image.load("sprites/left.png"), (self.x, self.y))
elif self.direction == "right":
mainwin.blit(pygame.image.load("sprites/right.png"), (self.x, self.y))
elif self.direction == "up":
mainwin.blit(pygame.image.load("sprites/up.png"), (self.x, self.y))
elif self.direction == "down":
mainwin.blit(pygame.image.load("sprites/down.png"), (self.x, self.y))
def getkey(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
elif event.type == KEYDOWN:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
if event.key == K_LEFT or event.key == K_a:
self.moveleft = True
self.moveright = False
if not self.moveup and not self.movedown:
self.direction = "left"
elif event.key == K_RIGHT or event.key == K_d:
self.moveleft = False
self.moveright = True
if not self.moveup and not self.movedown:
self.direction = "right"
elif event.key == K_UP or event.key == K_w:
self.moveup = True
self.movedown = False
if not self.moveleft and not self.moveright:
self.direction = "up"
elif event.key == K_DOWN or event.key == K_s:
self.moveup = False
self.movedown = True
if not self.moveleft and not self.moveright:
self.direction = "down"
elif event.type == KEYUP:
if event.key == K_LEFT or event.key == K_a:
self.moveleft = False
if self.moveup:
self.direction = "up"
if self.movedown:
self.direction = "down"
elif event.key == K_RIGHT or event.key == K_d:
self.moveright = False
if self.moveup:
self.direction = "up"
if self.movedown:
self.direction = "down"
elif event.key == K_UP or event.key == K_w:
self.moveup = False
if self.moveleft:
self.direction = "left"
if self.moveright:
self.direction = "right"
elif event.key == K_DOWN or event.key == K_s:
self.movedown = False
if self.moveleft:
self.direction = "left"
if self.moveright:
self.direction = "right"
pygame.display.update()
mainmenu()
pygame.quit()
The main problem is that you have two event loops.
In your main loop, you call pygame.event.get() to get all events which will clear the event queue.
Later, you call pygame.event.get() again in char1.getkey(). At this point, the event queue is already empty (this may happen vice versa, of course).
The easy way to fix it is to just pass every event from the main loop to char1:
while running:
mainwin.blit(background, (0, 0))
for event in pygame.event.get():
char1.getkey(event)
if event.type == pygame.QUIT:
pygame.quit()
char1.animandmove()
pygame.display.update()
and handle them in getkey:
def getkey(self, event):
if event.type == ...
...
There are several other issues with your code but that's out of scope of this question/answer.

Why wont this blit on my screen?

I know this is going to be (hopefully) an easy fix, but I cannot get the gameover screen to blit on my screen. I have thought through this for the past two hours, and none of my tweaks are working. Any help would be greatly appreciated!
This file contains the main file loop as while as sprite group
updates and general updates/renders for the program
import pygame, sys
import player
import random
import math
from constants import *
from bullet import *
from block import *
pygame.init()
screen = pygame.display.set_mode((800,600))
pygame.display.set_caption("Open")
clock = pygame.time.Clock()
def main():
moveX = 0
moveY = 0
sprite_list = pygame.sprite.Group()
bullet_list = pygame.sprite.Group()
block_list = pygame.sprite.Group()
main_player = player.Player()
sprite_list.add(main_player)
main_player.rect.x = 400
main_player.rect.y = 550
for i in range(1,10):
blocks = Block()
blocks.center_x = random.randrange(760)
blocks.center_y = random.randrange(400)
blocks.radius = random.randrange(10,200)
blocks.angle = random.random() * 4 * math.pi
blocks.speed = 0.04
block_list.add(blocks)
sprite_list.add(blocks)
font = pygame.font.Font(None, 36)
game_over = False
score = 0
level = 1
gameLoop = True
while gameLoop:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
moveX = 5
if event.key == pygame.K_LEFT:
moveX = -5
if event.key == pygame.K_DOWN:
moveY = 5
if event.key == pygame.K_UP:
moveY = -5
if event.key == pygame.K_SPACE:
bullets = Bullet()
bullets.rect.x = main_player.rect.x + 16
bullets.rect.y = main_player.rect.y + 16
sprite_list.add(bullets)
bullet_list.add(bullets)
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT and moveX >= 0:
moveX = 0
if event.key == pygame.K_LEFT and moveX <= 0:
moveX = 0
if event.key == pygame.K_DOWN and moveY >= 0:
moveY = 0
if event.key == pygame.K_UP and moveY <= 0:
moveY = 0
for bullets in bullet_list:
block_hit_list = pygame.sprite.spritecollide(bullets, block_list, True)
for block in block_hit_list:
score += 1
bullet_list.remove(bullets)
sprite_list.remove(bullets)
if bullets.rect.y < 0:
bullet_list.remove(bullets)
sprite_list.remove(bullets)
if pygame.sprite.spritecollide(main_player, block_list, True):
gameLoop = False
game_over = True
sprite_list.update()
screen.fill(BLACK)
sprite_list.draw(screen)
main_player.rect.x += moveX
main_player.rect.y += moveY
score_text = font.render("Score: "+str(score), True, WHITE)
screen.blit(score_text,[10,10])
level_text = font.render("Level: "+str(level), True, WHITE)
screen.blit(level_text,[115,10])
if game_over == True:
you_lose_text = font.render("YOU SUCK", True, RED)
screen.blit(you_lose_text, [300,300])
pygame.time.wait(1000)
break
clock.tick(60)
pygame.display.update()
pygame.quit()
if __name__ == "__main__":
main()
HERE IS MY ISSUE:
if game_over == True:
you_lose_text = font.render("YOU SUCK", True, RED)
screen.blit(you_lose_text, [300,300])
pygame.time.wait(1000)
break
I am getting no error, and the pygame.time.wait function is working correctly? Why is it just skipping over displaying the text?
Maybe it is not the best solution but your code doesn't need better.
blit draws in buffer. You have to use update before wait to send data from buffer to screen.
if game_over == True:
you_lose_text = font.render("YOU SUCK", True, RED)
screen.blit(you_lose_text, [300,300])
pygame.display.update() # send on screen
pygame.time.wait(1000)
break
clock.tick(60)
pygame.display.update()
pygame.quit()

Categories