1
votes

I'm making a rhythm game. When a "beat" (arrow) hits a certain coordinate, it disappears. If the corresponding key is being pressed, the game adds to the player's score.

But when I run my code, it doesn't add to the score.

Here's my code:

import pygame
import time
import itertools

pygame.init()
SCREENWIDTH = 1000
SCREENHEIGHT = 650
screen = pygame.display.set_mode([SCREENWIDTH, SCREENHEIGHT])
screen.fill((255, 123, 67))
pygame.draw.rect(screen, (0, 255, 188), (0, 50, 1000, 650), 0)
myfont = pygame.font.SysFont('Ink Free', 30)

background = screen.copy()
clock = pygame.time.Clock()
stageon = True

sprites = pygame.sprite.Group()
class Player(pygame.sprite.Sprite):
    sprite = pygame.image.load("Sprites/lee.png")

    def __init__(self, *groups):
        super().__init__(*groups)
        self.image = Player.sprite
        self.rect = self.image.get_rect(topleft=(445, 550))
        self.pos = pygame.Vector2(self.rect.topleft)
        self.score = 0
    def update(self):
        key = pygame.key.get_pressed()
        dist = 3
        if key[pygame.K_DOWN]:
            self.rect.y += dist
        elif key[pygame.K_UP]:
            self.rect.y -= dist
        if key[pygame.K_RIGHT]:
            self.rect.x += dist
        elif key[pygame.K_LEFT]:
            self.rect.x -= dist

player = Player(sprites)

beatgroup = pygame.sprite.Group()
class Beat(pygame.sprite.Sprite):
    def __init__(self, ticks, image):
        super().__init__(beatgroup)
        self.image = image
        self.rect = self.image.get_rect()
        self.pos = pygame.Vector2(730, 100)
        self.path = itertools.cycle(((730, 100), (850, 100),))
        self.next_point = pygame.Vector2(next(self.path))
        self.speed = 2
        self.ticks = 200

    def update(self):
        move = self.next_point - self.pos
        move_length = move.length()
        if move_length != 0:
            move.normalize_ip()
            move = move * self.speed
            self.pos += move
        key = pygame.key.get_pressed()
        if self.pos == (850, 100):
            self.kill()

        #here's the problem area   
        if self.pos == (850, 100) and  key[pygame.K_DOWN] and self.image == pygame.image.load("Sprites/down.png"):
            player.score += 10
        elif self.pos == (850, 100) and key[pygame.K_UP] and self.image == pygame.image.load("Sprites/up.png"):
            player.score += 10
        elif self.pos == (850, 100) and key[pygame.K_LEFT] and self.image == pygame.image.load("Sprites/left.png"):
            player.score += 10
        elif self.pos == (850, 100) and key[pygame.K_RIGHT] and self.image == pygame.image.load("Sprites/right.png"):
            player.score += 10

        if move.length() == 0 or move_length < self.speed:
            self.next_point = pygame.Vector2(next(self.path))

        self.rect.topleft = self.pos



class Beat_gen(pygame.sprite.Sprite):
    def __init__(self, order):
        super().__init__(beatgroup)
        self.image = pygame.image.load("Sprites/beat_cropped.png")
        self.rect = self.image.get_rect(topleft=(730, 100))
        self.start_time = pygame.time.get_ticks()
        print(self.start_time)
        self.order = []
        self.picorder = []
        for i in order:
            self.order.append(i[0])
            self.picorder.append(i[1])
        self.currentbeat = 0
        self.LastBeat = 0
    def update(self):
        if self.currentbeat == len(self.order):
                stageon = False
        else:
            time_gone = pygame.time.get_ticks() - self.start_time
            if time_gone >= self.order[self.currentbeat] or self.currentbeat == 0:
                self.start_time = pygame.time.get_ticks()
                Beat(self.order[self.currentbeat], self.picorder[self.currentbeat])
                self.currentbeat += 1
                self.LastBeat = pygame.time.get_ticks()

class Hit_Line(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__(beatgroup)
        self.image = pygame.image.load("Sprites/hit-line.png")
        self.rect = self.image.get_rect(topleft=(873, 60))
        def update(self):
            self.image.draw()


beatgen = Beat_gen([(820, pygame.image.load("Sprites/left.png")), (410, pygame.image.load("Sprites/right.png")),(410, pygame.image.load("Sprites/left.png")),
                    (410, pygame.image.load("Sprites/right.png")),(410, pygame.image.load("Sprites/left.png")), (410, pygame.image.load("Sprites/right.png")),
                    (410, pygame.image.load("Sprites/left.png")), (410, pygame.image.load("Sprites/right.png")),(410, pygame.image.load("Sprites/left.png")),
                    (410, pygame.image.load("Sprites/right.png")),(410, pygame.image.load("Sprites/left.png")), (410, pygame.image.load("Sprites/right.png")),
                    (410, pygame.image.load("Sprites/left.png")), (410, pygame.image.load("Sprites/right.png")),(410, pygame.image.load("Sprites/left.png")),
                    (410, pygame.image.load("Sprites/right.png"))])

def main():
    while stageon:
        for events in pygame.event.get():
            if events.type == pygame.QUIT: 
                pygame.quit()
                return


        sprites.update()
        beatgroup.update()
        screen.blit(background, (0, 0))
        sprites.draw(screen)
        beatgroup.draw(screen)
        pygame.display.update()

        clock.tick(100)

if __name__ == '__main__':
    main()

Also, a note the way I tested to see if the score WAS going up was that in my original code, the score is displayed on screen. I also printed it to console. And to prove it wasn't my bad rhythm game skills, I held down one key for a while (right now it just goes left right left right)

I've run through my code several times trying to find a problem with it, but I couldn't find it.

Any explanation would be appreciated.

Thanks :)

1
And you're sure the "beat" is exactly at the coordinates 850, 100 when you press the key? Have you printed self.pos vs what is expected? Also, don't do pygame.image.load() every keypress. That's insane. Place the image in a local variable and or use integers/strings to compare with, that will be extremely slow in the long run. What you also could do, is just add a print('got here') in the "problem area" if statements. Just to see if you even end up in those blocks, which I'm pretty sure you aren't. Most likely because self.image != pygame.image.load() instance issue. - Torxed
The multiply-loaded copies of the same image are likely not comparing as equal. - jasonharper
That's the point i tried to get across, try doing self.image == pygame.image.load("Sprites/right.png") and only that. The instance of the two, will be different. You could probably do something like self.image.path == pygame.image.load(...).path, but that's ineffective. So try to compare by name/integer instead. - Torxed
The part where the code checks if the key is being pressed is being skipped. That happens quite often to me. And I'm pretty sure it should detect a key press since I'm holding the key down. I tried to print something to the console after the part where it adds to the score but it didn't print. - Eleeza the Other World Wizard
I removed the part where it checks what the beat's image is. It works fine, but defeats the purpose of the images being arrows and makes the game too easy to cheat at. - Eleeza the Other World Wizard

1 Answers

1
votes

It's future me! How I solved it was that I added another attribute to the Beat class called direction, which is a string containing either "left", "right", "up", or "down".

To get this assigned, I went to the part where the Beat_gen gets initialised and in each tuple, I added another value, like so: (820, pygame.image.load("Sprites/left.png"), "left"). Then I went up to the Beat_gen class and added a list called dirorder (direction order) and made a loop iterate through each tuple, get the third value and append it to the list, as done for the image and the timing.

Then added this to the Beat initialisation as an argument to assign it; self.dirorder[self.currentbeat]