class NameEntry: def __init__(self, items=SIGNS, menu=False): self.items = items self.menu = menu base.cam.set_pos(0, 0, 0) base.cam.set_hpr(0, 0, 0) self.currentSign = 0 self.currentFrameID = 0 self.currentFrame = None self.sound_lo = loader.load_sfx("assets/sfx/pong_lo.wav") self.sound_lo.set_volume(0.4) self.sound_ye = loader.load_sfx("assets/sfx/pickup.wav") self.sound_ye.set_volume(0.4) self.sound_no = loader.load_sfx("assets/sfx/bounce.wav") self.sound_no.set_volume(0.4) self.repeating = 0 self.spinnerNode = NodePath("spinner") self.spinnerNode.setPos(0, 3, -0.2) self.spinnerNode.setHpr(-90, 0, 0) self.spinnerNode.setShaderAuto(True) size = (-0.15, 0.15, -0.05, 0.375) z = 0.5 if menu: self.spinnerNode.setScale(0.6) self.spinnerNode.setZ(-0.4) else: self.help = DirectLabel( text= "left/right = Choose sign | up = Select sign | down = remove/back", frameColor=(0, 0, 0, 0), text_fg=(1, 1, 1, 1), pos=(0, 0, -0.8), scale=0.07) self.first = DirectFrame(text="", frameColor=(0, 0, 0, 1), frameSize=size, pos=(-0.4, 0, z), text_scale=0.35, text_fg=(1, 1, 1, 1), text_font=base.font, text_align=TextNode.ACenter) self.second = DirectFrame(text="", frameColor=(0, 0, 0, 1), frameSize=size, pos=(0, 0, z), text_scale=0.35, text_fg=(1, 1, 1, 1), text_font=base.font, text_align=TextNode.ACenter) self.third = DirectFrame(text="", frameColor=(0, 0, 0, 1), frameSize=size, pos=(0.4, 0, z), text_scale=0.35, text_fg=(1, 1, 1, 1), text_font=base.font, text_align=TextNode.ACenter) self.currentFrame = self.first self.arrowA = DirectFrame(frameSize=(-0.1, 0.1, -0.1, 0.1), frameColor=(0, 0, 0, 0), pos=(-0.4, 0, z - 0.15), image="assets/gui/arrow.png", image_scale=0.2, scale=0.5) self.arrowA.setTransparency(1) self.arrowB = DirectFrame(frameSize=(-0.1, 0.1, -0.1, 0.1), frameColor=(0, 0, 0, 0), pos=(0, 0, -0.5), image="assets/gui/arrow.png", image_scale=0.2, scale=0.5) self.arrowB.setTransparency(1) self.task = base.task_mgr.add(self.update) r = 1 for i, sign in enumerate(self.items): deg = 2 * pi / len(self.items) t = deg * i x = r * cos(t) y = r * sin(t) s = TextNode(sign) s.setText(sign) s.setAlign(TextNode.ACenter) s.setFont(base.font) s.setTextColor(1, 1, 1, 1) snp = self.spinnerNode.attachNewNode(s) snp.setScale(0.2) if sign == "end": snp.setScale(0.1) snp.setPos(x, y, 0) snp.setHpr(90 + i * (360 / len(self.items)), 0, 0) self.spinnerNode.reparentTo(render) self.delay = 0.2 def activate(self): self.sound_ye.play() if self.currentSign == 0: base.messenger.send("do_start") elif self.currentSign == 1: base.messenger.send("do_highscore") else: base.messenger.send("do_quit") def tick(self): self.delay -= globalClock.get_dt() if self.delay < 0: return True def update(self, task): if self.tick(): context = base.device_listener.read_context('player') if context["move"] > 0.2: self.rotateRight() if self.repeating: self.delay = 0.2 * (0.9**self.repeating) self.repeating += 1 else: self.delay = 0.2 self.repeating = 1 elif context['move'] < -0.2: self.rotateLeft() if self.repeating: self.delay = 0.2 * (0.9**self.repeating) self.repeating += 1 else: self.delay = 0.2 self.repeating = 1 elif context["accelerate"] or context["select"]: self.addSign() self.delay = 0.2 self.repeating = False elif context["decelerate"] or context["backspace"]: self.removeSign() self.delay = 0.2 self.repeating = False else: self.delay = 0 self.repeating = False if self.spinnerNode: desired_h = -self.currentSign * 360 / len(self.items) - 90 current_h = self.spinnerNode.get_h() diff = (((desired_h - current_h) + 180) % 360) - 180 delta = diff * globalClock.dt * 10 if abs(delta) > abs(diff): delta = diff self.spinnerNode.set_h(current_h + delta) return task.cont def destroy(self): self.task.remove() self.spinnerNode.removeNode() if not self.menu: self.first.destroy() self.second.destroy() self.third.destroy() self.arrowA.destroy() self.arrowB.destroy() self.help.destroy() def addSign(self): if self.menu: self.activate() return else: self.sound_ye.play() if self.items[self.currentSign] == "end": base.messenger.send("nameEntryDone") return self.currentFrame.setText(self.items[self.currentSign]) if self.currentFrameID < 2: self.arrowA.setX(self.arrowA.getX() + 0.4) self.currentFrameID += 1 if self.currentFrameID == 0: self.currentFrame = self.first elif self.currentFrameID == 1: self.currentFrame = self.second elif self.currentFrameID == 2: self.currentFrame = self.third else: self.currentSign = SIGNS.index("end") def removeSign(self): if self.menu: self.activate() return if self.currentFrame["text"] != "": self.currentFrame.setText("") return if self.currentFrameID > 0: self.sound_no.play() self.arrowA.setX(self.arrowA.getX() - 0.4) self.currentFrameID -= 1 if self.currentFrameID == 0: self.currentFrame = self.first elif self.currentFrameID == 1: self.currentFrame = self.second elif self.currentFrameID == 2: self.currentFrame = self.third def get(self): return "{}{}{}".format(self.first["text"], self.second["text"], self.third["text"]) def rotateLeft(self): self.sound_lo.play() self.currentSign -= 1 if self.currentSign < 0: self.currentSign = len(self.items) - 1 def rotateRight(self): self.sound_lo.play() self.currentSign += 1 if self.currentSign >= len(self.items): self.currentSign = 0