1
votes

I'm trying to send the rocks into random positions,i tried: self.x += random.randint(-5, 5) but this is not good because every iteration of the main loop, the random number is recalculated and this creates a flickering effect that, besides being horrible, blocks the right angle of the rock. How can I fix it? I just want, starting from the high center of the screen, that the rocks go down with a random angle, then I would implement some bounces and so create my video game, but I'm stuck in that point. it's the first time I write on this forum so if I do something wrong I apologize in advance.

I want this random angle for the rocks

This is my code:

import pygame
import random
import time
import math

pygame.init()

display_width = 600
display_height = 500
screen = pygame.display.set_mode( (display_width, display_height) )
fps = 60
font_ubuntumono = pygame.font.SysFont('ubuntumono', 50, True)
rock = pygame.image.load('cave-painting.png').convert_alpha()
rock_width = rock.get_width()
rock_height = rock.get_height()
player = pygame.image.load('wizard.png').convert_alpha()

def initialize():
    global speed_rock, rocks, playerX, playerY
    speed_rock = 2
    playerX = display_width//2
    playerY = 400
    rocks = []
    rocks.append( RockClass() )

class RockClass:
    def __init__(self):
        self.x = display_width//2
        self.y = 0

    def continueDraw(self, a, b):
        self.x += **???**
        self.y += speed_rock
        screen.blit( rock, (self.x, self.y) )

    def collision(self, player, playerX, playerY):
        tolerability = 5
        right_player = playerX + player.get_width() - tolerability
        left_player = playerX + tolerability
        up_player = playerY + tolerability
        right_rock = self.x + rock_width
        left_rock = self.x
        down_rock = self.y + rock_height

        #check collision
        if down_rock > up_player and 
           ( ( left_player < left_rock and left_rock < right_player) or 
               ( right_player > right_rock and right_rock > left_player) ):
            #delete the rock from the screen
            self.x = 5000

initialize()

def update():
    pygame.display.update()
    pygame.time.Clock().tick(fps)

def drawThings():
    #draw background
    screen.fill ( (255, 255, 255) )

    #draw rocks
    for rock2 in rocks:
        rock2.continueDraw(210, 210)

    #draw the player
    screen.blit( player, (playerX, playerY) )

running = True
#main loop
while running:

    #event loop
    for event in pygame.event.get():

        #move player
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                playerX -= 30
            if event.key == pygame.K_RIGHT:
                playerX += 30

        #quit
        if event.type == pygame.QUIT:
            running = False

    #to generate infinite rocks
    if rocks[-1].y > 10:
        rocks.append( RockClass() )

    #check the player-rock collision
    for rock2 in rocks:
        rock2.collision(player, playerX, playerY)

    #bordo alto
    if playerX <= 0:
        playerX = 0
    if playerX >= 600:
        playerX = 600

    #update screen
    drawThings()
    update()
1
You need to create a random angle when you initialise each rock, then move the rock in that direction on every tick and account for bouncing off the sides - Iain Shelvington
Thanks for reply,I can't figure out how to move the rock in the direction of the angle. - C-Gian
Can you please post the original code? This code is not executable. - Rabbid76
what do you mean for original code? I tried to replicate various games and now I was trying to do this on my own, so this is the original code, I'm not copying it. EDIT: maybe you can't run it because you have not the resources(the images).I posted the enitre code, idk :/ - C-Gian
@C-Gian No, rocks is not defined in global namespace, because global rocks is missing. rock is multiply used. First it is a pygame.Surface object, later it is a Rcok object. That causes an error in screen.blit( rock, (self.x, self.y) ) - Rabbid76

1 Answers

3
votes

I recommend to generate a random speed for the x axis by random.uniform(a, b) in the constructor of Rock:

class Rock:
    def __init__(self):
        self.x = display_width//2
        self.y = 0
        self.speed_x = random.uniform(-2, 2)

Add self.speed_x to self.x in continueDraw:

class Rock:
    # [...]

    def continueDraw(self, a, b):
        self.x += self.speed_x
        self.y += speed_rock
        screen.blit( rock_img, (self.x, self.y) )

I recommend to use pygame.Rect respectively colliderect() for the collision detection:

class Rock:
    # [...]

    def collision(self, player, playerX, playerY):

        tolerability = 5
        player_rect = pygame.Rect(playerX+tolerability, playerY,
                                  player.get_width()-2*tolerability, player.get_height())
        rock_rect = pygame.Rect(self.x, self.y, rock_width, rock_height)

        #check collision
        if player_rect.colliderect(rock_rect):
            #delete the rock from the screen
            self.x = 5000