class BetterOnscreenImage(DebugObject): def __init__(self, image=None, parent=None, x=0, y=0, w=10, h=10, transparent=True, nearFilter=True): DebugObject.__init__(self, "BOnscreenImage") self.initialPos = Vec3(x + w / 2.0, 1, -y - h / 2.0) self._node = OnscreenImage( image=image, parent=parent, pos=self.initialPos, scale=(w / 2.0, 1, h / 2.0)) if transparent: self._node.setTransparency(TransparencyAttrib.MAlpha) tex = self._node.getTexture() tex.setMinfilter(Texture.FTNearest) tex.setMagfilter(Texture.FTNearest) tex.setAnisotropicDegree(8) tex.setWrapU(Texture.WMClamp) tex.setWrapV(Texture.WMClamp) def getInitialPos(self): return self.initialPos def posInterval(self, *args, **kwargs): return self._node.posInterval(*args, **kwargs)
def add_counter (self, attr, pic): root = NodePath (PandaNode ('new-root')) root.reparentTo (self.node) img = OnscreenImage ( image = pic, pos = self._next_position, parent = root, scale = 0.1) img.setTransparency (TransparencyAttrib.MAlpha) setattr (self, 'img_' + attr, img) txt_pos = self._next_position + Vec3 (.12, 0, -.05) txt = OnscreenText ( text = '0', shadow = (1, 1, 1, 1), font = self.font, mayChange = True, pos = (txt_pos.getX (), txt_pos.getZ ()), scale = .16, align = TextNode.ALeft, parent = root) setattr (self, 'txt_' + attr, txt) self._next_position += Vec3 (0, 0, -.22) self._counter_nodes.append (root)
def LoadImage(self, filename, parent): myImage = OnscreenImage(image = 'Assets/Images/HUD/%s' % (filename)) myImage.setTransparency(TransparencyAttrib.MAlpha) myImage.reparentTo(parent) myImage.setScale((myImage.getTexture().getOrigFileXSize() / 1024.0, 1, myImage.getTexture().getOrigFileYSize() / 1024.0)) myImage.hide() return myImage
class Preloader: def __init__(self, fonts): self.createGraphics(fonts) file = open("models.txt", "r") self.models = file.readlines() file.close() for N in range(len(self.models)): self.models[N] = self.models[N].replace("\n", "") self.totalItems = len(self.models) self.loaderBar.setTexOffset(self.modTS, .015, 0) base.graphicsEngine.renderFrame() #base.graphicsEngine.renderFrame() self.itemCount = 0 for M in self.models: item = loader.loadModel(M) self.itemCount += 1 progress = self.itemCount / float(self.totalItems) self.loaderBar.setTexOffset(self.modTS, -progress + .005, 0) base.graphicsEngine.renderFrame() #base.graphicsEngine.renderFrame() self.destroy() def createGraphics(self, fonts): self.modTS = TextureStage("Modulate") self.modTS.setMode(TextureStage.MModulate) self.frame = DirectFrame(frameSize = (-.3, .3, -.2, .2), frameColor = (1,1,1,0), parent = base.aspect2d) loaderEgg = loader.loadModel("Models/EnergyBar.egg") self.loaderBG = loaderEgg.find("**/EnergyBG") self.loaderBar = loaderEgg.find("**/EnergyBar") self.loaderFrame = loaderEgg.find("**/EnergyFrame") self.loaderBG.reparentTo(self.frame) self.loaderBar.reparentTo(self.loaderBG) self.loaderFrame.reparentTo(self.loaderBG) self.loaderBG.setPos(0, 0, -.2) alpha = loader.loadTexture("Models/LoaderAlpha.png") alpha.setFormat(Texture.FAlpha) alpha.setWrapU(Texture.WMClamp) self.loaderBar.setTexture(self.modTS, alpha) self.image = OnscreenImage(image = 'Models2/3dcrlogo.png', pos = (0, 0, -.05), scale = (0.799,0,0.152)) self.image.setTransparency(TransparencyAttrib.MAlpha) return def destroy(self): self.loaderBG.removeNode() self.image.destroy() self.frame.destroy()
def LoadContent(self): # Load the dark background blackBG = OnscreenImage(image = 'Assets/Images/Inventory/BlackScreen.png', scale = (2, 1, 1)) blackBG.setTransparency(TransparencyAttrib.MAlpha) blackBG.reparentTo(self.node) # Load the inventory image self.inventoryBackground = OnscreenImage(image = 'Assets/Images/Inventory/inventory.png') self.inventoryBackground.setTransparency(TransparencyAttrib.MAlpha) self.inventoryBackground.reparentTo(self.node) # Load the button for changing the firemode self.fmButton = FireModeButton(self.node) # Load the inventory slots startPos = [[263, 524], [622, 440], [622, 282], [372, 361], [406, 282], [406, 440], [293, 361]] padding = 69 for i, inventory in enumerate(self.inventories): invSlots = inventory.GetInventorySlots() for x in xrange(len(invSlots)): for y in xrange(len(invSlots[0])): inventorySlot = invSlots[x][y] if(isinstance(inventory, MainInventory)): if(y == 0): button = InventorySlotButton(x, y, startPos[i][0], 741, padding, x, 0, inventorySlot, inventory, self.OnInventorySlotButtonClick) else: button = InventorySlotButton(x, y, startPos[i][0], startPos[i][1], padding, x, y - 1, inventorySlot, inventory, self.OnInventorySlotButtonClick) else: button = InventorySlotButton(x, y, startPos[i][0], startPos[i][1], padding, x, y, inventorySlot, inventory, self.OnInventorySlotButtonClick) button.ReparentTo(self.node) inventorySlot.SetInventorySlotButton(button) self.node.hide()
class ItemIcon(): def __init__(self, itemName, parentNode): print 'itemicon', itemName, parentNode self.parentNode = parentNode # The node of its parent (e.g. the inventory) self.itemName = itemName # The filename of the icon self.image = None # The actual icon #self.iconNode = aspect2d.attachNewNode('iconnode') self.LoadContent() def LoadContent(self): self.itemImage = OnscreenImage(image = "Assets/Images/Items/%s.png" % (self.itemName)) self.itemImage.setScale((self.itemImage.getTexture().getOrigFileXSize() / 1024.0, 1, self.itemImage.getTexture().getOrigFileYSize() / 1024.0)) self.itemImage.setTransparency(TransparencyAttrib.MAlpha) self.itemImage.reparentTo(self.parentNode) def setBin(self, binType, value): print 'set bin', binType, value self.itemImage.setBin(binType, value) def SetPos(self, pos): self.itemImage.setPos(pos) def Destroy(self): self.itemImage.destroy()
class EnvironmentLoader(): """ Loads an environment into the game.""" def __init__(self): self.envGen = EnvironmentGenerator() # Used to create a new environment self.SetupDirectories() self.isSaving = False self.saveImage = OnscreenImage(image = 'Assets/Images/HUD/Save.png', scale = 128.0 / 1024, pos = (0.8, 0, -0.85)) self.saveImage.setTransparency(TransparencyAttrib.MAlpha) self.saveImage.reparentTo(aspect2d) self.saveImage.hide() taskMgr.setupTaskChain('EnvironmentSave', numThreads = 1, frameSync = False) def SetupDirectories(self): """ Creates the necessary directories for saving and loading environments. """ self.MkDir('Assets') self.MkDir('Assets/OfflineLevels') self.MkDir('Assets/ServerLevels') def MkDir(self, dirName): """ Creates the specified directory.""" try: os.makedirs(dirName) except OSError, e: if e.errno != errno.EEXIST: raise
class ResultScreen: def __init__(self, rank, score, stats): text_list = [] text_list.append(OnscreenText(text = 'Level Ended', pos = (0.0, 0.7), scale = 0.3, font=babelfish_font, align=TextNode.ACenter, fg=(1,1,1,1))) judgements = ["PERFECT","GOOD","OK","BAD","MISS"] text_j = "\n".join(judgements) text_n = "\n".join(["%d" % stats[j] for j in judgements]) text_list.append(OnscreenText(text = text_j, pos = (-1.2, 0.35), scale = 0.2, font=babelfish_font, align=TextNode.ALeft, fg=(1,1,1,1))) text_list.append(OnscreenText(text = text_n, pos = (0.2, 0.35), scale = 0.2, font=babelfish_font, align=TextNode.ARight, fg=(1,1,1,1))) text_list.append((OnscreenText(text = "RANK", pos = (0.85, 0.35), scale = 0.15, font=babelfish_font, align=TextNode.ACenter, fg=(1,1,1,1)))) self.rank_image = OnscreenImage(image = "./image/rank_%s.png" % rank, pos = (0.7, 0.0, -0.2), scale = (256.0/base.win.getXSize()*0.8, 1.0, 256.0/base.win.getYSize()*0.8), parent=render2d) self.rank_image.setTransparency(TransparencyAttrib.MAlpha) #text_list.append((OnscreenText(text = rank, pos = (0.75, -0.25), scale = 0.9, font=babelfish_font, align=TextNode.ACenter, fg=(1,1,1,1)))) text_list.append((OnscreenText(text = 'SCORE %d'%score, pos = (0.0, -0.7), scale = 0.2, font=babelfish_font, align=TextNode.ACenter, fg=(1,1,1,1)))) text_list.append((OnscreenText(text = 'press "SPACE " to continue', pos = (0.0, -0.9), scale = 0.16, font=babelfish_font, align=TextNode.ACenter, fg=(1,1,1,1)))) self.text_list = text_list def clear(self): self.rank_image.destroy() for txt in self.text_list: txt.destroy()
class Interface(): def __init__(self): self.show_window() def show_window(self): self.window = OnscreenImage(image = "Interface/login_window.png", pos = (0,0,0), scale = (0.5, 1, 0.7) ) self.window.setTransparency(TransparencyAttrib.MAlpha) #add button self.usernameButton = DirectEntry(text = "" ,scale=.05, pos = (-0.3, 0, 0.3), initialText="Username", numLines = 2,focusInCommand=self.clearText1) self.passwordButton = DirectEntry(text = "" ,scale=.05, pos = (-0.3, 0, 0.1), initialText="Password", numLines = 2,focusInCommand=self.clearText2) self.submitButton = DirectButton(image = "Interface/submit2.png", pos = (-0.05, 0, -0.2),scale = (0.2, 1, 0.07)) self.submitButton.setTransparency(TransparencyAttrib.MAlpha) #clear the text def clearText1(self): self.usernameButton.enterText('') def clearText2(self): self.passwordButton.enterText('')
class SplashCard(object): '''this class shows up a splash message''' #------------------------------------------------------------ # def __init__(self, image, backgroundColor): self.loadingimage = OnscreenImage(image, color=(1, 1, 1, 1), scale=.5, parent=aspect2d) self.loadingimage.setTransparency(1) # this image will be on top of all therefore we use setBin 'fixed' and with the higher sort value self.loadingimage.setBin("fixed", 20) self.curtain = OnscreenImage('textures/curtain.png', parent=render2d, color=backgroundColor) self.curtain.setTransparency(1) # this is to set it below the loading panel self.curtain.setBin("fixed", 10) # the loading panel faders self.loadingOut = self.loadingimage.colorInterval(1, Vec4(1, 1, 1, 0), Vec4(1, 1, 1, 1)) # the black curtain faders self.openCurtain = self.curtain.colorScaleInterval(1, Vec4(1, 1, 1, 0), Vec4(1, 1, 1, 1)) for i in range(4): base.graphicsEngine.renderFrame() #------------------------------------------------------------ # def destroy(self): Sequence(self.loadingOut, self.openCurtain).start() #Sequence(self.openCurtain).start() #self.loadingimage.destroy() #self.curtain.destroy()
def __init__(self): # Initialize the ShowBase class from which we inherit, which will # create a window and set up everything we need for rendering into it. ShowBase.__init__(self) base.disableMouse() # Allow manual positioning of the camera camera.setPos(0, -10, 1) # Set the cameras' position camera.setHpr(0, 0, 0) # and orientation self.keyMap = { "left": 0, "right": 0, "up": 0, "down": 0} taskMgr.add(self.startCarousel, "moveTask") imageObject = OnscreenImage(image = 'env_sky.jpg', pos = (-10,0,-10)) imageObject.setImage('env_sky.jpg') imageObject.setTransparency(TransparencyAttrib.MAlpha) self.loadModels() # Load and position our models self.setupLights() # Add some basic lighting self.accept("escape", sys.exit) self.accept("arrow_left", self.setKey, ["left", True]) self.accept("arrow_right", self.setKey, ["right", True]) self.accept("arrow_up", self.setKey, ["up", True]) self.accept("arrow_down", self.setKey, ["down", True]) self.accept("arrow_left-up", self.setKey, ["left", False]) self.accept("arrow_right-up", self.setKey, ["right", False]) self.accept("arrow_up-up", self.setKey, ["up", False]) self.accept("arrow_down-up", self.setKey, ["down", False])
class Speedometer(DirectObject): def __init__(self): self.initSpeedometer() def initSpeedometer(self): """Initialize display of the Speedometer.""" #Load image of the speedometer on the screen. ppp = ( -1, 0, -0.7 ) self.spdm = OnscreenImage(image = 'Resources/Images/speedometer.png', scale=0.25, pos = ppp ) self.spdm.setTransparency(TransparencyAttrib.MAlpha) #Enable Transparency #Load image of the speedometer's pointer on the screen. self.pointer = OnscreenImage(image = 'Resources/Images/needle.png', scale=0.25, pos = ppp ) self.pointer.setTransparency(TransparencyAttrib.MAlpha) #Enable Transparency self.updateSpeedometer(0) def updateSpeedometer(self, speed): """Update indicator of speed on the speedometer, i.e, angle of the pointer. - mainPlayerSpeed: Current speed of the player. - maxSpeed: maxSpeed of the player.""" #Set range of the movement of the pointer, according to the image of the speedometer. minAngle, maxAngle = 0 , 270 maxSpeed = 280 #Calculate the new current angle of the pointer. currentAngle = (speed - 46) * maxAngle / maxSpeed #Set new rotation to the pointer. self.pointer.setR(currentAngle)
def __init__(self): taskMgr.add(self.step,"MinimapTask") pos = Vec3(1.4, 0, -0.64) self.scale = (180) self.constant = 22 cpos = Vec3(0,0,0) #center mapImage = "models/gui/minimap/minimap.png" self.mapRadius = 75 self.distanceScale = (20*self.mapRadius/self.scale) self.map = aspect2d.attachNewNode('Map') props = base.win.getProperties() self.Height = float(props.getYSize()) self.Hscale = (1/self.Height) self.map.setScale(self.Hscale) self.map.setPos(pos) self.dots = [] self.dotPlayer = OnscreenImage(image = "models/gui/minimap/Player.png", scale = 3,pos = (base.camera.getX()/self.constant,0,base.camera.getY()/self.constant), parent = self.map) self.planetTargets = None self.starTargets = None image = OnscreenImage(image = mapImage, scale = self.scale, parent = self.map) image.setTransparency(True)
def loadRareCandyImage(pos=(0.17,0,-0.75)): path = r"../google_drive/ball/data/img/rareCandy.png" rareCandyImage = OnscreenImage(parent=aspect2d, image=path, pos=pos, scale=_SCALE_RARE_CANDY) rareCandyImage.setTransparency(TransparencyAttrib.MAlpha) return rareCandyImage
def makeOnscreenVariable(self,fileName,x,y,z,width,height): imageVariable = OnscreenImage(image = fileName) imageVariable.reparentTo(pixel2d) imageVariable.setPos(x,y,z) imageVariable.setScale(width,1,height) #probably needs an include of some sort imageVariable.setTransparency(TransparencyAttrib.MAlpha) return imageVariable
def LoadContent(self): bg = OnscreenImage(image = 'Assets/Images/Inventory/BlackScreen.png', scale = (2, 1, 1)) bg.setTransparency(TransparencyAttrib.MAlpha) bg.reparentTo(self.node) self.LoadButton('Button_Multiplayer', 'multiplayer', 'multiplayer_over', 0, 0, self.OnButtonClicked, ['multiplayer']) self.LoadButton('Button_Options', 'options', 'options_over', 0, -0.3, self.OnButtonClicked, ['options']) self.LoadButton('Button_Exit', 'exit', 'exit_over', 0, -0.6, self.OnButtonClicked, ['exit'])
class HUD(DirectObject): def __init__(self): self.winXhalf = base.win.getXSize() / 2 self.winYhalf = base.win.getYSize() / 2 croshairsize = 0.05#17.0 self.crosshair = OnscreenImage( image = os.path.join("..", "data", "crosshair.png"), scale = (croshairsize, 1, croshairsize), #pos = (self.winXhalf - croshairsize/2.0, 0, -self.winYhalf - croshairsize/2.0) pos = (0, 0, 0) ) self.crosshair.setTransparency(1) self.ammo = DirectLabel( scale = 0.15, text = "100/100", pos = (base.a2dLeft + 0.025, 0.0, base.a2dBottom + 0.05), text_align = TextNode.ALeft, frameColor = (0, 0, 0, 0), text_fg = (1,1,1,1), text_shadow = (0, 0, 0, 1), text_shadowOffset = (0.05, 0.05) ) self.ammo.setTransparency(1) self.nowPlaying = DirectLabel( scale = 0.05, text = "Now Playing: Echovolt - Nothing to Fear", pos = (base.a2dLeft + 0.025, 0.0, base.a2dTop - 0.05), text_align = TextNode.ALeft, frameColor = (0, 0, 0, 0), text_fg = (1,1,1,1) ) self.nowPlaying.setTransparency(1) self.accept("window-event", self.recalcAspectRatio) self.hide() def show(self): self.crosshair.show() self.nowPlaying.show() self.ammo.show() def hide(self): self.crosshair.hide() self.nowPlaying.hide() self.ammo.hide() def updateAmmo(self, maxAmmo, ammo): self.ammo["text"] = "%02d/%02d" % (maxAmmo, ammo) def recalcAspectRatio(self, window): self.ammo.setPos(base.a2dLeft + 0.025, 0.0, base.a2dBottom + 0.05) self.ammo.setPos(base.a2dLeft + 0.025, 0.0, base.a2dTop - 0.05)
class ButtonViewer: def __init__(self, bpm, z_pos = -0.7): self.BTN_SPACE_PER_BEAT = 0.2 self.BTN_SIZE = 64.0 self.BTN_SIZE = 64.0 self.BTN_SCALE = (self.BTN_SIZE/base.win.getXSize(), 1 ,self.BTN_SIZE/base.win.getYSize()) self.z_pos = z_pos self.delay_per_beat = beat_delay(bpm) self.tex_buttons = {} for b, i in zip(["A", "B", "C", "D"],["down", "right", "left", "up"]): self.tex_buttons[b] = loader.loadTexture("image/wii_%s.png" % i) #~ else: #~ for b, i in zip(["A", "B", "C", "D"],["cross", "circle", "square", "triangle"]): #~ self.tex_buttons[b] = loader.loadTexture("image/b_%s.png" % i) ## Button marker self.button_marker = OnscreenImage(image="image/b_marker.png",pos=(0, 2, self.z_pos), scale=self.BTN_SCALE, parent=render2d) self.button_marker.setTransparency(TransparencyAttrib.MAlpha) self.button_node = render2d.attachNewNode("Button Root Node") self.initial_x = self.button_node.getX() self.next_button = 0 def append_button(self, button, beat): btn_image = OnscreenImage(image=self.tex_buttons[button], pos=(-beat*self.BTN_SPACE_PER_BEAT, 0, self.z_pos), scale=self.BTN_SCALE, parent=render2d) btn_image.setTransparency(TransparencyAttrib.MAlpha) btn_image.reparentTo(self.button_node) def update(self, time): self.button_node.setX(self.initial_x + time2pos(time, self.delay_per_beat, self.BTN_SPACE_PER_BEAT)) def button_hit(self): pass #~ button = self.button_node.getChild(self.next_button) #~ button.setAlphaScale(.0) #~ self.next_button += 1 #~ button = self.button_node.getChild(self.next_button ) #~ pos = render2d.getRelativePoint(self.button_node, button.getPos()) #~ button.reparentTo(render2d) #~ button.setPos(pos) #~ LerpFunc(button.setAlphaScale, duration=0.2, fromData=1, toData=0, blendType='easeOut').start() def button_miss(self): pass #self.next_button += 1 def __del__(self): self.button_node.removeNode() self.button_marker.removeNode()
class HUD(): def __init__(self): self.speedometer = OnscreenImage(image = 'img/speedometerDial.png', pos = (-1, 0, -.7) ) self.speedometer.setScale(.25) self.speedometer.setTransparency(TransparencyAttrib.MAlpha) self.speedPin = OnscreenImage(image = 'img/speedometerNeedle.png', pos = (-1, 0, -.7)) self.speedPin.setScale(.10) self.speedPin.setTransparency(TransparencyAttrib.MAlpha) self.speedPin.setHpr(0, 0, 0) self.minimap = OnscreenImage(image = 'img/minimap.png', pos = (1.05, 0, -.65)) self.minimap.setScale(.19, .19, .3) self.dot = OnscreenImage(image = 'img/dot.png', pos = (1.01, 0, -.55)) self.dot.setScale(.025) font1 = loader.loadFont('img/goodfish.ttf') self.lapText = OnscreenText(text = "0/10", font = font1, pos = (1, -.1, 0), fg = (1, 1, 1, 1) ) self.lapText.setScale(.05) self.placeText = OnscreenText(text = "", font = font1, pos = (1, -.2, 0), fg = (1, 1, 1, 1)) self.placeText.setScale(.05) self.timerText = OnscreenText(text = "Time: ", font = font1, pos = (1, -.3, 0), fg = (1, 1, 1, 1)) def update(self, velocity, x, y, laps, place, time): if velocity < 0: velocity = -velocity self.dot.setPos(1.01+(x/4250), 0, -.55+(y/4250)) self.lapText.setText("Laps: " + str(laps)+"/3") self.speedPin.setHpr(0, 0, 4*velocity) self.placeText.setText("Position: "+str(place)) self.timerText.setText("Time: "+ str(round(time))) """def getDist(self, x, y, checkpoint): cx = checkpoint[0] cy = checkpoint[1] dist = math.sqrt((cx-x)**2 + (cy-y)**2) rotAngle = math.atan2(-y,x) newX = x*math.cos(rotAngle) - y*math.sin(rotAngle) dToCheckpoint = dist - newX return dToCheckpoint""" """def updateMiniMap(self, x, y): self.dot.setPos(1+(x/1000), 0, -.7+(y/1000))"""
class LifeBar: def __init__(self): ## Life bar self.image = OnscreenImage(image="image/life_bar.png",pos=(0, 0, 0), scale=(256.0/base.win.getXSize(),1,32.0/base.win.getYSize()), parent=render2d) self.image.setTransparency(TransparencyAttrib.MAlpha) self.image.setZ(-0.9) self.image.setY(2) def __del__(self): self.image.destroy()
class ScreenDecorationManager: def __init__(self): self.tex_judgements = {} for i in ["PERFECT","GOOD","OK","BAD","MISS"]: self.tex_judgements[i] = loader.loadTexture("image/j_%s.png" % i.lower()) ## Judgement message self.image_judgement = OnscreenImage(image=self.tex_judgements["OK"],pos=(0, 0, 0), scale=(256.0/base.win.getXSize(),1,32.0/base.win.getYSize()), parent=render2d) self.image_judgement.setTransparency(TransparencyAttrib.MAlpha) #self.image_judgement.setPos(-0.7, 1, 0.6) self.image_judgement.setAlphaScale(0) interval_pos = LerpPosInterval(self.image_judgement, duration=0.1, startPos=VBase3(-1.2, 1, 0.5), pos=VBase3(-0.7, 1, 0.5), blendType='easeOut') interval_alpha = LerpFunc(self.image_judgement.setAlphaScale, duration=0.1, blendType='easeOut') interval_fade = LerpFunc(self.image_judgement.setAlphaScale, fromData=1, toData=0, duration=1.0, blendType='easeOut') self.judgement_enters = Sequence(Parallel(interval_pos, interval_alpha), Wait(1.0), interval_fade) ## Chain message text_node = TextNode('chain_msg') text_node.setAlign(TextNode.ACenter) text_node.setFont(babelfish_font) text_node.setTextColor(1, 1, 0.16, .9) text_node.setShadow(0.05, 0.05) text_node.setShadowColor(0.05, 0, 0.43, .9) self.chain_msg = aspect2d.attachNewNode(text_node) self.chain_msg.setPos(-.9, 1, 0.35) self.chain_msg.setScale(0.11) def judgement_msg(self, msg, chain): if self.judgement_enters.isPlaying(): self.judgement_enters.clearToInitial() self.image_judgement.setTexture(self.tex_judgements[msg]) self.judgement_enters.start() if chain > 1: self.chain_msg.node().setText("%d CHAIN" % chain) taskMgr.add(self.task_ClearJudgementTask, "clear-judgement") def task_ClearJudgementTask(self, task): if task.time < 1.5: return Task.cont self.chain_msg.node().clearText() def __del__(self): self.judgement_enters.finish() self.image_judgement.destroy() self.chain_msg.removeNode()
def createVelocityIndicator(self, colour=None): """ loads an image used to represent the direction of motion """ if colour is None: colour = self.colour # load the image, put it in aspect2d and make sure # transparency is respected vel_ind = OnscreenImage(image="gui/velocityindicator.png", pos=(0.0, 0.0, 0.0), scale=0.05, color=colour) vel_ind.reparentTo(aspect2d) vel_ind.setTransparency(TransparencyAttrib.MAlpha) return vel_ind
class Main(DirectObject): def __init__(self): # Network Setup self.cManager = ConnectionManager() self.startConnection() #taskMgr.add(self.menu, "Menu") base.win.setClearColor(Vec4(0,0,0,1)) self.imageObject = OnscreenImage(parent = render2d, image = 'images/mainPage.png', pos = (0,0,0), scale = (1.444, 1, 1.444)) self.imageObject.setTransparency(TransparencyAttrib.MAlpha) self.button = DirectButton(image ='images/button.png',pos = (-.1,0,-.25), relief = None, scale = .40, command = self.startWorld) self.button.setTransparency(TransparencyAttrib.MAlpha) #self.cAudio = def startConnection(self): """Create a connection to the remote host. If a connection cannot be created, it will ask the user to perform additional retries. """ if self.cManager.connection == None: if not self.cManager.startConnection(): return False return True def menu(self, task): # Accept raw_input choice choice = input("1 - Rand int\n2 - Rand string\n3 - Rand short\n4 - Rand float\n6 - Exit\n") msg = 0 if choice is 1: msg = random.randint(-(2**16), 2**16 - 1) elif choice is 2: msg = ''.join(random.choice('abcdefghijklmnopqrstuvwxyz') for x in range(7)) elif choice is 3: msg = random.randint(0, 2**16 - 1) elif choice is 4: msg = 100 * random.random() elif choice is 6: sys.exit() else: print "Invalid input" self.cManager.sendRequest(choice, msg); def startWorld(self): #send login request print "elll"
def LoadCrosshair(self, filename): parentNode = self.node.attachNewNode('CrossHair') if('Sniper' in filename): x = OnscreenImage(image = 'Assets/Images/Crosshairs/OuterBlack.png', scale = 2.2) x.setTransparency(TransparencyAttrib.MAlpha) x.reparentTo(parentNode) x = OnscreenImage(image = 'Assets/Images/Crosshairs/%s.png' % (filename), scale = 1) x.setTransparency(TransparencyAttrib.MAlpha) x.reparentTo(parentNode) parentNode.hide() return parentNode
def create_token_counter(self): # Set onscreen image and set transparency self.shape = OnscreenImage(image = 'img/tire_score.png', pos = (1, 0, -.85), scale = (.3,1,.1)) self.shape.setTransparency(TransparencyAttrib.MAlpha) # Set another onscreen image and set transparency tire = OnscreenImage(parent=self.shape,image = 'img/tire.png', pos = (-1, 0, 0), scale = (.4,1,1)) tire.setTransparency(TransparencyAttrib.MAlpha) # Set text displaying the number of token collected self.score = OnscreenText(parent=self.shape, text = str(self.__game.eve.tiresCollected), pos = (0, -.1), scale = (.3,.8), fg=(255,255,255,1)) # Hide token counter self.shape.hide()
class OptionsScreen: def __init__(self, options): self.bg = OnscreenImage(image='./image/bg.png', pos = (0.0, -1.0, 0.0), parent=render2d) self.bg.setTransparency(TransparencyAttrib.MAlpha) self.title = OnscreenText(text = 'Options', pos = (0.0, 0.7), scale = 0.3, font=babelfish_font, align=TextNode.ACenter, fg=(1,1,1,1)) self.option_title_txt = OnscreenText(text='Controller', scale=0.2, pos=(-1.0, 0.0), font=babelfish_font, align=TextNode.ALeft, fg=(1,1,1,1)) self.option_value = options.get('game-opts', 'controller') self.option_value_txt = OnscreenText(text=self.option_value, scale=0.2, pos=(.7, 0.0), font=babelfish_font, align=TextNode.ACenter, fg=(1,1,1,1)) self.options = options self.curr_controller = 0 self.controllers = ['Keyboard','Joypad', 'Mouse'] #define o controle atual baseado no arquivo salvo for f in self.controllers: if f == self.option_value: break else: self.curr_controller += 1 def option_changed(self, command): self.toggle_value(command) def toggle_value(self, opt): if opt == 'nav-right': self.curr_controller += 1 elif opt == 'nav-left': self.curr_controller -= 1 if (self.curr_controller >= len(self.controllers)): self.curr_controller = 0 elif (self.curr_controller < 0): self.curr_controller = len(self.controllers) - 1 self.option_value = self.controllers[self.curr_controller] self.option_value_txt.destroy() self.option_value_txt = OnscreenText(text=self.option_value, scale=0.2, pos=(.7, 0.0), font=babelfish_font, align=TextNode.ACenter, fg=(1,1,1,1)) def clear(self): self.bg.destroy() self.title.destroy() self.option_title_txt.destroy() self.option_value_txt.destroy() self.options.set('game-opts', 'controller', self.option_value)
def loadGUI(self): self.vidas_imgs = list() w = 0.24 for i in range(self.VIDAS): image_warning = OnscreenImage(image = '../data/Texture/signal_warning.png', pos=(-1 + i*w, 0, 0.85), parent=self._playing_node2d) image_warning.setScale(0.1) image_warning.setTransparency(TransparencyAttrib.MAlpha) image_warning.hide() image_ok = OnscreenImage(image = '../data/Texture/signal_ok.png', pos=(-1 + i*w, 0, 0.85), parent=self._playing_node2d) image_ok.setScale(0.1) image_ok.setTransparency(TransparencyAttrib.MAlpha) image_ok.show() self.vidas_imgs.append((image_ok, image_warning)) self._level_time_O = OnscreenText(text = '', pos = (0, 0.85), scale = 0.14, fg=(1.0, 1.0, 1.0, 1.0), bg=(0.0, 0.0, 0.0, 1.0), parent=self._playing_node2d)
def LoadContent(self, title, message): bg = OnscreenImage(image = 'Assets/Images/Inventory/BlackScreen.png', scale = (2, 1, 1)) bg.setTransparency(TransparencyAttrib.MAlpha) bg.reparentTo(self.node) popup = OnscreenImage(image = 'Assets/Images/Menus/Popups/popup.png') popup.setTransparency(TransparencyAttrib.MAlpha) popup.reparentTo(self.node) titleText = OnscreenText(text = title, pos = (-0.29, 0.51), scale = 0.07, fg = (1, 1, 1, 1)) titleText.reparentTo(self.node) self.LoadButton('Button_Okay', 'okay', 'okay_over', -0.27, -0.13, self.OnButtonClicked, ['okay']) self.LoadButton('Button_Cancel', 'cancel', 'cancel_over', 0.27, -0.13, self.OnButtonClicked, ['cancel']) messageText = OnscreenText(text = message, pos = (0, 0.2), scale = 0.07, fg = (1, 1, 1, 1)) messageText.reparentTo(self.node)
def make_level_item(self, level_header): level_name = level_header['NAME'] level_item = aspect2d.attachNewNode(level_name) level_img = OnscreenImage(image='./levels/%s/image.png' % level_name, scale=(512.0/base.win.getXSize(), 1 ,362.0/base.win.getYSize()), pos = (0.0, 0.0, 0.3), parent=level_item) level_img.setTransparency(TransparencyAttrib.MAlpha) level_img.reparentTo(level_item) if level_header.has_key("TITLE"): title_str = "%s" % level_header["TITLE"] else: title_str = "%s" % level_header["NAME"] artist_str = "" if level_header.has_key("ARTIST"): artist_str = "by %s" % level_header["ARTIST"] title_text = OnscreenText(text = title_str, pos = (0.0, 0.-0.3), scale = 0.2, font=babelfish_font, align=TextNode.ACenter, fg=(1,1,1,1)) title_text.reparentTo(level_item) next_y = -0.50 if artist_str: next_y -= 0.05 artist_text = OnscreenText(text = artist_str, pos = (0.0, 0.-0.4), scale = 0.15, font=babelfish_font, align=TextNode.ACenter, fg=(1,1,1,1)) artist_text.reparentTo(level_item) bpm_text = OnscreenText(text = "BPM %.2f" % level_header["BPM"], pos = (0.0, next_y), scale = 0.18, font=babelfish_font, align=TextNode.ACenter, fg=(1,1,1,1)) bpm_text.reparentTo(level_item) if self.game_opts.has_option('hiscores', level_name): his = self.game_opts.get('hiscores', level_name).split(',') maxrank = OnscreenText(text = "max rank %s" % his[0].upper(), pos = (0.0, next_y-0.15), scale = 0.18, font=babelfish_font, align=TextNode.ACenter, fg=(1,1,1,1)) hiscore = OnscreenText(text = "hiscore %s" % his[1], pos = (0.0, next_y-0.25), scale = 0.18, font=babelfish_font, align=TextNode.ACenter, fg=(1,1,1,1)) maxrank.reparentTo(level_item) hiscore.reparentTo(level_item) return level_item
class HUDBottomRight(DirectObject): def __init__(self): self.node = base.a2dBottomRight.attachNewNode('hudBottomRight')#GUIOrder.ORDER[GUIOrder.HUD]) self.node.setBin('fixed', GUIOrder.ORDER[GUIOrder.HUD]) self.ammoIcon = OnscreenImage(image = 'Assets/Images/HUD/HUDBottomRight.png', scale = 512.0 / 1024, pos = (-0.5, 0, 0.5)) self.ammoIcon.setTransparency(TransparencyAttrib.MAlpha) self.ammoIcon.reparentTo(self.node) self.ammoTextClip = OnscreenText(text = '30', pos = (-0.35, 0.09), scale = 0.12, fg = (1, 1, 1, 1), shadow = (0, 0, 0, 1), mayChange = True, align=TextNode.ARight, font = Globals.FONT_SAF) self.ammoTextClip.reparentTo(self.node) self.ammoTextClip.setBin('fixed', GUIOrder.ORDER[GUIOrder.HUD]) self.ammoTextLeft = OnscreenText(text = '90', pos = (-0.23, 0.05), scale = 0.07, fg = (1, 1, 1, 1), shadow = (0, 0, 0, 1), mayChange = True, align=TextNode.ARight, font = Globals.FONT_SAF) self.ammoTextLeft.reparentTo(self.node) self.ammoTextLeft.setBin('fixed', GUIOrder.ORDER[GUIOrder.HUD]) self.accept(AmmoChangeEvent.EventName, self.OnAmmoChangeEvent) self.accept(SelectedItemChangeEvent.EventName, self.OnSelectedItemChangeEvent) def OnAmmoChangeEvent(self, event): item = event.GetItem() if(item and item.GetCurrentClipAmmo() == ''): self.ChangeAmmoText('', '') else: self.ChangeAmmoText(str(item.GetCurrentClipAmmo()), str(item.GetTotalRemainingAmmo())) def ChangeAmmoText(self, clip, total): self.ammoTextClip.setText(clip) self.ammoTextLeft.setText(total) def OnSelectedItemChangeEvent(self, event): if(event.GetItemStack() and event.GetItemStack().GetItem()): self.OnAmmoChangeEvent(AmmoChangeEvent(None, event.GetItemStack().GetItem())) else: self.ChangeAmmoText('', '') def Destroy(self): self.ignoreAll() self.ammoIcon.removeNode() self.ammoTextClip.removeNode() self.ammoTextLeft.removeNode() self.node.removeNode()
class miniMap(object): def __init__(self, mainActor): self.teamMateImage = 'models/hexahedron.png' self.heroImage = 'models/mainHero2.png' self.miniMapImage = 'models/miniMap000.png' self.towerImage = 'models/tower_neitral.png' self.towerRed = 'models/tower_red.png' self.towerBlue = 'models/tower_blue.png' self.map = OnscreenImage(image = self.miniMapImage, pos=(-0.7, 0, 0.8), scale=(MAP_SCALEX, 0, MAP_SCALEY)) self.map.setTransparency(1) #self.map.reparentTo(rander) self.hero = OnscreenImage(image=self.heroImage, pos=(mainActor.getX()/525, 0, mainActor.getY()/160), scale=(HERO_SCALE, 1, HERO_SCALE), hpr=(0, 0, mainActor.getH())) self.hero.reparentTo(self.map) self.hero.setTransparency(1) self.npc = {} self.tower = {} self.team = {} def resizeScreen(self, x, y): if x != 800 and y != 600: self.map.setPos(-1.4, 0, 0.8) else: self.map.setPos(-0.7, 0, 0.8) def setMap(self, mapScale, x, y): self.map = OnscreenImage(image = self.miniMapImage, pos=(x, 0, y), scale=(mapScale, mapScale, mapScale)) return self.map def setHero(self, heroScale, x, y, h): self.hero = OnscreenImage(image=self.heroImage, pos=(x, 0, y), scale=(heroScale, 1, heroScale), hpr=(0, 0, h)) return self.hero def updateHeroPos(self, getX, getY): if getX <= 0 and getY <= 0: ay = (MAP_AY + (getY))/MAP_AY y = MAP_SCALEY-(ay*MAP_SCALEY) ax = (MAP_AX + (getX))/MAP_AX x = MAP_SCALEX-(ax*MAP_SCALEX) elif getX > 0 and getY < 0: ay = (MAP_AY + (getY))/MAP_AY y = MAP_SCALEY-(ay*MAP_SCALEY) ax = (MAP_BX - (getX))/MAP_BX x = -MAP_SCALEX+(ax*MAP_SCALEX) elif getX < 0 and getY > 0: ay = (MAP_BY - (getY))/MAP_BY y = -MAP_SCALEY+(ay*MAP_SCALEY) ax = (MAP_AX + (getX))/MAP_AX x = MAP_SCALEX-(ax*MAP_SCALEX) else: ay = (MAP_BY - (getY))/MAP_BY y = -MAP_SCALEY+(ay*MAP_SCALEY) ax = (MAP_BX - (getX))/MAP_BX x = -MAP_SCALEX+(ax*MAP_SCALEX) self.hero.setPos(x, 0, y) def updateHeroHpr(self, getH): h = -getH self.hero.setHpr(0, 0, h) def setNpc(self, npcName, npcImage, npcScale, x, y): self.Nps = OnscreenImage(image=npcImage, pos=(x, 0, y), scale=(npcScale*MAP_SCALEY, 1, npcScale*MAP_SCALEX)) self.Nps.reparentTo(self.map) self.Nps.setTransparency(1) self.npc[npcName] = self.Nps return self.npc def delNpc(self, npcName): del self.npc[npcName] def setTower(self, towerName, towerScale, getX, getY): if getX <= 0 and getY <= 0: ay = (MAP_AY + (getY))/MAP_AY y = MAP_SCALEY-(ay*MAP_SCALEY) ax = (MAP_AX + (getX))/MAP_AX x = MAP_SCALEX-(ax*MAP_SCALEX) elif getX > 0 and getY < 0: ay = (MAP_AY + (getY))/MAP_AY y = MAP_SCALEY-(ay*MAP_SCALEY) ax = (MAP_BX - (getX))/MAP_BX x = -MAP_SCALEX+(ax*MAP_SCALEX) elif getX < 0 and getY > 0: ay = (MAP_BY - (getY))/MAP_BY y = -MAP_SCALEY+(ay*MAP_SCALEY) ax = (MAP_AX + (getX))/MAP_AX x = MAP_SCALEX-(ax*MAP_SCALEX) else: ay = (MAP_BY - (getY))/MAP_BY y = -MAP_SCALEY+(ay*MAP_SCALEY) ax = (MAP_BX - (getX))/MAP_BX x = -MAP_SCALEX+(ax*MAP_SCALEX) self.tower_ = OnscreenImage(image=self.towerImage, pos=(x, 0, y), scale=(towerScale*MAP_SCALEY, 1, towerScale*MAP_SCALEX)) self.tower_.reparentTo(self.map) self.tower_.setTransparency(1) self.tower[towerName] = self.tower_ return self.tower def changeTowerColor(self, towerName, towerImage): self.tower[towerName].setImage(towerImage) def delTower(self, towerName): del self.tower[towerName] def setTeamMate(self, mateName, mateScale, getX, getY): if getX <= 0 and getY <= 0: ay = (MAP_AY + (getY))/MAP_AY y = MAP_SCALEY-(ay*MAP_SCALEY) ax = (MAP_AX + (getX))/MAP_AX x = MAP_SCALEX-(ax*MAP_SCALEX) elif getX > 0 and getY < 0: ay = (MAP_AY + (getY))/MAP_AY y = MAP_SCALEY-(ay*MAP_SCALEY) ax = (MAP_BX - (getX))/MAP_BX x = -MAP_SCALEX+(ax*MAP_SCALEX) elif getX < 0 and getY > 0: ay = (MAP_BY - (getY))/MAP_BY y = -MAP_SCALEY+(ay*MAP_SCALEY) ax = (MAP_AX + (getX))/MAP_AX x = MAP_SCALEX-(ax*MAP_SCALEX) else: ay = (MAP_BY - (getY))/MAP_BY y = -MAP_SCALEY+(ay*MAP_SCALEY) ax = (MAP_BX - (getX))/MAP_BX x = -MAP_SCALEX+(ax*MAP_SCALEX) self.teamMate = OnscreenImage(image=self.teamMateImage, pos=(x, 0, y), scale=(mateScale*MAP_SCALEY, 1, mateScale*MAP_SCALEX)) self.teamMate.reparentTo(self.map) self.teamMate.setTransparency(1) self.team[mateName] = self.teamMate return self.team def updateTeamMatePos(self, mateName, getX, getY): if getX <= 0 and getY <= 0: ay = (MAP_AY + (getY))/MAP_AY y = MAP_SCALEY-(ay*MAP_SCALEY) ax = (MAP_AX + (getX))/MAP_AX x = MAP_SCALEX-(ax*MAP_SCALEX) elif getX > 0 and getY < 0: ay = (MAP_AY + (getY))/MAP_AY y = MAP_SCALEY-(ay*MAP_SCALEY) ax = (MAP_BX - (getX))/MAP_BX x = -MAP_SCALEX+(ax*MAP_SCALEX) elif getX < 0 and getY > 0: ay = (MAP_BY - (getY))/MAP_BY y = -MAP_SCALEY+(ay*MAP_SCALEY) ax = (MAP_AX + (getX))/MAP_AX x = MAP_SCALEX-(ax*MAP_SCALEX) else: ay = (MAP_BY - (getY))/MAP_BY y = -MAP_SCALEY+(ay*MAP_SCALEY) ax = (MAP_BX - (getX))/MAP_BX x = -MAP_SCALEX+(ax*MAP_SCALEX) self.team[mateName].setPos(x, 0, y) def updateTeamMateHpr(self, mateName, getH): h = -getH self.team[mateName].setHpr(0, 0, h) def delTeamMate(self, mateName): del self.team[mateName]
class Player(object): """ Player is the main actor in the fps game """ HP = 100 EROSION = 0 updateTime = 0 speed = 10 FORWARD = Vec3(0, 2, 0) BACK = Vec3(0, -1, 0) LEFT = Vec3(-1, 0, 0) RIGHT = Vec3(1, 0, 0) STOP = Vec3(0) walk = STOP strafe = STOP readyToJump = False jump = 0 state = '' cameraState = 1 visionState = 0 RightButton = 0 LeftButton = 0 goodmanager = None isInteractive = False SLOW = 1 End = 0 Begin = 1 TaskState = End def __init__(self, goodmanager, m, g): """ inits the player """ # 6/17 self.walksound = loader.loadSfx("res/sounds/footstep.mp3") self.goodmanager = goodmanager self.menu = m self.game = g self.loadModel() self.setUpCamera() self.setMouseIcon() self.createCollisions() self.attachControls() self.initSkill() self.shoot = Shoot() # init mouse update task self.initSave() self.initTask() self.initMission() def initMission(self): if self.game.levelName == "tutorial": self.mission = Mission(self, self.menu) elif self.game.levelName == "levelTwo": self.mission = MissionTwo(self, self.menu) elif self.game.levelName == "levelThree": self.mission = MissionThree(self, self.menu) def initSave(self): self.erosionFrame = DirectFrame(frameColor=(0, 0, 0, 0), frameSize=(-1, 1, -1, 1), pos=(-1.2, 0, 0)) self.erosionFrame.hide() self.erosionFrame.setScale(.02, 1, .4) self.background = OnscreenImage('res/erosion_bar.png', pos=(0, 0, 0), scale=(1, 1, 1)) self.background.setTransparency(TransparencyAttrib.MAlpha) self.background.reparentTo(self.erosionFrame) # self.erosionBar = DirectWaitBar(value=self.EROSION, pos=(0, 0, 0), barTexture='res/erosion_value.png', # relief=None) # self.erosionBar.setHpr(0, 0, -90) # self.erosionBar.setScale(0.98, 1, 10) # self.erosionBar.hide() # self.erosionBar.reparentTo(self.erosionFrame) self.erosionBar = OnscreenImage('res/erosion_value.png', pos=(0, 0, 0), scale=(1, 1, 1)) self.erosionBar.setScale(1) self.erosionBar.setTransparency(TransparencyAttrib.MAlpha) self.erosionBar.reparentTo(self.erosionFrame) self.currentItemFrame = DirectFrame( frameColor=(0, 0, 0, 0), frameSize=(-2, 2, -2, 2), pos=(-1.2, 0, .8), image='res/models/items/injection.png', scale=(.1)) self.currentItemFrame.setTransparency(TransparencyAttrib.MAlpha) self.currentItemFrame.hide() # self.currentItemFrame.show() def initTask(self): if self.TaskState == self.Begin: return self.TaskState = self.Begin self.state = '' self.game.gameState = '' self.mouseIconNormal.show() taskMgr.add(self.mouseUpdate, "mouse-task") taskMgr.add(self.moveUpdate, "move-task") taskMgr.add(self.jumpUpdate, 'jump-task') taskMgr.add(self.erosionUpdate, "erosion-task") def endTask(self): if self.TaskState == self.End: return self.TaskState = self.End self.state = 'pause' self.mouseIconWatch.hide() self.mouseIconNormal.hide() taskMgr.remove('mouse-task') taskMgr.remove('move-task') taskMgr.remove('jump-task') taskMgr.remove('erosion-task') # reset update time self.updateTime = 5 def loadModel(self): """ make the nodepath for player """ # self.playerModel = Actor("res/models/ralph", {"run": "res/models/ralph-run", "walk": "res/models/ralph-walk"}) self.playerModel = Actor("res/models/hitman-model5", { "walk": "res/models/hitman-walk5", "stand": "res/models/hitman-stand" }) # self.playerModel = Actor("res/models/hitman2-model", {"walk": "res/models/hitman2-walk", "stand":"res/models/hitman-stand"}) self.playerModel.setH(180) self.playerModel.setZ(0) self.playerModel.setScale(1.1) # self.playerModel.hide() self.node = NodePath("player") self.node.reparentTo(render) self.playerModel.reparentTo(self.node) # self.node.setPos(0, 0, 10) self.node.setPos(-250, 265, 0) self.node.setHpr(150, 0, 0) self.node.setScale(20) self.node.hide(BitMask32.bit(0)) self.node.hide(BitMask32.bit(1)) def setMouseIcon(self): self.mouseIconNormal = OnscreenImage(image="res/mouse/mouse1.png", pos=(0, 1.1, 0)) self.mouseIconNormal.setTransparency(TransparencyAttrib.MAlpha) self.mouseIconNormal.setScale(0.02) self.mouseIconNormal.setLightOff() self.mouseIconNormal.setSa(0.5) self.mouseIconWatch = OnscreenImage(image="res/mouse/mouse2.png", pos=(0, 1.1, 0)) self.mouseIconWatch.setTransparency(TransparencyAttrib.MAlpha) self.mouseIconWatch.setScale(0.05) self.mouseIconWatch.setSa(0.5) self.mouseIconWatch.setLightOff() self.mouseIconNormal.reparentTo(base.camera) self.mouseIconWatch.reparentTo(base.camera) self.mouseIconWatch.hide() def SetMouseModeNormal(self, mode): if mode == 'Watch': self.mouseIconWatch.show() self.mouseIconNormal.hide() elif mode == 'Normal': self.mouseIconNormal.show() self.mouseIconWatch.hide() def setUpCamera(self): """ puts camera at the players node """ pl = base.cam.node().getLens() pl.setFov(70) base.cam.node().setLens(pl) base.camera.reparentTo(self.node) base.cam.node().setCameraMask(BitMask32.bit(3)) self.oldcameraState = 0 self.cameranewPos = None self.cameranewH = None self.changeCamera() # 6/17 def createCollisions(self): """ create a collision solid and ray for the player """ cn = CollisionNode('PlayerCollideNode') cn.addSolid(CollisionSphere(0, 0, 4, 1)) solid = self.node.attachNewNode(cn) solid.setScale(1, 1, 1) solid.setPos(0, 0, 0) # solid.show() base.cTrav.addCollider(solid, base.pusher) base.pusher.addCollider(solid, self.node, base.drive.node()) # init players floor collisions ray = CollisionRay() ray.setOrigin(0, 0, 3) ray.setDirection(0, 0, -1) cn = CollisionNode('playerRay') cn.addSolid(ray) cn.setFromCollideMask(BitMask32.bit(0)) cn.setIntoCollideMask(BitMask32.allOff()) solid = self.node.attachNewNode(cn) # solid.show() base.cTrav.setRespectPrevTransform(True) self.nodeGroundHandler = CollisionHandlerQueue() base.cTrav.addCollider(solid, self.nodeGroundHandler) # init players Forward Ray ForwardSegment = CollisionSegment(0, 2, 0, 0, 20, 0) cn = CollisionNode('playerForwardSegment') cn.addSolid(ForwardSegment) cn.setFromCollideMask(BitMask32.bit(0)) cn.setIntoCollideMask(BitMask32.allOff()) solid = base.camera.attachNewNode(cn) # solid.show() base.cTrav.addCollider(solid, self.nodeGroundHandler) # repair cross wall ForwardSegment = CollisionSegment(0, -4, 3, 0, 4, 3) cn = CollisionNode('PlayerMoveForwardSegment') cn.addSolid(ForwardSegment) cn.setFromCollideMask(BitMask32.bit(0)) cn.setIntoCollideMask(BitMask32.allOff()) solid = self.node.attachNewNode(cn) # solid.show() base.cTrav.addCollider(solid, self.nodeGroundHandler) # init play Right Ray ForwardSegment = CollisionSegment(-2, 0, 3, 2, 0, 3) cn = CollisionNode('PlayerMoveRightSegment') cn.addSolid(ForwardSegment) cn.setFromCollideMask(BitMask32.bit(0)) cn.setIntoCollideMask(BitMask32.allOff()) solid = self.node.attachNewNode(cn) # solid.show() base.cTrav.addCollider(solid, self.nodeGroundHandler) def attachControls(self): """ attach key events """ # base.accept("space", self.__setattr__, ["readyToJump", True]) # base.accept("space-up", self.__setattr__, ["readyToJump", False]) self.keyEven = [ "s", "s-up", "w", "w-up", "a", "d", "a-up", "d-up", "c", "o", "mouse3", "mouse3-up", "mouse1", "mouse1-up" ] base.accept("s", self.__setattr__, ["walk", self.STOP]) base.accept("w", self.__setattr__, ["walk", self.FORWARD]) base.accept("s", self.__setattr__, ["walk", self.BACK]) base.accept("s-up", self.__setattr__, ["walk", self.STOP]) base.accept("w-up", self.__setattr__, ["walk", self.STOP]) base.accept("a", self.__setattr__, ["strafe", self.LEFT]) base.accept("d", self.__setattr__, ["strafe", self.RIGHT]) base.accept("a-up", self.__setattr__, ["strafe", self.STOP]) base.accept("d-up", self.__setattr__, ["strafe", self.STOP]) base.accept("c", self.changeCamera) base.accept("o", self.doubleVision) base.accept("mouse3", self.__setattr__, ["RightButton", 1]) base.accept("mouse3-up", self.__setattr__, ["RightButton", 0]) base.accept("mouse1", self.__setattr__, ["LeftButton", 1]) base.accept("mouse1-up", self.__setattr__, ["LeftButton", 0]) def IgnoreControls(self): for name in self.keyEven: base.ignore(name) print base.getAllAccepting() def initSkill(self): self.tex = Texture() self.tex.setMinfilter(Texture.FTLinear) base.win.addRenderTexture(self.tex, GraphicsOutput.RTMTriggeredCopyTexture) self.tex.setClearColor((0, 0, 0, 1)) self.tex.clearImage() # Create another 2D camera. Tell it to render before the main camera. self.backcam = base.makeCamera2d(base.win, sort=-10) self.background = NodePath("background") self.backcam.reparentTo(self.background) self.background.setDepthTest(0) self.background.setDepthWrite(0) self.backcam.node().getDisplayRegion(0).setClearDepthActive(0) self.bcard = base.win.getTextureCard() self.bcard.reparentTo(base.render2d) self.bcard.setTransparency(1) self.fcard = base.win.getTextureCard() self.fcard.reparentTo(base.render2d) self.fcard.setTransparency(1) # Add the task that initiates the screenshots. taskMgr.add(self.takeSnapShot, "takeSnapShot") if base.win.getGsg().getCopyTextureInverted(): # print("Copy texture is inverted.") self.bcard.setScale(1, 1, -1) self.fcard.setScale(1, 1, -1) self.bcard.hide() self.fcard.hide() self.nextclick = 0 self.clickrate = 10000 def takeSnapShot(self, task): if task.time > self.nextclick: self.nextclick += 1.0 / self.clickrate if self.nextclick < task.time: self.nextclick = task.time base.win.triggerCopy() return task.cont def doubleVision(self): self.visionState = 1 - self.visionState if self.visionState == 1: self.bcard.show() self.bcard.setColor(1, 1, 1, 0.60) self.bcard.setScale(1.0) self.bcard.setPos(-0.05, 0, 0) self.bcard.setR(0) self.fcard.show() self.fcard.setColor(1, 1, 1, 0.60) self.fcard.setScale(1.0) self.fcard.setPos(0.05, 0, 0) self.fcard.setR(0) self.clickrate = 10000 self.nextclick = 0 else: self.bcard.hide() self.fcard.hide() def changeCamera(self): if self.cameraState == 1: self.cameraState = 0 else: self.cameraState = 1 self.setCamera() def setCamera(self): self.cameraoldPos = base.camera.getPos() self.cameraoldNear = base.cam.node().getLens().getNear() if self.cameraState == 0: self.cameranewPos = Vec3(0, -5, 10) pl = base.cam.node().getLens() self.cameranewNear = 1 base.cam.node().setLens(pl) elif self.cameraState == 1: self.cameranewPos = Vec3(0, -1, 8) self.cameranewNear = 1 # self.playerModel.hide() self.playerModel.hide(BitMask32.bit(3)) elif self.cameraState == 2: self.cameranewPos = Vec3(0, -1.5, 8) self.cameranewNear = 1 taskMgr.add(self.updatecamera, "updatecamera") def updatecamera(self, task): if task.time < 0.2: camera.setPos( (self.cameraoldPos * (0.2 - task.time) + self.cameranewPos * (task.time)) / 0.2) return task.cont if self.cameraState == 1: self.playerModel.hide(BitMask32.bit(3)) else: self.playerModel.show(BitMask32.bit(3)) pl = base.cam.node().getLens() pl.setNear(self.cameraoldNear) base.cam.node().setLens(pl) return def erosionUpdate(self, task): if self.EROSION >= 100: self.mission.end("endA") return if self.EROSION >= 80: self.visionState = 0 self.doubleVision() else: self.visionState = 1 self.doubleVision() # self.erosionBar['value'] = self.EROSION self.erosionBar.setScale(1, 1, self.EROSION / 100) self.erosionBar.setPos(0, 0, -1 + self.EROSION / 100) if task.time > self.updateTime: self.EROSION = math.pow(2, (self.EROSION / 20 - 1)) / 6 + self.EROSION # print task.time, 'time' # print self.EROSION self.updateTime += 10 # print self.updateTime return task.cont def erosionUpdateTemp(self): if self.EROSION >= 100: if self.game.levelName == 'levelThree': self.mission.chessBoard.hide() self.mission.end("endA") return if self.EROSION >= 80: self.visionState = 0 self.doubleVision() else: self.visionState = 1 self.doubleVision() # self.erosionBar['value'] = self.EROSION self.erosionBar.setScale(1, 1, self.EROSION / 100) self.erosionBar.setPos(0, 0, -1 + self.EROSION / 100) def mouseUpdate(self, task): """ this task updates the mouse """ if self.state == '': md = base.win.getPointer(0) x = md.getX() y = md.getY() if base.win.movePointer(0, base.win.getXSize() / 2, base.win.getYSize() / 2): self.node.setH(self.node.getH() - (x - base.win.getXSize() / 2) * 0.1) base.camera.setP(base.camera.getP() - (y - base.win.getYSize() / 2) * 0.1) if (base.camera.getP() < -45.): base.camera.setP(-45) if (base.camera.getP() > 45.): base.camera.setP(45) if self.RightButton == 1: self.shoot.MouseDown(self.node) self.EROSION += 5 self.RightButton = 0 # check Interactive Goods nearest = 1000.0 goods = None for i in range(self.nodeGroundHandler.getNumEntries()): entry = self.nodeGroundHandler.getEntry(i) IntoName = entry.getIntoNode().getName() FromName = entry.getFromNode().getName() if FromName == 'playerForwardSegment': if entry.getSurfacePoint(base.camera).getY() < nearest: nearest = entry.getSurfacePoint(base.camera).getY() goods = self.goodmanager.GoodsIta.get(IntoName) if goods and goods.Interactive == True: # print goods.Name self.SetMouseModeNormal('Watch') self.isInteractive = True self.currentInteract = goods else: self.SetMouseModeNormal('Normal') self.isInteractive = False self.currentInteract = None if self.LeftButton == 1 and self.isInteractive: print 'trigger interactive event' print goods.Name self.mission.interactiveWith(goods) return task.cont def moveUpdate(self, task): """ this task makes the player move """ # move where the keys set it # print self.node.getPos() nearestForward = 1000.0 nearestRight = 1000.0 RightEntry = None ForwardEntry = None for i in range(self.nodeGroundHandler.getNumEntries()): entry = self.nodeGroundHandler.getEntry(i) IntoName = entry.getIntoNode().getName() FromName = entry.getFromNode().getName() if FromName == 'PlayerMoveForwardSegment' and ( IntoName != 'PlayerCollideNode'): if entry.getSurfacePoint(self.node).getY() < nearestForward: nearestForward = entry.getSurfacePoint(self.node).getY() ForwardEntry = entry if FromName == 'PlayerMoveRightSegment' and (IntoName != 'PlayerCollideNode'): if abs(entry.getSurfacePoint(self.node).getX()) < nearestRight: nearestRight = abs(entry.getSurfacePoint(self.node).getX()) RightEntry = entry if nearestForward < 2 and nearestForward > -2: self.SLOW = abs(nearestForward) * 0.2 self.node.setPos(self.node.getPos() + ForwardEntry.getSurfaceNormal(render)) else: self.SLOW = 1 if nearestRight < 2: self.node.setPos(self.node.getPos() + RightEntry.getSurfaceNormal(render)) if (nearestForward < 0 and nearestForward > -5.) or nearestRight < 5: if self.cameraState == 0: self.cameraState = 2 self.setCamera() else: if self.cameraState == 2: self.cameraState = 0 self.setCamera() if self.state == '': self.walksound.setLoop(False) #self.walksound.stop() if ((self.walk == self.FORWARD) and (self.playerModel.getAnimControl('walk').isPlaying() == False)): self.walksound.setLoop(True) self.walksound.setVolume(0.5) self.walksound.play() self.playerModel.getAnimControl('walk').play() elif self.walk == self.STOP and self.playerModel.getAnimControl( 'stand').isPlaying() == False: self.playerModel.getAnimControl('stand').play() self.playerModel.getAnimControl('walk').stop() self.walksound.setLoop(False) self.walksound.stop() if self.strafe == LVector3f( -1, 0, 0) or self.strafe == LVector3f(1, 0, 0): self.walksound.setLoop(True) # self.walksound.setVolume(0.5) self.walksound.play() elif self.strafe == LVector3f(0, 0, 0): self.walksound.setLoop(False) self.walksound.stop() #elif self.walk == self.BACK: #self.walksound.setLoop(True) #self.walksound.setVolume(0.5) #self.walksound.play() self.node.setFluidPos( self.node, self.walk * globalClock.getDt() * self.speed * self.SLOW) self.node.setFluidPos( self.node, self.strafe * globalClock.getDt() * self.speed * self.SLOW) return task.cont # 6/17 def jumpUpdate(self, task): """ this task simulates gravity and makes the player jump """ # get the highest Z from the down casting ray highestZ = -100 for i in range(self.nodeGroundHandler.getNumEntries()): entry = self.nodeGroundHandler.getEntry(i) # print entry z = entry.getSurfacePoint(render).getZ() # if z > highestZ and entry.getFromNode().getName() == 'playerRay' and entry.getIntoNode().getName() != "PlayerCollideNode": if z > highestZ and entry.getFromNode().getName( ) == 'playerRay' and entry.getIntoNode().getName() == "floor": highestZ = z # print highestZ # gravity effects and jumps self.node.setZ(self.node.getZ() + self.jump * globalClock.getDt() * 600) self.jump -= 1 * globalClock.getDt() if highestZ > self.node.getZ(): self.jump = 0 self.node.setZ(highestZ) if self.readyToJump: self.jump = 1 return task.cont
class BetterOnscreenImage(DebugObject): """ Simple wrapper arroun OnscreenImage, providing a simpler interface and better visuals """ def __init__(self, image=None, parent=None, x=0, y=0, w=10, h=10, transparent=True, nearFilter=True, anyFilter=True): """ Creates a new image, taking (x,y) as topleft coordinates. When nearFilter is set to true, a near filter will be set to the texture passed. This provides sharper images. When anyFilter is set to false, the passed image won't be modified at all. This enables you to display existing textures, otherwise the texture would get a near filter in the 3D View, too. """ DebugObject.__init__(self, "BetterOnscreenImage") self.w, self.h = w, h self.initialPos = self.translatePos(x, y) self._node = OnscreenImage(image=image, parent=parent, pos=self.initialPos, scale=(w / 2.0, 1, h / 2.0)) if transparent: self._node.setTransparency(TransparencyAttrib.MAlpha) tex = self._node.getTexture() if nearFilter and anyFilter: tex.setMinfilter(Texture.FTNearest) tex.setMagfilter(Texture.FTNearest) if anyFilter: tex.setAnisotropicDegree(8) tex.setWrapU(Texture.WMClamp) tex.setWrapV(Texture.WMClamp) def getInitialPos(self): """ Returns the initial position of the image. This can be used for animations """ return self.initialPos def posInterval(self, *args, **kwargs): """ Returns a pos interval, this is a wrapper around NodePath.posInterval """ return self._node.posInterval(*args, **kwargs) def hprInterval(self, *args, **kwargs): """ Returns a hpr interval, this is a wrapper around NodePath.hprInterval """ return self._node.hprInterval(*args, **kwargs) def setImage(self, img): """ Sets the current image """ self._node.setImage(img) def setPos(self, x, y): """ Sets the position """ self.initialPos = self.translatePos(x, y) self._node.setPos(self.initialPos) def translatePos(self, x, y): """ Converts 2d coordinates to pandas coordinate system """ return Vec3(x + self.w / 2.0, 1, -y - self.h / 2.0) def remove(self): self._node.remove() def hide(self): self._node.hide() def show(self): self._node.show()
class Console: def __init__(self): return None def create(self, CommandDictionary, event: str = "f1"): base.a2dBottomLeft.set_bin('background', 123) # avoid drawing order conflict self.CommandDictionary = { **CommandDictionary, **{ "usage": self.helper, "help": self.showCommands } } # copy for further use in other methods self.hidden = False self.textscale = 0.04 self.Lines = 47 self.font = loader.loadFont( MAINDIR + '/assets/fonts/terminus-ttf-4.47.0/TerminusTTF-4.47.0.ttf') self.background = OnscreenImage(image=str(MAINDIR) + "/assets/images/bg.png", pos=(0.65, 0, 1), parent=base.a2dBottomLeft) self.background.setTransparency(TransparencyAttrib.MAlpha) self.SavedLines = [ OnscreenText(text='', pos=(0.01, 0.1 + x * self.textscale), scale=self.textscale, align=TextNode.ALeft, fg=(1, 1, 1, 1), parent=base.a2dBottomLeft, font=self.font) for x in range(self.Lines) ] self.loadConsoleEntry() self.commands = self.CommandDictionary self.callBackIndex = -1 self.InputLines = [] #self.entry.reparent_to(App) base.accept(event, self.toggle) base.accept('arrow_up', self.callBack, [True]) base.accept('arrow_down', self.callBack, [False]) self.ConsoleOutput('- Panda3d runtime console by Balrog -', color=Vec4(0, 0, 1, 1)) self.ConsoleOutput('successfully loaded all components', color=Vec4(0, 1, 0, 1)) self.toggle() # initialize as hidden return None def loadConsoleEntry(self): #-1.76, 0, -0.97 self.entry = DirectEntry(scale=self.textscale, frameColor=(0, 0, 0, 1), text_fg=(1, 1, 1, 1), pos=(0.015, 0, 0.03), overflow=1, command=self.ConvertToFunction, initialText="", numLines=1, focus=True, width=40, parent=base.a2dBottomLeft, entryFont=self.font) return None def toggle(self): if self.hidden: for i in self.SavedLines: i.show() self.entry.show() self.background.show() else: for i in self.SavedLines: i.hide() self.entry.hide() self.background.hide() self.hidden = not (self.hidden) return None def clearText(self): self.entry.enterText('') return None def ConvertToFunction(self, data): # callback stuff self.callBackIndex = -1 self.InputLines.append(data) # gui self.entry.destroy() self.loadConsoleEntry() self.ConsoleOutput(" ") self.ConsoleOutput(str(MAINDIR) + "> " + data) Buffer = [] ind = data.find('(') if ind <= 0: # no occurence Buffer.append(data) else: Buffer.append(data[0:ind]) # indentify keyword data = data[ind:len(data)] # strip the string as we move along if not (data[0] == '(' and data[len(data) - 1] == ')'): # closing parenthesis syntax stuff self.ConsoleOutput( 'Missing parenthesis ")" in "' + Buffer[0] + data + '"', (1, 0, 0, 1)) return None else: pass data = data[1:len(data) - 1] # cut these useless '()' out left = find_all('(', data) right = find_all(')', data) if len(left) != len(right): # unmatched parethesis error self.ConsoleOutput( 'SyntaxError: unmatched parenthesis found in expression', (1, 0, 0, 1)) return None # we need to split the list according to the parenthesis structure nl = len(left) for i in range(nl): temp = data[left[i]:right[i] + 1].replace(',', '|') temp = ' ' + temp[ 1:len(temp) - 1] + ' ' # the spaces compensate the index gap data = data[:left[i]] + temp + data[right[i] + 1:] Buffer += data.split(',') # identify arguments for i in range(len(Buffer)): Buffer[i] = Buffer[i].strip() if '|' in Buffer[i]: Buffer[i] = Buffer[i].split('|') # internal tuples for j in range(len(Buffer[i])): Buffer[i][j] = Buffer[i][j].strip() # now the string has been converted into a readable list for j in range(1, len(Buffer)): try: if str(int(Buffer[j])) == Buffer[j]: Buffer[j] = int(Buffer[j]) except: pass try: if str(float(Buffer[j])) == Buffer[j]: Buffer[j] = float(Buffer[j]) except ValueError: if str(Buffer[j]) != 'None': Buffer[j] = str(Buffer[j]) else: Buffer[j] = None except TypeError: if type(Buffer[j]) is list: for t in range( len(Buffer[j]) ): # a recursive algorithm might have been a better option try: if str(int(Buffer[j][t])) == Buffer[j][t]: Buffer[j][t] = int(Buffer[j][t]) except ValueError: pass try: if str(float(Buffer[j][t])) == Buffer[j][t]: Buffer[j][t] = float(Buffer[j][t]) except ValueError: if str(Buffer[j][t]) != 'None': Buffer[j][t] = str(Buffer[j][t]) else: Buffer[j][t] = None Buffer[j] = tuple(Buffer[j]) # formating is done, let's head over to the execution try: ChosenCommand = self.commands[Buffer[0]] if len(Buffer) - 1 and Buffer[ 1] != '': # several arguments have been provided try: ChosenCommand(*Buffer[1:]) return None except TypeError: self.ConsoleOutput("Wrong arguments provided", (1, 0, 0, 1)) return None else: try: ChosenCommand() return None except TypeError: self.ConsoleOutput( 'This command requires (at least) one argument', (1, 0, 0, 1)) return None except: self.CommandError(Buffer[0]) return None def SError(self, report): self.ConsoleOutput("Traceback (most recent call last):", (1, 0, 0, 1)) self.ConsoleOutput( "Incorrect use of the '" + str(report) + "' command", (1, 0, 0, 1)) return None def CommandError(self, report): self.ConsoleOutput("Traceback (most recent call last):", (1, 0, 0, 1)) self.ConsoleOutput( "SyntaxError: command '" + str(report) + "' is not defined", (1, 0, 0, 1)) def ConsoleOutput(self, output, color: Vec4 = Vec4(1, 1, 1, 1), mode: str = 'add'): #maxsize = self.entry['width'] maxsize = 81 #maxsize = 66 # hermit font discretized = [ output[i:i + maxsize] for i in range(0, len(output), maxsize) ] if mode == 'add': for i in discretized: # for each line for x in range(self.Lines - 1, 0, -1): self.SavedLines[x].text = self.SavedLines[x - 1].text self.SavedLines[x].fg = self.SavedLines[x - 1].fg self.SavedLines[0].text = i self.SavedLines[0].fg = color elif mode == 'edit': n = len(discretized) for i in range(n): self.SavedLines[i].text = discretized[n - i - 1] self.SavedLines[i].fg = color return None def helper(self, index): ''' Provides help concerning a given command ''' try: i = self.CommandDictionary[index] self.ConsoleOutput("Help concerning command '%s':" % str(index), color=(0.243, 0.941, 1, 1)) self.ConsoleOutput("- associated function name is '%s'" % str(i.__name__)) self.ConsoleOutput("- Documentation provided: ") doc = self.TextToLine(str(i.__doc__)) if not doc == str(None): self.ConsoleOutput(doc.strip()) else: self.ConsoleOutput("No docstring found") self.ConsoleOutput("- Known arguments: ") arg = list(i.__code__.co_varnames) del arg[0] # remove the self argument arg = str(arg) if len(arg) - 2: self.ConsoleOutput(str(arg)[1:len(str(arg)) - 1]) # remove brackets else: self.ConsoleOutput("No arguments required") except KeyError: self.ConsoleOutput("Unknown command '%s'" % str(index), (1, 0, 0, 1)) return None def showCommands(self): ''' Shows a list of available commands ''' self.ConsoleOutput("List of available commands: ", color=(0.243, 0.941, 1, 1)) for i in self.CommandDictionary: self.ConsoleOutput("- " + str(i)) self.ConsoleOutput(" ") self.ConsoleOutput( "Use usage(command) for more details on a specific command") return None def callBack(self, key: bool): invertedInput = self.InputLines[::-1] if key: # up key pressed try: # avoid out of range errors if self.callBackIndex < len(invertedInput): self.callBackIndex += 1 self.entry.enterText(invertedInput[self.callBackIndex]) except: pass else: try: if self.callBackIndex >= 0: self.callBackIndex -= 1 self.entry.enterText( ([''] + invertedInput)[self.callBackIndex]) except: pass def TextToLine(self, text): try: text = text.replace("\n", "") except: pass return text
class ExperimentCredits: def __init__(self): self.music = loader.loadMusic( 'phase_4/audio/bgm/science_fair_credits.ogg') cm = CardMaker('screen-cover') cm.setFrameFullscreenQuad() self.screenCover = render2d.attachNewNode(cm.generate()) self.screenCover.hide() self.screenCover.setScale(100) self.screenCover.setColor((0, 0, 0, 1)) self.logo = OnscreenImage(image='phase_3/maps/toontown-logo.png', scale=(1.0 * (4.0 / 3.0), 1, 1.0 / (4.0 / 3.0)), pos=(-0.05, 1, -0.85)) self.logo.setTransparency(TransparencyAttrib.MAlpha) self.logo.reparentTo(base.a2dTopCenter) self.logo.hide() self.creditsSeq = None def disableToonInterface(self): pass def enableToonInterface(self): pass def start(self): base.musicManager.stopAllSounds() self.disableToonInterface() self.music.play() self.creditsSeq = Sequence( # Fade the screen black Sequence( Func(self.screenCover.show), Func(self.screenCover.setTransparency, 1), LerpColorScaleInterval(self.screenCover, 4, Vec4(1, 1, 1, 1), startColorScale=Vec4(1, 1, 1, 0)), Func(self.screenCover.clearColorScale), Func(self.screenCover.clearTransparency)), # Fade the logo in Sequence( Func(self.logo.show), LerpColorScaleInterval(self.logo, 2, Vec4(1, 1, 1, 1), startColorScale=Vec4(1, 1, 1, 0)), Func(self.logo.clearColorScale)), # Wait 2 seconds Wait(2.0), # Fade the logo out Sequence( LerpColorScaleInterval(self.logo, 5, Vec4(1, 1, 1, 0), startColorScale=Vec4(1, 1, 1, 1)), Func(self.logo.clearColorScale), Func(self.logo.hide)), # Chan's slide chanSlide.construct(), ) self.creditsSeq.start() def stop(self): pass def cleanup(self): pass
class CameraHandler(): def __init__(self, character): self.character = character # Setup mouse base.disableMouse() hideMouse(True) self.mouseSensitivity = 0.1 base.taskMgr.doMethodLater(0.1, self.prepareCameraTask, "prepare-camera") # Setup camera base.camera.reparentTo(self.character.node) base.camera.setPos(0, 0, 0) base.camera.lookAt(0, 1, 0) # Create target self.target = OnscreenImage(image="media/target.png", pos=(0, 0, 0)) self.target.setTransparency(TransparencyAttrib.MAlpha) self.target.setScale(0.1) self.target.setSa(0.5) # Create overlay self.overlayCard = CardMaker("overlayCard") self.overlayCard.setFrameFullscreenQuad() self.overlay = base.render2d.attachNewNode(self.overlayCard.generate()) self.overlay.setTransparency(TransparencyAttrib.MAlpha) self.overlay.setColor(0, 0, 0, 0) # Setup interval sequences self.shakeSequence = None self.flashSequence = None def shake(self, amplitude=(1, 0, 0), duration=1.0, swings=1): if self.shakeSequence != None: self.shakeSequence.finish() self.shakeSequence = Sequence() swings = int(swings) duration = float(duration) dt = duration / (swings * 4) ds = Point3(amplitude) for i in range(swings): self.shakeSequence.append(LerpPosInterval(base.camera, dt, ds * -1)) self.shakeSequence.append(LerpPosInterval(base.camera, dt * 2, ds)) self.shakeSequence.append( LerpPosInterval(base.camera, dt, Point3(0, 0, 0))) self.shakeSequence.start() def flash(self, color=(1, 1, 1, 1), duration=1.0, fadeIn=0.2): if self.flashSequence != None: self.flashSequence.finish() self.flashSequence = Sequence() dtIn = float(duration) * fadeIn dtOut = duration - dtIn if dtIn > 0: self.flashSequence.append( LerpColorInterval(self.overlay, dtIn, color)) if dtOut > 0: self.flashSequence.append( LerpColorInterval(self.overlay, dtOut, (0, 0, 0, 0), color)) self.flashSequence.start() def prepareCameraTask(self, task): base.win.movePointer(0, base.win.getXSize() / 2, base.win.getYSize() / 2) base.taskMgr.add(self.controlCameraTask, "camera-control") return task.done def controlCameraTask(self, task): char = self.character.node # Get current mouse location. md = base.win.getPointer(0) x = md.getX() y = md.getY() # Rotate character based on mouse coordinates. if base.win.movePointer(0, base.win.getXSize() / 2, base.win.getYSize() / 2): char.setP( (char.getP() - (y - base.win.getYSize() / 2) * self.mouseSensitivity) % 360) char.setH( (char.getH() - (x - base.win.getXSize() / 2) * self.mouseSensitivity) % 360) # Don't let the camera loop over. Allowed range is 0-90 (up) and 360-270 (down). if char.getP() > 90 and char.getP() < 180: char.setP(90) elif char.getP() < 270 and char.getP() >= 180: char.setP(270) return task.cont
class ScoreScreen(GameScreen): def __init__(self, screen_manager): ''' Constructor ''' super(ScoreScreen, self).__init__(screen_manager, 'score_screen') self.player_text = OnscreenText( "Player 1", 1, font=base.fontLoader.load('digital.ttf'), fg=(1, 1, 1, 1), pos=(0, .93), align=TextNode.ACenter, scale=.1, mayChange=True, parent=self.node2d) self.score_text = OnscreenText("00", 1, font=base.fontLoader.load('arial.ttf'), fg=((0.0 / 255.0), (255.0 / 255.0), (255.0 / 255.0), 1), pos=(0, .8), align=TextNode.ACenter, scale=.15, mayChange=True, parent=self.node2d) self.ball_text = OnscreenText( "BALL 1", 1, font=base.fontLoader.load('motorwerk.ttf'), fg=(1, 1, 1, 1), pos=(1.15, 0.92), scale=.1, mayChange=True, parent=self.node2d) self.acmag_text = DMDSpriteFont("assets/sprites/num_font_dotmatrix", self.node2d, sX=0.2, sY=0.2, sZ=0.2) self.acmag_text.hide() self.acmag_text.setPos((1.0, 0, 0.7)) self.clock = OnscreenImage(image='assets/images/time.png', pos=(0.78, 0, 0.93), parent=self.node2d, scale=.06) self.bonus2x = OnscreenImage(image='assets/images/2x.png', pos=(-1.25, 0, 0.93), parent=self.node2d, scale=.06) self.bonus3x = OnscreenImage(image='assets/images/3x.png', pos=(-1.25, 0, 0.93), parent=self.node2d, scale=.06) self.bonus4x = OnscreenImage(image='assets/images/4x.png', pos=(-1.25, 0, 0.93), parent=self.node2d, scale=.06) self.bonus5x = OnscreenImage(image='assets/images/5x.png', pos=(-1.25, 0, 0.93), parent=self.node2d, scale=.06) self.cfb = OnscreenImage(image='assets/images/cfb.png', pos=(-1.1, 0, 0.93), parent=self.node2d, scale=.06) self.sj = OnscreenImage(image='assets/images/hud_superjets.png', pos=(-1.0, 0, 0.93), parent=self.node2d, scale=.06) self.sj_text = OnscreenText("25", 1, font=base.fontLoader.load('motorwerk.ttf'), fg=(1, 0, 0, 1), pos=(-0.5, 0.92), scale=.1, mayChange=True, parent=self.node2d) self.timer_text = OnscreenText( "--", 1, font=base.fontLoader.load('motorwerk.ttf'), fg=(1, 0, 0, 1), pos=(0.88, 0.92), scale=.1, mayChange=True, parent=self.node2d) modInfo = self.place_model(model_name="spinner.egg", scale=(0.1, 0.2, 0.2), pos=(-23, 120, -30), rotate=False, p=7, h=15, reference="spinner") self.random_award_text = OnscreenText( "", 1, font=base.fontLoader.load('eurostile.ttf'), fg=(0, 1, 0, 1), pos=(0, 0, 0), scale=.15, mayChange=True, parent=self.node2d) #modInfo['interval'] = modInfo['model'].hprInterval( 0.6, Vec3(15,450,0) ) #modInfo['interval'].loop() modInfo['interval'] = None self.spinner = modInfo self.laser_millions = OnscreenImage( parent=self.node2d, # Parented to our 2d node renderer image="assets/images/laser_millions.png", # File name specified pos=(0, 0, -2), # z: -2 is off screen at the bottom scale=(0.3, 0.3, 0.3) ) # Scale it down a bit horizontally and vertically to make it look right self.ef_bonus = OnscreenImage( parent=self.node2d, # Parented to our 2d node renderer image="assets/images/edgar_friendly.png", # File name specified pos=(0, 0, 0), # z: -2 is off screen at the bottom scale=(0.3, 0.3, 0.3) ) # Scale it down a bit horizontally and vertically to make it look right self.ef_bonus_task = None self.toggle_ef = False self.ef_bonus.hide() self.top_popper_award = OnscreenImage( parent=self.node2d, # Parented to our 2d node renderer image="assets/images/top_award_bg.png", # File name specified pos=(0, 0, 0), # z: -2 is off screen at the bottom scale=(0.75, 0.3, 0.3), sort=-20, ) # Scale it down a bit horizontally and vertically to make it look right self.top_popper_award.hide() self.standup_collected = OnscreenImage( parent=self.node2d, # Parented to our 2d node renderer image="assets/images/standup_spotted.png", # File name specified pos=(0, 0, -2), # z: -2 is off screen at the bottom scale=(0.6, 0.3, 0.4) ) # Scale it down a bit horizontally and vertically to make it look right self.mtlM = Sprite(parent=self.node, file_name="assets/sprites/mtl/m/m", file_type="png", num_frames=33, int_padding=4, scale=(2.5, 2.5, 2.5), pos=(6, 40, 15)) self.mtlT = Sprite(parent=self.node, file_name="assets/sprites/mtl/t/t", file_type="png", num_frames=33, int_padding=4, scale=(2.5, 2.5, 2.5), pos=(9, 40, 15)) self.mtlL = Sprite(parent=self.node, file_name="assets/sprites/mtl/l/l", file_type="png", num_frames=33, int_padding=4, scale=(2.5, 2.5, 2.5), pos=(12, 40, 15)) self.retina = Sprite(parent=self.node, file_name="assets/sprites/retina/retina_scan_", file_type="png", num_frames=36, int_padding=2, scale=(7.5, 7.5, 7.5), pos=(-10, 40, 0), auto_gc=False) self.hide_m() self.hide_t() self.hide_l() self.hide_retina() def set_award_text(self, text): self.random_award_text.setText(text) def show_top_award(self): self.top_popper_award.show() self.random_award_text.show() def hide_top_award(self): self.random_award_text.hide() self.top_popper_award.hide() def spin_spinner(self): blue_side = 3435 red_side = 3255 if random.randint(1, 2) == 1: angle = blue_side else: angle = red_side if self.spinner['interval'] != None: self.spinner['interval'].finish() self.spinner['interval'] = None self.spinner['model'].setP(0) self.spinner['interval'] = self.spinner['model'].hprInterval( 3, Vec3(15, angle, 0), blendType='easeOut') self.spinner['interval'].start() def update_acmag_text(self, text): self.acmag_text.setText(text) self.acmag_text.show() def hide_acmag_text(self): self.acmag_text.hide() def update_timer_text(self, text): self.timer_text.setText(text) def update_score(self, player, score): self.player_text.setText(str(player)) if score == 0: self.score_text.setText("00") else: #self.score_text.setText(str(locale.format("%d", score, grouping=True))) self.score_text.setText(str(base.format_score(score))) def update_ball(self, ball): self.ball_text.setText("BALL " + str(ball)) self.update_hud() def show_score(self): self.player_text.show() self.score_text.show() def hide_score(self): self.player_text.hide() self.score_text.hide() def hide_ball(self): self.ball_text.hide() def show_ball(self): self.ball_text.show() def hide_timer(self): self.timer_text.hide() self.clock.hide() def show_timer(self): self.timer_text.show() self.clock.show() def blink_score(self): i = Sequence( LerpColorScaleInterval(self.score_text, 0.5, VBase4(0, 0, 1, 1)), LerpColorScaleInterval(self.score_text, 0.5, VBase4(1, 1, 1, 1))) i.start() def set_score_color(self, color): self.score_text.setFg(color) def show_laser_millions(self): # Load our trunk bonus image, parent it to our 2d renderer # We must also enable transparency on the image otherwise we get big ugly black squares self.laser_millions.setTransparency(TransparencyAttrib.MAlpha) # Set up a sequence to perform the animation in, pause and out... "sequentially" s = Sequence( # Lerp stands for "linearly interpolate", so we move from one position to the other with # an 'easeOut' blend so it comes to a nice slow stop at the end instead of an abrupt finish LerpPosInterval(self.laser_millions, 0.7, pos=(-1, 0, 0.7), startPos=(-3, 0, 0.7), blendType='easeOut'), # Pause the sequence for 2.5 seconds Wait(2.5), # Animate back to our home position (off screen) with an ease in so it starts moving gradually LerpPosInterval(self.laser_millions, 0.7, pos=(-3, 0, 0.7), blendType='easeIn')) # Fire off the sequence s.start() def show_standup_collected(self): # Load our trunk bonus image, parent it to our 2d renderer # We must also enable transparency on the image otherwise we get big ugly black squares self.standup_collected.setTransparency(TransparencyAttrib.MAlpha) # Set up a sequence to perform the animation in, pause and out... "sequentially" s = Sequence( # Lerp stands for "linearly interpolate", so we move from one position to the other with # an 'easeOut' blend so it comes to a nice slow stop at the end instead of an abrupt finish LerpPosInterval(self.standup_collected, 0.7, pos=(0, 0, 0), startPos=(-3, 0, 0), blendType='easeOut'), # Pause the sequence for 2.5 seconds Wait(2.5), # Animate back to our home position (off screen) with an ease in so it starts moving gradually LerpPosInterval(self.standup_collected, 0.7, pos=(-3, 0, 0), blendType='easeIn')) # Fire off the sequence s.start() def show_ef_bonus(self): if self.ef_bonus_task != None: return self.ef_bonus.show() self.ef_bonus_task = base.taskMgr.doMethodLater( 0.01, self.toggle_ef_bonus, 'ef_bonus') def toggle_ef_bonus(self, task): self.toggle_ef = not self.toggle_ef if self.toggle_ef: self.ef_bonus.hide() else: self.ef_bonus.show() return task.again def hide_ef_bonus(self): if self.ef_bonus_task != None: base.taskMgr.remove(self.ef_bonus_task) self.ef_bonus.hide() self.ef_bonus_task = None def show_m(self): self.mtlM.show() def show_t(self): self.mtlT.show() def show_l(self): self.mtlL.show() def hide_m(self): self.mtlM.hide() def hide_t(self): self.mtlT.hide() def hide_l(self): self.mtlL.hide() def show_retina(self): self.retina.show(1) def hide_retina(self): self.retina.hide() def update_hud(self): self.bonus2x.hide() self.bonus3x.hide() self.bonus4x.hide() self.bonus5x.hide() self.cfb.hide() self.sj.hide() self.sj_text.hide() if base.hwgame.current_player().bonus_x == 2: self.bonus2x.show() if base.hwgame.current_player().bonus_x == 3: self.bonus3x.show() if base.hwgame.current_player().bonus_x == 4: self.bonus4x.show() if base.hwgame.current_player().bonus_x >= 5: self.bonus5x.show() if base.hwgame.current_player().call_for_backup: self.cfb.show() if base.hwgame.current_player().super_jets: self.sj.show() self.sj_text.setText( str(base.hwgame.current_player().super_jets_left))
class MyApp(ShowBase): gameMode = "Intro" def __init__(self): ShowBase.__init__(self) #self.cameraSetup() self.setupKeyboard() self.initIntro() def gameChangeMode(self): if base.gameMode == "Intro": self.initIntro() elif base.gameMode == "Convo": self.initConvo() def initIntro(self): self.fadeAlpha = 0.0 self.fadeTime = 30.0 self.fadeInc = 1.0 / self.fadeTime self.fadeDir = "up" self.sceneImage = OnscreenImage(image="images/scene.png", scale=(1920.0 / 1080.0, 1, 1)) self.sceneImage.setTransparency(TransparencyAttrib.MAlpha) self.sceneImage.setAlphaScale(self.fadeAlpha) self.imageNumber = 0 self.sceneImageList = ["images/scene.png", "images/image1.jpg"] #self.texty = OnscreenText(str(self.fadeAlpha)) taskMgr.add(self.gameIntroUpdate, "GameIntroUpdate") def gameIntroUpdate(self, task): self.slideManager() if (base.gameMode != "Intro"): self.gameChangeMode() return Task.done return Task.cont def cameraSetup(self): base.camLens.setAspectRatio(1920.0 / 1080.0) def slideManager(self): if self.fadeDir == "up" and self.fadeAlpha < 1: self.fadeAlpha += self.fadeInc self.sceneImage.setAlphaScale(self.fadeAlpha) #self.texty.setText(str(self.fadeAlpha)) if self.fadeDir == "down" and self.fadeAlpha > 0: self.fadeAlpha -= self.fadeInc self.sceneImage.setAlphaScale(self.fadeAlpha) if self.fadeDir == "up" and self.fadeAlpha >= 1: self.fadeDir = "down" if self.fadeDir == "down" and self.fadeAlpha <= 0: if self.imageNumber < 1: self.fadeDir = "up" self.sceneImage.setImage(self.nextImage()) self.sceneImage.setTransparency(TransparencyAttrib.MAlpha) self.sceneImage.setAlphaScale(self.fadeAlpha) else: self.fadeDir = "up" base.gameMode = "Convo" self.sceneImage.setImage(self.sceneImageList[self.imageNumber]) self.sceneImage.setTransparency(TransparencyAttrib.MAlpha) self.sceneImage.setAlphaScale(self.fadeAlpha) def nextImage(self): self.imageNumber += 1 return self.sceneImageList[self.imageNumber] def initConvo(self): self.textToType = "This will be used for talking\nThis is a good conversation box" self.textVisible = "" self.strOptionA = "Yes" self.strOptionB = "No" self.strOptionC = "Maybe" self.convoResponseSelected = False self.convoDepth = "1" self.intOptionCount = 3 #self.txtConvo = OnscreenText(self.textVisible, align = TextNode.ALeft) self.txtConvo = TextNode("Texty Bastard") self.txtConvo.setText(self.textToType) self.txtReply = TextNode("reply") self.txtReply.setText("") self.intHover = 0 #self.txtConvo.setFrameColor(0, 0, 1, 1) #self.txtConvo.setFrameAsMargin(0.2, 0.2, 0.1, 0.1) myFrame = DirectFrame(frameColor=(0.8, 0.8, 0.8, 0.4), frameSize=(-1, 0, -1, 0)) nodePathConvo = aspect2d.attachNewNode(self.txtConvo) nodePathConvo.setScale(0.07) nodePathConvo.setPos(-1, 0, -0.1) self.i = 0 self.indent = 0.0 self.selectedResponse = 0 self.txtOptionA = OnscreenText(text="", pos=(-1, -0.6), align=TextNode.ALeft) self.txtOptionB = OnscreenText(text="", pos=(-1, -0.7), align=TextNode.ALeft) self.txtOptionC = OnscreenText(text="", pos=(-1, -0.8), align=TextNode.ALeft) taskMgr.add(self.gameConvoUpdate, "GameConvoUpdate") def gameConvoUpdate(self, task): if (len(self.textVisible) != len(self.textToType)): task.delayTime = 0.001 while (self.i < len(self.textToType)): self.textVisible += self.textToType[self.i] self.txtConvo.setText(self.textVisible) self.i += 1 return Task.again else: taskMgr.add(self.gameConvoOptions, "ConvoOptions") return Task.done def gameConvoOptions(self, task): self.txtOptionA.setText(self.strOptionA) self.txtOptionB.setText(self.strOptionB) self.txtOptionC.setText(self.strOptionC) if self.convoResponseSelected == True: if self.convoCheckBranch("01", self.convoDepth): #self.txtConvo.setText(self.convoGetStrings("01", self.convoDepth)) self.convoNextDialogue("01", self.convoDepth) else: #self.txtConvo.setText("It DIDn't worked") self.convoDepth = "1" self.convoNextDialogue("01", self.convoDepth) return Task.done elif self.selectedResponse == 0: if self.intOptionCount > 0: self.txtOptionA.setX(-1 + self.indent) self.txtOptionA.setFg(fg=(1, 0, 0, 1)) if self.intOptionCount > 1: self.txtOptionB.setX(-1) self.txtOptionB.setFg(fg=(0, 0, 0, 1)) if self.intOptionCount > 2: self.txtOptionC.setX(-1) self.txtOptionC.setFg(fg=(0, 0, 0, 1)) self.indent = self.getIndent(self.indent, 0.01, 0.1) return Task.again elif self.selectedResponse == 1: if self.intOptionCount > 0: self.txtOptionA.setX(-1) self.txtOptionA.setFg(fg=(0, 0, 0, 1)) if self.intOptionCount > 1: self.txtOptionB.setX(-1 + self.indent) self.txtOptionB.setFg(fg=(1, 0, 0, 1)) if self.intOptionCount > 2: self.txtOptionC.setX(-1) self.txtOptionC.setFg(fg=(0, 0, 0, 1)) self.indent = self.getIndent(self.indent, 0.01, 0.1) return Task.again elif self.selectedResponse == 2: if self.intOptionCount > 0: self.txtOptionA.setX(-1) self.txtOptionA.setFg(fg=(0, 0, 0, 1)) if self.intOptionCount > 1: self.txtOptionB.setX(-1) self.txtOptionB.setFg(fg=(0, 0, 0, 1)) if self.intOptionCount > 2: self.txtOptionC.setX(-1 + self.indent) self.txtOptionC.setFg(fg=(1, 0, 0, 1)) self.indent = self.getIndent(self.indent, 0.01, 0.1) return Task.again def convoGetStrings(self, npcId, depth): if self.convoCheckBranch(npcId, depth) != True: return "#Error# String Not Found\nLooking for: " + "(" + str( npcId) + ")." + depth + ":" char = "" line = "" feed = "" path = os.path.abspath(os.getcwd()) f = open(path + "\\text\\stringsConvo.txt", "r") while line != "(" + str(npcId) + ")." + depth + ":": while char != ":": char = f.readline(1) line += char feed += "\n" + line if line != "(" + str(npcId) + ")." + depth + ":": char = "" line = "" f.readline() print(feed + " Selected") f.readline(1) line = f.readline() line = line.replace("##", "\n") f.close() return line def convoCheckBranch(self, npcId, depth): path = os.path.abspath(os.getcwd()) f = open(path + "\\text\\stringsConvo.txt", "r") char = "" line = "" branchFound = False while line != "<END>:": char = "" line = "" while char != ":": char = f.readline(1) line += char if line == "<END>:": f.close() return False elif line == "(" + str(npcId) + ")." + str(depth) + ":": f.close() return True else: f.readline() def convoNextDialogue(self, npcId, depth): self.textToType = self.convoGetStrings(npcId, depth) self.intOptionCount = self.convoGetOptionCount(npcId, depth) if self.intOptionCount == 1: self.strOptionA = self.convoGetStrings(npcId, depth + ".A") self.strOptionB = "" self.strOptionC = "" elif self.intOptionCount == 2: self.strOptionA = self.convoGetStrings(npcId, depth + ".A") self.strOptionB = self.convoGetStrings(npcId, depth + ".B") self.strOptionC = "" elif self.intOptionCount == 3: self.strOptionA = self.convoGetStrings(npcId, depth + ".A") self.strOptionB = self.convoGetStrings(npcId, depth + ".B") self.strOptionC = self.convoGetStrings(npcId, depth + ".C") else: self.strOptionA = "" self.strOptionB = "" self.strOptionC = "" self.textVisible = "" self.txtOptionA.setText("") self.txtOptionB.setText("") self.txtOptionC.setText("") self.txtConvo.setText(self.textVisible) #self.intOptionCount = 2 self.selectedResponse = 0 self.i = 0 self.convoResponseSelected = False taskMgr.add(self.gameConvoUpdate, "GameConvoUpdate") def convoGetOptionCount(self, npcId, depth): if self.convoCheckBranch( npcId, depth + ".A") and self.convoCheckBranch( npcId, depth + ".B") and self.convoCheckBranch( npcId, depth + ".C"): return 3 elif self.convoCheckBranch(npcId, depth + ".A") and self.convoCheckBranch( npcId, depth + ".B"): return 2 elif self.convoCheckBranch(npcId, depth + ".A"): return 1 else: return 0 def getIndent(self, value, increment, limit): if (value + increment >= limit): return limit else: return value + increment def setupKeyboard(self): self.accept("arrow_down", self.convoOptionDown) self.accept("arrow_up", self.convoOptionUp) self.accept("enter", self.convoOptionSelect) def convoOptionUp(self): self.indent = 0.0 if self.selectedResponse == 0: self.selectedResponse = self.intOptionCount - 1 elif self.selectedResponse > 0: self.selectedResponse -= 1 def convoOptionDown(self): self.indent = 0.0 if self.selectedResponse < self.intOptionCount - 1: self.selectedResponse += 1 elif self.selectedResponse == self.intOptionCount - 1: self.selectedResponse = 0 def convoOptionSelect(self): if self.selectedResponse == 0: self.convoDepth += ".A.1" elif self.selectedResponse == 1: self.convoDepth += ".B.1" elif self.selectedResponse == 2: self.convoDepth += ".C.1" self.convoResponseSelected = True
class QuestEmblemGui(DirectFrame): notify = directNotify.newCategory('QuestEmblemGui') def __init__(self, parent): DirectFrame.__init__(self, parent) self.emblem = OnscreenImage(image=loader.loadTexture( 'phase_5/maps/quest_available_emblem.png'), parent=self) self.emblem.setTransparency(TransparencyAttrib.MAlpha) self.emblem.setBillboardAxis() self.emblem.setTwoSided(1) glowMdl = loader.loadModel('phase_4/models/minigames/particleGlow.bam') self.glow = OnscreenImage(parent=self.emblem, image=glowMdl, color=(1.0, 1.0, 0.4, 1.0), scale=(3.0, 3.0, 3.0), pos=(0, 0.05, 0)) self.glow.setBin('gui-popup', 10) glowMdl.removeNode() self.track = None self.state = LOADED def setEmblem(self, questAvailable=QUEST_AVAILABLE): # Sets the texture of the emblem. texture = loader.loadTexture('phase_5/maps/quest_available_emblem.png') if questAvailable is 0: texture = loader.loadTexture( 'phase_5/maps/quest_scroll_emblem.png') self.state = questAvailable self.emblem.setImage(texture) self.emblem.setTransparency(TransparencyAttrib.MAlpha) self.emblem.setBillboardAxis() self.emblem.setTwoSided(1) def start(self, bobMinHeight=0.5, bobMaxHeight=0.5): # Shows the emblem and starts the bobbing animation. # Stops so we don't have two animations running at once. self.stop() # Shows the emblem self.show() # Let's create the animation and run the animation. self.track = Sequence( LerpPosInterval(self.emblem, 1.35, pos=(0, 0, self.getZ() - bobMinHeight), startPos=(0, 0, bobMaxHeight), blendType='easeInOut'), LerpPosInterval(self.emblem, 1.35, pos=(0, 0, bobMaxHeight), startPos=(0, 0, self.getZ() - bobMinHeight), blendType='easeInOut')).loop() def stop(self): # Hides the emblem and stops the animation. self.hide() if self.track: self.track.pause() self.track = None self.state = DISABLED def destroy(self): self.stop() self.glow.destroy() self.emblem.destroy() self.state = None DirectFrame.destroy(self)
class DriverPageGui(ThanksPageGui): def __init__(self, mdt, menu_args, driverpage_props): self.props = driverpage_props ThanksPageGui.__init__(self, mdt, menu_args) def bld_page(self): self.skills = [drv[2] for drv in self.props.drivers] menu_gui = self.mdt.menu.gui menu_args = self.mdt.menu.gui.menu_args widgets = [ OnscreenText(text=_('Select the driver'), pos=(0, .8), **menu_gui.menu_args.text_args) ] self.track_path = self.mdt.menu.track t_a = self.mdt.menu.gui.menu_args.text_args.copy() del t_a['scale'] name = OnscreenText(_('Write your name:'), pos=(-.1, .6), scale=.06, align=TextNode.A_right, **t_a) self.ent = DirectEntry(scale=.08, pos=(0, 1, .6), entryFont=menu_args.font, width=12, frameColor=menu_args.btn_color, initialText=self.props.player_name or _('your name')) self.ent.onscreenText['fg'] = menu_args.text_fg self.drivers = [] for row, col in product(range(2), range(4)): idx = (col + 1) + row * 4 widgets += [ ImgBtn(scale=.24, pos=(-.75 + col * .5, 1, .25 - row * .5), frameColor=(0, 0, 0, 0), image=self.props.drivers_img[0] % idx, command=self.on_click, extraArgs=[idx], **self.mdt.menu.gui.menu_args.imgbtn_args) ] self.drivers += [widgets[-1]] sign = lambda x: '\1green\1+\2' if x > 0 else '' psign = lambda x: '+' if x == 0 else sign(x) def ppcol(x): return '\1green\1%s\2' % x if x > 0 else '\1red\1%s\2' % x pcol = lambda x: x if x == 0 else ppcol(x) def add_lab(txt, pos_z): return OnscreenText(txt + ':', pos=(-.95 + col * .5, pos_z - row * .5), scale=.046, align=TextNode.A_left, **t_a) def add_txt(val, pos_z): return OnscreenText('%s%s%%' % (psign(val), pcol(val)), pos=(-.55 + col * .5, pos_z - row * .5), scale=.052, align=TextNode.A_right, **t_a) lab_lst = [(_('adherence'), .04), (_('speed'), .16), (_('stability'), .1)] widgets += map(lambda lab_def: add_lab(*lab_def), lab_lst) txt_lst = [(self.skills[idx - 1][1], .04), (self.skills[idx - 1][0], .16), (self.skills[idx - 1][2], .1)] widgets += map(lambda txt_def: add_txt(*txt_def), txt_lst) self.img = OnscreenImage(self.props.cars_img % self.mdt.car, parent=base.a2dBottomRight, pos=(-.38, 1, .38), scale=.32) widgets += [self.img, name, self.ent] map(self.add_widget, widgets) fpath = eng.curr_path + 'yyagl/assets/shaders/filter.vert' with open(fpath) as ffilter: vert = ffilter.read() shader = Shader.make(Shader.SL_GLSL, vert, frag) self.img.setShader(shader) self.img.setTransparency(True) self.t_s = TextureStage('ts') self.t_s.setMode(TextureStage.MDecal) empty_img = PNMImage(1, 1) empty_img.add_alpha() empty_img.alpha_fill(0) tex = Texture() tex.load(empty_img) self.img.setTexture(self.t_s, tex) ThanksPageGui.bld_page(self) self.update_tsk = taskMgr.add(self.update_text, 'update text') self.enable_buttons(False) def enable_buttons(self, enable): for drv in self.drivers: drv['state'] = NORMAL if enable else DISABLED drv.setShaderInput('enable', 1 if enable else .2) # do wdg.enable, wdg.disable def update_text(self, task): has_name = self.ent.get() != _('your name') if has_name and self.ent.get().startswith(_('your name')): self.ent.enterText(self.ent.get()[len(_('your name')):]) self.enable_buttons(True) elif self.ent.get() in [_('your name')[:-1], '']: self.ent.enterText('') self.enable_buttons(False) elif self.ent.get() not in [_('your name'), '']: self.enable_buttons(True) return task.cont # don't do a task, attach to modifications events def on_click(self, i): txt_path = self.props.drivers_img[1] self.img.setTexture(self.t_s, loader.loadTexture(txt_path % i)) self.widgets[-1]['state'] = DISABLED self.enable_buttons(False) taskMgr.remove(self.update_tsk) names = Utils().get_thanks(6) cars = self.props.cars[:] cars.remove(self.mdt.car) shuffle(cars) drv_idx = range(1, 9) drv_idx.remove(i) shuffle(drv_idx) drivers = [(i, self.ent.get(), self.skills[i - 1], self.mdt.car)] drivers += [(drv_idx[j], names[j], self.skills[j - 1], cars[j]) for j in range(6)] self.mdt.menu.gui.notify('on_driver_selected', self.ent.get(), drivers, self.mdt.track, self.mdt.car) def destroy(self): self.img = None taskMgr.remove(self.update_tsk) PageGui.destroy(self)
class Unit: def __init__(self, unitID, position, mainClass): # self = copy.copy(mainClass.unitHandler.unitDict[mainClass.unitHandler.main['units'][unitID]]) self.model = mainClass.unitHandler.unitDict[ mainClass.unitHandler.main['units'][unitID]].model self.fullName = copy.copy(mainClass.unitHandler.unitDict[ mainClass.unitHandler.main['units'][unitID]].fullName) self.HP = copy.copy(mainClass.unitHandler.unitDict[ mainClass.unitHandler.main['units'][unitID]].HP) self.info = copy.copy(mainClass.unitHandler.unitDict[ mainClass.unitHandler.main['units'][unitID]].info) self.moveType = copy.copy(mainClass.unitHandler.unitDict[ mainClass.unitHandler.main['units'][unitID]].moveType) self.model = copy.copy(mainClass.unitHandler.unitDict[ mainClass.unitHandler.main['units'][unitID]].model) self.radius = copy.copy(mainClass.unitHandler.unitDict[ mainClass.unitHandler.main['units'][unitID]].radius) self.mass = copy.copy(mainClass.unitHandler.unitDict[ mainClass.unitHandler.main['units'][unitID]].mass) self.startForce = copy.copy(mainClass.unitHandler.unitDict[ mainClass.unitHandler.main['units'][unitID]].startForce) self.maxForce = copy.copy(mainClass.unitHandler.unitDict[ mainClass.unitHandler.main['units'][unitID]].maxForce) self.dig = copy.copy(mainClass.unitHandler.unitDict[ mainClass.unitHandler.main['units'][unitID]].dig) self.reinforce = copy.copy(mainClass.unitHandler.unitDict[ mainClass.unitHandler.main['units'][unitID]].reinforce) self.shovel = copy.copy(mainClass.unitHandler.unitDict[ mainClass.unitHandler.main['units'][unitID]].shovel) self.hold = copy.copy(mainClass.unitHandler.unitDict[ mainClass.unitHandler.main['units'][unitID]].hold) self.modelHeight = copy.copy(mainClass.unitHandler.unitDict[ mainClass.unitHandler.main['units'][unitID]].modelHeight) self.selectScale = copy.copy(mainClass.unitHandler.unitDict[ mainClass.unitHandler.main['units'][unitID]].selectScale) self.job = False self.uID = mainClass.unitHandler.unitUniqueID print self.uID self.modelNode = loader.loadModel(self.model) self.modelNode.setName('unit ' + str(self.uID).zfill(3)) self.modelNode.reparentTo(render) self.modelNode.setPos(position) self.modelNode.setCollideMask(BitMask32.bit(1)) self.select = OnscreenImage(image='data/models/game/selected.png') self.select.setScale(float(self.selectScale)) self.select.reparentTo(self.modelNode) self.select.setZ(float(self.modelHeight) / 2) self.select.setTransparency(TransparencyAttrib.MAlpha) self.select.setBillboardPointEye() self.select.hide() self.groundRay = CollisionRay() self.groundRay.setOrigin(0, 0, 100) self.groundRay.setDirection(0, 0, -1) self.groundCol = CollisionNode('unit Ray') self.groundCol.addSolid(self.groundRay) self.groundCol.setTag('units', 'ray1') self.groundCol.setFromCollideMask(BitMask32.bit(0)) self.groundCol.setIntoCollideMask(BitMask32.allOff()) self.groundColNp = self.modelNode.attachNewNode(self.groundCol) self.groundColNp.setPos(0, 0, 0) self.groundHandler = CollisionHandlerFloor() self.groundHandler.setMaxVelocity(100) base.cTrav2.addCollider(self.groundColNp, self.groundHandler) self.groundHandler.addCollider(self.groundColNp, self.modelNode) self.AI = AICharacter(self.fullName, self.modelNode, self.mass * 2, self.startForce * 2, self.maxForce * 2) mainClass.unitHandler.AIWorld.addAiChar(self.AI) self.AIBehaviors = self.AI.getAiBehaviors() if (self.moveType == 'ground'): self.aStar = astar.aStar(mainClass.unitHandler.meshes.landMesh, mainClass) elif (self.moveType == 'water'): self.aStar = astar.aStar(mainClass.unitHandler.meshes.waterMesh, mainClass) elif (self.moveType == 'air'): self.aStar = astar.aStar(mainClass.unitHandler.meshes.airMesh, mainClass) print self # mainClass.unitHandler.unitUniqueID += 1
class Rodney(Actor): def __init__(self, app, model, rightArm=None, leftArm=None, leftArmBook=None, lives=9): Actor.__init__(self, model) self.app = app self.scene = app.scene self.lives = lives self.last_x = 0 self.last_y = 0 # self.charged = True self.block = False self.setHpr(180, 0, 0) if leftArm: self.leftArm = self.app.loader.loadModel(leftArm) if rightArm: self.rightArm = self.app.loader.loadModel(rightArm) if leftArmBook: self.leftArmBook = self.app.loader.loadModel(leftArmBook) self.set_up_arms() self.init_collision() self.load_HUD() self.init_mouse_control_event() def set_up_arms(self): self.rightArm.reparentTo(self) self.rightArm.setPos(0, -1, 0.8) self.rightArm.setHpr(180, 0, 0) self.leftArm.reparentTo(self) self.leftArm.setPos(-10, 0, 2) self.leftArm.setScale(0.2, 02, 0.2) self.leftArm.setHpr(180, 0, 0) self.leftArmBook.reparentTo(self.leftArm) self.leftArmBook.setPos(-1, 0, -4) def load_HUD(self): self.life_image = OnscreenImage( image= 'Thats_so_Ravens/PureMagicApp/PureMagicAssets/life_images/rodney_lives_' + str(self.lives) + '.png', scale=(0.9, 0, 0.1), pos=(0.1, 0, 1.3)) self.life_image.setTransparency(TransparencyAttrib.MAlpha) self.shield_image = OnscreenImage( image='Thats_so_Ravens/PureMagicApp/PureMagicAssets/Shield_off.png', scale=(0.1), pos=(0.8, 0, 1.0)) self.shield_image.setTransparency(TransparencyAttrib.MAlpha) # self.charge_image = OnscreenImage(image='Thats_so_Ravens/PureMagicApp/PureMagicAssets/charge_on.png', scale=(0.1), # pos=(.8, 0, 1)) # self.charge_image.setTransparency(TransparencyAttrib.MAlpha) def set_life_image(self): self.life_image.setImage( 'Thats_so_Ravens/PureMagicApp/PureMagicAssets/life_images/rodney_lives_' + str(self.lives) + '.png') self.life_image.setTransparency(TransparencyAttrib.MAlpha) def set_shield_image(self, onoff): self.shield_image.setImage( 'Thats_so_Ravens/PureMagicApp/PureMagicAssets/Shield_' + onoff + '.png') self.shield_image.setTransparency(TransparencyAttrib.MAlpha) # def set_charge_image(self, onoff): # self.charge_image.setImage('Thats_so_Ravens/PureMagicApp/PureMagicAssets/charge_' + onoff + '.png') # self.charge_image.setTransparency(TransparencyAttrib.MAlpha) # def set_charge_image(self): def init_collision(self): cs = CollisionSphere(0, 0, 0, 1) cnodePath = self.attachNewNode(CollisionNode('rodneyCnode')) cnodePath.node().addSolid(cs) def shooting_animation(self): shooting_animation = [] ######## TODO Change numbers to actually make a shooting animation shooting_animation.append( self.rightArm.hprInterval(1.0, Vec3(180, 90, 0))) shoot = Sequence(*shooting_animation) shoot.start() def blocking_animation(self): blocking_animation = [] ######## TODO Change numbers to actually make a blocking animation blocking_animation.append( self.leftArm.hprInterval(1.0, Vec3(180, 90, 0))) block = Sequence(*blocking_animation) block.start() # def charge(self): # #self.play(charge_animation) # self.charged = True # self.set_charge_image("on") def shoot(self, target): # if self.charged: # ###Rodney shoot animation # self.app.rodProjectiles.append(Projectile(self.app, "PureMagicApp/Maya_Assets/scenes/projectile.egg", self.getPos(), target, "rodney")) # self.app.rodProjectiles[-1].shoot() # self.charged = False # self.set_charge_image("off") # else: # self.play(uncharged animation) self.app.rodProjectiles.append( Projectile(self.app, "PureMagicApp/Maya_Assets/scenes/projectile.egg", self.getPos(), target, "rodney")) self.app.rodProjectiles[-1].shoot() def die(self): self.app.game_over() #TODO uncoment out rodneyloosingLives def get_hit(self): if not self.block: self.lives -= 1 # self.play(get hit animation) if self.lives == 0: self.die() else: self.set_life_image() def blocks(self): self.set_shield_image("on") self.block = True #self.play(blocking animation) #self.pose(blocking animation) #### last frame for 1 second def unblocks(self): self.set_shield_image("off") self.block = False def init_mouse_control_event(self): props = WindowProperties() #props.setCursorHidden(True) self.app.win.requestProperties(props) def mouse_control_event(self, task): if self.app.mouseWatcherNode.hasMouse(): pres_y = self.app.mouseWatcherNode.getMouseY() pres_x = self.app.mouseWatcherNode.getMouseX() if self.block and pres_x > BLOCK_TRIGGER: self.unblocks() # TODO: add the scaling factor of the screen size so that we make the line at 0.4 * screenLength if self.last_y < self.app.WINDOW_SIZE_Y * SHOOT_TRIGGER and pres_y > self.app.WINDOW_SIZE_Y * SHOOT_TRIGGER: ratio_y = self.map(pres_y) - self.map(self.last_y) ratio_x = self.map(pres_x) - self.map(self.last_x) if ratio_y == 0: ratio_y = 0.0001 degree = math.degrees(math.atan(ratio_x / ratio_y)) self.shoot(self.scale(degree)) #TODO: convert degree(should be between 0-180) to a number within the x constraints of profs motion elif pres_y < BLOCK_TRIGGER: self.blocks() self.last_x = self.app.mouseWatcherNode.getMouseX() self.last_y = self.app.mouseWatcherNode.getMouseY() task.delayTime = 0.15 return task.again def scale(self, degree): #magic numbers are adjustments with 30 = to profs y pos, 0 profs z pos. return (degree // 2 + 12, 30, 0) def map(self, num): new_num = (num + 100) / 2 return new_num
def __init__(self, base, world, track): super().__init__() self.world = world self.track = track self.steering = 0 self.accelerator = 0 self.brake = 0 self.gear_ratios = [-4, 0, 3.9, 2.9, 2.3, 1.87, 1.68, 1.54, 1.46] self.gear = 1 self.differential_ratio = 4.5 self.transmission_efficiency = 0.95 self.wheel_radius = 0.4 self.drag_coefficient = 0.48 self.engine_torque_curve = [ (0, 466), (564, 469), (1612, 469), (2822, 518), (3870, 517), (4516, 597), (5000, 613), (5564, 600), (6048, 655), (6693, 681), (7177, 716), (7822, 696), (8306, 696), (11048, 569), (13951, 391), (15000, 339), (15483, 301), (16612, 247), (17177, 65), (18306, 55) ] self.fw_wingspan = 0.64 self.fw_cord = 1.01 self.fw_clift = 0.7 self.rw_wingspan = 0.64 self.rw_cord = 0.51 self.rw_clift = 0.2 self.car_node = None self.car = None dial_scale = 0.2 speed_dial = OnscreenImage(image='tex/speed360.rgb', pos=(-dial_scale, 0, dial_scale), scale=(dial_scale, 1, dial_scale), parent=base.a2dBottomCenter) speed_dial.setTransparency(TransparencyAttrib.MAlpha) self.speed_dial = OnscreenImage(image='tex/dial.rgb', parent=speed_dial) rpm_dial = OnscreenImage(image='tex/rpm20000.rgb', pos=(dial_scale, 0, dial_scale), scale=(dial_scale, 1, dial_scale), parent=base.a2dBottomCenter) rpm_dial.setTransparency(TransparencyAttrib.MAlpha) self.rpm_dial = OnscreenImage(image='tex/dial.rgb', parent=rpm_dial) self.gear_text = OnscreenText(text='N', pos=(-0.02, -0.67), scale=0.4, parent=rpm_dial, fg=(255, 0, 0, 1)) self.reset() taskMgr.add(self.update, 'update')
class Level: def __init__(self, background): #----------------------------------------------------------------------------------------------------------------------------------------------- #---------------------------------------------------VARIABLE DECLARATION------------------------------------------------------------------------ #----------------------------------------------------------------------------------------------------------------------------------------------- # Background self.back = background self.back[0].setX(34) self.back[1].setX(146) # Arrow self.arrow = OnscreenImage(image="./tex/fletxa.png", pos=(1.1, 0, 0.60), hpr=None, scale=(0.20, 0, 0.20), color=None, parent=None, sort=5) self.arrow.setTransparency(TransparencyAttrib.MAlpha) self.arrow.hide() self.arrowSound = base.loadSfx('./sound/fletxa.wav') self.arrowSound.setVolume(.5) # Items, enemies list self.items = [] self.enemies = [] # Others self.numMoveIt = 0 self.movingBackground = False self.state = 0 self.win = None #----------------------------------------------------------------------------------------------------------------------------------------------- #---------------------------------------------------LEVEL CONFIGURATION------------------------------------------------------------------------- #----------------------------------------------------------------------------------------------------------------------------------------------- # Start tasks taskMgr.add(self.taskLevel, 'taskLevel') #end __init__ #----------------------------------------------------------------------------------------------------------------------------------------------- #----------------------------------------------------------------FUNCTIONS---------------------------------------------------------------------- #----------------------------------------------------------------------------------------------------------------------------------------------- # It moves the background on screen. def moveBackground(self, x, y): if (math.fabs(self.numMoveIt - self.back[0].getX()) >= 30.0): self.movingBackground = False self.arrow.hide() #end moveBackground # It hides the level. def hideLevel(self): self.win.hide() #end hideLevel # It configures the level for a level transition. def moveOn(self): self.numMoveIt = 0 self.movingBackground = True self.interval = self.back[0].posInterval( 5.0, Point3(self.back[0].getX() - 30, self.back[0].getY(), self.back[0].getZ())) self.interval.start() self.interval2 = self.back[1].posInterval( 5.0, Point3(self.back[1].getX() - 30, self.back[1].getY(), self.back[1].getZ())) self.interval2.start() self.numMoveIt = self.back[0].getX() self.arrow.show() self.arrowSound.play() #end moveOn # It removes all items from screen. def removeItems(self): while self.items != []: for x in self.items: x.model.setX(-100) self.items.remove(x) #end removeItems # It removes all the items and enemies from screen. def removeAll(self): while self.items != []: for x in self.items: x.model.setX(-100) self.items.remove(x) while self.enemies != []: for x in self.enemies: x.model.setX(-100) x.life = x.life - 1 self.enemies.remove(x) #end removeAll #----------------------------------------------------------------------------------------------------------------------------------------------- #----------------------------------------------------------------TASKS,THREADS------------------------------------------------------------------ #----------------------------------------------------------------------------------------------------------------------------------------------- # It manages the level on every scene. def taskLevel(self, task): return task.cont #end taskLevel #end class Level
from panda3d.core import TransparencyAttrib import direct.directbase.DirectStart from direct.gui.OnscreenImage import OnscreenImage from panda3d.core import TextNode textObject = OnscreenImage(image='data/black.png', pos=(0, 0, -1.5), color=(0, 0, 0, .4), parent=base.render2d) textObject.setTransparency(TransparencyAttrib.MAlpha) # Run the tutorial base.run()
class Minimap: def __init__(self, path='/models', scale = 0.0, posX = -0.9, posZ = -0.65, mapimageName = None): taskMgr.add(self.step,"MinimapTask") self.path = path self.posX = posX self.posZ = posZ b = 500 pos = Vec3(self.posX,0,self.posZ)#Aspect2D coordinates for the location of the center of the minimap. if mapimageName is None: mapimageName = '%s/battlemap.png' % self.path#mapimage is the image to place in the minimap self.scale = scale #this value is the number of pixels wide the map will be. ratio = b/self.scale self.dotScale = (ratio) * b self.dotSize = 0.005 / ratio self.map = aspect2d.attachNewNode('Map') mapimage = self.getMapImage(mapimageName) props = base.win.getProperties( ) self.Height = float(props.getYSize()) self.Hscale = (1/self.Height) self.map.setScale(self.Hscale) #Sets scale to the screen resolution. self.map.setPos(pos) #this is the location on aspect2d for the minimap. self.dots = [] self.dots.append([]) self.targets = [] self.targets.append([]) self.teamImage = [] #a list of paths to the image that each team will use. self.setNumTeams(9) self.mapimage = OnscreenImage(image = mapimage, scale = self.scale, parent = self.map) self.mousePosition = OnscreenImage(image = self.path + 'select3.png', scale = self.dotSize*10, pos = (0,0,0), parent = aspect2d) self.totaltargets = 0 def destroy(self): """Remove Minimap from game""" for team in range(len(self.dots)): #will cycle through each team for i in range(len(self.dots[team])): #will cycle through each member of the team dot = self.dots[team][i] dot.removeNode() self.mousePosition.removeNode() self.mapimage.removeNode() self.map.removeNode() def getMapImage(self, mapimageName): texImage=PNMImage() texImage.read(Filename(mapimageName)) tex=Texture() tex.load(texImage) return tex def setTargets(self, targets, team): for i in range(len(targets)): self.targets[team].append(targets[i]) for i in range(len(self.targets[team])): self.dots[team].append(OnscreenImage(image = self.teamImage[team], scale = self.dotSize, pos = (0,0,0), parent = aspect2d)) def setBezel(self, image = None, scale = None): if image is None: image = '%s/bezel.png' % self.path if scale is None: scale = 1 self.bezel = OnscreenImage(image = image, scale = self.scale * scale, parent = self.map) self.bezel.setTransparency(TransparencyAttrib.MAlpha) def setScale(self, scale): self.scale = scale def setPos(self,num): #must be a Vec3 self.pos = num def appendTarget(self, target = None, team = None): #target must be a nodepath, team must be an integer if target is not None: self.targets[team].append(target) x = len(self.targets[team]) self.dots[team].append(OnscreenImage(image = self.teamImage[team], scale = self.dotSize, pos = (0,0,0), parent = aspect2d)) def setNumTeams(self, num): #Num must be an integer. Sets the number of different groups for the map to track. Each group may be tracked using a different graphic newTargets = [] for x in range(num): newTargets.append([]) self.dots.append([]) self.teamImage.append('%s/dot%d.png' % (self.path, x)) self.targets = newTargets def removeTarget(self, target = None, team = None): for i in range(len(self.targets[team])): if self.targets[team][i] == target: #This means the object in question is the object to be removed self.dots[team][i].stash() def step(self, task): try: for team in range(len(self.targets)): #will cycle through each team for i in range(len(self.targets[team])): #will cycle through each member of the team target = self.targets[team][i] if target.isEmpty() == False: x = (target.getX()/self.dotScale) + self.posX z = (target.getZ()/self.dotScale) + self.posZ self.dots[team][i].setX(x) self.dots[team][i].setZ(z) self.mousePosition.setX((camera.getX()/self.dotScale + self.posX)) self.mousePosition.setZ((camera.getZ()/self.dotScale + self.posZ)) return Task.cont except: pass
class world(ShowBase): def __init__(self): try: ShowBase.__init__(self) except: sys.exit("[WARNING]: unknown error: Showbase initialisation failed") # ------------------------------- Begin of parameter variables (pretty messy actually) ------------------------------------ #debug ------ self.debug=False #[ /!\ IMPORTANT /!\ ] do not leave this value to True when you commit the code to github, as it is impossible to change once ingame, and modifies quite a lot of graphical parameters #debug ------ self.stored_collisions=[] # this counts the amount of collisions and allows us to detect the income of a new collision in order to create a new particle effect when it appears self.timescale=5 # this can be changed at any moment, it represents the speed of the ingame time self.worldscale=0.1 # currently useless self.camera_delta=0.5 # camera delta displacement self.sensitivity_x,self.sensitivity_y=20,20 self.watched=None # watched object (object focused by the cursor) self.state=['paused','free',None] # state of things: [simulation paused/running,camera following object/free,followed object/None] print('free mode on') self.iteration=0 #iteration for the menu to be drawn once self.collision_status=False # Keep this on False, that's definitely not a setting # currently useless self.u_constant=6.67408*10**(-11) #just a quick reminder self.u_radius=5 #just what I said earlier # ------------------------------- End of parameter variables (sry for the mess) -------------------------------------------- self.Game_state=state() self.Game_state.cleanup() # better safe than sorry self.taskMgr.add(self.wait,'wait_task') self.setBackgroundColor(0,0,0) def wait(self,task): if not(task.time): self.screen_fill=OnscreenImage(image=str(MAINDIR)+"/Engine/main_page.png",pos = (0, 0, 0),scale=(1.77777778,1,1)) elif task.time>4: self.taskMgr.remove('wait_task') self.screen_fill.destroy() self.menu() return None return task.cont def menu(self): # loading time # music self.menu_music=self.loader.loadSfx(str(MAINDIR)+'/Sound/deadmau5-cabin.mp3') self.menu_music.setLoop(True) self.menu_music.play() # filters try: self.filters = CommonFilters(self.win, self.cam) except: pass self.Game_state.root_node.setAntialias(AntialiasAttrib.MAuto) def quit(): sys.exit(0) button_block_pos=(-1.2,0.35,0.25) maps_start=loader.loadModel(str(MAINDIR)+'/Engine/start.egg') maps_quit=loader.loadModel(str(MAINDIR)+'/Engine/quit.egg') maps_set=loader.loadModel(str(MAINDIR)+'/Engine/set.egg') self.start_button=DirectButton(pos=button_block_pos,frameColor=(0,0,0,0),scale=(0.717,0.4,0.221),geom=(maps_start.find('**/Start'),maps_start.find('**/Start_push'),maps_start.find('**/Start_on'),maps_start.find('**/Start')),command=self.loadgame) self.quit_button=DirectButton(pos=(button_block_pos[0]+0.135,button_block_pos[1],button_block_pos[2]-0.4),frameColor=(0,0,0,0),scale=(1,0.4,0.221),geom=(maps_quit.find('**/Quit'),maps_quit.find('**/Quit_push'),maps_quit.find('**/Quit_on'),maps_quit.find('**/Quit')),command=quit) self.settings_button=DirectButton(pos=(button_block_pos[0]-0.075,button_block_pos[1],button_block_pos[2]-0.2),frameColor=(0,0,0,0),scale=(0.56,0.4,0.221),geom=(maps_set.find('**/Set'),maps_set.find('**/Set_push'),maps_set.find('**/Set_on'),maps_set.find('**/Set')),command=self.not_implemented_yet) # settings not implemented yet self.title_pic=OnscreenImage(image=str(MAINDIR)+'/Engine/title.png',pos=(0,0.35,0), scale=(0.51,1,0.5)) self.title_pic.setTransparency(TransparencyAttrib.MAlpha) pannel_pos_x=1.25 self.activity_log=OnscreenImage(image=str(MAINDIR)+'/Engine/activity_log.png',pos=(pannel_pos_x,0.35,0.30),scale=(0.375,0.75,0.086775)) self.activity_log.setTransparency(TransparencyAttrib.MAlpha) #self.activity_log_bg=OnscreenImage(image=str(MAINDIR)+'/Engine/activity_log_bg.png',pos=(pannel_pos_x,-0.35,-0.3),scale=(0.5,0.4,0.675)) #self.activity_log_bg.setTransparency(TransparencyAttrib.MAlpha) #spaces compensate the center text effect self.logs=OnscreenText(text=' PyOS v0.11 \n\n Added main menu in last update\n Particle support has now become reality\n but still needs some improvement\n\n\n Feature in progress:\n collision animation\n\n\nRelease date >>',pos=(pannel_pos_x-0.3,0.11,0.2), scale=(0.05,0.05,0.05),fg=(1,1,1,1)) self.shrug=OnscreenImage(image=str(MAINDIR)+'/Engine/shrug.png',pos=(pannel_pos_x-0.35,0.35,-0.48),scale=(0.1,1,0.0317)) self.shrug.setTransparency(TransparencyAttrib.MAlpha) self.backgrnd=OnscreenImage(image=str(MAINDIR)+'/Engine/Stars.png',scale=(85.44,1,48),pos=(0,60,0)) self.backgrnd.reparentTo(self.Game_state.root_node) #self.filters.set_gamma_adjust(0.9) self.moon=self.loader.loadModel(str(MAINDIR)+"/Engine/Icy.egg") self.moon.setScale(0.2,0.2,0.2) self.moon.setPos(0,50,0) # radius of orbit equals 50 units self.moon.reparentTo(self.Game_state.root_node) self.intro_planet=self.loader.loadModel(str(MAINDIR)+"/Engine/tessena.egg") self.intro_planet_atm=self.loader.loadModel(str(MAINDIR)+"/Engine/tessena_atm.egg") self.intro_planet.setPos(0,-35,0) self.intro_planet_atm.setPos(0,-35,0) self.intro_planet.reparentTo(self.Game_state.root_node) self.intro_planet_atm.reparentTo(self.Game_state.root_node) self.intro_planet.setHpr(-110,0,0) self.intro_planet_atm.setHpr(-110,0,0) self.cam.setPos(0,-70,0) self.disable_mouse() # lighting d=DirectionalLight('menu_dlight') d.setColor(VBase4(0.631,0.369,1,1)) dlight=self.Game_state.root_node.attachNewNode(d) dlight.setHpr(60,-30,0) e=DirectionalLight('menu_dlight2') e.setColor(VBase4(1,1,1,1)) elight=self.Game_state.root_node.attachNewNode(e) elight.setHpr(60,-30,0) self.moon.setLight(elight) self.intro_planet.setLight(dlight) self.intro_planet_atm.setLight(dlight) self.task_mgr.add(self.rotate,'rotationtask') # penser a l'enlever def rotate(self,task): self.intro_planet.setHpr(self.intro_planet,(0.1,0,0)) self.intro_planet_atm.setHpr(self.intro_planet_atm,(0.07,0,0)) self.moon.setHpr(self.moon,(0.2,0,0)) self.moon.setPos(50*sin(task.time*0.02),50*cos(task.time*0.02),0) return task.cont # end of menu subfunctions def loadgame(self): # transition phase self.menu_music.setLoop(False) self.menu_music.stop() self.taskMgr.remove('rotationtask') self.cam.setPos(0,0,0) self.Game_state.cleanup() self.activity_log.hide() #self.activity_log_bg.hide() self.logs.hide() self.shrug.hide() self.start_button.hide() self.quit_button.hide() self.settings_button.hide() self.title_pic.hide() # end of transition phase # Mouse parameters self.hidden_mouse=True wp = WindowProperties() wp.setCursorHidden(self.hidden_mouse) self.win.requestProperties(wp) # preparing the menu text list: quit_to_desk=self.loader.loadModel(str(MAINDIR)+"/Engine/quit_to_desktop.egg") quit_to_menu=self.loader.loadModel(str(MAINDIR)+"/Engine/quit_to_menu.egg") resume=self.loader.loadModel(str(MAINDIR)+"/Engine/resume.egg") self.paused_menu_text=[] global_tempPosx=-1 self.paused_menu_text.append(DirectButton(pos=(global_tempPosx-0.065,0,-0.2),frameColor=(0,0,0,0),scale=(1,0.4,0.211),geom=(quit_to_desk.find('**/quit_to_desktop'),quit_to_desk.find('**/quit_to_desktop_push'),quit_to_desk.find('**/quit_to_desktop_on'),quit_to_desk.find('**/quit_to_desktop')),command=self.system_break)) self.paused_menu_text.append(DirectButton(pos=(global_tempPosx,0,0),frameColor=(0,0,0,0),scale=(1.12,0.4,0.211),geom=(quit_to_menu.find('**/quit_to_menu'),quit_to_menu.find('**/quit_to_menu_push'),quit_to_menu.find('**/quit_to_menu_on'),quit_to_menu.find('**/quit_to_menu')),command=self.ingame_back_to_menu)) self.paused_menu_text.append(DirectButton(pos=(global_tempPosx-0.325,0,0.2),frameColor=(0,0,0,0),scale=(0.47,0.4,0.211),geom=(resume.find('**/resume'),resume.find('**/resume_push'),resume.find('**/resume_on'),resume.find('**/resume')),command=self.toggle_pause)) # btw I found something about energy transmission through thermal radiation. I think it uses some Boltzmann formula stuff. Link here: # https://fr.wikibooks.org/wiki/Plan%C3%A9tologie/La_temp%C3%A9rature_de_surface_des_plan%C3%A8tes#Puissance_re%C3%A7ue_par_la_Terre # Defining important data lists # music imports (paths) self.sounds=[str(MAINDIR)+"/Sound/001.mp3", str(MAINDIR)+"/Sound/Blazing-Stars.mp3", str(MAINDIR)+"/Sound/Cold-Moon.mp3", str(MAINDIR)+"/Sound/Light-Years_v001.mp3", str(MAINDIR)+"/Sound/The-Darkness-Below.mp3", str(MAINDIR)+"/Sound/Retro-Sci-Fi-Planet.mp3", str(MAINDIR)+"/Sound/droid-bishop-nightland.mp3", str(MAINDIR)+"/Sound/interstellar-ost-03-dust-by-hans-zimmer.mp3", str(MAINDIR)+"/Sound/interstellar-ost-04-day-one-by-hans-zimmer.mp3", str(MAINDIR)+"/Sound/ascendant-remains-2015.mp3", str(MAINDIR)+"/Sound/droid-bishop-nightland.mp3", str(MAINDIR)+"/Sound/john-carpenter-utopian-facade-official-music-video.mp3", str(MAINDIR)+"/Sound/stranger-things-2-eulogy.mp3", str(MAINDIR)+"/Sound/interstellar-ost-07-the-wormhole-by-hans-zimmer.mp3"] self.collision_solids=[] #collision related stuff - comments are useless - just RTFM self.light_Mngr=[] self.data=[ [0,0,0,-0.00,0.003,0,0.30,0.30,0.30,100000.00,True,[self.loader.loadModel(str(MAINDIR)+"/Engine/lp_planet_0.egg"),(0.1,0,0),self.loader.loadModel(str(MAINDIR)+"/Engine/lp_planet_1.egg"),(0.14,0,0)],"low_poly_planet01",False,0.1] ,[10,0,0,0,0.003,0,0.05,0.05,0.05,20.00,True,[self.loader.loadModel(str(MAINDIR)+"/Engine/Icy.egg"),(0.05,0,0)],"Ottilia_modified",False,0.1] ,[0,70,10,0,0.005,0,0.1,0.1,0.1,40.00,True,[self.loader.loadModel(str(MAINDIR)+"/Engine/asteroid_1.egg"),(0,0,0.2)],"Selena",False,1] ,[100,0,10,0,0,0,5,5,5,1000000,True,[self.loader.loadModel(str(MAINDIR)+"/Engine/sun1.egg"),(0.01,0,0),self.loader.loadModel(str(MAINDIR)+"/Engine/sun1_atm.egg"),(0.01,0,0)],"Sun",True,0.1] ,[-100,50,70,0,0,0.003,0.15,0.15,0.15,1000.00,True,[self.loader.loadModel(str(MAINDIR)+"/Engine/Earth2.egg"),(-0.1,0,0),self.loader.loadModel(str(MAINDIR)+"/Engine/Earth2_atm.egg"),(-0.15,0,0)],"big_fucking_planet",False,0.1] ,[200,0,0,-0.001,0,0.01,0.1,0.1,0.1,100000,False,[self.loader.loadModel(MAINDIR+"/Engine/realistic_asteroid.egg"),(0,0.01,0)],"spaceship",False,0] ,[0,-120,0,0.004,0,0,0.3,0.3,0.3,100000,True,[self.loader.loadModel(str(MAINDIR)+"/Engine/FG1.egg"),(0.01,0,0),self.loader.loadModel(str(MAINDIR)+"/Engine/FG2.egg"),(0.01,0,0),self.loader.loadModel(str(MAINDIR)+"/Engine/FG3.egg"),(0.01,0,0),self.loader.loadModel(str(MAINDIR)+"/Engine/FG4.egg"),(0.01,0,0),self.loader.loadModel(str(MAINDIR)+"/Engine/FG5.egg"),(0.01,0,0)],"Frozen_giant",False,0.1] # insert your 3d models here, following the syntax (this is the default scene that will be loaded on startup) ] # the correct reading syntax is [x,y,z,l,m,n,scale1,scale2,scale3,mass,static,[file,(H,p,r),file,(H,p,r)...],id,lightsource,brakeforce] for each body - x,y,z: position - l,m,n: speed - scale1,scale2,scale3: obvious (x,y,z) - mass: kg - static: boolean - [files]: panda3d readfiles list (first file must be the ground, the others are atmosphere models) #id: str - lightsource: boolean - #if you want the hitbox to be correctly scaled,and your body to have reasonable proportions, your 3d model must be a 5*5 sphere, or at least have these proportions # create the real data list, the one used by the program self.bodies=[] for c in self.data: temp=body() temp.fill_entries(c) self.bodies.append(temp) temp=None #self.bodies.reverse() # Quick presetting self.setBackgroundColor(0,0,0,True) # enable particles self.enableParticles() self.toggle_particles() # debug # create particle class object self.particle=particle() # intialize object: self.particle.config_path='/Engine/destruction_sphere.ptf' # the MAINDIR is already included inside the class definition # non-body type structures loading if SKYBOX=='sky': self.isphere=self.loader.loadModel(str(MAINDIR)+"/Engine/InvertedSphere.egg") #loading skybox structure self.tex=loader.loadCubeMap(str(MAINDIR)+'/Engine/Skybox4/skybox_#.png') elif SKYBOX=='arena': self.box=self.loader.loadModel(str(MAINDIR)+"/Engine/arena.egg") #load shaders (optionnal) ''' sun_shader=Shader.load(Shader.SLGLSL,MAINDIR+'/Engine/Shaders/flare_v.glsl',MAINDIR+'/Engine/Shaders/flare_f.glsl') ''' self.camLens.setNearFar(0.5, 100000) self.orbit_lines=[] #under developement # see https://www.panda3d.org/manual/?title=Collision_Solids for further collision interaction informations base.graphicsEngine.openWindows() try: print('\n[Loader manager]:\n') ''' self.filters.setBlurSharpen(amount=0) # just messing around ''' if not self.debug: self.filters.set_gamma_adjust(1.0) # can be usefull self.filters.set_bloom(intensity=1,size="medium") for c in self.bodies: # loading and displaying the preloaded planets and bodies if c.is_lightSource and not self.debug: # VM filtering self.filters.setVolumetricLighting(c.filelist[0],numsamples=50,density=0.5,decay=0.95,exposure=0.035) #c.filelist[u].set_shader(sun_shader) if BLUR: self.filters.setCartoonInk() for u in range(0,len(c.filelist),2): # loading each sub-file c.filelist[u].reparentTo(self.Game_state.root_node) c.filelist[u].setScale(tuple(c.scale)) c.filelist[u].setPos(tuple(c.position)) if u==0 and not(c.is_lightSource): c.filelist[u].setShaderAuto() #activate auto shading for compact, non translucent bodies #setting the collision solid up temp=hitbox() temp.Volume=CollisionSphere(0,0,0,self.u_radius) temp.NodePath=c.filelist[0].attachNewNode(CollisionNode(c.id)) temp.CollisionNode=temp.NodePath.node() self.collision_solids.append(temp) #the radius is calculated by using the average scale + the self.u_radius # the structure of the collision_solids list will be: [temp1,temp2,...] # asteroids and irregular shapes must be slightly bigger than their hitbox in order to avoid visual glitches self.collision_solids[len(self.collision_solids)-1].CollisionNode.addSolid(self.collision_solids[len(self.collision_solids)-1].Volume) #I am definitely not explaining that temp=None if self.debug: loadPrcFileData("", "show-frame-rate-meter 1") self.collision_solids[len(self.collision_solids)-1].NodePath.show() # debugging purposes only print("collision: ok") print("placing body: done") if c.is_lightSource: self.light_Mngr.append([PointLight(c.id+"_other")]) self.light_Mngr[len(self.light_Mngr)-1].append(self.Game_state.root_node.attachNewNode(self.light_Mngr[len(self.light_Mngr)-1][0])) self.light_Mngr[len(self.light_Mngr)-1][1].setPos(tuple(c.position)) # shadow stuff self.light_Mngr[len(self.light_Mngr)-1][1].node().setShadowCaster(True) ''' self.light_Mngr[len(self.light_Mngr)-1][1].node().getLens().setFov(40) self.light_Mngr[len(self.light_Mngr)-1][1].node().getLens().setNearFar(10, 100) ''' self.Game_state.root_node.setLight(self.light_Mngr[len(self.light_Mngr)-1][1]) self.light_Mngr.append([AmbientLight(c.id+"_self")]) self.light_Mngr[len(self.light_Mngr)-1][0].setColorTemperature(3000) self.light_Mngr[len(self.light_Mngr)-1].append(self.Game_state.root_node.attachNewNode(self.light_Mngr[len(self.light_Mngr)-1][0])) for u in range(0,len(c.filelist),2): c.filelist[u].setLight(self.light_Mngr[len(self.light_Mngr)-1][1]) print("lights: done") else: self.light_Mngr.append([]) #create an empty list, so that the coordinates of the data in the list is the same as in self.bodies (easier for further analysis and potential deletion) self.light_Mngr.append([]) print("loaded new body, out: done") if SKYBOX=='sky': self.isphere.setTexGen(TextureStage.getDefault(), TexGenAttrib.MWorldCubeMap) # *takes a deep breath* cubemap stuff ! self.isphere.setTexProjector(TextureStage.getDefault(), self.Game_state.root_node, self.isphere) self.isphere.setTexPos(TextureStage.getDefault(), 0, 0, 0) self.isphere.setTexScale(TextureStage.getDefault(), .5) # that's a thing... self.isphere.setTexture(self.tex)# Create some 3D texture coordinates on the sphere. For more info on this, check the Panda3D manual. self.isphere.setLightOff() self.isphere.setScale(10000) #hope this is enough self.isphere.reparentTo(self.Game_state.root_node) elif SKYBOX=='arena': self.box.setPos(0,0,0) self.box.setScale(100) self.box.reparentTo(self.Game_state.root_node) # collision traverser and other collision stuff # that's super important, and super tricky to explain so just check the wiki self.ctrav = CollisionTraverser() self.queue = CollisionHandlerQueue() for n in self.collision_solids: self.ctrav.add_collider(n.NodePath,self.queue) # the traverser will be automatically updated, no need to repeat this every frame # debugging only if self.debug: self.ctrav.showCollisions(self.Game_state.root_node) # play a random music self.current_playing=random.randint(0,len(self.sounds)-1) self.current_song=self.loader.loadSfx(self.sounds[self.current_playing]) self.current_song.play() # task manager stuff comes here self.intro_loop() except: sys.exit(":( something went wrong: files could not be loaded") # key bindings self.accept('escape',self.toggle_pause) self.accept('mouse1',self.handle_select,[True]) self.accept('wheel_up',self.handle_scrolling,[True]) # center button (just a quick test) self.accept('wheel_down',self.handle_scrolling,[False]) self.accept('z',self.move_camera,[0,True]) self.accept('q',self.move_camera,[1,True]) self.accept('s',self.move_camera,[2,True]) self.accept('d',self.move_camera,[3,True]) self.accept('a',self.move_camera,[4,True]) self.accept('e',self.move_camera,[5,True]) self.accept('arrow_right',self.time_change,[True]) self.accept('arrow_left',self.time_change,[False]) self.accept('z-up',self.move_camera,[0,False]) self.accept('q-up',self.move_camera,[1,False]) self.accept('s-up',self.move_camera,[2,False]) self.accept('d-up',self.move_camera,[3,False]) self.accept('a-up',self.move_camera,[4,False]) self.accept('e-up',self.move_camera,[5,False]) self.keymap=['z',0,'q',0,'s',0,'d',0,'a',0,'e',0,'mouse1',0] if self.debug: # draw axis coord=[(1,0,0),(0,1,0),(0,0,1)] axis=[] for c in range(3): axis.append(LineSegs()) axis[c].moveTo(0,0,0) axis[c].drawTo(coord[c]) axis[c].setThickness(3) axis[c].setColor(tuple([coord[c][u]*255 for u in range(len(coord[c]))] +[True])) NodePath(axis[c].create()).reparent_to(self.Game_state.root_node) # camera positionning ------- self.focus_point=[0,0,0] # point focused: can become a body's coordinates if the user tells the program to do so self.zoom_distance=30 # distance to the focus point in common 3D units (can be modified by scrolling) self.cam_Hpr=[0,0,0] # phi, alpha, theta - aka yaw, pitch, roll self.cam_Hpr=[self.cam_Hpr[n]*pi/180 for n in range(len(self.cam_Hpr))] # convert to rad phi,alpha,theta,zoom,object=self.cam_Hpr[0]*pi/180,self.cam_Hpr[1]*pi/180,self.cam_Hpr[2]*pi/180,self.zoom_distance,self.state[2] # temporary vars if self.state[1]=='free': self.camera_pos=[0,0,0] self.camera.setPos(tuple(self.camera_pos)) elif self.state[1]=='linked': # find the object (self.state[2]) in the data list list_pos=[self.bodies[n].filelist[0] for n in range(len(self.bodies))].index(object.getParent()) self.focus_point=self.bodies[list_pos].position # take the focused object's coordinates self.camera_pos=[self.focus_point[0]+sin(phi)*cos(-alpha)*zoom,self.focus_point[1]-cos(phi)*cos(-alpha)*zoom,self.focus_point[2]+sin(-alpha)*zoom] #keep it up to date so that it's not hard to find whend switching modes self.camera.setPos(tuple(self.camera_pos)) self.camera.setHpr(self.cam_Hpr) # cursor self.cursor=self.showsimpletext('.',(0,0),(0.08,0.08),None,(1,1,1,True)) # yeah, you can laugh, but this still works so I don't care self.pointerNode=CollisionNode('cursor') self.pointerNP=camera.attachNewNode(self.pointerNode) self.pointerNode.setFromCollideMask(BitMask32.bit(1)) # separate collisions (in order to avoid mistakes during physical calculations) self.cursor_ray=CollisionRay() # create the mouse control ray self.pointerNode.addSolid(self.cursor_ray) self.ctrav.add_collider(self.pointerNP,self.queue) #self.screen_fill.destroy() # delete the displayed picture return None def showsimpletext(self,content,pos,scale,bg,fg): #shows a predefined, basic text on the screen (variable output only) return OnscreenText(text=content,pos=pos,scale=scale,bg=bg,fg=fg) def intro_loop(self): self.taskMgr.add(self.mouse_check,'mousePositionTask') self.taskMgr.add(self.placement_Mngr,'frameUpdateTask') self.taskMgr.add(self.Sound_Mngr,'MusicHandle') self.taskMgr.add(self.camera_update,'cameraPosition') self.taskMgr.remove('showIntroPic') return None def placement_Mngr(self,task): # void main = main game mechanics, frame updating function (kinda, all pausing and menu functions must be applied here) if self.state[0]=='running' or not task.time: self.ctrav.traverse(self.Game_state.root_node) #self.queue = CollisionHandlerQueue() # update the collision queue brakeforce=[0 for n in range(len(self.bodies))] # create an empty brakeforce list if self.queue.getNumEntries(): if self.debug: print(self.queue.getNumEntries()) # debug, shows only one digit most of the time # now we have to create a temp list containing only the Entries that refer to collisions between bodies, # not cursor-type collisions: temp1,temp2=[],[] for count in range(len(self.queue.getEntries())): if self.queue.getEntries()[count].getFromNodePath()!=self.pointerNP: temp1.append(self.queue.getEntries()[count]) else: temp2.append(self.queue.getEntries()[count]) # the temp1 and temp2 lists have been created # run the check for the body-with-body collisions if len(temp1)>len(self.stored_collisions): print('[WARNING]: New collision') # debugging , detects when a collision occurs AND IT F*****G WORKS BITCH !! (actually I created this system so that the particles linked to the collision are only created once) self.particle.add_particle(temp1[len(self.stored_collisions):]) #b=len(temp1[self.stored_collisions:len(temp1)]) for x in temp1[len(self.stored_collisions):]: self.particle.activate(x.getIntoNodePath().getParent(),self.Game_state.root_node) elif len(temp1)<len(self.stored_collisions): print('Collision ended') a=self.stored_collisions[len(temp1):] for x in a: self.particle.deactivate(x.getIntoNodePath().getParent()) self.particle.deactivate(x.getFromNodePath().getParent()) # at this point we should probably delete the particle object, as if we don't, it might still be updated, even if the collision doesn't exist in the self.queue anymore self.stored_collisions=temp1 #else do nothing for c in range(0,len(temp1),2): entry=temp1[c] brakeforce=self.collision_log(entry,brakeforce) # run the check for the cursor-with-body collisions for c in range(len(temp2)): entry=temp2[c] self.watched=entry.getIntoNodePath() # print "out" # update the collider list self.ctrav.clear_colliders() self.queue = CollisionHandlerQueue() for n in self.collision_solids: self.ctrav.add_collider(n.NodePath,self.queue) self.ctrav.add_collider(self.pointerNP,self.queue) # add the cursor ray again else: self.watched=None # collision events are now under constant surveillance acceleration=[] for c in range(len(self.bodies)): #selects the analysed body var=self.bodies[c] Bdf=[0,0,0] #Bdf stands for 'bilan des forces' in french, it's the resulting acceleration for d in self.bodies[0:c]+self.bodies[c+1:len(self.bodies)-1]: #selects the body which action on the analysed body we're studying...not sure about that english sentence though S,M=[d.mass]+d.position,[var.mass]+var.position temp=self.dual_a(S,M) Bdf=[Bdf[x]+temp[x] for x in range(3)] # list sum # add the result to the global save list acceleration.append(Bdf) #update the bodies' position self.speed_update(acceleration,brakeforce) self.pos_update() self.apply_update() elif self.state[0]=='paused': self.handle_menu(self.iteration) self.iteration+=1 return task.cont def speed_update(self,a,brakeforce): for c in range(len(self.bodies)): #the function updates the speed tuple accordingly self.bodies[c].speed[0]+=self.timescale*a[c][0] #self.bodies[c].speed[0]/=brakeforce[c]+1 # aero/lytho braking has to be applied to the colliding object # actually, speed isn't applied that way self.bodies[c].speed[1]+=self.timescale*a[c][1] #self.bodies[c].speed[1]/=brakeforce[c]+1 self.bodies[c].speed[2]+=self.timescale*a[c][2] #self.bodies[c].speed[2]/=brakeforce[c]+1 return 0 def pos_update(self): #updates the positional coordinates for c in range(len(self.bodies)): self.bodies[c].position[0]+=self.timescale*self.bodies[c].speed[0] self.bodies[c].position[1]+=self.timescale*self.bodies[c].speed[1] self.bodies[c].position[2]+=self.timescale*self.bodies[c].speed[2] return 0 def apply_update(self): #actually moves the hole 3d stuff around count=0 #local counter for c in self.bodies: for u in range(len(c.filelist)): if u%2!=0: c.filelist[u-1].setHpr(c.filelist[u-1],tuple([self.timescale*i for i in c.filelist[u]])) else: c.filelist[u].setPos(tuple(c.position)) if c.is_lightSource: self.light_Mngr[count][1].setPos(tuple(c.position)) count+=2 return 0 def camera_update(self,task): phi,alpha,theta,zoom,object=self.cam_Hpr[0]*pi/180,self.cam_Hpr[1]*pi/180,self.cam_Hpr[2]*pi/180,self.zoom_distance,self.state[2] if self.state[1]=='free': self.camera.setPos(tuple(self.camera_pos)) elif self.state[1]=='linked': # find the object (self.state[2]) in the data list list_pos=[self.bodies[n].filelist[0] for n in range(len(self.bodies))].index(object.getParent()) self.focus_point=self.bodies[list_pos].position # take the focused object's coordinates self.camera_pos=[self.focus_point[0]+sin(phi)*cos(-alpha)*zoom,self.focus_point[1]-cos(phi)*cos(-alpha)*zoom,self.focus_point[2]+sin(-alpha)*zoom] self.camera.setPos(tuple(self.camera_pos)) self.camera.setHpr(tuple(self.cam_Hpr)) # collision cursor stuff goes here: self.cursor_ray.setFromLens(self.camNode,0,0) # relatively to the camera, the cursor position will always be 0,0 which is the position of the # white point on the screen if self.keymap!=['z',0,'q',0,'s',0,'d',0]: for x in range(1,len(self.keymap),2): if self.keymap[x]: self.move_camera(int((x-1)/2),True) # why (x-1)/2 ? because we have to make the tow readable as a key number, like 0,1,2,3 return task.cont def dual_a(self,S,M): #S is the "static object", the one that applies the force to the "moving" object M O=[] #This will be the list with the accelerations for an object d=sqrt((S[1]-M[1])**2+(S[2]-M[2])**2+(S[3]-M[3])**2) x=(self.u_constant*S[0]*(S[1]-M[1]))/d**2 y=(self.u_constant*S[0]*(S[2]-M[2]))/d**2 z=(self.u_constant*S[0]*(S[3]-M[3]))/d**2 O.append(x) O.append(y) O.append(z) return O def collision_log(self,entry,brakeforce): from_pos=[self.bodies[n].filelist[0] for n in range(len(self.bodies))].index(entry.getFromNodePath().getParent()) into_pos=[self.bodies[n].filelist[0] for n in range(len(self.bodies))].index(entry.getIntoNodePath().getParent()) #find the nodepath in the list f_radius=sum(self.bodies[from_pos].scale)*self.u_radius/3 i_radius=sum(self.bodies[into_pos].scale)*self.u_radius/3 if max(f_radius,i_radius)==f_radius: inverted=True into_pos,from_pos=from_pos,into_pos else: inverted=False # currently useless brakeforce[from_pos]=self.bodies[from_pos].brakeforce # get the force given in the data list # those are the two positions of the nodepaths, now we need to know which one is bigger, in order to obtain the fusion effect # from_pos is the smaller body, into_pos is the bigger one self.collision_gfx(self.momentum_transfer(from_pos,into_pos,entry,inverted),f_radius,i_radius) #some useless data remains from version 0.9 return brakeforce def momentum_transfer(self,f_pos,i_pos,entry,inverted): if self.debug: print("colliding") # debug, makes the game laggy (only activated when the self.debug var is on) interior = entry.getInteriorPoint(self.Game_state.root_node) # default surface = entry.getSurfacePoint(self.Game_state.root_node) if self.debug: print((interior - surface).length()) # debug, doesn't slow the game down too much so I haven't removed it if (interior - surface).length() >= self.u_radius*2*sum(self.bodies[f_pos].scale)/3: # this is the body deletion routine if self.state[2]==self.collision_solids[f_pos].NodePath: self.state[1]='free' self.state[2]=None # Lighting if self.bodies[f_pos].is_lightSource: self.Game_state.root_node.clearLight(self.light_Mngr[2*f_pos][1]) self.Game_state.root_node.clearLight(self.light_Mngr[2*f_pos][1]) self.filters.delVolumetricLighting() #temp self.ctrav.remove_collider(self.collision_solids[f_pos].NodePath) self.bodies[f_pos].delete_body() self.bodies[i_pos].scale[0]*=(self.bodies[i_pos].mass+self.bodies[f_pos].mass)/self.bodies[i_pos].mass self.bodies[i_pos].scale[1]*=(self.bodies[i_pos].mass+self.bodies[f_pos].mass)/self.bodies[i_pos].mass self.bodies[i_pos].scale[2]*=(self.bodies[i_pos].mass+self.bodies[f_pos].mass)/self.bodies[i_pos].mass self.bodies[i_pos].mass+=self.bodies[f_pos].mass # particle deletion self.particle.deactivate(self.collision_solids[f_pos].NodePath.getParent()) self.particle.deactivate(self.collision_solids[i_pos].NodePath.getParent()) # scale updating () ''' temporarly removed for c in range(0,len(self.bodies[i_pos].filelist),2): self.bodies[i_pos].filelist[c].setScale(tuple(self.bodies[i_pos].scale)) ''' # deleting the destroyed planet's data self.bodies=self.bodies[:f_pos]+self.bodies[f_pos+1:len(self.bodies)] self.collision_solids=self.collision_solids[:f_pos]+self.collision_solids[f_pos+1:len(self.collision_solids)] # update the light list self.light_Mngr=self.light_Mngr[:2*f_pos]+self.light_Mngr[2*f_pos+2:len(self.light_Mngr)] # just a quick test if self.debug: self.ctrav.showCollisions(self.Game_state.root_node) if self.debug: print("planet destroyed") return interior,surface # used for the collision gfx calculations def printScene(self): #debug file=open("scenegraph.txt","a") ls = LineStream() self.Game_state.root_node.ls(ls) while ls.isTextAvailable(): file.write(ls.getLine()) file.write("\n") file.write("\n") file.write("END\n") file.write("\n") file.close() def Sound_Mngr(self,task): if self.current_song.length()-self.current_song.getTime()==0: #could have just used not() self.current_playing=random.choice(list(range(0,self.current_playing))+list(range(self.current_playing+1,len(self.sounds)))) self.current_song=self.loader.loadSfx(self.sounds[self.current_playing]) self.current_song.play() print(self.current_playing) return task.cont def collision_gfx(self,points,Rf,Ri): # collision animation calculations # section size calculation # we know the depth of penetration (no silly jokes please), which allows us, knowing the radius of each body, # to calculate the radius of the section (I've got no idea how to say that in correct english) # the display of the particles all over this circle will be a piece of cake (at least I hope so) - edit - it wasn't # see documents in the screenshot folder for more informations about the maths ''' interior,surface=points[0],points[1] p=(interior - surface).length() p2=(p**2-2*Ri*p)/(2*Ri-2*p-2*Rf) p1=p-p2 ''' #currently useless self.update_particle_pos() # now we know everything about our impact section (the circle that defines the contact between the two bodies) # we just have to find the coord of the circle's center: we will take the surfacepoint impact point return 0 def create_crater(self): # see project for more informations return None def toggle_pause(self): self.toggle_particles() # pause the particles temp=['paused','running'] self.state[0]=temp[self.state[0]==temp[0]] # switches between paused and running self.iteration=0 if self.state[0]=='paused': # discord rpc updating try: RPC.update(state="Version: 0.11", details="In the menus",large_image="logo",small_image=None) except: pass self.handle_menu(self.iteration) else: # discord RPC updating try: RPC.update(state="Version: 0.11", details="In a simulation",large_image="logo",small_image=None) except: pass self.filters.del_blur_sharpen() self.filters.set_gamma_adjust(1) # make the mouse invisible self.hidden_mouse=True wp = WindowProperties() wp.setCursorHidden(self.hidden_mouse) # set the mouse pos to 0 self.center_mouse() self.win.requestProperties(wp) for u in self.paused_menu_text: u.hide() return None def handle_menu(self,iteration): if not iteration: self.accept('escape',self.toggle_pause) self.draw_menu() # make the mouse visible self.hidden_mouse=False wp = WindowProperties() wp.setCursorHidden(self.hidden_mouse) self.win.requestProperties(wp) else: a=1 # indentation (temporary) #put your mouse detection stuff here # menu stuff # menu stuff # please use directGui for that purpose (better rendering performances) # the menu doesn't actually work, as the whole clicking reaction routine is not implemented return None def draw_menu(self): self.filters.setBlurSharpen(amount=0) self.filters.set_gamma_adjust(1.7) for u in self.paused_menu_text: u.show() return None def show_credits(self): print("created by l3alr0g, zudo and Fang (at least this part) --> I'll do something better later") return None def system_break(self): # place your data saving routines here print("system exit successful, data saved") print("executing sys.exit()") print("out: done") sys.exit(0) return None def handle_scrolling(self,up): # up is a boolean: up=True means up, up=False means down if up and self.state[0]=='running': if self.state[1]=='linked': self.zoom_distance*=0.95 else: self.camera_delta*=1.1 elif not up and self.state[0]=='running': if self.state[1]=='linked': self.zoom_distance/=0.95 else: self.camera_delta/=1.1 return None def rotate_camera(self): self.camera.setHpr(tuple(self.cam_Hpr)) return None def move_camera(self,tow,pressed): # tow stands for towards, pressed is a boolean which indicates the state of the key if pressed: self.keymap[2*tow+1]=1 self.state[1]='free' #print('free mode on') self.state[2]=None else: self.keymap[2*tow+1]=0 if self.keymap[2*tow+1]: phi,alpha,theta,delta,zoom=self.cam_Hpr[0]*pi/180,self.cam_Hpr[1]*pi/180,self.cam_Hpr[2]*pi/180,self.camera_delta,self.zoom_distance if self.keymap[2*tow]=='q': if self.state[1]=='free': self.camera_pos=[self.camera_pos[0]-cos(phi)*cos(theta)*delta,self.camera_pos[1]-sin(phi)*cos(theta)*delta,self.camera_pos[2]+sin(theta)*delta] # moving the camera if self.keymap[2*tow]=='z': if self.state[1]=='free': self.camera_pos=[self.camera_pos[0]-sin(phi)*cos(alpha)*delta,self.camera_pos[1]+cos(phi)*cos(alpha)*delta,self.camera_pos[2]+sin(alpha)*delta] if self.keymap[2*tow]=='s': if self.state[1]=='free': self.camera_pos=[self.camera_pos[0]+sin(phi)*cos(alpha)*delta,self.camera_pos[1]-cos(phi)*cos(alpha)*delta,self.camera_pos[2]-sin(alpha)*delta] if self.keymap[2*tow]=='d': if self.state[1]=='free': self.camera_pos=[self.camera_pos[0]+cos(phi)*cos(theta)*delta,self.camera_pos[1]+sin(phi)*cos(theta)*delta,self.camera_pos[2]-sin(theta)*delta] if self.keymap[2*tow]=='a': self.cam_Hpr[2]-=1 if self.keymap[2*tow]=='e': self.cam_Hpr[2]+=1 return None def mouse_check(self,task): # gets the mouse's coordinates mwn = self.mouseWatcherNode if mwn.hasMouse(): x,y=mwn.getMouseX(),mwn.getMouseY() #print(x,y) # debug # focus_point coordinates modifier code here: if self.state==['running','free',None]: self.cam_Hpr[0]-=x*self.sensitivity_x # the - fixes a bug I can't solve # sensitivity is a coefficient used for mouse displacement routines self.cam_Hpr[1]+=y*self.sensitivity_y # those formulas do not work when theta (self.cam_Hpr[2]) changes self.rotate_camera() self.center_mouse() elif self.state[0]=='running' and self.state[1]=='linked': self.cam_Hpr[0]-=x*self.sensitivity_x self.cam_Hpr[1]-=y*self.sensitivity_y self.rotate_camera() self.center_mouse() ''' if self.debug: print(self.cam_Hpr,self.camera_pos) # debug ''' return task.cont def center_mouse(self): self.win.movePointer(0, int(self.win.getProperties().getXSize() / 2), int(self.win.getProperties().getYSize() / 2)) # move mouse back to center --> careful ! this makes the delta calculation code buggy def handle_select(self,is_clicked): if is_clicked and self.watched!=None: self.state[1]='linked' # toggle following mode self.state[2]=self.watched print('linked mode on, focusing: ',self.watched) #else: # do nothing actually return None def update_particle_pos(self): # harder than I thought for x in range(len(self.particle.particle_list)): a=[i.getIntoNodePath() for i in self.queue.getEntries()].index(self.particle.particle_list[x][1]) # finding the intonodepath inside self.queue.getEntries() self.particle.particle_list[x][0].setPos(self.queue.getEntries()[a].getSurfacePoint(self.Game_state.root_node)) # all particles are being displaced to the position of the surface impact point tempvar=self.queue.getEntries()[a].getSurfacePoint(self.Game_state.root_node) - self.queue.getEntries()[a].getIntoNodePath().getParent().getPos() H,P,R=-atan(tempvar[0]/tempvar[1])*180/pi+180,(-atan(tempvar[2]/tempvar[1])+pi/2)*180/pi,0 self.particle.particle_list[x][0].setHpr(H,P,R) # self.queue.getEntries()[a].getIntoNodePath().getParent().getPos() # +self.queue.getEntries()[a].getSurfacePoint(self.queue.getEntries()[a].getIntoNodePath()) return None def time_change(self,income): # income is a boolean, True means speed up, False means speed down if income: self.timescale*=1.2 else: self.timescale*=0.80 return None def not_implemented_yet(self): # comes with self.follow function self.sign=OnscreenImage(image=str(MAINDIR)+"/Engine/not_implemented_yet.png",pos=(0,0,0),scale=(0.5,0.5,0.5)) # scale is useless: already at scale (the pic is square shaped) self.sign.setTransparency(TransparencyAttrib.MAlpha) self.accept("escape",self.follow) self.quit_button['state']=DGG.DISABLED self.settings_button['state']=DGG.DISABLED self.start_button['state']=DGG.DISABLED return None def follow(self): # dependencies of the not_implemented_yet function self.ignore("escape") self.sign.destroy() self.quit_button['state']=DGG.NORMAL self.settings_button['state']=DGG.NORMAL self.start_button['state']=DGG.NORMAL return None def easter_egg(self): return "please be patient, our hens are working on it" # I am not responsible for the bad quality of my humor def ingame_back_to_menu(self): # large name, I know, I had no ideas self.filters.set_gamma_adjust(1) for u in self.paused_menu_text: u.hide() self.filters.del_blur_sharpen() self.Game_state.cleanup() # we have to delete all the taskManager routines we implemented during the simulation # here comes the whole stuff: self.taskMgr.remove('mousePositionTask') self.taskMgr.remove('frameUpdateTask') self.taskMgr.remove('MusicHandle') self.taskMgr.remove('cameraPosition') # end of task manager stuff self.stored_collisions=[] self.watched=None self.state=['paused','free',None] self.iteration=0 self.filters.delVolumetricLighting() # temporary, as I have to implement multiple light source handling # music self.current_song.stop() self.menu() return None
class PGWorld(ShowBase.ShowBase): DEBUG = False loadPrcFileData("", "window-title {}".format(PG_EDITION)) loadPrcFileData("", "framebuffer-multisample 1") loadPrcFileData("", "multisamples 8") loadPrcFileData("", 'bullet-filter-algorithm groups-mask') loadPrcFileData("", "audio-library-name null") loadPrcFileData("", "model-cache-compressed-textures 1") # loadPrcFileData("", " framebuffer-srgb truein") # loadPrcFileData("", "geom-cache-size 50000") # v-sync, it seems useless # loadPrcFileData("", "sync-video 1") # for debug use # loadPrcFileData("", "gl-version 3 2") def __init__(self, config: dict = None): # Setup config and Panda3d self.world_config = config # self.world_config = merge_config(self.default_config(), config) # if config is not None: # self.world_config.merge(config) if self.world_config["pstats"]: # pstats debug provided by panda3d loadPrcFileData("", "want-pstats 1") loadPrcFileData("", "win-size {} {}".format(*self.world_config["window_size"])) # Setup onscreen render if self.world_config["use_render"]: self.mode = RENDER_MODE_ONSCREEN # Warning it may cause memory leak, Pand3d Official has fixed this in their master branch. # You can enable it if your panda version is latest. loadPrcFileData("", "threading-model Cull/Draw") # multi-thread render, accelerate simulation when evaluate else: if self.world_config["use_image"]: self.mode = RENDER_MODE_OFFSCREEN loadPrcFileData("", "threading-model Cull/Draw") else: self.mode = RENDER_MODE_NONE if is_mac() and (self.mode == RENDER_MODE_OFFSCREEN): # Mac don't support offscreen rendering self.mode = RENDER_MODE_ONSCREEN # Setup some debug options if self.world_config["headless_image"]: # headless machine support loadPrcFileData("", "load-display pandagles2") if self.world_config["debug"]: # debug setting PGWorld.DEBUG = True _free_warning() setup_logger(debug=True) self.accept('1', self.toggleDebug) self.accept('2', self.toggleWireframe) self.accept('3', self.toggleTexture) self.accept('4', self.toggleAnalyze) else: # only report fatal error when debug is False _suppress_warning() # a special debug mode if self.world_config["debug_physics_world"]: self.accept('1', self.toggleDebug) self.accept('4', self.toggleAnalyze) super(PGWorld, self).__init__(windowType=self.mode) # Change window size at runtime if screen too small # assert int(self.world_config["use_topdown"]) + int(self.world_config["use_image"]) <= 1, ( # "Only one of use_topdown and use_image options can be selected." # ) # main_window_position = (0, 0) if self.mode == RENDER_MODE_ONSCREEN: if self.world_config["fast_launch_window"]: pass else: loadPrcFileData("", "compressed-textures 1") # Default to compress h = self.pipe.getDisplayHeight() w = self.pipe.getDisplayWidth() if self.world_config["window_size"][0] > 0.9 * w or self.world_config["window_size"][1] > 0.9 * h: old_scale = self.world_config["window_size"][0] / self.world_config["window_size"][1] new_w = int(min(0.9 * w, 0.9 * h * old_scale)) new_h = int(min(0.9 * h, 0.9 * w / old_scale)) self.world_config["window_size"] = tuple([new_w, new_h]) from panda3d.core import WindowProperties props = WindowProperties() props.setSize(self.world_config["window_size"][0], self.world_config["window_size"][1]) self.win.requestProperties(props) logging.warning( "Since your screen is too small ({}, {}), we resize the window to {}.".format( w, h, self.world_config["window_size"] ) ) # main_window_position = ( # (w - self.world_config["window_size"][0]) / 2, (h - self.world_config["window_size"][1]) / 2 # ) # self.highway_render = None # if self.world_config["use_topdown"]: # self.highway_render = HighwayRender(self.world_config["use_render"], main_window_position) # screen scale factor self.w_scale = max(self.world_config["window_size"][0] / self.world_config["window_size"][1], 1) self.h_scale = max(self.world_config["window_size"][1] / self.world_config["window_size"][0], 1) if self.mode == RENDER_MODE_ONSCREEN: self.disableMouse() if not self.world_config["debug_physics_world"] and (self.mode in [RENDER_MODE_ONSCREEN, RENDER_MODE_OFFSCREEN ]): initialize_asset_loader(self) gltf.patch_loader(self.loader) # Display logo if self.mode == RENDER_MODE_ONSCREEN and (not self.world_config["debug"]) \ and (not self.world_config["fast_launch_window"]): self._loading_logo = OnscreenImage( image=AssetLoader.file_path("PGDrive-large.png"), pos=(0, 0, 0), scale=(self.w_scale, 1, self.h_scale) ) self._loading_logo.setTransparency(True) for i in range(20): self.graphicsEngine.renderFrame() self.taskMgr.add(self.remove_logo, "remove _loading_logo in first frame") self.closed = False # add element to render and pbr render, if is exists all the time. # these element will not be removed when clear_world() is called self.pbr_render = self.render.attachNewNode("pbrNP") # attach node to this root root whose children nodes will be clear after calling clear_world() self.worldNP = self.render.attachNewNode("world_np") # same as worldNP, but this node is only used for render gltf model with pbr material self.pbr_worldNP = self.pbr_render.attachNewNode("pbrNP") self.debug_node = None # some render attribute self.pbrpipe = None self.light = None # physics world self.physics_world = PGPhysicsWorld(self.world_config["debug_static_world"]) # collision callback self.physics_world.dynamic_world.setContactAddedCallback(PythonCallbackObject(pg_collision_callback)) # for real time simulation self.force_fps = ForceFPS(self, start=True) # init terrain self.terrain = Terrain() self.terrain.attach_to_pg_world(self.render, self.physics_world) # init other world elements if self.mode != RENDER_MODE_NONE: from pgdrive.world.our_pbr import OurPipeline self.pbrpipe = OurPipeline( render_node=None, window=None, camera_node=None, msaa_samples=4, max_lights=8, use_normal_maps=False, use_emission_maps=True, exposure=1.0, enable_shadows=False, enable_fog=False, use_occlusion_maps=False ) self.pbrpipe.render_node = self.pbr_render self.pbrpipe.render_node.set_antialias(AntialiasAttrib.M_auto) self.pbrpipe._recompile_pbr() self.pbrpipe.manager.cleanup() # set main cam self.cam.node().setCameraMask(CamMask.MainCam) self.cam.node().getDisplayRegion(0).setClearColorActive(True) self.cam.node().getDisplayRegion(0).setClearColor(ImageBuffer.BKG_COLOR) lens = self.cam.node().getLens() lens.setFov(70) lens.setAspectRatio(1.2) self.sky_box = SkyBox() self.sky_box.attach_to_pg_world(self.render, self.physics_world) self.light = Light(self.world_config) self.light.attach_to_pg_world(self.render, self.physics_world) self.render.setLight(self.light.direction_np) self.render.setLight(self.light.ambient_np) self.render.setShaderAuto() self.render.setAntialias(AntialiasAttrib.MAuto) # ui and render property if self.world_config["show_fps"]: self.setFrameRateMeter(True) # onscreen message self.on_screen_message = PGOnScreenMessage( debug=self.DEBUG ) if self.mode == RENDER_MODE_ONSCREEN and self.world_config["onscreen_message"] else None self._show_help_message = False self._episode_start_time = time.time() self.accept("h", self.toggle_help_message) self.accept("f", self.force_fps.toggle) else: self.on_screen_message = None # task manager self.taskMgr.remove('audioLoop') def render_frame(self, text: Optional[Union[dict, str]] = None): """ The real rendering is conducted by the igLoop task maintained by panda3d. Frame will be drawn and refresh, when taskMgr.step() is called. This function is only used to pass the message that needed to be printed in the screen to underlying renderer. :param text: A dict containing key and values or a string. :return: None """ if self.on_screen_message is not None: self.on_screen_message.update_data(text) self.on_screen_message.render() if self.mode == RENDER_MODE_ONSCREEN: self.sky_box.step() # if self.highway_render is not None: # self.highway_render.render() def clear_world(self): """ Call me to setup the whole visualization world after _init_ """ # attach all node to this node asset_path self.worldNP.node().removeAllChildren() self.pbr_worldNP.node().removeAllChildren() if self.world_config["debug_physics_world"]: self.addTask(self.report_body_nums, "report_num") self._episode_start_time = time.time() def step(self): dt = self.world_config["physics_world_step_size"] self.physics_world.dynamic_world.doPhysics(dt, 1, dt) def _debug_mode(self): debugNode = BulletDebugNode('Debug') debugNode.showWireframe(True) debugNode.showConstraints(True) debugNode.showBoundingBoxes(False) debugNode.showNormals(True) debugNP = self.render.attachNewNode(debugNode) self.physics_world.dynamic_world.setDebugNode(debugNP.node()) self.debug_node = debugNP def toggleAnalyze(self): self.worldNP.analyze() print(self.physics_world.report_bodies()) # self.worldNP.ls() def toggleDebug(self): if self.debug_node is None: self._debug_mode() if self.debug_node.isHidden(): self.debug_node.show() else: self.debug_node.hide() def report_body_nums(self, task): logging.debug(self.physics_world.report_bodies()) return task.done def close_world(self): self.taskMgr.stop() # It will report a warning said AsynTaskChain is created when taskMgr.destroy() is called but a new showbase is # created. logging.debug( "Before del taskMgr: task_chain_num={}, all_tasks={}".format( self.taskMgr.mgr.getNumTaskChains(), self.taskMgr.getAllTasks() ) ) self.taskMgr.destroy() logging.debug( "After del taskMgr: task_chain_num={}, all_tasks={}".format( self.taskMgr.mgr.getNumTaskChains(), self.taskMgr.getAllTasks() ) ) # while self.taskMgr.getAllTasks(): # time.sleep(0.1) self.physics_world.destroy() self.destroy() AssetLoader.destroy() import sys if sys.version_info >= (3, 0): import builtins else: import __builtin__ as builtins if hasattr(builtins, 'base'): del builtins.base def toggle_help_message(self): if self.on_screen_message: self.on_screen_message.toggle_help_message() def draw_line(self, start_p, end_p, color, thickness: float): """ Draw line use LineSegs coordinates system. Since a resolution problem is solved, the point on screen should be described by [horizontal ratio, vertical ratio], each of them are ranged in [-1, 1] :param start_p: 2d vec :param end_p: 2d vec :param color: 4d vec, line color :param thickness: line thickness :param pg_world: pg_world class :return: """ line_seg = LineSegs("interface") line_seg.setColor(*color) line_seg.moveTo(start_p[0] * self.w_scale, 0, start_p[1] * self.h_scale) line_seg.drawTo(end_p[0] * self.w_scale, 0, end_p[1] * self.h_scale) line_seg.setThickness(thickness) line_np = self.aspect2d.attachNewNode(line_seg.create(False)) return line_np def remove_logo(self, task): alpha = self._loading_logo.getColor()[-1] if alpha < 0.1: self._loading_logo.destroy() return task.done else: new_alpha = alpha - 0.08 self._loading_logo.setColor((1, 1, 1, new_alpha)) return task.cont
class InfoGUI(DirectFrame, StateData.StateData): notify = DirectNotifyGlobal.directNotify.newCategory('InfoGUI') def __init__(self, avChooser): DirectFrame.__init__(self, pos=(0, 0, 0.05), relief=None, image=DGG.getDefaultDialogGeom(), image_scale=(2.2, 1, 1.4), image_pos=(0, 0, -0.05), image_color=ToontownGlobals.GlobalDialogColor, text=TTLocalizer.AvatarChooserInfo, text_scale=0.12, text_pos=(0, 0.5), borderWidth=(0.01, 0.01)) StateData.StateData.__init__(self, 'info-gui-done') self.isLoaded = False self.setBin('gui-popup', 0) self.initialiseoptions(InfoGUI) self.avChooser = avChooser self.textRolloverColor = Vec4(1, 1, 0, 1) self.textDownColor = Vec4(0.5, 0.9, 1, 1) self.textDisabledColor = Vec4(0.4, 0.8, 0.4, 1) self.descPos = (0.485, 0, -0.2) self.halloweenMiniserver = None self.halloweenMiniserverSeq = None return def unload(self): if not self.isLoaded: return self.isLoaded = False self.exit() DirectFrame.destroy(self) def load(self): if self.isLoaded: return self.isLoaded = True gui = loader.loadModel('phase_3.5/models/gui/friendslist_gui') guiButton = loader.loadModel('phase_3/models/gui/quit_button') if base.cr.holidayValue == 1: ImagePath = 'phase_14.5/maps/halloween_server_1.png' else: if base.cr.holidayValue == 2: ImagePath = 'phase_14.5/maps/halloween_server_3.png' else: if base.cr.holidayValue == 3: ImagePath = 'phase_14.5/maps/halloween_server_5.png' else: if base.cr.holidayValue == 4: ImagePath = 'phase_14.5/maps/halloween_server_2.png' else: if base.cr.holidayValue == 5: ImagePath = 'phase_14.5/maps/halloween_server_4.png' else: if base.cr.holidayValue == 6: ImagePath = 'phase_14.5/maps/halloween_server_4.png' self.sname = DirectLabel(parent=self, text=TTLocalizer.ServerPageName % base.cr.serverName, relief=None, pos=(0.0, 0.0, 0.35), scale=0.079, text_fg=Vec4(0, 0, 0, 1), text_align=TextNode.ACenter, text_font=ToontownGlobals.getToonFont()) self.description = DirectLabel(parent=self, text=TTLocalizer.InfoDescription + base.cr.serverDescription, relief=None, pos=(0.0, 0.0, 0.25), scale=0.069, text_fg=Vec4(0, 0, 0, 1), text_wordwrap=24, text_align=TextNode.ACenter, text_font=ToontownGlobals.getToonFont()) self.cancel = DirectButton(parent=self, relief=None, text=TTLocalizer.DisplaySettingsCancel, image=(guiButton.find('**/QuitBtn_UP'), guiButton.find('**/QuitBtn_DN'), guiButton.find('**/QuitBtn_RLVR')), image_scale=(0.6, 1, 1), text_scale=TTLocalizer.DSDcancel, text_pos=TTLocalizer.DSDcancelPos, pos=(0.93, 0, -0.65), command=self.__cancel) if base.cr.isHalloween and base.cr.holidayValue != 0: self.halloweenMiniserver = OnscreenImage(image=ImagePath, pos=(0.0, 0, -0.13), scale=(0.3125, 0.3125, 0.25)) self.halloweenMiniserver.reparentTo(self) self.halloweenMiniserver.setTransparency(TransparencyAttrib.MAlpha) self.halloweenMiniserverSeq = Sequence( self.halloweenMiniserver.scaleInterval(3, (0.5, 0.5, 0.4), blendType='easeInOut'), self.halloweenMiniserver.scaleInterval(3, (0.3125, 0.3125, 0.25), blendType='easeInOut')) self.halloweenMiniserverSeq.loop() self.event = DirectLabel( text='A unqiue Halloween event is\nactive on this Mini-Server!', relief=None, pos=(0.0, 0.0, -0.6), scale=0.069, text_fg=Vec4(0, 0, 0, 1), text_align=TextNode.ACenter, text_font=ToontownGlobals.getToonFont()) self.event.reparentTo(self) self.eventSeq = Sequence( Wait(1.4), Func(self.event.setColorScale, 1, 1, 1, 0), Wait(1.4), Func(self.event.setColorScale, 1, 1, 1, 1)) self.eventSeq.loop() gui.removeNode() guiButton.removeNode() self.hide() return def enter(self): if self.isEntered == 1: return self.isEntered = 1 if self.isLoaded == 0: self.load() base.transitions.fadeScreen(0.5) self.show() def exit(self): if self.isEntered == 0: return self.isEntered = 0 base.transitions.noTransitions() self.ignoreAll() self.hide() def __cancel(self): self.exit()
class EventManager(ShowBase): def __init__(self): ShowBase.__init__(self) #self.setFrameRateMeter(True) self.agui() self.initkeys() self.game_init = False self.rungame = False taskMgr.add(self.game, "Game",) # this is setting the main information at the start page def agui(self): self.a,self.b = text_entry("Particpant ID",0.6) self.c,self.d = text_entry("Age",0.5) self.e,self.f = text_entry("Gender",0.4,options = ["Male","Female"]) self.butt = button("Go!",-0.5,extras=[self.b,self.d,self]) self.p_ID = self.b.get() self.todelete = [self.c,self.d,self.a,self.b,self.e,self.f,self.butt] # code to start the game def game(self,task): if self.game_init: self.initgame() for thing in self.todelete: thing.destroy() self.game_init = False if self.rungame: if self.GameOver == False: if self.new_trial: self.init_trial() elif self.go: self.godisp() else: if self.joystickon == 1: self.getjoystick() else: self.move() self.animate() self.dig() self.drag() self.movecam() if self.savelog: self.log() self.savelog = False else: if self.BlackScreen == 0: self.BlackScreen = 1 OnscreenImage(image = 'textures/black.jpg', pos = (0, 0, 0),scale=100) self.starimage = OnscreenImage(image = 'textures/goldstar.png', pos = (0,0,0),scale=0.1) self.starimage.setTransparency(TransparencyAttrib.MAlpha) #self.EndText = OnscreenText(text = "GREAT JOB!" , pos = (-100, -0.5), scale = 0.1*self.goscale) return task.cont # creating the log file - note that I added 1 column variable to the end of file. def log(self): print "log" """Save trial ID - Age - Gender - Reversal - """ self.file.write("\n") self.file.write("%s\t" % self.p_ID) self.file.write("%s\t" % self.p_age) self.file.write("%s\t" % self.p_gender) self.file.write("%s\t" % self.trial_no) self.file.write("%s\t" % self.reversal) self.file.write("%s\t" % self.trial[0]) self.file.write("%s\t" % self.dug) self.file.write("%s\t" % self.trialscore) self.file.write("%s\t" % self.TotalScore) self.file.write("%s\t" % self.RunningTotal) self.file.write("%s\t" % self.LastFiveSixCount) self.file.write("%s\t" % self.trial_num_phase) for visit_no in self.visits: self.file.write("%s\t" % visit_no) self.file.write("%s\t" % self.RT) # setting up the onscreen text for start of trial. def godisp(self): self.ReadyText.destroy() self.GoText.destroy() self.goscale+=60./self.framerate if self.goscale < 60: self.ReadyText = OnscreenText(text = "Ready!" , pos = (0, -0.5), scale = 0.1*self.goscale/2) elif self.goscale < 120: self.GoText.destroy() elif self.goscale < 180: self.GoText = OnscreenText(text = "Go!" , pos = (0, -0.5), scale = 0.1*(self.goscale-120)/2) else: self.go = False self.t0 = time.time() # not using the joystick so this doesn't work def getjoystick(self): dt = globalClock.getDt() if self.canMove == True: for event in pygame.event.get(): pass self.isMoving = False self.isTurning = False if self.joystick.get_axis( 4 )<-0.8: self.isMoving=True self.get_move(dt) if self.joystick.get_axis( 3 )<-0.8: self.kiki.setH(self.kiki.getH() + 300 * dt) self.isTurning = True if self.joystick.get_axis( 3 )>0.8: self.kiki.setH(self.kiki.getH() - 300 * dt) self.isTurning = True if self.joystick.get_button( 1 ) > 0.8: if self.get_dig()>-1: self.digging = True # parameters to move character def move(self): dt = globalClock.getDt() #get time from last frame #check for keyboard input if self.canMove == True: self.isMoving=False if self.LRSpin == "Spin": if self.keyMap["spin"]: pass #self.camspin = True else: self.camspin = False if self.keyMap["left"]: self.kiki.setH(self.kiki.getH() + 300 * dt) self.isTurning = True if self.keyMap["right"]: self.kiki.setH(self.kiki.getH() - 300 * dt) self.isTurning = True if self.keyMap["forward"]: self.isMoving=True self.get_move(dt) if self.keyMap["back"]: self.isMoving=True self.get_move(dt,back=1) if not self.keyMap["left"] and not self.keyMap["right"]: self.isTurning = False else: a,b = -1,-1 self.isTurning = True if self.keyMap["left"]: self.kiki.setH(90) self.isMoving=True self.get_move(dt,side=1) a = 0 if self.keyMap["right"]: self.kiki.setH(270) self.isMoving=True self.get_move(dt,side=-1) a = 1 if self.keyMap["forward"]: self.kiki.setH(0) self.isMoving=True self.get_move(dt) b = 0 if self.keyMap["back"]: self.kiki.setH(180) self.isMoving=True self.get_move(dt,back=1) b = 1 if a > -1 and b > -1: self.kiki.setH([[45,315],[135,225]][b][a]) if self.keyMap["dig"]: if self.get_dig()>-1: self.digging = True # parameters to dig in the box def get_dig(self): x,y = self.kiki.getPos()[0],self.kiki.getPos()[1] dig = -1 for i,j in zip(self.presLoc,[0,1,2,3]): if abs(x -self.boxloca[i][0])<3 and abs(y -self.boxloca[i][1])<3: dig = j if self.dug == -1: self.RT = time.time() - self.t0 self.savelog = True self.dug = j # if you got the trial correct if self.dug == self.trial[0]: if self.trialscore == 0: self.TotalScore+=1 self.addstar = 1 self.trialscore = 1 self.RunningTotal+=1 else: self.RunningTotal = 0 return dig # parameters to get feedback from the box (star or no star) def dig(self): if self.digging == True: self.plnp.setPos(self.boxloca[self.presLoc[self.dug]][0],self.boxloca[self.presLoc[self.dug]][1], 0) self.render.setLight(self.plnp) self.isMoving = False self.canMove=False if self.boxcam == True: if self.dug == self.trial[0]: self.star.reparentTo(self.render) self.starspin() elif self.negfeedbac ==1: if self.clouddisp == 1: self.clouddisp =0 ex = 0 self.presents[self.dug].detachNode() self.clouds.reparentTo(self.render) self.clouds.setPos(self.boxloca[self.presLoc[self.dug]][0],self.boxloca[self.presLoc[self.dug]][1],2) if self.dragback == False: if flipbook_2(self.clouds,self.cloudsframe,loop=0): self.dragback= True self.clouds.detachNode() self.clouds.currentframe = 0 self.digging = False else: flipbook_2(self.kiki,self.losingframe,loop=1) else: self.digging = False self.dragback= True else: a = flipbook_2(self.kiki,self.digframe,0) flipbook_2(self.presents[self.dug],self.presentsframe,0) if a: self.boxcam = True # making the start spin def starspin(self): self.presents[self.dug].detachNode() self.spin +=60./self.framerate if self.spin < 180: self.star.setH(self.spin*5) self.star.setPos(self.boxloca[self.presLoc[self.dug]][0],self.boxloca[self.presLoc[self.dug]][1],3+self.spin/30.) flipbook_2(self.kiki,self.winframe,loop=1) else: self.dragback = True self.star.detachNode() self.digging = False def get_move(self,dt,back = 0,side = 0): if self.LRSpin == "Spin": if back == 0: dir = -self.kiki.getH()/360*2*np.pi else: dir = -self.kiki.getH()/360*2*np.pi-np.pi else: dir = 0 if back == 1: dir = pi if side == -1: dir = pi/2 if side == 1: dir = 3*pi/2 prop = [self.kiki.getPos()[0]-25*np.sin(dir)*dt,self.kiki.getPos()[1]-25*np.cos(dir)*dt] pos = self.kiki.getPos() i,j = prop if prop[0]<-13: i=-13 if prop[0]>13: i = 13 if prop[1]>13: j = 13 if prop[1]<-13: j = -13 if pos[1]>=-10 and prop[1]<-10 and (prop[0]<-10 or prop[0]>10): j=-10 if pos[1]<=10 and prop[1]>10 and (prop[0]<-10 or prop[0]>10): j=10 if pos[0]>=-10 and prop[0]<-10 and (prop[1]<-10 or prop[1]>10): i=-10 if pos[0]<=10 and prop[0]>10 and (prop[1]<-10 or prop[1]>10): i=10 self.kiki.setPos(i,j,self.kiki.getPos()[2]) self.check_location() def check_location(self): pos = self.kiki.getPos() if pos[0]<=-10+self.change_dist and pos[1]<=-10+self.change_dist: a = 0 elif pos[0]>=10-self.change_dist and pos[1]<=-10+self.change_dist: a = 1 elif pos[0]>=10-self.change_dist and pos[1]>=10-self.change_dist: a = 2 elif pos[0]<=-10+self.change_dist and pos[1]>=10-self.change_dist: a = 3 else: if self.atbox > -1: self.presents[self.atbox].setTexture(self.texgrey) self.atbox = -1 a = -1 if a > -1: if self.atbox == -1: self.visits[self.presLoc.index(a)]+=1 self.atbox = self.presLoc.index(a) self.presents[self.atbox].setTexture(self.textures[self.atbox]) def animate(self): if self.isMoving: flipbook_2(self.kiki,self.runframe) else: self.kiki.pose("go", 0) # parameters to drag back to the beginning def drag(self): if self.dragback: # adds star to the screen if they won if self.addstar == 1: self.starimage = OnscreenImage(image = 'textures/goldstar.png', pos = (-1.2+self.starLoc[self.TotalScore-1][0]*0.2, -0.8, -0.8+0.1*self.starLoc[self.TotalScore-1][1]),scale=0.1) self.starimage.setTransparency(TransparencyAttrib.MAlpha) self.addstar = -1 self.floater.setZ(1.0) self.dragtime+=60./self.framerate if self.dragtime < self.time_out: pos = self.kiki.getPos() step = [-pos[0]/(self.time_out-self.dragtime),-pos[1]/(self.time_out-self.dragtime)] self.kiki.setPos(pos[0]+step[0],pos[1]+step[1],1) flipbook_2(self.kiki,self.dragframe,loop=1,) else: # here is my code to end game... # elf.LastFiveSixCount if self.reversal == 0 and self.trial_num_phase == self.end_aq_after: self.GameOver = True elif self.reversal == 1 and self.trial_num_phase == self.end_rev_after: self.GameOver = True else: self.new_trial = True self.TrialScoreList.append(self.trialscore) if len(self.TrialScoreList) >= 6: self.TrialScoreLastFiveSix= self.TrialScoreList[-6:] self.LastFiveSixCount = self.TrialScoreLastFiveSix.count(1) elif len(self.TrialScoreList) == 5: self.TrialScoreLastFiveSix= self.TrialScoreList[-5:] self.LastFiveSixCount = self.TrialScoreLastFiveSix.count(1) if self.LastFiveSixCount == 5: self.reverse_now = True print("trial number", self.trial_no) print("trial score", self.trialscore) print("total trial score list", self.TrialScoreList) print("score list for last 6 trials", self.TrialScoreLastFiveSix) print("how many correct in last 6 trials", self.LastFiveSixCount) print("reverse now", self.reverse_now) print("running total", self.RunningTotal) print("self rev after", self.revafter) # starting each trial def init_trial(self): if self.reverse_now == True and self.reversal == 0: self.reversal = 1 # need to reset all of these variables back to zero!! self.RunningTotal = 0 self.TrialScoreList = [] self.TrialScoreLastFiveSix= [] self.LastFiveSixCount =0 self.trial_num_phase = 0 self.reverse_now = False self.correctbox = fluffle([i for i in range(3) if i != self.correctbox])[0] self.textures[-1] = self.tex5 elif self.reverse_now == True and self.reversal == 1: self.GameOver = True # if self.RunningTotal == self.revafter and self.reversal == 0: # self.reversal = 1 # self.RunningTotal = 0 # self.trial_num_phase = 0 # self.correctbox = fluffle([i for i in range(3) if i != self.correctbox])[0] # self.textures[-1] = self.tex5 #elif self.RunningTotal == self.revafter and self.reversal == 1: # self.GameOver = True self.camspinning = 0 self.camspin = False self.render.setLightOff(self.plnp) self.new_trial = False self.boxcam = False self.go = True self.goscale = 0 self.ReadyText = OnscreenText(text = "Ready..." , pos = (-100, -0.5), scale = 0.1*self.goscale) self.GoText = OnscreenText(text = "Go!" , pos = (-100, -0.5), scale = 0.1*self.goscale) self.floater.setZ(2.0) self.spin = 0 self.dragback = False self.dragtime = 0 self.trial_no += 1 self.trial_num_phase +=1 self.trialscore = 0 self.trial = [self.correctbox] self.pos = [0.,0.] self.kiki.setPos(0,0,1.) self.kiki.setH(0) self.presLoc = [0,1,2,3] self.canMove = True self.digging = False self.atbox = -1 self.addstar = -1 self.clouddisp = 1 self.presLoc = fluffle(self.presLoc) self.boxloca = [[-12.,-12.],[12.,-12.],[12.,12.],[-12.,12.]] if self.trial_no>0: self.presents[self.dug].reparentTo(self.render) self.dug = -1 for pres,loc in zip(self.presents,self.presLoc): pres.setPos(self.boxloca[loc][0],self.boxloca[loc][1],2.1) pres.setTexture(self.texgrey) if self.boxloca[loc][1] == -12: pres.setH(180) else: pres.setH(0) pres.currentframe = 0 pres.pose("go",0) self.visits = [0,0,0,0] # setting the keys for moving the character and digging def initkeys(self): self.keyMap = {"left": 0, "right": 0, "forward": 0,"back":0, "dig":0,"spin":0} self.accept("escape", sys.exit) self.accept("arrow_left", self.setKey, ["left", True]) self.accept("arrow_right", self.setKey, ["right", True]) self.accept("arrow_up", self.setKey, ["forward", True]) self.accept("arrow_down", self.setKey, ["back", True]) self.accept("d",self.setKey, ["dig",True]) self.accept("y",self.setKey, ["spin",True]) self.accept("arrow_left-up", self.setKey, ["left", False]) self.accept("arrow_right-up", self.setKey, ["right", False]) self.accept("arrow_up-up", self.setKey, ["forward", False]) self.accept("arrow_down-up", self.setKey, ["back", False]) self.accept("d-up",self.setKey, ["dig",False]) self.accept("y-up",self.setKey, ["spin",False]) def setKey(self, key, value): self.keyMap[key] = value def initgame(self): self.transition = Transitions(loader) self.getparameters() self.GameOver = False self.BlackScreen = 0 self.p_ID = self.b.get() self.p_age = self.d.get() self.p_gender = self.f.get() self.file = open('logs/Reversal3D_end30_5of6_logfile_'+str(self.p_ID)+'.txt', 'w') # added two extra columns to the log file self.file.write("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t" % ("pID","Age","Gender","TrialNumber","Reversal","Target", "Choice","Correct","TotalScore","RunningTotal", "Last6TrialsTotal", "TrialNumPhase", "Visits0","Visits1", "Visits2","Visits3","ResponseTime")) print "ID:", self.p_ID, "Gender:",self.p_gender,"Age:",self.p_age print "ID:", self.p_ID, "Gender:",self.p_gender,"Age:",self.p_age self.rungame = True self.TotalScore = 0 self.RunningTotal = 0 self.trial_no = -1 self.new_trial = True self.end_aq_after = 30 self.end_rev_after = 30 self.trial_num_phase = 0 self.reverse_now = False self.TrialScoreList = [] self.TrialScoreLastFiveSix= [] self.LastFiveSixCount = 0 # when starting a new trial, pick gender and kiki parameters self.new_trial = True if self.p_gender == "Male": self.kiki = CreateActor("Models/baseboy.x","textures/baseboy2.png",0,0,0,0) else: self.kiki = CreateActor("Models/kiki.x","textures/kiki.jpg",0,0,0,0) self.kiki.currentframe= 0 self.kiki.reparentTo(self.render) self.isTurning = False self.lag = 0 self.ScoreText = None # how often screen refreshes self.framerate = 30 globalClock.setMode(ClockObject.MLimited) globalClock.setFrameRate(self.framerate) self.frames = [int(round(i)) for i in np.arange(0,1200,60./self.framerate)] # creating the boxes self.present1 = CreateActor("Models/test.x","textures/presentgrey.png",0,0,0,0) self.present1.reparentTo(self.render) self.present2 = CreateActor("Models/test.x","textures/presentgrey.png",0,0,0,0) self.present2.reparentTo(self.render) self.present3 = CreateActor("Models/test.x","textures/presentgrey.png",0,0,0,0) self.present3.reparentTo(self.render) self.present4 = CreateActor("Models/test.x","textures/presentgrey.png",0,0,0,0) self.present4.reparentTo(self.render) self.presents = [self.present1,self.present2,self.present3,self.present4] self.texgrey = loader.loadTexture("textures/presentgrey.png") if self.boxcol == "A": self.tex1 = loader.loadTexture("textures/presentblue.png") self.tex2 = loader.loadTexture("textures/presentyellow.jpg") self.tex3 = loader.loadTexture("textures/presentpink.jpg") self.tex4 = loader.loadTexture("textures/presentgreen.png") self.tex5 = loader.loadTexture("textures/presentpurple.png") else: self.tex1 = loader.loadTexture("textures/presentbrown.jpg") self.tex2 = loader.loadTexture("textures/presentorange.png") self.tex3 = loader.loadTexture("textures/presentred.png") self.tex4 = loader.loadTexture("textures/presentgreys.png") self.tex5 = loader.loadTexture("textures/presentlightpurple.png") self.textures = [self.tex1,self.tex2,self.tex3,self.tex4] # making the star and positions self.star = self.loader.loadModel("Models/star.x") tex = loader.loadTexture("textures/gold_texture.jpg") self.star.setTexture(tex) self.star.setScale(self.starsize) self.star.setPos(0, 0, 3) # making the black cloud and their positions self.clouds = CreateActor("Models/clouds.x","textures/cotton.jpg",0,0,0,0) self.star.setScale(self.cloudsize) # setting up the room environment self.environ = self.loader.loadModel("Models/Room.x") self.environ.reparentTo(self.render) # setting the wall colors - note that Reversal task uses set "A" and # practice task uses set B if self.wallcol == "A": tex = loader.loadTexture("textures/arena.png") else: # set B tex = loader.loadTexture("textures/room2.png") self.environ.setTexture(tex) self.environ.setScale(2, 2, 2) self.environ.setPos(0, 0, 0) self.starLoc = [] for i in range(4): for j in range(10): self.starLoc.append([i,j]) self.floater = NodePath(PandaNode("floater")) self.floater.reparentTo(self.kiki) self.floater.setZ(2.0) self.angle = -2*np.pi*self.kiki.getH()/360 alight = AmbientLight('alight') alight.setColor(VBase4(2, 2, 2, 1)) alnp = render.attachNewNode(alight) render.setLight(alnp) self.plight = PointLight('plight') self.plight.setColor(VBase4(0, 0, 0, 0)) self.plnp = render.attachNewNode(self.plight) #animation frames: self.runframe = get_frames(1,40,self.framerate) self.digframe = get_frames(60,240,self.framerate) self.presentsframe = get_frames(0,180,self.framerate) self.winframe = get_frames(320,360,self.framerate) self.losingframe = get_frames(380,460,self.framerate) self.dragframe = get_frames(242,302,self.framerate) self.cloudsframe = get_frames(0,180,self.framerate) # this is the new way to randomize the correct box for each subject # this will also reset for reversal self.correctbox = fluffle([0,1,2])[0] #np.random.randint(0,3) self.reversal = 0 self.savelog = False # we don't have the joystick version # will always print error in console self.joystickon = 0 try: if joystick.get_count() > 0: self.joystickon = 1 self.joystick = joystick.Joystick(0) self.joystick.init() except: print "Joystick Error" self.joystickon = 0 # parameters from the menu.py GUI # can change any of these manually via the gui # note that we are using # view height 60 for distance # rev after 5 trials # neg feedback of smoke puff # box color A for reversal task, B for practice # wall colors A for reversal task, B for practice # spin is OFF for this task! def getparameters(self): with open("parameters.txt",'r') as f: params= [x.strip().split('\t') for x in f] self.viewheight = int(params[1][1]) self.change_dist = float(params[3][1]) self.time_out = float(params[4][1]) self.revafter = int(params[2][1]) self.outof = int(params[12][1]) self.negfeedbac = {"Smoke-puff":1,"None":0}[params[5][1]] sizes = {"Small":0.5, "Medium":1, "Large":2} self.cloudsize = sizes[params[7][1]] self.starsize = sizes[params[6][1]] self.boxcol = params[8][1] self.wallcol = params[9][1] self.camRot = params[10][1] self.LRSpin = params[11][1] # this is for moving the camera to follow the character around # note that we have spin turned off. def movecam(self): if self.camspin: self.camspinning += 1./10 self.camera.setPos(self.kiki.getX()+(10*np.sin(self.angle+self.camspinning)), self.kiki.getY() + 10*np.cos(self.angle+self.camspinning), self.viewheight) self.camera.lookAt(self.floater) elif self.camRot == "On": if self.isTurning: self.lag=0.9 elif self.lag > 0: self.lag-=(0.01)*(60./self.framerate) else: self.lag = 0 newangle = -2*np.pi*self.kiki.getH()/360 self.angle = newangle+(self.angle-newangle)*self.lag self.camera.setPos(self.kiki.getX()+(10*np.sin(self.angle)), self.kiki.getY() + 10*np.cos(self.angle),self.viewheight) i = self.camera.getPos()[0] j = self.camera.getPos()[1] if self.viewheight < 39: if self.camera.getPos()[0]>13: i = 13 if self.camera.getPos()[0]<-13: i = -13 if self.camera.getPos()[1]>13: j = 13 if self.camera.getPos()[1]<-13: j = -13 self.camera.setPos(i,j,self.camera.getPos()[2]) if self.boxcam == False: self.camera.lookAt(self.floater) else: self.camera.setPos(self.kiki.getX()+(10*np.sin(self.angle)), self.kiki.getY() + 10*np.cos(self.angle), self.viewheight) i = self.camera.getPos()[0] j = self.camera.getPos()[1] if self.camera.getPos()[0]>13: i = 13 if self.camera.getPos()[0]<-13: i = -13 if self.camera.getPos()[1]>13: j = 13 if self.camera.getPos()[1]<-13: j = -13 self.camera.setPos(i,j,self.camera.getPos()[2]) self.floater.setZ(2+self.spin/300.) self.camera.lookAt(self.floater) else: self.camera.setPos(self.kiki.getX(), self.kiki.getY()+0.1,self.viewheight) self.camera.lookAt(self.floater) def seconds(self,secs): return secs*self.framerate
class CameraBrowser(NodePath): def __init__(self, controls): NodePath.__init__(self, "CameraBrowser") self.reparentTo(render2d) self.controls = controls frameColor = (1, 1, 1, .95) # Generate 4 frames around the display region leftFrame = DirectFrame(frameSize=(-.98, -.96, -.98, .98), frameColor=frameColor, parent=self) rightFrame = DirectFrame(frameSize=(.96, .98, -.98, .98), frameColor=frameColor, parent=self) bottomFrame = DirectFrame(frameSize=(-.98, .98, -.98, -.96), frameColor=frameColor, parent=self) topFrame = DirectFrame(frameSize=(-.98, .98, .98, .96), frameColor=frameColor, parent=self) self.title = OnscreenText(parent=topFrame, pos=(-.6, .8), fg=(1, 1, 1, 1), text="", font=base.cogFont, scale=.16) self.titleCircle = OnscreenImage(image='data/titleCircle.png', parent=self.title, pos=(-.85, 0, .84), scale=.07) self.exitButton = DirectButton(text="Close", text_fg=(1, 1, 1, 1), scale=.07, pos=(0, 0, -.9), text_bg=(0, 0, 0, .75), text_font=base.cogFont, command=self.controls.request, extraArgs=['Flashlight']) self.titleCircle.setTransparency(1) def load(self): self.map = base.a2dBottomRight.attachNewNode( CardMaker("fnaf-map").generate()) texture = "phase_9/maps/tt_fnaf_map.png" if base.withinTTH else "data/fnafmap.png" self.map.setTexture(loader.loadTexture(texture)) self.map.setTransparency(1) self.map.setPos(self.map, (-1.25, 0, 0)) self.map.setScale(1.15) self.map.stash() self.cameras = [] for index, (pos, hpr, name) in enumerate(CameraPoints): self.createCamera(index, pos, hpr, name) self.__cameraIndex = 0 def setCamera(self, index): self.disableCurrentCamera() self.__cameraIndex = index self.enableCurrentCamera() def disableCurrentCamera(self): name, button, camNP = self.cameras[self.__cameraIndex] base.camera.reparentTo(render) base.camera.setPos(render, 0, 0, 0) button['state'] = DGG.NORMAL def enableCurrentCamera(self): name, button, camNP = self.cameras[self.__cameraIndex] base.camera.reparentTo(camNP) base.camera.setPos(camNP, 0, 30, -10) cleanName = name.replace(' ', '') cleanName = cleanName.replace('(', '') cleanName = cleanName.replace(')', '') messenger.send("cameraSeeing%s" % cleanName) button['state'] = DGG.DISABLED def createCamera(self, index, pos, hpr, name): camNP = render.attachNewNode(Camera('cam')) camNP.setPos(pos) camNP.setHpr(hpr) cleanName = name.replace(' ', '') cleanName = cleanName.replace('(', '') cleanName = cleanName.replace(')', '') pos = CameraButtonPos.get(cleanName) button = DirectFrame(parent=self.map, frameColor=(1, 1, 1, 0), frameSize=(-.16, .29, -.15, .15), pos=pos, scale=.2, state=DGG.NORMAL) button.bind(DGG.B1PRESS, lambda x: self.setCamera(index)) button.setTextureOff() self.cameras.append((name, button, camNP)) def blinkCircle(self, task): time = int(task.time) method = (self.titleCircle.hide, self.titleCircle.show)[time % 2] method() return task.cont def show(self): NodePath.show(self) self.exitButton.unstash() self.map.unstash() self.titleCircle.show() taskMgr.doMethodLater(1, self.blinkCircle, 'fnaf-camera-blinkCircle') self.enableCurrentCamera() def hide(self): NodePath.hide(self) self.exitButton.stash() if hasattr(self, 'map'): self.map.stash() self.disableCurrentCamera() taskMgr.remove('fnaf-camera-blinkCircle')
class InfoOverScreen: """ The popup window class """ def __init__(self, MainScreen, text=""): self.main_screen = MainScreen self._image = OnscreenImage(image=self.main_screen.image_path + "comm.png", pos=(0, 0, 0), parent=self.main_screen.gui_render_node, ) # image in front self._image.set_bin("fixed", 10) self._image.setTransparency(TransparencyAttrib.MAlpha) self._text = OnscreenText(text=text, align=TextNode.ALeft, mayChange=True, pos=self.main_screen.gimp_pos(210, 230), scale=(0.06, 0.08), fg=LVector4f(1, 1, 1, 1), parent=self._image, wordwrap=20, ) self._show = False self._image.hide() self._text.hide() def is_on_screen(self): """ @return: True if the popup is on screen. False otherwise """ return self._show def show(self, t=None): """ Shows the window @param t: a mute parameter allowing to call it in a doMethodLater """ self._show = True self._image.show() self._text.show() self.main_screen.update() def hide(self, t=None): """ Hides the window @param t: a mute parameter allowing to call it in a doMethodLater """ self._show = False self._image.hide() self._text.hide() self.main_screen.update() def set_text(self, text, end="\n\n... (Entrée pour continuer) ..."): """ Sets the text of the popup. @param text: the text @param end: the end text. """ self._text["text"] = text + end if self._show: self.main_screen.update()
def __init__(self): GameObject.__init__(self, Vec3(0, 0, 0), "Models/PandaChan/act_p3d_chan", { "stand" : "Models/PandaChan/a_p3d_chan_idle", "walk" : "Models/PandaChan/a_p3d_chan_run" }, 5, 10, "player") self.actor.getChild(0).setH(180) mask = BitMask32() mask.setBit(1) self.collider.node().setIntoCollideMask(mask) mask = BitMask32() mask.setBit(1) self.collider.node().setFromCollideMask(mask) base.pusher.addCollider(self.collider, self.actor) base.cTrav.addCollider(self.collider, base.pusher) self.lastMousePos = Vec2(0, 0) self.groundPlane = Plane(Vec3(0, 0, 1), Vec3(0, 0, 0)) self.ray = CollisionRay(0, 0, 0, 0, 1, 0) rayNode = CollisionNode("playerRay") rayNode.addSolid(self.ray) mask = BitMask32() mask.setBit(2) rayNode.setFromCollideMask(mask) mask = BitMask32() rayNode.setIntoCollideMask(mask) self.rayNodePath = render.attachNewNode(rayNode) self.rayQueue = CollisionHandlerQueue() base.cTrav.addCollider(self.rayNodePath, self.rayQueue) self.beamModel = loader.loadModel("Models/Misc/bambooLaser") self.beamModel.reparentTo(self.actor) self.beamModel.setZ(1.5) self.beamModel.setLightOff() self.beamModel.hide() self.beamHitModel = loader.loadModel("Models/Misc/bambooLaserHit") self.beamHitModel.reparentTo(render) self.beamHitModel.setZ(1.5) self.beamHitModel.setLightOff() self.beamHitModel.hide() self.beamHitPulseRate = 0.15 self.beamHitTimer = 0 self.damagePerSecond = -5.0 self.score = 0 self.scoreUI = OnscreenText(text = "0", pos = (-1.3, 0.825), mayChange = True, align = TextNode.ALeft, font = base.font) self.healthIcons = [] for i in range(self.maxHealth): icon = OnscreenImage(image = "UI/health.png", pos = (-1.275 + i*0.075, 0, 0.95), scale = 0.04) icon.setTransparency(True) self.healthIcons.append(icon) self.damageTakenModel = loader.loadModel("Models/Misc/playerHit") self.damageTakenModel.setLightOff() self.damageTakenModel.setZ(1.0) self.damageTakenModel.reparentTo(self.actor) self.damageTakenModel.hide() self.damageTakenModelTimer = 0 self.damageTakenModelDuration = 0.15 self.laserSoundNoHit = loader.loadSfx("Sounds/laserNoHit.ogg") self.laserSoundNoHit.setLoop(True) self.laserSoundHit = loader.loadSfx("Sounds/laserHit.ogg") self.laserSoundHit.setLoop(True) self.beamHitLight = PointLight("beamHitLight") self.beamHitLight.setColor(Vec4(0.1, 1.0, 0.2, 1)) self.beamHitLight.setAttenuation((1.0, 0.1, 0.5)) self.beamHitLightNodePath = render.attachNewNode(self.beamHitLight) self.hurtSound = loader.loadSfx("Sounds/FemaleDmgNoise.ogg") self.yVector = Vec2(0, 1) self.actor.loop("stand")
def show_image(self, path, **props): osi = OnscreenImage(image=path, **props) osi.setTransparency(TransparencyAttrib.MAlpha) self._hud.append(osi) return osi
class Player(object, DirectObject.DirectObject): def __init__(self): self.node = 0 #the player main node self.modelNode = 0 #the node of the actual model self.cNode = 0 #the player collision node attached to node self.cNodePath = 0 #node path to cNode self.contrail = ParticleEffect() self.contrail.setTransparency(TransparencyAttrib.MDual) self.contrail2 = ParticleEffect() self.contrail2.setTransparency(TransparencyAttrib.MDual) self.landing = False self.freeLook = False self.speed = 10 self.speedMax = 100 self.agility = 3 self.missileSpeed = 50 self.HP = 10 self.collisionHandler = CollisionHandlerEvent() # the collision handlers self.collisionHandlerQueue = CollisionHandlerQueue() self.zoom = -5 self self.textSpeed = OnscreenText(text = 'Speed: '+str(self.speed), pos = (-1.34, 0.95), scale = 0.07, fg=(1,1,1,1), bg=(0.2,0.2,0.2,0.4), align=TextNode.ALeft) self.textHP = OnscreenText(text = 'HP: '+str(self.HP), pos = (-1.33, 0.85), scale = 0.07, fg=(1,1,1,1), bg=(0.2,0.2,0.2,0.4), align=TextNode.ALeft) self.roll = 0 self.camHeight = 10 base.win.movePointer(0, base.win.getXSize()/2, base.win.getYSize()/2) self.myImage=OnscreenImage(image = 'cursor.png', pos = (0, 0, -0.02), scale=(0.05)) self.myImage.setTransparency(TransparencyAttrib.MAlpha) self.loadModel() self.addCamera() self.addEvents() self.addCollisions() self.addSound() self.moveTask = taskMgr.add(self.moveUpdateTask, 'move-task') self.mouseTask = taskMgr.add(self.mouseUpdateTask, 'mouse-task') self.zoomTaskPointer = taskMgr.add(self.zoomTask, 'zoom-task') ''' loadModel This will load all the visible stuff ''' def loadModel(self): """ make the nodepath for player """ self.node = NodePath('player') self.node.setPos(1000,1000,200) self.node.reparentTo(render) self.node.lookAt(0,0,200) self.modelNode = loader.loadModel('griffin') self.modelNode.reparentTo(self.node) self.modelNode.setScale(0.3) playerMaterial = Material() playerMaterial.setShininess(22.0) #Make this material shiny playerMaterial.setAmbient(VBase4(1,1,1,1)) playerMaterial.setSpecular(VBase4(0.7,0.7,0.7,0.7)) self.modelNode.setMaterial(playerMaterial) self.modelNode.setShaderAuto() self.aimNode = NodePath('aimNode') self.aimNode.reparentTo(self.node) self.aimNode.setPos(0,15,2) #self.contrail.loadConfig('media/contrail.ptf') #self.contrail.start(self.node,render) ''' addCamera camera setup ''' def addCamera(self): base.disableMouse() base.camera.reparentTo(self.node) base.camera.setPos(0,self.zoom,2) base.camera.lookAt(self.aimNode) ''' addEvents This will set up the events the class will accept ''' def addEvents(self): self.accept( "wheel_up" , self.evtSpeedUp ) self.accept( "wheel_down" , self.evtSpeedDown ) self.accept('mouse1',self.evtShoot) self.accept('hit',self.evtHit) self.accept('l',self.evtLand) self.accept('o',self.evtStart) self.accept('f',self.evtFreeLookON) self.accept('f-up',self.evtFreeLookOFF) self.accept('mouse3',self.evtBoostOn) self.accept("menuOpen", self.evtMenuOpen) self.accept("menuClosed", self.evtMenuClose) ''' addCollisions This will add a collision sphere for the player and a segment to check weather the ground is close/flat enough for landing ''' def addCollisions(self): self.cNode = CollisionNode('player') self.cNode.addSolid(CollisionSphere(0,0,0,2.3)) self.cNode.setFromCollideMask(BitMask32(0x1A)) self.cNode.setIntoCollideMask(BitMask32(0x4)) self.cNodePath = self.node.attachNewNode(self.cNode) #self.cNodePath.show() self.collisionHandler.addInPattern('hit') base.cTrav.addCollider(self.cNodePath, self.collisionHandler) # landing segment: self.landingCNodeSegment = CollisionNode('playerRay') self.landingCNodeSegment.addSolid(CollisionSegment(0, 0, 0, 0, 0, -20)) self.landingCNodeSegment.setIntoCollideMask(BitMask32.allOff()) self.landingCNodeSegment.setFromCollideMask(BitMask32(0x8)) self.landingCNodeSegmentPath = self.node.attachNewNode(self.landingCNodeSegment) #self.landingCNodeSegmentPath.show() base.cTrav.addCollider(self.landingCNodeSegmentPath, self.collisionHandlerQueue) ''' addSound adds the engine sound @TODO add more ''' def addSound(self): self.engineSound = loader.loadSfx("engine.mp3") self.engineSound.setLoop(True) self.engineSound.play() self.engineSound.setVolume(0.9) self.engineSound.setPlayRate(0) ''' deleteTask task which calls the destructor after a given time (after the explosion animation) ''' def deleteTask(self, task): self.__del__() return task.done ''' mouseUpdateTask This task will handle mouse movement and control the planes rotation. If free look is enabled, it will rotate the camera around the player. ''' def mouseUpdateTask(self,task): """ this task updates the mouse """ md = base.win.getPointer(0) x = md.getX() y = md.getY() deltaX = 0 deltaY = 0 if base.win.movePointer(0, base.win.getXSize()/2, base.win.getYSize()/2): deltaX = (x - base.win.getXSize()/2) *0.06 #* globalClock.getDt() *70 #* self.agility * (0.5+abs(self.roll)/50) deltaY = (y - base.win.getYSize()/2)*0.06 if deltaX > self.agility: deltaX = self.agility if deltaX < -self.agility: deltaX = -self.agility if deltaY > self.agility: deltaY = self.agility if deltaY < -self.agility: deltaY = -self.agility # don't move ship while in freelook mode if not self.freeLook: self.node.setH(self.node.getH() - deltaX) self.node.setP(self.node.getP() - deltaY) # don't move ship while in freelook mode if not self.freeLook: self.roll += deltaX self.camHeight += deltaY self.roll *= 0.95 #/ (globalClock.getDt() * 60)#* globalClock.getDt() * 700 self.camHeight *= 0.95 #* globalClock.getDt() * 700 if self.roll < -25 * self.speed/self.speedMax: self.roll = -25 * self.speed/self.speedMax if self.roll > 25 * self.speed/self.speedMax: self.roll = 25 * self.speed/self.speedMax self.node.setR(self.roll*3) base.camera.setZ(2-self.camHeight*0.5* self.speed/self.speedMax) base.camera.lookAt(self.aimNode) base.camera.setR(-self.roll*2) #base.camera.setY(-30+self.speed/10) #base.camera.setX(self.roll*0.5) # freelook mode: if self.freeLook: self.camRotH -= deltaX *3 self.camRotV -= deltaY *3 if self.camRotV < 1: self.camRotV = 1 if self.camRotV > 179: self.camRotV = 179 base.camera.setX( math.cos(math.radians(self.camRotH))*math.sin(math.radians(self.camRotV)) *30 ) base.camera.setY( math.sin(math.radians(self.camRotH))*math.sin(math.radians(self.camRotV)) *30 ) base.camera.setZ( math.cos(math.radians(self.camRotV)) *30 ) base.camera.lookAt(self.node) return task.cont ''' moveUpdateTask Will update players position depending on speed and direction ''' def moveUpdateTask(self,task): """ this task makes the player move """ # move where the keys set it self.node.setPos(self.node,Vec3(0,1.0*globalClock.getDt()*self.speed,0)) #self.node.setPos(self.node,self.strafe*globalClock.getDt()*self.speed) return task.cont def landTask(self,task): if self.collisionHandlerQueue.getNumEntries() == 0 and task.frame > 3: print 'to faar' self.landing = False self.evtFreeLookOFF() return task.done elif self.collisionHandlerQueue.getNumEntries() == 0: return task.cont self.collisionHandlerQueue.sortEntries() entry = self.collisionHandlerQueue.getEntry(0) if entry.getInto != self.cNode: n = entry.getSurfaceNormal(render) n.normalize() if n.getZ() < 0.8: print 'too steep' self.landing = False self.evtFreeLookOFF() return task.done self.cNode.setFromCollideMask(BitMask32(0x0)) self.cNode.setIntoCollideMask(BitMask32(0x0)) self.node.setZ(self.node.getZ()-0.05 ) if entry.getSurfacePoint(self.node).getZ() > -0.5: #self.landing = tr #self.evtFreeLookOFF() return task.done return task.cont def startTask(self,task): self.collisionHandlerQueue.sortEntries() entry = self.collisionHandlerQueue.getEntry(0) self.node.setZ(self.node.getZ()+0.05 ) if entry.getSurfacePoint(self.node).getZ() < -10: self.landing = False self.evtFreeLookOFF() self.cNode.setFromCollideMask(BitMask32(0x18)) self.cNode.setIntoCollideMask(BitMask32(0x4)) return task.done return task.cont ''' explode this will cause the plane to explode with a nice particle effect. ''' def explode(self): self.ignoreAll() self.cNode.setIntoCollideMask(BitMask32.allOff()) taskMgr.remove(self.moveTask) taskMgr.remove(self.mouseTask) taskMgr.remove(self.zoomTaskPointer) self.moveTask = 0 self.mouseTask = 0 if self.contrail != 0: self.contrail.cleanup() self.modelNode.hide() self.contrail = ParticleEffect() self.contrail.loadConfig('media/explosion.ptf') self.contrail.start(self.node) self.contrail.setLightOff() self.contrail2.cleanup() self.deleteTask = taskMgr.doMethodLater(4, self.deleteTask, 'delete task') ''' zoomTask will adjust camera position according to zoom factor specified in self.zoom in a smooth way. ''' def zoomTask(self, task): if base.camera.getY() != self.zoom and self.freeLook == False: base.camera.setY( base.camera.getY()+ (self.zoom- base.camera.getY())*globalClock.getDt()*2 ) return task.cont ''' evtBoostOn Will set most inputs to ignore, add a speed boost and an additional particle effect ''' def evtBoostOn(self): taskMgr.remove(self.mouseTask) self.ignore( "wheel_up") self.ignore( "wheel_down") self.ignore('mouse1') self.ignore('l') self.ignore('o') self.ignore('f') self.ignore('f-up') self.accept('mouse3-up',self.evtBoostOff) self.speed +=200 self.textSpeed.setText('Speed: '+str(self.speed)) self.contrail2.loadConfig('media/contrail-boost.ptf') self.contrail2.start(self.node) self.zoom = -25 self.evtFreeLookOFF() ''' evtBoostOff Will reactivate inputs, substract speed boost and stop the additional particle effect ''' def evtBoostOff(self): self.speed -=200 self.textSpeed.setText('Speed: '+str(self.speed)) self.ignore('mouse3-up') self.addEvents() self.mouseTask = taskMgr.add(self.mouseUpdateTask, 'mouse-task') #self.contrail.loadConfig('../../media/contrail.ptf') self.contrail2.softStop() self.zoom = -5-(self.speed/10) ''' evtHit This event will be called if the player gets hit by an object. It will reduce the HP by 1 each time we hit a missile. If HP reaches 0, the player will explode. If we hit an other object like a rock, the player will explode imidiatly ''' def evtHit(self, entry): if entry.getIntoNodePath().getParent().getTag("orign") != self.node.getName(): if entry.getIntoNodePath().getName() == "projectile": self.HP -= 1 self.textHP.setText('HP : '+str(self.HP)) if self.HP == 0: self.explode() else: self.explode() ''' evtFreeLookON Event that activates free look mode and therefore changes cam position ''' def evtFreeLookON(self): if self.landing == False: self.freeLook = True self.camRotH = 270 self.camRotV = 80 self.myImage.hide() ''' evtFreeLookOFF Event that deactivates free look mode and therefore changes cam position back to original ''' def evtFreeLookOFF(self): if self.landing == False: self.freeLook = False base.camera.setPos(0,-20,2) base.camera.lookAt(self.aimNode) self.myImage.show() ''' __del__ destructor will remove particle effect, tasks and the whole node ''' def __del__(self): self.ignoreAll() self.contrail.cleanup() base.camera.reparentTo(render) base.camera.setPos(2000,2000,800) base.camera.lookAt(0,0,0) if self.moveTask != 0: taskMgr.remove(self.moveTask) if self.mouseTask != 0: taskMgr.remove(self.mouseTask) self.node.removeNode() messenger.send( 'player-death' ) ''' evtShoot this event will launch a single missiles ''' def evtShoot(self): if self.landing: return 0 x = math.sin(math.radians(-self.node.getH())) *(self.missileSpeed+self.speed) y = math.cos(math.radians(-self.node.getH())) *(self.missileSpeed+self.speed) z = math.sin(math.radians(self.node.getP())) *(self.missileSpeed+self.speed) x *= math.cos(math.radians(self.node.getP())) y *= math.cos(math.radians(self.node.getP())) Projectile(self.node.getPos(), Point3(x,y,z), self.node.getHpr(), 'player') ''' evtSpeedUp Will be called if player wants to increase speed. - engine sound will become louder - camera will zoom out - speed display will be updated ''' def evtSpeedUp(self): if self.landing: return 0 self.speed += 5 self.engineSound.setPlayRate(self.engineSound.getPlayRate()+0.05) if self.speed > self.speedMax: self.speed = self.speedMax #self.engineSound.setVolume(1) self.engineSound.setPlayRate(1) self.zoom = -5-(self.speed/10) self.textSpeed.setText('Speed: '+str(self.speed)) ''' evtSpeedDown Will be called if player wants to decrease speed. - engine sound will become more silent - camera will zoom in - speed display will be updated ''' def evtSpeedDown(self): if self.landing: return 0 self.textSpeed.setText('Speed: '+str(self.speed)) self.speed -= 5 self.engineSound.setPlayRate(self.engineSound.getPlayRate()-0.05) if self.speed < 0: self.speed = 0 #self.engineSound.setVolume(0) self.engineSound.setPlayRate(0) self.zoom = -5-(self.speed/10) def evtLand(self): if self.speed != 0 or self.landing: return 0 self.evtFreeLookON() # landing will enable freelook mode self.landing = True self.node.setP(0) taskMgr.add(self.landTask, 'land-task') def evtStart(self): if not self.landing: return 0 taskMgr.add(self.startTask, 'start-task') def evtMenuOpen(self): """event that will be called if main menu is opened (esc)""" taskMgr.remove(self.mouseTask) taskMgr.remove(self.moveTask) self.myImage.hide() props = WindowProperties() props.setCursorHidden(0) base.win.requestProperties(props) def evtMenuClose(self): """event that will be called if main menu is closed (esc)""" #self.addEvents() props = WindowProperties() props.setCursorHidden(1) base.win.requestProperties(props) self.mouseTask = taskMgr.add(self.mouseUpdateTask, 'mouse-task') self.moveTask = taskMgr.add(self.moveUpdateTask, 'move-task') self.myImage.show()
class Jugador(DirectObject): #Les variables que tinguin un # son canviables, i les que tinguin ## depenen de la nau WIN_WIDTH = 800 # H_WIDTH = WIN_WIDTH / 2 WIN_HEIGHT = 600 # H_HEIGHT = WIN_HEIGHT / 2 CAM_FOV = 51. CAM_FOV_RAD = radians(CAM_FOV) / 2 CAM_FOV_RAD_TAN = tan(CAM_FOV_RAD) VEL_MAX_AVIO = 100 ## VEL_MIN_AVIO = 30 ## VEL_AVIO_RECTE = 40. ## VEL_TOMBA_AVIO = 90. ## VEL_COSTAT = 30. ## ACCELERACIO = 35 ## CAMERA_Y = -9 ## BALA_VEL_BASE = 500 ## QUIT_KEY = "escape" # ACCELERATE_KEY = "w" # DECELERATE_KEY = "s" # RIGHT_KEY = "d" # LEFT_KEY = "a" # CENTRA_RATA_KEY = "c" # SHOOT_KEYS = ["mouse1", "e"] # SHOOT_TIME = .15 ## def __init__(self, base, ini_pos=Point3(0, 100, 100), tipus="kamikaze", wwidth=None, wheight=None): DirectObject.__init__(self) if wwidth and wheight: self.WIN_WIDTH = wwidth self.H_WIDTH = self.WIN_WIDTH / 2 self.WIN_HEIGHT = wheight self.H_HEIGHT = self.WIN_HEIGHT / 2 self.keyMap = {"shoot": 0, "centerPointer": 0, "turn": 0} self.bulletClock = 0. self.overheatClock = 0. self.BALA_VEL = self.BALA_VEL_BASE + self.VEL_MIN_AVIO ambient = AmbientLight("alight") ambientNp = render.attachNewNode(ambient) ambient.setColor(VBase4(.3, .3, .3, 1.)) self.avio = render.attachNewNode("avio") self.avio.setHpr(randint(0, 359), randint(0, 359), randint(0, 359)) self.avio.setPos(ini_pos) self.avioR = self.avio.attachNewNode("avioDum2") if tipus == "kamikaze": self.modelAvio = base.loader.loadModel('prova/avio1blend') else: self.modelAvio = base.loader.loadModel('prova/avio1blend') self.modelAvio.reparentTo(self.avioR) self.avioVel = self.VEL_MIN_AVIO self.balaDreta = self.modelAvio.find("**/BalaDreta") self.balaEsquerra = self.modelAvio.find("**/BalaEsquerra") self.avio.setLight(ambientNp) self.avio.setAntialias(AntialiasAttrib.MMultisample) self.modelAvio.setColor(1, 1, 0, 1) self.modelAvio.setScale(.51) lightBales = AmbientLight('dlight') self.lightBalesNp = base.camera.attachNewNode(lightBales) self.lightBalesNp.setHpr(0, 0, 0) #-#-#-#-configuracio de camara base.disableMouse() #~ self.oobe() base.camera.reparentTo(self.avio) base.camera.setHpr(self.avio, 0, 0, 0) base.camera.setPos(self.avio, 0, self.CAMERA_Y, 1.5) base.camLens.setFov(self.CAM_FOV * (4. / 3.), self.CAM_FOV) self.mirilla2 = OnscreenImage(image="prova/textures/areatir2.png", parent=pixel2d) self.mirilla2.setScale(128) self.mirilla2.setTransparency(1) self.mirilla2.setPos(self.H_WIDTH, 0, -self.H_HEIGHT) self.mirilla = base.loader.loadModel("prova/textures/fixador.egg") self.mirilla.reparentTo(pixel2d) self.mirilla.setScale(64.) self.mirilla.setPos(0, 0, 0) self.mirilla.find('**/+SequenceNode').node().pose(0) self.cursorGirar = pixel2d.attachNewNode("cursorGirar") self.cursorGirarImage = OnscreenImage( image="prova/textures/fletxa.png", parent=self.cursorGirar) self.cursorGirarImage.setScale(16. / 2, 1., 32. / 2) self.cursorGirarImage.setPos(0, 0, 0) self.cursorGirarImage.setHpr(-90, 0, -90) self.cursorGirarImage.setTransparency(1) cursorGirarEffect = BillboardEffect.make(up_vector=Vec3(0, 0, 1), eye_relative=False, axial_rotate=False, offset=0., look_at=self.mirilla2, look_at_point=Point3(0, 0, 0)) self.cursorGirar.setEffect(cursorGirarEffect) self.overheats = [] for i in range(8): if i % 2 == 0: self.overheats.append( OnscreenImage(image="prova/textures/overheat1.png", parent=pixel2d)) else: self.overheats.append( OnscreenImage(image="prova/textures/overheat2.png", parent=pixel2d)) self.overheats[i].setScale(32., 1., 32.) self.overheats[i].setTransparency(1) self.overheats[i].hide() self.overheats[0].setPos(self.H_WIDTH + 36, 0, -self.H_HEIGHT + 36) self.overheats[0].setHpr(0, 0, 0) self.overheats[1].setPos(self.H_WIDTH + 36, 0, -self.H_HEIGHT + 36) self.overheats[1].setHpr(0, 0, 0) self.overheats[2].setPos(self.H_WIDTH + 36, 0, -self.H_HEIGHT - 36) self.overheats[2].setHpr(0, 0, 90) self.overheats[3].setPos(self.H_WIDTH + 36, 0, -self.H_HEIGHT - 36) self.overheats[3].setHpr(0, 0, 90) self.overheats[4].setPos(self.H_WIDTH - 36, 0, -self.H_HEIGHT - 36) self.overheats[4].setHpr(0, 0, 180) self.overheats[5].setPos(self.H_WIDTH - 36, 0, -self.H_HEIGHT - 36) self.overheats[5].setHpr(0, 0, 180) self.overheats[6].setPos(self.H_WIDTH - 36, 0, -self.H_HEIGHT + 36) self.overheats[6].setHpr(0, 0, -90) self.overheats[7].setPos(self.H_WIDTH - 36, 0, -self.H_HEIGHT + 36) self.overheats[7].setHpr(0, 0, -90) #PARTICLE SYSTEM SETUP self.particlesDummy = render.attachNewNode("particlesDummy") self.particlesDummy.setPosHprScale(0, 0, 0, 0, 0, 0, 1, 1, 1) self.particlesDummy.clearLight(render.find("dlight")) self.particlesDummy.setLight(self.lightBalesNp) base.enableParticles() #COLLISIONS base.cTrav = CollisionTraverser() base.cTrav.setRespectPrevTransform(True) self.balaCol = CollisionNode("balaCol") self.balaCol.setIntoCollideMask(BitMask32.allOff()) self.balaCol.setFromCollideMask(BitMask32(0x00000001)) balaColSolid = CollisionSphere(0., 0., 0., .2) self.balaCol.addSolid(balaColSolid) self.pickRay = CollisionNode("pickRay") self.pickRayNp = base.camera.attachNewNode(self.pickRay) self.pickRay.setIntoCollideMask(BitMask32.allOff()) self.pickRay.setFromCollideMask(BitMask32(0x00000002)) self.pickRayCHandler = CollisionHandlerQueue() self.mouseRay = CollisionRay() self.pickRay.addSolid(self.mouseRay) self.mouseRay.setOrigin(0, 0, 0) base.cTrav.addCollider(self.pickRayNp, self.pickRayCHandler) #~ self.nearPlane = CollisionNode("nearPlane") #~ self.nearPlaneNp = base.camera.attachNewNode(self.nearPlane) #~ base.camRays.setIntoCollideMask(BitMask32(0x00000001)) #~ self.nearPlaneNp.setPos(0, 1, 0) #~ self.nearPlaneColSolid = CollisionPlane(Plane(Vec3(0, -1, 0), Point3(0, 1, 0))) #~ self.nearPlane.addSolid(self.nearPlaneColSolid) def giraAvio(task): timeVar = globalClock.getDt() point = base.win.getPointer(0) pointerx = point.getX() pointery = point.getY() self.mouseRay.setFromLens(base.camNode, pointerx, pointery) #Cursors de la pantalla self.mirilla.setPos(pointerx, 0, -pointery) self.cursorGirar.setPos(pointerx, 0, -pointery) r = pow(abs(pointery - self.H_HEIGHT), 2) + pow( abs(pointerx - self.H_WIDTH), 2) if r > 8000: self.mirilla.hide() self.cursorGirar.show() else: self.mirilla.show() self.cursorGirar.hide() #3D pointerx = (pointerx - self.H_WIDTH) pointery = (pointery - self.H_HEIGHT) self.avioR.setX(self.avio, -pointerx * 3. / float(self.WIN_WIDTH)) self.avioR.setZ(self.avio, pointery * 3. / (self.WIN_HEIGHT)) self.avio.setH(self.avio, -pointerx * 256. / self.WIN_WIDTH * timeVar) self.avio.setP(self.avio, -pointery * 256. / self.WIN_HEIGHT * timeVar) self.avioR.setR(self.avio, pointerx / 10.) self.avioR.setP(self.avio, pointery / 70.) self.avioR.setH(self.avio, -pointerx / 50.) #~ self.avioVel += self.avioAcc*timeVar #~ self.avio.setPos(self.avio, self.avioVel*timeVar) return task.cont def propulsaAvio(acceleracio, task): self.avioVel += acceleracio * globalClock.getDt() if self.avioVel < self.VEL_MIN_AVIO: self.avioVel = self.VEL_MIN_AVIO elif self.avioVel > self.VEL_MAX_AVIO: self.avioVel = self.VEL_MAX_AVIO self.BALA_VEL = self.BALA_VEL_BASE + self.avioVel #MOSTRA LA VELOCITAT pos = float(self.avioVel - self.VEL_MIN_AVIO) / ( self.VEL_MAX_AVIO - self.VEL_MIN_AVIO) base.camera.setY(self.CAMERA_Y - pos * 4) #~ self.marcaVelocitat.setX(MARCAVEL_INI_X+pos*137.) return task.cont self.haCremat = False def mouAvio(task): timeVar = globalClock.getDt() self.avio.setPos(self.avio, 0, self.avioVel * timeVar, 0) if self.keyMap["shoot"] == 1: if self.bulletClock <= 0.: self.bulletClock = self.SHOOT_TIME if not self.haCremat: if self.overheatClock > 16: self.haCremat = True self.overheatClock = 18 else: self.overheatClock += self.SHOOT_TIME shoot() else: self.bulletClock -= timeVar else: self.bulletClock = 0. self.overheatClock -= timeVar if self.overheatClock < 16: self.haCremat = False if self.haCremat: self.overheatClock -= timeVar if self.overheatClock < 0: self.overheatClock = 0 elif self.overheatClock < 2: self.overheats[0].hide() elif self.overheatClock < 4: self.overheats[1].hide() self.overheats[0].show() elif self.overheatClock < 6: self.overheats[2].hide() self.overheats[1].show() elif self.overheatClock < 8: self.overheats[3].hide() self.overheats[2].show() elif self.overheatClock < 10: self.overheats[4].hide() self.overheats[3].show() elif self.overheatClock < 12: self.overheats[5].hide() self.overheats[4].show() elif self.overheatClock < 14: self.overheats[6].hide() self.overheats[5].show() self.overheats[7].hide() elif self.overheatClock < 16: self.overheats[7].hide() self.overheats[6].show() else: self.overheats[7].show() if self.keyMap["turn"] == 1: self.avio.setX(self.avio, -self.VEL_COSTAT * timeVar) elif self.keyMap["turn"] == -1: self.avio.setX(self.avio, self.VEL_COSTAT * timeVar) return task.cont def avioRecte(task): p = self.avio.getP(render) if p > 170 or p < -170: return task.cont timeVar = globalClock.getDt() roll = self.avio.getR(render) if roll < -self.VEL_AVIO_RECTE * timeVar: self.avio.setR(render, roll + self.VEL_AVIO_RECTE * timeVar) elif roll <= self.VEL_AVIO_RECTE * timeVar: self.avio.setR(render, 0) else: self.avio.setR(render, roll - self.VEL_AVIO_RECTE * timeVar) return task.cont self.balaPositiu = True def shoot(): bala = self.particlesDummy.attachNewNode("balaDummy") balaImage = OnscreenImage(image="prova/textures/bala.png", parent=bala) balaImage.setTransparency(1) balaImage.setScale(.1, 1., .2) balaImage.setBillboardPointEye() bala.setQuat(self.modelAvio.getQuat(render)) if self.balaPositiu: bala.setPos(self.balaDreta.getPos(render)) self.balaPositiu = False else: bala.setPos(self.balaEsquerra.getPos(render)) self.balaPositiu = True balaSphere = bala.attachNewNode(self.balaCol) balaColHandler = CollisionHandlerQueue() base.cTrav.addCollider(balaSphere, balaColHandler) #~ if type(self.shootPoint) == 'libpanda.Point3': #~ bala.lookAt(self.shootPoint) #~ else: bala.setH(bala, 180.) taskMgr.add( mouBala, "moubala", extraArgs=[bala, balaImage, self.BALA_VEL, balaColHandler], appendTask=True) def mouBala(bala, balaImage, vel, queue, task): if task.time > 3: balaImage.detachNode() expbala = ParticleEffect() expbala.reparentTo(self.particlesDummy) expbala.loadConfig('explosio.ptf') expbala.start(bala) taskMgr.doMethodLater(.25, suprimir, "suprimir", extraArgs=[bala, expbala]) return task.done if queue.getNumEntries() != 0: balaImage.detachNode() entry = queue.getEntry(0) bala.setPos(entry.getSurfacePoint(self.particlesDummy)) expbala = ParticleEffect() expbala.reparentTo(self.particlesDummy) expbala.loadConfig('explosio.ptf') expbala.start(bala) taskMgr.doMethodLater(.25, suprimir, "suprimir", extraArgs=[bala, expbala]) return task.done bala.setFluidPos(bala, 0, vel * globalClock.getDt(), 0) balaImage.setR(balaImage, 1000 * globalClock.getDt()) return task.cont def suprimir(bala, expbala): bala.detachNode() expbala.cleanup() expbala.detachNode() def setKey(key, value): self.keyMap[key] = value def centraRatoli(): point = base.win.getPointer(0) x = point.getX() y = point.getY() x -= self.H_WIDTH y -= self.H_HEIGHT r = sqrt(pow(abs(y), 2) + pow(abs(x), 2)) def centra(t, x, y): base.win.movePointer(0, trunc(x * t) + self.H_WIDTH, trunc(y * t) + self.H_HEIGHT) i = LerpFunc(centra, fromData=1., toData=0., duration=r / 700., blendType='easeInOut', extraArgs=[x, y], name="centraRata") i.start() self.previousPos = 0 self.interval01 = LerpPosHprInterval(self.modelAvio, .5, Point3(3, 0, 0), VBase3(0, 0, 70), Point3(0, 0, 0), VBase3(0, 0, 0), blendType='easeInOut') self.interval10 = LerpPosHprInterval(self.modelAvio, .5, Point3(0, 0, 0), VBase3(0, 0, 0), Point3(-3, 0, 0), VBase3(0, 0, -70), blendType='easeInOut') self.interval02 = LerpPosHprInterval(self.modelAvio, .5, Point3(-3, 0, 0), VBase3(0, 0, -70), Point3(0, 0, 0), VBase3(0, 0, 0), blendType='easeInOut') self.interval20 = LerpPosHprInterval(self.modelAvio, .5, Point3(0, 0, 0), VBase3(0, 0, 0), Point3(3, 0, 0), VBase3(0, 0, 70), blendType='easeInOut') self.interval12 = LerpPosHprInterval(self.modelAvio, 1., Point3(-3, 0, 0), VBase3(0, 0, -70), Point3(3, 0, 0), VBase3(0, 0, 70), blendType='easeInOut') self.interval21 = LerpPosHprInterval(self.modelAvio, 1., Point3(3, 0, 0), VBase3(0, 0, 70), Point3(-3, 0, 0), VBase3(0, 0, -70), blendType='easeInOut') def allIntervalsStopped(): if self.interval01.isStopped() and self.interval10.isStopped( ) and self.interval02.isStopped() and self.interval20.isStopped( ) and self.interval12.isStopped() and self.interval21.isStopped(): return True else: return False def tombaAvio(task): if self.keyMap[ "turn"] == 0 and self.previousPos != 0 and allIntervalsStopped( ): if self.previousPos == 1: self.interval10.start() else: self.interval20.start() self.previousPos = 0 elif self.keyMap[ "turn"] == -1 and self.previousPos != -1 and allIntervalsStopped( ): if self.previousPos == 0: self.interval01.start() else: self.interval21.start() self.previousPos = -1 elif self.keyMap[ "turn"] == 1 and self.previousPos != 1 and allIntervalsStopped( ): if self.previousPos == 0: self.interval02.start() else: self.interval12.start() self.previousPos = 1 return task.cont def anim1(): self.mirilla.find('**/+SequenceNode').node().setPlayRate(1.) self.mirilla.find('**/+SequenceNode').node().play(0, 3) def anim2(): self.mirilla.find('**/+SequenceNode').node().setPlayRate(1.) self.mirilla.find('**/+SequenceNode').node().play(4, 8) def anim3(): self.mirilla.find('**/+SequenceNode').node().setPlayRate(-1.) self.mirilla.find('**/+SequenceNode').node().play(0, 3) def anim4(): self.mirilla.find('**/+SequenceNode').node().setPlayRate(-1.) self.mirilla.find('**/+SequenceNode').node().play(3, 8) #events self.accept(self.QUIT_KEY, sysExit, [0]) self.accept(self.ACCELERATE_KEY, taskMgr.add, [ propulsaAvio, "propulsaAvio1", None, [self.ACCELERACIO], None, None, True ]) self.accept(self.ACCELERATE_KEY + "-up", taskMgr.remove, ["propulsaAvio1"]) self.accept(self.DECELERATE_KEY, taskMgr.add, [ propulsaAvio, "propulsaAvio2", None, [-self.ACCELERACIO], None, None, True ]) self.accept(self.DECELERATE_KEY + "-up", taskMgr.remove, ["propulsaAvio2"]) for key in self.SHOOT_KEYS: self.accept(key, setKey, ["shoot", 1]) self.accept(key + "-up", setKey, ["shoot", 0]) self.accept(self.RIGHT_KEY, setKey, ["turn", -1]) self.accept(self.LEFT_KEY, setKey, ["turn", 1]) self.accept(self.RIGHT_KEY + "-up", setKey, ["turn", 0]) self.accept(self.LEFT_KEY + "-up", setKey, ["turn", 0]) self.accept(self.CENTRA_RATA_KEY, centraRatoli) self.accept("n", anim1) self.accept("m", anim2) self.accept("v", anim3) self.accept("b", anim4) taskMgr.add(giraAvio, "GiraAvio") taskMgr.add(mouAvio, "MouAvio") taskMgr.add(avioRecte, "avioRecte") taskMgr.add(tombaAvio, "tombaAvio")