Accelerate OpenGL 2d on python3 - python

I used OpenGL to draw about 20 circles. Each circle has 2 lines, ~10 segments, and all of them have different colors and lenght. FPS ~=4. How can I do this faster?
I am using Python 3 on Ubuntu
Code:
class ScreenOpenGL(Screen):
def __init__(self,layers,layers_lock):
""" Инициализирует экран и запускает его, потом всю программу """
Screen.__init__(self,"OpenGL",layers,layers_lock)
self.window = 0
self.quad = None
self.keypress = []
print("Fuck")
# self.infoScreen = ScreenCursesInfo()
self.infoScreen = ScreenStandartInfo()
GLUT.glutInit(sys.argv)
GLUT.glutInitDisplayMode(GLUT.GLUT_RGBA | GLUT.GLUT_DOUBLE | GLUT.GLUT_ALPHA | GLUT.GLUT_DEPTH)
GLUT.glutInitWindowSize(640, 480)
GLUT.glutInitWindowPosition(400, 400)
self.window = GLUT.glutCreateWindow(b"Project Evoluo alpha")
GLUT.glutDisplayFunc(self._loop) # Функция, отвечающая за рисование
GLUT.glutIdleFunc(self._loop) # При простое перерисовывать
GLUT.glutReshapeFunc(self._resize) # изменяет размеры окна
GLUT.glutKeyboardFunc(self._keyPressed) # Обрабатывает нажатия
self._initGL(640, 480)
field_params(640, 480)
print("Fuck")
def run(self):
# для threading
GLUT.glutMainLoop()
def _initGL(self,Width,Height):
GL.glShadeModel(GL.GL_SMOOTH);
GL.glClearColor(0.0, 0.0, 0.0, 0.0) # This Will Clear The Background Color To Black
GL.glClearDepth(1.0) # Enables Clearing Of The Depth Buffer
GL.glDepthFunc(GL.GL_LESS) # The Type Of Depth Test To Do
GL.glHint(GL.GL_LINE_SMOOTH_HINT, GL.GL_NICEST)
GL.glEnable(GL.GL_BLEND); # Enable Blending
GL.glLineWidth(1.);
GL.glDisable(GL.GL_LINE_SMOOTH)
GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
self.width = Width
self.height = Height
self.quad = GLU.gluNewQuadric()
GLU.gluQuadricNormals(self.quad, GLU.GLU_SMOOTH)
GLU.gluQuadricTexture(self.quad, GL.GL_TRUE)
def _resize(self,Width,Height):
if Height == 0:
Height = 1
self.width = Width
self.height = Height
field_params(Width,Height)
GL.glViewport(0, 0, Width, Height) # Reset The Current Viewport And Perspective Transformation
GL.glMatrixMode(GL.GL_PROJECTION)
GL.glLoadIdentity()
GL.glOrtho(0.0,Width,0.0,Height,-1.0,1.0)
GL.glMatrixMode(GL.GL_MODELVIEW) # Select The Modelview Matrix
GL.glLoadIdentity()
def update(self):
GLUT.glutSwapBuffers()
def clear(self):
GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
GL.glLoadIdentity() # Reset The View
def write(self,pos,str):
pass
def __del__(self):
del(self.infoScreen)
GLUT.glutDestroyWindow(self.window)
self._end()
# sys.exit()
def getch(self):
if self.keypress != []:
# print
return self.keypress.pop(-1)[0]
else:
return None
def _keyPressed(self,*args):
if args != None:
self.keypress.append(args)
print(self.keypress)
def _draw_prepare(self):
del(self._layers)
self._layers = []
for layer in layers:
if layer.__class__ == LayerObjects:
self._layers.append([layer.type,copy.deepcopy(layer.get_objs()),copy.copy(layer._attacked)])
def draw_eyes(self,vis,r_max,dphi):
for x in range(0,7):
GLU.gluPartialDisk(self.quad,
1,
vis[x][0] * r_max,
5,
3,
- ((x - 3) * 15 + 7.5 + dphi / pi * 180) + 90,
15)
def draw_sensitivity(self,sens,r_max,dphi):
for x in range(0,5):
GLU.gluPartialDisk(self.quad,
1,
sens[x] * r_max,
5,
3,
- (52.5 + (x+1) * 51 + dphi / pi * 180) + 90,
51)
pass
def draw_obj(self,obj,_id,pos,circle,lines,attacked):
# Кружок
GL.glLoadIdentity()
GL.glTranslatef(pos[0]-1,pos[1]-1,0)
red,green,blue = obj.color # берём цвет
GL.glColor3f(red,green,blue)
GLU.gluDisk(self.quad,*circle)
#Глазки
GL.glColor3f(1-red,1-green,1-blue)
try:
eyes = obj.eyes
except NameError:
pass
else:
self.draw_eyes(obj.eyes.eyes,obj.radius * k_screen,obj.pos[1])
# Прикосновения
GL.glColor3f(1,0,0)
try:
sensitivity = obj.sensitivity
except NameError:
pass
else:
self.draw_sensitivity(obj.sensitivity._sens,obj.radius * k_screen,obj.pos[1])
# Полосочки
GL.glBegin(GL.GL_LINES)
for color,x,y in lines:
GL.glColor3f(*color)
GL.glVertex3f(0,0,0)
GL.glVertex3f(x,y,0)
GL.glEnd()
def draw(self,layer):
global width,height
if layer[0] == "Layer Objects":
attacked = layer[2]
for obj in layer[1]:
#Стрелочки-направления
pos = [int(x) for x in obj.get_pos_screen()]
positions = [pos,]
radius_scr = obj.radius * k_screen
att = Vector(radius_scr * (1 +obj._attack_range*obj._attack),
obj.pos[1],
isPolar = True
)
speed = obj.speed[0] * k_screen * 5
if pos[0] < radius_scr:
positions.append([pos[0] + self.width,pos[1]])
if pos[0] + radius_scr > self.width:
positions.append([pos[0] - self.width,pos[1]])
if pos[1] < radius_scr:
positions.append([pos[0],pos[1] + self.height])
if pos[1] + radius_scr > self.height:
positions.append([pos[0],pos[1] - self.height])
for ps in positions:
self.draw_obj(obj,obj._id, ps , [0,obj.radius*k_screen,20,1], [ [ (1,0,0) , att.x, att.y ], [ (0,0,1) , speed.x, speed.y] ] , attacked)
self.infoScreen.draw()
Function code, that draws:
def _draw_prepare(self):
""" Копирует из глобальной переменной всё, что ей нужно """
self._layers = copy.deepcopy(layers)
def _loop(self):
global tick
if (self.ch == b'q') or (self.ch == b'\xb1') or (self.ch == 27) or (self.ch == 113):
isEnd = True
self.__del__()
del(self)
return 0
elif (self.ch == b's'):
self._is_draw = not self._is_draw
print("changed to %d" %self._is_draw)
else:
if (self.last_tick != tick) and (self._is_draw):
self.layers_lock.acquire(1)
self._draw_prepare()
self.layers_lock.release()
self.last_tick = tick
# рисует сцену
return self._main()
def _main(self):
global tick
self.clear()
if self._is_draw:
for layer in self._layers:
self.draw(layer)
self.update()
self.ch = self.getch()
And on GitHub

Related

tkinter image not loading, tclerror

