def draw(self, screen, camera): if self.rect == [Vct(0, 0), Vct(0, 0)]: return else: if not self.is_crop: pygame.draw.rect(screen, (0, 255, 0),( (self.rect[0]*camera.scale-camera.pos).tuple(), ((self.rect[1]+Vct(1, 1))*camera.scale).tuple()), 1) else: pygame.draw.rect(screen, (255, 0, 0),( (self.rect[0]*camera.scale-camera.pos).tuple(), ((self.rect[1]+Vct(1, 1))*camera.scale).tuple()), 1)
def save(self): #uloží buňky co jsou ve výběru označeném čtvercem a uloží je do listu self.buffer self.buffer = [] for pos in self.units: classes.Unit.units[pos].selected = False rel_pos = pos - self.rect[0]-round(self.rect[1]/2) self.buffer.append([rel_pos, type(classes.Unit.units[pos]), classes.Unit.units[pos].orientation]) self.untis = [] self.rect = [Vct(0, 0), Vct(0, 0)] print(self.buffer)
def draw(self, screen, camera): pygame.draw.rect(screen, self.wirecolors[self.life], (((self.pos + Vct(0.05, 0.05)) * camera.scale - camera.pos).tuple(), (Vct(0.9, 0.9) * camera.scale).tuple())) if self.selected: pygame.draw.rect(screen, self.colors["green"], (((self.pos) * camera.scale - camera.pos).tuple(), (Vct(1, 1) * camera.scale).tuple()), 1)
def draw(self, screen, camera): if self.orientation == "upDown": pygame.draw.rect(screen, self.color, (((self.pos - Vct(0.25, 0)) * camera.scale - camera.pos).tuple(), ((Vct(1.5, 1) * camera.scale).tuple()))) pygame.draw.rect(screen, self.colors["grey"], (((self.pos - Vct(0.25, 0)) * camera.scale - camera.pos).tuple(), ((Vct(1.5, 1) * camera.scale).tuple())), int(0.1 * camera.scale)) elif self.orientation == "leftRight": pygame.draw.rect(screen, self.color, (((self.pos - Vct(0, 0.25)) * camera.scale - camera.pos).tuple(), ((Vct(1, 1.5) * camera.scale).tuple()))) pygame.draw.rect(screen, self.colors["grey"], (((self.pos - Vct(0, 0.25)) * camera.scale - camera.pos).tuple(), ((Vct(1, 1.5) * camera.scale).tuple())), int(0.1 * camera.scale)) if self.selected: pygame.draw.rect(screen, self.colors["green"], (((self.pos) * camera.scale - camera.pos).tuple(), (Vct(1, 1) * camera.scale).tuple()), 1)
def crop(self): self.buffer = [] for pos in self.units: classes.Unit.units[pos].selected = False rel_pos = pos - self.rect[0]-round(self.rect[1]/2) self.buffer.append([rel_pos, type(classes.Unit.units[pos]), classes.Unit.units[pos].orientation]) classes.Unit.delete_cell(pos) self.is_crop = False self.untis = [] self.rect = [Vct(0, 0), Vct(0, 0)] print(self.buffer)
def __init__(self): self.end = False self.screen = pygame.display.set_mode((1800, 1000)) self.clock = pygame.time.Clock() self.tick = 0 self.tickrate = 8 self.keys = [] self.mousepos = Vct(0, 0) self.m1 = False self.m2 = False self.inputhandler = inputhandler.Handler() self.camera = camera.Camera(Vct(0, 0), 20) self.sWheel = selection_wheel.Wheel(self.screen) self.filehandler = filehandler.Filehandler()
def draw(self, screen, camera): verts = [((vert + self.pos) * camera.scale - camera.pos).tuple() for vert in self.triangles[self.orientation]] pygame.draw.polygon(screen, self.colors["grey"], verts) if self.selected: pygame.draw.rect(screen, self.colors["green"], (((self.pos) * camera.scale - camera.pos).tuple(), (Vct(1, 1) * camera.scale).tuple()), 1)
def __init__(self): self.mousexy = Vct( 0, 0) # pozice kurzoru relativně vůči zvětšení a posunu kamery self.activeunit = classes_models.Wire # Třída, jež je uložena s této proměnné se bude vytvářet při klikání myši self.keys = {} self.buttonpressed = False self.transistorRotation = [["upDown", "leftRight"], 0] self.diodeRotation = [["left", "up", "right", "down"], 0]
def __init__(self, screen): self.r = 0 self.timer = 0 self.size = Vct(500, 500) self.surface = pygame.Surface( (self.size).tuple(), pygame.SRCALPHA) # vlastní povrch (nutné k průhlednosti) self.models = [ models.Wire, models.Transistor, models.Diode, models.Remove, models.BringAlive ] # seznam všech možností, které chci mít v tomto kolečku self.spacing = 2 * math.pi / len(self.models) self.camera = camera.Camera( Vct(0, 0), 20 ) # vlastní kamera je nutná aby byla zachována velikost náhledu i při zvětšování a zmenšování self.screensize = Vct(screen.get_size()[0], screen.get_size()[1]) self.closestToMouse = [ models.Wire, float("inf") ] # volba, která je nejblíže k myši je uložena v této hodnotě
def mark(self, mousexy): self.units = [] if self.rect[0] == Vct(0, 0): self.rect[0] = mousexy self.rect[1] = mousexy-self.rect[0] for pos in classes.Unit.units: if self.is_in_rect(pos): self.units.append(pos) classes.Unit.units[pos].selected = True else: classes.Unit.units[pos].selected = False
def load(self): # Z uložených textových souborů vytvoří buffer, který lze poté vložit do simulace self.buffer = [] list = [name for name in os.listdir() if ".txt" in name] for i, name in enumerate(list): print(str(i+1) + ". " + name) # tímto se usnadní výběr souboru, uživatel nemusí psát celý název, stačí pouze číslo try: file = open(list[int(input("select number of file:"))-1]) except IndexError: print("There is no file with that number :(") return for line in file.readlines(): # tímto cyklem se načítá soubor do bufferu line = line.strip().split(" ") line[0] = [s.strip("()") for s in line[0].split(",")] if line[1] == "wire": self.buffer.append([Vct(int(line[0][0]), int(line[0][1])), classes.Wire, line[2]]) if line[1] == "diode": self.buffer.append([Vct(int(line[0][0]), int(line[0][1])), classes.Diode, line[2]]) if line[1] == "transistor": self.buffer.append([Vct(int(line[0][0]), int(line[0][1])), classes.Transistor, line[2]])
def update(self): self.keys = pygame.key.get_pressed() if self.keys[pygame.K_ESCAPE]: self.end = True self.mousepos = Vct(pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1]) self.m1 = pygame.mouse.get_pressed()[0] self.m2 = pygame.mouse.get_pressed()[2] self.tick = (self.tick + 1) % self.tickrate if self.tick == 0: classes.Unit.make_new_itteration() self.inputhandler.update(self.keys, self.m1, self.mousepos, self.camera, self.sWheel, self.filehandler) self.camera.update(self.m2, self.mousepos) self.sWheel.update(self.mousepos)
def draw(pos,screen, camera, selected = False, orientation = "upDown"): pygame.draw.rect(screen, white, (((pos+Vct(0.05, 0.05))*camera.scale-camera.pos).tuple(), (Vct(0.9, 0.9)*camera.scale).tuple())) if orientation == "upDown": pygame.draw.rect(screen, white, (((pos-Vct(0.25, 0) )* camera.scale-camera.pos).tuple(), ((Vct(1.5, 1) * camera.scale).tuple()))) pygame.draw.rect(screen, lightgrey, (((pos-Vct(0.25, 0))* camera.scale-camera.pos).tuple(), ((Vct(1.5, 1)*camera.scale).tuple())),int(0.1 *camera.scale)) if orientation == "leftRight": pygame.draw.rect(screen, white, (((pos-Vct(0, 0.25) )* camera.scale-camera.pos).tuple(), ((Vct(1, 1.5) * camera.scale).tuple()))) pygame.draw.rect(screen, lightgrey, (((pos-Vct(0, 0.25))* camera.scale-camera.pos).tuple(), ((Vct(1, 1.5) * camera.scale).tuple())),int(0.1 *camera.scale)) if selected: pygame.draw.rect(screen, green, (((pos+Vct(0.05, 0.05))*camera.scale-camera.pos).tuple(), (Vct(0.9, 0.9)*camera.scale).tuple()), 1)
class Unit(): units = {} # slovník držící všechny buňky a jejich souřadnice living_units = [ ] # souřadnice všech buněk, které jsou aktivní a je třeba je updatovat new_itteration = [ ] # souřadnice všech buněk, které budou živé i v příští iteraci simulace. Na konci každého kroku simulace se seznam living_units změní na new_itteration directions = { "up": Vct(0, -1), #slouží k zjišťování sousedů "down": Vct(0, 1), "left": Vct(-1, 0), "right": Vct(1, 0) } colors = { "grey": (127, 127, 127), "lightgrey": (180, 180, 180), "white": (255, 255, 255), "green": (0, 255, 0) } wirecolors = { 0: (255, 255, 255), 1: (255, 100, 100), 2: (255, 50, 50), 3: (255, 0, 0), 4: (0, 255, 0) } def __init__(self, pos): self.pos = pos self.neighbors = {} self.life = 0 self.selected = False self.orientation = None def updateneighbors(self): # zjistí a uloží všechny svoje sousedy (slouží primárně k optimalizaci) self.neighbors = {} for d in self.directions.values(): if d + self.pos in self.units: self.neighbors[d + self.pos] = self.units[d + self.pos] def draw(self, screen, camera): pygame.draw.rect(screen, self.wirecolors[self.life], (((self.pos + Vct(0.05, 0.05)) * camera.scale - camera.pos).tuple(), (Vct(0.9, 0.9) * camera.scale).tuple())) if self.selected: pygame.draw.rect(screen, self.colors["green"], (((self.pos) * camera.scale - camera.pos).tuple(), (Vct(1, 1) * camera.scale).tuple()), 1) def make_new_itteration(): # Vytvoří novou iteraci simulace Unit.new_itteration = [] filtred_new_itter = [] for pos in Unit.living_units: if not pos in filtred_new_itter: filtred_new_itter.append(pos) Unit.living_units = filtred_new_itter # zbav se duplikátů for pos in Unit.living_units: if type(Unit.units[pos]) == Diode: Unit.units[pos].update() for pos in Unit.living_units: if type(Unit.units[pos]) != Diode: Unit.units[pos].update() Unit.living_units = Unit.new_itteration def delete_cell(pos): neighbors = Unit.units[pos].neighbors del Unit.units[pos] #odstraní buňku se seznamu všech buňek if pos in Unit.new_itteration: #odstraní buňku z nové iterace Unit.new_itteration.remove(pos) if pos in Unit.living_units: #odstraní buňky z žíjících buňek Unit.living_units.remove(pos) for n in neighbors: #updatetuje všechny sousedy odstraněné buňky aby se jí nesnažily oživit Unit.units[n].updateneighbors()
class Diode(): triangles = {"left":[Vct(0, 0.5), Vct(1, 0), Vct(1, 1)], "right":[Vct(0, 0), Vct(0, 1), Vct(1, 0.5)], "up":[Vct(0, 1), Vct(1, 1), Vct(0.5, 0)], "down":[Vct(0, 0), Vct(1, 0), Vct(0.5, 1)]} def draw(pos,screen, camera, selected = False, orientation = "down"): verts = [((vert+pos)*camera.scale-camera.pos).tuple() for vert in Diode.triangles[orientation]] pygame.draw.polygon(screen, grey,verts) if selected: pygame.draw.rect(screen, green, (((pos+Vct(0.05, 0.05))*camera.scale-camera.pos).tuple(), (Vct(0.9, 0.9)*camera.scale).tuple()), 1)
class Diode(Unit): """ Dioda vede proud pouze směrem svojí orentace, všechny ostatní impulsy ignoruje """ triangles = { "left": [Vct(0, 0.5), Vct(1, 0), Vct(1, 1)], #slouží k vykreslování "right": [Vct(0, 0), Vct(0, 1), Vct(1, 0.5)], "up": [Vct(0, 1), Vct(1, 1), Vct(0.5, 0)], "down": [Vct(0, 0), Vct(1, 0), Vct(0.5, 1)] } def __init__(self, pos, orientation="left"): super().__init__(pos) self.orientation = orientation self.new_itteration.append(self.pos) def update(self): self.life = 0 for d in self.directions: #zjistí svojí orientaci a podle té se vyhodnotí if self.orientation == d: if self.pos - self.directions[ d] in self.living_units and self.neighbors[ self.pos - self.directions[d]].life == 3: if self.pos + self.directions[d] in self.neighbors: if type(self.neighbors[self.pos + self.directions[d]] ) == Transistor and not d in self.neighbors[ self.pos + self.directions[d]].orientation.lower(): self.neighbors[self.pos + self.directions[d]].blocked = 8 self.new_itteration.append(self.pos + self.directions[d]) # speciálné je zde ošetřená interakce s tranzistorem, ten se zablokuje byl-li oživen Diodou při odpovídající orientaci else: self.neighbors[self.pos + self.directions[d]].life = 3 self.new_itteration.append(self.pos + self.directions[d]) self.new_itteration.append(self.pos) def draw(self, screen, camera): verts = [((vert + self.pos) * camera.scale - camera.pos).tuple() for vert in self.triangles[self.orientation]] pygame.draw.polygon(screen, self.colors["grey"], verts) if self.selected: pygame.draw.rect(screen, self.colors["green"], (((self.pos) * camera.scale - camera.pos).tuple(), (Vct(1, 1) * camera.scale).tuple()), 1) def make_new(pos, orientation): Unit.units[pos] = Diode(pos, orientation) Unit.units[pos].updateneighbors() for n in Unit.units[pos].neighbors.values(): n.updateneighbors() def __repr__(self): return ("Diode {} {} {}".format(self.pos.x, self.pos.y, self.orientation))
def draw(pos,screen, camera, selected = False, orientation = "down"): verts = [((vert+pos)*camera.scale-camera.pos).tuple() for vert in Diode.triangles[orientation]] pygame.draw.polygon(screen, grey,verts) if selected: pygame.draw.rect(screen, green, (((pos+Vct(0.05, 0.05))*camera.scale-camera.pos).tuple(), (Vct(0.9, 0.9)*camera.scale).tuple()), 1)
def __init__(self): self.units = [] # v tomto listu jsou uložené všechny buňky, jež jsou označeny výběrem self.buffer = [] # slouží k ukládání a nahrávání buňek self.rect = [Vct(0, 0), Vct(0, 0)] # obdelník ukazující výběr self.is_crop = False
def draw(pos,screen, camera, selected = False,orientation = None): pygame.draw.rect(screen, red, (((pos+Vct(0.05, 0.05))*camera.scale-camera.pos).tuple(), (Vct(0.9, 0.9)*camera.scale).tuple())) if selected: pygame.draw.rect(screen, green, (((pos+Vct(0.05, 0.05))*camera.scale-camera.pos).tuple(), (Vct(0.9, 0.9)*camera.scale).tuple()), 1)
def __init__(self, pos, scale): self.pos = pos self.scale = scale self.shiftstart = Vct(0, 0) self.shiftapplied = False
def update(self, keys, m1, mousepos, camera, wheel, filehandler): self.mousexy = round( ((mousepos + camera.pos) - (mousepos + camera.pos) % camera.scale) / camera.scale) self.keys = keys self.m1 = m1 if self.m1: if wheel.timer <= 10: if self.activeunit == classes_models.Wire: classes.Wire.make_new(self.mousexy) elif self.activeunit == classes_models.Transistor: classes.Transistor.make_new( self.mousexy, self.transistorRotation[0][self.transistorRotation[1]]) elif self.activeunit == classes_models.Diode: classes.Diode.make_new( self.mousexy, self.diodeRotation[0][self.diodeRotation[1]]) elif self.activeunit == classes_models.BringAlive: #ožíví vybranou buňku if self.mousexy in classes.Unit.units: classes.Unit.units[self.mousexy].life = 3 classes.Unit.living_units.append(self.mousexy) elif self.activeunit == classes_models.Remove: #odstraní buňky if self.mousexy in classes.Unit.units: classes.Unit.delete_cell(self.mousexy) elif self.activeunit == "copytool" or self.activeunit == "croptool": filehandler.mark(self.mousexy) elif self.activeunit == "insertiontool": filehandler.blit_copy(self.mousexy) else: self.activeunit = wheel.change_active_unit() if wheel.timer > 50: wheel.timer = 50 if keys[pygame.K_e] and not self.buttonpressed: self.buttonpressed = True if wheel.timer == 0: wheel.timer = 500 elif wheel.timer > 50: wheel.timer = 50 if keys[pygame.K_r] and not self.buttonpressed: self.buttonpressed = True if self.activeunit == classes_models.Transistor: self.transistorRotation[1] = (self.transistorRotation[1] + 1) % 2 if self.activeunit == classes_models.Diode: self.diodeRotation[1] = (self.diodeRotation[1] + 1) % 4 if not keys[pygame.K_e] and not keys[pygame.K_r]: self.buttonpressed = False if keys[pygame.K_LCTRL] and keys[pygame.K_c]: self.activeunit = "copytool" filehandler.is_crop = False if self.activeunit == "copytool" and not self.m1 and filehandler.rect != [ Vct(0, 0), Vct(0, 0) ]: filehandler.save() self.activeunit = "insertiontool" if keys[pygame.K_LCTRL] and keys[pygame.K_v]: self.activeunit = "insertiontool" if keys[pygame.K_LCTRL] and keys[pygame.K_s]: filehandler.store_buffer() if keys[pygame.K_LCTRL] and keys[pygame.K_l]: filehandler.load() self.activeunit = "insertiontool" if keys[pygame.K_LCTRL] and keys[pygame.K_x]: filehandler.is_crop = True self.activeunit = "croptool" if self.activeunit == "croptool" and not self.m1 and filehandler.rect != [ Vct(0, 0), Vct(0, 0) ]: filehandler.crop() self.activeunit = "insertiontool"
def polar_to_cartestian(r, angle): # tato funkce slouže k převodu z polární soustavy do kartezské x = r * math.cos(angle) y = r * math.sin(angle) return Vct(x, y)