Ошибочная физика Pymunk с PygamePython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Ошибочная физика Pymunk с Pygame

Сообщение Anonymous »

Я использую Pymunk и Pygame для создания платформера на основе физики, используя мяч (подумайте о играх Red Ball Flash). Я не эксперт по Pymunk, и мое текущее использование не работает: < /p>
При вводе (нажатие A или D) мяч, по -видимому, колеблется влево и вправо вместо того, чтобы катиться в направлении, в котором вы нажимаете. Увеличение силы импульса только делает это колебание более неустойчивым, и иногда заставляет мяч двигаться влево и летать? При необходимости я могу отправить кадры того, как это выглядит. Кажется, никто не работает. Изменение силы/импульса делает поведение более неустойчивым.
Ниже приведен минимальный воспроизводимый пример, который я сделал, используя некоторые из моего кода проекта:
import pygame
import pymunk
import sys

# Initialize pygame and create window
pygame.init()
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Minimal Pymunk Ball Example")
clock = pygame.time.Clock()

# Create pymunk space and set gravity
space = pymunk.Space()
space.gravity = (0, 900) # Positive y is downward in pygame

# Collision types
BALL = 1
GROUND = 2

# Track ground contact for jumping
player_grounded = False

# Ground collision handler
def begin_collision(arbiter, space, data):
global player_grounded
player_grounded = True
return True

def separate_collision(arbiter, space, data):
global player_grounded
player_grounded = False
return True

# Set up collision handlers
handler = space.add_collision_handler(BALL, GROUND)
handler.begin = begin_collision
handler.separate = separate_collision

# Create ball physics object
def create_ball(space, position):
mass = 5.0
radius = 20
moment = pymunk.moment_for_circle(mass, 0, radius)
body = pymunk.Body(mass, moment)
body.position = position

# Set natural damping to prevent excessive sliding
body.damping = 0.85

shape = pymunk.Circle(body, radius)
shape.elasticity = 0.0
shape.friction = 0.5
shape.collision_type = BALL

space.add(body, shape)
return body, shape

# Create static platforms
def create_segment(space, p0, p1, thickness):
body = pymunk.Body(body_type=pymunk.Body.STATIC)
shape = pymunk.Segment(body, p0, p1, thickness)
shape.friction = 0.9
shape.elasticity = 0.0
shape.collision_type = GROUND
space.add(body, shape)
return body, shape

# Create level
def create_level(space):
# Ground
create_segment(space, (0, 500), (800, 500), 4)

# Slope
create_segment(space, (500, 500), (700, 400), 4)

# Platform
create_segment(space, (700, 400), (800, 400), 4)

# Create physics objects
create_level(space)
ball_body, ball_shape = create_ball(space, (100, 450))

# Movement parameters
MOVE_IMPULSE = 50.0 # Horizontal impulse strength
JUMP_IMPULSE = 300.0 # Vertical jump impulse
MAX_SPEED = 250.0 # Maximum horizontal speed
can_jump = True

# Main game loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False

# Handle input - IMPULSE BASED MOVEMENT
keys = pygame.key.get_pressed()

# Apply horizontal impulses for movement
if keys[pygame.K_LEFT] and ball_body.velocity.x > -MAX_SPEED:
# Apply impulse to instantly change momentum
ball_body.apply_impulse_at_local_point((-MOVE_IMPULSE, 0), (0, 0))

if keys[pygame.K_RIGHT] and ball_body.velocity.x < MAX_SPEED:
ball_body.apply_impulse_at_local_point((MOVE_IMPULSE, 0), (0, 0))

# Apply impulse for jumping
if keys[pygame.K_SPACE] and player_grounded and can_jump:
ball_body.apply_impulse_at_local_point((0, -JUMP_IMPULSE), (0, 0))
can_jump = False

# Reset jump flag when space key is released
if not keys[pygame.K_SPACE]:
can_jump = True

# Cap horizontal speed if needed
if abs(ball_body.velocity.x) > MAX_SPEED:
ball_body.velocity = pymunk.Vec2d(
MAX_SPEED * (1 if ball_body.velocity.x > 0 else -1),
ball_body.velocity.y
)

# Update physics
dt = 1/60.0
space.step(dt)

# Clear screen and draw
screen.fill((0, 0, 0))

# Draw ground and platforms (white)
for shape in space.shapes:
if isinstance(shape, pymunk.Segment):
a = shape.body.local_to_world(shape.a)
b = shape.body.local_to_world(shape.b)
pygame.draw.line(screen, (255, 255, 255),
(int(a.x), int(a.y)), (int(b.x), int(b.y)),
int(shape.radius * 2))

# Draw ball (red)
ball_pos = int(ball_body.position.x), int(ball_body.position.y)
pygame.draw.circle(screen, (255, 0, 0), ball_pos, int(ball_shape.radius))

# Debug info
try:
font = pygame.font.SysFont(None, 24)
debug_text = f"Velocity: ({int(ball_body.velocity.x)}, {int(ball_body.velocity.y)}) | Grounded: {player_grounded}"
text_surf = font.render(debug_text, True, (255, 255, 255))
screen.blit(text_surf, (10, 10))
except:
pass # Skip debug text if font fails

pygame.display.flip()
clock.tick(60)

# Clean exit
pygame.quit()
sys.exit()


Подробнее здесь: https://stackoverflow.com/questions/795 ... ith-pygame
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»