Pygame multiple keys weird behaviour - pygame

I'm making a game with pygame and I encountered a problem with the following code :
while not self.end: # main game loop
keys = pygame.key.get_pressed()
if keys[K_LEFT]:
adddirection(LEFT)
elif keys[K_RIGHT]:
adddirection(RIGHT)
elif keys[K_UP]:
adddirection(UP)
elif keys[K_DOWN]:
adddirection(DOWN)
When I hold TOP arrow or DOWN arrow, if I press any right or left key, nothing will happen, the elif does not resolves. Why ? Should I do this another way ?
If I replace all the 'elif' by 'if' the opposite happens. If I hold left or right, top and down will never resolves.
I would like to understand that weird mechanic.

The code would be like
for event in pygame.event.get():
if event.type==QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if (event.key == K_LEFT):
//
elif (event.key == K_RIGHT):
//
elif (event.key == K_UP):
//
elif (event.key == K_DOWN):
//
keys_pressed = key.get_pressed()
if keys_pressed[K_LEFT]:
//
if keys_pressed[K_RIGHT]:
if keys_pressed[K_UP]:
//
if keys_pressed[K_DOWN]:
//
Replace // with your condtions

So, as per the nature of elif stacks, if one resolves as true, it wont test the others and simply skip, loop up how if elif else works online somewhere.
so you need to either use "if" for each, or split it in to a for loop.
However since you say when you use if for all of them, you still don't get your expected behaviour. I suspect this could be caused by "adddirection()", could you post that too if you cannot solve this issue?
As is mentioned in another answer, you can also use pygame events to deal with keypresses

The problem may be unsolvable. The way keyboards work is every key sends a signal on a copper wire through the USB cable. Mechanical (gaming) keyboards have a copper wire for each key, however to reduce the cost of cheap keyboards, many keys share a wire, and as a result only one of the keys which share a wire can be pressed at once. The arrow keys are on the same wire which may be contributing to your issue. The reason WASD is generally used for movement in games is because the 4 keys run along different wires.
TLDR: You may have better luck using WASD instead of your arrow keys

Related

Input within Functions - Python

I created a game that randomly picks a number, and the user has to guess that number. Normally, this would be easy, but I'm required to use functions to make it happen.
I have my code linked below. To explain:
get_num() function gives us a number (supposed to be 1 to 1000, but I have it 1 to 10 for troubleshooting)
ask_user() is an input that prompts the user to put in a number.
guess_check() is supposed to determine if your number it too high or too low.
num_guesses() is going to keep track of the number of times the user has guessed. But it's not done, you can ignore that for now.
I'm running PyCharm Community Edition 2021.3.2, for the record.
The problem: The program works fine, except it cannot tell if a number is too big or too small. When you keep guessing the same number, lets say "2", it will keep saying the number is too high and too low. Why? I have the If Statements perfect. If you look at the screenshot, the correct number is 7, and I have the proper if statement. Yet, it still recognizes 2 as higher than 7. Why?
Here is a picture for proof:
Here is the code:
def main():
answer = get_num()
guess = ask_user()
num_guesses = 0
while guess != answer:
check = guess_check(guess)
if check == 2:
print(f"Check is {check}. Your guess of {guess} is too high. Pick something lower. You're now on Guess {num_guesses}!\n")
guess = ask_user()
elif check == 1:
print(f"Check is {check}. Your guess of {guess} is too low. Pick something higher. You're now on Guess {num_guesses}! The correct answer is {answer}\n")
guess = ask_user()
print(f"Check is {check}. Congratulations! Your guess of {guess} is correct! \n\nNumber of Guesses: {num_guesses}")
# This function actually gives us the number to guess
def get_num():
# Randomly determines a number between 0 and 1000
import random
answer = random.randrange(1, 10)
return answer
def ask_user():
answer = int(input("Pick a number: "))
return answer
def guess_check(guess):
answer = get_num()
if guess > answer:
# Guess is too high, therefore value for guess_check() is 2
check = 2
elif guess < answer:
# Guess is too low, therefore value for guess_check() is 1
check = 1
else:
# Guess is right on, therefore value for guess_check() is 0
check = 0
return check
def num_guesses():
number = 1
guess = guess_check()
#If Statement for whether guess is too high (2) or too low (1). If it's 0, then the number of guesses will not increase.'
if guess == 1 or guess == 2:
number += 1
return number
main()
I've tried a few things to get around the problem:
I combined the ask_user() and guess_check() functions into 1 function. This did not make a difference.
Tried coding this exact same program without using functions. Ran just fine. The guess check part of the code ran without issues. So this tells me the functions are the reason this issue is happening.
Anyway, thanks so much for the help. You don't even know how much I appreciate this. I'm desperate.

pygame.event.get() is looping for some reason [duplicate]

