0

Hi I am trying to program the arcade game asteroids, and have made it so when the user presses spacebar, a circle is created where the 'ship' is currently located and its position added to 'ball_list' while the ship's horizontal and vertical velocities are stored as the new circle's velocities in 'ball_vlist', as shown

def draw(canvas):
    global ship_pos, ship_vel, ball_list

    if current_key=='32':             # if spacebar is pressed
        ball_list.append(ship_pos)    # create a new circle and store is position
        ball_vlist.append(ship_vel)   # add a velocity to this new circle

When I run the whole program, the ship moves at the speed I initially gave it, as I would expect. However, when I press spacebar it speeds up, and I have no idea why. I've found out that this line is causing the problem:

ball_list.append(ship_pos)

because when i comment it out the ship continues normally when spacebar is pressed. Is append somehow changing the ship's position? I've checked that the ship's velocity (ship_vel) remains constant even when the ship accelerates..

Thank you for any help! If you need additional context, here is the whole program:

import simplegui

ball_list = []
ball_vlist = []
ship_pos = [200, 400]
ship_vel = [.5, -.5]
current_key=' '

frame = simplegui.create_frame("Asteroids", 800, 500)

def tick():
    global ball_list, ball_vlist, ship_pos

    # update the ship position

    ship_pos[0] += ship_vel[0]
    ship_pos[1] += ship_vel[1]


    # update the ball positions

    for i in range(len(ball_list)):
        ball_list[i][0]+=ball_vlist[i][0]
        ball_list[i][1]+=ball_vlist[i][1]       

def draw(canvas):
    global ship_pos, ship_vel, ball_list

    if current_key=='32':
        ball_list.append(ship_pos)
        ball_vlist.append(ship_vel)

    for ball_pos in ball_list:
        canvas.draw_circle(ball_pos, 1, 1, "white", "white")    # these are the circles the ship shoots

    canvas.draw_circle(ship_pos, 4, 1, "red", "green")    # this is my 'ship' (just to test)

def keydown(key):
    global current_key
    current_key = str(key)

def keyup(key):
    global current_key
    current_key=' '

timer = simplegui.create_timer(10, tick)
frame.set_keydown_handler(keydown)
frame.set_keyup_handler(keyup)
frame.set_draw_handler(draw)

frame.start()
timer.start()

2 Answers 2

2

Try this:

ball_list.append(ship_pos[:])
ball_vlist.append(ship_vel[:])

When you append ship_pos (and ship_vel), you are actually appending the same list. ball_list[0] will now refer to the same list as ship_pos. This means that if you change one (e.g. ball_list[0][0] = 5), then the other will be changed as well (ship_pos[0] == 5).

You can fix this by duplicating the lists using [:], so that you are now appending a new copy of the list.

I don't think any of that actually made sense, so here's some code that might help:

>>> a = []
>>> b = [1,2]
>>> a.append(b)
>>> a
[[1, 2]]
>>> a[0][0] = 3
>>> a
[[3, 2]]
>>> b
[3, 2]

>>> a=[]
>>> b=[1,2]
>>> a.append(b[:])
>>> a
[[1, 2]]
>>> a[0][0] = 3
>>> a
[[3, 2]]
>>> b
[1, 2]
Sign up to request clarification or add additional context in comments.

Comments

0

The issue is with appending a list to an array, the list remains as a reference.

Example:

>>> i = [1, 2, 3]
>>> x = []
>>> x.append(i)
>>> x[0][1] = 5
>>> i
[1, 5, 3]
>>> 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.