0

I am new to python and am building a little 2d shoot out game. I have a function "attack()" that takes 3 arguments.

I'm trying to pass in a string variable argument, and two integer variables, and return all three to the main program for further use.

This is the code for the function and it's implementation code inside the main loop.

fire_state = "ready"
def attack(w,x,y):
    w ='fire'
    screen.blit(attackimg, (x+25,y+30))
    return w,x,y

 if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                 if fire_state == "ready":
                 print(fire_state)
                    attackX = playerX
                    attack(w=fire_state,x=attackX,y=attackY)

If I hard code the string variable as a global variable inside the function it works, but severely limits the functions usability.

fire_state2 = "ready"
def attack2(x,y):
    global fire_state2 
    fire_state2 ='fire'
    screen.blit(attackimg, (x+25,y+30))

if event.key == pygame.K_w:
                if fire_state2 == "ready":
                    attack2X = player2X
                    attack2(attack2X, attack2Y)

If someone could explain why the fire_state variable isn't updateing unless it's defined as global inside the function, but the integer variables work just fine when passed in as arguments.

Mwatson
  • 1
  • 1
  • Are you expecting `w = 'fire'` to update `fire_state`? – Carcigenicate Jan 10 '21 at 16:56
  • See [here](https://stackoverflow.com/questions/986006/how-do-i-pass-a-variable-by-reference) for why this doesn't work. The simplest solution though would just be to use the `w`: that you're already returning: `fire_state, _, _ = attack(w=fire_state,x=attackX,y=attackY)` – Carcigenicate Jan 10 '21 at 16:58
  • Ok that works! So if I got it right, short answer is, the string is technically a list and needs to be reassigned to fire_state (aka the target variable). Because the function has multiple arguments, you use an underscore _ to skip over the output you don't want to assign. – Mwatson Jan 10 '21 at 18:40
  • I wouldn't say the "string is technically a list". `return w,x,y` returns a tuple containing three elements (it's the same thing as `return (w,x,y)`). The second half of your comment is right though. `_` is just to ignore the second and third elements in the tuple. You could also do `fire_state, *_ = attack(w=fire_state,x=attackX,y=attackY)` to ignore all after the first (`*` is given every element that wasn't bound). – Carcigenicate Jan 10 '21 at 19:44
  • "Because the function has multiple arguments," It's because it has multiple return values, not because it takes multiple arguments. `def func(): return 1, 2, 3` works in the same way, but doesn't take any arguments. – Carcigenicate Jan 10 '21 at 19:45
  • There doesn't seem to be any point in passing `w` into the function though since you never use the `w` passed in, and there also doesn't seem to be any point in returning `x` and `y` since you never change them in the function, so they're the same as they were when they were passed in. I'd write your code as [just this](https://gist.github.com/carcigenicate/df5bb4e139ac55231a9622aea629a496). – Carcigenicate Jan 10 '21 at 19:50
  • Ok that makes sense. Thank you for just explaining and not being uppity about it, and for the shorter syntax tips. I was thinking it was returning ```x , y ``` because the position on the screen was being updated but I get it now having looked at yours, and have a better understanding of how functions fundamentally work. Thanks again – Mwatson Jan 15 '21 at 14:59

0 Answers0