I'm working with movements and I have made the red block follow the white block which is the player when ever the white block changes directions I have the red block also change directions is there a way I could make it smoothier other then it teleporting the tail to the direction of the player? Video Link
here is how the red tail moves based on the white block if the player is moving down the x and y of the tail changes and same for the up ,left,right I want a better way to do this without it instantly teleporting to those position like smoothly move there
if down:
#-- the tail red change directions
tail.y = player1.y - 80
tail.x = player1.x
if up:
#-- the tail red change directions
tail.y = player1.y + 80
tail.x = player1.x
if left:
#-- the tail red change directions
tail.y = player1.y
tail.x = player1.x + 80
if right:
#-- the tail red change directions
tail.y = player1.y
tail.x = player1.x - 80
my full code
import pygame
pygame.init()
# draw the iwndow
width = 500
height = 750
window = pygame.display.set_mode((height,width))
# the player class
class player:
def __init__(self,x,y,height,width,color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
self.rect = pygame.Rect(x,y,height,width)
self.speed = 5
def draw(self):
self.rect.topleft = (self.x,self.y)
pygame.draw.rect(window,self.color,self.rect)
# display the player
color = (255,255,255)
player1 = player(180,190,40,40,color)
# bg
bg = pygame.image.load('2.png')
# the colision to determine the direction the player should move
class player:
def __init__(self,x,y,height,width,color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
self.rect = pygame.Rect(x,y,height,width)
self.speed = .9
def draw(self):
self.rect.topleft = (self.x,self.y)
pygame.draw.rect(window,self.color,self.rect)
# display the player
color = (255,255,255)
tailcolor = (176, 58, 46)
player1 = player(180,170,50,50,color)
tail = player(100,170,50,50,tailcolor)
def draw():
window.fill((0,0,0))
window.blit(bg,(0,0))
player1.draw()
tail.draw()
# make movements True
right = False
left = False
up = False
down = False
only_up = False
only_left = False
# get position
pos = True
pos2 = 0
# the main loop
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# check for key press
keys = pygame.key.get_pressed()
if down:
#-- the tail red change directions
tail.y = player1.y - 80
tail.x = player1.x
if up:
#-- the tail red change directions
tail.y = player1.y + 80
tail.x = player1.x
if left:
#-- the tail red change directions
tail.y = player1.y
tail.x = player1.x + 80
if right:
#-- the tail red change directions
tail.y = player1.y
tail.x = player1.x - 80
#--------------------------------------------------- player movement
if left == False:
if keys[pygame.K_RIGHT]:
if not keys[pygame.K_UP]:
if not keys[pygame.K_DOWN]:
right = True
if right:
left = False
down = False
up = False
player1.x += player1.speed
if right == False:
if keys[pygame.K_LEFT]:
if not keys[pygame.K_UP]:
if not keys[pygame.K_DOWN]:
left = True
if left:
right = False
down = False
up = False
player1.x -= player1.speed
if down == False:
if keys[pygame.K_UP]:
up = True
if up:
down = False
left = False
right = False
player1.y -= player1.speed
if up == False:
if keys[pygame.K_DOWN]:
down = True
if down:
up = False
left = False
right = False
player1.y += player1.speed
#--------------------------------------------------- player movement
# show everything drawn
draw()
pygame.display.update()
pygame.quit()
I think you can achieve that by using some sort of delay. Instead of getting the position of the tail based on the current position of the player, you want to get the position of the tail based on an "old position of the player".
Also, the delay should be a variable that you can change at will later, in case you want to adjust how close the tail follows the player.
Here is what I would try:
tail_delay
, and assign it a specific amount of time.player1
with timestamps (it will be a collection of positions in the end). That object, let's call it player1_positions_record
, will be updated constantly in the infinite loop (this can be a waste of memory - don't save all positions, you only need a few seconds, and older than that you discard).tail_delay
and the player1_positions_record
. That way you'll use a past position of player1
.As mentioned in the comments, this is not a perfect solution but it works:
import pygame
from datetime import datetime, timedelta
pygame.init()
# tail delay in seconds
tail_delay=timedelta(seconds=0.3)
# draw the iwndow
width = 900
height = 1200
window = pygame.display.set_mode((height,width))
# the player class
class player:
def __init__(self,x,y,height,width,color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
self.rect = pygame.Rect(x,y,height,width)
self.speed = 5
def draw(self):
self.rect.topleft = (self.x,self.y)
pygame.draw.rect(window,self.color,self.rect)
# display the player
color = (255,255,255)
player1 = player(180,190,40,40,color)
# bg
bg = pygame.image.load('2.png')
# the colision to determine the direction the player should move
class player:
def __init__(self,x,y,height,width,color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
self.rect = pygame.Rect(x,y,height,width)
self.speed = .9
def draw(self):
self.rect.topleft = (self.x,self.y)
pygame.draw.rect(window,self.color,self.rect)
# display the player
color = (255,255,255)
tailcolor = (176, 58, 46)
player1 = player(180,170,50,50,color)
tail = player(100,170,50,50,tailcolor)
def draw():
window.fill((0,0,0))
window.blit(bg,(0,0))
player1.draw()
tail.draw()
# make movements True
right = False
left = False
up = False
down = False
only_up = False
only_left = False
# get position
pos = True
pos2 = 0
# the main loop
run = True
player1_positions_record=[]
test_time=datetime.now()
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# add current position, and delete the positions that are old
# in 1 second, I counted 270 timestamps approx, so I will cut the timestamps in 500 (don't think we need more than that)
player1_positions_record.append((datetime.now(), (player1.x, player1.y)))
if len(player1_positions_record) > 500:
player1_positions_record = player1_positions_record[-500:]
# now it's time to find the position of the tail. It will be an old position of the player
right_now=datetime.now()
for position in player1_positions_record:
position_timestamp=position[0]
print(type(position_timestamp))
if position[0]>right_now-tail_delay:
tail.y = position[1][1] # second element of the tuple containing the old position
tail.x = position[1][0] # first element
break
# check for key press
keys = pygame.key.get_pressed()
# if down:
# #-- the tail red change directions
# tail.y = player1.y - 80
# # tail.x = player1.x
# if up:
# #-- the tail red change directions
# tail.y = player1.y + 80
# # tail.x = player1.x
# if left:
# #-- the tail red change directions
# tail.y = player1.y
# tail.x = player1.x + 80
# if right:
# #-- the tail red change directions
# tail.y = player1.y
# tail.x = player1.x - 80
#--------------------------------------------------- player movement
if left == False:
if keys[pygame.K_RIGHT]:
if not keys[pygame.K_UP]:
if not keys[pygame.K_DOWN]:
right = True
if right:
left = False
down = False
up = False
player1.x += player1.speed
if right == False:
if keys[pygame.K_LEFT]:
if not keys[pygame.K_UP]:
if not keys[pygame.K_DOWN]:
left = True
if left:
right = False
down = False
up = False
player1.x -= player1.speed
if down == False:
if keys[pygame.K_UP]:
up = True
if up:
down = False
left = False
right = False
player1.y -= player1.speed
if up == False:
if keys[pygame.K_DOWN]:
down = True
if down:
up = False
left = False
right = False
player1.y += player1.speed
#--------------------------------------------------- player movement
# show everything drawn
draw()
pygame.display.update()
pygame.quit()