how to correctly move a sprite with the keys avoiding conflicts in pygame? - sprite

Is a simple game where a monkey throws bananas.
I want to launch the banana when the space bar is released and continue running.
When the space bar is held the banana must remain attached to the monkey until the space bar is released.
The first launch works properly, from the second onwards the bananas are not thrown correctly.
done=False
while not done:
for ev in pygame.event.get():
if ev.type == QUIT:
done = True
if ev.type ==KEYDOWN:
if ev.key== K_RIGHT:
move_right=True
if ev.key== K_LEFT:
move_left = True
if ev.key==K_SPACE:
space_down=True
still=True
elif ev.type ==KEYUP:
if ev.key== K_RIGHT:
move_right=False
if ev.key== K_LEFT:
move_left=False
if ev.key==K_SPACE:
still=False
space_down=False
launch=True
#Game logic
#move monkey
if move_right and monkey.rect.right<screen.get_width():
monkey.rect.x += 5
elif move_left and monkey.rect.left>0:
monkey.rect.x -= 5
#banana launch
if space_down:
banana=Throw_Objects()
banana.rect.midtop = monkey.rect.topright
space_down=False
if still and not space_down and move_right and monkey.rect.right < screen.get_width():
banana.rect.x += 5
if still and not space_down and move_left and monkey.rect.left > 0:
banana.rect.x -= 5
if launch:
for banana in all_object:
banana.rect.y -= 5
if banana.rect.top < 0:
banana.kill()
Any suggestions to make sure that the banana is launched when the space bar is released and when, as long as you press the space bar, the new banana will remain attached to the monkey without affecting the movement of the previous one?
Thank you

i resolded by adding a sprite group after launch in this way
if space_down:
banana=Throw_Objects()
banana.rect.midtop = monkey.rect.topright
space_down=False
if move_right and monkey.rect.right<screen.get_width():
monkey.rect.x += 5
if still:
banana.rect.x += 5
elif move_left and monkey.rect.left>0:
monkey.rect.x -= 5
if still:
banana.rect.x -= 5
if launch :
banana.rect.y -= 5
only_banana.add(banana)
launch=False
for banana in only_banana:
banana.rect.y -= 5
for banana in all_object:
if banana.rect.top < 0:
banana.kill()

Related

I'm trying to make a Tamagotchi and I'm having trouble updating it's current mood

hungry = 0
bored = 0
current_state = "Happy"
while True:
print("Tamagotchi current state is:", current_state)
action = input("")
if action == "feed":
hungry = hungry - 1
bored = bored + 1
elif action == "play":
hungry = hungry + 1
bored = bored - 1
elif action == "ignore":
hungry = hungry + 1
bored = bored + 1
if current_state == 'HAPPY':
if hungry >= 2:
current_state = "HUNGRY"
elif bored >= 2:
current_state = "BORED"
elif hungry >= 4:
current_state = "SAD"
if hungry < 0:
hungry = 0
if bored < 0:
bored = 0
if current_state == "HUNGRY":
if hungry >= 4:
current_state = "SAD"
elif bored > hungry:
current_state = "BORED"
elif hungry < 2:
current_state = "HAPPY"
if hungry < 0:
hungry = 0
if bored < 0:
bored = 0
if current_state == "BORED":
if bored >= 4:
current_state = "SAD"
elif hungry > bored:
current_state = "HUNGRY"
elif bored < 2:
current_state = "Happy"
if hungry < 0:
hungry = 0
if bored < 0:
bored = 0
When I run the program and type in a action it still says happy even if I type feed in twice or play. Was planning on it changing it's mood based on a action a user types in. I have restraints where bored and hungry can never go below zero and if they do they get set back to zero. Also if the Tamagotchi becomes sad it should exit the while statement and print it's dead.
might want to make your variables global. Pretty sure what's going on is when you call the (current_state) variable in your print statement, the actual variable never "updated" as intended, hence why it will always say it's happy. Hope that helps :)

'var' is not defined in 'for' loop

This is a code example from book:
width, height = 240, 60
midx, midy = width // 2, height // 2
for xen in range(width):
for уen in range(height):
if xen < 5 or xen >= width - 5 or уen < 5 or уen >= height - 5:
image[xen, yen] = border_color
elif midx - 20 < xen < midx + 20 and midy - 20 < уen < midy + 20:
image[xen, yen] = square_color
When I try to run this, I get error: 'yen' is not defined. But it was defined in 'for' loop, and so 'xen' was defined. I know that the book I am reading is kind of old, but I don't understand why am I getting this error and how to avoid this. I know there are loops, but this code seems fully legit to me. What's the trick?
When I copy and paste your code, the y in yen in your for loop is an odd character (maybe a Cyrillic 'U'). It looks like a y but it's not. Try retyping the line:
for уen in range(height):
These look the same, but if you run the snippet, you'll see they aren't:
console.log("уen" == "yen")

Python 3: How to exit loop without stopping function

