0

I am working on a game, where you can input the function to a graph, it then draw that graph and a Rocket followes it. My problem is, that while rotating the rocket, it stutters a lot.I've tried rounding and setting the interval of points where the rocket appeares lower, but it didnt help. I'm getting the angle of rotation through math.atan2(dy,dx).

my Code:

import math
import sys
import pygame
import numpy as np

pygame.init()

# variables
background_colour = (255, 255, 255)
screen = pygame.display.set_mode((1920, 1080))
pt_list = []
base_font = pygame.font.SysFont("calibri", 16)
user_text = ""
clock = pygame.time.Clock()
input_rect = pygame.Rect(20, 20, 140, 32)
color_active = (255, 255, 255)
color_passive = (255, 126, 0)
color = color_passive
box_active = False
function_input = user_text
fixed_text_inp_box = "f(x) =  "
coord_list = []
draw = False
black = (0, 0, 0)
drawn = False
coord_index = 0
angle = 0

bg = pygame.image.load("bg1.png")
bg = pygame.transform.scale(bg, (1920, 1080))
rocket = pygame.image.load("rocket-1.png")
rocket = pygame.transform.scale(rocket, (200, 116))


def replace_x(function):
    f = lambda x: eval(function)
    return f


def convert_y(y_coords):
    y_coords = 540 - y_coords
    return y_coords


def convert_x(x_coord):
    x_coord = x_coord + 960
    return x_coord


def get_pt_list(user_inp, fixed_text_box):
    user_inp = user_inp.replace("^", "**")
    user_inp = user_inp.replace("1x", "1*x")
    user_inp = user_inp.replace("2x", "2*x")
    user_inp = user_inp.replace("3x", "3*x")
    user_inp = user_inp.replace("4x", "4*x")
    user_inp = user_inp.replace("5x", "5*x")
    user_inp = user_inp.replace("6x", "6*x")
    user_inp = user_inp.replace("7x", "7*x")
    user_inp = user_inp.replace("8x", "8*x")
    user_inp = user_inp.replace("9x", "9*x")
    user_inp = user_inp.replace("0x", "0*x")
    user_inp = user_inp.replace(")(", ")*(")
    user_inp = user_inp.replace("x(", "x*(")
    user_inp = user_inp.replace("1(", "1*(")
    user_inp = user_inp.replace("2(", "2*(")
    user_inp = user_inp.replace("3(", "3*(")
    user_inp = user_inp.replace("4(", "4*(")
    user_inp = user_inp.replace("5(", "5*(")
    user_inp = user_inp.replace("6(", "6*(")
    user_inp = user_inp.replace("7(", "7*(")
    user_inp = user_inp.replace("8(", "8*(")
    user_inp = user_inp.replace("9(", "9*(")
    user_inp = user_inp.replace("0(", "0*(")
    user_inp = user_inp.replace(")0", ")*0")
    user_inp = user_inp.replace(")1", ")*1")
    user_inp = user_inp.replace(")2", ")*2")
    user_inp = user_inp.replace(")3", ")*3")
    user_inp = user_inp.replace(")4", ")*4")
    user_inp = user_inp.replace(")5", ")*5")
    user_inp = user_inp.replace(")6", ")*6")
    user_inp = user_inp.replace(")7", ")*7")
    user_inp = user_inp.replace(")8", ")*8")
    user_inp = user_inp.replace(")9", ")*9")
    user_inp = user_inp.replace(")x", ")*x")

    f = replace_x(user_inp)

    try:
        for x in np.arange(-32, 32, 0.0625):
            pt_list.append((x, f(x)))
    except (ValueError, SyntaxError, NameError):
        fixed_text_inp_box = "Invalid Function"
        print("wrong")
        return user_text

    for pt in pt_list:
        x = round(convert_x(pt[0] * 30))
        y = round(convert_y(pt[1] * 30))
        coord_list.append((x, y))

    return coord_list


def custom_round(x, base=5):
    return base * round(x/base)


# def draw_func(self, coord_list, animated):
screen.fill(background_colour)
pygame.display.set_caption('Mathe Kreativarbeit')

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        if event.type == pygame.MOUSEBUTTONDOWN:
            if input_rect.collidepoint(event.pos):
                box_active = True
            else:
                box_active = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                box_active = False
            if box_active:
                if event.key == pygame.K_BACKSPACE:
                    if user_text == "Invalid Input":
                        user_text = ""
                    else:
                        user_text = user_text[:-1]
                    pt_list = []
                    coord_list = []
                    draw = False
                elif event.key == pygame.K_RETURN:
                    draw = True
                else:
                    user_text += event.unicode

    screen.blit(bg, (0, 0))

    # draws the coordinate system
    pygame.draw.line(screen, (255, 255, 255), (960, 0), (960, 1080), 2)
    pygame.draw.line(screen, (255, 255, 255), (0, 540), (1920, 540), 2)

    for numbers in range(0, 64):
        pygame.draw.aaline(screen, (255, 255, 255), (numbers * 30, 530), (numbers * 30, 550))

    for numbers in range(0, 36):
        pygame.draw.aaline(screen, (255, 255, 255), (950, numbers * 30), (970, numbers * 30))

    if box_active:
        color = color_active
    else:
        color = color_passive

    pygame.draw.rect(screen, color, input_rect, 2)
    text_surface = base_font.render(fixed_text_inp_box + user_text, False, (255, 255, 255))
    input_rect.w = max(100, text_surface.get_width() + 10)
    screen.blit(text_surface, (input_rect.x + 5, input_rect.centery - 5))

    if len(coord_list) > 1:
        try:
            pygame.draw.aalines(screen, (255, 255, 255), False, coord_list, 3)
        except (ValueError, SyntaxError, NameError, TypeError):
            user_text = "Invalid Input"
    if draw:
        try:
            coord_list = get_pt_list(user_text, fixed_text_inp_box)
            print(coord_list)
            prev_x = coord_list[0]
            for x in coord_list:
                pygame.draw.aaline(screen, (255, 255, 255), prev_x, x)
                pygame.display.flip()
                pygame.time.delay(2)
                prev_x = x
        except (ValueError, SyntaxError, NameError, TypeError):
            user_text = "Invalid Input"
        draw = False
        drawn = True

    if drawn:
        try:
            y1 = int(coord_list[coord_index][1])
            y2 = int(coord_list[coord_index + 1][1])
            x1 = int(coord_list[coord_index][0])
            x2 = int(coord_list[coord_index + 1][0])
            dy = y1 - y2
            dx = x2 - x1
            angle = math.degrees(math.atan2(dy, dx))
            custom_round(angle, 5)
            angle %= 360
            rot_rocket = pygame.transform.rotate(rocket, angle)
            screen.blit(rot_rocket, (int(coord_list[coord_index][0]) - 100, int(coord_list[coord_index][1])))
            pygame.display.flip()
            angle = 0
            coord_index += 10
            pygame.time.delay(10)
        except IndexError:
            coord_index -= 2
            drawn = False

    pygame.display.flip()
    clock.tick(60)
  • See [How do I rotate an image around its center using PyGame?](https://stackoverflow.com/questions/4183208/how-do-i-rotate-an-image-around-its-center-using-pygame/54714144#54714144) – Rabbid76 Apr 04 '22 at 08:51

0 Answers0