Pymunk Pygame Object positions does not update - python

Trying the following code with python 2.7. Basically its a circle that hangs from a bar and an apple that you can hit with an impulse by pressing the spacebar. There is also a square.
import time
import pygame
import pymunk
import pymunk.pygame_util
import sys
pygame.init()
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
space = pymunk.Space()
space.gravity = 0, -1000
ball_body = pymunk.Body(100, 100)
ball_body.position = 400.0, 300.0
ball_body.angular_velocity = 10.0
ball_shape = pymunk.Circle(ball_body, 15)
ball_shape.friction = 0.5
ball_shape.elasticity = 0.9
ball_shape.color = (0,0,0,0)
space.add(ball_body, ball_shape)
static_lines = [pymunk.Segment(space.static_body, (20,20), (780,20), 2),
pymunk.Segment(space.static_body, (20,580), (780,580), 2),
pymunk.Segment(space.static_body, (20,20), (20,580), 2),
pymunk.Segment(space.static_body, (780,20), (780,580), 2)]
for static_line in static_lines:
static_line.color = (255,255,255)
static_line.elasticity = 0.9
static_line.friction = 1
space.add(static_lines)
i = 0
prev_body = pymunk.Body(10, 10000)
prev_body.position = (300, 580)
chain_fix_point = pymunk.Body()
chain_fix_point.position = (300, prev_body.position[1])
# Another
i = 0
prev_body = pymunk.Body(10, 10000)
prev_body.position = (600, 580)
chain_fix_point = pymunk.Body()
chain_fix_point.position = (600, prev_body.position[1])
while i < 20:
# rotation_center_body = pymunk.Body()
# rotation_center_body.position = (400, prev_body.position[1] - 20)
body = pymunk.Body(1, 1)
body.position = (600, prev_body.position[1] - 10)
line = pymunk.Circle(body, 5)
line.elasticity = 0
line.friction = 1
if i == 0:
rotation_center_joint = pymunk.PinJoint(body, chain_fix_point)
else:
rotation_center_joint = pymunk.PinJoint(body, prev_body)
space.add(line, body, rotation_center_joint)
prev_body = body
i += 1
blob_body = pymunk.Body(5, 1)
blob_body.position = prev_body.position[0], prev_body.position[1] - 40
blob_shape = pymunk.Circle(blob_body, 20)
rotation_center_joint = pymunk.SlideJoint(blob_body, prev_body,(0,0),(0,0),0,40)
space.add(blob_body, blob_shape, rotation_center_joint)
appleimg = pygame.image.load('apple.png')
box_body = pymunk.Body(10,10000)
box_body.position = 600, 300
box_vertices = [(570, 270),(570, 330),(630,330),(630,270)]
box_shape = pymunk.Poly(box_body, box_vertices, offset=(0, 0), radius=1).create_box(box_body, size = (60,60))
box_shape.friction = 0.5
box_shape.elasticity = 0.9
box_shape.color = (255,0,0)
space.add(box_body, box_shape)
def main():
running = True
angle = 0;
while running == True:
print "game loop"
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
ball_body.apply_impulse(j = (100000, 100000))
screen.fill((0,0,0))
pymunk.pygame_util.draw(screen, space)
if ball_body.angle != 0:
angle += ball_body.angular_velocity
img = pygame.transform.rotate(appleimg, angle)
screen.blit(img, (ball_body.position[0] - 20, 580 - ball_body.position[1]))
pygame.display.flip()
clock.tick(60)
space.step(1/60)
pygame.quit()
quit()
main()
The gameloop runs but the position does not update.
This code worked pretty well for python 3.5. But when I switched to 2.7, its failing.

The problem is that in python 2.x you get 0 when you divide 1 by 60 when you call the step function, since / is doing integer division in 2.x.
You can fix this problem either by importing the python 3 division with
from __future__ import division
Or you can divide by a float instead 1/60.0
Check this question for mor info: In Python 2, what is the difference between '/' and '//' when used for division?

Related

How can I fix a Python circular import problem?

