1

Recently I've been trying to make a simple game with pymunk. My goal (at the moment) is for the boxes to be affected by gravity, and to 'jump' when they have their up() function called.

Here is my code.

import pygame
from pygame.locals import *
from pygame.color import *
import pymunk
import pymunk.pygame_util

#constants
WALL_BOUNCINESS = 0
FLOOR_FRICTION = 1
accuracy=1
WALL_PADDING=5


#pygame initiation stuff
pygame.init()
width,height=1500,750
screen = pygame.display.set_mode((width, height))

#main loop initialisations
clock = pygame.time.Clock()
running = True

#physics things
space=pymunk.Space()
space.gravity=(0,-900)

#where the magic happens
draw_options = pymunk.pygame_util.DrawOptions(screen)

#boundaries
wall_body = space.static_body
walls = [pymunk.Segment(wall_body, (WALL_PADDING,height-WALL_PADDING), (width-WALL_PADDING,height-WALL_PADDING),1),
    pymunk.Segment(wall_body, (WALL_PADDING,height-WALL_PADDING), (WALL_PADDING,WALL_PADDING), 1),
    pymunk.Segment(wall_body, (WALL_PADDING,WALL_PADDING), (width-WALL_PADDING,WALL_PADDING), 1),
    pymunk.Segment(wall_body, (width-WALL_PADDING,WALL_PADDING), (width-WALL_PADDING,height-WALL_PADDING),1)]
for wall in walls:
    wall.elasticity = WALL_BOUNCINESS
    wall.friction = FLOOR_FRICTION
space.add(walls)

#keybindings
keybindings={}

#adding objects

class player(): #using a class for neatness, not instantiation purposes
    def __init__(self, starting_coords, keyset_LUR=None):

        x,y=starting_coords[0], starting_coords[1]

        mass=10
        inertia = pymunk.moment_for_box(mass, (100,100))

        self.body = pymunk.Body(mass, inertia)

        self.shape = pymunk.Poly(self.body,((x,y),(x+100,y),(x+100,y+100),(x,y+100)))
        self.shape.elasticity = 0
        self.shape.friction = 0.5

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

        if keyset_LUR:
            funcs=iter((self.left, self.up, self.right))
            for key in keyset_LUR:
                keybindings[key]=next(funcs)

    def left(self):...
    def right(self):...
    def up(self):
        self.body.apply_impulse_at_local_point((0,100))


p1=player((100,100),(K_a,K_w,K_d))
p2=player((1300,100),(K_LEFT,K_UP,K_RIGHT))

#main løóp
while running:
    for event in pygame.event.get():
        if event.type == QUIT: running = False
        elif event.type == KEYDOWN:
            if event.key in keybindings: keybindings[event.key]()

    screen.fill(THECOLORS["white"])

    space.debug_draw(draw_options) #so happy this exists

    dt=1/(60*accuracy)
    for _ in range(accuracy):
        space.step(dt)

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

Apologies for my informal commenting. I've tried to use simple variable names so that the code's not too hard to follow. I believe the problem is with the player class, as it controls how the squares behave. My physics knowledge is bad, and I don't really understand the concept of inertia, so if I've made a mistake relating to a fundamental concept related to physics, I'd really appreciate any explanations which could help clear up my misunderstanding. This is how it currently behaves.

This is how it currently behaves

PS. I'm trying to teach myself pymunk/python, and have very little formal education in either of the two, so I apologise for any 'unorthodox' code, hopefully it's not too hard to follow.

Thanks :)

4

1 に答える 1

1

問題は、プレーヤー ボックスが中央にないことです。ボックスの重心は、ワールド座標で (0,0) にあります。

したがって、ポリゴン シェイプを (-50,-50) から (50,50) のボックスにする必要があります。次に、形状が取り付けられているボディを動かして、必要な場所に配置します。

ということで、まずは交換

    self.shape = pymunk.Poly(self.body,((x,y),(x+100,y),(x+100,y+100),(x,y+100)))

    self.shape = pymunk.Poly(self.body,((-50,-50),(50,-50),(50,50),(-50,50)))

次に、直後に体の位置を x,y に設定します

    self.body.position = x,y
于 2018-09-02T08:28:49.387 に答える