You’re taking the image dynamically, but you’re always putting the drawing in the same position (300,400) on the main screen -
You have to create variables (x and y, for example), to maintain the character’s position, and update these variables within the if
that check the keys, and choose the image to draw.
You didn’t even tell if the rest is working well - with no error message - with a code of this size it is difficult to guess if everything is ok, although it seems. The code seems complete, but without the image we can’t test.
So, if everything else is ok, what can we do: (1) put the main body of the program into a function. Although it works like this, with the while True:
loose in the middle of the module, this is not recommended -
it is impossible to reuse this code - (for example, when this game evolves and you want to show a message when the character changes screen, and back in this while True
: there is no way like this. If you are in a function, just call the function again.
And then, as all the rest of the "if" is right, just add the variables of location "x" and "y" and use these in place of the fixed numbers - the character should walk.
Well, I put some kind of image here and ran the program - yes, it’s in fact without any other problem.
So, in addition to the minimal changes I suggested, I put a few more
things already anticipating three or four other steps - that you would face next.
The first of them - in addition to putting the game logic within a function, I did this also with the boot function, and put some values
game critics within variables. With the name in capital letters of these variables, by the style convention they should be treated as constants - that is, I do not change their value after giving the initial value. I did this with the screen size, and the character size:
So at other points in the code where I needed reference to these values, I didn’t have to copy the number - and then, if I want to change
then just change the value once in the code.
The other things comment after the code:
import pygame
LARG, ALT = 800, 600
TAM_PERSONAGEM = 100
def init():
global tela, personagem
pygame.init()
tela = pygame.display.set_mode((LARG, ALT),0,32)
personagem = pygame.image.load('./você.png').convert_alpha()
def get_frame_by_gid(gid):
global personagem
columns = 4
width = TAM_PERSONAGEM
height = TAM_PERSONAGEM
space_h = 0
margin = 0
top = 0
space_v = 0
linha = gid//columns
coluna = gid % columns
x = (coluna*(width+ space_h)) + margin
y = (linha * (height+ space_v)) + top
quadro = personagem.subsurface(pygame.Rect((x,y),(width,height)))
return quadro
cima = [4,5,6,7]
baixo = [0,1,2,3]
esquerda = [8,9,10,11]
direita = [12,13,14,15]
parado_cima = [4]
parado_baixo = [0]
parado_esquerda = [8]
parado_direita = [12]
passo = 20
def principal():
lista_quadro = parado_esquerda
quadro = 0
clk = pygame.time.Clock()
x_anterior = x = LARG // 2
y_anterior = y = ALT // 2
vel_x = vel_y = 0
while True:
tela.fill((0,0,0))
quadro = quadro + 1
if quadro >= len(lista_quadro):
quadro = 0
gid = lista_quadro[quadro]
frame = get_frame_by_gid(gid)
pygame.draw.rect(tela, (0, 0, 0),(x_anterior, y_anterior, 100, 100))
tela.blit(frame,(x, y))
pygame.display.update()
clk.tick(8)
for i in pygame.event.get():
if i.type == pygame.QUIT:
return
elif i.type == pygame.KEYDOWN:
if i.key == pygame. K_LEFT:
lista_quadro = esquerda
vel_x = - passo
elif i.key == pygame. K_UP:
lista_quadro = cima
vel_y = - passo
elif i.key == pygame. K_DOWN:
lista_quadro = baixo
vel_y = passo
elif i.key == pygame. K_RIGHT:
lista_quadro = direita
vel_x = passo
elif i.type == pygame.KEYUP:
if i.key == pygame.K_LEFT:
lista_quadro = parado_esquerda
vel_x = 0
elif i.key == pygame.K_UP:
lista_quadro = parado_cima
vel_y = 0
elif i.key == pygame.K_DOWN:
lista_quadro = parado_baixo
vel_y = 0
elif i.key == pygame.K_RIGHT:
lista_quadro = parado_direita
vel_x = 0
x_anterior = x
y_anterior = y
if 0 <= x + vel_x < LARG - TAM_PERSONAGEM :
x += vel_x
if 0 <= y + vel_y < LARG - TAM_PERSONAGEM :
y += vel_y
init()
principal()
pygame.quit()
First thing - besides entering "x" and "y", I entered "vel_x" and "vel_y" - to indicate how many pixels to walk on each axis - and update everything at the end. I could do it alone
...
if i.key == pygame. K_LEFT:
lista_quadro = esquerda
x -= passo
...
That is - add my step variable directly on x and y - but having a "speed x" variable I gain two things: first - the Pcs do send several 'KEYDOWN' events when a key is pressed - but the amount of events depends on OS key repetition parameters-you could get less than a 'KEYDOWN' (or more than one) in each frame of the game - and then the move on the x axis would get uneven. With speed, I talk that he is walking left in the first keydown event - and ready, only will stop when there is a "KEYUP" of the corresponding arrow key, and the speed goes to zero.
The second advantage has to do with one of the advances I made in the game - at the end of the function, before updating x and y in each frame, I check if the persongaem will continue on the screen limits. (use the shape 0 < x < max
which is characteristic of Python, works like notation we learn in mathematics. Python internally does the same thing as 0 < x and x < max
) -
If I didn’t have a vel_x - I would have to do this check on the left key and the right key: a lot more lines of program, and a mix of concepts - take the event, with "check if the person can" . With the separate verification code, it becomes easy when the project grows to pass this to a part function as well.
Well, and besides the vel_x and vel_y I picked up a x_anterior
and y_anterior
- because if the program simply drew the character in the new position, the previous position would be marked and he would leave "trace". Hmm . but only now have I noticed that a call is also made to tela.fill
- this clears the screen between one frame and another - only it uses much more machine processing - with the previous x and y and drawing the black rectangle in the previous position, it is not necessary to fill the whole screen .
The recommendation is that you experiment there - until you understand all these points - experiemnte take the call to "tela.Fill" and also comment on the pygame.draw.rect
- and you’ll see the trail left - it’s important to understand the operation of the game and the program, at a level where whoever programs into a ready game engine, just doesn’t understand - these concepts are missing.
Good project there - in the next questions, do not forget to give a little context, otherwise the staff closes the question before someone can answer. (I got here with 4 votes to close - in the 5th vote it is closed)
Hello - then take a tour of the site - your question is with negative votes because you missed adding some text - only with the code and the title of the question sometimes becomes a problem figure out how to answer.
– jsbueno