views:

164

answers:

2

I am just starting out learning pygame and livewires, and I'm trying to make a single-player pong game, where you just hit the ball, and it bounces around until it passes your paddle (located on the left side of the screen and controlled by the mouse), which makes you lose. I have the basic code, but the ball doesn't stay on the screen, it just flickers and doesn't remain constant. Also, the paddle does not move with the mouse. I'm sure I'm missing something simple, but I just can't figure it out. Help please! Here's what I have:

from livewires import games
import random

games.init(screen_width=640, screen_height=480, fps=50)

class Paddle(games.Sprite):

    image=games.load_image("paddle.bmp")

    def __init__(self, x=10):
        super(Paddle, self).__init__(image=Paddle.image,
                                    y=games.mouse.y,
                                    left=10)
        self.score=games.Text(value=0, size=25, top=5, right=games.screen.width - 10)
        games.screen.add(self.score)

    def update(self):
        self.y=games.mouse.y
        if self.top<0:
            self.top=0
        if self.bottom>games.screen.height:
            self.bottom=games.screen.height
        self.check_collide()

    def check_collide(self):
        for ball in self.overlapping_sprites:
            self.score.value+=1
            ball.handle_collide()

class Ball(games.Sprite):

    image=games.load_image("ball.bmp")
    speed=5

    def __init__(self, x=90, y=90):
        super(Ball, self).__init__(image=Ball.image,
                                   x=x, y=y,
                                   dx=Ball.speed, dy=Ball.speed)

    def update(self):
        if self.right>games.screen.width:
            self.dx=-self.dx
        if self.bottom>games.screen.height or self.top<0:
            self.dy=-self.dy
        if self.left<0:
            self.end_game()
            self.destroy()

    def handle_collide(self):
        self.dx=-self.dx

    def end_game(self):
        end_message=games.Message(value="Game Over",
                                  size=90,
                                  x=games.screen.width/2,
                                  y=games.screen.height/2,
                                  lifetime=250,
                                  after_death=games.screen.quit)
        games.screen.add(end_message)



def main():

    background_image=games.load_image("background.bmp", transparent=False)
    games.screen.background=background_image

    paddle_image=games.load_image("paddle.bmp")
    the_paddle=games.Sprite(image=paddle_image,
                            x=10,
                            y=games.mouse.y)
    games.screen.add(the_paddle)

    ball_image=games.load_image("ball.bmp")
    the_ball=games.Sprite(image=ball_image,
                          x=630,
                          y=200,
                          dx=2,
                          dy=2)
    games.screen.add(the_ball)

    games.mouse.is_visible=False

    games.screen.event_grab=True

    games.screen.mainloop()

main()
+1  A: 

I can't help you because you did not post the complete code here. At least, I do not see where you're updating the positions of the sprites (self.x += self.dx somewhere?) and updating the draw to screen. You're also not utilising your classes in the main() function.

That said, I'm seeing

 def __init__(self, x=10):

and inside the constructor you never used the x variable. That worries me, too.

Consider using the Paddle and Ball class as a Sprite, like the following:

if __name__ == '__main__':

    background_image = games.load_image("background.bmp", transparent=False)
    games.screen.background = background_image

    the_paddle = Puddle()
    games.screen.add(the_paddle)

    the_ball = Ball()
    games.screen.add(the_ball)

    games.mouse.is_visible = False
    games.screen.event_grab = True

    games.screen.mainloop()

Note I've taken the liberty to make your code read more Pythonic. I have never used livewires, however, so my code may not function. But it should point you to the right direction. Good luck!

Xavier Ho
A: 

Why are you using livewires? You can use only pygame a pong game.

import pygame

pygame.init()
screen = pygame.display.set_mode((640, 480)) # window size
pygame.display.set_caption("Simple pong") # window title

# this is a rect that contains the ball
# at the beginning it is set in the center of the screen
ball_rect = pygame.Rect((312, 232), (16, 16))
# speed of the ball (x, y)
ball_speed = [4, 4]

# this contains your paddle
# vertically centered on the left side
paddle_rect = pygame.Rect((8, 200), (8, 80))

# 1 point if you hit the ball
# -5 point if you miss the ball
score = 0

# load the font for displaying the score
font = pygame.font.Font(None, 30)

# mainloop
while True:
    # event handler
    for event in pygame.event.get():
        # quit event => close the game
        if event.type == pygame.QUIT:
            exit(0)
        # control the paddle with the mouse
        elif event.type == pygame.MOUSEMOTION:
            paddle_rect.centery = event.pos[1]
            # correct paddle position if it's going out of window
            if paddle_rect.top < 0:
                paddle_rect.top = 0
            elif paddle_rect.bottom >= 480:
                paddle_rect.bottom = 480

    # this test if up or down keys are pressed
    # if yes move the paddle
    if pygame.key.get_pressed()[pygame.K_UP] and paddle_rect.top > 0:
        paddle_rect.top -= 5
    elif pygame.key.get_pressed()[pygame.K_DOWN] and paddle_rect.bottom < 480:
        paddle_rect.top += 5

    # update ball position
    # this move the ball
    ball_rect.left += ball_speed[0]
    ball_rect.top += ball_speed[1]

    # these two if block control if the ball is going out on the screen
    # if it's going it reverse speed to simulate a bounce
    if ball_rect.top <= 0 or ball_rect.bottom >= 480:
        ball_speed[1] = -ball_speed[1]

    if ball_rect.right >= 640:
        ball_speed[0] = -ball_speed[0]
    # this control if the ball touched the left side
    elif ball_rect.left <= 0:
        score -= 5
        # reset the ball to the center
        ball_rect = pygame.Rect((312, 232), (16, 16))

    # test if the ball is hit by the paddle
    # if yes reverse speed and add a point
    if paddle_rect.colliderect(ball_rect):
        ball_speed[0] = -ball_speed[0]
        score += 1

    # clear screen
    screen.fill((255, 255, 255))

    # draw the ball, the paddle and the score
    pygame.draw.rect(screen, (0, 0, 0), paddle_rect) # paddle
    pygame.draw.circle(screen, (0, 0, 0), ball_rect.center, ball_rect.width/2) # ball
    score_text = font.render(str(score), True, (0, 0, 0))
    screen.blit(score_text, (320-font.size(str(score))[0]/2, 5)) # score

    # update screen and wait 20 milliseconds
    pygame.display.flip()
    pygame.time.delay(20)
Francesco Pasa