Reputation: 153
Quick summary of what I am creating: It is a game in which an alien spaceship bounces around the screen (like the dell logo/loading screen) with a certain boundary so that it stays near the top of the screen. Near the bottom of the screen there is a player ship that has to click to shoot the enemy space invaders style, while moving side to side (but at the moment I'm still working on keyboard/mouse working simultaneously because events only do the top of the queue). There are also cows being beamed up from beneath you by the mothership. If you catch the cow you get points. If you fail to dodge one, you lose points and a life. If you catch one with a "net" you get points.
The issue I am having is this error (cowRect = (cow_x[i], cow_y[i], 127, 76)
IndexError: list index out of range
), which I think would be caused by theprogram attempting to iterate through the lists while they are still empty, although it seems like items are in the list when it is "scanning" through it.
Some snippets of my code (It's like 170 lines so I won't post it all):
Beginning-
cowList = []
statusList = []
cow_x = []
cow_y = []
Inside main loop-
if hits >= hitsNeeded and time.time() >= currentTime + 1:
cowList.append(cownumber)
cownumber += 1
statusList.append(3)
cow_x.append(random.randint(0, 573))
cow_y.append(700)
Also inside main loop-
for i in statusList:
cowRect = (cow_x[i], cow_y[i], 127, 76)
if cow_y[i] + 111 < 0:
statusList[i] = 0 #offscreen
if cowRect.colliderect(missileRect):
statusList[i] = 1 #exploded
points -= 15
netRect = (net_x, net_y, 127, 127)
if cowRect.colliderect(netRect):
points += 90
screen.blit(milkplus, (cow_x[i], cow_y[i]))
powerup = pygame.mixer.Sound("C:/Python35/powerup.mp3")
powerup.play()
shotNet = 0
statusList[i] = 2 #caught
if cowRect.colliderect(playerRect):
points -= 10
lives -= 1
statusList[i] = 4 #player collision
for i in statusList:
if statusList[i] == 3: #alive
screen.blit(cow, (cow_x[i], cow_y[i]))
cow_y[i] -= cowSpeed
Yes, I do realize that I don't really need to have 4 states of cow, it just helps to keep my head organized (that goes for some other things in here too).
I apologize if I have made some mistake, I haven't been on here in a very long time.
Upvotes: 0
Views: 78
Reputation: 19770
The problem you are seeing is due to the way that for
loops work in Python. They iterate through the contents of the list, not the list indexes. As mentioned in the comments, you could fix the error by simply doing for i in range(len(statusList))
, but I want to suggest that you rather use a slightly different strategy to encode the information about the cows, by having a list of cows rather than four lists about the cows.
class Cow:
def __init__(x, y):
self.status = 'alive'
self.x = x
self.y = y
Beginning-
cows = []
Inside main loop-
if hits >= hitsNeeded and time.time() >= currentTime + 1:
cows.append(Cow(random.randint(0, 573), 700))
Also inside main loop-
for cow in cows:
cowRect = (cow.x, cow.y, 127, 76)
if cow.y + 111 < 0:
cow.status = 'offscreen'
if cowRect.colliderect(missileRect):
cow.status = 'exploded'
points -= 15
netRect = (net_x, net_y, 127, 127)
if cowRect.colliderect(netRect):
points += 90
screen.blit(milkplus, (cow.x, cow.y))
powerup = pygame.mixer.Sound("C:/Python35/powerup.mp3")
powerup.play()
shotNet = 0
cow.status = 'caught' #caught
if cowRect.colliderect(playerRect):
points -= 10
lives -= 1
cow.status = 'collision'
for cow in cows:
if cow.status == 'alive':
screen.blit(cow_pic, (cow.x, cow.y))
cow.y -= cowSpeed
This will make things easier in the future. If you are uncomfortable with classes, you can get similar behaviour with collections.namedtuple
.
Upvotes: 2