I have 3 python files: main.py, settings.py and classes.py
main.py:
import pygame as pg
from classes import *
from settings import *
pg.font.init()
HEALTH_FONT = pg.font.SysFont('comicsans', 20)
pg.display.set_caption("Testa Game")
ground_surface = pg.image.load('graphics/ground.png').convert()
BG_COLOR = (0, 255, 255)
BLACK = (0, 0, 0)
run = True
while run == True:
clock = pg.time.Clock()
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
exit()
clock.tick(FPS)
keys_pressed = pg.key.get_pressed()
health_text = HEALTH_FONT.render("Health: " + str(class_type.health), 1, BLACK)
WIN.fill(BG_COLOR)
WIN.blit(class_type.karakter_surface, (class_type.karakter.x, class_type.karakter.y))
WIN.blit(ground_surface, (0, 350))
WIN.blit(health_text, (10, 10))
karakter_moving(keys_pressed, class_type.karakter)
pg.display.flip()
settings.py:
import pygame as pg
from classes import *
WIDTH, HEIGHT = 900, 500
WIN = pg.display.set_mode((WIDTH, HEIGHT))
class_type = death_mage
FPS = 60
def karakter_moving(keys_pressed, karakter):
if keys_pressed[pg.K_w] and karakter.y - class_type.speed > 0:
karakter.y -= class_type.speed
if keys_pressed[pg.K_s] and karakter.y + class_type.speed + karakter.height < HEIGHT - 5:
karakter.y += class_type.speed
if keys_pressed[pg.K_a] and karakter.x - class_type.speed > 0: #LEFT
karakter.x -= class_type.speed
if keys_pressed[pg.K_d] and karakter.x + class_type.speed + karakter.width < WIDTH:
karakter.x += class_type.speed
classes.py:
import pygame as pg
from settings import WIN
pg.init()
def fire_ball():
fireball = []
maxFireBall = 3
manacost = 1
color = 'ORANGE'
for event in pg.event.get():
if event.type == pg.KEYDOWN:
if event.key == pg.K_SPACE and len(fireball) < maxFireBall:
dmFireBall = pg.Rect(
death_mage.karakter.x + death_mage.karakter.width, death_mage.karakter.y + death_mage.karakter.height//2 - 2, 10, 5)
fireball.append(dmFireBall)
death_mage.mana -= manacost
pg.draw.rect(WIN, color, fireball)
class death_mage:
KARAKTER_WIDTH, KARAKTER_HEIGHT = 60, 85
karakter = pg.Rect(400, 200, KARAKTER_WIDTH, KARAKTER_HEIGHT)
karakter_surface = pg.transform.scale(pg.image.load('Assets/death_mage.png'), (KARAKTER_WIDTH, KARAKTER_HEIGHT))
health = 10
mana = 5
attack = 1
speed = 2
attack_speed = 1
crit_rate = 0
crit_damage = 0
Error message:
"settings.py", line 12, in <module>
class_type = death_mage
NameError: name 'death_mage' is not defined
or if settings.py: from classes import death_mage
"settings.py", line 3, in <module>
from classes import death_mage
ImportError: cannot import name 'death_mage' from partially initialized module 'classes' (most likely due to a circular import)
How can I remedy this?
Thanks to helping me
One of your modules has got no urls.py

Visualize/Show Pymunk body shape [duplicate]

Why do bodies in pymunk keep colliding without actually touching each other even after the position and body shape is correctly set?
You will see from my code below that the bird keeps colliding with the ball without actually touching the ball.
import pygame, pymunk
pygame.init()
WIDTH, HEIGHT = 900, 500
win = pygame.display.set_mode((WIDTH,HEIGHT))
pygame.display.set_caption("Flappy OBJ")
color = (255,255,255)
win.fill(color)
fps = 120
fb_img = pygame.image.load("images/flappy-bird.png")#.convert()
fb_img = pygame.transform.rotate(pygame.transform.scale(fb_img, (30,20)), 0)
ball_img = pygame.image.load("images/ball.png")#.convert()
ball_img = pygame.transform.rotate(pygame.transform.scale(ball_img, (60,60)), 0)
def bird_body():
body = pymunk.Body(1, 100, body_type=pymunk.Body.DYNAMIC)
body.position = (50, 0)
shape = pymunk.Poly.create_box(body, (30,20))
space.add(body, shape)
return shape
def ball_body():
body = pymunk.Body(1, 100, body_type = pymunk.Body.KINEMATIC)
body.position = (500, 300)
body.velocity = (-25,0)
shape = pymunk.Circle(body, 60)
shape.color = (0,255,255, 128)
space.add(body, shape)
return shape
space = pymunk.Space()
space.gravity = (0, 20)
fb_body = bird_body()
b_body = ball_body()
def draw_window():
global scroll
win.fill(color)
space.step(0.03)
win.blit(ball_img, (b_body.body.position.x, b_body.body.position.y))
win.blit(fb_img, (fb_body.body.position.x, fb_body.body.position.y))
pygame.display.update()
def main():
w_was_down = True
clock = pygame.time.Clock()
run = True
while run:
clock.tick(fps)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_w]:
if not w_was_down:
fb_body.body.apply_impulse_at_local_point((0,-50))
w_was_down = True
else:
w_was_down = False
draw_window()
pygame.quit()
main()
Tap w to move the bird up. some more details some more details some more details
The 2nd argument of pymunk.Circle is the radius, but not the diameter:
shape = pymunk.Circle(body, 60)
shape = pymunk.Circle(body, 30)
And the position of the pymuk object is the center of the object:
win.blit(ball_img, (b_body.body.position.x, b_body.body.position.y))
win.blit(fb_img, (fb_body.body.position.x, fb_body.body.position.y))
win.blit(ball_img, (b_body.body.position.x-30, b_body.body.position.y-30))
win.blit(fb_img, (fb_body.body.position.x-15, fb_body.body.position.y-10))

