user1064913
user1064913

Reputation: 323

Pygame Problems

I've been developing a simple game where a square moves around a screen. Recently I've tried using classes to organize everything but now the square doesn't move around the screen. I'm not sure where I went wrong. Here's my script:

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

class Player(pygame.sprite.Sprite):
    def __init__(self, xy):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((40, 40))
        self.rect = pygame.Rect(500, 300, 40, 40)
        self.rect.centerx, self.rect.centery = xy
        self.moveLeft = False
        self.moveRight = False
        self.moveUp = False
        self.moveDown = False
        self.movementspeed = 6

    def up(self):
        self.moveUp = True

    def down(self):
        self.moveDown = True

    def left(self):
        self.moveLeft = True

    def right(self):
        self.moveRight = True

    def move(self, dy, dx):
        if self.rect.bottom + dy > 700:
            self.rect.bottom = 700
        elif self.rect.top + dy < 0:
            self.rect.top = 0
        elif self.rect.left + dx > 0:
            self.rect.left = 0
        elif self.rect.right + dx < 1000:
            self.rect.right = 1000

    def update(self):
        self.move(self.movementspeed, self.movementspeed)

class Game(object):
    def __init__(self):
        pygame.init()
        self.window = pygame.display.set_mode((1000, 700))
        self.clock = pygame.time.Clock()
        pygame.display.set_caption("Avoid!")
        pygame.event.set_allowed([QUIT, KEYDOWN, KEYUP])
        self.background = pygame.Surface((800, 400))
        self.background.fill((255, 255, 255))
        self.window.blit(self.background, (0, 0))
        self.sprites = pygame.sprite.RenderUpdates()
        self.player = Player((500, 300))
        self.sprites.add(self.player)

    def run(self):
        running = True
        while running:
            self.clock.tick(60)
            running = self.handleEvents()
            for sprite in self.sprites:
                sprite.update()
            self.sprites.clear(self.window, self.background)
            dirty = self.sprites.draw(self.window)
            pygame.display.update(dirty)

    def handleEvents(self):
        for event in pygame.event.get():
            if event.type == QUIT:
                return False
            elif event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    return False
                if event.key == K_UP:
                    self.player.up
                if event.key == K_DOWN:
                    self.player.down
                if event.key == K_LEFT:
                    self.player.left
                if event.key == K_RIGHT:
                    self.player.right
            elif event.type == KEYUP:
                if event.key == K_UP:
                    self.player.up
                if event.key == K_DOWN:
                    self.player.down
                if event.key == K_LEFT:
                    self.player.left
                if event.key == K_RIGHT:
                    self.player.right

        return True

if __name__ == "__main__":
    game = Game()
    game.run()

And here's my original script:

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

pygame.init()
mainClock = pygame.time.Clock()

WINDOWWIDTH = 1000
WINDOWHEIGHT = 700
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption("Avoid!")

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

player = pygame.Rect(500, 300, 40, 40)
playerImage = pygame.Surface((40, 40))

enemy = pygame.Rect(300, 400, 20, 20)
enemyImage = pygame.Surface((20, 20))
enemyImage.fill((RED))

food = pygame.Rect(300, 500 , 20, 20)
foodImage = pygame.Surface((20, 20))
foodImage.fill((GREEN))

class Score(pygame.sprite.Sprite):
    """A sprite for the score."""

    def __init__(self, xy):
        pygame.sprite.Sprite.__init__(self)
        self.xy = xy    # save xy -- will center our rect on it when we change the score
        self.font = pygame.font.Font(None, 50)  # load the default font, size 50
        self.color = (BLACK)         # our font color in rgb
        self.score = 0  # start at zero
        self.reRender() # generate the image

    def update(self):
        pass

    def add(self, points):
        """Adds the given number of points to the score."""
        self.score += points
        self.reRender()

    def reset(self):
        """Resets the scores to zero."""
        self.score = 0
        self.reRender()

    def reRender(self):
        """Updates the score. Renders a new image and re-centers at the initial coordinates."""
        self.image = self.font.render("%d"%(self.score), True, self.color)
        self.rect = self.image.get_rect()
        self.rect.center = self.xy



my_score = Score((75, 575))

font = pygame.font.Font(None, 36)
text = font.render("%d" % (my_score.score), 1, (10, 10, 10))
textpos = text.get_rect(centerx=windowSurface.get_width()/2)

moveLeft = False
moveRight = False
moveUp = False
moveDown = False

MOVESPEED = 6

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        if event.type == KEYDOWN:
            if event.key == K_LEFT:
                moveRight = False
                moveLeft = True
            if event.key == K_RIGHT:
                moveLeft = False
                moveRight = True
            if event.key == K_UP:
                moveDown = False
                moveUp = True
            if event.key == K_DOWN:
                moveUp = False
                moveDown = True
        if event.type == KEYUP:
            if event.key == K_ESCAPE:
                pygame.quit()
                sys.exit()
            if event.key == K_LEFT:
                moveRight = False
                moveLeft = True
            if event.key == K_RIGHT:
                moveLeft = False
                moveRight = True
            if event.key == K_UP:
                moveDown = False
                moveUp = True
            if event.key == K_DOWN:
                moveUp = False
                moveDown = True

    windowSurface.fill(WHITE)

    if moveDown and player.bottom < WINDOWHEIGHT:
        player.top += MOVESPEED
    if moveUp and player.top > 0:
        player.top -= MOVESPEED
    if moveLeft and player.left > 0:
        player.left -= MOVESPEED
    if moveRight and player.right < WINDOWWIDTH:
        player.right +=MOVESPEED

    if player.colliderect(enemy):
        my_score.reset

    if not player.colliderect(food):
        windowSurface.blit(text, textpos)
    else:
        my_score.add(5)
        windowSurface.blit(text, textpos)


    windowSurface.blit(playerImage, player)
    windowSurface.blit(enemyImage, enemy)
    windowSurface.blit(foodImage, food)

    pygame.display.update()
    mainClock.tick(40)

What worked before doesn't seem to be working anymore. Can anyone tell me why this is?

Upvotes: 0

Views: 758

Answers (1)

osa1
osa1

Reputation: 7078

You didn't just change your first script's structure. There are lots of other changes too. Some points:

  • Where did you set your Player sprite's color? Or where did you fill your sprite's surface? I can't see any sprites in your updated version, I think it's because your background color and sprite color is the same.
  • I think your move method is wrong. You are not moving your sprite, you are just setting it's position to some points.
  • In your game loop, you are not calling your Player's down or up methods, you forgot your () after method names.
  • You're not setting initial positions to your Player rect's.
  • You're never setting Player.moveDown, Player.modeUp, etc. false. This means once player starts moving up, it never stops(and you will have an another problem when player moves up, and then down).

Solving one or more of this things should solve your problem.

Upvotes: 1

Related Questions