Question

I am trying to make my sprite go to the bottom check to see if it is on a bottom and if it is on the bottom go to the top and check to see if it is on the top then go down and do that in a endless loop. This is the code that i am trying but it does not work, it goes to the bottom and stops.:

if baddieRect.bottom > WINDOWHEIGHT:
    baddieRect.move_ip(0, -5)
if baddieRect.bottom < WINDOWHEIGHT:
    baddieRect.move_ip(0, 5)

My whole code:

import pygame, random, sys
from pygame.locals import *

WINDOWWIDTH = 600
WINDOWHEIGHT = 600
TEXTCOLOR = (255, 255, 255)
BGC = (0, 0, 0)
FPS = 80
PLAYERMOVERATE = 5
countBy = 1

def terminate():
    pygame.quit()
    sys.exit()


def waitForPlayerToPressKey():
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                terminate()
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    terminate()
                return

def playerHasHitShoot(playerRect, shootRect):
    if playerRect.colliderect(shootRect):
        return True
    return False

def baddieHasHitShoot(baddieRect, shootRect):
    if baddieRect.colliderect(shootRect):
        return True
    return False

def drawText(text, font, surface, x, y):
    textobj = font.render(text, 1, TEXTCOLOR)
    textrect = textobj.get_rect()
    textrect.topleft = (x, y)
    surface.blit(textobj, textrect)

def fire(shoot):
    shootRect.topleft = ((playerRect / 2), 101)
    shootRect.move_ip(5, 1)

pygame.init()
pygame.font.init()
font = pygame.font.SysFont(None,48)
mainClock = pygame.time.Clock()
screen = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.set_caption('Mothers Day')
pygame.mouse.set_visible(True)
pygame.display.set_icon(pygame.image.load('gameicon.gif'))
icon = pygame.image.load('icon.bmp').convert_alpha()        
pygame.display.set_icon(icon)
gameStartSound = pygame.mixer.Sound('gamestart.wav')
gameOverSound = pygame.mixer.Sound('gamestart.wav')
pygame.mixer.music.load('background.wav')

playerImage = pygame.image.load('starship.bmp')
playerRect = playerImage.get_rect()
baddieImage = pygame.image.load('enemy.bmp')
baddieRect = baddieImage.get_rect()
shootImage = pygame.image.load('shoot.bmp')
shootRect = shootImage.get_rect()

def main():
    UPDOWN # if true go up, else go down
    while True:
        #update the position
        if UPDOWN: 
            baddieRect.move_ip(0, -5) 
        elif not UPDOWN: 
            baddieRect.move_ip(0, 5)

        # where your code is not quite right
        if baddieRect.bottom > WINDOWHEIGHT: #correct
            UPDOWN = True
        #yours baddieRect.bottom < WINDOWHEIGHT
        #mine elif baddieRect.top < 0
        elif baddieRect.top < 0: # tests if the 'baddie' hits the top
            UPDOWN = False

drawText('Star Trek', font, screen, (WINDOWWIDTH / 2.5), (WINDOWHEIGHT / 3))
drawText('Press a key to start.', font, screen, (WINDOWWIDTH / 3.75) - 30, (WINDOWHEIGHT / 3) + 50)
pygame.display.update()
waitForPlayerToPressKey()


