Как я могу получить координаты pymunk.Circle? - PullRequest
2 голосов
/ 24 апреля 2019

Я новичок в Python, поэтому, пожалуйста, прости меня, если я неправильно назвал объекты Pygame.Мне было поручено создать виртуальный игровой автомат Pachinko.У меня проблемы с получением координат шара, когда он падает через окно.Мне нужны координаты, чтобы отслеживать счет и сбрасывать циклы, чтобы пользователь мог бросить еще один шар, когда он достигнет нижнего уровня.

Вот мой исходный код.

#Project specific libraries
import pygame                   #https://www.pygame.org/news
import pymunk                   #http://www.pymunk.org/en/latest/
import pymunk.util
import pymunk.pygame_util
import tkinter                  #https://docs.python.org/2/library/tkinter.html

#Standard libraries
import sys
import math
import random
import os
import time

#Import ALL tools from tkinter & pygame libraies
from tkinter import *
from pygame import *

#Constants for object to object interaction
COLLTYPE_FLOOR = 3
COLLTYPE_BOUNCER = 2
COLLTYPE_BALL = 1

#****************************************************************************
def goal_reached(arbiter, space1, data):

    ball_i, floor_i  = arbiter.shapes

    space_i = space1

    space_i.remove(ball_i, ball_i.body)
    remove_from_ball_list(ball_i)
    return True
#*************************************************************

main = Tk()
main.resizable(width=False, height=False)
main.title("Pachinko")
embed = Frame(main, width = 500, height = 500) 

embed.pack() #packs window to the left
os.environ['SDL_WINDOWID'] = str(embed.winfo_id())

screen = pygame.display.set_mode((500,500))
screen.fill(pygame.Color(255,215,255))
clock = pygame.time.Clock()

#List of ball "objects"
balls = []

#might not need balls_to_remove List
balls_to_remove = []

#velocity, gravity
space = pymunk.Space()
space.gravity = 0, -200

#Floor boundaries
floor = pymunk.Segment(space.static_body, (0.0, 10.0), (500.0, 10.0), 1.0)
floor.collision_type = COLLTYPE_FLOOR
space.add(floor)

#Left wall boundaries
left_wall = pymunk.Segment(space.static_body, (0.0, 500.0), (0.0, 0.0), 1.0)
left_wall.friction = 1.0
left_wall.elasticity = 0.9
left_wall.collision_type = COLLTYPE_BOUNCER
space.add(left_wall)

#Right wall boundaries
right_wall = pymunk.Segment(space.static_body, (500.0, 500.0), (500.0, 0.0), 1.0)
right_wall.friction = 1.0
right_wall.elasticity = 0.9
right_wall.collision_type = COLLTYPE_BOUNCER
space.add(right_wall)

draw_options = pymunk.pygame_util.DrawOptions(screen)
space.debug_draw(draw_options)

#Generate a fixed field of pins
done = 0
x_shift = 45
y_shift = 150
step = 0
tier = 0
while(done == 0):
    variance = random.randint(1, 15) 
    pin_radius = random.randint(14, 17)
    newPin = pymunk.Body(body_type=pymunk.Body.KINEMATIC)
    x = x_shift + variance
    y = y_shift + variance
    newPin.position = x, y
    shape = pymunk.Circle(newPin, pin_radius)
    shape.collision_type = COLLTYPE_BOUNCER
    space.add(newPin, shape)
    x_shift += 85
    step += 1
    if(step == 5):          #Tier one
        x_shift = 100
        y_shift += 60
    if(step == 10):         #Tier two
        x_shift = 50
        y_shift += 60
    if(step == 15):         #Tier three
        x_shift = 100
        y_shift += 60
    if(step == 20):         #Tier four
        x_shift =50
        y_shift += 60
    if(step == 25):         #Tier five
        x_shift = 100
        y_shift += 60
        done = 1

    #Generate the five poles (left to right)
