0

Thanks for the help in advance. I'm new to the Python language and using this project to learn Python, right now it uses a function to draw tiles to the screen and I'm working on getting a sprite to be able to move with key presses. The problem is that my function keyMoveSprite() can't see my global variables x_coordinate and y_coordinate. They were inside my function but this caused my sprite not to move due to the x and y variables being set back to 0 every iteration, so I figured they needed to be outside of the loop. Any suggestions? Here is my code. I kind of think this problem may be due to it the function being repeatedly called in my main loop of the game, but it needs to be repeatedly called to keep track of input.

import pygame,sys
from pygame.locals import *

pygame.init()  

#Global Variables
screen_x = 800
screen_y = 480
screen =  pygame.display.set_mode((screen_x, screen_y))
x_coordinate = 0
y_coordinate = 0
moveX, moveY = 0, 0


#This function will take the screen coordinates and draw
#a tile to the entire screen. It will draw tiles no matter
#the screen size.

def keyMoveSprite():
    sprite = pygame.image.load("character.png").convert_alpha()

    for event in pygame.event.get():

        if event.type == KEYDOWN:
            if event.key == K_LEFT:
                moveX = -10
            elif event.key == K_RIGHT:
                moveX = +10
            elif event.key == K_UP:
                moveY = -10
            elif event.key == K_DOWN:
                moveY = +10

        if event.type == KEYUP:
            if event.key == K_LEFT:
                moveX = 0
            elif event.key == K_RIGHT:
                moveX = 0
            elif event.key == K_UP:
                moveY = 0
            elif event.key == K_DOWN:
                moveY = 0

    x_coordinate = x_coordinate + moveX
    y_coordinate = y_coordinate + moveY

    screen.blit(sprite,(x_coordinate, y_coordinate))
    pygame.display.update()
    print("Character drawn at:", x_coordinate, y_coordinate)


def mapDraw(screen_x, screen_y):



    floor = pygame.image.load("floor_tile.png")
    wall = pygame.image.load("wall_tile.png")
    treasure = pygame.image.load("treasure_chest.png")

# Intialize row for loop
    row = 0
    mapColumn = 0
    mapRow = 0

#Loop between the values 0 to the screen's y variable, in intervals of
#32, and store them in the variable row once per loop.

    mapArray = [
        [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
        [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
        [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
        [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
        [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
        [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
        [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
        [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
        [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
        [1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1],
        [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1],
        [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1],
        [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1],
        [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1],
        [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
        ]


    for row in range(0, screen_y, 32):
        column = 0 # Set column to 0 per iteration, this allows reset of the x coordinate
        print("Map Row Value:", mapRow)
        mapColumn = 0 # Resets mapColumn variable to 0
        for column in range(0, screen_x, 32):

            if mapArray[mapRow][mapColumn] == 0:

                screen.blit(floor, (column, row)) 
                #print(column,row)
                pygame.display.update()
                #print("Map Column Value:",mapColumn)
                print("MapCol",mapColumn,"MapRow",mapRow)

            elif mapArray[mapRow][mapColumn] == 1:
                screen.blit(wall, (column, row))
                pygame.display.update()







            mapColumn = mapColumn + 1

        mapRow = mapRow + 1


def main():

    mapFloor = mapDraw(800,480)
    while True:

        keyMoveSprite()

main()
DougLuce
  • 93
  • 4
  • 10

1 Answers1

1

Try using the global keyword so that the interpreter can disambiguate between the local assignments of x_coordinate and y_coordinate:

def keyMoveSprite():
    global x_coordinate, y_coordinate
    # The rest of your code...

A better way to solve this problem is to create a class to represent your player, its position, and other state associated with it, rather than storing everything in globals.

Community
  • 1
  • 1
kevintodisco
  • 5,061
  • 1
  • 22
  • 28
  • This works, thanks so much. Any chance you have an idea how to make it so that my sprite doesn't "drag" on the screen? – DougLuce Nov 09 '13 at 07:34
  • @DougLuce What do you mean by "drag"? Another question/answer may already exist about this new problem you're encountering. Perhaps I can help you find it. – kevintodisco Nov 09 '13 at 07:39
  • Done, new to the site but I found the check box. I mean that it blits the image to the screen at each iteration, but I need to figure out a way to "undraw" each image after it moves. – DougLuce Nov 09 '13 at 07:42
  • @DougLuce Ah, I see what you mean. To solve that you just have to add `screen.fill((0,0,0))` to your `while` loop in `main`. Essentially, every frame you need to clear the screen and redraw the scene with everything in their new positions. It's the classic game rendering paradigm. – kevintodisco Nov 09 '13 at 07:53
  • Hmm this is used to fill the screen with solid black, I thought that pygame.display.update() updated the screen? I tried screen.fill((0,0,0)) but it filled the screen with black on top of my already drawn map. – DougLuce Nov 09 '13 at 07:58
  • 1
    @DougLuce You'll need to put the call first in the loop, before you draw anything else. `pygame.display.update()` will indeed update the display with the contents of the `screen` surface, but if that surface is not cleared before drawing again, you will still have data from the previous frame, creating the trailing effect. – kevintodisco Nov 09 '13 at 08:03
  • Thank, I appreciate the help. I understand what's happening now, thanks for clarifying this concept for me. – DougLuce Nov 09 '13 at 18:22