python - How do I make a projectile in pygame that will move upward? -


i wrote game meant shoot blue square screen when spacebar pressed. however, blue square right above shooter. here code:

import pygame, sys, random gameobjects import *   def main():      pygame.init()      screen = pygame.display.set_mode((800, 800))      numberofcolumns = 5     columnwidth = screen.get_width() / numberofcolumns      numberofrows = 5     rowwidth = screen.get_width() / numberofrows      magazineimage = pygame.image.load("images/magazine.bmp")     magazineissueoneimage = pygame.image.load("images/magazine #1.bmp")      monsterstate1 = pygame.image.load("images/zombie pos 1.bmp")     monsterstate2 = pygame.image.load("images/zombie pos 2.bmp")     monsterstate3 = pygame.image.load("images/zombie pos 3.bmp")     monsters = []      forrystate1 = pygame.image.load("images/forry pos 1.bmp")         forrystate2 = pygame.image.load("images/forry pos 2.bmp")     forrydelaytime = 8      gameobjects = []     gameobjectblittingcounter = 0      monsterspawnspotlist = [(rowwidth * -5), (rowwidth * -4), (rowwidth * -3), (rowwidth * -2), (rowwidth * -1)]      monster in range(0, 5):         monster = monster(monsterstate1, monsterstate2, monsterstate3, ((columnwidth / 2 - monsterstate1.get_width() / 2) + gameobjectblittingcounter * columnwidth), random.choice(monsterspawnspotlist))         monsters.append(monster)         gameobjects.append(monster)         gameobjectblittingcounter += 1      forry = forry(forrystate1, forrystate2, columnwidth, rowwidth, screen, forrydelaytime, magazineimage, magazineissueoneimage)     gameobjects.append(forry)       while true:           screen.fill((0,255,0))          event in pygame.event.get():             if event.type == pygame.quit:                 sys.exit()          #update projectiles          if forry.projectilecall == true:             magazine = magazine(magazineimage, forry)             gameobjects.append(magazine)          #update game objects          gameobject in gameobjects:             gameobject.update()           #render         gameobjectblittingcounter = 0          gameobject in gameobjects:             screen.blit(gameobjects[gameobjectblittingcounter].image, ((gameobjects[gameobjectblittingcounter].rect.x), (gameobjects[gameobjectblittingcounter].rect.y)))             gameobjectblittingcounter += 1           pygame.display.flip()     if __name__ == "__main__":     main() 

the file gameobjects.py looks this:

import pygame   class monster(pygame.sprite.sprite):     def __init__(self, monsterstate1, monsterstate2, monsterstate3, xcoord, ycoord):         self.monsterstate1 = monsterstate1         self.monsterstate2 = monsterstate2         self.monsterstate3 = monsterstate3         self.image = self.monsterstate1         self.rect = self.image.get_rect()         self.rect.y = ycoord         self.rect.x = xcoord       def update(self):         self.movedown()      def movedown(self):         self.rect.y += 1      def onspawn(self):         return      def ondeath(self):         return      def reset(self):         return    class forry(pygame.sprite.sprite):     def __init__(self, forrystate1, forrystate2, columnwidth, rowwidth, screen, delaytime, magazineimage, magazineissueoneimage):         self.forrystate1 = forrystate1         self.forrystate2 = forrystate2         self.image = self.forrystate1         self.columnwidth = columnwidth         self.rowwidth = rowwidth         self.rect = self.image.get_rect()         self.rect.y = self.columnwidth / 2 - self.image.get_width() / 2         self.rect.y = screen.get_height() - (self.rowwidth / 2 - self.image.get_height() / 2)         self.delaytime = delaytime         self.delay = 0         self.magazineimage = magazineimage         self.magazineissueoneimage = magazineissueoneimage         self.projectilecall = false         self.rightbound = screen.get_width() - (self.columnwidth / 2 + self.image.get_width() / 2)         self.leftbound = (self.columnwidth / 2 - self.image.get_width() / 2)       def update(self):         #check player input         playerinput = self.checkplayerinput()          #update position         if self.delay > 0:             self.delay -= 1         elif self.delay < 0:             self.delay = 0         else:             self.updateposition(playerinput)          #keep on screen         self.keeponscreen()      def checkplayerinput(self):         left = pygame.key.get_pressed() [pygame.k_left]         right = pygame.key.get_pressed() [pygame.k_right]         shoot = pygame.key.get_pressed() [pygame.k_space]         return (left, right, shoot)      def updateposition(self, playerinput):         left = playerinput[0]         right = playerinput[1]         shoot = playerinput[2]         if self.projectilecall == true:             self.projectilecall = false             self.image = self.forrystate1         if shoot:             self.image = self.forrystate2             self.projectilecall = true             self.delay = self.delaytime         if left:             self.rect.x -= self.columnwidth             self.delay = self.delaytime         if right:             self.rect.x += self.columnwidth             self.delay = self.delaytime      def keeponscreen(self):         if self.rect.x >= self.rightbound:             self.rect.x = self.rightbound         elif self.rect.x <= self.leftbound:             self.rect.x = self.leftbound       def onspawn(self):         return      def ondeath(self):         return      def reset(self):         return   class magazine(pygame.sprite.sprite):     def __init__(self, image, shooter):         self.image = image         self.rect = image.get_rect()         self.rect.x = shooter.rect.x         self.rect.y = shooter.rect.y - shooter.image.get_height()          def update(self):             self.rect.y -= 5             if self.rect.y <= 0 - self.image.get_height():                 self.kill() 

