# Learning about multiple arguments in a function

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.

``````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

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.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]

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 = []

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.

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.

``````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]