PyGame: Why isn't my object moving automatically

I want 'rock' to be able to automatically move to the left when running the program but nothing happens, from my understanding I have made it so that the rocks x position moves by 3 every iteration
import pygame
p = pygame.display.set_mode((900, 600))
pygame.display.set_caption("First game")
FPS = 60
WHITE = 255, 255, 255
RED = 255, 0, 0
GREEN = 0, 255, 0
BLUE = 0, 0, 255
DBLUE = 57, 64, 90
board1 = pygame.image.load("board.png")
board2 = pygame.image.load("board.png")
rock = pygame.image.load("rock.png")
def draw_window(board1_move, board2_move, rock_scaled):
p.fill(DBLUE)
board1_scaled = pygame.transform.rotate(pygame.transform.scale(board1, (55, 40)), 40)
board2_scaled = pygame.transform.rotate(pygame.transform.scale(board2, (55, 40)), 40)
rock_scaled = pygame.transform.rotate(pygame.transform.scale(rock, (55, 40)), 0)
p.blit(board1_scaled, (board1_move.x, board1_move.y))
p.blit(board2_scaled, (board2_move.x, board2_move.y))
p.blit(rock_scaled, (400, 250))
pygame.display.update()
keypress = pygame.key.get_pressed()
def board1_move_func(keypress, board1_move):
if keypress[pygame.K_w] and board1_move.y > 0:
board1_move.y -= 3
if keypress[pygame.K_s] and board1_move.y < 530:
board1_move.y += 3
def board2_move_func(keypress, board2_move):
if keypress[pygame.K_UP] and board2_move.y > 0:
board2_move.y -= 3
if keypress[pygame.K_DOWN] and board2_move.y < 530:
board2_move.y += 3
def main():
rock_x = 450
rock_y = 250
board1_move = pygame.Rect(20, 250, 55, 40)
board2_move = pygame.Rect(805, 250, 55, 40)
rock_move = pygame.Rect(rock_x, rock_y, 55, 40)
clock = pygame.time.Clock()
run = True
while run == True:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keypress = pygame.key.get_pressed()
rock_x += 3
board1_move_func(keypress, board1_move)
board2_move_func(keypress, board2_move)
draw_window(board1_move, board2_move, rock_move)
pygame.quit()
if __name__ == "__main__":
main()
You change rock_x, but draw the object at the position stored in rock_move. rock_move is not magically tied with rock_x. You can update rock_move after changing rock_x:
rock_x += 3
rock_move.x = rock_x
However, I recommend changing rock_move instead of rock_x:
rock_move.x += 3

