My character can't move and shoot at the same time - python

When i move up or down, then i press space(or any other key, is what i have noticed) my charecter stops. I am new to python and pygame, started this week.
import sheetFile
import pygame
pygame.init()
# creates the screen
screen = pygame.display.set_mode(
(1021, 276), pygame.HWSURFACE | pygame.DOUBLEBUF)
# heading which is displayed next to the icon
pygame.display.set_caption("Dragon Flight")
# adds an icon
icon = pygame.image.load("dragon.png")
pygame.display.set_icon(icon)
# loads an image which we use for a background
bg = pygame.image.load("background2.jpg").convert()
char = pygame.image.load("char_1.png")
charX = 50
charY = 138
charChangeY = 0
fireballImg = pygame.image.load('fire.png')
fireballX = 90
fireballY = 150
fireballX_change = 20
fireballY_change = 0
fireball_state = "ready"
fireballs = []
def character(x, y):
screen.blit(char, (x, y))
sheet = pygame.image.load("sheet2.png").convert_alpha()
BLACK = (0, 0, 0, 0)
sprite_sheet = sheetFile.Sheets(sheet)
frame_1 = sprite_sheet.getImage(0, 61, 64, BLACK)
frame_2 = sprite_sheet.getImage(1, 61, 64, BLACK)
frame_3 = sprite_sheet.getImage(2, 61, 64, BLACK)
current_frame = 0
clock = pygame.time.Clock()
running = True
print("hello")
# game loop
while running:
clock.tick(24)
screen.blit(bg, (0, 0))
# for loop through the event queue
for event in pygame.event.get():
charY += charChangeY
# Check for QUIT event
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
charChangeY = -3
if event.key == pygame.K_s:
charChangeY = 3
if event.key == pygame.K_SPACE:
fireballY = charY
fireball = {
'img': fireballImg,
'x': 90,
'y': charY,
'x_change': 20,
'y_change': 0,
'state': 'ready'
}
fireballs.append(fireball)
screen.blit(fireball['img'],
(fireball['x'] + 16, fireball['y'] + 10))
for i, fireball in enumerate(fireballs):
screen.blit(fireball['img'], (fireball['x'] + 16, fireball['y'] + 10))
fireball['x'] += fireball['x_change']
if fireball['x'] >= 1000:
fireballs.pop(i)
if event.type == pygame.KEYUP:
charChangeY = 0
if charY >= 211:
charY = 211
elif charY <= 0:
charY = 0
if fireballX >= 1000:
fireballX = 90
fireball_state = "ready"
if fireball_state == "fire":
fire_fireball(fireballX, fireballY)
fireballX += fireballX_change
# update the current frame
`current_frame += 1
# check if the current frame is greater than 2 (3 frames)
if current_frame > 3:
current_frame = 0
# display the appropriate frame
if current_frame == 0:
current_image = screen.blit(frame_1, (charX, charY))
elif current_frame == 1:
current_image = screen.blit(frame_2, (charX, charY))
elif current_frame == 2:
current_image = screen.blit(frame_3, (charX, charY))
elif current_frame == 3:
current_image = screen.blit(frame_2, (charX, charY))`
current_image
pygame.display.update()
pygame.quit()
This is another file for the spritesheet
import pygame
class Sheets():
def __init__(self, image):
self.sheet = image
def getImage(self, frame, width, height, colour):
image = pygame.Surface((width, height)).convert_alpha()
image.blit(self.sheet, (0, 0), ((frame * width), 0, width, height))
image.set_colorkey(colour)
return image
I think the problem is in the event loop, pressing another key means that the previous action stops or a new one has started . Tried adding another event loop but the events didn't work, then i tried rearrangeing the code so that each event is in a different key down event type but nothing changed. I saw somewhere making a variable for each action
moving_up = False
moving_down = False
firing = False
but i couldn't figure it out.
Tried this:
keys = pygame.key.get_pressed()
if keys[pygame.K_w]:
charChangeY = -3
if keys[pygame.K_s]:
charChangeY = 3
if keys[pygame.K_SPACE]:
fireballY = charY
fireball = {
'img': fireballImg,
'x': 90,
'y': charY,
'x_change': 20,
'y_change': 0,
'state': 'ready'
}
fireballs.append(fireball)
screen.blit(fireball['img'],
(fireball['x'] + 16, fireball['y'] + 10))
but this makes it so if i fire i can move, but if i move and then fire my charecter stops

