gh1234
gh1234

Reputation: 1

Loop function in pygame does not make characters in game move

I am working on a dodger like game. I have so far created one enemy and a player. I turned my loop into a function, but when I run the program the characters do not move. The characters did move before I turned the loop into a function.

#this where I am initializing and defining my variables
import pygame
import sys
from pygame.locals import *
pygame.init()
display_height=500
display_width=1000
red=(255,0,0)
white=(255,255,255)
black=(0,0,0)
blue=(0,0,255)
green=(0,255,0)
v=500+100

    
FPS=30
dropper_y=30
dropper_x=500
hero_y=400
baddie_thickness=40
v_change=0

def dropper(amount, baddie_list):
    for x in baddie_list:
        dodger_x=500
        dodger_y=30
    
    
    

 
fps=pygame.time.Clock()
set_Display=pygame.display.set_mode((display_width,display_height))
set_Display.fill(black)
hero=pygame.image.load('hero.png')
dropper=pygame.image.load('droppers1.png')
movement='null'
move_left='ahadun'
pixRate=8
#this is the enemy class
class baddie:
    def __init__(self):
        self.x=dropper_x
        self.y=dropper_y
        self.image=pygame.draw.rect(set_Display,green,(self.x,self.y,baddie_thickness,baddie_thickness))
    def render(self):
        self.rend=pygame.draw.rect(set_Display,green,(self.x,self.y,baddie_thickness,baddie_thickness))
#this is the player class
class goodie:
    def __init__(self):
        self.x=v
        self.y=hero_y
        self.image=pygame.draw.rect(set_Display,blue,(self.x,self.y,40,40))
    def render(self):
        self.rend=pygame.draw.rect(set_Display,blue,(self.x,self.y,40,40))
#these are text functions but have not been put to use
def text_objects(text, font):
    textSurface = font.render(text, True, white)
    return  textSurface, textSurface.get_rect()
def message_display(text):
    largeText=pygame.font.Font('freesansansbold.ttf',100)
    TextSurf,TextRect = text_objects(text,largeText)
    TextRect.center= ((display_width/2,display_height/2))
    set_Display.blit(TexttSurf, TextRect)
    time.sleep(2)
    pygame.display.update()
 #this is a quit function   
def end():
    pygame.quit()
    sys.exit()
    
    
 #this the loop function   
def gameloop():
  while True:
      good=goodie()
      good.render()
      bad=baddie()
      bad.render()
      dropper_y=30
      fps=pygame.time.Clock()
      movement='null'
      move_left='ahadun'
      pixRate=8
      
      FPS=30
      dropper_y=30
      dropper_x=500
      hero_y=400
      baddie_thickness=40
      v_change=0

      #This is where the movement of the enemy is done
      if movement=='null':
          dropper_y+=pixRate
              
      if dropper_y>500:
          dropper_y=30
          pixRate+=0.5
      set_Display.fill(black)
      bad.render()
      good.render()
      for event in pygame.event.get():
         set_Display.fill(black)
         good.render()
         bad.render()
         if event.type == pygame.QUIT:
                  pygame.quit()
                  sys.exit()
         #This is where the player moves from key events
         keys = pygame.key.get_pressed()
         if event.type == pygame.KEYDOWN:
              if event.key == pygame.K_LEFT:
                  v_change-=15
              elif event.key == pygame.K_RIGHT:
                  v_change+=15
              
         if event.type == pygame.KEYUP:
              if event.key == pygame.K_RIGHT:
                 v_change+=0
              elif event.key == pygame.K_LEFT:
                  v_change-=0
         if movement=='null':
              dropper_y+=1
         if dropper_y>500:
              dropper_y=30
         #This is collision detection but does not work properly
         if v>=dropper_x and v <= dropper_x+baddie_thickness:
              if hero_y>=dropper_y and hero_y <= dropper_y+baddie_thickness:
                  print 'oh no'
                  end()
                  #end()
         baddie_list=[]
         baddie_list.append(dropper_x)
         print (good.x)
      good.x+=v_change
      pygame.display.update()
      fps.tick(FPS)
        
          
        
    
                       
           
       
