import pygame
# Some colors
GREEN = ( 0,255,0)
BLUE = ( 0, 0, 255)
WHITE = ( 255, 255, 255)
BLACK = ( 0, 0, 0)
pygame.init()
clock = pygame.time.Clock()
#Screen
SCREEN = pygame.display.set_mode([1000,700])
#Title
pygame.display.set_caption("Trying to move things")
#Variables
x_position = 100
y_position = 100
x_speed = 0
y_speed = 0
#Positions
image_image_positions = [x_position,y_position]
#Graphics
image_image = pygame.image.load("izzat.png").convert()
image_image.set_colorkey(BLACK)
#Main loop ____
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# Keyboard commands.
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
y_speed = -5
elif event.key == pygame.K_DOWN:
y_speed = 5
elif event.key == pygame.K_w:
x_speed = -5
elif event.key == pygame.K_s:
x_speed = 5
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_speed = 0
elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y_speed = 0
elif event.key == pygame.K_w or event.key == pygame.K_s:
x_speed += 0
if y_position + y_speed >=0 and y_position + y_speed + 60 <=500:
y_position += y_speed
x_position += x_speed
SCREEN.fill(GREEN)
SCREEN.blit(image_image, image_image_positions)
print(x_position)
print(y_position)
pygame.display.flip()
clock.tick(60)
pygame.quit()
Hello, I have been having a problem which I'm really not happy at because I have been trying to fix it for a while now. So basically I have a image, and I wish to move the image based on the keyboard inputs, yet whatever I try nothing works. I then wondered maybe the y and x position aren't changing at all which is why the images positions are not changing, well I did print( those positions) but it the positions are definitely changing, the variables, so I do not get how the image positions do not change at all. Then I thought maybe because it's a tuple, so I changed it to parenthesis, that also did not work. I just don't get why my image position doesn't move if the variables for the position of the image do change. Thank you if you could help me in any way. I have looked this up but I couldn't find any help. Thank you for your help if you help me!
Update__________
Ok so apparently the image_image_position stays the same despite the variables changing when I printed the positions of image_image_position. Is there any way to change them and not have them stay at 100,100 all the time and change with the variables being changed?
You haven't assigned the speeds.
image_image_positions[0] = xspeed
image_image_positions[1] = yspeed
You are only changing your variables yspeed and xspeed, but you are not setting the actual positions of the image. Add the following line before the blit:
image_image_positions = [x_position,y_position]
Full code:
import pygame
# Some colors
GREEN = ( 0,255,0)
BLUE = ( 0, 0, 255)
WHITE = ( 255, 255, 255)
BLACK = ( 0, 0, 0)
pygame.init()
clock = pygame.time.Clock()
#Screen
SCREEN = pygame.display.set_mode([1000,700])
#Title
pygame.display.set_caption("Trying to move things")
#Variables
x_position = 100
y_position = 100
x_speed = 0
y_speed = 0
#Positions
image_image_positions = [x_position,y_position]
#Graphics
image_image = pygame.image.load("izzat.png").convert()
image_image.set_colorkey(BLACK)
#Main loop ____
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# Keyboard commands.
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
y_speed = -5
elif event.key == pygame.K_DOWN:
y_speed = 5
elif event.key == pygame.K_w:
x_speed = -5
elif event.key == pygame.K_s:
x_speed = 5
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_speed = 0
elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y_speed = 0
elif event.key == pygame.K_w or event.key == pygame.K_s:
x_speed += 0
if y_position + y_speed >=0 and y_position + y_speed + 60 <=500:
y_position += y_speed
x_position += x_speed
image_image_positions = [x_position,y_position]
SCREEN.fill(GREEN)
SCREEN.blit(image_image, image_image_positions)
print(x_position)
print(y_position)
pygame.display.flip()
clock.tick(60)
pygame.quit()
While you ARE updating the x/y positions, this isn't changing where the image is being drawn:
SCREEN.blit(image_image, image_image_positions)
image_image_positions, is never changed throughout the life-span of your application (besides startup).
To fix this simply add the update into your loop:
image_image_positions = [x_position,y_position]
Related
My question is how can I better my shooting functionality in my game. I am trying to make it to where the player can shoot in the direction it is moving (ex.shoot up,down,left,right) as well as shoot while moving and shoot while idle.
The player and missile are both rectangular using pygame shapes to make it easier for me to understand the logic behind game development.
def player(px,py):
pygame.draw.rect(gameWindow,black,[px,py,30,30])
def missile(mx,my):
pygame.draw.rect(gameWindow,black,[mx,my,10,10])
Here is the code of the game to help better understand what I'm talking about. The small section I have commented out is what I have tried. I only have it currently set to move in the x direction going left from its initial starting point.
import pygame #####IMPORTING PYGAME MODULE###########################
pygame.init() #####INITIALIZING PYGAME##################################
gameWindow = pygame.display.set_mode((800,600)) ###Screen Width and Height###
clock = pygame.time.Clock() ## FRAMES PER SECOND ##
white = (255,255,255)
black = (0,0,0)
red = (255,0,0)
def player(px,py):
pygame.draw.rect(gameWindow,black,[px,py,30,30])
def missile(mx,my):
pygame.draw.rect(gameWindow,black,[mx,my,10,10])
def enemies():
return
def gameloop():
px = 700
py = 300
mx = 700
my = 300
px_change = 0
py_change = 0
mx_change = 0
my_change = 0
gameExit = False
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
mx_change = -10
if event.key == pygame.K_RIGHT:
mx_change = 10
if event.key == pygame.K_UP:
my_change = -10
if event.key == pygame.K_DOWN:
my_change = 10
if event.key == pygame.K_SPACE:
mx_change = -6
#if event.key == pygame.K_SPACE and pygame.K_RIGHT:
#mx_change = 6
if event.key == pygame.K_LEFT:
px_change = -10
if event.key == pygame.K_RIGHT:
px_change = 10
if event.key == pygame.K_UP:
py_change = -10
if event.key == pygame.K_DOWN:
py_change = 10
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
px_change = 0
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
py_change = 0
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
mx_change = 0
mx = px
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
my_change = 0
my = py
if event.key == pygame.K_SPACE:
mx_change = 0
my_change = 0
mx = px
my = py
px += px_change
py += py_change
mx += mx_change
my += my_change
gameWindow.fill(white)
player(px,py)
missile(mx,my)
pygame.display.update()
clock.tick(100)
pygame.quit()
quit()
gameloop()
I would suggest using different objects for your player and missile. The way you have things set up right now, there can only be 1 player and 1 missile. Only having 1 player might be fine but 1 missile makes for a dull game. I suggest using a class, such as this simple example:
class Projectile():
def init(self,x,y,vx,vy):
self.x = x
self.y = y
self.vx = vx
self.vy = vy
def update(self):
self.x += self.vx
self.y += self.vy
Now that you have a class you can start doing great things! Want to have spacebar fire a new missile instead of moving the one missile on screen? ezpz! All you need is a list of your missile objects to keep track of, say my_missile_list:
if event.key == pygame.K_SPACE:
my_missile_list.append(Projectile(px,py,missile_x_velocity,missile_y_velocity))
This creates an entirely new instance of the class Projectile based on the input position and speeds.
Finally, we need to have all these missiles move! This is where the class definition makes our life easier! Once per frame we just have to update the bullets:
for b in my_missile_list:
b.update()
There are more advantages to using classes here but this is a start. If you read through this and make a few changes your game will work much more like what you are looking for.
You should set missille only when you KEYDOWN space, and not use other keys to change it. Player may have variable direction so you will know in which direction it is looking when it stay and you will know in which direction move misille.
import pygame
# --- constants --- (UPPER_CASE_NAMES)
WHITE = (255,255,255)
BLACK = (0,0,0)
RED = (255,0,0)
# --- classes --- (CamelCaseNames)
# empty
# --- functions ---- (lower_case_names_
def player(screen, x, y):
pygame.draw.rect(screen, BLACK, (x, y, 30, 30))
def missile(screen, x, y):
pygame.draw.rect(screen, RED, (x, y, 10, 10))
def enemies():
pass
def gameloop(screen):
px = 700
py = 300
mx = 700
my = 300
px_change = 0
py_change = 0
p_direction = 'left'
mx_change = 0
my_change = 0
#m_direction = 'left'
game_exit = False
clock = pygame.time.Clock() ## FRAMES PER SECOND ##
while not game_exit:
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_exit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
px_change = -10
p_direction = 'left'
if event.key == pygame.K_RIGHT:
px_change = 10
p_direction = 'right'
if event.key == pygame.K_UP:
py_change = -10
p_direction = 'top'
if event.key == pygame.K_DOWN:
py_change = 10
p_direction = 'down'
if event.key == pygame.K_SPACE:
mx = px
my = py
if p_direction == 'left':
mx_change = -16
my_change = 0
elif p_direction == 'right':
mx_change = 16
my_change = 0
elif p_direction == 'top':
mx_change = 0
my_change = -16
elif p_direction == 'down':
mx_change = 0
my_change = 16
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
px_change = 0
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
py_change = 0
# --- changes/updates ---
px += px_change
py += py_change
mx += mx_change
my += my_change
# --- draws ----
screen.fill(WHITE)
player(screen, px, py)
missile(screen, mx, my)
pygame.display.update()
# --- FPS ---
clock.tick(30)
# --- main ---
pygame.init()
screen = pygame.display.set_mode((800,600))
gameloop(screen)
pygame.quit()
#quit()
Instead of px, py and mx,my you should use pygame.Rect() - it can be used to draw() and blit() and it has methods to check collisions.
I'm trying to learn python so I'm messing around with pygame. I'm a complete beginner.
so far I have made it so that I can control an image, moving it in 2d with the arrow keys.
However, I drew the image facing left and it is always facing left and I want to make it face the direction it's moving. I managed to make it rotate 180 degrees when I press right, but that was everytime I press right so I kept flipping the wrong way.
I need it to face right when moving right and left when moving left.
Image attached.
Thank you
import pygame
import time
pygame.init()
display_width = 1000
display_height = 800
black=(0,0,0)
white=(255,255,255)
gamedisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('metal gear python')
clock = pygame.time.Clock()
snakeimg= pygame.image.load('snake.png')
snake_width = 96
snake_height= 79
def snake(x,y):
gamedisplay.blit(snakeimg, (x,y))
discovered = False
while not discovered:
for event in pygame.event.get():
if event.type == pygame.QUIT:
discovered = TRUE
print (event)
x = (display_width * 0.45)
y = (display_height * 0.8)
x_change=0
y_change=0
snake_speed=0
gameExit= False
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
print(event)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -3
elif event.key == pygame.K_RIGHT:
x_change = 3
elif event.key == pygame.K_RIGHT:
x_change = 3
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
x_change = 0
elif event.key == pygame.K_RIGHT:
x_change = 0
x += x_change
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
y_change = -3
elif event.key == pygame.K_DOWN:
y_change = 3
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y_change = 0
y += y_change
gamedisplay.fill(white)
snake(x,y)
if x > display_width-snake_width or x < 0:
gameExit=True
if y > display_height-snake_height or y < 0:
True
pygame.display.update()
clock.tick(60)
pygame.quit()
quit()
Mainly i change the snake function, so that it computes the correct rotation and then rotates the image. Also I change a little bit of the logic, especially at event handling so it is easier to read
import pygame
import time
pygame.init()
display_width = 1000
display_height = 800
black = (0, 0, 0)
white = (255, 255, 255)
gamedisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('metal gear python')
clock = pygame.time.Clock()
snakeimg = pygame.image.load('snake.png')
snake_width = 96
snake_height = 79
def snake(x, y):
if x_change == 0 and y_change == 0:
rotation = -90
elif x_change > 0 and y_change == 0:
rotation = 180
elif x_change < 0 and y_change == 0:
rotation = 0
elif x_change == 0 and y_change > 0:
rotation = 90
elif x_change == 0 and y_change < 0:
rotation = -90
elif x_change < 0 and y_change < 0:
rotation = -45
elif x_change < 0 and y_change > 0:
rotation = 45
elif x_change > 0 and y_change < 0:
rotation = -135
elif x_change > 0 and y_change > 0:
rotation = 135
gamedisplay.blit(pygame.transform.rotate(snakeimg, rotation), (x, y))
discovered = False
while not discovered:
for event in pygame.event.get():
if event.type == pygame.QUIT:
discovered = True
print(event)
x = (display_width * 0.45)
y = (display_height * 0.8)
x_change = 0
y_change = 0
snake_speed = 0
gameExit = False
while not gameExit:
for event in pygame.event.get():
print(event)
if event.type == pygame.QUIT:
gameExit = True
discovered = True # so you can actually quit the game
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -3
elif event.key == pygame.K_RIGHT:
x_change = 3
elif event.key == pygame.K_UP:
y_change = -3
elif event.key == pygame.K_DOWN:
y_change = 3
elif event.type == pygame.KEYUP:
if event.key in (pygame.K_LEFT, pygame.K_RIGHT):
x_change = 0
elif event.key in (pygame.K_UP, pygame.K_DOWN):
y_change = 0
x += x_change
y += y_change
gamedisplay.fill(white)
snake(x, y)
if x > display_width - snake_width or x < 0:
gameExit = True
if y > display_height - snake_height or y < 0:
gameExit = True
pygame.display.update()
clock.tick(60)
pygame.quit()
quit()
And still i have the question: Why 2 game loops inside each other?
I'm just messing around with Pygame and I can't see what I'm doing incorrectly to make the red circle move with the arrow keys. I can't tell if it's in my main loop. I also haven't been able to find very many tutorials on sprite or looping animations with Pygame. If I for example wanted to make a square oscillate for example like a moving platform how would I do that?
import pygame
import time
## event handling varibles
player_x = 0
player_y = 0
x = 250
y = 250
## screen display
display_width = 500
display_height = 500
pygame.init()
game_screen = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption("test")
# player
def player():
pygame.draw.circle(game_screen,red,(x,y),15)
# colors
white = (255,255,255)
red = (255,0,0)
black = (0,0,0)
### main loop
dead = False
while dead != True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
dead = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player_x = -1
elif event.key == pygame.K_RIGHT:
player_x = +1
if event.key == pygame.K_UP:
player_y = +1
elif event.key == pygame.K_DOWN:
player_y = -1
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or pygame.K_RIGHT:
player_x = 0
if event.key == pygame.K_UP or pygame.K_DOWN:
player_y = 0
game_screen.fill(black)
player()
pygame.display.update()
x -= player_x
y -= player_y
pygame.quit()
quit()
Your indendation is all messed up.
Your code won't do anything unless the event is QUIT... which then makes it quit.
Your boolean logic is wrong.
This is not proper syntax event.key == pygame.K_UP or pygame.K_DOWN. The order of precedence here is as follows (event.key == pygame.K_UP) or (K_DOWN). Since K_DOWN is truthy, it is always true and thus this entire statement is always true.
I think you mean: event.key == pygame.K_UP or event.key == pygame.K_DOWN
Lastly, it wont' keep moving as you say you want.
It will only move when there is an event in the queue. You can make it keep moving by generating events. Perhaps with an event timer.
Here is a fixed version, hope this helps:
import pygame
import time
## event handling varibles
player_x = 0
player_y = 0
x = 250
y = 250
## screen display
display_width = 500
display_height = 500
pygame.init()
game_screen = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption("test")
# player
def player(game_screen, red, point): # Use parameters not globals
pygame.draw.circle(game_screen, red, point, 15)
# colors
white = (255,255,255)
red = (255,0,0)
black = (0,0,0)
### main loop
pygame.time.set_timer(pygame.USEREVENT, 1) # 1 per second
dead = False
while not dead:
for event in pygame.event.get():
if event.type == pygame.QUIT:
dead = True
elif event.type == pygame.USEREVENT:
pygame.time.set_timer(pygame.USEREVENT, 1) # Set another timer for another 1 second
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player_x = +10
elif event.key == pygame.K_RIGHT:
player_x = -10
elif event.key == pygame.K_UP:
player_y = +10
elif event.key == pygame.K_DOWN:
player_y = -10
elif event.type == pygame.KEYUP:
if event.key in [pygame.K_LEFT, pygame.K_RIGHT]:
player_x = 0
elif event.key in [pygame.K_UP, pygame.K_DOWN]:
player_y = 0
game_screen.fill(black)
player(game_screen,red,(x,y))
pygame.display.update()
x -= player_x
y -= player_y
pygame.quit()
How would I get some mechanics for falling when in an empty space, many answers on the internet said to add gravity but I couldn't understand how they did that they just showed me a bunch of equations.
Also, how would I set an image as my background?
Here's my source code:
import pygame
pygame.init()
display_width = 2560
display_height = 1440
white = (255,255,255)
gameDisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('RGB')
clock = pygame.time.Clock()
filler = pygame.image.load('filleraftergimp.png')
def fill(x,y):
gameDisplay.blit(filler,(x,y))
x = (display_width * 0.45)
y = (display_height * 0.8)
x_change = 0
y_change = 0
diedorgameover = False
while not diedorgameover:
for event in pygame.event.get():
if event.type == pygame.QUIT:
diedorgameover = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
x_change = -5
elif event.key == pygame.K_d:
x_change = 5
elif event.key == pygame.K_s:
y_change = 5
elif event.key == pygame.K_w:
y_change = -5
if event.type == pygame.KEYUP:
if event.key == pygame.K_a or event.key == pygame.K_d:
x_change = 0
if event.key == pygame.K_s or event.key == pygame.K_w:
y_change = 0
x += x_change
y += y_change
gameDisplay.fill(white)
fill(x,y)
pygame.display.update()
clock.tick(60)
pygame.quit()
quit()
To implement gravity in your game (as in a 2D platformer), you can just increase the y_change variable each frame, so that you move the object a bit faster downwards each time. Take a look at this example:
import pygame as pg
pg.init()
LIGHTBLUE = pg.Color('lightskyblue2')
DARKBLUE = pg.Color(11, 8, 69)
display = pg.display.set_mode((800, 600))
width, height = display.get_size()
clock = pg.time.Clock()
player_image = pg.Surface((30, 60))
player_image.fill(DARKBLUE)
x = width * 0.45
y = 0
x_change = 0
y_change = 0
on_ground = False
# A constant value that you add to the y_change each frame.
GRAVITY = .3
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.KEYDOWN:
if event.key == pg.K_a:
x_change = -5
elif event.key == pg.K_d:
x_change = 5
elif event.key == pg.K_s:
y_change = 5
elif event.key == pg.K_w:
if on_ground: # Only jump if the player is on_ground.
y_change = -12
on_ground = False
elif event.type == pg.KEYUP:
if event.key == pg.K_a and x_change < 0:
x_change = 0
elif event.key == pg.K_d and x_change > 0:
x_change = 0
# Add the GRAVITY value to y_change, so that
# the object moves faster each frame.
y_change += GRAVITY
x += x_change
y += y_change
# Stop the object when it's near the bottom of the screen.
if y >= height - 130:
y = height - 130
y_change = 0
on_ground = True
# Draw everything.
display.fill(LIGHTBLUE)
pg.draw.line(display, (0, 0, 0), (0, height-70), (width, height-70))
display.blit(player_image, (x, y))
pg.display.update()
clock.tick(60)
pg.quit()
I'm developing a very basic engine, basing myself on tutorials from Pygame, and I'm having a little problem with "smoothness". How do I make my player walk "smoother"?
My event handler is pretty basic, pretty standard, nothing new, and I even figured out how to make a "boost" (run) for test. But the thing is, at the pygame.KEYUP, those lots of zeros destroy the "smoothness" of my little player, and I don't want that, but I don't want it to walk ad infinitum.
import pygame
import gfx
# Main Class
class Setup:
background = gfx.Images.background
player = gfx.Images.player
pygame.init()
# Configuration Variables:
black = (0,0,0)
white = (255,255,255)
green = (0,255,0)
red = (255,0,0)
title = "Ericson's Game"
# Setup:
size = [700,700]
screen = pygame.display.set_mode(size)
pygame.display.set_caption(title)
done = False
clock = pygame.time.Clock()
# Logic Variables
x_speed = 0
y_speed = 0
x_speed_boost = 0
y_speed_boost = 0
x_coord = 350
y_coord = 350
screen.fill(white)
# Main Loop:
while done == False:
screen.blit(background,[0,0])
screen.blit(player,[x_coord,y_coord])
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
done = True
if event.key == pygame.K_a:
x_speed = -6
x_speed_boost = 1
if event.key == pygame.K_d:
x_speed = 6
x_speed_boost = 2
if event.key == pygame.K_w:
y_speed = -6
y_speed_boost = 1
if event.key == pygame.K_s:
y_speed = 6
y_speed_boost = 2
if event.key == pygame.K_LSHIFT:
if x_speed_boost == 1:
x_speed = -10
if x_speed_boost == 2:
x_speed = 10
if y_speed_boost == 1:
y_speed = -10
if y_speed_boost == 2:
y_speed = 10
if event.type == pygame.KEYUP:
if event.key == pygame.K_a:
x_speed = 0
x_speed_boost = 0
if event.key == pygame.K_d:
x_speed = 0
x_speed_boost = 0
if event.key == pygame.K_w:
y_speed = 0
y_speed_boost = 0
if event.key == pygame.K_s:
y_speed = 0
y_speed_boost = 0
x_coord = x_coord + x_speed
y_coord = y_coord + y_speed
pygame.display.flip()
pygame.display.update()
clock.tick(20)
pygame.quit()
Code will be simpler/clearer using keystate polling for your use. If other parts of the game use 'on press' logic, you can use event handling. So your movement would be:
If you are calling pygame.display.flip() then you don't use pygame.display.update(). Infact it will probably slow it down to use both.
I used your x_coord variable. But it would simplify things to use a tuple or vector for player location. You can use a float, for smoother precision for movement. Then it blits as an int to screen.
while not done:
for event in pygame.event.get():
# any other key event input
if event.type == QUIT:
done = True
elif event.type == KEYDOWN:
if event.key == K_ESC:
done = True
vel_x = 0
vel_y = 0
speed = 1
if pygame.key.get_mods() & KMOD_SHIFT
speed = 2
# get key current state
keys = pygame.key.get_pressed()
if keys[K_A]:
vel_x = -1
if keys[K_D]:
vel_x = 1
if keys[K_W]:
vel_y = -1
if keys[K_S]:
vel_y = 1
x_coord += vel_x * speed
y_coord += vel_y * speed
You are ticking the clock at a rate of 20 frames per second. This is probably causing the choppiness. Change it to something bigger like 70:
clock.tick(70)