How to get keyboard input in pygame?. It makes absolutely no sense to handle events outside the event loop. You must handle the pygame.KEYUP event in the event loop:
while running:
# [...]
for event in pygame.event.get():
# [...]
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
charChangeY = -3
if event.key == pygame.K_s:
charChangeY = 3
if event.key == pygame.K_SPACE:
fireballY = charY
fireball = {
'img': fireballImg,
'x': 90,
'y': charY,
'x_change': 20,
'y_change': 0,
'state': 'ready'
}
fireballs.append(fireball)
if event.type == pygame.KEYUP:
if event.key == pygame.K_w or event.key == pygame.K_s:
charChangeY = 0
charY += charChangeY
See How can I make a sprite move when key is held down and How do I stop more than 1 bullet firing at once?.
I suggest using the keyboard event for firing the projectile, but pygame.key.get_pressed() for the movement:
while running:
# [...]
for event in pygame.event.get():
# [...]
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
fireballY = charY
fireball = {
'img': fireballImg,
'x': 90,
'y': charY,
'x_change': 20,
'y_change': 0,
'state': 'ready'
}
fireballs.append(fireball)
keys = pygame.key.get_pressed()
charChangeY = (keys[pygame.K_s] - keys[pygame.K_w]) * 3
charY += charChangeY

Related

How do I flip this sprite in pygame?

