Related
I am starting to write a game but whenever I run my code it takes 2 minutes to boot up and even then some methods are not working. The main ones that's not working are quitting pygame and drawGameScene().
My code is:
import os, random
from pygame import *
init()
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d, %d" %(0, 20)
scalefactor = 2
FPS = 60
screenWidth = round(224 * scalefactor)
screenHeight = round(298 * scalefactor)
size = screenWidth, screenHeight
screen = display.set_mode(size)
button = 0
RED = (255, 0, 0)
BLUE = (0,0,255)
STATEGAME = 1
STATEQUIT = 3
curState = STATEGAME
titleFont = font.SysFont("Times New Roman",45)
def drawText(words, screen,position, color, font):
text = font.render(words, False, color)
textSize = text.get_size()
position[0] = position[0] - textSize[0]//2
position[1] = position[1] - textSize[1]//2
#centers the text
screen.blit(text,position)
def gameRun():
while curState != STATEQUIT:
if curState == STATEGAME:
drawGameScene()
eventCheck()
updater()
def eventCheck():
for evnt in event.get():
if evnt.type == QUIT:
curState == STATEQUIT
def updater():
pass
def drawGameScene():
draw.rect(screen,RED,(0,0,screenWidth,screenHeight))
drawText("High Score", screen, [0,0], BLUE, titleFont)
display.update
gameRun()
display.flip()
no error messages are given
Please Help, It's for a project
For the quitting pygame:
You should use the code as below:
for events in event.get():
if events.type == QUIT:
pygame.quit()
exit() #this is from sys module
This way, your pygame is quitted at the first place. So, you don't need anything about curstate, etc.
Also, you need to use while True statement to repeat the blitting process.
Full code:
import os, random
from pygame import *
from sys import exit
init()
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d, %d" %(0, 20)
scalefactor = 2
FPS = 60
screenWidth = round(224 * scalefactor)
screenHeight = round(298 * scalefactor)
size = screenWidth, screenHeight
screen = display.set_mode(size)
button = 0
RED = (255, 0, 0)
BLUE = (0,0,255)
titleFont = font.SysFont("Times New Roman",45)
def drawText(words,screen,position,color,font):
text = font.render(words, False, color)
textSize = text.get_size()
position[0] = position[0] - textSize[0]//2
position[1] = position[1] - textSize[1]//2
#centers the text
screen.blit(text,position)
def gameRun():
drawGameScene()
eventCheck()
updater()
def eventCheck():
for events in event.get():
if events.type == QUIT:
quit()
exit()
def updater():
pass
def drawGameScene():
draw.rect(screen,RED,(0,0,screenWidth,screenHeight))
drawText("High Score", screen, [0,0], BLUE, titleFont)
#display.update()
while True:
gameRun()
display.flip()
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.
I'm beginner at pygame development, when I update my spritesheet image, the old image persists in the surface.
How do I clear the surface?
main.py
FPS = 10
try:
import sys
import random
import math
import os
import getopt
import pygame
from socket import *
from pygame.locals import *
from player import *
except ImportError as err:
print("Couldn't load module. {}".format( err ) )
sys.exit(2)
pygame.init()
fps_clock = pygame.time.Clock()
screen = pygame.display.set_mode((600, 600))
game_surface = pygame.Surface(screen.get_size())
game_surface.fill((250,250,250))
game_surface_image = pygame.image.load("data/landscape.jpg").convert()
game_surface.convert()
p = Player()
player_surface = pygame.Surface((p.SPRITE_WIDTH, p.SPRITE_HEIGHT), pygame.SRCALPHA)
# ---------------------------------------------------------------
# MAIN LOOP -----------------------------------------------------
# ---------------------------------------------------------------
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
screen.fill((250,250,250))
pygame.display.set_caption("FPS: {:.2f}".format(fps_clock.get_fps()))
p.animation()
player_surface.blit(p.image, (0,0), p.rect)
game_surface.blit(game_surface_image, (0,0))
game_surface.blit(player_surface, (screen.get_rect().centerx - p.SPRITE_WIDTH/2, screen.get_rect().centery - p.SPRITE_HEIGHT/2))
screen.blit(game_surface, (0,0))
pygame.display.update()
fps_clock.tick(FPS)
player.py
import pygame
from pygame.locals import *
class Player(pygame.sprite.Sprite):
SPRITE_HEIGHT = 110
SPRITE_WIDTH = 60
SPRITE_QTY = 8
SPRITE_NAME = "data/player_sprite.png"
__ANIMATION_INTERVAL = 12
__ANIMATION_COUNT = 0
__SPRITE_POSITION = 0
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(self.SPRITE_NAME).convert_alpha()
self.rect = (0, 0, self.SPRITE_WIDTH, self.SPRITE_HEIGHT)
def animation(self):
if self.__ANIMATION_COUNT == self.__ANIMATION_INTERVAL:
self.__ANIMATION_COUNT = 0
if self.__SPRITE_POSITION < self.SPRITE_QTY - 1:
self.__SPRITE_POSITION += 1
else:
self.__SPRITE_POSITION = 0
self.rect = Rect(self.SPRITE_WIDTH * self.__SPRITE_POSITION, 0, self.SPRITE_WIDTH * self.__SPRITE_POSITION + self.SPRITE_WIDTH, self.SPRITE_HEIGHT)
else:
self.__ANIMATION_COUNT += 1
The problem lies in this line:
player_surface.blit(p.image, (0,0), p.rect)
The player image is blit again on top of the old image. The player_surface needs to be cleared first.
Adding player_surface.fill(BLANK_ALPHA) with BLANK_ALHPA = (0, 0, 0, 0) should do the trick.
player_surface.fill(BLANK_ALPHA)
player_surface.blit(p.image, (0,0), p.rect)
I am a making a Pygame game called Ninja Quest. So far, I have only worked on it for a couple of days however, I find that when I launch the game, everything works fine but, after about 30 seconds, the game will crash, saying:
Traceback (most recent call last): File "NinjaQuest.py", line 151,
in File "NinjaQuest.py", line 146, in main pygame.error:
Couldn't read from 'Resources/Menu/Disasterpeace - Home.ogg'
Although I have only done the menu right now, and none of the options work, I would appreciate it if someone could tell me what is wrong with my code, as I have asked some of my piers, but they couldn't figure out the problem. Thanks in advance :).
By the way, here is my 'NinjaQuest.py':
#Imports
from pygame.locals import *; import pygame; from Image import *; from Background import *;
import sys, os
#Constants
FPS = 200
WINDOWWIDTH = 900; WINDOWHEIGHT = 506;
GAMETITLE = "Ninja Quest"; VERSION = "0.5 Pre-Dev"
WHITE = [255,255,255]; RED = [255,0,0]; GREEN = [0,255,0]; BLUE = [0,0,255]; BLACK = [0,0,0]
surface = pygame.display.set_mode([WINDOWWIDTH, WINDOWHEIGHT])
pygame.display.set_caption(GAMETITLE)
clock = pygame.time.Clock()
slc = 1
openingFinished = True
''' I define stuff here to avoid doing it in a loop to avoid lag '''
#Draw menu
pygame.font.init()
#Define background
background = Background("Resources/Menu/Background.png", 0, (601 - 506) * -1)
#Define text
titleFont = pygame.font.Font("Resources/ka1.ttf", 40)
titleText = titleFont.render("Ninja Quest",True,(255,165,0))
titleFont2 = pygame.font.Font("Resources/ka1.ttf", 30)
titleText2 = titleFont2.render(VERSION,True,(255,165,0))
newFont = pygame.font.Font("Resources/ka1.ttf", 30)
newText = newFont.render("New Game",True,(255,165,0))
loadFont = pygame.font.Font("Resources/ka1.ttf", 30)
loadText = loadFont.render("Load Game",True,(255,165,0))
creditFont = pygame.font.Font("Resources/ka1.ttf", 30)
creditText = creditFont.render("Credits",True,(255,165,0))
def drawMenu():
global titleText
global titleText2
global newText
global loadText
global creditText
global background
surface.blit(background.image, background.rect)
if slc == 1:
newText = newFont.render("New Game",True,BLUE)
loadText = newFont.render("Load Game",True,(255,165,0))
creditText = newFont.render("Credits",True,(255,165,0))
elif slc == 2:
loadText = newFont.render("Load Game",True,BLUE)
newText = newFont.render("New Game",True,(255,165,0))
creditText = newFont.render("Credits",True,(255,165,0))
elif slc == 3:
creditText = newFont.render("Credits",True,BLUE)
loadText = newFont.render("Load Game",True,(255,165,0))
newText = newFont.render("New Game",True,(255,165,0))
surface.blit(titleText,(WINDOWWIDTH / 2 - titleText.get_width() / 2, titleText.get_height()))
surface.blit(titleText2,(WINDOWWIDTH / 2 - titleText2.get_width() / 2, titleText.get_height() + titleText.get_height()))
surface.blit(newText,(WINDOWWIDTH / 2 - newText.get_width() / 2, WINDOWHEIGHT * 0.33333))
surface.blit(loadText,(WINDOWWIDTH / 2 - newText.get_width() / 2, (WINDOWHEIGHT * 0.33333) + loadText.get_height()))
surface.blit(creditText,(WINDOWWIDTH / 2 - newText.get_width() / 2, (WINDOWHEIGHT * 0.33333) + creditText.get_height() * 2))
pygame.display.update()
#Draw opening scene
def drawOpening():
openingFinished = False
surface.fill((255,255,255))
#Play theme tune
pygame.mixer.init()
pygame.mixer.music.load("Resources/Menu/8-Bit.ogg")
pygame.mixer.music.play()
pygame.display.update()
pygame.time.wait(1000)
#Draw background
background = Image("Resources/Menu/The 8-Bit Developers.png", 4, 4, 0, 0)
background = Image("Resources/Menu/The 8-Bit Developers.png", 4, 4, WINDOWWIDTH / 2 - background.image.get_width() / 2, WINDOWHEIGHT / 2 - background.image.get_height() / 2)
surface.blit(background.image,background.rect)
pygame.display.update()
pygame.time.wait(2000)
openingFinished = True
#Main Loop
def main(newGame):
running = True
global slc
pygame.key.set_repeat(1, 10)
#a = pygame.image.load("Resources/Menu/Icon.png")
#pygame.display.set_icon(a)
pygame.init()
if newGame == True:
#Start game and then music
pygame.mixer.pre_init(44100, -16, 2, 2048) # setup mixer to avoid sound lag
surface.fill((255,255,255))
drawOpening()
#pygame.mixer.music.load("Resources/Menu/Disasterpeace - Home.ogg")
pygame.mixer.music.load(os.path.join("Resources","Menu","Disasterpeace - Home.ogg"))
pygame.mixer.music.play()
while running:
#Controls
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN and openingFinished == True:
if event.key == pygame.K_UP:
slc -= 1
if slc == 0:
slc = 3
if event.key == pygame.K_DOWN:
slc += 1
if slc == 4:
slc = 1
if event.key == pygame.K_RETURN:
if slc == 1:
#new game
pass
if slc == 2:
#resume game
pass
if slc == 3:
#credits
pass
drawMenu()
pygame.display.flip()
pygame.mixer.music.queue(os.path.join("Resources","Menu","Disasterpeace - Home.ogg"))
clock.tick(FPS)
if __name__ == '__main__':
main(True)
Edit: I am on Mac OS X 10.9 'Maverics' if it helps
I think I have finally solved my problem! It appears that I can avoid the game crashing if, instead of using pygame.mixer.music.queue() every iteration of my main loop, instead, I just use:
if pygame.mixer.music.get_busy() == False:
pygame.mixer.music.load(os.path.join("Resources","Menu","Disasterpeace - Home.ogg"))
pygame.mixer.music.play()
This is the final code:
#Imports
from pygame.locals import *; import pygame; from Image import *; from Background import *;
import sys, os
#Constants
FPS = 200
WINDOWWIDTH = 900; WINDOWHEIGHT = 506;
GAMETITLE = "Ninja Quest"; VERSION = "0.5 Pre-Dev"
WHITE = [255,255,255]; RED = [255,0,0]; GREEN = [0,255,0]; BLUE = [0,0,255]; BLACK = [0,0,0]
surface = pygame.display.set_mode([WINDOWWIDTH, WINDOWHEIGHT])
pygame.display.set_caption(GAMETITLE)
clock = pygame.time.Clock()
slc = 1
openingFinished = True
''' I define stuff here to avoid doing it in a loop to avoid lag '''
#Draw menu
pygame.font.init()
#Define background
background = Background("Resources/Menu/Background.png", 0, (601 - 506) * -1)
#Define text
titleFont = pygame.font.Font("Resources/ka1.ttf", 40)
titleText = titleFont.render("Ninja Quest",True,(255,165,0))
titleFont2 = pygame.font.Font("Resources/ka1.ttf", 30)
titleText2 = titleFont2.render(VERSION,True,(255,165,0))
newFont = pygame.font.Font("Resources/ka1.ttf", 30)
newText = newFont.render("New Game",True,(255,165,0))
loadFont = pygame.font.Font("Resources/ka1.ttf", 30)
loadText = loadFont.render("Load Game",True,(255,165,0))
creditFont = pygame.font.Font("Resources/ka1.ttf", 30)
creditText = creditFont.render("Credits",True,(255,165,0))
def drawMenu():
global titleText
global titleText2
global newText
global loadText
global creditText
global background
surface.blit(background.image, background.rect)
if slc == 1:
newText = newFont.render("New Game",True,BLUE)
loadText = newFont.render("Load Game",True,(255,165,0))
creditText = newFont.render("Credits",True,(255,165,0))
elif slc == 2:
loadText = newFont.render("Load Game",True,BLUE)
newText = newFont.render("New Game",True,(255,165,0))
creditText = newFont.render("Credits",True,(255,165,0))
elif slc == 3:
creditText = newFont.render("Credits",True,BLUE)
loadText = newFont.render("Load Game",True,(255,165,0))
newText = newFont.render("New Game",True,(255,165,0))
surface.blit(titleText,(WINDOWWIDTH / 2 - titleText.get_width() / 2, titleText.get_height()))
surface.blit(titleText2,(WINDOWWIDTH / 2 - titleText2.get_width() / 2, titleText.get_height() + titleText.get_height()))
surface.blit(newText,(WINDOWWIDTH / 2 - newText.get_width() / 2, WINDOWHEIGHT * 0.33333))
surface.blit(loadText,(WINDOWWIDTH / 2 - newText.get_width() / 2, (WINDOWHEIGHT * 0.33333) + loadText.get_height()))
surface.blit(creditText,(WINDOWWIDTH / 2 - newText.get_width() / 2, (WINDOWHEIGHT * 0.33333) + creditText.get_height() * 2))
pygame.display.update()
#Draw opening scene
def drawOpening():
openingFinished = False
surface.fill((255,255,255))
#Play theme tune
pygame.mixer.init()
pygame.mixer.music.load("Resources/Menu/8-Bit.ogg")
pygame.mixer.music.play()
pygame.display.update()
pygame.time.wait(1000)
#Draw background
background = Image("Resources/Menu/The 8-Bit Developers.png", 4, 4, 0, 0)
background = Image("Resources/Menu/The 8-Bit Developers.png", 4, 4, WINDOWWIDTH / 2 - background.image.get_width() / 2, WINDOWHEIGHT / 2 - background.image.get_height() / 2)
surface.blit(background.image,background.rect)
pygame.display.update()
pygame.time.wait(2000)
openingFinished = True
#Main Loop
def main(newGame):
running = True
global slc
pygame.key.set_repeat(1, 10)
#a = pygame.image.load("Resources/Menu/Icon.png")
#pygame.display.set_icon(a)
pygame.init()
if newGame == True:
#Start game and then music
pygame.mixer.pre_init(44100, -16, 2, 2048) # setup mixer to avoid sound lag
surface.fill((255,255,255))
drawOpening()
#pygame.mixer.music.load("Resources/Menu/Disasterpeace - Home.ogg")
pygame.mixer.music.load(os.path.join("Resources","Menu","Disasterpeace - Home.ogg"))
pygame.mixer.music.play()
while running:
#Controls
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN and openingFinished == True:
if event.key == pygame.K_UP:
slc -= 1
if slc == 0:
slc = 3
if event.key == pygame.K_DOWN:
slc += 1
if slc == 4:
slc = 1
if event.key == pygame.K_RETURN:
if slc == 1:
#new game
pass
if slc == 2:
#resume game
pass
if slc == 3:
#credits
pass
drawMenu()
pygame.display.flip()
if pygame.mixer.music.get_busy() == False:
pygame.mixer.music.load(os.path.join("Resources","Menu","Disasterpeace - Home.ogg"))
pygame.mixer.music.play()
clock.tick(FPS)
if __name__ == '__main__':
main(True)
I want to say a big thank you to PyNEwbie for trying to help me, and listening to my problem.
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?