This simple piece of code crashes (the window is not responding) after a few seconds (around 5).
import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 24)
#clock = pygame.time.Clock()
#font = pygame.font.Font(None, 32)
cycles = 0
while True:
screen.fill(0)
# text = font.render('Cycles : %d' % cycles, True, (255, 255, 255))
# screen.blit(text, (100, 100))
cycles += 1
pygame.display.update()
If I uncomment the commented lines, I can clearly see the program going out of control when displaying values between 47 and 50.
I use python 2.7 and pygame 1.9.2, Windows 8 (64 bits) and Eclipse + PyDev.
Call pygame.event.get() at the beginning of the while loop.
You need to regularly make a call to one of four functions in the pygame.event module in order for pygame to internally interact with your OS. Otherwise the OS will think your game has crashed. So make sure you call one of these:
pygame.event.get() returns a list of all events currently in the event queue.
pygame.event.poll() returns a single event from the event queue or pygame.NOEVENT if the queue is empty.
pygame.event.wait() returns a single event from the event queue or waits until an event can be returned.
pygame.event.pump() allows pygame to handle internal actions. Useful when you don't want to handle events from the event queue.
The window does not respond (freeze), because you do not handle the events. You have to handle the events by either pygame.event.pump() or pygame.event.get(), to keep the window responding.
See the documentation of pygame.event.pump():
For each frame of your game, you will need to make some sort of call to the event queue. This ensures your program can internally interact with the rest of the operating system.
Add an event loop, for instance:
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# [...]
Alternatively just pump the events:
while True:
pygame.event.pump()
# [...]
Minimal example: repl.it/#Rabbid76/PyGame-MinimalApplicationLoop

Caffe loss layer - backward function

I have a question about backward function in Caffe's loss layer.
I have seen implementation of a Euclidean loss layer at :
https://github.com/BVLC/caffe/blob/master/examples/pycaffe/layers/pyloss.py
At the end, the backward function is defined as follow :
def backward(self, top, propagate_down, bottom):
for i in range(2):
if not propagate_down[i]:
continue
if i == 0:
sign = 1
else:
sign = -1
bottom[i].diff[...] = sign * self.diff / bottom[i].num
I know that bottom[0] indicates the predicted value and bottom[1] is target values (ground truth).
Can you help me understand why sign is +1 for prediction and -1 for targets?
I thought that we didn't need to assign any values to bottom[1].diff for targets.
If I have multi-label problem, how can I update the code ?
When bottom[1] is ground truth you should expect propagate_down[1] to be False thus no gradient is propagated to the labels.
However, if you use this loss layer to compare two trainable blobs you would like to propagate gradients to both bottoms.
The sign is only due to the derivative of this particular loss, write the derivative and you'll see where it comes from.
The one thing I am missing here is top[0].diff. If I understand correctly it should hold the loss_weight defined for this layer...

Lecture collision boolean expression algorithm

I am trying to write a lecture collision algorithm for a schedule application. Each lecture has a start and end date.
currentListElement is the existing lecture in my current schedule, and I want to add chosenLecture, and check if there is a collision between my current lectures. Therefore, this boolean expression should return true if collision occurs.
Thank you for your help
(currentListElement['startDate'] < chosenLecture['startDate']
|| currentListElement['startDate'] >= chosenLecture['endDate'])
&& (currentListElement['endDate'] <= chosenLecture['startDate']
|| currentListElement['endDate'] > chosenLecture['endDate'])
Actually there is a little mistake, try this:
(currentListElement['endDate'] < chosenLecture['startDate']
|| currentListElement['startDate'] > chosenLecture['endDate'])
There is no collision in two cases:
The lecture is set entirely before the current one. To check that, just make sure it ends before the current starts.
The lecture is set entirely after the current one. To check that, just make sure it starts after the current ends.

How performant is collision detection in ActionScript 3?

I'm gonna be using hitTestObject() for quite a lot sprites each frame (e.g. 4 * 500). There will be many false and only a few or none true.
I thought I might check distances sprite1.x - sprite2.x and sprite1.y - sprite2.y first so that I let only near objects to be checked for collision. Then I wondered does ActionScript routines already check for distances first ? Flash is optimized in many ways so do I have to bother to increase performance for collision detection ?
// something like this ?
public static function near(sprite1: Sprite, sprite2: Sprite): Boolean
{
return (Math.abs(sprite1.x - sprite2.x) < 64) && (Math.abs(sprite1.y - sprite2.y) < 64);
}
if (near(sprite1, sprite2))
if (sprite1.hitTestObject(sprite2))
collide(sprite1, sprite2);
No, hitTestObject() is not optimized this way. So, if you can lower the amount of hitTestObject() calls, do it.
If you want performance on many objects you should try shape collisions instead. If you don't want to code it yourself, just take a look at Box2D or Nape. Both engines have been heavily optimised to do those kind of calculatons.