EDIT: I've now flipped the sprite, but when the animation plays on the flipped sprite, it has a black background instead of blending in with the major background. Just updated my code to the current situation. (2/8/2021)
I'm trying to flip a sprite in pygame, for example, I don't want them running left but looking right, which is what is happening right now.
The part that is giving me issues is the second comment that says ISSUES.
Here is my code (spritesheet is a class that transforms the image into a surface):
import pygame
import os
import sys
import random
from pygame.locals import *
import spritesheet
import time
pygame.init()
clock = pygame.time.Clock()
FPS = 60
prev_time = time.time()
pygame.display.set_caption('Platformer')
BG_COLOR = (50, 50, 50)
BLACK = (0, 0, 0)
WIN_SIZE = [1920,1080]
WIN = pygame.display.set_mode((WIN_SIZE[0], WIN_SIZE[1]), 0, 32)
# CONFIGURING Animations
IDLE_INDEX = 0
RUN_INDEX = 0
moving_right = False
moving_left = False
lookingRight = True
speed = 4
animation_tick = 8
player_location = [50, 50]
player_y_momentum = 0
player_rect = pygame.Rect(player_location[0] + 155, player_location[1] + 140, 70, 133)
def retrieve_list(animType, image):
if animType == "idle":
IDLE_FRAMES = []
IDLE_STEPS = 9
sprite_sheet = spritesheet.SpriteSheet(image)
for step in range(IDLE_STEPS):
newFRAME = sprite_sheet.get_image(step, 120, 80, 3.5, BLACK)
IDLE_FRAMES.append(newFRAME)
return IDLE_FRAMES
if animType == "run":
RUN_FRAMES = []
RUN_STEPS = 9
sprite_sheet = spritesheet.SpriteSheet(image)
for step in range(RUN_STEPS):
newFRAME = sprite_sheet.get_image(step, 120, 80, 3.5, BLACK)
RUN_FRAMES.append(newFRAME)
return RUN_FRAMES
sprite_sheet_img_IDLE = pygame.image.load('Spritesheets/Outline/120x80_PNGSheets/_Idle.png')
sprite_sheet_img_RUN = pygame.image.load('Spritesheets/Outline/120x80_PNGSheets/_Run.png')
IDLE_FRAMES = retrieve_list("idle", sprite_sheet_img_IDLE)
RUN_FRAMES = retrieve_list("run", sprite_sheet_img_RUN)
currentANIMATION = "idle"
playingAnim = None
while True:
clock.tick(FPS)
now = time.time()
dt = now - prev_time
prev_time = now
WIN.fill(BG_COLOR)
if currentANIMATION == "idle":
if player_location[1] > WIN_SIZE[1] - IDLE_FRAMES[IDLE_INDEX].get_height():
player_y_momentum = -player_y_momentum
else:
player_y_momentum += 0.2
player_location[1] += player_y_momentum
elif currentANIMATION == "run":
if player_location[1] > WIN_SIZE[1] - RUN_FRAMES[RUN_INDEX].get_height():
player_y_momentum = -player_y_momentum
else:
player_y_momentum += 0.2
player_location[1] += player_y_momentum
if moving_right:
currentANIMATION = "run"
if not lookingRight:
lookingRight = True
WIN.fill(BG_COLOR)
playingAnim = WIN.blit(RUN_FRAMES[RUN_INDEX], (player_location[0], player_location[1]))
player_location[0] += speed
if moving_left:
currentANIMATION = "run"
if lookingRight:
lookingRight = False
leftFrame = pygame.transform.flip(RUN_FRAMES[RUN_INDEX], True, False)
WIN.fill(BG_COLOR)
playingAnim = WIN.blit(leftFrame, (player_location[0], player_location[1]))
player_location[0] -= speed
elif moving_right != True and moving_left != True:
currentANIMATION = "idle"
WIN.fill(BG_COLOR)
playingAnim = WIN.blit(IDLE_FRAMES[IDLE_INDEX], (player_location[0], player_location[1]))
player_rect.x = player_location[0] + 155
player_rect.y = player_location[1] + 140
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_RIGHT or event.key == ord('d'):
moving_right = True
if event.key == K_LEFT or event.key == ord('a'):
moving_left = True
if event.type == KEYUP:
if event.key == K_RIGHT or event.key == ord('d'):
moving_right = False
if event.key == K_LEFT or event.key == ord('a'):
moving_left = False
pygame.display.update()
if animation_tick == 8: # change 20 to how ever many ticks in between animation frames
if currentANIMATION == "idle":
if IDLE_INDEX < 8:
IDLE_INDEX += 1
else:
IDLE_INDEX = 0
if currentANIMATION == "run":
if RUN_INDEX < 8:
RUN_INDEX += 1
else:
RUN_INDEX = 0
animation_tick = 0 # reset tick back to 0 after changing frame
else:
animation_tick += 1 # add 1 each iteration of the while loop
Here are the spritesheets if you want to replicate my situation:
running spritesheet:
idle spritesheet:
I've tried flipping the original surface, but then the image gets messed up with black around it, and it doesn't play the animation.
pygame.transform.flip does not flip the image in place, but returns a new image that is flipped:
flipped_image = pygame.transform.flip(image, True, False)
Forgot to add .convert_alpha() when I was flipping the image. Apparently when the image is flipped it recreates the black rectangle.

How to stop a timer in pygame

