How to simulate a morse-tapper in Python3 [duplicate] - python-3.x

I am making a game in pygame 1.9.2.
It's a faily simple game in which a ship moves between five columns of bad guys who attack by moving slowly downward. I am attempting to make it so that the ship moves left and right with the left and right arrow keys. Here is my code:
keys=pygame.key.get_pressed()
if keys[K_LEFT]:
location-=1
if location==-1:
location=0
if keys[K_RIGHT]:
location+=1
if location==5:
location=4
It works too well. The ship moves too fast. It is near impossible to have it move only one location, left or right. How can i make it so the ship only moves once every time the key is pressed?

You can get the events from pygame and then watch out for the KEYDOWN event, instead of looking at the keys returned by get_pressed()(which gives you keys that are currently pressed down, whereas the KEYDOWN event shows you which keys were pressed down on that frame).
What's happening with your code right now is that if your game is rendering at 30fps, and you hold down the left arrow key for half a second, you're updating the location 15 times.
events = pygame.event.get()
for event in events:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
location -= 1
if event.key == pygame.K_RIGHT:
location += 1
To support continuous movement while a key is being held down, you would have to establish some sort of limitation, either based on a forced maximum frame rate of the game loop or by a counter which only allows you to move every so many ticks of the loop.
move_ticker = 0
keys=pygame.key.get_pressed()
if keys[K_LEFT]:
if move_ticker == 0:
move_ticker = 10
location -= 1
if location == -1:
location = 0
if keys[K_RIGHT]:
if move_ticker == 0:
move_ticker = 10
location+=1
if location == 5:
location = 4
Then somewhere during the game loop you would do something like this:
if move_ticker > 0:
move_ticker -= 1
This would only let you move once every 10 frames (so if you move, the ticker gets set to 10, and after 10 frames it will allow you to move again)

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 1, otherwise 0. Use pygame.key.get_pressed() to evaluate the current state of a button and get continuous movement:
while True:
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= speed
if keys[pygame.K_RIGHT]:
x += speed
if keys[pygame.K_UP]:
y -= speed
if keys[pygame.K_DOWN]:
y += speed
This code can be simplified by subtracting "left" from "right" and "up" from "down":
while True:
keys = pygame.key.get_pressed()
x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * speed
y += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * speed
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 movement:
while True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x -= speed
if event.key == pygame.K_RIGHT:
x += speed
if event.key == pygame.K_UP:
y -= speed
if event.key == pygame.K_DOWN:
y += speed
See also Key and Keyboard event
Minimal example of continuous movement: replit.com/#Rabbid76/PyGame-ContinuousMovement
import pygame
pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
rect = pygame.Rect(0, 0, 20, 20)
rect.center = window.get_rect().center
vel = 5
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
print(pygame.key.name(event.key))
keys = pygame.key.get_pressed()
rect.x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * vel
rect.y += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * vel
rect.centerx = rect.centerx % window.get_width()
rect.centery = rect.centery % window.get_height()
window.fill(0)
pygame.draw.rect(window, (255, 0, 0), rect)
pygame.display.flip()
pygame.quit()
exit()
Minimal example for a single action: replit.com/#Rabbid76/PyGame-ShootBullet
import pygame
pygame.init()
window = pygame.display.set_mode((500, 200))
clock = pygame.time.Clock()
tank_surf = pygame.Surface((60, 40), pygame.SRCALPHA)
pygame.draw.rect(tank_surf, (0, 96, 0), (0, 00, 50, 40))
pygame.draw.rect(tank_surf, (0, 128, 0), (10, 10, 30, 20))
pygame.draw.rect(tank_surf, (32, 32, 96), (20, 16, 40, 8))
tank_rect = tank_surf.get_rect(midleft = (20, window.get_height() // 2))
bullet_surf = pygame.Surface((10, 10), pygame.SRCALPHA)
pygame.draw.circle(bullet_surf, (64, 64, 62), bullet_surf.get_rect().center, bullet_surf.get_width() // 2)
bullet_list = []
run = True
while run:
clock.tick(60)
current_time = pygame.time.get_ticks()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
bullet_list.insert(0, tank_rect.midright)
for i, bullet_pos in enumerate(bullet_list):
bullet_list[i] = bullet_pos[0] + 5, bullet_pos[1]
if bullet_surf.get_rect(center = bullet_pos).left > window.get_width():
del bullet_list[i:]
break
window.fill((224, 192, 160))
window.blit(tank_surf, tank_rect)
for bullet_pos in bullet_list:
window.blit(bullet_surf, bullet_surf.get_rect(center = bullet_pos))
pygame.display.flip()
pygame.quit()
exit()

import pygame
pygame.init()
pygame.display.set_mode()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit(); #sys.exit() if sys is imported
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_0:
print("Hey, you pressed the key, '0'!")
if event.key == pygame.K_1:
print("Doing whatever")
In note that K_0 and K_1 aren't the only keys, to see all of them, see pygame documentation, otherwise, hit tab after typing in
pygame.
(note the . after pygame) into an idle program. Note that the K must be capital. Also note that if you don't give pygame a display size (pass no args), then it will auto-use the size of the computer screen/monitor. Happy coding!

I think you can use:
pygame.time.delay(delayTime)
in which delayTime is in milliseconds.
Put it before events.

Try this:
keys=pygame.key.get_pressed()
if keys[K_LEFT]:
if count == 10:
location-=1
count=0
else:
count +=1
if location==-1:
location=0
if keys[K_RIGHT]:
if count == 10:
location+=1
count=0
else:
count +=1
if location==5:
location=4
This will mean you only move 1/10 of the time. If it still moves to fast you could try increasing the value you set "count" too.

The reason behind this is that the pygame window operates at 60 fps (frames per second) and when you press the key for just like 1 sec it updates 60 frames as per the loop of the event block.
clock = pygame.time.Clock()
flag = true
while flag :
clock.tick(60)
Note that if you have animation in your project then the number of images will define the number of values in tick(). Let's say you have a character and it requires 20 sets images for walking and jumping then you have to make tick(20) to move the character the right way.

Just fyi, if you're trying to ensure the ship doesn't go off of the screen with
location-=1
if location==-1:
location=0
you can probably better use
location -= 1
location = max(0, location)
This way if it skips -1 your program doesn't break

make something like this, but based on time delay. i call my function first time immediately and then lunch timer, and while button is pressed i call it every button_press_delta seconds
from time import time
before main loop:
button_press_delta = 0.2
right_button_pressed = 0
while not done:
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
if not right_button_pressed:
call_my_function()
right_button_pressed = 1
right_button_pressed_time_start = time()
if right_button_pressed:
right_button_pressed_time = (
time() - right_button_pressed_time_start)
if right_button_pressed_time > button_press_delta:
call_my_function()
right_button_pressed_time_start = time()
else:
right_button_pressed = 0

You should use clock.tick(10) as stated in the docs.

all of the answers above are too complexicated i would just change the variables by 0.1 instead of 1
this makes the ship 10 times slower
if that is still too fast change the variables by 0.01
this makes the ship 100 times slower
try this
keys=pygame.key.get_pressed()
if keys[K_LEFT]:
location -= 0.1 #or 0.01
if location==-1:
location=0
if keys[K_RIGHT]:
location += 0.1 #or 0.01
if location==5:
location=4

To slow down your game, use pygame.clock.tick(10)

Related

Space Invaders bug pygame

After finally beeing able to make multiple enemies in the game I confronted myself with the most annoying bug ever. I have multiple enemies, a space ship and I can even shoot bullets, but right after I added the enemies to the game and followed the exact same steps as show in this video, the background is gone for some reason, what made the speed of the player character, of the enemies and the bullet went like crazy. Plus, the sprites are duplicating themselves and wont go away, and the only think that I can think is "What the hell am I doing wrong??" because I feel like I can't even follow the steps and copy the code from a video (btw I'm not receiving any error messages). Anyways, here's the full game code.
import pygame
import random
import math
# Initiate pygame
pygame.init()
# Display the game window
screen = pygame.display.set_mode((800, 600))
# Title and Icon
pygame.display.set_caption('Space Invaders')
icon = pygame.image.load('icon.png')
pygame.display.set_icon(icon)
# Background
background = pygame.image.load('background.png')
# Player
playerSprite = pygame.image.load('player.png')
playerX = 370
playerY = 480
playerX_change = 0
# Enemies
enemySprite = []
enemyX = []
enemyY = []
enemyX_change = []
enemyY_change = []
num_of_enemies = 6
for i in range(num_of_enemies):
enemySprite.append(pygame.image.load('enemy.png'))
enemyX.append(random.randint(0, 736))
enemyY.append(random.randint(50, 150))
enemyX_change.append(4)
enemyY_change.append(40)
# Bullet
bulletSprite = pygame.image.load('bullet.png')
bulletX = 0
bulletY = 480
bulletY_change = 10
# When bullet_state = 'ready', you can't see the bullet on the screen
# When bullet_state = 'fire', the bullet is currently moving
bullet_state = 'ready'
score = 0
def player(x, y):
screen.blit(playerSprite, (x, y))
def enemy(x, y, i):
screen.blit(enemySprite[i], (x, y))
def fire_bullet(x, y):
global bullet_state
bullet_state = 'fire'
screen.blit(bulletSprite, (x + 16, y + 10))
def isCollision(enemyX, enemyY, bulletX, bulletY):
distance = math.sqrt((math.pow(enemyX - bulletX, 2)) + (math.pow(enemyY - bulletY, 2)))
if distance < 27:
return True
else:
return False
# Game Loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# If a key is pressed, check if it's the right or left arrow key
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -5
if event.key == pygame.K_RIGHT:
playerX_change = 5
if event.key == pygame.K_SPACE:
if bullet_state == 'ready':
bulletX = playerX
fire_bullet(playerX, bulletY)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
# Player movement
playerX += playerX_change
# Prevents the player from going off the border
if playerX <= 0:
playerX = 0
elif playerX >= 736:
playerX = 736
# Enemies movement
for i in range(num_of_enemies):
enemyX[i] += enemyX_change[i]
if enemyX[i] <= 0:
enemyX_change[i] = 4
enemyY[i] += enemyX_change[i]
elif enemyX[i] >= 736:
enemyX_change[i] = -4
enemyY[i] += enemyY_change[i]
# Collision
collision = isCollision(enemyX[i], enemyY[i], bulletX, bulletY)
if collision:
bulletY = 480
bullet_state = 'ready'
score += 1
print(score)
enemyX[i] = random.randint(0, 736)
enemyY[i] = random.randint(50, 150)
enemy(enemyX[i], enemyY[i], i)
# Bullet movement
if bulletY <= 0:
bulletY = 480
bullet_state = 'ready'
if bullet_state == 'fire':
fire_bullet(bulletX, bulletY)
bulletY -= bulletY_change
player(playerX, playerY)
pygame.display.update()
the background is gone for some reason
Of course, because the background is never blit to screen.
the sprites are duplicating themselves and wont go away,
That's because you don't draw the background.
blit the background in the main application loop, before the objects of the scene are drawn:
while running:
# [...]
screen.blit(background, (0, 0))
# Enemies movement
for i in range(num_of_enemies):
# [...]
the speed of the player character, of the enemies and the bullet went like crazy.
Use pygame.time.Clock() to control the frames per second.
clock = pygame.time.Clock()
running = True
while running:
clock.tick(60)
# [...]
Another (less sophisticated) possibility, which is probably use in the tutorial is to use pygame.time.delay():
running = True
while running:
pygame.time.delay(10)
# [...]

Pygame assistance [duplicate]

I am making a game in pygame 1.9.2.
It's a faily simple game in which a ship moves between five columns of bad guys who attack by moving slowly downward. I am attempting to make it so that the ship moves left and right with the left and right arrow keys. Here is my code:
keys=pygame.key.get_pressed()
if keys[K_LEFT]:
location-=1
if location==-1:
location=0
if keys[K_RIGHT]:
location+=1
if location==5:
location=4
It works too well. The ship moves too fast. It is near impossible to have it move only one location, left or right. How can i make it so the ship only moves once every time the key is pressed?
You can get the events from pygame and then watch out for the KEYDOWN event, instead of looking at the keys returned by get_pressed()(which gives you keys that are currently pressed down, whereas the KEYDOWN event shows you which keys were pressed down on that frame).
What's happening with your code right now is that if your game is rendering at 30fps, and you hold down the left arrow key for half a second, you're updating the location 15 times.
events = pygame.event.get()
for event in events:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
location -= 1
if event.key == pygame.K_RIGHT:
location += 1
To support continuous movement while a key is being held down, you would have to establish some sort of limitation, either based on a forced maximum frame rate of the game loop or by a counter which only allows you to move every so many ticks of the loop.
move_ticker = 0
keys=pygame.key.get_pressed()
if keys[K_LEFT]:
if move_ticker == 0:
move_ticker = 10
location -= 1
if location == -1:
location = 0
if keys[K_RIGHT]:
if move_ticker == 0:
move_ticker = 10
location+=1
if location == 5:
location = 4
Then somewhere during the game loop you would do something like this:
if move_ticker > 0:
move_ticker -= 1
This would only let you move once every 10 frames (so if you move, the ticker gets set to 10, and after 10 frames it will allow you to move again)
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 1, otherwise 0. Use pygame.key.get_pressed() to evaluate the current state of a button and get continuous movement:
while True:
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= speed
if keys[pygame.K_RIGHT]:
x += speed
if keys[pygame.K_UP]:
y -= speed
if keys[pygame.K_DOWN]:
y += speed
This code can be simplified by subtracting "left" from "right" and "up" from "down":
while True:
keys = pygame.key.get_pressed()
x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * speed
y += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * speed
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 movement:
while True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x -= speed
if event.key == pygame.K_RIGHT:
x += speed
if event.key == pygame.K_UP:
y -= speed
if event.key == pygame.K_DOWN:
y += speed
See also Key and Keyboard event
Minimal example of continuous movement: replit.com/#Rabbid76/PyGame-ContinuousMovement
import pygame
pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
rect = pygame.Rect(0, 0, 20, 20)
rect.center = window.get_rect().center
vel = 5
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
print(pygame.key.name(event.key))
keys = pygame.key.get_pressed()
rect.x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * vel
rect.y += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * vel
rect.centerx = rect.centerx % window.get_width()
rect.centery = rect.centery % window.get_height()
window.fill(0)
pygame.draw.rect(window, (255, 0, 0), rect)
pygame.display.flip()
pygame.quit()
exit()
Minimal example for a single action: replit.com/#Rabbid76/PyGame-ShootBullet
import pygame
pygame.init()
window = pygame.display.set_mode((500, 200))
clock = pygame.time.Clock()
tank_surf = pygame.Surface((60, 40), pygame.SRCALPHA)
pygame.draw.rect(tank_surf, (0, 96, 0), (0, 00, 50, 40))
pygame.draw.rect(tank_surf, (0, 128, 0), (10, 10, 30, 20))
pygame.draw.rect(tank_surf, (32, 32, 96), (20, 16, 40, 8))
tank_rect = tank_surf.get_rect(midleft = (20, window.get_height() // 2))
bullet_surf = pygame.Surface((10, 10), pygame.SRCALPHA)
pygame.draw.circle(bullet_surf, (64, 64, 62), bullet_surf.get_rect().center, bullet_surf.get_width() // 2)
bullet_list = []
run = True
while run:
clock.tick(60)
current_time = pygame.time.get_ticks()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
bullet_list.insert(0, tank_rect.midright)
for i, bullet_pos in enumerate(bullet_list):
bullet_list[i] = bullet_pos[0] + 5, bullet_pos[1]
if bullet_surf.get_rect(center = bullet_pos).left > window.get_width():
del bullet_list[i:]
break
window.fill((224, 192, 160))
window.blit(tank_surf, tank_rect)
for bullet_pos in bullet_list:
window.blit(bullet_surf, bullet_surf.get_rect(center = bullet_pos))
pygame.display.flip()
pygame.quit()
exit()
import pygame
pygame.init()
pygame.display.set_mode()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit(); #sys.exit() if sys is imported
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_0:
print("Hey, you pressed the key, '0'!")
if event.key == pygame.K_1:
print("Doing whatever")
In note that K_0 and K_1 aren't the only keys, to see all of them, see pygame documentation, otherwise, hit tab after typing in
pygame.
(note the . after pygame) into an idle program. Note that the K must be capital. Also note that if you don't give pygame a display size (pass no args), then it will auto-use the size of the computer screen/monitor. Happy coding!
I think you can use:
pygame.time.delay(delayTime)
in which delayTime is in milliseconds.
Put it before events.
Try this:
keys=pygame.key.get_pressed()
if keys[K_LEFT]:
if count == 10:
location-=1
count=0
else:
count +=1
if location==-1:
location=0
if keys[K_RIGHT]:
if count == 10:
location+=1
count=0
else:
count +=1
if location==5:
location=4
This will mean you only move 1/10 of the time. If it still moves to fast you could try increasing the value you set "count" too.
The reason behind this is that the pygame window operates at 60 fps (frames per second) and when you press the key for just like 1 sec it updates 60 frames as per the loop of the event block.
clock = pygame.time.Clock()
flag = true
while flag :
clock.tick(60)
Note that if you have animation in your project then the number of images will define the number of values in tick(). Let's say you have a character and it requires 20 sets images for walking and jumping then you have to make tick(20) to move the character the right way.
Just fyi, if you're trying to ensure the ship doesn't go off of the screen with
location-=1
if location==-1:
location=0
you can probably better use
location -= 1
location = max(0, location)
This way if it skips -1 your program doesn't break
make something like this, but based on time delay. i call my function first time immediately and then lunch timer, and while button is pressed i call it every button_press_delta seconds
from time import time
before main loop:
button_press_delta = 0.2
right_button_pressed = 0
while not done:
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
if not right_button_pressed:
call_my_function()
right_button_pressed = 1
right_button_pressed_time_start = time()
if right_button_pressed:
right_button_pressed_time = (
time() - right_button_pressed_time_start)
if right_button_pressed_time > button_press_delta:
call_my_function()
right_button_pressed_time_start = time()
else:
right_button_pressed = 0
You should use clock.tick(10) as stated in the docs.
all of the answers above are too complexicated i would just change the variables by 0.1 instead of 1
this makes the ship 10 times slower
if that is still too fast change the variables by 0.01
this makes the ship 100 times slower
try this
keys=pygame.key.get_pressed()
if keys[K_LEFT]:
location -= 0.1 #or 0.01
if location==-1:
location=0
if keys[K_RIGHT]:
location += 0.1 #or 0.01
if location==5:
location=4
To slow down your game, use pygame.clock.tick(10)

Powerbar decrease script, pygame

I'm trying to create a "powerbar."
In the following code I can press left & right key to increase the bar, and the prg terminates when the bar_start_width > 400 px.
I would like the "powerbar" to decrease while bar_start_width > 0. So, if you stop to press the buttons, the bar will slowly decrease until bar_start_width > 0.
With my code it is slowly decreasing bar_start_width, but not updating the display. The while loop also continues running.
Here is full code:
import time
import random
import pygame
import time
import pygame
pygame.init()
display_width = 800
display_height = 600
black = (0, 0, 0)
white = (255, 255, 255)
gameDisplay = pygame.display.set_mode((display_width, display_height))
clock = pygame.time.Clock()
def powerbar(thingx, thingy, thingw, thingh, color):
pygame.draw.rect(gameDisplay, color, [thingx, thingy, thingw, thingh])
def game_quit():
pygame.quit()
quit()
def game_loop():
decrease_speed = -1
bar_start_width = 0
bar_x = 100
bar_y = 100
bar_height = 50
bar_color = black
x_change = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
gameDisplay.fill(white) # the background color before img
# Should change so you can ONLY press right after left (or opposite)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = 5
if event.key == pygame.K_RIGHT:
x_change = 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_change = 0
bar_start_width += x_change
# Draw powerbar
powerbar(bar_x, bar_y, bar_start_width, bar_height, bar_color)
if bar_start_width > 10:
while True:
bar_start_width += decrease_speed
time.sleep(0.5)
print(bar_start_width) #See output in terminal
if bar_start_width == 0:
break
if bar_start_width > 400:
game_quit()
pygame.display.update()
clock.tick(60)
game_loop()
pygame.quit()
quit()
I have tried also to think in terms of a for loop to solve my problems but after long time of trying out different things this is the best I can come up with.
Can anyone help, or link me to a similar discussion?
Thanks!
I'm not sure why you have a nested while loop in the main while loop. If I understand you correctly, you want to decrease the width every frame if (not while) the width is greater than 0. Just remove the while loop and the time.sleep call and decrease the width if bar_start_width > 0:.
import pygame
pygame.init()
black = (0, 0, 0)
white = (255, 255, 255)
gameDisplay = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
def game_loop():
decrease_speed = -1
bar_start_width = 0
bar_x = 100
bar_y = 100
bar_height = 50
x_change = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = 5
elif event.key == pygame.K_RIGHT:
x_change = 5
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_change = 0
bar_start_width += x_change
if bar_start_width > 0:
bar_start_width += decrease_speed
if bar_start_width <= 0: # Set it to the minimum width of 1.
bar_start_width = 1
if bar_start_width > 400:
print('> 400')
gameDisplay.fill(white)
# Draw powerbar
pygame.draw.rect(gameDisplay, black, (bar_x, bar_y, bar_start_width, bar_height))
pygame.display.update()
clock.tick(60)
game_loop()
pygame.quit()
I've rearranged a few things, because the game logic and the event loop were mixed. You should generally try to separate the event handling, game logic and the rendering.

Pressing a button to have constant movement

I followed an online tutorial to make a snake game and want some help to make some changes. As of now, holding the left or right arrow keys will cause the snake to move. Would it be able to make the snake move to the left or right with only a tap of the button so the user doesn't have to hold down the arrow keys?
question = True
while not gameExit:
#Movement
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
direction = "left"
start_x_change = -block_size_mov
start_y_change = 0
elif event.key == pygame.K_RIGHT:
leftMov = False
direction = "right"
start_x_change = block_size_mov
start_y_change = 0
The solution is to start off by storing the x,y coordinates of the sprite, set a modifier (increase or decrease amount) on keypress, and then add the modifier to the coordinates while looping. I've written a quick demo of such a system:
import pygame
from pygame.locals import *
pygame.init()
# Set up the screen
screen = pygame.display.set_mode((500,500), 0, 32)
# Make a simple white square sprite
player = pygame.Surface([20,20])
player.fill((255,255,255))
# Sprite coordinates start at the centre
x = y = 250
# Set movement factors to 0
movement_x = movement_y = 0
while True:
screen.fill((0,0,0))
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_LEFT:
movement_x = -0.05
movement_y = 0
elif event.key == K_RIGHT:
movement_x = 0.05
movement_y = 0
elif event.key == K_UP:
movement_y = -0.05
movement_x = 0
elif event.key == K_DOWN:
movement_y = 0.05
movement_x = 0
# Modify the x and y coordinates
x += movement_x
y += movement_y
screen.blit(player, (x, y))
pygame.display.update()
Note that you need to reset the x movement modifier to 0 when changing y, and vice-versa - otherwise you end up with interesting diagonal movements!
For a snake game, you might want to modify the snake size as well as/instead of position - but you should be able to achieve something similar using the same structure.

pygame event keys are not responding even though idle is not showing an error?

import pygame
from pygame import *
pygame.init
pygame.display.init
pygame.display.set_caption("Test")
bg = pygame.image.load("bg.jpg")
human = pygame.image.load("human1.bmp")
display_screen = pygame.display.set_mode((1000,500))
keyboard_input = 0
clock = pygame.time.Clock()
def screen_Quit():
running = False
while not running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
keyboard_input = (90)
print("Left arrow key has been pressed.")
if event.key == pygame.K_RIGHT:
keyboard_input = (-90)
print("Right arrow key has been pressed.")
if event.key == pygame.K_UP:
keyboard_input = (20)
print("Up arrow key has been pressed.")
if event.key == pygame.K_DOWN:
keyboard_input = (-20)
print("Down arrow key has been pressed.")
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
keyboard_input = (0)
print("Left arrow key has been released.")
if event.key == pygame.K_RIGHT:
keyboard_input = (0)
print("Right arrow key has been released.")
if event.key == pygame.K_UP:
keyboard_input = (0)
print("Up arrow key has been released.")
if event.key == pygame.K_DOWN:
keyboard_input = (0)
print("Down arrow key has been released.")
# this code here has been left for later --> print(event)
display_screen.blit(bg, [0,0])
display_screen.blit(human, [50,87])
pygame.display.update()
clock.tick(60)
screen_Quit()
pygame.quit
quit()
I don't understand the problem, I have posted my full code as the problem might be something else. The problem I've been having with the program is the event keys in python it's not responding to the input which is the keyboard I'm using pygame to create a game but cannot understand why the event keys are not working. I have checked everywhere and cannot understand. The code seems fine to me, python idle is not giving any errors I'm even getting input in the idle but the character doesn't move there should be no reason for it not to move.
Here is a picture and a link to a video that goes more in depth into the problem (I created the video myself):
an image of the problem
Link to video:
https://www.youtube.com/watch?v=QVFaiuF9KY8&feature=youtu.be
Video will most likely be more useful than image.
Short Answer
Your code doesn't have any commands that tell the image to move. I fixed this and posted the full working code at the bottom. If you want a more in depth explanation, read on.
Explanation
If that is your full code, then the problem is that first of all you don't even have any code in the first place that tells the character to move. And second of all your pygame.display.update() is outside the while loop, so any changes made to the screen don't show.
For every event you just told python to print a message:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
keyboard_input = (90)
print("Left arrow key has been pressed.")
What you want to do is add another line there to actually move the character.
This can be done by changing it's x and y position. I recommend using sprites for this, but for now since you are using an image, we'll just stick to that.
To change the position of an image you have to run a new window.blit() with the desired (x,y). This means that you will have to constantly iterate this if you're going to need to move it around a lot, so it's better to put it INSIDE the running while loop. So bring this part of your code on indentation forward:
display_screen.blit(bg, [0,0])
display_screen.blit(human, [50,87])
pygame.display.update()
clock.tick(60)
screen_Quit()
pygame.quit
quit()
So now the screen get's regularly updated. The second thing you want to do is create 2 new variables x and yand change
display_screen.blit(human, [50,87])
to
display_screen.blit(human, [x,y])
This basically means that you character now gets blitted to the screen at the position YOU choose, not at a fixed position that doesn't change. So now you can add + to the x position whenever the left key is clicked, or - from the x position whenever the right key is clicked!
Here is the full working code:
import pygame
from pygame import *
pygame.init
pygame.display.init
pygame.display.set_caption("Test")
bg = pygame.image.load("bg.jpg")
human = pygame.image.load("human1.bmp")
display_screen = pygame.display.set_mode((1000,500))
keyboard_input = 0
clock = pygame.time.Clock()
running = False
x=0
y=0
moving = "none"
white = (255,255,255)
while True:
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:
moving = "left"
print("Left arrow key has been pressed.")
elif event.key == pygame.K_RIGHT:
moving = "right"
print("Right arrow key has been pressed.")
elif event.key == pygame.K_UP:
moving = "up"
print("Up arrow key has been pressed.")
elif event.key == pygame.K_DOWN:
moving = "down"
print("Down arrow key has been pressed.")
else:
moving = "hello"
if moving == "left":
x -= 5
if moving == "right":
x += 5
if moving == "up":
y -= 5
if moving == "down":
y += 5
# this code here has been left for later --> print(event)
display_screen.blit(bg,[0,0])
display_screen.blit(human, [x,y])
clock.tick(60)
pygame.display.update()
You never update the position of your player and just blit it at [50,87]. If you want it to move, you first have to store the position, e.g. player_pos = [50, 87] and define variables for the velocity velocity_x = 0, then set the velocity in the event loop if a key gets pressed:
if event.key == pygame.K_RIGHT:
velocity_x = 5
and update the position in the while loop:
player_pos[0] += velocity_x
player_pos[1] += velocity_y

Resources