0

I'm attempting to write a program using pymunk and pygame. The program(as of right now) is just a car driving with some obstacles. I'm trying to use pymunk to check if the car and any obstacle have collided, and if they do I will have some other function called. The problem I'm having is the car and/or obstacles don't seem to be added to space.

Here is the code I'm running at the moment, my apologies for the sloppiness.

Thanks

Edit: My goal is to use pymunk to detect collisions between the obstacles and car to return something like "game over". The problem is that I can't tell if the obstacles and/or car are being added the pymunk space.

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()

2 Answers2

0

The reason you can't see the car is because you are calling gameDisplay.fill(pg.Color("black")) after drawing the car.

Note also that you are calling a lot of the code inside the while loop which you shouldn't be. E.g. you are redrawing the black background at every cycle.

Here's some things you should move around. If in doubt, place print statements in the functions to see how often they are being called.

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:
        ...

I'm not going to decipher the code to see whether obstacles are actually being added, but you can print space._get_shapes() to see what shapes are in the space.

andyhasit
  • 14,137
  • 7
  • 49
  • 51
  • The problem isn't that the car isn't being drawn, it is. Everything works how it should, except the pymunk aspect. My goal is to use pymunk to detect collisions between the obstacles and car to return something like a "game over". The problem is that I can't tell if the obstacles and/or car are being added the pymunk space. – Joe Granlie Apr 12 '18 at 00:53
0

There are multiple problems that prevent the code from working as you intend.

  1. obs_to_space only add the shape to the space, not the body.

    Fix by adding the body.

  2. car_to_space is called each frame. That means that each frame a new car body and car shape is added to the space. (so after a while the space will contains 100s of cars :)

    You can fix this by adding the car shape once in the beginning and then updating its position each iteration in your while loop.

  3. You dont have any code to actually see if Pymunk register any collision between the car and obstacles.

    There are different ways to handle this. From your code it looks like you want to handle the movement of the car yourself, and only use Pymunk for collisions. In this case the easiest is probably to not add the car at all to the space, instead each frame you use space.shape_query to see if the shape of the car hits another shape in the space.

    On the other hand, if you are only using Pymunk for basic collision detection it might be easier to use the collision detection built into Pygame instead.

viblo
  • 4,159
  • 4
  • 20
  • 28