#I tried calling my enemy and player class here but it did not work
good=goodie()
bad=baddie()
good.render
good.x+=v_change
bad.render
gameloop()
pygame.quit()
quit()
    

Upvotes: 0

Views: 322

Answers (1)

furas
furas

Reputation: 142711

You have mess in code.

Everytime in while True you set dropper_y = 30 (even twice) , hero_y = 40, etc. so objects can't move.


EDIT:

by the way: pygame.draw.rect puts rectangle on the screen. You can't assign this rectangle to variable - it has no sense. Better use self.rect = pygame.Rect(x, y, width, height) to keep rectangle size and position and use it in pygame.draw.rect(display, self.color, self.rect)


EDIT:

mainloop in function is usefull if all your game use classes.

My version with arranged code but without functions. I couldn't understand some lines in your code.

There is PEP8 document with some suggestion about function/class/variable names, empty lines for readability, spaces after comma and after/before = == += < > etc.

# --- imports ---

import pygame
import sys

# --- constants - uppercase ---

HEIGHT = 500
WIDTH  = 1000

RED   = (255,  0,  0)
WHITE = (255,255,255)
BLACK = (  0,  0,  0)
BLUE  = (  0,  0,255)
GREEN = (  0,255,  0)

FPS = 30

BADDIE_THICKNESS = 40

DROPPER_Y = 30
DROPPER_X = 500
HERO_Y = 400

# --- classes - CamelCase ----

class Baddie:
    '''enemy class''' # docstring
                      # empty line for readability
    def __init__(self, display, x=DROPPER_X, y=DROPPER_Y, color=GREEN):
        self.display = display
        self.rect = pygame.Rect(x, y, BADDIE_THICKNESS, BADDIE_THICKNESS)
        self.color = color
        #self.change = [0, 0]
                      # empty line for readability
    def render(self):
        pygame.draw.rect(self.display, self.color, self.rect)

    def update(self):
        self.rect.y += 1
        if self.rect.y > 500:
            self.rect.y = 30
                      # two empty lines for readability        

class Goodie:
    '''player class'''

    def __init__(self, display, x=0, y=HERO_Y, color=BLUE):
        self.display = display
        self.rect = pygame.Rect(x, y, 40, 40)
        self.color = color
        self.change = 0

    def render(self):
        pygame.draw.rect(self.display, self.color, self.rect)

    def update(self):
        self.rect.x += self.change

        # stay on screen
        if self.rect.left < 0:
            self.rect.left = 0
        elif self.rect.right > WIDTH:
            self.rect.right = WIDTH

# --- functions - lowercase with _ ---

def create_center_text(display, font, text):

    text = font.render(text, True, WHITE)

    rect = text.get_rect()
    rect.center = display.get_rect().center

    #rect = text.get_rect(center=display.get_rect().center)

    return text, rect

# ---------------------------------------------------------------------
# --- main ---
# ---------------------------------------------------------------------

# --- init ---

pygame.init()

display = pygame.display.set_mode((WIDTH,HEIGHT))

# created only once
good = Goodie(display)

# create only once
bads = []

for x in range(1, 11):
   bads.append(Baddie(display, x*90, x*30))

# created only once
font_large = pygame.font.Font(None, 100)

# created only once
game_over_text, game_over_rect = create_center_text(display, font_large, "GAME OVER")

# --- mainloop ---

# created only once
fps = pygame.time.Clock()

game_over = False
running = True

while running:

    # --- events ---

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False # exit `gameloop`

        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                running = False # exit `gameloop`

            elif event.key == pygame.K_LEFT:
                good.change = -15
            elif event.key == pygame.K_RIGHT:
                good.change = +15

        elif event.type == pygame.KEYUP:
            if event.key in (pygame.K_LEFT, pygame.K_RIGHT):
                good.change = 0 # a += 0 is useless because it is a=a+0

    # --- updates ---

    if not game_over:

        # move good
        good.update()

        # move bads
        for bad in bads:
            bad.update()

        # check colision
        for bad in bads:
            if good.rect.colliderect(bad.rect):
                print 'oh no'
                game_over = True # exit `gameloop`

    # --- draws ---

    display.fill(BLACK)

    for bad in bads:
        bad.render()

    good.render()

    if game_over:
        display.blit(game_over_text, game_over_rect)

    pygame.display.update()

    # --- FPS ---

    fps.tick(FPS)

