如何获取pymunk.Circle的坐标?

时间:2019-04-23 23:26:21

标签: python pygame pymunk

我是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 :(得分:0)

似乎这些球被收集在列表balls中。因此,您可以循环浏览以获得所需的所有信息。例如,如果将以下代码放在while循环中,它将在每帧中打印每个球的位置。

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

但是,也许您不需要自己检查每一帧?您已经有一个goal_reached函数,如果我正确理解,一旦球到达球门就会调用该函数。在此处,您可以更新比分并切换一些内容,以允许玩家添加另一个球。