Python Forum

Full Version: Image skipping
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hey, this is my first post btw.

So I am trying to create a game where you can catch a ball and afterwards it refreshes. However the image of the ball that is supposed to run down the lane skips from screen_width (1280) - 100 all the way to x: 200 when it's updated with self.x -= self.speed. I don't know where it went wrong.

import sys
import pygame
from pygame.sprite import Group
from pygame.sprite import Sprite
from random import randint

import pygame
from pygame.sprite import Sprite

class Ball(Sprite):

    def __init__(self, ai_settings, screen):
        #Initialize alien and starting position

        super(Ball, self).__init__()
        self.screen = screen
        self.ai_settings = ai_settings

        self.speed = 1
        self.drop_speed = 10
        self.direction = 1

        #Load the alien image and set its Rect attribute
        self.image = pygame.image.load('ball.jpg')
        self.rect = self.image.get_rect()

        self.rect.x = self.rect.width
        self.rect.y = self.rect.height

        self.x = float(self.rect.x)

    def blitme(self):
        self.screen.blit(self.image, self.rect)

    def update(self):
        self.x -= self.speed / 10
        self.rect.x = self.x


class Bullet(Sprite):
    def __init__(self, sets, screen, ship):
        super(Bullet, self).__init__()
        self.screen = screen

        self.rect = pygame.Rect(0, 0, sets.bullet_width, sets.bullet_height)
        self.rect.centery = ship.rect.centery
        self.rect.right = ship.rect.right

        self.x = float(self.rect.x)
        self.color = sets.bullet_color
        self.speed = sets.bullet_speed

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

    def draw_bullet(self):
        pygame.draw.rect(self.screen, self.color, self.rect)

class Gf():

    def check_keydown_events(event, sets, screen, ship, bullets):
        if event.key == pygame.K_UP:
            ship.moving_up = True
        elif event.key == pygame.K_DOWN:
            ship.moving_down = True
        elif event.key == pygame.K_c:
            # create a new bullet and add it to Group
            if len(bullets) < sets.allowed:
                new_bullet = Bullet(sets, screen, ship)
                bullets.add(new_bullet)

    def check_keyup_events(event, ship):
        if event.key == pygame.K_UP:
            ship.moving_up = False
        elif event.key == pygame.K_DOWN:
            ship.moving_down = False

    def check_events(self, sets, screen, ship, bullets):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                Gf.check_keydown_events(event, sets, screen, ship, bullets)
            elif event.type == pygame.KEYUP:
                Gf.check_keyup_events(event, ship)

    def update_screen(self, ai_settings, screen, ship, bg_color, bullets, balls):

        # Redraw the screen during each pass through the loop.
        screen.fill(bg_color)
        ship.blitme()
        balls.draw(screen)

        # Redraw all bullets behind ship and aliens.
        for bullet in bullets.sprites():
            bullet.draw_bullet()

        # Make the most recently drawn screen visible.
        pygame.display.flip()

    def update_balls(self, balls):
        balls.update()

    def create_ball(self, sets, screen, balls):

        for v in range(0,2):
            random_number = randint(-sets.screen_height / 2,sets.screen_height / 2)
            ball = Ball(sets, screen)
            at = Ball(sets, screen)
            at.rect.x = -1000
            at.rect.y = (sets.screen_height / 2) + random_number
            balls.add(at)

    def update_collision(self, balls, sets, screen, ships, bullets):
        # check for any bullets that have hit aliens

        collisions = pygame.sprite.groupcollide(ships, balls, False, True)

        if len(balls) == 0:
            Gf.create_ball(self, sets, screen, balls)

class Ship(Sprite):

    def __init__(self, settings, speed, screen, image):
        super(Ship, self).__init__()
        self.settings = settings
        self.speed = speed
        self.screen = screen
        self.image = pygame.image.load(image)

        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()

        self.rect.centery = self.screen_rect.centery
        self.rect.left = self.screen_rect.left

        self.center = float(self.rect.centerx)

        self.moving_up = False
        self.moving_down = False

    def update(self):

        if self.moving_up and self.rect.top > 0:
            self.rect.centery -= self.speed
        elif self.moving_down and self.rect.bottom < 800:
            self.rect.centery += self.speed

    def blitme(self):
        self.screen.blit(self.image, self.rect)