'pygame error': font not initialized..on a already used font?

This is a strange problem cause I've already use the font, during the same execuction, and... in the same function !
I explain myself with a part of my program :
def text(show_text, show_size, show_color, show_x, show_y):
fontObj = pygame.font.Font('Font.ttf',show_size) # The line 43
Load_text = fontObj.render(show_text,True,show_color,None)
render_text = Load_text.get_rect()
render_text.center = (show_x,show_y)
screen.blit(Load_text,render_text)
def checkmouse(t_text,size,px,py,color1,color2,window):
global p_x, p_y
px_min = px - (int(len(str(text))/2))
px_max = px + (int(len(str(text))/2))
py_min = py - 10
py_max = py + 10
if p_x >= px_min and p_x <= px_max and p_y >= py_min and p_y <= py_max :
text(t_text,size,color1,px,py) # The line 68
pygame.display.update()
else:
text(t_text,size,color2,px,py)
pygame.display.update()
The problem is here :
if w == 'main':
sceen=pygame.display.set_mode((1920,1080), pygame.NOFRAME)
while w == 'main':
image(bg32_big,0,0)
Main = True
while Main :
checkmouse('Play',32,960,260,Dark_Blue,White,'load') # line 109
checkmouse('Quit',32,1520,740,Dark_Blue,White,'load')
And this is my 'traceback' :
Traceback (most recent call last):
File "C:\Users\Cédric\3D Objects\_TAL WIP_\TAL 1 script\newfile.py", line 143, in <module>
Window('main')
File "C:\Users\Cédric\3D Objects\_TAL WIP_\TAL 1 script\newfile.py", line 109, in Window
checkmouse('Play',32,960,260,Dark_Blue,White,'load')
File "C:\Users\Cédric\3D Objects\_TAL WIP_\TAL 1 script\newfile.py", line 68, in checkmouse
text(t_text,size,color2,px,py)
File "C:\Users\Cédric\3D Objects\_TAL WIP_\TAL 1 script\newfile.py", line 43, in text
fontObj = pygame.font.Font('Font.ttf',show_size)
pygame.error: font not initialized
But how it's possible ? In the same function, I've use text('Loading, this may take a few time...',15,Dark_Blue,240,240) before and it's worked perfectly, so why ?
PS: full code:
import time
spb = time.time()
#----+ Major Imports +----#
print('Loading pygame and other child modules :')
import pygame
import os, sys
pygame.init()
print('All modules was loaded succesfully !')
#---+ center windows +---#
os.environ['SDL_VIDEO_CENTERED'] = '1'
#-----+ ALL THE CONSTANTS FROM THE GAME +-----#
print('+*---------------*+')
print('Getting variables')
Dark_Blue = ( 0, 0, 128)
White = ( 255, 255, 255)
barPos = (40, 200)
barSize = (400, 25)
current_load = 'rien.png'
max_a = 3 # Numbur of pictures to convert
a=0
bar_percent = 0
display_percent = '0'
a_db,a_da,a_dif = 0,0,0
p_x,p_y = 0,0
show_size = 25
fontObj = pygame.font.Font('Font.ttf',show_size)
#------+ Loading window +------#
screen=pygame.display.set_mode((1,1), pygame.NOFRAME)
#-----+ ALL THE DEFINITIONS OF THE PROGRAM +-----#
print('Getting definitions')
def text(show_text, show_size, show_color, show_x, show_y):
fontObj = pygame.font.Font('Font.ttf',show_size)
Load_text = fontObj.render(show_text,True,show_color,None)
render_text = Load_text.get_rect()
render_text.center = (show_x,show_y)
screen.blit(Load_text,render_text)
def image(name,x,y):
screen.blit(name,(x,y))
def DrawBar(pos, size, borderC, barC, progress):
global screen
pygame.draw.rect(screen, borderC, (*pos, *size), 1)
innerPos = (pos[0]+3, pos[1]+3)
innerSize = ((size[0]-6) * progress, size[1] - 6)
pygame.draw.rect(screen, barC, (*innerPos, *innerSize))
# The Program draw a bar from the value that we give in 'progress'
# which is equal to a/max_a !
def checkmouse(t_text,size,px,py,color1,color2,window):
global p_x, p_y
px_min = px - (int(len(str(text))/2))
px_max = px + (int(len(str(text))/2))
py_min = py - 10
py_max = py + 10
if p_x >= px_min and p_x <= px_max and p_y >= py_min and p_y <= py_max :
text(t_text,size,color1,px,py)
pygame.display.update()
else:
text(t_text,size,color2,px,py)
pygame.display.update()
#---+ Needed for loading +---#
bg32 = pygame.image.load('sprites/bg32.png').convert_alpha()
bgbar = pygame.image.load('sprites/bgbar.png').convert_alpha()
outline = pygame.image.load('sprites/outline.png').convert_alpha()
title = pygame.image.load('sprites/loading_title.png').convert_alpha()
#---+ Program Heart +---#
def Window(w):
global screen,a,max_a,barPos,barSize,Very_Dark_Blue,borderColor,bg32,bgbar
global outline,title,current_load,a_dif,a_db,a_da,bar_percent
if w == 'first_load':
screen=pygame.display.set_mode((480,270), pygame.NOFRAME)
w = 'load'
if w == 'load':
print(current_load)
a_db = int(( a / max_a ) * 100)
a = a + 1
a_da = int(( a/max_a ) * 100)
a_dif = a_da - a_db
for i in range(0,a_dif):
image(bg32,0,0)
image(bgbar,40,200)
image(outline,0,0)
image(title,40,0)
bar_percent = bar_percent + 1
DrawBar(barPos, barSize, Dark_Blue, Dark_Blue, bar_percent/100)
display_percent = str(current_load) + ' - ' + str(bar_percent) + ' %'
text(display_percent,25,Dark_Blue,240,185)
text('Loading, this may take a few time...',15,Dark_Blue,240,240)
pygame.display.update()
if w == 'main':
sceen=pygame.display.set_mode((1920,1080), pygame.NOFRAME)
while w == 'main':
image(bg32_big,0,0)
Main = True
while Main :
checkmouse('Play',32,960,260,Dark_Blue,White,'load')
checkmouse('Quit',32,1520,740,Dark_Blue,White,'load')
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
Window(window)
pygame.quit()
print('+*---------------*+')
print('Loading window :')
#-----+ Loading window +-----#
current_load = 'Background.png'
Window('first_load')
background = pygame.image.load('sprites/Background.png').convert_alpha()
current_load = 'outline.png'
Window('load')
outline_big = pygame.image.load('sprites/outline.png').convert_alpha()
current_load = 'bg32.png'
Window('load')
bg32_big = pygame.image.load('sprites/bg32_big.png').convert_alpha()
print('All pictures was loaded succesfully !')
#---+ time debug +---#
spe = time.time()
spt = spe - spb
sptm = 0
while spt >= 60:
spt = spt - 60
sptm = sptm + 1
print('+*---------------------*+')
print('All ressources needed for the game was loaded in',sptm,'minutes and',spt,'seconds')
#-----+ and... +-----#
Window('main')
Just don't call pygame.quit() in your main loop:
while Main :
checkmouse('Play',32,960,260,Dark_Blue,White,'load')
checkmouse('Quit',32,1520,740,Dark_Blue,White,'load')
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
Window(window)
pygame.quit() # <-- don't do this
It will put the font module (and other modules) in a state that's no longer useable.

