Here's the problem --> enemyship_sprites.add(Enemy((cols*60)+20, (rows*40)+30), level)<br>
1,2
1
2
1 0<br>
you've put a braket after +30 which ends the Enemy call. The numbering
is +1 for opening braket -1 for closing so 0 is the end of the Enemy
call if you understand this.<br><br><div><span class="gmail_quote">On 6/30/05, <b class="gmail_sendername">D. Hartley</b> <<a href="mailto:denise.hartley@gmail.com">denise.hartley@gmail.com</a>> wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hey guys!<br><br>I have a 'quest,' and at first glance this email looks long, but the<br>problem is probably not as complex as the length implies. Please bear<br>with me, if I could get some advice on this particular problem, it
<br>would go along way toward helping me be a better Python programmer.<br><br>Some of you might remember, a few months ago, I was working on a space<br>invaders game for a birthday present. One of the functions I really
<br>wanted to add to the game was to change the enemy "ships" at each new<br>level. Because of my deadline and my newness to Python, I did this in<br>an extremely ugly way. To give you an idea:<br><br>the original main loop called:
<br> enemyship_sprites = createEnemies(screen, enemy_speed)<br><br>createEnemies looks like this:<br><br>def createEnemies(screen, speed):<br> enemyship_sprites = EnemySprites(speed)<br> for rows in xrange(5):<br> for cols in xrange(8):
<br> enemyship_sprites.add(Enemy((cols*60)+20, (rows*40)+30), level)<br> enemyship_sprites.draw(screen)<br> return enemyship_sprites<br><br>It creates an instance of EnemySprites (my holder class) which<br>contains code for when the ships hit bottom, when to update them, etc.
<br> It also calls "Enemy()", which looks like this:<br><br>class Enemy(pygame.sprite.Sprite):<br> def __init__(self, startx, starty):<br> pygame.sprite.Sprite.__init__(self)<br> if level == 1:<br>
self.image, self.rect = load_image('salad_ship.bmp', -1)<br> self.rect.centerx = startx<br> self.rect.centery = starty<br> def update(self, direction, go_down):<br> jump = 40 # how much the enemies move to the right/left on
<br>each jump<br> if go_down:<br> # if a ship is moving down on this round,<br> # it doesn't move on the x-axys<br> self.rect.move_ip((0, 5))<br> else:<br> # move a ship in the x-axys.
<br> # if direction=1, it moves to the right; -1 to the left<br> self.rect.move_ip((jump * direction, 0))<br> # maybe it's time for a shot? :)<br> # the chances are 1/30<br> dice = random.randint
(0,30)<br> global enemy_shot_sprites<br> if dice == 1:<br> shot = EnemyShot(self.rect.midtop)<br> enemy_shot_sprites.add(shot)<br><br><br>Now, get ready for one of the uglier things you've probably seen lately (!!):
<br><br>Since I can only access the variable "level" from within the main<br>loop, for some reason I thought I couldnt use it in my class<br>definitions (which of course come before and are outside of the<br>mainloop). So within the main loop, I did:
<br><br> if level == 1:<br>
enemyship_sprites = createEnemies1(screen, enemy_speed)<br> elif level == 2:<br>
enemyship_sprites = createEnemies2(screen, enemy_speed)<br> elif level == 3:<br>
enemyship_sprites = createEnemies3(screen, enemy_speed)<br> elif level == 4:<br>
enemyship_sprites = createEnemies4(screen, enemy_speed)<br> elif level == 5:<br>
enemyship_sprites = createEnemies5(screen, enemy_speed)<br> elif level == 6:<br>
enemyship_sprites = createEnemies6(screen, enemy_speed)<br> elif level == 7:<br>
enemyship_sprites = createEnemies7(screen, enemy_speed)<br> elif level == 8:<br>
enemyship_sprites = createEnemies8(screen, enemy_speed)<br> else:<br>
enemyship_sprites = createEnemies9(screen, enemy_speed)<br><br>And yes, I created 9 different createEnemies, all pretty much carbon<br>copies of each other except that they called Enemy1, Enemy2, Enemy3,<br>etc. And then (you guessed it), I created 9 different Enemy
<br>functions, too, so that each one could have its own (different)<br>bitmap.<br><br>Now... this is just ridiculous.<br><br>To my credit, I did actually know that at the time. But the day before<br>the birthday, I figured if I could make it work somehow, I would, and
<br>I'd make it prettier later. Now just happens to be that later ;)<br><br>So now that I've got a little more Python experience under my belt<br>(not much, but a little), it occurred to me that when I call<br>createEnemies in the mainloop, I could pass in an argument 'level'.
<br><br>mainloop now starting off with:<br> enemyship_sprites = createEnemies(screen, enemy_speed, level)<br><br>level is one of my main loop variables, so it'll know what i'm talking<br>about and can take that variable and pass it in when it calls
<br>createEnemies. (Btw, please forgive me if I mix up terms like argument<br>and variable or use them in the wrong places, I'm still getting used<br>to them!) In any case, then I changed my createEnemies to look like<br>
this:<br><br>def createEnemies(screen, speed, level):<br> enemyship_sprites = EnemySprites(speed)<br> for rows in xrange(5):<br> for cols in xrange(8):<br> enemyship_sprites.add(Enemy((cols*60)+20, (rows*40)+30), level)
<br> enemyship_sprites.draw(screen)<br> return enemyship_sprites<br><br>Since the part that changes each level actually matters when the Enemy<br>function gets called (because that's where the bmps are loaded), I<br>made Enemy need 'level':
<br><br>class Enemy(pygame.sprite.Sprite):<br> def __init__(self, startx, starty, level):<br> pygame.sprite.Sprite.__init__(self)<br> if level == 1:<br> self.image, self.rect = load_image('salad_ship.bmp', -1)
<br> elif level == 2:<br> (.................etc)<br> self.rect.centerx = startx<br> self.rect.centery = starty<br>(...............etc)<br><br><br>Now I know this email is getting hard to read ;)
<br><br>At this point I was thinking I'd have one createEnemies, called in the<br>mainloop, which would take the level and, when it called Enemy to<br>create the ships, use that level argument to determine which bmp to<br>
use for the ship itself. One createEnemies(), one Enemy(), there you<br>go.<br><br>But now it's giving me an error when createEnemies is called, for the<br>enemyship_sprites.add(Enemy((cols*60)+20, (rows*40)+30), level) line,
<br>saying __init__() (and this would be Enemy's init, correct?) takes<br>exactly 4 arguments (3 given): and Enemy's init, as you can see,<br>takes (self, startx, starty, level). But the first argument is just<br>'self'! I don't have to pass that in.... I never *did*, anyway, in
<br>all my Enemy1, Enemy2, Enemy3 code...?<br><br>I can send the full code for anybody who thinks that would be<br>clearer to look at (ha ha) - I was going to attach it here but it<br>would make the message too big for the list. I know that going
<br>through such a messy<br>problem like this is a pain, and questions like this don't always get<br>a lot of responses on the list. My code worked, it was just messy,<br>and so I suppose I could just leave it alone. But I want to clean it
<br>up: I want to make it more Pythonic, more organized, more efficient,<br>and would really love any advice anyone could offer.<br><br>Heck, for all I know, I could just be needing to add a "self.___"<br>somewhere, heaven knows that has tripped me up before!
<br><br>Would love to hear from you guys, and thanks again,<br>Denise<br>_______________________________________________<br>Tutor maillist - <a href="mailto:Tutor@python.org">Tutor@python.org</a><br><a href="http://mail.python.org/mailman/listinfo/tutor">
http://mail.python.org/mailman/listinfo/tutor</a><br></blockquote></div><br>