I am a complete newbie and have tried solving this problem (with my own head and with online research) for the last 5 hours.
Below is a snippet of a function we have written to simulate a game. We want to offer the ooportunity to start a new round - meaning if a player hits "b", the game should start again at the beginning of the range (0, players). But right now it just goes onto the next player in the range (if player 1 enters "b", the program calls player 2)
players = input(4)
if players in range(3, 9):
for player in range(0, players):
sum_points = 0
throw_per_player_counter = 0
print("\nIt is player no.", player+1, "'s turn!\n")
print("\nPress 'return' to roll the dice.\n"
"To start a new round press 'b'.\n"
"Player", player+1)
roll_dice = input(">>> ")
if roll_dice == "b":
player = 0
throw_per_player_counter = 0
sum_points = 0
print("\n * A new round was started. * \n")
I have tried return and break, also tried to put it all in another while-loop... failed. Break and return just ended the function.
Any hints highly appreciated!
you could change the for loop to a while loop. instead of using a range, make player a counter
players = 4
if 3 <= players < 9:
player = 0 # here's where you make your counter
while player < players:
sum_points = 0
throw_per_player_counter = 0
print("\nIt is player no.", player+1, "'s turn!\n")
print("\nPress 'return' to roll the dice.\n"
"To start a new round press 'b'.\n"
"Player", player+1)
roll_dice = input(">>> ")
player += 1 # increment it
if roll_dice == "b":
player = 0 # now your reset should work
throw_per_player_counter = 0
sum_points = 0
print("\n * A new round was started. * \n")

Pygame pong ball

Here I give the speed and the direction to the ball
if collision_ball_pad_l == True:
print("ball hit the left pad")
ball_movement = -ball_movement
if first_collision == 0:
ball_movement_y = random.choice([1,-1])*speed
first_collision +=1
If ball hits the edge it must change the direction but it prints me that the speed is 0
if collision_ball_shield_u == True:
print("ball hit the left pad")
ball_movement_y -= ball_movement_y
print (ball_movement_y)
You have to change sign of variable - from + to - or from - to +
You can do it in one line - see - in code
ball_movement_y = -ball_movement_y

The concise 'how many beers' issue?

Where I'm at
I'm trying to figure out how many beers I can buy with 10 RMB after recycling every bottle I get. It's obvious to me that I'm doing something wrong, procedurally, but it's not occurring to me what that is. I'm currently reading "How To Think Like a Computer Scientist: Think Python" on chapter 9. I feel like this should be an easy program for me, but I'm not sure how to loop in the recycling portion of the app. What would be the most concise way to rinse and repeat beer purchases?
The question
Basically, one beer costs 2 RMB. 2 bins gets 1 RMB. 4 caps gets 1 RMB. I'm starting out with 10 RMB. How many beers can I buy (recycling all the bins and caps)?
#5 bottles 5 caps
#= 3 rmb + 1 caps 1 bottles
#6th bottle bought
#= 2rmb + 2 caps
#7th bottle bought
#= 0rmb + 3 caps 1 bottles.
import math
def countbeers(rmb):
beers = 0;
caps = 0;
bins = 0;
bcost = 2;
for i in range (0,rmb):
beers += 1/2
for i in range (0,math.floor(beers)):
caps += 1
bins += 1
rmb = rmb - bcost
for i in range (0,caps):
rmb += 1/4
for i in range (0,bins):
rmb += 1/2
# if rmb > 2 what goes here, trying to loop back through
return beers
print(countbeers(10))
Second attempt
#5 bottles 5 caps
#= 3 wallet + 1 caps 1 bottles
#6th bottle bought
#= 2wallet + 2 caps
#7th bottle bought
#= 0wallet + 3 caps 1 bottles.
import math
global beers
global caps
global bins
global bcost
beers = 0
caps = 0
bins = 0
bcost = 2
def buybeers(wallet):
beers = 0
for i in range (0,wallet):
beers += 1/2
wallet -= 2
return beers
def drinkbeers(beers):
for i in range (0,math.floor(beers)):
caps += 1
bins += 1
wallet = wallet - bcost
return wallet, caps, bins
def recycle(caps, bins):
for i in range (0,caps):
wallet += 1/4
for i in range (0,bins):
wallet += 1/2
return wallet
def maxbeers(wallet):
if wallet > 2:
buybeers(wallet)
if math.floor(beers) > 1:
drinkbeers(beers)
if caps > 4 | bins > 2:
recycle(caps, bins)
return wallet
wallet = int(input("How many wallet do you have?"))
maxbeers(wallet)
if wallet >= 2:
maxbeers(wallet)
elif wallet < 2:
print(beers)
Your main problem is that you are not looping. Every beer you bought from rmb gives you one more bottle, and one more cap. This new bottle and cap might be enough to earn you another rmb, which might be enough for another beer. Your implementation handles this to a limited extent, since you call maxbeers multiple times, but it will not give the correct answer if you give it a truckload of beers, i.e. 25656 bottles.
If you know the number of rmb you have, you can do the calculation by hand on paper and write this:
def maxbeers(rmb):
return 7 # totally correct, I promise. Checked this by hand.
but that's no fun. What if rmb is 25656?
Assuming we can exchange:
2 bottles -> 1 rmb
4 caps -> 1 rmb
2 rmb -> 1 beer + 1 cap + 1 bottle
we calculate it like this, through simulation:
def q(rmb):
beers = 0
caps = 0
bottles = 0
while rmb > 0:
# buy a beer with rmb
rmb -= 2
beers += 1
caps += 1
bottles += 1
# exchange all caps for rmb
while caps >= 4:
rmb += 1
caps -= 4
# exchange all bottles for rmb
while bottles >= 2:
rmb += 1
bottles -= 2
return beers
for a in range(20):
print("rmb:", a, "beers:", q(a))
Then we can buy 20525 beers.

Resources