topScore = 0
while True:

    score = 10000
    playerRect.topleft = (0, 100)
    baddieRect.topright = (600, 100)
    moveUp = moveDown = False
    pygame.mixer.music.play(-1, 0.0)


    while True:
        score -= countBy

        for event in pygame.event.get():
            if event.type == QUIT:
                terminate()

            if event.type == KEYDOWN:
                if event.key == K_UP:
                    moveDown = False
                    moveUp = True
                if event.key == ord(' '):
                    fire
                if event.key == K_DOWN:
                    moveUp = False
                    moveDown = True

            if event.type == KEYUP:
                if event.key == ord(' '):
                    fire
                if event.key == K_ESCAPE:
                        terminate()
                if event.key == K_UP or event.key == ord('w'):
                    moveUp = False
                if event.key == K_DOWN or event.key == ord('s'):
                    moveDown = False


        if moveUp and playerRect.top > 0:
            playerRect.move_ip(0, -1 * PLAYERMOVERATE)
        if moveDown and playerRect.bottom < WINDOWHEIGHT:
            playerRect.move_ip(0, PLAYERMOVERATE)



        sb = pygame.image.load('sb.png')
        screen.blit(sb, (600, 600))
        screen.fill(BGC)

        main()


        drawText('Score: %s' % (score), font, screen, 10, 0)
        drawText('Top Score: %s' % (topScore), font, screen, 10, 40)

        screen.blit(playerImage, playerRect)
        screen.blit(shootImage, shootRect)
        screen.blit(baddieImage, baddieRect)
        pygame.display.update()


        if playerHasHitShoot(playerRect, shootRect):
            score = 0 
            break

        if baddieHasHitShoot(baddieRect, shootRect):
            if score > topScore:
                score = topscore
                break
        mainClock.tick(FPS)




    pygame.mixer.music.stop()
    gameOverSound.play()
    drawText('GAME OVER', font, screen, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3))
    drawText('Press a key to play again.', font, screen, (WINDOWWIDTH / 3) - 80, (WINDOWHEIGHT / 3) + 50)
    pygame.display.update()
    waitForPlayerToPressKey()
    gameOverSound.stop()
Was it helpful?

Solution

Yeah OK. So the reasoning for this is that you test if it's greater than the bottom, and then you say if it's the bottom to go back up 5. They offset each other, and if you change it to an if else statement you will get this really annoying jittering motion.

In order to fix this you should define a variable called something along the lines of UPDOWN (if Boolean) or DIRECTION (if integer based).

So I'm going to use the Boolean, now you haven't shown much of your code, which is both good and bad, good because you narrowed it down to the exact problem, but bad because I'm not sure exactly where to put it in your code, so I'm going to make my own loop to sort of show how you would use it.

def main():
    UPDOWN = False # if true go up, else go down
    while True:
        #update the position
        if UPDOWN: 
            baddieRect.move_ip(0, -5) 
        elif not UPDOWN: 
            baddieRect.move_ip(0, 5)

        # where your code is not quite right
        if baddieRect.bottom > WINDOWHEIGHT: #correct
            UPDOWN = True
        #yours baddieRect.bottom < WINDOWHEIGHT
        #mine elif baddieRect.top < 0
        elif baddieRect.top < 0: # tests if the 'baddie' hits the top
            UPDOWN = False

Now why does this work, it tests if your sprite hits the bottom, and if it does it goes, but if it hits the top it goes down. I hope you can see how you went a bit wrong in your if statement. nothing too big, just a minor mistake that I can see how you missed.

Cheers!


------------------EDIT---------------------

So you responded saying that you don't know where to put main The truth of the matter is that main is just a place holder. I just wanted to get the point across that it was in your mainloop. Well I found your main loop and put it in accordingly I have put comments on my edits

import pygame, random, sys
from pygame.locals import *

WINDOWWIDTH = 600
WINDOWHEIGHT = 600
TEXTCOLOR = (255, 255, 255)
BGC = (0, 0, 0)
FPS = 80
PLAYERMOVERATE = 5
countBy = 1

def terminate():
    pygame.quit()
    sys.exit()


def waitForPlayerToPressKey():
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                terminate()
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    terminate()
                return

def playerHasHitShoot(playerRect, shootRect):
    if playerRect.colliderect(shootRect):
        return True
    return False

def baddieHasHitShoot(baddieRect, shootRect):
    if baddieRect.colliderect(shootRect):
        return True
    return False

def drawText(text, font, surface, x, y):
    textobj = font.render(text, 1, TEXTCOLOR)
    textrect = textobj.get_rect()
    textrect.topleft = (x, y)
    surface.blit(textobj, textrect)

def fire(shoot):
    shootRect.topleft = ((playerRect / 2), 101)
    shootRect.move_ip(5, 1)