For my endscreen, I want a line that says "You survived for X seconds" but in that line, the timer continues to run after game over.
I've tried to move the timer code a bit downwards in the main loop (after the if gameover: part.) I also tried if not gameover and time_difference >= 1500: but the timer still runs.
This is my programme loop with timer:
Code is removed for now. Will re-upload in 1 to 2 months.
and endscreen code if necessary:
def gameOverScreen():
ending = 1
global run, gameover
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
For those who need it, with some help, the code now works.
#Start screen Loop
done = False
start_time = pygame.time.get_ticks()
while not done and display_instructions:
if not pygame.mixer.music.get_busy():
pygame.mixer.music.load('bgm.mp3')
pygame.mixer.music.play()
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.MOUSEBUTTONDOWN:
instruction_page += 1
if instruction_page == 2:
display_instructions = False
# Set the screen background
win.fill(black)
if instruction_page == 1:
text = font.render("Instructions:", True, white)
win.blit(text, [10, 20])
text = font.render("1. Use WASD, or the Arrow Keys to move", True, white)
win.blit(text, [10, 100])
text = font.render("2. Left click to shoot", True, white)
win.blit(text, [10, 150])
text = font.render("3. Collect ammunition", True, white)
win.blit(text, [10, 200])
text = font.render("4. STAY ALIVE", True, white)
win.blit(text, [10, 250])
text = font.render("Kill or be killed", True, red)
win.blit(text, [260, 420])
text = font.render("How long can you survive?", True, red)
win.blit(text, [150, 470])
text = font.render("Click to start", True, white)
win.blit(text, [270, 600])
clock.tick(60)
pygame.display.flip()
def gameOverScreen(end_time):
seconds_survived = (end_time - start_time) // 1000
ending = 1
global run, gameover
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
win.fill(black)
timer = pygame.time.get_ticks() - now2
if ending == 1:
win.blit(endscreen.image, endscreen.rect)
time = font.render(str(seconds_survived/1000) ,1,red)
win.blit(time, (410, 600))
endtext = font.render("You survived for seconds", True, red)
win.blit(endtext, [100, 600])
kill = font.render("Kill count: " +str(killcounter), 1, red)
win.blit(kill, (280, 650))
pygame.display.flip()
clock.tick(100)
# Programme loop
run = True
gameover = False
while run:
actual_ticks = pygame.time.get_ticks()
if gameover:
now2 = now = actual_ticks
gameOverScreen(end_time)
continue
timer = actual_ticks - now2
time_difference = actual_ticks - now
if time_difference >= 1500:
newenemy = Enemy(random.randrange(50,780), random.randrange(50,780), 1 ,wall_list)
enemy_list.add(newenemy)
all_sprite_list.add(newenemy)
newenemy2 = Enemy(random.randrange(50,780), random.randrange(50,780), 1 ,wall_list)
enemy_list.add(newenemy2)
all_sprite_list.add(newenemy2)
now = actual_ticks
all_sprite_list.update()
win.fill(white)
win.blit(background.image, background.rect)
for e in enemy_list:
e.move(player)
collide = pygame.sprite.spritecollide(player, enemy_list, False)
if collide:
gameover = True
end_time = pygame.time.get_ticks()
food_collide = pygame.sprite.spritecollide(player,food_list,False)
for food in food_collide:
score += 1
bullets += 10
food_list.remove(food)
newfood = Food()
food_list.add(newfood)
all_sprite_list.add(newfood)
all_sprite_list.remove(food)
food_list.update()
all_sprite_list.update()
pygame.mixer.music.load('reload.mp3')
pygame.mixer.music.play()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT or event.key == ord('a'):
player.move(-2, 0)
elif event.key == pygame.K_RIGHT or event.key == ord('d'):
player.move(2, 0)
elif event.key == pygame.K_UP or event.key == ord('w'):
player.move(0, -2)
elif event.key == pygame.K_DOWN or event.key == ord('s'):
player.move(0, 2)
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == ord('a'):
player.move(2, 0)
elif event.key == pygame.K_RIGHT or event.key == ord('d'):
player.move(-2, 0)
elif event.key == pygame.K_UP or event.key == ord('w'):
player.move(0, 2)
elif event.key == pygame.K_DOWN or event.key == ord('s'):
player.move(0, -2)
elif event.type == pygame.MOUSEBUTTONDOWN:
aim_pos = event.pos
player_position = player.rect.center
bullet_vec = pygame.math.Vector2(aim_pos[0] - player_position[0], aim_pos[1] - player_position[1]).normalize() * 10
bullet = Bullet()
bullet.rect.center = player.rect.center
bullet.vec = bullet_vec
if bullets > 0:
all_sprite_list.add(bullet)
bullets -= 1
pygame.mixer.music.load('Gunshot.mp3')
pygame.mixer.music.play()
else:
pygame.mixer.music.load('reload.mp3')
pygame.mixer.music.play()
hit = pygame.sprite.spritecollide(bullet, enemy_list, False)
for enemy in hit:
killcounter += 1
enemy_list.remove(enemy)
all_sprite_list.remove(enemy)
enemy_list.update()
all_sprite_list.update()
enemy.move(player)
all_sprite_list.update()
all_sprite_list.draw(win)
time = font.render(str(timer/1000) ,1,black)
win.blit(time, (680, 5))
scoretext = font.render("Bullets: " +str(bullets), 1, black)
win.blit(scoretext, (5, 5))
kill = font.render("Kill count: " +str(killcounter), 1, black)
win.blit(kill, (250, 5))
pygame.display.flip()
clock.tick(100)
pygame.quit()
What I had to do was:
add a start for a new timer
#Start screen Loop
done = False
start_time = pygame.time.get_ticks()
When you determine the game is over, obtain the time taken here
def gameOverScreen():
seconds_survived = (pygame.time.get_ticks() - start_time) // 1000
ending = 1
What you have to do is find the time at the moment of collision (when collide is true) and pass that as an argument to gameOverScreen().
if collide:
gameover = True
end_time = pygame.time.get_ticks()
And gameOverScreen should receive the argument end_time and use it to display the seconds
def gameOverScreen(end_time):
seconds_survived = (end_time - start_time) // 1000
Keep in mind this only works because "if collide" is True only once, if it was True repeatedly then end_time would keep updating in the loop and you would again see the same case of increasing seconds.
Hope this helped someone!

