-2

I am making a remake of a video game to learn pygame and livewires. I am using livewires because it seems to be a good way to have the background graphics loaded with a sprite.

I am trying to have a pre-loaded sprite move horizontally, while staying mobile on the correct location (in this case it is 50 pixels up).

I can get the sprite move using pygame or I can have the background with the sprite loaded in the right position or I can have the sprite move, but both seems to not occur at the same time.

For added bonus, I am also going to need the screen to scroll right when the character moves a different position.

Here is my code:

import pygame, sys
from livewires import games
from pygame.locals import *

games.init(screen_width = 640, screen_height = 480, fps = 50) #setup up the window siz

class Mario(games.Sprite):

    def update(self, pressed_keys):
        move = 50 #Setup the origianl position of the character
        if pressed_keys[K_RIGHT]: move += 1 #press right key to move forward
        if pressed_keys[K_LEFT]: move -= 1 #press left key to move back     

    def main():
        pygame.init()
        screen_image = games.load_image("World 1-1.bmp", transparent = False) #setup the background image
        games.screen.background = screen_image
        mario_image = games.load_image("Mario3.bmp")
        mario = games.Sprite(image = mario_image, x = move, y=370) #setup the position of the character
        sprites.add(mario)
        pygame.display.update()

        while True:
            for event in pygame.event.get():
                if event.type == QUIT: return pygame.quit() #if the player quits

            keys_pressed = pygame.key.get_pressed()

    games.screen.mainloop()

    main()
buhtz
  • 10,774
  • 18
  • 76
  • 149
JohnC
  • 17
  • 3

1 Answers1

3

It seems much simpler to me if you just use Pygame or use Livewires. Dont' try to force two modules to work together if they were not meant to. Besides, the Livewires's intro page says that the module is meant to be an add-on to a Python course, not a stand-alone game module. I recommend that you just use Pygame, as it is a stand-alone game module.

Also, you code above seems a bit sloppy(please to not take that personally), and I'll show you below how to make a starter Pygame file.

the main part of a Pygame file, is the game loop. A typical Pygame game loop(or any game loop really), has three basic parts:

  1. A event checker, to check for any events
  2. A event executer, to do certain actions when the corresponding events happen.
  3. A place where the graphics are rendered.

To give a general idea of a good starting file for Pygame games, here is an example:

import pygame #import the pygame moudle into the namespace <module>

WIDTH = 640 # define a constant width for our window
HEIGHT = 480 # define a constant height for our window

display = pygame.display.set_mode((WIDTH, HEIGHT)) #create a pygame window, and
#initialize it with our WIDTH and HEIGHT constants

running = True # our variable for controlling our game loop

while running:
    for e in pygame.event.get(): # iterate ofver all the events pygame is tracking
        if e.type == pygame.QUIT: # is the user trying to close the window?
            running = False # if so break the loop
            pygame.quit() # quit the pygame module
            quit() # quit is for IDLE friendliness

    display.fill((255, 255, 255)) # fill the pygame screen with white
    pygame.display.flip() # update the screen

The above would be a good starting point for making Pygame games.

But getting back to the problem at hand:

With me assuming that your using Pygame exclusively, there are several ways to make sprites/shapes move in Pygame.

Method 1: Using a sprite class

To make a your Mario sprite move, you could use a sprite class like the one below.

class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load("path\to\file.png")
        self.image.set_colorkey() # make this the color of your outlines around your image(if any exit)
        self.rect = self.image.get_rect()
        self.rect.x = WIDTH / 2
        self.rect.y = HEIGHT / 2
        self.vx = 0
        self.vy = 0

    def update(self):
        self.vx = 0
        self.vy = 0
        key = pygame.key.get_pressed()
        if key[pygame.K_LEFT]:
            self.vx = -5
        elif key[pygame.K_RIGHT]:
            self.vx = 5
        if key[pygame.K_UP]:
            self.vy = -5
        elif key[pygame.K_DOWN]:
            self.vy = 5
        self.rect.x += self.vx
        self.rect.y += self.vy

Since your class is inheriting from Pygame's sprite class, You must name your image self.image and you must name your rectangle for the image self.rect. As you can also see, the class has two main methods. One for creating the sprite(init) and one for updating the sprite(update)

To use your class, make a Pygame sprite group to hold all your sprites, and then add your player object to the group:

sprites = pygame.sprite.Group()
player = Player()
sprtites.add(player)

And to actual render your sprites to the screen call sprites.update() and sprites.draw() in your game loop, where you update the screen:

sprites.update()
window_name.fill((200, 200, 200))
sprites.draw(window_name)
pygame.display.flip()

The reason i highly recommended using sprite classes, is that it will make your code look much cleaner, and be much easier to maintain. You could even move each sprite class to their own separate file.

Before diving fully into the method above however, you should read up on pygame.Rect objects and pygame.sprite objects, as you'll be using them.

Method 2: Using A function

If you prefer not to get into sprite classes, you can create your game entities using a function similar to the one below.

def create_car(surface, x, y, w, h, color):
    rect = pygame.Rect(x, y, w, h)
    pygame.draw.rect(surface, color, rect)
    return rect

If you would still like to use a sprites, but don't want to make a class just modify the function above slightly:

def create_car(surface, x, y, color, path_to_img):
    img = pygame.image.load(path_to_img)
    rect = img.get_rect()
    surface.blit(img, (x, y))

Here is an example of how i would use the functions above to make a movable rectangle/sprite:

import pygame

WIDTH = 640
HEIGHT = 480
display = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Moving Player Test")
clock = pygame.time.Clock()
FPS = 60

def create_car(surface, x, y, w, h, color):
    rect = pygame.Rect(x, y, w, h)
    pygame.draw.rect(surface, color, rect)
    return rect

running = True
vx = 0
vy = 0
player_x = WIDTH / 2 # middle of screen width
player_y = HEIGHT / 2 # middle of screen height
player_speed = 5
while running:
    clock.tick(FPS)
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            running = False
            pygame.quit()
            quit()
        if e.type == pygame.KEYDOWN:
            if e.key == pygame.K_LEFT:
                vx = -player_speed
            elif e.key == pygame.K_RIGHT:
                vx = player_speed
            if e.key == pygame.K_UP:
                vy = -player_speed
            elif e.key == pygame.K_DOWN:
                vy = player_speed
        if e.type == pygame.KEYUP:
            if e.key == pygame.K_LEFT or e.key == pygame.K_RIGHT or\
               e.key == pygame.K_UP or e.key == pygame.K_DOWN:
                vx = 0
                vy = 0

    player_x += vx
    player_y += vy
    display.fill((200, 200, 200))
    ####make the player#####
    player = create_car(display, player_x, player_y, 10, 10, (255, 0, 0))
    pygame.display.flip()

I should note, I'm assuming a few things with each method outlined above.

That your either using a circle, square, or some type of pygame shape object. Or that your using a sprite. If your not currently using any of the methods outlined above, I suggest that you do. Doing so will make your code much easier to maintain once you begin to build larger and more complex games.

Christian Dean
  • 22,138
  • 7
  • 54
  • 87