class Settings():

    def __init__(self, speed, screen):
        self.speed = speed
        self.screen = screen

    screen_width = 1200
    screen_height = 800

    # Bullet Settings
    bullet_speed = 2
    bullet_height = 15
    bullet_width = 5
    bullet_color = (255, 255, 255)
    allowed = 5

def rungame():
    pygame.init()

    screen_width = 1200
    screen_height = 800

    tgf = Gf()
    speed = 2
    bullets = Group()
    balls = Group()
    ships = Group()
    screen = pygame.display.set_mode((screen_width, screen_height))
    sets = Settings(speed, screen)
    ship = Ship(sets, speed, screen, 'p2/sidewayship.png')
    ships.add(ship)
    pygame.display.set_caption("Sideway shooter 1000")
    bg_color = (0, 0, 0)

    tgf.create_ball(sets, screen, balls)

    while True:
        for bullet in bullets.copy():
            if bullet.rect.right >= screen_width:
                bullets.remove(bullet)

        ship.update()
        tgf.check_events(sets, screen, ship, bullets)
        bullets.update()
        tgf.update_screen(sets, screen, ship, bg_color, bullets, balls)
        tgf.update_balls(balls)
        tgf.update_collision(balls, sets, screen, ships, bullets)

rungame()
codes of interest:

class Ball(Sprite):

    def __init__(self, ai_settings, screen):
        #Initialize alien and starting position

        super(Ball, self).__init__()
        self.screen = screen
        self.ai_settings = ai_settings

        self.speed = 1
        self.drop_speed = 10
        self.direction = 1

        #Load the alien image and set its Rect attribute
        self.image = pygame.image.load('ball.jpg')
        self.rect = self.image.get_rect()

        self.rect.x = self.rect.width
        self.rect.y = self.rect.height

        self.x = float(self.rect.x)
    def create_ball(self, sets, screen, balls):

        for v in range(0,2):
            random_number = randint(-sets.screen_height / 2,sets.screen_height / 2)
            ball = Ball(sets, screen)
            at = Ball(sets, screen)
            at.rect.x = -1000
            at.rect.y = (sets.screen_height / 2) + random_number
            balls.add(at)
Here's where it's supposed to start:
[Image: 24los35.png]

Here's where it starts:
[Image: 14uxkap.png]

How come I can't edit the post? =/

full code for class(Ball):

class Ball(Sprite):

    def __init__(self, ai_settings, screen):
        #Initialize alien and starting position

        super(Ball, self).__init__()
        self.screen = screen
        self.ai_settings = ai_settings

        self.speed = 1
        self.drop_speed = 10
        self.direction = 1

        #Load the alien image and set its Rect attribute
        self.image = pygame.image.load('ball.jpg')
        self.rect = self.image.get_rect()

        self.rect.x = self.rect.width
        self.rect.y = self.rect.height

        self.x = float(self.rect.x)

    def blitme(self):
        self.screen.blit(self.image, self.rect)

    def update(self):
        self.x -= self.speed / 10
        self.rect.x = self.x
(May-10-2018, 03:01 PM)Aisuuu Wrote: [ -> ]
    while True:
        for bullet in bullets.copy():
            if bullet.rect.right >= screen_width:
                bullets.remove(bullet)
 
        ship.update()
        tgf.check_events(sets, screen, ship, bullets)
        bullets.update()
        tgf.update_screen(sets, screen, ship, bg_color, bullets, balls)
        tgf.update_balls(balls)
        tgf.update_collision(balls, sets, screen, ships, bullets)

Without running the code, my initial impression could be that you don't have any sort of clock, so your code runs as fast as it possibly can. So try using pygame's clock to see if that helps. Before the while loop: clock = pygame.time.Clock(), and then inside the while loop (the very last line of the loop): clock.tick(60) (the parameter is your target fps, and the clock will pause the game to make sure it doesn't go faster than that).
Hey, thanks for the response!

I tried running the code but now it glitches from the original placement to the final placement, as in I can see the image glitching to the left =/
(May-10-2018, 03:01 PM)Aisuuu Wrote: [ -> ]
        self.rect.x = self.rect.width
        self.rect.y = self.rect.height
That's in your Ball.__init__. So you always set it's position to a pretty small number? I'm not sure I understand what that's supposed to be doing.
Thanks!

what i don't get is that I can set the position using those values, but if I udpate them from outside the __init__ it doesn't work?