# --- end ---

pygame.quit()
sys.exit()

EDIT: using class

# --- imports ---

import pygame
import sys

# --- constants - uppercase ---

HEIGHT = 500
WIDTH  = 1000

RED   = (255,  0,  0)
WHITE = (255,255,255)
BLACK = (  0,  0,  0)
BLUE  = (  0,  0,255)
GREEN = (  0,255,  0)

FPS = 30

BADDIE_THICKNESS = 40

DROPPER_Y = 30
DROPPER_X = 500
HERO_Y = 400

# --- classes - CamelCase ----

class Baddie:
    '''enemy class''' # docstring
                      # empty line for readability
    def __init__(self, display, x=DROPPER_X, y=DROPPER_Y, color=GREEN):
        self.display = display
        self.rect = pygame.Rect(x, y, BADDIE_THICKNESS, BADDIE_THICKNESS)
        self.color = color
        #self.change = [0, 0]
                      # empty line for readability
    def render(self):
        pygame.draw.rect(self.display, self.color, self.rect)

    def update(self):
        self.rect.y += 1
        if self.rect.y > 500:
            self.rect.y = 30


class Goodie:
    '''player class'''

    def __init__(self, display, x=0, y=HERO_Y, color=BLUE):
        self.display = display
        self.rect = pygame.Rect(x, y, 40, 40)
        self.color = color
        self.change = 0

    def render(self):
        pygame.draw.rect(self.display, self.color, self.rect)

    def update(self):
        self.rect.x += self.change

        # stay on screen
        if self.rect.left < 0:
            self.rect.left = 0
        elif self.rect.right > WIDTH:
            self.rect.right = WIDTH

# --- functions - lowercase with _ ---

# ---------------------------------------------------------------------
# --- main ---
# ---------------------------------------------------------------------

class Game:

    def __init__(self):
        '''--- init ---'''

        pygame.init()

        self.display = pygame.display.set_mode((WIDTH,HEIGHT))

        # create only once
        self.good = Goodie(self.display)

        self.bads = []

        for x in range(1, 11):
           self.bads.append(Baddie(self.display, x*90, x*30))

        self.font_large = pygame.font.Font(None, 100)

        self.game_over_text, self.game_over_rect = self.create_center_text(self.font_large, "GAME OVER")

    def create_center_text(self, font, text):

        text = font.render(text, True, WHITE)

        rect = text.get_rect()
        rect.center = self.display.get_rect().center

        #rect = text.get_rect(center=display.get_rect().center)

        return text, rect


    def run(self):
        '''--- mainloop ---'''

        fps = pygame.time.Clock()

        game_over = False
        running = True

        while running:

            # --- events ---

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False # exit `gameloop`

                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        running = False # exit `gameloop`

                    elif event.key == pygame.K_LEFT:
                        self.good.change = -15
                    elif event.key == pygame.K_RIGHT:
                        self.good.change = +15

                elif event.type == pygame.KEYUP:
                    if event.key in (pygame.K_LEFT, pygame.K_RIGHT):
                        self.good.change = 0 # a += 0 is useless because it is a=a+0

            # --- updates ---

            if not game_over:

                # move good
                self.good.update()

                # move bads
                for bad in self.bads:
                    bad.update()

                # check colision
                for bad in self.bads:
                    if self.good.rect.colliderect(bad.rect):
                        print 'oh no'
                        game_over = True # exit `gameloop`

            # --- draws ---

            self.display.fill(BLACK)

            for bad in self.bads:
                bad.render()

            self.good.render()

            if game_over:
                self.display.blit(self.game_over_text, self.game_over_rect)

            pygame.display.update()

            # --- FPS ---

            fps.tick(FPS)

        # --- end ---

        pygame.quit()
        sys.exit()

#----

Game().run()

Upvotes: 2

Related Questions