Snake game: snake and apples do not appear on the screen

I'm trying to make the snake game in python, but sadly my snake and my apples aren't appearing on the screen, all i see is a gray screen with nothing on it, can you help me out? thanks!
P.S - i would like an explanation as well about why my current code isn't working so i would avoid it in the future, thanks again.
import pygame, sys, random, time
from pygame.locals import *
pygame.init()
mainClock = pygame.time.Clock()
windowWidth = 500
windowHeight = 500
windowSurface = pygame.display.set_mode((windowWidth, windowHeight), 0, 32)
red = (255, 0, 0)
green = (0, 255, 0)
color = (100, 100, 100)
snakeHead = [250, 250]
snakePosition = [[250, 250],[240, 250],[230, 250]]
applePosition = [random.randrange(1,50)*10,random.randrange(1,50)*10]
def collisionBoundarias(snakeHead):
if snakeHead[0] >= 500 or snakeHead[0] < 0 or snakeHead[1] >= 500 or snakeHead[1] < 0:
return 1
else:
return 0
def collisionSelf(SnakePosition):
snakeHead = snakePosition[0]
if snakeHead in snakePosition[1:]:
return 1
else:
return 0
while True:
windowSurface.fill(color)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.type == pygame.K_RIGHT or event.key == pygame.K_d:
snakeHead[0] += 10
if event.type == pygame.K_LEFT or event.key == pygame.K_a:
snakeHead[0] -= 10
if event.type == pygame.K_UP or event.type == pygame.K_w:
snakeHead[1] += 10
if event.type == pygame.K_DOWN or event.type == pygame.K_s:
snakeHead[1] -= 10
def displaySnake(snakePosition):
for position in snakePosition:
pygame.draw.rect(windowSurface ,red,pygame.Rect(position[0],position[1],10,10))
def display_apple(windowSurface, applePosition, apple):
windowSurface.blit(apple ,(applePosition[0], applePosition[1]))
snakePosition.insert(0,list(snakeHead))
snakePosition.pop()
def displayFinalScore(displayText, finalScore):
largeText = pygame.font.Font('freesansbold.ttf',35)
TextSurf = largeText.render(displayText, True, (255, 255, 255))
TextRect = TextSurf.get_rect()
TextRect.center = ((windowWidth/2),(windowHeight/2))
windowSurface.blit(TextSurf, TextRect)
pygame.display.update()
time.sleep(2)
def collisionApple(applePosition, score):
applePosition = [random.randrange(1,50)*10,random.randrange(1,50)*10]
score += 1
return applePosition, score
if snakeHead == applePosition:
applePosition, score = collisionApple(applePosition, score)
snakePosition.insert(0,list(snakeHead))
pygame.display.update()
clock = pygame.time.Clock()
clock.tick(20)
As mentioned in the comments, the objects don't appear because you never draw them by calling the displaySnake and display_apple functions. It also makes no sense to define these functions in the while loop again and again.
Here's a fixed version of the code. I've changed the movement code, so that the snake moves continually each frame. (It could still be improved, but I tried to keep it simple.)
import pygame, sys, random, time
from pygame.locals import *
pygame.init()
mainClock = pygame.time.Clock()
windowWidth = 500
windowHeight = 500
windowSurface = pygame.display.set_mode((windowWidth, windowHeight), 0, 32)
clock = pygame.time.Clock()
red = (255, 0, 0)
green = (0, 255, 0)
color = (100, 100, 100)
snakeHead = [250, 250]
snakePosition = [[250, 250],[240, 250],[230, 250]]
applePosition = [random.randrange(1,50)*10,random.randrange(1,50)*10]
apple = pygame.Surface((10, 10))
apple.fill(green)
score = 0
speed = 10
# Define a velocity variable (a list or better a pygame.Vector2).
velocity = pygame.Vector2(speed, 0)
def collisionBoundarias(snakeHead):
return snakeHead[0] >= 500 or snakeHead[0] < 0 or snakeHead[1] >= 500 or snakeHead[1] < 0
def collisionApple(applePosition, score):
applePosition = [random.randrange(1,50)*10,random.randrange(1,50)*10]
score += 1
return applePosition, score
def displaySnake(snakePosition):
for position in snakePosition:
pygame.draw.rect(windowSurface, red, pygame.Rect(position[0], position[1], 10, 10))
def display_apple(windowSurface, applePosition, apple):
windowSurface.blit(apple, (applePosition[0], applePosition[1]))
while True:
# Event handling.
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
# Replace `type` with `key`.
if event.key == pygame.K_RIGHT or event.key == pygame.K_d:
velocity.x = speed
velocity.y = 0
if event.key == pygame.K_LEFT or event.key == pygame.K_a:
velocity.x = -speed
velocity.y = 0
if event.key == pygame.K_UP or event.key == pygame.K_w:
velocity.x = 0
velocity.y = -speed
if event.key == pygame.K_DOWN or event.key == pygame.K_s:
velocity.x = 0
velocity.y = speed
# Game logic.
snakeHead[0] += velocity.x # Update the x-position every frame.
snakeHead[1] += velocity.y # Update the y-position every frame.
snakePosition.insert(0, snakeHead)
snakePosition.pop()
if snakeHead == applePosition:
applePosition, score = collisionApple(applePosition, score)
snakePosition.insert(0, snakeHead)
# Drawing.
windowSurface.fill(color)
displaySnake(snakePosition)
display_apple(windowSurface, applePosition, apple)
pygame.display.update()
clock.tick(20)

