# Learning about multiple arguments in a function

**URL:** <https://discuss.python.org/t/learning-about-multiple-arguments-in-a-function/7500>\
**Category:** Python Help\
**Created:** [March 3, 2021, 11:17pm UTC](https://discuss.python.org/t/learning-about-multiple-arguments-in-a-function/7500 "2021-03-03T23:17:33Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![jcsmithga](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jcsmithga](https://discuss.python.org/u/jcsmithga)\
**Post date:** [March 3, 2021, 11:17pm UTC](https://discuss.python.org/t/learning-about-multiple-arguments-in-a-function/7500/1 "2021-03-03T23:17:33Z")

</div>

Hey all,

Fresh n00b here. I’ve been playing around with some tutorials on how to make a 2D game, and I’m trying to dive a little bit deeper into the physics of character movement. First, I reckon I’l post what I have, then ask my question.

```auto
import pygame
from pygame.locals import *

pygame.init()

clock = pygame.time.Clock()
fps = 60
player_speed = 3
walk_acc = 0
run_acc = 0

screen_width = 700
screen_height = 700

screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('Platformer')

#define game variables
tile_size = 35

#load images
sun_img = pygame.image.load('img/sun.png')
bg_img = pygame.image.load('img/sky.png')
class Player():
    def __init__ (self, x, y):
        self.images_right = []
        self.images_left = []
        self.index = 0
        self.counter = 0
        for num in range(1, 5):
            img_right = pygame.image.load(f'img/guy{num}.png')
            img_right = pygame.transform.scale(img_right, (28, 56))
            img_left = pygame.transform.flip(img_right, True, False)
            self.images_right.append(img_right)
            self.images_left.append(img_left)
        self.image = self.images_right[self.index]    
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.vel_y = 0
        self.jumped = False
        self.direction = 1
        
    def update(self, walk_acc, run_acc):
        dx = 0
        dy = 0
        walk_cooldown = 4

    
        #get keypresses
        key = pygame.key.get_pressed()       
        if self.rect.bottom < screen_height - tile_size:
            self.jumped = True
        if key[pygame.K_SPACE] and self.jumped == False:
            self.vel_y = -15
            self.jumped = True 
        if key[pygame.K_SPACE] == False:
            self.jumped = False    
        if key[pygame.K_LEFT] and self.direction == 1:
            walk_cooldown = 0
        if key[pygame.K_RIGHT] and self.direction == -1:   
            walk_cooldown = 0         
        if key[pygame.K_LEFT]:
            walk_acc += 1
            if walk_acc > 3:
                walk_acc = 3
            if key[pygame.K_LSHIFT] and key[pygame.K_LEFT]:
                run_acc += 1
                if run_acc > 7:
                    run_acc = 7      
            dx -= player_speed + walk_acc + run_acc
            self.counter +=1
            self.direction = -1
        if key[pygame.K_RIGHT]:
            walk_acc += 1
            if walk_acc > 3:
                walk_acc = 3
            if key[pygame.K_LSHIFT] and key[pygame.K_RIGHT]:
                run_acc += 1
                if run_acc > 7:
                    run_acc = 7       
            dx += player_speed + walk_acc + run_acc
            self.counter += 1
            self.direction = 1
        if key[pygame.K_LSHIFT] == False and key[pygame.K_RIGHT] == False and key[pygame.K_LEFT] == False:
                walk_acc -= 1
                run_acc -= 1
                if walk_acc < 0:
                    walk_acc = 0
                if run_acc < 0:
                    run_acc = 0             
        if key[pygame.K_LEFT] == False and key[pygame.K_RIGHT] == False:
            self.counter = 0
            self.index = 0
            if self.direction == 1:    
                self.image = self.images_right[self.index]
            if self.direction == -1:    
                self.image = self.images_left[self.index]
        if key[pygame.K_LEFT] == True and key[pygame.K_RIGHT] == True:
            self.counter = 0
            self.index = 0
            if self.direction == 1:    
                self.image = self.images_right[self.index]
            if self.direction == -1:    
                self.image = self.images_left[self.index]                

        #handle animations
        if self.counter > walk_cooldown:
            self.counter = 0
            self.index += 1
            if self.index >= len(self.images_right):
                self.index = 0
            if self.direction == 1:    
                self.image = self.images_right[self.index]
            if self.direction == -1:    
                self.image = self.images_left[self.index]    

        #add gravity
        self.vel_y += 1
        if self.vel_y > 10:
            self.vel_y = 10
        dy += self.vel_y

        #check for collision

        #update player coordinates
        self.rect.x += dx
        self.rect.y += dy

        if self.rect.bottom > screen_height - tile_size:
            self.rect.bottom = screen_height - tile_size
            dy = 0
            

        #draw player onto screen
        screen.blit(self.image, self.rect) 
        print(walk_acc)
        print(run_acc)
        return walk_acc
        return run_acc   

class World():
    def __init__ (self, data):
        self.tile_list = []

        #load images
        dirt_img = pygame.image.load('img/dirt.png')
        grass_img = pygame.image.load('img/grass.png')

        row_count = 0
        for row in data:
            col_count = 0
            for tile in row:
                if tile == 1:
                    img = pygame.transform.scale(dirt_img, (tile_size, tile_size))
                    img_rect = img.get_rect()
                    img_rect.x = col_count * tile_size
                    img_rect.y = row_count * tile_size
                    tile = (img, img_rect)
                    self.tile_list.append(tile)
                if tile == 2:
                    img = pygame.transform.scale(grass_img, (tile_size, tile_size))
                    img_rect = img.get_rect()
                    img_rect.x = col_count * tile_size
                    img_rect.y = row_count * tile_size
                    tile = (img, img_rect)
                    self.tile_list.append(tile)    
                col_count += 1
            row_count += 1  

    def draw(self):
        for tile in self.tile_list:
            screen.blit(tile[0], tile[1])
                          

world_data =[
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
]

player = Player(70, screen_height - 91)
world = World(world_data)

run = True
while run:
    clock.tick(fps)
    screen.blit(bg_img, (0, 0))
    screen.blit(sun_img, (100, 75))

    world.draw()
    
    walk_acc = player.update(walk_acc, run_acc)
    run_acc = player.update(walk_acc, run_acc)
    
    for event in pygame.event.get():
        key = pygame.key.get_pressed() 
        if event.type == pygame.QUIT:
            run = False
    pygame.display.update()        

pygame.quit()

```

Hopefully that formatted correctly. So my question is this:

Initially I had the update function only take two arguments, self and acc (acceleration). In my game loop, I had acc = player.update(acc) and with a few tweaks, everything worked fine. I would press LSHIFT and acc would increment, and decrement when it was not held. Now that there are 3 args for update, I’m not quite sure of the syntax of the stuff that I have in the main game loop.

I know this code probably looks really ugly, but, it’s a start. Any pointers? Basically I’m trying to increment walk\_acc and run\_acc using the update function.

---

<div class="post-metadata">

**Author:** ![cameron](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/cameron/32/2658_2.png) [@cameron](https://discuss.python.org/u/cameron)\
**Post date:** [March 4, 2021, 7:28am UTC](https://discuss.python.org/t/learning-about-multiple-arguments-in-a-function/7500/2 "2021-03-04T07:28:25Z")

</div>

> Fresh n00b here. I’ve been playing around with some tutorials on how to  
> make a 2D game, and I’m trying to dive a little bit deeper into the  
> physics of character movement. First, I reckon I’l post what I have,  
> then ask my question.
> 
> ```auto
> Hopefully that formatted correctly. So my question is this:
> 
> ```

BTW, Apparently “```py” gets nice syntax highlighting (there are 3  
backticks there, in case this gets mangled). But the formatting looked  
fine to me (reading the post via email).

> Initially I had the update function only take two arguments, self and  
> acc (acceleration). In my game loop, I had acc = player.update(acc) and  
> with a few tweaks, everything worked fine. I would press LSHIFT and acc  
> would increment, and decrement when it was not held. Now that there are  
> 3 args for update, I’m not quite sure of the syntax of the stuff that I  
> have in the main game loop.

Looks fine to me. With a class method defined as:

```
class Player:
    def method(self, blah,blah,...):

```

when you call it with an instance:

```
player.method(1,2,3)

```

it implicitly takes “player” and supplied it as “self” in the method. So  
if you defined the method with 3 arguments (self,walk\_acc,run\_acc) then  
you call it with 2 arguments:

```
player.update(walk_acc,run_acc)

```

Also, note that Python, if you get the number of arguments wrong, python  
will complain that “update” expects 3 arguments but got (whatever).  
because the method itself has 3 parameters. You call it with 2 (one  
fewer).

> I know this code probably looks really ugly, but, it’s a start. Any  
> pointers? Basically I’m trying to increment walk\_acc and run\_acc using  
> the update function.

Does it work? Looks ok to me.

That said, I’ll insert a few random comments in the code below. But it  
basicly looks good to me.

> class Player():

You don’t need the brackets if there are no superclasses.

> def update(self, walk\_acc, run\_acc):  
> dx = 0  
> dy = 0  
> walk\_cooldown = 4
> 
> ```
> #get keypresses
> key = pygame.key.get_pressed()
> if self.rect.bottom < screen_height - tile_size:
> self.jumped = True
> if key[pygame.K_SPACE] and self.jumped == False:
> self.vel_y = -15
> self.jumped = True
> if key[pygame.K_SPACE] == False:
> self.jumped = False
> if key[pygame.K_LEFT] and self.direction == 1:
> 
> ```

Purely style, but I would write this as:

```
if self.direction == 1 and key[pygame.K_LEFT]:

```

in that I’d be thinking “here is code for direction=1”: if K\_LEFT: do  
this.

> ```
> walk_cooldown = 0
> if key[pygame.K_RIGHT] and self.direction == -1:
> walk_cooldown = 0
> if key[pygame.K_LEFT]:
> walk_acc += 1
> if walk_acc > 3:
> walk_acc = 3
> 
> ```

You can shorten this to:

```
walk_acc = min(walk_acc + 1, 3)

```

There’s a bultin max() as well.

> ```
> if key[pygame.K_LSHIFT] and key[pygame.K_LEFT]:
> 
> ```

You don’t need and “key[pygame.K\_LEFT]” here - you’re inside that test  
already, so it must be true.

> ```
> if key[pygame.K_LSHIFT] == False and key[pygame.K_RIGHT] == 
> False and key[pygame.K_LEFT] == False:
> 
> ```

We don’t test “key[pygame.K\_LSHIFT==False” in Python, rather “not  
key[pygame.K\_LSHIFT]”. So if not this and not that and not the\_other.

> ```
> walk_acc -= 1
> run_acc -= 1
> if walk_acc < 0:
> walk_acc = 0
> if run_acc < 0:
> run_acc = 0
> if key[pygame.K_LEFT] == False and key[pygame.K_RIGHT] == False:
> self.counter = 0
> self.index = 0
> if self.direction == 1:
> self.image = self.images_right[self.index]
> if self.direction == -1:
> self.image = self.images_left[self.index]
> if key[pygame.K_LEFT] == True and key[pygame.K_RIGHT] == True:
> 
> ```

Again, “if key[pygame.K\_LEFT] and key[pygame.K\_RIGHT]”.

> ```
> self.counter = 0
> self.index = 0
> if self.direction == 1:
> self.image = self.images_right[self.index]
> if self.direction == -1:
> self.image = self.images_left[self.index]
> 
> #handle animations
> if self.counter > walk_cooldown:
> self.counter = 0
> self.index += 1
> if self.index >= len(self.images_right):
> self.index = 0
> if self.direction == 1:
> self.image = self.images_right[self.index]
> if self.direction == -1:
> self.image = self.images_left[self.index]
> 
> #add gravity
> self.vel_y += 1
> if self.vel_y > 10:
> self.vel_y = 10
> 
> ```

You can use min() again here.

Otherwise it all looks quite good.

Cheers,  
Cameron Simpson [cs@cskk.id.au](mailto:cs@cskk.id.au)
