Python point curves

Viewed 153

I would like to create a game in python but I need a thought provoking impulse, how I can draw a point, which draws a line behind him/a trail, so far, so good, I have no idea how to make my point not just moving in the 4 directions, I want him to move forward on his own and the user should steer left and right.


Missing is:

• The trail of my point (later I have to check, if another sprite touches it)
• The "curvy" moving


My current code:

import pygame
import os

pygame.init()
width, height = 970, 970
screen = pygame.display.set_mode((width, height))
h_center = ((height / 2) - 4)
w_center = ((width / 2) - 4)


class Point(pygame.sprite.Sprite):
    def __init__(self):
        self.image = pygame.image.load(os.path.join("assets", "point.png"))
        self.x = (width / 2)
        self.y = (height / 2)
        self.speed = 5
        self.direction = 3  # 1:north ; 2:east ; 3:south ; 4:west

    def handle_keys(self):
        key = pygame.key.get_pressed()
        dist = 1
        if key[pygame.K_DOWN]:
            self.direction = 3
        elif key[pygame.K_UP]:
            self.direction = 1
        if key[pygame.K_RIGHT]:
            self.direction = 2
        elif key[pygame.K_LEFT]:
            self.direction = 4

    def move(self):
        if self.direction == 1:
            self.y -= self.speed
        if self.direction == 2:
            self.x += self.speed
        if self.direction == 3:
            self.y += self.speed
        if self.direction == 4:
            self.x -= self.speed

    def draw(self, surface):
        surface.blit(self.image, (self.x, self.y))


def main():
    point = Point()
    clock = pygame.time.Clock()
    background = pygame.image.load('backgroundborder.png').convert()
    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                running = False

        point.handle_keys()
        point.move()
        screen.fill((0, 0, 0))
        screen.blit(background, (0, 0))
        point.draw(screen)

        pygame.display.update()

        clock.tick(40)


if __name__ == '__main__':
    main()

Please assist

1 Answers

Two things:

  • Use a list to store the trail. It's just a list of previous positions.
  • Use the arrow keys to adjust speed, not direction

I also added a few lines of code so the dot stays on the screen. The dot.png is just a black dot 20x20 pixels.

Here's the updated code:

import pygame
import os

pygame.init()
width, height = 970, 970
screen = pygame.display.set_mode((width, height))
h_center = ((height/2) - 4)
w_center = ((width/2) - 4)

trail=[None]*50 # trail has 50 dots
trailimage = pygame.image.load('dot.png')

class Point(pygame.sprite.Sprite):
    def __init__(self):
        self.image = pygame.image.load('dot.png')
        self.x = (width/2)
        self.y = (height/2)
        self.speed = {'x':0, 'y':0}
        self.direction = 3  # 1north ; 2east ; 3south ; 4west

    def handle_keys(self):
        key = pygame.key.get_pressed()
        dist = 1
        if key[pygame.K_DOWN]:
            self.speed['y']+=0.25
        elif key[pygame.K_UP]:
            self.speed['y']-=0.25
        if key[pygame.K_RIGHT]:
            self.speed['x']+=0.25
        elif key[pygame.K_LEFT]:
            self.speed['x']-=0.25

    def move(self):
        self.y += self.speed['y']
        self.x += self.speed['x']
        # wrap to other side of screen
        if self.x > width: self.x = (self.x - width)
        elif self.x < 0: self.x = (width + self.x)
        if self.y > height: self.y = (self.y - height)
        elif self.y < 0: self.y = (height + self.y)

    def draw(self, surface):
        surface.blit(self.image, (self.x, self.y))


def main():
    point = Point()
    clock = pygame.time.Clock()
    #background = pygame.image.load('backgroundborder.png').convert()
    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                running = False

        point.handle_keys()
        point.move()
        screen.fill((200, 200, 200))
        #screen.blit(background, (0, 0))
        for d in trail:
            if d: screen.blit(trailimage, d)
        del trail[0]  # remove last point in trail
        trail.append((point.x,point.y))  # append this position
            
        point.draw(screen)        

        pygame.display.update()

        clock.tick(40)

if __name__ == '__main__':
    main()

To make the controls more like CurveFever, I updated the code so the left \ right keys adjust the travel direction (in degrees). The speed is constant.

Here is the updated code:

import pygame
import os
import math

pygame.init()
width, height = 970, 970
screen = pygame.display.set_mode((width, height))
h_center = ((height/2) - 4)
w_center = ((width/2) - 4)

trail=[None]*50 # trail has 50 dots
trailimage = pygame.image.load('dot.png')
speed = 8 # constant

class Point(pygame.sprite.Sprite):
    def __init__(self):
        self.image = pygame.image.load('dot.png')
        self.x = (width/2)
        self.y = (height/2)
        self.speed = {'x':0, 'y':0}
        self.deg = -90 # up, direction in degrees

    def handle_keys(self):
        key = pygame.key.get_pressed()
        dist = 1
        if key[pygame.K_RIGHT]:
            self.deg+=2
        elif key[pygame.K_LEFT]:
            self.deg-=2
        self.speed['x'] = speed*math.cos(math.radians(self.deg))
        self.speed['y'] = speed*math.sin(math.radians(self.deg))

    def move(self):
        self.y += self.speed['y']
        self.x += self.speed['x']
        # wrap to other side of screen
        if self.x > width: self.x = (self.x - width)
        elif self.x < 0: self.x = (width + self.x)
        if self.y > height: self.y = (self.y - height)
        elif self.y < 0: self.y = (height + self.y)

    def draw(self, surface):
        surface.blit(self.image, (self.x, self.y))


TrailTrim = False # set True for constant trail length

def main():
    point = Point()
    clock = pygame.time.Clock()
    #background = pygame.image.load('backgroundborder.png').convert()
    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                running = False

        point.handle_keys()
        point.move()
        screen.fill((200, 200, 200))  # clear screen
        #screen.blit(background, (0, 0))
        for d in trail:
            if d: screen.blit(trailimage, d)
        if (TrailTrim): del trail[0]   # delete trail end
        trail.append((point.x,point.y))  # add current postiion
            
        point.draw(screen) # draw current point

        pygame.display.update()

        clock.tick(40)  # 40 FPS


if __name__ == '__main__':
    main()
Related