step = 0
x_shift = 100
while(step < 4):
    pole0 = pymunk.Segment(space.static_body, (x_shift, 100.0), (x_shift, 10.0), 5.0)
    pole0.friction = 1.0
    pole0.elasticity = 0.9
    pole0.collision_type = COLLTYPE_BOUNCER
    space.add(pole0)
    step += 1
    x_shift += 100


pygame.display.flip()
pygame.display.init()
pygame.display.update()

#https://stackoverflow.com/questions/23410161/pygame-collision-code
h = space.add_collision_handler(COLLTYPE_BALL, COLLTYPE_FLOOR)

h.begin = goal_reached

def remove_from_ball_list(temp1):
    #print("where in list is it?")
    for ball in balls:
        if temp1 == ball:
            #print("Time to remove from the list")
            balls.remove(ball)



#Primary game loop
ticks = 50
play = True
while play == True:
    mouseClick = pygame.event.get()
    dropHeight = 440

    for event in mouseClick:
        if event.type == pygame.MOUSEBUTTONUP:
            mouseX, mouseY = pygame.mouse.get_pos()
            ticks = 0

    #keep making new balls & pins
    if ticks == 0:
        step = 0
        x_shift = 0
        y_shift = 0

        #Generate the new ball
        mass = 1
        inertia = pymunk.moment_for_circle(mass, 0, 14, (0, 0))
        radius = 12
        ball = pymunk.Body(mass, inertia)

        #Keep the ball in bounds when user drops
        if(mouseX < 25):
            mouseX = 10
        if(mouseX > 480):
            mouseX = 490
        ball.position = mouseX, dropHeight
        shape = pymunk.Circle(ball, radius)
        shape.collision_type = COLLTYPE_BALL
        space.add(ball, shape)
        balls.append(shape)
        ticks = 50
    pygame.draw.line(screen, (255,0,255), (20,60), (480,60), 2)
    space.step(1/50.0)
    space.debug_draw(draw_options)
    pygame.display.update()
    pygame.display.flip()
    screen.fill(pygame.Color(255,215,255))
    clock.tick(50)
    #ticks -= 1
    main.update()

А вот конкретный фрагмент кода, в который я хотел бы добавить функцию:

#Primary game loop
ticks = 50
play = True
while play == True:
    mouseClick = pygame.event.get()
    dropHeight = 440

    for event in mouseClick:
        if event.type == pygame.MOUSEBUTTONUP:
            mouseX, mouseY = pygame.mouse.get_pos()
            ticks = 0

    #keep making new balls & pins
    if ticks == 0:
        step = 0
        x_shift = 0
        y_shift = 0

        #Generate the new ball
        mass = 1
        inertia = pymunk.moment_for_circle(mass, 0, 14, (0, 0))
        radius = 12
        ball = pymunk.Body(mass, inertia)

        #Keep the ball in bounds when user drops
        if(mouseX < 25):
            mouseX = 10
        if(mouseX > 480):
            mouseX = 490
        ball.position = mouseX, dropHeight
        shape = pymunk.Circle(ball, radius)
        shape.collision_type = COLLTYPE_BALL
        space.add(ball, shape)
        balls.append(shape)
        ticks = 50
    pygame.draw.line(screen, (255,0,255), (20,60), (480,60), 2)
    space.step(1/50.0)
    space.debug_draw(draw_options)
    pygame.display.update()
    pygame.display.flip()
    screen.fill(pygame.Color(255,215,255))
    clock.tick(50)
    #ticks -= 1
    main.update()

Я хотел бы вывести координаты шара в терминал, чтобы я мог добавитьозвучивание и перезапуск функций.Мне кажется, что мне не хватает очень простого решения.

screenshot

1 Ответ

0 голосов
/ 24 апреля 2019

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

for b in balls:
  print("ball position", b.body.position)

Однако, может быть, вам не нужно проверять это каждый кадр самостоятельно?У вас уже есть функция goal_reached, которая вызывается, когда мяч достиг цели, если я правильно понимаю.Там вы можете обновить счет и переключить что-нибудь, чтобы позволить игроку добавить еще один шар.

...