pygame.init()
pygame.font.init()
font = pygame.font.SysFont(None,48)
mainClock = pygame.time.Clock()
screen = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.set_caption('Mothers Day')
pygame.mouse.set_visible(True)
pygame.display.set_icon(pygame.image.load('gameicon.gif'))
icon = pygame.image.load('icon.bmp').convert_alpha()        
pygame.display.set_icon(icon)
gameStartSound = pygame.mixer.Sound('gamestart.wav')
gameOverSound = pygame.mixer.Sound('gamestart.wav')
pygame.mixer.music.load('background.wav')

playerImage = pygame.image.load('starship.bmp')
playerRect = playerImage.get_rect()
baddieImage = pygame.image.load('enemy.bmp')
baddieRect = baddieImage.get_rect()
shootImage = pygame.image.load('shoot.bmp')
shootRect = shootImage.get_rect()

drawText('Star Trek', font, screen, (WINDOWWIDTH / 2.5), (WINDOWHEIGHT / 3))
drawText('Press a key to start.', font, screen, (WINDOWWIDTH / 3.75) - 30, (WINDOWHEIGHT / 3) + 50)
pygame.display.update()
waitForPlayerToPressKey()


topScore = 0
while True:

    score = 10000
    playerRect.topleft = (0, 100)
    baddieRect.topright = (600, 100)
    moveUp = moveDown = False
    pygame.mixer.music.play(-1, 0.0)

    UPDOWN = False# if true go up, else go down DEFINE UPDOWN
    while True:
        #I ADDED IN THE BELOW lines. They were just not positioned correctly in your code
        #update the position
        print ("got here #1")
        if UPDOWN: 
            baddieRect.move_ip(0, -5) 
        elif not UPDOWN: 
            baddieRect.move_ip(0, 5)
        print ("got here #2")
        # where your code is not quite right
        if baddieRect.bottom > WINDOWHEIGHT: #correct
            UPDOWN = True
        #yours baddieRect.bottom < WINDOWHEIGHT
        #mine elif baddieRect.top < 0
        elif baddieRect.top < 0: # tests if the 'baddie' hits the top
            UPDOWN = False

        score -= countBy

        for event in pygame.event.get():
            if event.type == QUIT:
                terminate()

            if event.type == KEYDOWN:
                if event.key == K_UP:
                    moveDown = False
                    moveUp = True
                if event.key == ord(' '):
                    fire
                if event.key == K_DOWN:
                    moveUp = False
                    moveDown = True

            if event.type == KEYUP:
                if event.key == ord(' '):
                    fire
                if event.key == K_ESCAPE:
                        terminate()
                if event.key == K_UP or event.key == ord('w'):
                    moveUp = False
                if event.key == K_DOWN or event.key == ord('s'):
                    moveDown = False

        if moveUp and playerRect.top > 0:
            playerRect.move_ip(0, -1 * PLAYERMOVERATE)
        if moveDown and playerRect.bottom < WINDOWHEIGHT:
            playerRect.move_ip(0, PLAYERMOVERATE)



        sb = pygame.image.load('sb.png')
        screen.blit(sb, (600, 600))
        screen.fill(BGC)

        #got rid of the next line which is why I commented it out. as main is no longer a function
        #main()


        drawText('Score: %s' % (score), font, screen, 10, 0)
        drawText('Top Score: %s' % (topScore), font, screen, 10, 40)

        screen.blit(playerImage, playerRect)
        screen.blit(shootImage, shootRect)
        screen.blit(baddieImage, baddieRect)
        pygame.display.update()


        if playerHasHitShoot(playerRect, shootRect):
            score = 0 
            break

        if baddieHasHitShoot(baddieRect, shootRect):
            if score > topScore:
                score = topscore
                break
        mainClock.tick(FPS)




    pygame.mixer.music.stop()
    gameOverSound.play()
    drawText('GAME OVER', font, screen, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3))
    drawText('Press a key to play again.', font, screen, (WINDOWWIDTH / 3) - 80, (WINDOWHEIGHT / 3) + 50)
    pygame.display.update()
    waitForPlayerToPressKey()
    gameOverSound.stop()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top