Объект не добавляется в пространство в pymunk

Я пытаюсь написать программу, используя pymunk и pygame. Программа (на данный момент) представляет собой просто вождение автомобиля с некоторыми препятствиями. Я пытаюсь использовать pymunk, чтобы проверить, столкнулись ли машина и какое-либо препятствие, и если они это сделают, у меня будет вызвана какая-то другая функция. Проблема, с которой я сталкиваюсь, заключается в том, что машина и / или препятствия, похоже, не добавляются в пространство.

Вот код, который я запускаю в данный момент, мои извинения за небрежность.

Спасибо

Редактировать: Моя цель - использовать pymunk для обнаружения столкновений между препятствиями и автомобилем, чтобы вернуть что-то вроде «игра окончена». Проблема в том, что я не могу сказать, добавляются ли препятствия и/или автомобиль в пространство pymunk.

import pygame as pg
import pymunk
import random
import numpy as np

pg.init()

display_width = 1500
display_height = 1000

black = (0, 0, 0)
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
yellow = (255, 255, 100)

gameDisplay = pg.display.set_mode((display_width, display_height))
clock = pg.time.Clock()

carImg = pg.image.load('photoshop_car.jpg')
carImg.set_colorkey(black)

rectangles = []

space = pymunk.Space()

def draw_car(x, y):
    pg.draw.circle(gameDisplay, blue, (x, y), 25)

def forward_movement_x(theta_degrees, movement_speed, currentx):

    theta_radians = theta_degrees * (np.pi / 180)
    delta_x = movement_speed * np.sin(theta_radians)
    return delta_x

def forward_movement_y(theta_degrees, movement_speed, currenty):
    theta_radians = theta_degrees * (np.pi / 180)
    delta_y = movement_speed * np.cos(theta_radians)
    return delta_y

def draw_obs(num_obs):
    for i in range(num_obs):
        obstaclex = random.randrange(0, display_width)
        obstacley = random.randrange(0, display_height)
        obstacle_width = random.randrange(50, 75)
        obstacle_height = random.randrange(50, 75)
        rectangles.append((obstaclex, obstacley, obstacle_width, obstacle_height))
        return rectangles

def obs_to_space(space):
    for i in rectangles:
        body = pymunk.Body(body_type = pymunk.Body.STATIC)
        obstacle_in_space = pymunk.Poly.create_box(body, size = (i[0], i[1]))
        body.position = (i[0], display_height - i[1])
        space.add(obstacle_in_space)

def car_to_space(x, y):
    mass = 10
    radius = 25
    moment = pymunk.moment_for_circle(mass, 0, radius)
    body = pymunk.Body(mass, moment)
    body.position = (x, y)
    shape = pymunk.Circle(body, radius)
    space.add(body, shape)

def coll_begin(arbiter, space, data):
    print("begin")
    return True

def coll_pre(arbiter, space, data):
    print("pre")
    return True

def coll_post(arbiter, space, data):
    print("pre")


def coll_separate(arbiter, space, data):
    print("pre")


def game_loop():
    gameExit = False
    draw_obs(5)

    x = (display_width * .5)
    y = (display_height * .5)
    car_rotation = 0
    rotate_speed = 0
    car_speed = 10
    car_direction = True

    obs_to_space(space)

    while not gameExit:

        gameDisplay.fill(pg.Color("black"))

        for i in range(len(rectangles)):
            pg.draw.rect(gameDisplay, red, rectangles[i])

        for event in pg.event.get():
            if event.type == pg.QUIT:
                gameExit = True
            if event.type == pg.KEYDOWN:
                if event.key == pg.K_LEFT:
                    rotate_speed = 5
                if event.key == pg.K_RIGHT:
                    rotate_speed = -5
            if event.type == pg.KEYUP:
                if event.key == pg.K_LEFT or event.key == pg.K_RIGHT:
                    rotate_speed = 0

        car_rotation = car_rotation + rotate_speed

        x = x - forward_movement_x(car_rotation, car_speed, x)
        y = y - forward_movement_y(car_rotation, car_speed, y)
        x = int(x)
        y = int(y)

        car_to_space(x, y)

        draw_car(x, y)

        pg.display.update()
        clock.tick(30)

game_loop()
pg.quit()
quit()

person Joe Granlie    schedule 12.04.2018    source источник


Ответы (2)


Причина, по которой вы не видите машину, заключается в том, что вы звоните gameDisplay.fill(pg.Color("black")) после того, как нарисовали машину.

Также обратите внимание, что вы вызываете много кода внутри цикла while, чего быть не должно. Например. вы перерисовываете черный фон в каждом цикле.

Вот некоторые вещи, которые вы должны передвигать. Если вы сомневаетесь, поместите операторы печати в функции, чтобы увидеть, как часто они вызываются.

def game_loop():
    gameExit = False
    draw_obs(5)

    x = int(display_width * .5)
    y = int(display_height * .5)
    car_rotation = 0
    rotate_speed = 0
    car_speed = 10
    car_direction = True

    gameDisplay.fill(pg.Color("black"))
    obs_to_space(space)
    draw_car(x, y)

    for i in range(len(rectangles)):
        pg.draw.rect(gameDisplay, red, rectangles[i])

    while not gameExit:
        ...

Я не буду расшифровывать код, чтобы увидеть, действительно ли добавляются препятствия, но вы можете напечатать space._get_shapes(), чтобы увидеть, какие фигуры находятся в пространстве.

person andyhasit    schedule 12.04.2018
comment
Проблема не в том, что машину не рисуют, а в том, что она есть. Все работает как надо, кроме аспекта pymunk. Моя цель — использовать pymunk для обнаружения столкновений между препятствиями и автомобилем, чтобы вернуть что-то вроде окончания игры. Проблема в том, что я не могу сказать, добавляются ли препятствия и/или автомобиль в пространство pymunk. - person Joe Granlie; 12.04.2018

Есть несколько проблем, которые мешают коду работать так, как вы задумали.

  1. obs_to_space добавляет в пространство только форму, а не тело.

    Исправить, добавив тело.

  2. car_to_space вызывается каждый кадр. Это означает, что в каждом кадре в пространство добавляется новый кузов и форма автомобиля. (так что через какое-то время пространство будет содержать 100 автомобилей :)

    Вы можете исправить это, добавив форму автомобиля один раз в начале, а затем обновляя ее положение на каждой итерации в цикле while.

  3. У вас нет никакого кода, чтобы увидеть, регистрирует ли Pymunk какое-либо столкновение между автомобилем и препятствиями.

    Есть разные способы справиться с этим. Из вашего кода видно, что вы хотите самостоятельно управлять движением автомобиля и использовать Pymunk только для столкновений. В этом случае проще всего вообще не добавлять автомобиль в пространство, вместо этого в каждом кадре вы используете space.shape_query, чтобы увидеть, пересекается ли форма автомобиля с другой формой в пространстве.

    С другой стороны, если вы используете Pymunk только для базового обнаружения столкновений, может быть проще использовать обнаружение столкновений, встроенное в Pygame.

person viblo    schedule 12.04.2018