How do I continuously loop KEYDOWN in pygame?

I'm new to python/pygame and I can't figure this out. Whenever I press and hold a key it won't loop the KEYDOWN. Also, if I hold the key on my keyboard down and move the mouse at the same time, it seems to move continuously.
Can someone tell me what I'm doing wrong?
import pygame
import random
pygame.init()
#Colors
white = 255, 255, 255
black = 0, 0, 0
back_color = 48, 255, 124
light_color = 34, 155, 78
#Display W/H
display_width = 800
display_height = 600
#X/Y
x_axis = 400
y_axis = 580
Block_size = 20
x_int = 0
y_int = 0
ON = True
Window = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('Game')
#On Loop
while ON == True:
#Screen Event
for Screen in pygame.event.get():
#Quit Screen
if Screen.type == pygame.QUIT:
pygame.quit()
exit()
#Quit Full Screen
if Screen.type == pygame.KEYDOWN:
if Screen.key == pygame.K_q:
pygame.quit()
exit()
#Full Screen !!!!!!!! EDIT THIS !!!!!!!!
if Screen.type == pygame.KEYDOWN:
if Screen.key == pygame.K_1:
pygame.display.set_mode((display_width, display_height),pygame.FULLSCREEN)
if Screen.key == pygame.K_2:
pygame.display.set_mode((display_width, display_height))
#Player Movement K DOWN
if Screen.type == pygame.KEYDOWN:
if Screen.key == pygame.K_d:
x_int = 20
if Screen.key == pygame.K_a:
x_int = -20
#Player Movement K UP
if Screen.type == pygame.KEYUP:
if Screen.key == pygame.K_d or Screen.key == pygame.K_a:
x_int = 0
x_axis += x_int
Window.fill((back_color))
Player = pygame.draw.rect(Window, light_color, [x_axis, y_axis, Block_size, Block_size])
pygame.display.update()
quit()
I have improved your code. You have placed the screen update (drawing the screen) portion in the events loop whereas it should be in the while loop. The code I have mode is a bit complex but works as expected. Why it is complex? When the key is held down, then the events list is empty (you can print the events). I have also made the block not to go out of the screen. The speed of the block was high so I decreased it to 10.
import pygame
import random
pygame.init()
#Colors
white = 255, 255, 255
black = 0, 0, 0
back_color = 48, 255, 124
light_color = 34, 155, 78
#Display W/H
display_width = 800
display_height = 600
#X/Y
x_axis = 400
y_axis = 580
global x_int
Block_size = 20
x_int = 0
y_int = 0
ON = True
Window = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('Game')
global topass_a,topass_d
x_int,topass_a,topass_d = 0,0,0
#On Loop
while ON:
#Screen Event
events = pygame.event.get()
def on_a_press():
global topass_a,x_int
x_int = -10
topass_a = 1
def on_d_press():
global topass_d,x_int
x_int = 10
topass_d = 1
if len(events) == 0:
if topass_a == 1:on_a_press()
if topass_d == 1:on_d_press()
for Screen in events:
if Screen.type == pygame.QUIT:
pygame.quit()
exit()
if Screen.type == pygame.KEYDOWN:
if Screen.key == pygame.K_q:
pygame.quit()
exit()
if Screen.key == pygame.K_1:
pygame.display.set_mode((display_width, display_height),pygame.FULLSCREEN)
if Screen.key == pygame.K_2:
pygame.display.set_mode((display_width, display_height))
if Screen.key == pygame.K_d or topass_d == 1:
on_d_press()
if Screen.key == pygame.K_a or topass_a == 1:
on_a_press()
if Screen.type == pygame.KEYUP:
if Screen.key == pygame.K_d or Screen.key == pygame.K_a:
x_int = 0
topass_a = 0
topass_d = 0
x_axis += x_int
x_int = 0
if x_axis < 0:x_axis=0
elif x_axis >= display_width-Block_size:x_axis = display_width-Block_size
Window.fill((back_color))
Player = pygame.draw.rect(Window, light_color, [x_axis, y_axis, Block_size, Block_size])
pygame.display.update()
You can further improve the code as you need.
Edit:
Why complex? Easy things come first. I have realized that there is no need to track the keys. pygame.key.get_pressed() returns the pressed key. Here is a smaller , better and improved code. I have also implemented the w and s (y_axis) keys.
import pygame
import random
pygame.init()
#Colors
white = 255, 255, 255
black = 0, 0, 0
back_color = 48, 255, 124
light_color = 34, 155, 78
#Display W/H
display_width = 800
display_height = 600
#X/Y
x_axis = 400
y_axis = 580
Block_size = 20
x_int = 0
y_int = 0
ON = True
Window = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('Game')
while ON:
events = pygame.event.get()
for Screen in events:
if Screen.type == pygame.QUIT:
pygame.quit()
exit()
if Screen.type == pygame.KEYDOWN:
if Screen.key == pygame.K_q:
pygame.quit()
exit()
if Screen.key == pygame.K_1:
pygame.display.set_mode((display_width, display_height),pygame.FULLSCREEN)
if Screen.key == pygame.K_2:
pygame.display.set_mode((display_width, display_height))
keys = pygame.key.get_pressed()
if keys[pygame.K_a]:
x_int = -10
if keys[pygame.K_d]:
x_int = 10
# keys controlling y axis, you can remove these lines
if keys[pygame.K_w]:
y_int = -10
if keys[pygame.K_s]:
y_int = 10
#x_axis......
x_axis += x_int
x_int = 0
if x_axis < 0:x_axis=0
elif x_axis >= display_width-Block_size:x_axis = display_width-Block_size
#y axis
y_axis += y_int
y_int = 0
if y_axis < 0:y_axis=0
elif y_axis >= display_height-Block_size:y_axis = display_height-Block_size
#updaing screen
Window.fill((back_color))
Player = pygame.draw.rect(Window, light_color, [x_axis, y_axis, Block_size, Block_size])
pygame.display.update()
You only receive pygame.KEYDOWN when the key is first pressed - not while it is held down. The simple solution is to only draw while the key is down (ie. when x_int != 0)
#On Loop
while ON == True:
#Screen Event
for Screen in pygame.event.get():
# <Removed not relevant code for brevity>
#Player Movement K DOWN
if Screen.type == pygame.KEYDOWN:
if Screen.key == pygame.K_d:
x_int = 20
if Screen.key == pygame.K_a:
x_int = -20
#Player Movement K UP
if Screen.type == pygame.KEYUP:
if Screen.key == pygame.K_d or Screen.key == pygame.K_a:
x_int = 0
# Render only happens if x_int is not zero
# (Need to add code to force render first time)
if x_int:
x_axis += x_int
Window.fill((back_color))
Player = pygame.draw.rect(Window, light_color, [x_axis, y_axis, Block_size, Block_size])
pygame.display.update()
As the program grows and gets more complex, you'll need better logic for when to render, but this will get you started.

