Why my raycasting keeps going through walls? - python

here's my code, ignore unused stuff and its overal messiness
import sys, pygame, time, math
pygame.init()
size = width, height = 640, 640
black = 0, 0, 0
screen = pygame.display.set_mode(size)
ball = pygame.image.load("ball.png")
map = pygame.image.load("map.png")
ballrect = ball.get_rect()
ballrect.x = 262
ballrect.y = 582
direction = math.pi
FOV = math.pi / 3
HALF_FOV = FOV / 2
CASTED_ARRAYS = 640
STEP_ANGLE = FOV / CASTED_ARRAYS
MAX_DEPTH = 640
def cast_rays():
start_angle = direction - HALF_FOV
for ray in range(CASTED_ARRAYS):
for depth in range(MAX_DEPTH):
target_x = (ballrect.centerx) - math.sin(start_angle) * depth
target_y = (ballrect.centery) + math.cos(start_angle) * depth
if screen.get_at((int(target_x), int(target_y))) == (223, 113, 38):
pygame.draw.line(screen, (0, 255, 255), (ballrect.centerx, ballrect.centery),
(target_x, target_y))
break
start_angle += STEP_ANGLE
while 1:
screen.blit(map, (0, 0))
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
direction -= 0.1
if keys[pygame.K_RIGHT]:
direction += 0.1
if keys[pygame.K_UP]:
ballrect.centerx += -math.sin(direction) * 5
ballrect.centery += math.cos(direction) * 5
if keys[pygame.K_DOWN]:
ballrect.centerx -= -math.sin(direction) * 5
ballrect.centery -= math.cos(direction) * 5
time.sleep(0.01)
screen.blit(ball, ballrect)
cast_rays()
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
so far, it's behaving this way:
it works, but it doesn't. i've tinkered the numbers, sometimes it gets better adding to the x, to the y, but it doesn't work completely. If you guys wanna try on your computer, here are the files needed for:
(it's tiny)
so, what's going on?

You need to read the color of the map instead of the color of the screen. You draw the lines on the screen, each line "cuts a small piece of the wall:
if screen.get_at((int(target_x), int(target_y))) == (223, 113, 38):
if map.get_at((int(target_x), int(target_y))) == (223, 113, 38):
Alternatively you can draw the lines after casting the rays:
def cast_rays():
targets = []
for ray in range(CASTED_ARRAYS):
angle = direction - HALF_FOV + ray * STEP_ANGLE
s, c = math.sin(angle), math.cos(angle)
for depth in range(MAX_DEPTH):
target = (round(ballrect.centerx - s * depth), round(ballrect.centery + c * depth))
if screen.get_at(target) == (223, 113, 38):
targets.append(target)
break
start = (ballrect.centerx, ballrect.centery)
for target in targets:
pygame.draw.line(screen, (0, 255, 255), start, target)

Related

Pygame: Moving an image around another image in a circular path

I know that there are already some solutions here but unfortunately they did not help me with my problem. I want to move a satellite image around a planet image in a circular path. I know how to move it in a line from left to right but I don't get it how to make the circle. This is my code so far
import pygame
from pygame.locals import *
from sys import exit
from math import sin
from math import cos
player_image = 'dragon-500px.png'
pygame.init()
screen = pygame.display.set_mode((1080, 720), 0, 32)
pygame.display.set_caption("Animate X!")
mouse_cursor = pygame.image.load(player_image).convert_alpha()
image_earth = pygame.image.load('Erde.jpg').convert()
image_earth = pygame.transform.scale(image_earth, (300,300))
image_earth_rect = image_earth.get_rect()
image_earth_rect.center = (540, 360)
radius = 100
center = (540, 360)
direction = pygame.math.Vector2(1,0)
clock = pygame.time.Clock()
speed = 300.0
x = 0 - mouse_cursor.get_width()
y = 10
while True:
time_passed = clock.tick() / 1000.0
moved_distance = time_passed * speed
for event in pygame.event.get():
if event.type == QUIT:
exit()
direction.rotate_ip(4)
direction.normalize_ip()
Satellite_pos = [int(i) for i in center + direction*radius]
screen.fill((255,255,255))
if x > screen.get_width():
x = 0 - mouse_cursor.get_width()
elif y > screen.get_height():
y = 10
screen.blit(mouse_cursor, (x, y))
screen.blit(image_earth, image_earth_rect)
x+=moved_distance
y+= moved_distance
pygame.display.update() ```
Compute the position of the satellite dependent on an angle:
angle = 0
# [...]
while True:
# [...]
center = image_earth_rect.center
Satellite_pos = [center[0] + radius * cos(angle), center[1] + radius * sin(angle)]
angle += 0.01
# [...]

Why my pygame code is crashing with "RecursionError: maximum recursion depth exceeded while calling a Python object"? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I want to put a system of collide on my pygame's rpg and my code is crashing with "RecursionError: maximum recursion depth exceeded while calling a Python object". I tried many things but the error always appears.
My code:
import pygame
from pygame.locals import *
from player import *
class Camera:
def __init__(self, widht, height):
self.rect = pygame.Rect(0, 0, widht, height)
self.widht = widht
self.height = height
self.center = list(self.rect.center)
self.x = self.center[0]
self.y = self.center[1]
def apply(self, entity):
return entity.move(self.rect.topleft)
def update(self, target):
y = -target.rect.y + int(769 / 2)
x = -target.rect.x + int(1024 / 2)
self.rect = pygame.Rect(x, y, self.widht, self.height)
class Level(pygame.sprite.Sprite):
def __init__(self):
self.structure = 0
self.all_blocks = pygame.sprite.Group()
def generer(self):
with open("niveau.txt", "r") as fichier:
structure_niveau = []
for ligne in fichier:
ligne_niveau = []
for sprite in ligne:
if sprite != '\n':
ligne_niveau.append(sprite)
structure_niveau.append(ligne_niveau)
self.structure = structure_niveau
def afficher(self, fenetre, x, y, camX, camY, playerX, playerY):
tailleSprite = 64
self.all_blocks.empty()
#Camera.__init__(self, x, y)
cam = Camera(1024, 768)
grass = pygame.image.load("assets/bloc/grass.png").convert_alpha()
tree = pygame.image.load("assets/bloc/tree_grass.png").convert_alpha()
no_texture = pygame.image.load("assets/bloc/no_texture.png").convert_alpha()
num_ligne = 0
for ligne in self.structure:
num_case = 0
for sprite in ligne:
x = num_case * tailleSprite + camX
y = num_ligne * tailleSprite + camY
sprite_rect = pygame.Rect(x, y, 64, 64)
screenRect = pygame.Rect(x, y, 1088, 836)
aroundPlayer = pygame.Rect(playerX, playerY, playerX + 128, playerY + 128)
if sprite == 'G':
if screenRect.contains(sprite_rect):
fenetre.blit(grass, (x, y))
if aroundPlayer.contains(sprite_rect):
self.all_blocks.add(sprite)
elif sprite == 'T':
if screenRect.contains(sprite_rect):
fenetre.blit(tree, (x, y))
#self.all_blocks.add(sprite)
#print(self.x, self.y)
else:
if screenRect.contains(sprite_rect):
fenetre.blit(no_texture, (x, y))
#print(x, y)
num_case += 1
num_ligne += 1
and main.py:
import pygame
from game import Game
from level import *
pygame.init()
lvl = Level()
WIDHT = 768
HEIGHT = 1024
screen = pygame.display.set_mode((1024, 768))
screen_rect = pygame.Rect(0, 0, HEIGHT, WIDHT)
pygame.display.set_caption("RPG")
game = Game()
cam = Camera(1024, 768)
running = True
lvl.generer()
print(game.player.rect)
print(screen_rect)
clock = pygame.time.Clock()
lvl.afficher(screen, 0, 0, 0, 0, game.player.rect.x, game.player.rect.y)
camPos = 0
while running:
lvl.afficher(screen, 0, 0, camPos, 0, game.player.rect.x, game.player.rect.y)
cam.apply(game.player.rect)
cam.update(game.player)
#print(cam.rect.topleft)
if game.pressed.get(pygame.K_RIGHT):
game.player.move_right()
#print(game.player.rect.x)
if not screen_rect.contains(game.player.rect):
game.player.rect.x -= HEIGHT -60
camPos += -HEIGHT
elif game.pressed.get(pygame.K_LEFT):
game.player.move_left()
#print(game.player.rect.x)
if not screen_rect.contains(game.player.rect):
game.player.rect.x += HEIGHT - 60
camPos += HEIGHT
elif game.pressed.get(pygame.K_DOWN):
game.player.move_down()
#print(game.player.rect.y)
if not screen_rect.contains(game.player.rect):
game.player.rect.y -= WIDHT - 80
elif game.pressed.get(pygame.K_UP):
game.player.move_up()
#print(game.player.rect.y)
if not screen_rect.contains(game.player.rect):
game.player.rect.y += WIDHT - 80
#print(cam.rect.x, cam.rect.y)
#print(cam.rect)
screen.blit(game.player.image, game.player.rect)
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
elif event.type == pygame.KEYDOWN:
game.pressed[event.key] = True
elif event.type == pygame.KEYUP:
game.pressed[event.key] = False
Try one of the following option which will help you to get rid of the error
try to change the algorithm from recursive to iterative
you can change the recursion limit with sys.setrecursionlimit(n) - in python recursion is limited to 999 calls.

creating barrier/buffer between two parts of the screen

I have no idea how to implement this, but I do know how to explain it. What the code is supposed to do is: While the program is running, stop the object moving around the screen from coming off it's designated area. How do I test for collision and reflect the moving object from that blocked off wall?
In relation to my code, I have a grid that makes up most of my screen and a small amount of the screen that holds text. The output of the code I hope to learn is two barriers: 1) for the grid so the moving object doesn't go under the text and 2) for the text so it doesn't print on other part of the screen.
Here is my current code:
import sys
from random import randrange
import pygame as pg
import timeit
import xlrd
# timer
start = timeit.default_timer()
# define main colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
# define trail colors
C1 = (31, 119, 180)
C2 = (174, 199, 232)
C3 = (255, 127, 14)
C4 = (255, 187, 120)
C5 = (44, 160, 44)
C6 = (152, 223, 138)
C7 = (214, 39, 40)
C8 = (255, 152, 150)
C9 = (148, 103, 189)
C10 = (197, 176, 213)
C11 = (140, 86, 75)
C12 = (196, 156, 148)
C13 = (227, 119, 194)
C14 = (247, 182, 210)
C15 = (127, 127, 127)
C16 = (199, 199, 199)
C17 = (188, 189, 34)
C18 = (219, 219, 141)
C19 = (23, 190, 207)
C20 = (158, 218, 229)
# define measurements
WIDTH, HEIGHT, MARGIN = 10, 10, 1
GRIDX, GRIDY = 90, 35
# text
class GridObject(pg.sprite.Sprite):
def __init__(self, pos, grid, *groups):
super().__init__(groups)
# create image from grid
self.grid = grid
self.gridsize = (len(grid[0]), len(grid))
imgsize = self.gridsize[0]*(WIDTH+MARGIN), self.gridsize[1]*(HEIGHT+MARGIN)
self.image = pg.Surface(imgsize, flags=pg.SRCALPHA)
self.image.fill((0, 0, 0, 0))
col = (1, 1, 1)
for c in range(self.gridsize[0]):
for r in range(self.gridsize[1]):
if self.grid[r][c] == 1:
rect = [(MARGIN + WIDTH) * c + MARGIN, (MARGIN + HEIGHT) * r + MARGIN, WIDTH, HEIGHT]
pg.draw.rect(self.image, col, rect)
self.rect = self.image.get_rect(center=pos)
self.vel = pg.math.Vector2(8, 0).rotate(randrange(360))
self.pos = pg.math.Vector2(pos)
def update(self, boundrect, hitGrid, hitList):
self.pos += self.vel
self.rect.center = self.pos
if self.rect.left <= boundrect.left or self.rect.right >= boundrect.right:
self.vel.x *= -1
if self.rect.top <= boundrect.top or self.rect.bottom >= boundrect.bottom:
self.vel.y *= -1
# align rect to grid
gridpos = round(self.rect.x / (WIDTH+MARGIN)), round(self.rect.y / (HEIGHT+MARGIN))
self.rect.topleft = gridpos[0] * (WIDTH+MARGIN), gridpos[1] * (HEIGHT+MARGIN)
# increment touched filed
global max_hit
max_hit = 0
oldHitList = hitList[:]
hitList.clear()
for c in range(self.gridsize[0]):
for r in range(self.gridsize[1]):
p = gridpos[1] + r, gridpos[0] + c
if p in oldHitList:
hitList.append(p)
elif self.grid[r][c] == 1:
if p[0] < len(hitGrid) and p[1] < len(hitGrid[p[0]]):
hitList.append(p)
if p not in oldHitList:
hitGrid[p[0]][p[1]] +=1
max_hit = max(max_hit, hitGrid[p[0]][p[1]])
ballGrid = [[0, 1, 1, 1, 0],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[0, 1, 1, 1, 0]]
def main():
screen = pg.display.set_mode((GRIDX * (WIDTH+MARGIN) + MARGIN, GRIDY * (HEIGHT+MARGIN) + 50))
# Set title of screen
pg.display.set_caption("Ball With Grid")
clock = pg.time.Clock()
sprite_group = pg.sprite.Group()
ball = GridObject((screen.get_width()//2, screen.get_height()//2), ballGrid, sprite_group)
hitGrid = [[0 for i in range(GRIDX)] for j in range(GRIDY)]
hitList = []
done = False
# create timer event
change_delay = 500 # 1/2 second(s)
change_event = pg.USEREVENT + 1
pg.time.set_timer(change_event, change_delay)
angles = [0, 45, 90, 135, 180, 225, 270, 315]
degreeChange = 0
print("REMINDER: Day 0 is the first day of the simulation.")
#text displayed at the bottom of the screen
# get day and temp from excel file
book = xlrd.open_workbook('daysTemp.xlsx')
sheet = book.sheet_by_index(0)
temps = []
days = []
day = 0
for k in range(1,sheet.nrows):
temps.append(int(sheet.row_values(k)[-2]))
days.append(int(sheet.row_values(k)[-1]))
d = ("day: ", str(days[0]))
t = ("temp: ", str(temps[0]))
print("day: ", days[day])
print("temp: ", temps[days[day]])
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
# receive timer event
if event.type == change_event:
degreeChange += 1
if degreeChange == 1:
degreeChange = degreeChange - 5
day += 1
print("day: ", days[day])
print("temp: ", temps[days[day]])
d = ("day: ", str(days[day]))
t = ("temp: ", str(temps[day]))
if day >= 365:
pg.quit()
for i in ball.vel:
# change angle by 45°
ball.vel = ball.vel.rotate(angles[randrange(0, len(angles))])
#print("angle: ", i)
if event.type == pg.KEYDOWN and event.key == pg.K_SPACE:
hitGrid = [[0 for i in range(GRIDX)] for j in range(GRIDY)]
screen.fill(BLACK)
# Draw the grid and add values to the cells
for row in range(GRIDY):
for column in range(GRIDX):
rect = [(MARGIN + WIDTH) * column + MARGIN, (MARGIN + HEIGHT) * row + MARGIN, WIDTH, HEIGHT]
colorlist = [WHITE,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20, WHITE]
color = colorlist[min(len(colorlist)-1, hitGrid[row][column])]
pg.draw.rect(screen, color, rect)
# stops program if the max number is reached
sprite_group.update(screen.get_rect(), hitGrid, hitList)
if max_hit >= 21:
print("\n"+"Program terminated.")
done = True
stop = timeit.default_timer()
end = stop-start
print("Time (in seconds):", end)
sprite_group.draw(screen)
# create a font object.
font = pg.font.Font('freesansbold.ttf', 24)
# create a text suface object,
text = font.render("".join(d) + ", " + "".join(t), True, GREEN, BLACK)
# create a rectangular text object
textRect = text.get_rect()
# set the center of the rectangular object.
textRect.center = ((GRIDX * (WIDTH+MARGIN) + 50) // 2, (GRIDY * (HEIGHT+MARGIN) + 50))
screen.blit(text, textRect)
pg.display.update()
clock.tick(60)
if __name__ == '__main__':
pg.init()
main()
pg.quit()
sys.exit()
Well it appears that you have almost done it. In update() you have
if self.rect.left <= boundrect.left or self.rect.right >= boundrect.right:
self.vel.x *= -1
if self.rect.top <= boundrect.top or self.rect.bottom >= boundrect.bottom:
self.vel.y *= -1
which is perfect, the only problem is boundrect seems to be the whole screen
sprite_group.update(screen.get_rect(), hitGrid, hitList)
All you need to do is pass a rect that doesnt include the bottom part.
bounding_box = pg.Rect(0,0,(GRIDX * (WIDTH+MARGIN) + MARGIN,GRIDY * (HEIGHT+MARGIN))
#this has same width and height as screen but doesnt have +50 for y
then update with new rect
sprite_group.update(bounding_box, hitGrid, hitList)
As for the text, it looks like it can only be in one place so should be fine

How create a simulation (pendulum, projectile motion) in pygame

I created a program that generates the placement of the pendulum, length, position of the ball, velocity, angles, and trajectory. The program's task is to find a solution where the ball can land safely through a 'cave'. The pendulum is inside an 85.75 by 66.75 area, length < 65, ball radius = 1.25
I want to create a simulation of the experiment in pygame, that will run my 1st program to generate all the parameters, and then display the solution and path the ball will follow. I have spent the past couple days learning pygame, but can't figure out how to 'transfer' my first program. Ive looked at other pendulum simulators, and tried to change it to work for my experiment, but I got lost and decided to come to StackOverflow for advice. If anyone could show me where I went wrong in making the simulation, it would be very appreciated.
first program
import math as m
import numpy as np
# Variables
c = 28.5
Wx = 20
Wy = 30
d = 85.75
f = 66.75
g = 385.826772
ay = -g
# Calculations
for theta in np.arange(1, 90, .01):
l = Wx + (m.tan(m.radians(theta)) * (f - Wy))
if Wx <= l <= d:
phi = 90 - theta
v = (d - l) / m.sin(m.radians(phi))
vc = v - 1.25
if (f - Wy) <= v <= 65:
h = f - (m.cos(m.radians(phi)) * v)
a = v * m.sin(m.radians(theta))
b = v * m.cos(m.radians(theta))
by = f - b
bx = l - a
if h <= f and by <= c:
vel = m.sqrt((2 * g) * (h - by)) * .95
velx = vel * m.cos(m.radians(theta))
vely = vel * m.sin(m.radians(theta))
y = (-vely**2) / (2 * ay)
Ymax = y + by
if m.isclose(Ymax, c, abs_tol= .01):
t1 = -vely / ay
t2 = m.sqrt((2 * Ymax) / -ay)
T = t1 + t2
x = velx * T
print(' l: {0} v: {1} vc: {2} h: {3}\n bx: {4} by: {5}\n vel: {6} velx: {7} vely: {8}\n y: {9} Ymax: {10} x: {11} T: {12}\n theta: {13} phi: {14}\n'
.format(l, v, vc, h, bx, by, vel, velx, vely, y, Ymax, x, T, theta, phi))
Simulator
import pygame
import numpy as np
import math as m
from math import pi
# Tarzan Variables
c = 28.5
Wy = 30
Wx = 20
d = 85.75
f = 66.75
# Colors
black = (0, 0, 0)
red = (255, 0, 0)
white = (255, 255, 255)
green = (0, 255, 0)
# Pygame Variables
theta = 0
v = 0
vel = 0
acc = 0
# Start Pygame
width, height = 900, 700
pygame.init()
background = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
# Tarzan
class Pendulum(object):
def __init__(self, XY, l, radius):
self.x = XY[0]
self.y = XY[1]
self.l = l
self.radius = radius
def draw(self, bg):
pygame.draw.line(bg, white, (self.l, 0), (self.x, self.y), 4)
pygame.draw.circle(bg, red, (self.x, self.y), self.radius)
pygame.draw.line(bg, green, (Wx, height), (Wx, (height - Wy)), 4)
# pygame.draw.circle(bg, white, (self.l, 0), int(v)) --- to see if pendulum is following an arc
def theta_v():
v = m.sqrt(m.pow(pendulum.x - (width / 2), 2) + m.pow(pendulum.y, 2))
theta = m.asin(((pendulum.x - (width / 2)) / v))
return theta, v
def get_path(theta, v):
pendulum.x = round(pendulum.l + (v * m.sin(theta)))
pendulum.y = round(v * m.cos(theta))
pendulum.l = pendulum.x - (v * m.sin(m.radians(theta)))
def redraw():
background.fill(black)
pendulum.draw(background)
pygame.display.update()
pendulum = Pendulum((75, 67), 500, 15)
# Close Pygame
stop = False
acceleration = False
while not stop:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
stop = True
if event.type == pygame.MOUSEBUTTONDOWN:
pendulum = Pendulum(pygame.mouse.get_pos(), 500, 15)
theta, v = theta_v()
acceleration = True
if acceleration:
acc = -.005 * m.sin(theta)
vel += acc
vel *= .995
theta += vel
get_path(theta, v)
print(pendulum.x, pendulum.y, (theta * (180 / pi)), v, vel, pendulum.l)
redraw()
pygame.quit()
quit()
I suppose you wanted this program to create a hanging pendulum swinging around correctly. There were a few things wrong with your code:
In order to calculate your pendulum.l value, you converted theta to radians first. As your theta value was already in radians, This was absolutely not nessary, and makes your pendulum.l value almost not change.
When you now execute your code, you might see that the attachment point of the pendulum is changing. This is because you are changing pendulum.l, and use it for drawingg the pendulum at the same time. This can be easily fixed by saving your first pendulum.l value, and use that value to draw the pendulum.
Your program keeps attampting to move the pendulum forever, giving sometimes unexpected results. You should add some way to figure out whether the pendulum is still moving (probably by chenking whether one of the variables is not changing enough - I had not enough time to figure it out)
Rounding your x and y values causes a buildup if rounding errors on the end, making the pendulium coming to a stop while still being tilted a bit. You can just round while drawing the penduluim to fix this.
The entire code should look like this:
import time
import pygame
import numpy as np
import math as m
from math import pi
# Tarzan Variables
c = 28.5
Wy = 30
Wx = 20
d = 85.75
f = 66.75
# Colors
black = (0, 0, 0)
red = (255, 0, 0)
white = (255, 255, 255)
green = (0, 255, 0)
# Pygame Variables
theta = 0
v = 0
vel = 0
acc = 0
# Start Pygame
width, height = 900, 700
pygame.init()
background = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
# Tarzan
class Pendulum(object):
def __init__(self, XY, l, radius):
self.x = XY[0]
self.y = XY[1]
self.l = l
self.lfixed = l
self.radius = radius
def draw(self, bg):
pygame.draw.line(bg, white, (self.lfixed, 0), (self.x, self.y), 4)
pygame.draw.circle(bg, red, (round(self.x), round(self.y)), self.radius)
pygame.draw.line(bg, green, (Wx, height), (Wx, (height - Wy)), 4)
# pygame.draw.circle(bg, white, (self.l, 0), int(v)) --- to see if pendulum is following an arc
def theta_v():
v = m.sqrt(m.pow(pendulum.x - (width / 2), 2) + m.pow(pendulum.y, 2))
theta = m.asin(((pendulum.x - (width / 2)) / v))
return theta, v
def get_path(theta, v):
pendulum.x = pendulum.l + (v * m.sin(theta))
pendulum.y = v * m.cos(theta)
pendulum.l = pendulum.x - (v * m.sin((theta)))
def redraw():
background.fill(black)
pendulum.draw(background)
pygame.display.update()
pendulum = Pendulum((75, 67), 500, 15)
# Close Pygame
stop = False
acceleration = False
while not stop:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
stop = True
if event.type == pygame.MOUSEBUTTONDOWN:
pendulum = Pendulum(pygame.mouse.get_pos(), 500, 15)
theta, v = theta_v()
acceleration = True
if acceleration:
acc = -.005 * m.sin(theta)
vel += acc
vel *= .995
theta += vel
get_path(theta, v)
print(pendulum.x, pendulum.y, (theta * (180 / pi)), v, vel, pendulum.l)
redraw()
time.sleep(0.1)
pygame.quit()
quit()

moving an object in a circular path [duplicate]

This question already has answers here:
Why it doesn't spin in a circle? And how to fix it?
(1 answer)
Ship moves up and left faster than down and right when rotating in pygame
(1 answer)
Closed 2 years ago.
This question is related to
My code is below. You can use any small image for my images.
import sys, os, pygame, itertools
from math import sin,cos,pi, radians
from pygame.locals import *
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (50,50) #Set window position
pygame.init()
clock = pygame.time.Clock()
FPS = 1000
SCREENW = 800 #screen width
SCREENH = 740 #screen height
BLACK = (0, 0, 0)
BLUE = (0, 0, 255)
ORANGE = (128, 100, 30)
FONT1= "Cookie-Regular.ttf"
SCREEN = pygame.display.set_mode((SCREENW, SCREENH), 0, 32) #display screen
clock = pygame.time.Clock()
#-------------------------------------------------------------------------------
def maketext(msg,fontsize, colour = ORANGE, font = FONT1):
mafont = pygame.font.Font(font, fontsize)
matext = mafont.render(msg, True, colour)
matext = matext.convert_alpha()
return matext
#-------------------------------------------------------------------------------
def print_info():
""""""
textcos = maketext(str(round(obj.rect.x, 2)) + " " + str(round(obj.rect.y, 2)), 30)
SCREEN.blit(textcos, (obj.rect.x, obj.rect.y + 30))
#-------------------------------------------------------------------------------
class object_factory(pygame.sprite.Sprite):
def __init__(self, imagelist, xpos, ypos, speedx = 0, speedy = 0, value = 0):
"""Constructor"""
pygame.sprite.Sprite.__init__(self)
self.name = ""
self.frame = 0
self.imagelist = imagelist
self.image = imagelist[self.frame]
self.mask = pygame.mask.from_surface(self.image) # pixelmask
self.rect = self.image.get_rect()
self.rect.x = xpos
self.rect.y = ypos
#self.speedx = speedx
#self.speedy = speedy
self.timer = 0
self.timerlimit = 10
#----------------------------------------------------------------------
#def move(self): # wallsprites, Herosprite, looptime
#self.rect.x += self.speedx
#self.rect.y += self.speedy
#----------------------------------------------------------------------
def update(self):
""""""
self.image = self.imagelist[self.frame]
if self.timer >= self.timerlimit:
self.frame += 1
if self.frame >= len(self.imagelist):
self.frame = 0
self.timer = 0
self.timer += 1
plat = pygame.image.load("plt0.png").convert_alpha()
star = pygame.image.load("gemp0.png").convert_alpha()
#box = pygame.image.load("crateB.png").convert_alpha()
platforms = pygame.sprite.Group()
boxes = pygame.sprite.Group()
rotcenx = SCREENW/2
rotceny = SCREENH/2
radius = 200
angle = radians(90) #pi/4 # starting angle 45 degrees
omega = radians(5) #Angular velocity
m = rotcenx + radius * cos(angle) #Starting position x
n = rotceny - radius * sin(angle) #Starting position y
for _ in itertools.repeat(None, 1):
madyax = SCREENW/2
madyay = SCREENH/2
araya = 200
konaya = radians(180) #pi/4 # starting angle 45 degrees
konika_pravegaya = radians(5) #Angular velocity
a = madyax + (araya * cos(konaya)) #Starting position x
b = madyay - (araya * sin(konaya)) #Startinh position y
plat = object_factory([plat], a, b)
plat.araya = araya
plat.konaya = konaya
plat.kp = konika_pravegaya
platforms.add(plat)
while True:
ms = clock.tick(FPS) # milliseconds passed since last frame
#looptime = milliseconds / 1000.0 # seconds passed since last frame
SCREEN.fill((BLACK))
pygame.draw.circle(SCREEN, BLUE, (SCREENW / 2, SCREENH / 2), 5)
##-----------------------------------------------------------
SCREEN.blit(star, (m, n)) # Draw current x,y
angle = angle + omega # New angle, we add angular velocity
m = m + radius * omega * cos(angle + pi / 2) # New x
n = n - radius * omega * sin(angle + pi / 2) # New y
##-----------------------------------------------------------
# show object anchored to center of rotation
pygame.draw.line(SCREEN, ORANGE, (rotcenx, rotceny), (m, n))
text = maketext(str(radius), 30)
SCREEN.blit(text, (m, n - 40))
text = maketext((str(round(m, 2)) + " " + str(round(n, 2))), 30)
SCREEN.blit(text, (m, n + 40)) # Draw current x,y
##------------------------------------------------------------------
for plat in platforms:
plat.konaya = plat.konaya + plat.kp
plat.rect.x = plat.rect.x + plat.araya * plat.kp * cos(plat.konaya + pi / 2)
plat.rect.y = plat.rect.y - plat.araya * plat.kp * sin(plat.konaya + pi / 2)
##------------------------------------------------------------------------
pygame.draw.line(SCREEN, ORANGE, (madyax, madyay), (plat.rect.x, plat.rect.y))
platforms.update()
platforms.draw(SCREEN)
pygame.event.pump()
keys = pygame.key.get_pressed()
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
pygame.quit()
sys.exit()
pygame.display.update()
pygame.time.wait(100)
Why does the code work when used outside a class and NOT when in? I simply can't find what I have done wrong.
Please don't ask me to read any Google documents or search on the Internet as I am posting after doing so and NOT finding an answer to my question. I am NOT an expert in math and would only like to know a solution to this problem. Please help.
Link to video is below
http://youtu.be/0oRDX246aj8

Categories