Python, Pygame, my while loop breaks before it ends and i dont kno how to fix it [duplicate]

This question already has answers here:
Why is my PyGame application not running at all?
(2 answers)
Why is nothing drawn in PyGame at all?
(2 answers)
Closed 1 year ago.
Im working on a school project on a motion projectile but my while loop breaks before it ends.
import pygame, sys
from pygame.locals import *
from math import *
def rot_center(image, center_angle):
orig_rect = image.get_rect()
rot_image = pygame.transform.rotate(image, center_angle)
rot_rect = orig_rect.copy()
rot_rect.center = rot_image.get_rect().center
rot_image = rot_image.subsurface(rot_rect).copy()
return rot_image
pygame.init()
FPS = 144
fpsClock = pygame.time.Clock()
SCENE = pygame.display.set_mode((1280, 720), 0, 32)
pygame.display.set_caption('Domača naloga')
backgroundImg = pygame.image.load('images/background.png')
cannonBaseImg = pygame.image.load('images/base.png')
cannonImg = pygame.image.load('images/cannon.png')
ballImg = pygame.image.load('images/cannonBall.png')
enemy = pygame.image.load('images/enemy.png')
cannonBasePos = (9,490)
cannonPos = (-5, 480)
ballPos = (22,510)
enemyPos = (40, 400)
cannonImg = pygame.transform.rotate(cannonImg, -15)
ang = 45
cannonMovImg = rot_center(cannonImg, ang)
# bug: backgoround image dissapears and it bugges green
SCENE.blit(backgroundImg, (0,0))
SCENE.blit(cannonMovImg, cannonPos )
SCENE.blit(ballImg, ballPos)
SCENE.blit(cannonBaseImg, cannonBasePos)
SCENE.blit(enemy, enemyPos)
t = 0
s = ballPos
v = (0, 0)
vm = 100
launched = False
while True: #<-- while starts here
dt = fpsClock.tick(FPS)
if launched:
t = t + dt/250.0 # cajt is clocka
a = (0.0, 10.0) # acceleration
v = (v0[0] + a[0]*t, v0[1] + a[1]*t) # spazz out nad 1000 !!!
vm = sqrt(v[0]*v[0] + v[1]*v[1])
s0 = ballPos # poz
s = (s0[0] + v0[0]*t + a[0]*t*t/2, s0[1] + v0[1]*t + a[1]*t*t/2)
if s[1] >= 510: # tla
launched = False
font = pygame.font.Font(None, 30)
text_ang = font.render("Kot = %d" % ang, 1, (10, 10, 10))
text_ang_pos = (1050, 50)
text_vm = font.render("Hitrost = %.1f m/s" % vm, 1, (10, 10, 10))
text_vm_pos = (1050, 80)
text_stat = font.render("Statistika:", 1, (10, 10, 10))
text_stat_pos = (1050, 20)
text_x = font.render("Dolžina = %.1f m" % s[0], 1, (10, 10, 10))
text_x_pos = (1050, 110)
text_t = font.render("Čas = %.1f s" % t, 1, (10, 10, 10))
text_t_pos = (1050, 140)
SCENE.blit(backgroundImg, (0,0))
SCENE.blit(cannonMovImg, cannonPos)
SCENE.blit(ballImg, s)
SCENE.blit(cannonBaseImg, cannonBasePos)
SCENE.blit(enemy, enemyPos) #<--- while loop breaks here
SCENE.blit(text_t, text_t_pos)
SCENE.blit(text_stat, text_stat_pos)
SCENE.blit(text_vm, text_vm_pos)
SCENE.blit(text_x, text_x_pos)
SCENE.blit(text_ang, text_ang_pos)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == KEYDOWN:
if event.key == K_SPACE:
ballPos = (0,478)
s = ballPos
t = 0
launched = True
v0 = (vm*cos(radians(ang)), -vm*sin(radians(ang)))
keystate = pygame.key.get_pressed()
if keystate[K_LEFT]:
ang+=2
if ang > 90:
ang = 90
cannonMovImg = rot_center(cannonImg, ang)
if keystate[K_RIGHT]:
ang-=2
if ang < 0:
ang = 0
cannonMovImg = rot_center(cannonImg, ang)
if keystate[K_UP]:
vm+=2
if keystate[K_DOWN]:
vm-=2
pygame.display.flip() #<-- while should end here
I've tried everything but even my teacher doesnt know the anwser. He said it's a bug in Python 3.6.3. Any ideas. I've researched for the past week and im frustrated. If anyone has any ideas please let me know. Thanks for your anwsers in advance

Categories

Resources