I'll try to explain this to my best ability. Short story short, making a tic tac toe game for a school project. I have all the code necessary i think, but when i run my code, tkinter window opens no problem, but when i am to click in one of the squares where i can place a "x" or a "o" my image wont load into the grid.
When i click, this is one the errors that pops up:
line 2776, in _create
return self.tk.getint(self.tk.call(
_tkinter.TclError: unknown option "562.5"
If i was to guess, the error must be in both "def draw_o" and "def draw_x"
If you want to try the code here is the images to download: https://imgur.com/a/kKJPIop
If relevant image of assignment: https://imgur.com/a/3iu4MJy
from math import log
from tkinter import *
import numpy as np
size = 600
symbol_size = (size / 3 - size / 8) /2
symbol_thick = 50
symbol_x_color = '#EE4035'
symbol_o_color = '#0492CF'
green = '#7BC043'
class cell:
def __init__(self):
self.window = Tk()
self.window.title("Bondesjakk/Tic Tac Toe")
self.canvas = Canvas(self.window, width = size, height = size)
self.canvas.pack()
self.window.bind("<Button-1>", self.click)
self.initialize_board()
self.player_x_turns = True
self.board_status = np.zeros(shape=(3, 3) )
self.player_x_starts = True
self.reset_board = False
self.gameover = False
self.tie = False
self.x_wins = False
self.o_wins = False
self.x_score = False
self.o_score = False
self.tie_score = False
def mainloop(self):
self.window.mainloop()
def initialize_board(self):
for i in range(2):
self.canvas.create_line( (i + 1) * size / 3, 0, (i + 1) * size / 3, size)
for i in range(2):
self.canvas.create_line(0, (i + 1) * size / 3, size, (i + 1) * size / 3)
def play_again(self):
self.initialize_board()
self.player_x_starts = not self.player_x_starts
self.player_x_turns = self.player_x_starts
self.board_status = np.zeros(shape =(3, 3) )
def draw_o(self, logical_pos):
o_image = PhotoImage('book/pybook/image/o.gif')
logical_pos = np.array(logical_pos)
grid_pos = self.convert_logical_to_grid_pos(logical_pos)
self.canvas.create_image(grid_pos[0] - symbol_size, grid_pos[1] - symbol_size,
grid_pos[0] + symbol_size, grid_pos[1] + symbol_size, width = symbol_thick,
image = o_image)
def draw_x(self, logical_pos):
x_image = PhotoImage('book/pybook/image/x.gif')
grid_pos = self.convert_logical_to_grid_pos(logical_pos)
self.canvas.create_image(grid_pos[0] - symbol_size, grid_pos[1] - symbol_size,
grid_pos[0] + symbol_size, grid_pos[1] + symbol_size, width = symbol_thick,
image = x_image)
def display_gameover(self):
if self.x_wins:
self.x_score += 1
text = "Winner: Player 1(x)"
color = symbol_x_color
elif self.o_wins:
self.o_score += 1
text = "Winner: Player 2(o)"
color = symbol_o_color
else:
self.tie_score += 1
text = "It's a tie"
color = "gray"
self.canvas.delete("all")
self.canvas.create_text(size / 2, size / 3, font = "cmr 60 bold", fill = color, text = text)
score_text = 'Scores \n'
self.canvas.create_text(size / 2, 5 * size / 8, font = "cmr 40 bold", fill = green, text = score_text)
score_text = 'Player 1 (x) : ' + str(self.x_score) + '\n'
score_text = 'Player 2 (o) : ' + str(self.o_score) + '\n'
score_text = 'Tie : ' + str(self.tie_score) + '\n'
self.canvas.create_text(size / 2, 3 * size / 4, font = "cmr 30 bold", fill = green, text = score_text)
self.reset_board = True
score_text = "Click to play again \n"
self.canvas.create_text(size / 2, 15* size / 16, font = "cmr 20 bold", fill = "gray", text = score_text)
def convert_logical_to_grid_pos(self, logical_pos):
logical_pos = np.array(logical_pos, dtype = int)
return (size / 3) * logical_pos + size / 6
def convert_grid_to_logical_pos(self, grid_pos):
grid_pos = np.array(grid_pos)
return np.array(grid_pos // (size / 3), dtype = int)
def is_grid_occupied(self, logical_pos):
if self.board_status[logical_pos[0] ][logical_pos[1] ] == 0:
return False
else:
return True
def is_winner(self, player):
player = -1 if player == "x" else 1
#Three in a row
for i in range(3):
if self.board_status[i][1] == self.board_status[i][2] == player:
return True
if self.board_status[0][1] == self.board_status[2][i] == player:
return True
#Diagonals
if self.board_status[0][0] == self.board_status[1][1] == self.board_status[2][2] == player:
return True
if self.board_status[2][0] == self.board_status[1][1] == self.board_status[0][2] == player:
return True
return False
def is_tie(self):
r, c = np.where(self.board_status == 0)
tie = False
if len(r) == 0:
tie = True
return tie
def is_gameover(self):
self.x_wins = self.is_winner("x")
if not self.x_wins:
self.o_wins = self.is_winner("o")
if not self.o_wins:
self.tie = self.is_tie()
gameover = self.x.wins or self.o.wins or self.tie
if self.x_wins:
print("x wins!")
if self.o_wins:
print("o wins!")
if self.tie:
print("It's a tie!")
return gameover
def click(self, event):
grid_pos = [event.x, event.y]
logical_pos = self.convert_grid_to_logical_pos(grid_pos)
if not self.reset_board:
if self.player_x_turns:
if not self.is_grid_occupied(logical_pos):
self.draw_x(logical_pos)
self.board_status[logical_pos[0] ][logical_pos[1] ] = -1
self.player_x_turns = not self.player_x_turns
else:
if not self.is_grid_occupied(logical_pos):
self.draw_o(logical_pos)
self.board_status[logical_pos[0] ][logical_pos[1] ] = 1
self.player_x_turns = not self.player_x_turns
if self.gameover():
self.display_gameover()
else:
self.canvas.delete("all")
self.play_again()
self.reset_board = False
game_instance = cell()
game_instance.mainloop()
In create_image() you use x1, y1, x2, y2, width=... but it expects only position (x1,y1) as tuple (without x2,y2) and without width=...
x = grid_pos[0] - symbol_size
y = grid_pos[1] - symbol_size
self.canvas.create_image( (x, y), image=x_image)
EDIT:
You have other mistakes
In line if self.gameover() you have to remove ()
--
If you use PhotoImage('book/pybook/image/o.gif') then it treats it as string with image's data, not as path to file. You have to use file=
o_image = PhotoImage(file='book/pybook/image/o.gif')
--
But there is another problem. There is bug in PhotoImage which removes image from memory when it is assigned to local variable in function. You should assign to class variable using self.
self.o_image = PhotoImage(file='book/pybook/image/o.gif')
--
And here another problem. You load the same image again and again and you assign it to the same variable - so bug removes previous image from memory and it removes it from canvas.
You could load it only once in __init__ and later use all time the same self.o_image, self.x_image
def __init___(...):
self.o_image = PhotoImage(file='book/pybook/image/o.gif')
self.x_image = PhotoImage(file='book/pybook/image/x.gif')
Doc (effbot.org in archive.org): PhotoImage, Canvas

Python treating all instances of an object as the same

I'm making a game with pygame and pymunk as a physics engine. I'm trying to kill a bullet whenever it hits a player or goes past its lifetime.
When I tried to space.remove(self.shape) and the second bullet hits the player, it gives me an "AssertionError: shape not in space, already removed. I simply changed it to teleport the bullets away, and then learned of the real error.
When I have more than one bullet in the space and a bullet hits the enemy player, all the current bullets teleport away, which means that when I tried to remove one bullet, it called the remove on all the bullets and thats why I had the initial error.
However the problem still remains that one bullet is being treated as every bullet.
Why is something that should be a non-static variable being called as a static variable?
I even tried to use deepcopy to see if that fixed it, but to no avail
This is my chunk of code, apologies since I don't know what is needed to understand it.
The key parts are most likely the Bullet class, the shoot() function in the Player class, and the drawBulletCollision() function
# PyGame template.
# Import modules.
import sys, random, math, time, copy
from typing import List
import pygame
from pygame.locals import *
from pygame import mixer
import pymunk
import pymunk.pygame_util
from pymunk.shapes import Segment
from pymunk.vec2d import Vec2d
pygame.mixer.pre_init(44110, -16, 2, 512)
mixer.init()
# Set up the window.
width, height = 1440, 640
screen = pygame.display.set_mode((width, height))
bg = pygame.image.load("space.png")
def draw_bg():
screen.blit(bg, (0, 0))
#load sounds
#death_fx = pygame.mixer.Sound("")
#death_fx.set_volume(0.25)
shoot_fx = mixer.Sound("shot.wav")
shoot_fx.set_volume(0.25)
#mixer.music.load("video.mp3")
#mixer.music.play()
#time.sleep(2)
#mixer.music.stop()
#gun_mode_fx = pygame.mixer.Sound("")
#gun_mode_fx.set_volume(0.25)
#thrust_mode_fx = pygame.mixer.Sound("")
#thrust_mode_fx.set_volume(0.25)
collision_fx = mixer.Sound("thump.wav")
collision_fx.set_volume(0.25)
ship_group = pygame.sprite.Group()
space = pymunk.Space()
space.gravity = 0, 0
space.damping = 0.6
draw_options = pymunk.pygame_util.DrawOptions(screen)
bulletList = []
playerList = []
environmentList = []
arbiterList = []
b0 = space.static_body
segmentBot = pymunk.Segment(b0, (0,height), (width, height), 4)
segmentTop = pymunk.Segment(b0, (0,0), (width, 0), 4)
segmentLef = pymunk.Segment(b0, (width,0), (width, height), 4)
segmentRit = pymunk.Segment(b0, (0,0), (0, height), 4)
walls = [segmentBot,segmentLef,segmentRit,segmentTop]
for i in walls:
i.elasticity = 1
i.friction = 0.5
i.color = (255,255,255,255)
environmentList.append(i)
class Player(object):
radius = 30
def __init__(self, position, space, color):
self.body = pymunk.Body(mass=5,moment=10)
self.mode = 0 # 0 is gun, 1 is thrust, ? 2 is shield
self.body.position = position
self.shape = pymunk.Circle(self.body, radius = self.radius)
#self.image
#self.shape.friction = 0.9
self.shape.elasticity= 0.2
space.add(self.body,self.shape)
self.angleGun = 0
self.angleThrust = 0
self.health = 100
self.speed = 500
self.gearAngle = 0
self.turningSpeed = 5
self.shape.body.damping = 1000
self.cooldown = 0
self.fireRate = 30
self.shape.collision_type = 1
self.shape.color = color
playerList.append(self)
def force(self,force):
self.shape.body.apply_force_at_local_point(force,(0,0))
def rocketForce(self):
radians = self.angleThrust * math.pi/180
self.shape.body.apply_force_at_local_point((-self.speed * math.cos(radians),-self.speed * math.sin(radians)),(0,0))
def draw(self):
gear = pygame.image.load("gear.png")
gearBox = gear.get_rect(center=self.shape.body.position)
gearRotated = pygame.transform.rotate(gear, self.gearAngle)
#gearRotated.rect.center=self.shape.body.position
x,y = self.shape.body.position
radianGun = self.angleGun * math.pi/180
radianThrust = self.angleThrust * math.pi/180
radiyus = 30 *(100-self.health)/100
screen.blit(gearRotated,gearBox)
self.gearAngle += 1
if radiyus == 30:
radiyus = 32
pygame.draw.circle(screen,self.shape.color,self.shape.body.position,radiyus,0)
pygame.draw.circle(screen,(0,0,0),self.shape.body.position,radiyus,0)
pygame.draw.line(
screen,(0,255,0),
(self.radius * math.cos(radianGun) * 1.5 + x,self.radius * math.sin(radianGun) * 1.5 + y),
(x,y), 5
)
pygame.draw.line(
screen,(200,200,0),
(self.radius * math.cos(radianThrust) * 1.5 + x,self.radius * math.sin(radianThrust) * 1.5 + y),
(x,y), 5
)
#more
def targetAngleGun(self,tAngle):
tempTAngle = tAngle - self.angleGun
tempTAngle = tempTAngle % 360
if(tempTAngle < 180 and not tempTAngle == 0):
self.angleGun -= self.turningSpeed
elif(tempTAngle >= 180 and not tempTAngle == 0):
self.angleGun += self.turningSpeed
self.angleGun = self.angleGun % 360
#print(tAngle, "target Angle")
#print(self.angleGun, "selfangleGun")
#print(tempTAngle, "tempTAngle")
def targetAngleThrust(self,tAngle):
tempTAngle = tAngle - self.angleThrust
tempTAngle = tempTAngle % 360
if(tempTAngle < 180 and not tempTAngle == 0):
self.angleThrust -= self.turningSpeed
elif(tempTAngle >= 180 and not tempTAngle == 0):
self.angleThrust += self.turningSpeed
self.angleThrust = self.angleThrust % 360
#print(tAngle, "target Angle")
#print(self.angleThrust, "selfangleGun")
#print(tempTAngle, "tempTAngle")
def targetAngle(self,tAngle):
if(self.mode == 0):
self.targetAngleGun(tAngle)
elif(self.mode == 1):
self.targetAngleThrust(tAngle)
def shoot(self):
if(self.cooldown == self.fireRate):
x,y = self.shape.body.position
radianGun = self.angleGun * math.pi/180
spawnSpot = (self.radius * math.cos(radianGun) * 1.5 + x,self.radius * math.sin(radianGun)*1.5+y)
self.shape.body.apply_impulse_at_local_point((-20 * math.cos(radianGun),-20 * math.sin(radianGun)),(0,0))
print(spawnSpot)
bT = Bullet(spawnSpot, 5, 50,self.shape.color)
b = copy.deepcopy(bT)
bulletList.append(b)
space.add(b.shape,b.shape.body)
b.getShot(self.angleGun)
self.cooldown = 0
print('pew')
shoot_fx.play()
# HEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEREEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
def tick(self):
self.draw()
if(self.cooldown < self.fireRate):
self.cooldown += 1
#for o in playerList:
# c = self.shape.shapes_collide(o.shape)
# if(len(c.points)>0):
# self.damage(c.points[0].distance/10)
for o in bulletList:
c = self.shape.shapes_collide(o.shape)
#print(c)
for o in walls:
c = self.shape.shapes_collide(o)
if(len(c.points)>0):
self.damage(c.points[0].distance * 3)
def damage(self, damage):
self.health -= abs(damage)
if self.health < 0:
self.health = 0
#maybe make it part of the player class
def drawWallCollision(arbiter, space, data):
for c in arbiter.contact_point_set.points:
r = max(3, abs(c.distance * 5))
r = int(r)
p = tuple(map(int, c.point_a))
pygame.draw.circle(data["surface"], pygame.Color("red"), p, r, 0)
print('magnitude', math.sqrt(arbiter.total_impulse[0]**2 + arbiter.total_impulse[1]**2))
#print('position', p)
#print(data)
print("its all arbitrary")
s1, s2 = arbiter.shapes
collision_fx.play()
def drawBulletCollision(arbiter, space, data):
s1, s2 = arbiter.shapes
for c in arbiter.contact_point_set.points:
magnitude = math.sqrt(arbiter.total_impulse[0]**2 + arbiter.total_impulse[1]**2)
for p in playerList:
avr = ((c.point_a[0] + c.point_b[0])/2, (c.point_a[1] + c.point_b[1])/2)
distance = (math.sqrt((avr[0] - p.shape.body.position[0]) **2 + (avr[1] - p.shape.body.position[1]) **2 ))
if(distance < Bullet.explosionRadius + Player.radius):
if not(s1.color == s2.color):
p.damage(magnitude)
for b in bulletList:
avr = ((c.point_a[0] + c.point_b[0])/2, (c.point_a[1] + c.point_b[1])/2)
distance = (math.sqrt((avr[0] - p.shape.body.position[0]) **2 + (avr[1] - p.shape.body.position[1]) **2 ))
if(distance < Bullet.explosionRadius + Player.radius):
if not(s1.color == s2.color):
b.damage(magnitude)
pygame.draw.circle(data["surface"], pygame.Color("red"), tuple(map(int, c.point_a)), 10, 0)
print('magnitude', magnitude)
#print('position', p)
#print(data)
print("its all arbitrary")
def drawArbitraryCollision(arbiter, space, data):
collision_fx.play()
class Ship(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("gear.png")
self.rect = self.image.get_rect()
self.rect.center = [x, y]
def rotate(self):
self.image = pygame.transform.rotate(self.image,1)
class Bullet(object):
damage = 2
explosionRadius = 5
def __init__(self, position, size, speed,color):
pts = [(-size, -size), (size, -size), (size, size), (-size, size)]
self.body = copy.deepcopy(pymunk.Body(mass=0.1,moment=1))
self.shape = copy.deepcopy(pymunk.Poly(self.body, pts))
self.shape.body.position = position
self.shape.friction = 0.5
self.shape.elasticity = 1
self.shape.color = color
self.speed = speed
self.size = size
self.shape.collision_type = 2
#space.add(self.body,self.shape)
#bulletList.append(self)
self.lifetime = 0
def getShot(self,angle):
radians = angle * math.pi/180
self.shape.body.apply_impulse_at_local_point((self.speed * math.cos(radians),self.speed * math.sin(radians)),(0,0))
def tick(self):
self.lifetime += 1
if(self.lifetime > 300):
self.shape.body.position = (10000,30)
def damage(self, damage):
self.lifetime = 300
#VELOCITY OF BULLET STARTS WITH VELOCITY OF PLAYER
#MAKE VOLUME OF SOUND DEPEND ON THE IMPULSE FOR THE IMPACTS
#error on purpose so you notice this
#INSTANCES NOT WORKING????
def runPyGame():
# Initialise PyGame.
pygame.init()
# Set up the clock. This will tick every frame and thus maintain a relatively constant framerate. Hopefully.
fps = 60.0
fpsClock = pygame.time.Clock()
running = True
font = pygame.font.SysFont("Arial", 16)
p1 = Player((240,240),space,(132, 66, 245,255))
p2 = Player((1200,400),space,(47, 247, 184,255))
space.add(segmentBot,segmentTop,segmentLef,segmentRit)
# Main game loop.
ch = space.add_collision_handler(1, 0)
ch.data["surface"] = screen
ch.post_solve = drawWallCollision
ch = space.add_collision_handler(1, 2)
ch.data["surface"] = screen
ch.post_solve = drawBulletCollision
ch = space.add_collision_handler(0, 2)
ch.data["surface"] = screen
ch.post_solve = drawArbitraryCollision
dt = 1/fps # dt is the time since last frame.
while True: # Loop forever!
keys = pygame.key.get_pressed()
for event in pygame.event.get():
# We need to handle these events. Initially the only one you'll want to care
# about is the QUIT event, because if you don't handle it, your game will crash
# whenever someone tries to exit.
if event.type == QUIT:
pygame.quit() # Opposite of pygame.init
sys.exit() # Not including this line crashes the script on Windows.
if event.type == KEYDOWN:
if event.key == pygame.K_s:
p1.mode = -(p1.mode - 0.5) + 0.5
print(p1.mode)
if (event.key == pygame.K_k and p1.mode == 0):
p1.shoot()
if event.key == pygame.K_KP_5:
p2.mode = -(p2.mode - 0.5) + 0.5
print(p2.mode)
if (event.key == pygame.K_m and p2.mode == 0):
p2.shoot()
#b = Bullet((200,200),51,51)
if(keys[K_w]):
p1.targetAngle(90)
if(keys[K_q]):
p1.targetAngle(45)
if(keys[K_a]):
p1.targetAngle(0)
if(keys[K_z]):
p1.targetAngle(315)
if(keys[K_x]):
p1.targetAngle(270)
if(keys[K_c]):
p1.targetAngle(225)
if(keys[K_d]):
p1.targetAngle(180)
if(keys[K_e]):
p1.targetAngle(135)
if(keys[K_k] and p1.mode == 1):
p1.rocketForce()
if(keys[K_KP_8]):
p2.targetAngle(90)
if(keys[K_KP_7]):
p2.targetAngle(45)
if(keys[K_KP_4]):
p2.targetAngle(0)
if(keys[K_KP_1]):
p2.targetAngle(315)
if(keys[K_KP_2]):
p2.targetAngle(270)
if(keys[K_KP_3]):
p2.targetAngle(225)
if(keys[K_KP_6]):
p2.targetAngle(180)
if(keys[K_KP_9]):
p2.targetAngle(135)
if(keys[K_m] and p2.mode == 1):
p2.rocketForce()
# Handle other events as you wish.
screen.fill((250, 250, 250)) # Fill the screen with black.
# Redraw screen here.
### Draw stuff
draw_bg()
space.debug_draw(draw_options)
for i in playerList:
i.tick()
screen.blit(
font.render("P1 Health: " + str(p1.health), True, pygame.Color("white")),
(50, 10),
)
screen.blit(
font.render("P2 Health: " + str(p2.health), True, pygame.Color("white")),
(50, 30),
)
for i in bulletList:
i.tick()
ship_group.draw(screen)
# Flip the display so that the things we drew actually show up.
pygame.display.update()
dt = fpsClock.tick(fps)
space.step(0.01)
pygame.display.update()
runPyGame()
I cant point to the exact error since the code is quite long and depends on files I dont have. But here is a general advice for troubleshooting:
Try to give a name to each shape when you create them, and then print it out. Also print out the name of each shape that you add or remove from the space. This should show which shape you are actually removing and will probably make it easy to understand whats wrong.
For example:
...
self.shape = pymunk.Circle(self.body, radius = self.radius)
self.shape.name = "circle 1"
print("Created", self.shape.name)
...
print("Adding", self.shape.name)
space.add(self.body,self.shape)
...
(Note that you need to reset the name of shapes you copy, since otherwise the copy will have the same name.)

Don't understand cause of RuntimeError: An attempt has been made to start a new process before the current process has finished

I am trying to use a map generator I made a few months ago. I remember it worked, I even showed it to some people, but now, it just doesn't work. I havent changed the python version, so this feels quite weird.
When I try to execute the code, I get this error:
RuntimeError:
An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.
This probably means that you are not using fork to start your
child processes and you have forgotten to use the proper idiom
in the main module:
if __name__ == '__main__':
freeze_support()
...
The "freeze_support()" line can be omitted if the program
is not going to be frozen to produce an executable.
I have made some research, and the only thing I find is people saying "add the line freeze_support() and it'll work", and it usually does, but it isn't working for me. I've tried torch.multiprocessing.freeze_support(), multiprocessing.freeze_support() and freeze_support(), but it gives the exact same error.
Here is my code:
#!/usr/bin/python3
import os
import signal
import sys
import numpy as np
from multiprocessing import Process, Manager, Value, Array
from threading import Thread
import pygame as pg
vec = pg.math.Vector2
manager = Manager()
SETTINGS = manager.dict()
start_settings = Value('i', 0)
in_settings = Value('i', 0)
quit_settings = Value('i', 0)
reset_settings = Value('i', 0)
generation_finished = Value('i', 0)
generation_started = Value('i', 0)
chunks_generated = Value('i', 0)
apply_settings = Value('i', 0)
SETTINGS["oct"] = 1
SETTINGS["scl"] = 250
SETTINGS["sea"] = 60
SETTINGS["lac"] = 2
SETTINGS["seed"] = 0
SETTINGS["wdh"] = 600
SETTINGS["hgt"] = 600
SETTINGS["offset"] = [0, 0]
SETTINGS["mwd"] = 600
SETTINGS["mhg"] = 600
SETTINGS["zoom"] = 0
SETTINGS["zoom_slider"] = 0
SETTINGS["noise"] = 2
SHARED_MAP = manager.dict()
def remap(OldValue, OldMin, OldMax, NewMin, NewMax):
OldRange = (float(OldMax) - float(OldMin))
NewRange = (float(NewMax) - float(NewMin))
NewValue = (((float(OldValue) - float(OldMin)) * NewRange) / OldRange) + float(NewMin)
return NewValue
def create_noise(iterations, x, y, scale, lacunarity, low, high, ngen):
maxAmp = 0
amp = 1
persistence = 0.5
freq = scale
noise = 0
for i in range(iterations):
noise = noise + ngen.noise2d(x/freq, y/freq) * amp
maxAmp = maxAmp + amp
amp = amp * persistence
freq = freq / lacunarity
noise = noise / maxAmp
noise = noise * (high - low) / 2 + (high + low) / 2
return int(high-noise)
def draw_colored(octv, scale, sea, width, height, lac, pos, seed, noise, offset):
from noise import pnoise2, snoise2
from opensimplex import OpenSimplex
import numpy as np
generation_started.value = 1
xoffset = offset[0] + pos[0]
yoffset = offset[1] + pos[1]
world = np.full((height, width, 3), 255, dtype=np.uint8)
normal_world = world.copy()
# Color all pixels
for x in range(width):
# print(x)
for y in range(height):
if noise == 2:
n = remap(snoise2((x+xoffset)/scale, (y+yoffset)/scale,
octaves=octv, base=seed, lacunarity=lac), -1, 1, 0, 100)
elif noise == 1:
n = remap(pnoise2((x+xoffset)/scale, (y+yoffset)/scale,
octaves=octv, base=seed, lacunarity=lac), -1, 1, 0, 100)
elif noise == 0:
ngen = OpenSimplex(seed)
n = create_noise(octv, x+xoffset, y+yoffset, scale, lac, 0, 100, ngen)
color_dist = int((100-sea)/(octv+2))
if n >= sea:
r = range(sea, 100, color_dist)
hmap = []
cmap = []
for i in r:
hmap.append(i)
cmap.append(remap(i, sea, 100, 150, 255))
d = 255-max(cmap)
for i, h in enumerate(hmap):
if n >= h:
normal_world[y][x][0] = cmap[i]/6
normal_world[y][x][1] = cmap[i] + d
normal_world[y][x][2] = cmap[i]/2
world[y][x][0] = cmap[i]/2
world[y][x][1] = cmap[i]
world[y][x][2] = cmap[i]/3
else:
r = range(0, sea, color_dist*2+1)
hmap = []
cmap = []
for i in r:
hmap.append(i)
cmap.append(remap(i, 0, sea, 50, 150))
for i, h in enumerate(hmap):
if n >= h:
normal_world[y][x][0] = 0
normal_world[y][x][1] = 0
normal_world[y][x][2] = cmap[i]
world[y][x][0] = cmap[i]
world[y][x][1] = 0
world[y][x][2] = 0
SHARED_MAP[tuple(pos)] = normal_world
generation_started.value = 0
generation_finished.value = 1
chunks_generated.value += 1
def sw():
import pygame as pg
from pgui import Slider, Entry, Button, CheckBox
import json
import os
pg.init()
pg.display.set_caption("Settings")
class CustomCheckBox:
def __init__(self, parent, *, x=0, y=0, size=20):
self.parent = parent
self.screen = parent.screen
self.box = CheckBox(self, x=x, y=y, size=size)
self.bg_color = (255, 255, 255)
self.border_width = 3
self.border_color = (0, 0, 0)
self.check_color = (0, 200, 0)
self.cross_width = 5
self.checked = False
self.check_style = "fill"
self.label_side = "top"
self.label_align = "left"
self.label_padding = 3
def update(self):
self.group = self.parent.noise_options
if self.box.clicked:
self.checked = True
for c in self.group:
if c != self:
c.checked = False
else:
pass
self.sync_attributes()
self.box.update()
def sync_attributes(self):
# ------- ATTRIBUTES -------
self.box.bg_color = self.bg_color
self.box.border_width = self.border_width
self.box.border_color = self.border_color
self.box.check_color = self.check_color
self.box.cross_width = self.cross_width
self.box.checked = self.checked
self.box.check_style = self.check_style
self.box.label_side = self.label_side
self.box.label_align = self.label_align
self.box.label_padding = self.label_padding
# --------------------------
def move(self, x, y):
self.box.move(x, y)
def set_font(self, font):
self.box.set_font(font)
def set_font_size(self, size):
self.box.set_font_size(size)
def set_font_color(self, color):
self.box.set_font_color(color)
def set_size(self, size):
self.box.set_size(size)
def set_style(self, style):
self.box.set_style(style)
def set_label(self, text):
self.box.set_label(text)
class Screen:
def create(self):
self.screen = pg.display.set_mode((800, 600))
self.load_button = Button(self, text="Load config", func=self.load)
self.load_button.move(20, 555)
self.load_button.height = 25
self.load_button.set_font_size(15)
self.save_button = Button(self, text="Save config", func=self.save)
self.save_button.move(145, 555)
self.save_button.height = 25
self.save_button.set_font_size(15)
self.reset_button = Button(self, text="Reset config", func=self.reset)
self.reset_button.move(270, 555)
self.reset_button.height = 25
self.reset_button.set_font_size(15)
self.opensimplex_option = CustomCheckBox(self, x=20, y=20)
self.opensimplex_option.check_color = (0, 0, 0)
self.opensimplex_option.set_font_size(15)
self.opensimplex_option.set_label("OpenSimplex noise")
self.opensimplex_option.label_side = "right"
self.opensimplex_option.label_padding = 5
self.perlin_noise_option = CustomCheckBox(self, x=20, y=50)
self.perlin_noise_option.check_color = (0, 0, 0)
self.perlin_noise_option.set_font_size(15)
self.perlin_noise_option.set_label("Perlin noise")
self.perlin_noise_option.label_side = "right"
self.perlin_noise_option.label_padding = 5
self.simplex_option = CustomCheckBox(self, x=20, y=80)
self.simplex_option.check_color = (0, 0, 0)
self.simplex_option.set_font_size(15)
self.simplex_option.set_label("Simplex noise")
self.simplex_option.label_side = "right"
self.simplex_option.label_padding = 5
self.settings_file = Entry(self, x=20, y=500, border=1, size=15, width=300)
self.settings_file.width = 300
self.settings_file.text = "settings.json"
self.settings_file.set_label("Settings file:")
self.noise_options = [
self.opensimplex_option,
self.perlin_noise_option,
self.simplex_option
]
self.noise_options[SETTINGS["noise"]].checked = True
self.widgets = [
self.load_button,
self.save_button,
self.reset_button,
self.opensimplex_option,
self.perlin_noise_option,
self.simplex_option,
self.settings_file
]
for w in self.widgets:
w.border_width = 1
def load(self):
filename = self.settings_file.text
if os.path.isfile(filename):
with open(filename, 'r') as f:
settings = json.load(f)
SETTINGS.update(settings)
self.apply_settings()
self.settings_file.set_label("Settings file:")
else:
self.settings_file.set_label("Settings file: No file at " + os.path.abspath(filename))
def save(self):
settings = SETTINGS.copy()
filename = "settings.json"
with open(filename, 'w') as f:
json.dump(settings, f)
def apply_settings(self):
apply_settings.value = 1
for i in self.noise_options:
i.checked = False
self.noise_options[SETTINGS["noise"]].checked = True
def reset(self):
reset_settings.value = 1
SETTINGS["noise"] = 2
self.noise_options[2].checked = True
self.noise_options[0].checked = False
self.noise_options[1].checked = False
def run(self):
if start_settings.value:
self.create()
start_settings.value = 0
in_settings.value = 1
if in_settings.value:
self.update()
self.events()
if quit_settings.value:
raise SystemExit
def update(self):
self.screen.fill((200, 200, 200))
for w in self.widgets:
w.update()
noises = [
self.opensimplex_option.checked,
self.perlin_noise_option.checked,
self.simplex_option.checked
]
for i, n in enumerate(noises):
if noises[i]:
SETTINGS["noise"] = i
pg.display.flip()
def events(self):
if in_settings.value:
for event in pg.event.get():
if event.type == pg.QUIT:
in_settings.value = 0
pg.display.quit()
elif event.type == pg.KEYDOWN:
if event.key == pg.K_ESCAPE:
in_settings.value = 0
pg.display.quit()
sc = Screen()
while True:
sc.run()
def editor():
import pygame as pg
from pgui import Slider, Entry, Button, CheckBox
import os
import cv2
pg.init()
screen = pg.display.set_mode((1200, 704))
pg.display.set_caption("Map creator")
class Editor:
def __init__(self):
self.screen = screen
self.value = 5
self.oct_slider = Slider(self, max=7)
self.oct_slider.move(20, 40)
self.oct_slider.set_length(300)
self.oct_slider.set_font_size(15)
self.oct_slider.set_width(15)
self.oct_slider.set_label("Octaves: 1")
self.oct_slider.set_mark(0)
self.sea_level_slider = Slider(self)
self.sea_level_slider.move(20, 80)
self.sea_level_slider.set_length(300)
self.sea_level_slider.set_font_size(15)
self.sea_level_slider.set_width(15)
self.sea_level_slider.set_label("Sea level: 60")
self.sea_level_slider.set_mark(60)
self.scale_slider = Slider(self, max=599)
self.scale_slider.move(575, 660)
self.scale_slider.set_length(585)
self.scale_slider.set_font_size(15)
self.scale_slider.set_width(15)
self.scale_slider.set_label("Scale: 100")
self.scale_slider.set_mark(99)
self.zoom_slider = Slider(self, max=200, orientation="vertical")
self.zoom_slider.move(525, 25)
self.zoom_slider.set_length(585)
self.zoom_slider.label_align = "center"
self.zoom_slider.set_font_size(15)
self.zoom_slider.set_label("Zoom: 1")
self.zoom_slider.set_width(15)
self.zoom_slider.set_mark(175)
self.zoom = 1
self.map_surface = pg.Surface((600, 600))
self.map_surface.fill(0)
self.map_rect = self.map_surface.get_rect()
self.map_rect.topleft = (575, 25)
self.map = pg.Surface((SETTINGS["wdh"], SETTINGS["hgt"]))
self.map.fill((100, 100, 100))
self.width_slider = Slider(self, max=120)
self.width_slider.move(20, 120)
self.width_slider.set_length(300)
self.width_slider.set_font_size(15)
self.width_slider.set_width(15)
self.width_slider.set_label("Width: 600")
self.width_slider.set_mark(50)
self.height_slider = Slider(self, max=120)
self.height_slider.move(20, 160)
self.height_slider.set_length(300)
self.height_slider.set_font_size(15)
self.height_slider.set_width(15)
self.height_slider.set_label("Height: 600")
self.height_slider.set_mark(50)
self.pos_entry = Entry(self, x=20, y=200, border=1, size=15)
self.pos_entry.text = '0,0'
self.pos_entry.set_label("X,Y Position:")
self.lac_slider = Slider(self, max=40)
self.lac_slider.move(20, 240)
self.lac_slider.set_length(300)
self.lac_slider.set_font_size(15)
self.lac_slider.set_width(15)
self.lac_slider.set_label("Lacunarity: 2")
self.lac_slider.set_mark(10)
self.seed_entry = Entry(self, x=20, y=360, border=1, size=15)
self.seed_entry.text = '0'
self.seed_entry.set_label("Seed:")
self.draw_button = Button(self, x=20, y=625, text="Generate", func=self.draw)
self.draw_button.width = 315
self.clear_button = Button(self, x=345, y=625, text="Clear", func=self.clear)
self.settings_button = Button(self, x=20, y=570, text='Settings', func=self.settings)
self.settings_button.height = 25
self.settings_button.set_font_size(15)
self.abort_button = Button(self, x=140, y=570, text='Abort', func=self.abort_generation)
self.abort_button.height = 25
self.abort_button.set_font_size(15)
self.save_button = Button(self, x=260, y=570, text='Save', func=self.save)
self.save_button.height = 25
self.save_button.set_font_size(15)
self.save_name = Entry(self, x=380, y=570)
self.save_name.text = "image.png"
self.save_name.set_font_size(15)
self.save_name.set_label("Save to file:")
self.widgets = [
self.oct_slider,
self.sea_level_slider,
self.draw_button,
self.scale_slider,
self.zoom_slider,
self.width_slider,
self.height_slider,
self.pos_entry,
self.lac_slider,
self.seed_entry,
self.clear_button,
self.settings_button,
self.abort_button,
self.save_button,
self.save_name
]
self.width_chunks = 4
self.height_chunks = 4
for w in self.widgets:
w.border_width = 1
if isinstance(w, Slider):
w.pointer_border_width = 1
self.movable_map_rect = pg.Rect((0, 0), (600, 600))
self.dragging = False
self.dist = vec(0, 0)
def settings(self):
start_settings.value = 1
def save(self):
filename = self.save_name.text
if filename[-4:] != ".png":
filename += ".png"
surf = pg.transform.rotate(self.map, 90)
surf = pg.transform.flip(surf, 0, 1)
image = []
for x in range(SETTINGS["mwd"]):
row = []
for y in range(SETTINGS["mhg"]):
row.append(surf.get_at((x, y)))
image.append(row)
image = np.array(image)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
print("saving image")
cv2.imwrite(filename, image)
def abort_generation(self):
if generation_started.value:
print("Generation aborted")
for p in self.draw_threads:
p.terminate()
p.join()
generation_started.value = 0
def draw(self):
SETTINGS["mwd"] = SETTINGS["wdh"]
SETTINGS["mhg"] = SETTINGS["hgt"]
SHARED_MAP.clear()
chunks_generated.value = 0
self.draw_threads = []
for x in range(self.width_chunks):
for y in range(self.height_chunks):
width = int(SETTINGS["wdh"]/self.width_chunks)
height = int(SETTINGS["hgt"]/self.height_chunks)
pos = [x*width, y*height]
self.draw_threads.append(Thread(target=draw_colored, args=(SETTINGS["oct"],
SETTINGS["scl"],
SETTINGS["sea"],
width,
height,
SETTINGS["lac"],
pos,
SETTINGS["seed"],
SETTINGS["noise"],
SETTINGS["offset"])))
for p in self.draw_threads:
p.start()
def clear(self):
self.map.fill((100, 100, 100))
self.map_surface.fill(0)
SHARED_MAP.clear()
chunks_generated.value = 0
def run(self):
self.update()
self.events()
def reset_settings(self):
self.oct_slider.set_mark(0)
self.sea_level_slider.set_mark(60)
self.scale_slider.set_mark(99)
self.zoom_slider.set_mark(175)
self.map.fill((100, 100, 100))
self.width_slider.set_mark(50)
self.height_slider.set_mark(50)
self.lac_slider.set_mark(10)
self.pos_entry.text = '0,0'
self.seed_entry.text = '0'
self.mmrect.topleft = self.map_rect.topleft
self.movable_map_rect.topleft = (0, 0)
self.dist = vec(0, 0)
def update_settings(self):
self.oct_slider.set_mark(SETTINGS["oct"]-1)
self.sea_level_slider.set_mark(SETTINGS["sea"])
self.scale_slider.set_mark(SETTINGS["scl"]-1)
self.zoom_slider.set_mark(SETTINGS["zoom_slider"])
self.zoom = SETTINGS["zoom"]
self.width_slider.set_mark(int((SETTINGS["wdh"]-100)/10))
self.height_slider.set_mark(int((SETTINGS["hgt"]-100)/10))
pos = SETTINGS["offset"]
x = str(pos[0])
y = str(pos[1])
self.pos_entry.text = x+','+y
self.lac_slider.set_mark(SETTINGS["lac"]*10-10)
self.seed_entry.text = str(SETTINGS["seed"])
def update(self):
mousepos = vec(pg.mouse.get_pos())
p1 = pg.mouse.get_pressed()[0]
# print(p1, mousepos)
self.screen.fill((200, 200, 200))
if reset_settings.value:
reset_settings.value = 0
self.reset_settings()
if apply_settings.value:
apply_settings.value = 0
self.update_settings()
if generation_finished.value:
generation_finished.value = 0
width = len(SHARED_MAP.values()[0])
height = len(SHARED_MAP.values()[0][0])
self.map = pg.Surface((width*self.width_chunks, height*self.height_chunks))
self.map.fill((100, 100, 100))
self.map_surface.fill((100, 100, 100))
for c in SHARED_MAP.items():
pos = c[0]
chunk = c[1]
map_chunk = pg.pixelcopy.make_surface(chunk)
self.map.blit(map_chunk, (pos[1], pos[0]))
self.map = pg.transform.flip(pg.transform.rotate(self.map, -90), 1, 0)
self.movable_map = pg.transform.scale(
self.map, (int(SETTINGS["mwd"]*self.zoom), int(SETTINGS["mhg"]*self.zoom)))
self.movable_map_rect.size = self.movable_map.get_rect().size
self.mmrect = self.movable_map_rect.copy()
self.mmrect.topleft = vec(self.mmrect.topleft) + vec(575, 25)
if self.mmrect.collidepoint(mousepos) and self.map_rect.collidepoint(mousepos):
mpos = vec(mousepos) - vec(575, 25)
if p1 and not self.dragging:
self.dragging = True
self.dist = mousepos - vec(self.mmrect.topleft)
elif self.dragging and p1:
self.mmrect.topleft = mousepos - self.dist
self.movable_map_rect.center = vec(self.mmrect.center) - vec(575, 25)
elif self.dragging and not p1:
self.dragging = False
self.map_surface.fill(0)
self.map_surface.blit(self.movable_map, self.movable_map_rect)
self.screen.blit(self.map_surface, self.map_rect)
pg.draw.rect(self.screen, (0, 0, 0), self.map_rect, 1)
for w in self.widgets:
w.update()
SETTINGS["oct"] = self.oct_slider.mark+1
SETTINGS["scl"] = self.scale_slider.mark+1
SETTINGS["sea"] = self.sea_level_slider.mark
try:
seed = int(self.seed_entry.text)
except:
if self.seed_entry.text.strip() != '':
seed = int("".join([str(ord(c)) for c in self.seed_entry.text]))
else:
seed = 0
self.oct_slider.set_label("Octaves: "+str(self.oct_slider.mark+1))
self.sea_level_slider.set_label("Sea level: "+str(self.sea_level_slider.mark))
self.scale_slider.set_label("Scale: "+str(self.scale_slider.mark+1))
self.zoom_slider.set_label("Zoom: "+str(self.zoom_slider.max-self.zoom_slider.mark-25))
SETTINGS["zoom_slider"] = self.zoom_slider.mark
zoomval = (self.zoom_slider.max-self.zoom_slider.mark)/25
if zoomval <= 0:
self.zoom = 0.025
else:
self.zoom = zoomval
SETTINGS["zoom"] = self.zoom
self.width_slider.set_label("Width: "+str((self.width_slider.mark)*10+100))
SETTINGS["wdh"] = (self.width_slider.mark)*10+100
self.height_slider.set_label("Height: "+str((self.height_slider.mark)*10+100))
SETTINGS["hgt"] = (self.height_slider.mark)*10+100
self.lac_slider.set_label("Lacunarity: "+str((self.lac_slider.mark+10)/10))
SETTINGS["lac"] = (self.lac_slider.mark+10)/10
pos = self.pos_entry.text.strip().split(',')
for i, p in enumerate(pos):
if p != '':
try:
pos[i] = int(p)
except:
pos[i] = 0
SETTINGS["offset"] = pos
pg.display.flip()
def events(self):
for event in pg.event.get():
if event.type == pg.QUIT:
if not in_settings.value:
quit_settings.value = 1
raise SystemExit
if event.type == pg.MOUSEWHEEL:
if self.map_rect.collidepoint(pg.mouse.get_pos()):
try:
m = self.zoom_slider.mark-event.y
self.zoom_slider.set_mark(m)
except:
self.zoom_slider.set_mark(200)
e = Editor()
while True:
e.run()
if __name__ == "__main__":
freeze_support()
set = Process(target=sw)
ed = Process(target=editor)
set.start()
ed.start()
set.join()
ed.join()
Here is the "settings.json" file needed to run the script:
{
"oct": 8,
"scl": 300,
"sea": 60,
"lac": 2.3,
"seed": 0,
"wdh": 600,
"hgt": 600,
"offset": [100, 100],
"mwd": 600,
"mhg": 600,
"zoom": 1.0,
"zoom_slider": 175,
"noise": 1
}
UPDATE: I have been able to find the line causing the error, which is line 12, manager = Manager(). I have tried looking for issues on the github repo, but I haven't been able to find anything. Is there any work around for this?
I don't have pygame installed and did not want to install it because I do not know pygame and am not really in a position to debug your program if you have other issues with your code other than the obvious things I saw. So I was not able to really test this. But I believe this is at least a good start in the right direction, if not perfect.
Instead of starting two processes, I have created a processing pool of size 2 to which I submit 2 "tasks." But what this allows me to do is to create the managed variables in my main process within the if __name__ == '__main__': block and then to initialize each process in the pool with global variables initialized with these values using a special pool initializer function. The only other change I made is based on the comment I posted to your question. I have therefore renamed method apply_settings to apply_our_settings.
#!/usr/bin/python3
import os
import signal
import sys
import numpy as np
from multiprocessing import Pool, Manager, Value
from threading import Thread
import pygame as pg
import traceback
# initialize processing pool's processes with global variables:
def init_pool(settings, shared_map, s_s, i_s, q_s, r_s, g_f, g_s, c_g, a_s):
global SETTINGS, SHARED_MAP, start_settings, in_settings, quit_settings, reset_settings, \
generation_finished, generation_started, chunks_generated, apply_settings
SETTINGS = settings
SHARED_MAP = shared_map
start_settings = s_s
in_settings = i_s
quit_settings = q_s
reset_settings = r_s
generation_finished = g_f
generation_started = g_s
chunks_generated = c_g
apply_settings = a_s
def remap(OldValue, OldMin, OldMax, NewMin, NewMax):
OldRange = (float(OldMax) - float(OldMin))
NewRange = (float(NewMax) - float(NewMin))
NewValue = (((float(OldValue) - float(OldMin)) * NewRange) / OldRange) + float(NewMin)
return NewValue
def create_noise(iterations, x, y, scale, lacunarity, low, high, ngen):
maxAmp = 0
amp = 1
persistence = 0.5
freq = scale
noise = 0
for i in range(iterations):
noise = noise + ngen.noise2d(x/freq, y/freq) * amp
maxAmp = maxAmp + amp
amp = amp * persistence
freq = freq / lacunarity
noise = noise / maxAmp
noise = noise * (high - low) / 2 + (high + low) / 2
return int(high-noise)
def draw_colored(octv, scale, sea, width, height, lac, pos, seed, noise, offset):
from noise import pnoise2, snoise2
from opensimplex import OpenSimplex
import numpy as np
generation_started.value = 1
xoffset = offset[0] + pos[0]
yoffset = offset[1] + pos[1]
world = np.full((height, width, 3), 255, dtype=np.uint8)
normal_world = world.copy()
# Color all pixels
for x in range(width):
# print(x)
for y in range(height):
if noise == 2:
n = remap(snoise2((x+xoffset)/scale, (y+yoffset)/scale,
octaves=octv, base=seed, lacunarity=lac), -1, 1, 0, 100)
elif noise == 1:
n = remap(pnoise2((x+xoffset)/scale, (y+yoffset)/scale,
octaves=octv, base=seed, lacunarity=lac), -1, 1, 0, 100)
elif noise == 0:
ngen = OpenSimplex(seed)
n = create_noise(octv, x+xoffset, y+yoffset, scale, lac, 0, 100, ngen)
color_dist = int((100-sea)/(octv+2))
if n >= sea:
r = range(sea, 100, color_dist)
hmap = []
cmap = []
for i in r:
hmap.append(i)
cmap.append(remap(i, sea, 100, 150, 255))
d = 255-max(cmap)
for i, h in enumerate(hmap):
if n >= h:
normal_world[y][x][0] = cmap[i]/6
normal_world[y][x][1] = cmap[i] + d
normal_world[y][x][2] = cmap[i]/2
world[y][x][0] = cmap[i]/2
world[y][x][1] = cmap[i]
world[y][x][2] = cmap[i]/3
else:
r = range(0, sea, color_dist*2+1)
hmap = []
cmap = []
for i in r:
hmap.append(i)
cmap.append(remap(i, 0, sea, 50, 150))
for i, h in enumerate(hmap):
if n >= h:
normal_world[y][x][0] = 0
normal_world[y][x][1] = 0
normal_world[y][x][2] = cmap[i]
world[y][x][0] = cmap[i]
world[y][x][1] = 0
world[y][x][2] = 0
SHARED_MAP[tuple(pos)] = normal_world
generation_started.value = 0
generation_finished.value = 1
chunks_generated.value += 1
def sw():
import pygame as pg
from pgui import Slider, Entry, Button, CheckBox
import json
import os
pg.init()
pg.display.set_caption("Settings")
class CustomCheckBox:
def __init__(self, parent, *, x=0, y=0, size=20):
self.parent = parent
self.screen = parent.screen
self.box = CheckBox(self, x=x, y=y, size=size)
self.bg_color = (255, 255, 255)
self.border_width = 3
self.border_color = (0, 0, 0)
self.check_color = (0, 200, 0)
self.cross_width = 5
self.checked = False
self.check_style = "fill"
self.label_side = "top"
self.label_align = "left"
self.label_padding = 3
def update(self):
self.group = self.parent.noise_options
if self.box.clicked:
self.checked = True
for c in self.group:
if c != self:
c.checked = False
else:
pass
self.sync_attributes()
self.box.update()
def sync_attributes(self):
# ------- ATTRIBUTES -------
self.box.bg_color = self.bg_color
self.box.border_width = self.border_width
self.box.border_color = self.border_color
self.box.check_color = self.check_color
self.box.cross_width = self.cross_width
self.box.checked = self.checked
self.box.check_style = self.check_style
self.box.label_side = self.label_side
self.box.label_align = self.label_align
self.box.label_padding = self.label_padding
# --------------------------
def move(self, x, y):
self.box.move(x, y)
def set_font(self, font):
self.box.set_font(font)
def set_font_size(self, size):
self.box.set_font_size(size)
def set_font_color(self, color):
self.box.set_font_color(color)
def set_size(self, size):
self.box.set_size(size)
def set_style(self, style):
self.box.set_style(style)
def set_label(self, text):
self.box.set_label(text)
class Screen:
def create(self):
self.screen = pg.display.set_mode((800, 600))
self.load_button = Button(self, text="Load config", func=self.load)
self.load_button.move(20, 555)
self.load_button.height = 25
self.load_button.set_font_size(15)
self.save_button = Button(self, text="Save config", func=self.save)
self.save_button.move(145, 555)
self.save_button.height = 25
self.save_button.set_font_size(15)
self.reset_button = Button(self, text="Reset config", func=self.reset)
self.reset_button.move(270, 555)
self.reset_button.height = 25
self.reset_button.set_font_size(15)
self.opensimplex_option = CustomCheckBox(self, x=20, y=20)
self.opensimplex_option.check_color = (0, 0, 0)
self.opensimplex_option.set_font_size(15)
self.opensimplex_option.set_label("OpenSimplex noise")
self.opensimplex_option.label_side = "right"
self.opensimplex_option.label_padding = 5
self.perlin_noise_option = CustomCheckBox(self, x=20, y=50)
self.perlin_noise_option.check_color = (0, 0, 0)
self.perlin_noise_option.set_font_size(15)
self.perlin_noise_option.set_label("Perlin noise")
self.perlin_noise_option.label_side = "right"
self.perlin_noise_option.label_padding = 5
self.simplex_option = CustomCheckBox(self, x=20, y=80)
self.simplex_option.check_color = (0, 0, 0)
self.simplex_option.set_font_size(15)
self.simplex_option.set_label("Simplex noise")
self.simplex_option.label_side = "right"
self.simplex_option.label_padding = 5
self.settings_file = Entry(self, x=20, y=500, border=1, size=15, width=300)
self.settings_file.width = 300
self.settings_file.text = "settings.json"
self.settings_file.set_label("Settings file:")
self.noise_options = [
self.opensimplex_option,
self.perlin_noise_option,
self.simplex_option
]
self.noise_options[SETTINGS["noise"]].checked = True
self.widgets = [
self.load_button,
self.save_button,
self.reset_button,
self.opensimplex_option,
self.perlin_noise_option,
self.simplex_option,
self.settings_file
]
for w in self.widgets:
w.border_width = 1
def load(self):
filename = self.settings_file.text
if os.path.isfile(filename):
with open(filename, 'r') as f:
settings = json.load(f)
SETTINGS.update(settings)
self.apply_our_settings()
self.settings_file.set_label("Settings file:")
else:
self.settings_file.set_label("Settings file: No file at " + os.path.abspath(filename))
def save(self):
settings = SETTINGS.copy()
filename = "settings.json"
with open(filename, 'w') as f:
json.dump(settings, f)
def apply_our_settings(self):
apply_settings.value = 1
for i in self.noise_options:
i.checked = False
self.noise_options[SETTINGS["noise"]].checked = True
def reset(self):
reset_settings.value = 1
SETTINGS["noise"] = 2
self.noise_options[2].checked = True
self.noise_options[0].checked = False
self.noise_options[1].checked = False
def run(self):
if start_settings.value:
self.create()
start_settings.value = 0
in_settings.value = 1
if in_settings.value:
self.update()
self.events()
if quit_settings.value:
raise SystemExit
def update(self):
self.screen.fill((200, 200, 200))
for w in self.widgets:
w.update()
noises = [
self.opensimplex_option.checked,
self.perlin_noise_option.checked,
self.simplex_option.checked
]
for i, n in enumerate(noises):
if noises[i]:
SETTINGS["noise"] = i
pg.display.flip()
def events(self):
if in_settings.value:
for event in pg.event.get():
if event.type == pg.QUIT:
in_settings.value = 0
pg.display.quit()
elif event.type == pg.KEYDOWN:
if event.key == pg.K_ESCAPE:
in_settings.value = 0
pg.display.quit()
sc = Screen()
while True:
sc.run()
def editor():
import pygame as pg
from pgui import Slider, Entry, Button, CheckBox
import os
import cv2
pg.init()
screen = pg.display.set_mode((1200, 704))
pg.display.set_caption("Map creator")
vec = pg.math.Vector2
class Editor:
def __init__(self):
self.screen = screen
self.value = 5
self.oct_slider = Slider(self, max=7)
self.oct_slider.move(20, 40)
self.oct_slider.set_length(300)
self.oct_slider.set_font_size(15)
self.oct_slider.set_width(15)
self.oct_slider.set_label("Octaves: 1")
self.oct_slider.set_mark(0)
self.sea_level_slider = Slider(self)
self.sea_level_slider.move(20, 80)
self.sea_level_slider.set_length(300)
self.sea_level_slider.set_font_size(15)
self.sea_level_slider.set_width(15)
self.sea_level_slider.set_label("Sea level: 60")
self.sea_level_slider.set_mark(60)
self.scale_slider = Slider(self, max=599)
self.scale_slider.move(575, 660)
self.scale_slider.set_length(585)
self.scale_slider.set_font_size(15)
self.scale_slider.set_width(15)
self.scale_slider.set_label("Scale: 100")
self.scale_slider.set_mark(99)
self.zoom_slider = Slider(self, max=200, orientation="vertical")
self.zoom_slider.move(525, 25)
self.zoom_slider.set_length(585)
self.zoom_slider.label_align = "center"
self.zoom_slider.set_font_size(15)
self.zoom_slider.set_label("Zoom: 1")
self.zoom_slider.set_width(15)
self.zoom_slider.set_mark(175)
self.zoom = 1
self.map_surface = pg.Surface((600, 600))
self.map_surface.fill(0)
self.map_rect = self.map_surface.get_rect()
self.map_rect.topleft = (575, 25)
self.map = pg.Surface((SETTINGS["wdh"], SETTINGS["hgt"]))
self.map.fill((100, 100, 100))
self.width_slider = Slider(self, max=120)
self.width_slider.move(20, 120)
self.width_slider.set_length(300)
self.width_slider.set_font_size(15)
self.width_slider.set_width(15)
self.width_slider.set_label("Width: 600")
self.width_slider.set_mark(50)
self.height_slider = Slider(self, max=120)
self.height_slider.move(20, 160)
self.height_slider.set_length(300)
self.height_slider.set_font_size(15)
self.height_slider.set_width(15)
self.height_slider.set_label("Height: 600")
self.height_slider.set_mark(50)
self.pos_entry = Entry(self, x=20, y=200, border=1, size=15)
self.pos_entry.text = '0,0'
self.pos_entry.set_label("X,Y Position:")
self.lac_slider = Slider(self, max=40)
self.lac_slider.move(20, 240)
self.lac_slider.set_length(300)
self.lac_slider.set_font_size(15)
self.lac_slider.set_width(15)
self.lac_slider.set_label("Lacunarity: 2")
self.lac_slider.set_mark(10)
self.seed_entry = Entry(self, x=20, y=360, border=1, size=15)
self.seed_entry.text = '0'
self.seed_entry.set_label("Seed:")
self.draw_button = Button(self, x=20, y=625, text="Generate", func=self.draw)
self.draw_button.width = 315
self.clear_button = Button(self, x=345, y=625, text="Clear", func=self.clear)
self.settings_button = Button(self, x=20, y=570, text='Settings', func=self.settings)
self.settings_button.height = 25
self.settings_button.set_font_size(15)
self.abort_button = Button(self, x=140, y=570, text='Abort', func=self.abort_generation)
self.abort_button.height = 25
self.abort_button.set_font_size(15)
self.save_button = Button(self, x=260, y=570, text='Save', func=self.save)
self.save_button.height = 25
self.save_button.set_font_size(15)
self.save_name = Entry(self, x=380, y=570)
self.save_name.text = "image.png"
self.save_name.set_font_size(15)
self.save_name.set_label("Save to file:")
self.widgets = [
self.oct_slider,
self.sea_level_slider,
self.draw_button,
self.scale_slider,
self.zoom_slider,
self.width_slider,
self.height_slider,
self.pos_entry,
self.lac_slider,
self.seed_entry,
self.clear_button,
self.settings_button,
self.abort_button,
self.save_button,
self.save_name
]
self.width_chunks = 4
self.height_chunks = 4
for w in self.widgets:
w.border_width = 1
if isinstance(w, Slider):
w.pointer_border_width = 1
self.movable_map_rect = pg.Rect((0, 0), (600, 600))
self.dragging = False
self.dist = vec(0, 0)
def settings(self):
start_settings.value = 1
def save(self):
filename = self.save_name.text
if filename[-4:] != ".png":
filename += ".png"
surf = pg.transform.rotate(self.map, 90)
surf = pg.transform.flip(surf, 0, 1)
image = []
for x in range(SETTINGS["mwd"]):
row = []
for y in range(SETTINGS["mhg"]):
row.append(surf.get_at((x, y)))
image.append(row)
image = np.array(image)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
print("saving image")
cv2.imwrite(filename, image)
def abort_generation(self):
if generation_started.value:
print("Generation aborted")
for p in self.draw_threads:
p.terminate()
p.join()
generation_started.value = 0
def draw(self):
SETTINGS["mwd"] = SETTINGS["wdh"]
SETTINGS["mhg"] = SETTINGS["hgt"]
SHARED_MAP.clear()
chunks_generated.value = 0
self.draw_threads = []
for x in range(self.width_chunks):
for y in range(self.height_chunks):
width = int(SETTINGS["wdh"]/self.width_chunks)
height = int(SETTINGS["hgt"]/self.height_chunks)
pos = [x*width, y*height]
self.draw_threads.append(Thread(target=draw_colored, args=(SETTINGS["oct"],
SETTINGS["scl"],
SETTINGS["sea"],
width,
height,
SETTINGS["lac"],
pos,
SETTINGS["seed"],
SETTINGS["noise"],
SETTINGS["offset"])))
for p in self.draw_threads:
p.start()
def clear(self):
self.map.fill((100, 100, 100))
self.map_surface.fill(0)
SHARED_MAP.clear()
chunks_generated.value = 0
def run(self):
self.update()
self.events()
def reset_settings(self):
self.oct_slider.set_mark(0)
self.sea_level_slider.set_mark(60)
self.scale_slider.set_mark(99)
self.zoom_slider.set_mark(175)
self.map.fill((100, 100, 100))
self.width_slider.set_mark(50)
self.height_slider.set_mark(50)
self.lac_slider.set_mark(10)
self.pos_entry.text = '0,0'
self.seed_entry.text = '0'
self.mmrect.topleft = self.map_rect.topleft
self.movable_map_rect.topleft = (0, 0)
self.dist = vec(0, 0)
def update_settings(self):
self.oct_slider.set_mark(SETTINGS["oct"]-1)
self.sea_level_slider.set_mark(SETTINGS["sea"])
self.scale_slider.set_mark(SETTINGS["scl"]-1)
self.zoom_slider.set_mark(SETTINGS["zoom_slider"])
self.zoom = SETTINGS["zoom"]
self.width_slider.set_mark(int((SETTINGS["wdh"]-100)/10))
self.height_slider.set_mark(int((SETTINGS["hgt"]-100)/10))
pos = SETTINGS["offset"]
x = str(pos[0])
y = str(pos[1])
self.pos_entry.text = x+','+y
self.lac_slider.set_mark(SETTINGS["lac"]*10-10)
self.seed_entry.text = str(SETTINGS["seed"])
def update(self):
mousepos = vec(pg.mouse.get_pos())
p1 = pg.mouse.get_pressed()[0]
# print(p1, mousepos)
self.screen.fill((200, 200, 200))
if reset_settings.value:
reset_settings.value = 0
self.reset_settings()
if apply_settings.value:
apply_settings.value = 0
self.update_settings()
if generation_finished.value:
generation_finished.value = 0
width = len(SHARED_MAP.values()[0])
height = len(SHARED_MAP.values()[0][0])
self.map = pg.Surface((width*self.width_chunks, height*self.height_chunks))
self.map.fill((100, 100, 100))
self.map_surface.fill((100, 100, 100))
for c in SHARED_MAP.items():
pos = c[0]
chunk = c[1]
map_chunk = pg.pixelcopy.make_surface(chunk)
self.map.blit(map_chunk, (pos[1], pos[0]))
self.map = pg.transform.flip(pg.transform.rotate(self.map, -90), 1, 0)
self.movable_map = pg.transform.scale(
self.map, (int(SETTINGS["mwd"]*self.zoom), int(SETTINGS["mhg"]*self.zoom)))
self.movable_map_rect.size = self.movable_map.get_rect().size
self.mmrect = self.movable_map_rect.copy()
self.mmrect.topleft = vec(self.mmrect.topleft) + vec(575, 25)
if self.mmrect.collidepoint(mousepos) and self.map_rect.collidepoint(mousepos):
mpos = vec(mousepos) - vec(575, 25)
if p1 and not self.dragging:
self.dragging = True
self.dist = mousepos - vec(self.mmrect.topleft)
elif self.dragging and p1:
self.mmrect.topleft = mousepos - self.dist
self.movable_map_rect.center = vec(self.mmrect.center) - vec(575, 25)
elif self.dragging and not p1:
self.dragging = False
self.map_surface.fill(0)
self.map_surface.blit(self.movable_map, self.movable_map_rect)
self.screen.blit(self.map_surface, self.map_rect)
pg.draw.rect(self.screen, (0, 0, 0), self.map_rect, 1)
for w in self.widgets:
w.update()
SETTINGS["oct"] = self.oct_slider.mark+1
SETTINGS["scl"] = self.scale_slider.mark+1
SETTINGS["sea"] = self.sea_level_slider.mark
try:
seed = int(self.seed_entry.text)
except:
if self.seed_entry.text.strip() != '':
seed = int("".join([str(ord(c)) for c in self.seed_entry.text]))
else:
seed = 0
self.oct_slider.set_label("Octaves: "+str(self.oct_slider.mark+1))
self.sea_level_slider.set_label("Sea level: "+str(self.sea_level_slider.mark))
self.scale_slider.set_label("Scale: "+str(self.scale_slider.mark+1))
self.zoom_slider.set_label("Zoom: "+str(self.zoom_slider.max-self.zoom_slider.mark-25))
SETTINGS["zoom_slider"] = self.zoom_slider.mark
zoomval = (self.zoom_slider.max-self.zoom_slider.mark)/25
if zoomval <= 0:
self.zoom = 0.025
else:
self.zoom = zoomval
SETTINGS["zoom"] = self.zoom
self.width_slider.set_label("Width: "+str((self.width_slider.mark)*10+100))
SETTINGS["wdh"] = (self.width_slider.mark)*10+100
self.height_slider.set_label("Height: "+str((self.height_slider.mark)*10+100))
SETTINGS["hgt"] = (self.height_slider.mark)*10+100
self.lac_slider.set_label("Lacunarity: "+str((self.lac_slider.mark+10)/10))
SETTINGS["lac"] = (self.lac_slider.mark+10)/10
pos = self.pos_entry.text.strip().split(',')
for i, p in enumerate(pos):
if p != '':
try:
pos[i] = int(p)
except:
pos[i] = 0
SETTINGS["offset"] = pos
pg.display.flip()
def events(self):
for event in pg.event.get():
if event.type == pg.QUIT:
if not in_settings.value:
quit_settings.value = 1
raise SystemExit
if event.type == pg.MOUSEWHEEL:
if self.map_rect.collidepoint(pg.mouse.get_pos()):
try:
m = self.zoom_slider.mark-event.y
self.zoom_slider.set_mark(m)
except:
self.zoom_slider.set_mark(200)
e = Editor()
while True:
e.run()
if __name__ == "__main__":
manager = Manager()
SETTINGS = manager.dict()
start_settings = Value('i', 0)
in_settings = Value('i', 0)
quit_settings = Value('i', 0)
reset_settings = Value('i', 0)
generation_finished = Value('i', 0)
generation_started = Value('i', 0)
chunks_generated = Value('i', 0)
apply_settings = Value('i', 0)
SETTINGS["oct"] = 1
SETTINGS["scl"] = 250
SETTINGS["sea"] = 60
SETTINGS["lac"] = 2
SETTINGS["seed"] = 0
SETTINGS["wdh"] = 600
SETTINGS["hgt"] = 600
SETTINGS["offset"] = [0, 0]
SETTINGS["mwd"] = 600
SETTINGS["mhg"] = 600
SETTINGS["zoom"] = 0
SETTINGS["zoom_slider"] = 0
SETTINGS["noise"] = 2
SHARED_MAP = manager.dict()
# create pool with two processes and initialize global variables:
pool = Pool(2, initializer=init_pool, initargs=(SETTINGS,
SHARED_MAP,
start_settings,
in_settings,
quit_settings,
reset_settings,
generation_finished,
generation_started,
chunks_generated,
apply_settings))
result1 = pool.apply_async(sw)
result2 = pool.apply_async(editor)
# wait for tasks to complete:
try:
return_value_1 = result1.get()
except Exception:
print(traceback.print_exc())
try:
return_value_2 = result2.get()
except Exception:
print(traceback.print_exc())
Note: Since your tasks do not actually return any values of interest, I could have awaited for the tasks to complete by issuing the following two commands in lieu of calling get() on the AsycnResult instances returned by the calls to apply_async:
pool.close()
pool.join()
But then any exceptions thrown in your tasks would not be detected.
I also question whether shared Value variables start_settings through apply_settings really needed to be implemented as shared variables; they don't seem to be shared with another process.

Python: PSO clumping <s>and code working only when mouse moves</s>

I'm trying to make a simple PSO (particle-swarm optimization) program.
Below is my current code, and I've been tweaking the weights only to find the "optimization" not working.
import random as ran
import math
# import threading as thr
import pygame as gm
# import pycuda as cuda
# import matplotlib.pyplot as plt
p_max = 10 # Maximum number of particles
rand_max = 100 # Maximum random vector value
# history = 10 # Number of iterations to record as history (including most current)
width = 600
height = 600
func_dict = {
"sphere" : ( lambda x, y: ( (x-(width/2))**2 + (y-(height/2))**2 ) ),
"booth" : ( lambda x, y: (((x-(width/2)) + 2*(y-(height/2)) - 7) ** 2) + ((2*(x-(width/2)) + (y-(height/2)) - 5) ** 2) ),
"matyas" : ( lambda x, y: (0.26 * ((x-(width/2))**2 + (y-(height/2))**2) - 0.48*(x-(width/2))*(y-(height/2))) )
} # (x-(width/2)) and (y-(height/2)) to shift the Zero to the display center
func = "sphere" # Choose function from func_dict
# Weights (0<w<1)
wLocal = 0.4 # Explore weight
wGlobal = 0.8 # Exploit weight
wRandom = 0.02 # Weight of random vector
global_best = [None, None, None] # Initial blank
class particle: # particles
global global_best
def __init__(self):
global global_best
global width, height
global func_dict, func
self.vel_x = 0
self.vel_y = 0
self.pos_x = ran.randint(0, width)
self.pos_y = ran.randint(0, height)
self.pos_z = func_dict[func](self.pos_x, self.pos_y)
self.local_best = [self.pos_x, self.pos_y, self.pos_z]
if (global_best[0] == None) or (global_best[1] == None) or (global_best[2] == None): # Is 1st particle
global_best = self.local_best
def update(self): # Update vectors
global width, height
global rand_max
global wGlobal, wLocal, wRandom
global global_best
self.vel_x = (wGlobal * (global_best[0] - self.pos_x)) + (wLocal * (self.local_best[0] - self.pos_x)) + (wRandom * ran.randint(-rand_max, rand_max))
self.vel_y = (wGlobal * (global_best[1] - self.pos_y)) + (wLocal * (self.local_best[1] - self.pos_y)) + (wRandom * ran.randint(-rand_max, rand_max))
# self.pos_x = (self.pos_x + self.vel_x) % width
# self.pos_y = (self.pos_y + self.vel_y) % height
self.pos_x += self.vel_x
self.pos_y += self.vel_y
if self.pos_x < 0:
self.pos_x = 0
if self.pos_y < 0:
self.pos_y = 0
if self.pos_x > width:
self.pos_x = width
if self.pos_y > height:
self.pos_y = height
self.pos_z = func_dict[func](self.pos_x, self.pos_y)
if self.pos_z < global_best[2]:
global_best = [self.pos_x, self.pos_y, self.pos_z]
particles = [None for _ in range(p_max)]
def initialize():
global_best = [None, None, None]
for foo in range(p_max):
particles[foo] = particle() # create new particles
# def dist(p1, p2): # distance
# return(math.sqrt( ( (p1.pos_x - p2.pos_y)**2) + ((p1.pos_y - p2.pos_y)**2) ) )
# def update(this): # this = particle
# this.vel_x = (wGlobal * (global_best[0] - this.pos_x)) + (wLocal * (this.local_best[0] - this.pos_x)) + (wRandom * ran.randint(0, rand_max))
# this.vel_y = (wGlobal * (global_best[1] - this.pos_y)) + (wLocal * (this.local_best[1] - this.pos_y)) + (wRandom * ran.randint(0, rand_max))
# # this.pos_x = (this.pos_x + this.vel_x) % width
# # this.pos_y = (this.pos_y + this.vel_y) % height
# this.pos_x += this.vel_x
# this.pos_y += this.vel_y
# if this.pos_x < 0:
# this.pos_x = 0
# if this.pos_y < 0:
# this.pos_y = 0
# if this.pos_x > width:
# this.pos_x = width
# if this.pos_y > height:
# this.pos_y = height
# # return this
# def update_multi(things): # things = list() of particles
# these = things
# for item in these:
# item = update(item)
# return these
gm.init()
main = gm.display.set_mode((width, height))
end_program = False
initialize()
main.fill((255, 255, 255))
while end_program == False:
# main.fill((255, 255, 255)) #Comment/Uncomment to leave trace
# plt.plot() # Plot functions
for event in gm.event.get():
if event.type == gm.QUIT:
end_program = True
for foo in range(len(particles)):
particles[foo].update()
gm.draw.circle(main, (0, 0, 0), (int(particles[foo].pos_x), int(particles[foo].pos_y)), 5, 0)
gm.display.flip()
Problem 1: Program only runs when mouse is moving
I'm not sure why but the program only runs fairly quickly for a few iterations but seems to just stop afterwards, but continues when the mouse is moved.
Problem 2: Particles appear to stay local
As I move the mouse around, it kinda runs. What emerges is clumps of traces left when the 2nd # main.fill((255, 255, 255)) is uncommented. The 1st initial traces from before the program stops without the mouse's movement seem more spread out and I'm not sure if that's the global variables or the randoms at work.
Edit: I've fixed the problem where the program only runs when the mouse moves by unindenting:
for foo in range(len(particles)):
particles[foo].update()
gm.draw.circle(main, (0, 0, 0), (int(particles[foo].pos_x), int(particles[foo].pos_y)), 5, 0)
However, the particles still seem to hardly move from their own positions, oscilating locally.
Problem 1 was solved thanks to Marius. I fixed it by simply putting update outside the event loop.
Problem 2 was fixed by adding the local update that I forgot.
if self.pos_z < global_best[2]: # This was not forgotten
global_best = [self.pos_x, self.pos_y, self.pos_z]
if self.pos_z < local_best[2]: # This was forgotten
local_best = [self.pos_x, self.pos_y, self.pos_z]

How do I import a gif in Tkinter?

So I have this maze code, and it's really cool but when you play you move around a red square. Is there a way that I can change this red square that moves around into an image, instead of where it says return "red" I want to put this personaje.gif file so a little person can appear moving through the maze.
this is my code:
import random
import Tkinter as tk
import sys
from PIL import Image, ImageTk
class Application(tk.Frame):
def __init__(self, width=600, height=600, size=600):
tk.Frame.__init__(self)
self.maze = Maze(width, height)
personaje = Image.open("personaje.gif")
photo = ImageTk.PhotoImage(personaje)
self.size = size
self.steps = 0
self.grid()
self.create_widgets()
self.draw_maze()
self.create_events()
def create_widgets(self):
width = self.maze.width * self.size
height = self.maze.height * self.size
self.canvas = tk.Canvas(self, width=width, height=height)
self.canvas.grid()
self.status = tk.Label(self)
self.status.grid()
def draw_maze(self):
for i, row in enumerate(self.maze.maze):
for j, col in enumerate(row):
x0 = j * self.size
y0 = i * self.size
x1 = x0 + self.size
y1 = y0 + self.size
color = self.get_color(x=j, y=i)
id = self.canvas.create_rectangle(x0, y0, x1, y1, width=0, fill=color)
if self.maze.start_cell == (j, i):
self.cell = id
self.canvas.tag_raise(self.cell) # bring to front
self.status.config(text='Movidas mínimas: %d' % self.maze.steps)
def create_events(self):
self.canvas.bind_all('<KeyPress-Up>', self.move_cell)
self.canvas.bind_all('<KeyPress-Down>', self.move_cell)
self.canvas.bind_all('<KeyPress-Left>', self.move_cell)
self.canvas.bind_all('<KeyPress-Right>', self.move_cell)
def move_cell(self, event):
if event.keysym == 'Up':
if self.check_move(0, -1):
self.canvas.move(self.cell, 0, -self.size)
self.steps += 1
if event.keysym == 'Down':
if self.check_move(0, 1):
self.canvas.move(self.cell, 0, self.size)
self.steps += 1
if event.keysym == 'Left':
if self.check_move(-1, 0):
self.canvas.move(self.cell, -self.size, 0)
self.steps += 1
if event.keysym == 'Right':
if self.check_move(1, 0):
self.canvas.move(self.cell, self.size, 0)
self.steps += 1
args = (self.steps, self.maze.steps)
self.status.config(text='Movimientos %d/%d' % args)
self.check_status()
def check_move(self, x, y):
x0, y0 = self.get_cell_coords()
x1 = x0 + x
y1 = y0 + y
return self.maze.maze[y1][x1] == 0
def get_cell_coords(self):
position = self.canvas.coords(self.cell)
x = int(position[0] / self.size)
y = int(position[1] / self.size)
return (x, y)
def check_status(self):
if self.maze.exit_cell == self.get_cell_coords():
args = (self.steps, self.maze.steps)
self.status.config(text='Resuelto en %d/%d movidas!' % args)
def get_color(self, x, y):
if self.maze.start_cell ==(x,y):
return "red"
if self.maze.exit_cell == (x, y):
return 'green'
if self.maze.maze[y][x] == 1:
return 'black'
class Maze(object):
def __init__(self, width=21, height=21, exit_cell=(1, 1)):
self.width = width
self.height = height
self.exit_cell = exit_cell
self.create()
def create(self):
self.maze = [[1] * self.width for _ in range(self.height)] # full of walls
self.start_cell = None
self.steps = None
self.recursion_depth = None
self._visited_cells = []
self._visit_cell(self.exit_cell)
def _visit_cell(self, cell, depth=0):
x, y = cell
self.maze[y][x] = 0 # remove wall
self._visited_cells.append(cell)
neighbors = self._get_neighbors(cell)
random.shuffle(neighbors)
for neighbor in neighbors:
if not neighbor in self._visited_cells:
self._remove_wall(cell, neighbor)
self._visit_cell(neighbor, depth+1)
self._update_start_cell(cell, depth)
def _get_neighbors(self, cell):
x, y = cell
neighbors = []
# Left
if x - 2 > 0:
neighbors.append((x-2, y))
# Right
if x + 2 < self.width:
neighbors.append((x+2, y))
# Up
if y - 2 > 0:
neighbors.append((x, y-2))
# Down
if y + 2 < self.height:
neighbors.append((x, y+2))
return neighbors
def _remove_wall(self, cell, neighbor):
x0, y0 = cell
x1, y1 = neighbor
# Vertical
if x0 == x1:
x = x0
y = (y0 + y1) / 2
# Horizontal
if y0 == y1:
x = (x0 + x1) / 2
y = y0
self.maze[y][x] = 0 # remove wall
def _update_start_cell(self, cell, depth):
if depth > self.recursion_depth:
self.recursion_depth = depth
self.start_cell = cell
self.steps = depth * 2 # wall + cell
def show(self, verbose=False):
MAP = {0: ' ', # path
1: '#', # wall
2: 'B', # exit
3: 'A', # start
}
x0, y0 = self.exit_cell
self.maze[y0][x0] = 2
x1, y1 = self.start_cell
self.maze[y1][x1] = 3
for row in self.maze:
print ' '.join([MAP[col] for col in row])
if verbose:
print "Steps from A to B:", self.steps
if __name__ == '__main__':
from optparse import OptionParser
parser = OptionParser(description="Random maze game")
parser.add_option('-W', '--width', type=int, default=43)
parser.add_option('-H', '--height', type=int, default=43)
parser.add_option('-s', '--size', type=int, default=11,
help="cell size")
args, _ = parser.parse_args()
for arg in ('width', 'height'):
if getattr(args, arg) % 2 == 0:
setattr(args, arg, getattr(args, arg) + 1)
print "Warning: %s must be odd, using %d instead" % (arg, getattr(args, arg))
sys.setrecursionlimit(5000)
app = Application(args.width, args.height, args.size)
app.master.title('Maze game')
app.mainloop()

Categories

Resources