my magazine blue square

so why doesn't projectile go screen?

++++++++

with fixes in answer below, have error:

when blue box goes off screen, supposed killed because of self.kill() in update function of magazine class.

however, instead of being killed, minute 1 of them gets off screen, gives me these errors:

traceback (most recent call last):   file "main.py", line 106, in <module>     main()   file "main.py", line 78, in main     projectileobject.update()   file "/users/number1son100/desktop/famous monsters game/gameobjects.py", line 117, in update     self.kill()   file "/library/frameworks/python.framework/versions/2.7/lib/python2.7/site-packages/pygame/sprite.py", line 174, in kill     c in self.__g.keys(): attributeerror: 'magazine' object has no attribute '_sprite__g' 

answer

stumped me while, classic case of "right under our noses":

look @ indentation of "update" function under magazine, indented 1 far right, means function defined -inside- __init__() instead of method of magazine wanted. if didnt make sense you, "dedent" block looks

class magazine(pygame.sprite.sprite):     def __init__(self, image, shooter):         self.image = image         self.rect = image.get_rect()         self.rect.x = shooter.rect.x         self.rect.y = shooter.rect.y - shooter.image.get_height()      def update(self):         self.rect.y -= 5         if self.rect.y <= 0 - self.image.get_height():             self.kill() 

some explaination why nothing happened no error: update function not method of magazine, did not overwrite 1 inherited pygame.sprite.sprite. result when called main loop, placehold/basic method called, not custom one. meant didnt error/exception didnt work!

moving on, there few major things issue here correction:

addendum

1)

not neccessarily issue, can use python "for x in y" syntax here:

    gameobject in gameobjects:         gameobject.update() 

later on in render section, i.e.:

    #render     gameobjectblittingcounter = 0      gameobject in gameobjects:         screen.blit(gameobjects[gameobjectblittingcounter].image, ((gameobjects[gameobjectblittingcounter].rect.x), (gameobjects[gameobjectblittingcounter].rect.y)))         gameobjectblittingcounter += 1 

becomes:

    gameobject in gameobjects:         screen.blit(gameobject.image, gameobject.rect) 

note can pass whole rect instead of splitting rect.x , rect.y

2)

you notice once fix update function, current code spawns multiple shots when press spacebar, because spawn mechanic looks if spacebar held , spawns projectile every loop, try removing spawning loop , once when space pressed or released

3)

cap framerate

in testing framerate spike high , make game run oddly. cap framerate using pygame.clock object , calling clock.tick(framerate) in loop

4)

in preparation further complexity, consider splitting "gameobjects" lists several different types (enemyobjects, projectileobjects, etc), because these may need different treatment @ point, or saves looping entire list effects enemies if occurs.


finally small plug of website, have source , docs pygame libraries can use , may in future.


Comments

Popular posts from this blog

php - Submit Form Data without Reloading page -

linux - Rails running on virtual machine in Windows -

php - $params->set Array between square bracket -