Python sprite not moving when key is held down

I'm working on the basics of a game right now, but for some reason I cannot get my sprite to move. I know that it's registering when I'm pressing the key down, but the sprite for some reason just stays still.
import pygame
import sys
from pygame.locals import *
import time
pygame.init()
black = (0, 0, 0)
white = (255, 255, 255)
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("RADICAL")
screen.fill(black)
imga = pygame.image.load('coina.png')
imgb = pygame.image.load('coinb.png')
sound = pygame.mixer.Sound('coin.mp3')
FPS = 80
imgx = 10
imgy = 10
pixMove = 10
steps = 0
x1 = 0
y1 = 0
keystate = pygame.key.get_pressed()
GameOver = False
while not GameOver:
screen.fill(white)
points = (steps)
font = pygame.font.SysFont(None, 30)
text = font.render('Score: '+str(points), True, black)
screen.blit(text, (0,0))
if steps % 2 == 0:
screen.blit(imga, (imgx, imgy))
else:
screen.blit(imgb, (imgx, imgy))
for event in pygame.event.get():
print event
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if keystate[pygame.K_UP]:
y1 -= pixMove
elif keystate[pygame.K_DOWN]:
y1 += pixMove
elif keystate[pygame.K_LEFT]:
x1 -= pixMove
elif keystate[pygame.K_RIGHT]:
x1 += pixMove
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x1 = 0
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y1 = 0
steps +=1
if event.type == K_SPACE:
sound.play()
time.sleep(1)
sound.stop()
pygame.display.update()
fpsTime.tick(FPS)
Generally you blit() images on to the screen (pygame.display.set_mode()), for the changes to to reflect on the screen we call pygame.display.update(), In your case the game never comes the statement, which is out of while loop.

Categories

Resources