Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import viz
- import vizact
- import viztask
- import vizshape
- import vizcam
- import vizinput
- import vizinfo
- import math
- viz.setMultiSample(4)
- viz.fov(60)
- viz.phys.enable()
- ######HARDWARE SETUP######
- choice = vizinput.choose('Select a 3D display type:', ['None', 'Stereo Horizontal', 'Stereo Vertical', 'Anagyphic', 'Interlaced Horizontal', 'Interlaced Vertical'])
- fullscreen = vizinput.ask('Fullscreen?')
- name = vizinput.input('What is your name?')
- viz.message('Please put the sensors in the following order from left to right (with the port openings facing you) for the game to function correctly. Force, rotation, slider, magnetic.')
- if name == '': #If no name is supplied
- name = 'Player' #Make name = 'Player'
- ###LEVEL INSTRUCTIONS###
- INSTRUCTIONS = """
- Hi {} !
- You should stay in this area for as long as you want to.
- Play around with materials to get an understanding of their physical properties!
- Click on an object to select it and use the rotation sensor to move the camera around it.
- You can scroll the mouse wheel to change its material. This effects how the forces work on it!
- To get into the game, click the GREEN button!
- You can reset the objects by clicking the BLUE button!
- You can click to get rid of this message!""".format(name)
- INSTRUCTIONS1 = """
- Hi {} !
- The if the colour of a switch matches the colour of a door, that's the door it will open when it activates!
- A RED switch means activating that switch will take you to the next level!""".format(name)
- INSTRUCTIONS2 = """
- Hi {} !
- If you're having trouble getting through a gap, you can use the slider to make you cube bigger or smaller!
- If you're stuck somewhere. Click the BLUE button to reset your cubes.""".format(name)
- INSTRUCTIONS3 = """
- Hi {} !
- Some switches are HOLD switches.
- You'll have to keep a heavy cube on them, otherwise the door will close again!""".format(name)
- ##SENSOR INDEX###
- sensorTouch = 0
- sensorMagnetic = 3
- sensorSlider = 2
- sensorRotate = 1
- ###GLOBALS###
- global currentLevel
- global totalLevels
- global ground
- global levelEnvironment
- global count
- count = 0
- ground = viz.addChild('ground.osgb')
- levelEnvironment = viz.addChild('ground.osgb')
- currentLevel = 0
- totalLevels = 4
- debug = False
- mouseState = viz.mouse.getState()
- forceBox = viz.addChild('box.wrl') #The force box is an invisible box at the end of the arrow, used to get a directional vector from it, to an object
- forceBox.visible(viz.OFF)
- forceBox.disable(viz.PHYSICS)
- arrow = viz.addChild('arrow.fbx')
- arrow.setEuler([0, -90, 0])
- arrow.disable(viz.PHYSICS)
- arrow.visible(viz.OFF)
- viz.cam.setHandler(vizcam.KeyboardCamera(forward='w',backward='s', left='a',right='d',turnRight='e',turnLeft='q'))
- ####################Classes####################
- class MaterialObject:
- def __init__(self, position, material):
- self.material = material #Bind its material
- self.selected = False
- self.initPosition = position
- self.object = viz.add('box.wrl')
- self.object.color(255,255,255)
- self.object.setPosition(position)
- self.object.texture(self.material.texture)
- self.object_shape = self.object.collideBox()
- objectsCreated.append(self) #Add to our list of objects.
- def GetName(self):
- return self.material.name
- def GetPosition(self):
- return [self.object.getPosition()[0], self.object.getPosition()[1], self.object.getPosition()[2]]
- def SetPosition(self, position):
- self.object.setPosition(position)
- def DoPhysics(self):
- if (phidgetSensor.getIndex() == sensorTouch) and phidgetSensor.getValue() > 100.0: #If this is the correct sensor and it has a decent force on it
- if debug == True: #Print the velocity magnitude for debug reasons
- objectMagnitude = self.object.getVelocity()[0] + self.object.getVelocity()[1] + self.object.getVelocity()[2]
- if objectMagnitude > 0:
- objectMagnitude = math.fabs(math.sqrt(objectMagnitude))
- print objectMagnitude
- Finalforce = phidgetSensor.getValue() / self.material.density #Take the sensor value and divide by the material density
- direction = viz.Vector(self.object.getPosition(mode = viz.ABS_GLOBAL)) - viz.Vector(forceBox.getPosition(mode = viz.ABS_GLOBAL)) #Set the directional vector from the force box to the object
- direction *= Finalforce #Times this directional vector by the force to get our velocity vector
- self.object.applyForce(direction, 0) #Apply this velocity
- elif (phidgetSensor.getIndex() == sensorMagnetic) and phidgetSensor.getValue() != 500:
- if self.material.magnetic == True:
- view = viz.MainView
- #Phidget magnet sensor gives a lower or higher value dependant on the magnetic pole of the magnet.
- #We want the game to respond in the same way no matter which side of the magnet is near the sensor. The sensor rests at 500, so we get the absolute value of the difference, which will give us a range of 0-500.
- magnetValue = math.fabs(500 - phidgetSensor.getValue())
- Finalforce = magnetValue / self.material.density
- direction = viz.Vector(self.object.getPosition(mode = viz.ABS_GLOBAL)) - viz.Vector(forceBox.getPosition(mode = viz.ABS_GLOBAL))
- direction *= Finalforce
- self.object.applyForce(-direction, 0) #Make the object come towards the arrow. i.e. Negative direction- the opposite of the force sensor
- def SetScale(self):
- if phidgetSensor.getIndex() == sensorSlider:
- newValue = (phidgetSensor.getValue() * 0.001) + 0.5 #Clamp the value between 0.5 (50% size) and 1.5 (150% size)Make the centre of the slider be the original size of the box.
- self.object.setScale(newValue, newValue, newValue)
- def RotateCamera(self):
- if phidgetSensor.getIndex() == sensorRotate:
- view = viz.MainView
- newValue = (phidgetSensor.getValue() /2.777777) #Clamp the rotation to 0-360 degrees
- view.setEuler([newValue, 0, 0]) #Set the camera rotation to match the new value
- view.setPosition([self.object.getPosition()[0], self.object.getPosition()[1], self.object.getPosition()[2]]) #Move the camera to the objects position
- view.move(0, 15, -7) #Raise it above and away from the object
- arrow.visible(viz.ON) #Turn the arrow on
- arrow.setPosition([self.object.getPosition()[0], self.object.getPosition()[1], self.object.getPosition()[2]])
- arrow.setEuler([newValue, 0, 0]) #Set this to the same rotation as the camera.
- forceBox.setPosition([view.getPosition()[0], view.getPosition()[1] - 12, view.getPosition()[2]])
- forceBox.setEuler([newValue, 0, 0])
- viz.lookAt(self.GetPosition())
- def ChangeMaterial(self, newMaterial):
- self.material = newMaterial
- self.object.texture(newMaterial.texture)
- class MaterialType:
- def __init__(self, name, texture, density, magnetic):
- self.name = name
- self.texture = texture
- self.density = density
- self.magnetic = magnetic
- class Door:
- def __init__(self, position, rotation):
- self.object = vizshape.addBox(size = [4.5, 4.5, 0.5], pos=position)
- self.object.setEuler(rotation)
- self.object.collideMesh()
- doorsCreated.append(self)
- class FloorSwitch:
- def __init__(self, position, rotation, color, holdSwitch, linkedObject):
- self.object = viz.add('platform.osg')
- self.object.setPosition(position)
- self.object.setEuler(rotation)
- self.object.setScale(0.5, 0.5, 0.5)
- self.active = False
- self.isExitSwitch = False
- self.holdSwitch = holdSwitch
- self.object.collideMesh() #Give our switch a collision mesh so we can collide our objects with it
- self.object.color(color)
- self.collisionShape = vizshape.addCylinder(1.0, 1.5)
- self.collisionShape.setPosition(position)
- self.collisionShape.setEuler(rotation)
- self.collisionShape.collideMesh()
- self.collisionShape.disable(viz.CONTACTS) #We dont want our objects to make contact with this mesh, only go through it
- if debug:
- self.collisionShape.polyMode(viz.POLY_WIRE) #Make it wireframe for debug purposes
- else:
- self.collisionShape.disable(viz.RENDERING) #Otherwise just disable its renderer
- self.collisionShape.disable(viz.PICKING) #We dont want to click on this object so disable that too.
- if linkedObject == 0: #Effectively if this is an exit switch
- self.LinkToObject(0)
- self.isExitSwitch = True
- if linkedObject != 0: #Otherwise link it to its object
- if isinstance(linkedObject, Door):
- self.LinkToObject(linkedObject) #In this case a door
- linkedObject.object.color(color) #Set the door to be the switches colour
- switchesCreated.append(self) #Add the switch to our list
- def LinkToObject(self, linkedObject):
- self.myLinkedObject = linkedObject
- class LevelManager:
- def LoadLevel(self, levelNumber):
- self.ClearLevel() #Clear any previous level
- viztask.schedule( CheckDisplayMessage() ) #Display the appropirate message for the level
- global ground
- global levelEnvironment
- global currentLevel
- ####SET UP THE LEVELS####
- if levelNumber == 0:
- ground = viz.addChild('ground.osgb')
- ground.collidePlane()
- box1 = MaterialObject([0, 1, 0], material_aluminium)
- box1 = MaterialObject([4, 1 ,0], material_copper)
- door_1 = self.AddDoor([4.0, 1.0, 1.0], [0, 0, 0])
- switch_1 = self.AddFloorSwitch([4, 0.05, -1.5], [0, 0, 0], viz.GREEN, False, door_1)
- view.setPosition(8, 10, 0)
- view.lookAt([0, 0, 0])
- currentLevel = 0
- if levelNumber == 1:
- view.setPosition(8, 18, 0)
- view.lookAt([4, 0, 0])
- levelEnvironment = viz.addChild('Level1.fbx')
- ground = viz.addChild('ground.osgb')
- ground.collidePlane()
- levelEnvironment.collideMesh()
- Level1Door = self.AddDoor([0, 3, 4.1], [90, 0, 0])
- Level1Switch = self.AddFloorSwitch([5, 0.2, 5], [0, 0, 0], viz.GREEN, False, Level1Door)
- Level1ExitSwitch = self.AddExitSwitch([-3.5, 0.05, 0], [0, 0, 0], viz.RED)
- box = MaterialObject([5, 2, 0], material_aluminium)
- button_startGame.visible(viz.OFF)
- currentLevel = 1
- elif levelNumber == 2:
- view.setPosition(8, 20, 0)
- view.lookAt([4, 0, 0])
- levelEnvironment = viz.addChild('Level2.fbx')
- ground = viz.addChild('ground.osgb')
- ground.setScale([2.0, 2.0, 2.0])
- ground.collidePlane()
- levelEnvironment.collideMesh()
- Level2Door = self.AddDoor([8.8, 3, -4.5], [90, 0, 0])
- Level2Switch = self.AddFloorSwitch([5, 0.2, 5], [0, 0, 0], viz.GREEN, False, Level2Door)
- Level2Door2 = self.AddDoor([20, 3, -0.2], [90, 0, 0])
- Level2Switch2 = self.AddFloorSwitch([15, 0.05, 0], [0, 0, 0], viz.BLUE, False, Level2Door2)
- Level2ExitSwitch = self.AddExitSwitch([24, 0.05, 0], [0, 0, 0], viz.RED)
- box = MaterialObject([5, 2, -3], material_aluminium)
- button_startGame.visible(viz.OFF)
- currentLevel = 2
- elif levelNumber == 3:
- view.setPosition(8, 20, 0)
- view.lookAt([4, 0, 0])
- levelEnvironment = viz.addChild('Level3.fbx')
- ground = viz.addChild('ground.osgb')
- ground.setScale([2.0, 2.0, 2.0])
- ground.collidePlane()
- levelEnvironment.collideMesh()
- Level3Door = self.AddDoor([8.8, 3, -2.5], [90, 0, 0])
- Level3Switch = self.AddFloorSwitch([-5, 0.2, -2], [0, 0, 0], viz.GREEN, True, Level3Door)
- Level3ExitSwitch = self.AddExitSwitch([24, 0.05, 0], [0, 0, 0], viz.RED)
- box = MaterialObject([5, 2, -3], material_aluminium)
- box2 = MaterialObject([2, 2, -3], material_iron)
- button_startGame.visible(viz.OFF)
- currentLevel = 3
- return
- def AddPointLight(self, position, intensity):
- levelLight = viz.addLight()
- levelLight.enable()
- levelLight.position(position[0], position[1], position[2])
- levelLight.intensity(intensity)
- return levelLight
- def AddFloorSwitch(self, position, rotation, color, holdSwitch, linkedObject):
- levelFloorSwitch = FloorSwitch(position, rotation, color, holdSwitch, linkedObject)
- return levelFloorSwitch
- def AddExitSwitch(self, position, rotataion, color):
- exitLevelSwitch = FloorSwitch(position, rotataion, viz.RED, False, 0)
- return exitLevelSwitch
- def AddDoor(self, position, rotation):
- levelDoor = Door(position, rotation)
- return levelDoor
- def ClearLevel(self):
- global switchesCreated
- global objectsCreated
- global objectSelected
- global doorsCreated
- global levelEnvironment
- global ground
- if switchesCreated.count > 0:
- for switches in switchesCreated:
- switches.object.remove(children = True)
- switchesCreated= []
- if doorsCreated.count > 0:
- for doors in doorsCreated:
- doors.object.remove(children = True)
- doorsCreated= []
- if objectsCreated.count > 0:
- for objects in objectsCreated:
- objects.object.remove(children = True)
- objectsCreated= []
- objectsCreated = []
- if objectSelected != 0:
- objectSelected = 0
- ground.remove()
- levelEnvironment.remove()
- arrow.visible(viz.OFF)
- viz.clearCache(viz.NODE_CACHE)
- return
- #################### GAME SETUP####################
- tex_aluminium = viz.addTexture('aluminium.png') #Load in our textures
- tex_copper = viz.addTexture('copper.tga')
- tex_iron = viz.addTexture('iron.tga')
- tex_gold = viz.addTexture('gold.tga')
- myext = viz.add('myextension.dle') #Add in our plugin
- phidgetSensor = myext.addMySensor(speed = 180, radius = 1)
- view = viz.MainView
- view.move([0, 0, -7])
- viz.clearcolor(viz.SKYBLUE) #make the skybox blue
- textScreen = viz.addText('',viz.SCREEN)
- desPanel = vizinfo.InfoPanel(' ',align=viz.ALIGN_CENTER_TOP,fontSize=22,icon=False,key=None)
- objectsCreated = [] #Create the lists we need
- switchesCreated = []
- doorsCreated = []
- objectSelected = 0
- ###Define our material properties###
- material_aluminium = MaterialType('Aluminium', tex_aluminium, 300, False)
- material_iron = MaterialType('Iron', tex_iron, 600, True)
- material_copper = MaterialType('Copper', tex_copper, 700, False)
- material_gold = MaterialType('Gold', tex_gold, 5000, False)
- materials = [material_aluminium, material_copper, material_iron, material_gold] ##Add them to our list
- button_reset = viz.addButton() #Add a button.
- button_reset.setPosition(0.5,0.8) #Set its position.
- button_reset.setScale(3,3) #Scale it.
- button_startGame = viz.addButton()
- button_startGame.setPosition(0.2, 0.8)
- button_startGame.setScale(3, 3)
- button_startGame.color(viz.GREEN)
- #Define our level manager
- myLevelManager = LevelManager()
- ####################FUNCTIONS####################
- def onButton(obj,state):
- if obj == button_reset: #If its the reset button
- if state == viz.DOWN:
- for objects in objectsCreated:
- objects.SetPosition(objects.initPosition) #Move objects back to their original positions
- objects.selected = False #Remove selection
- objects.object.reset() #Remove any phyics on the object
- else:
- return
- elif obj == button_startGame: #if its the start game button
- myLevelManager.LoadLevel(1) #Load the first level
- def setClickedObject(pickedObject):
- global objectSelected
- if objectSelected != 0: #If we already have an object selected
- objectSelected.selected = False #Remove selection
- objectSelected = pickedObject #Get the clicked object
- objectSelected.selected = True #Set object to selected
- def updateScreenText():
- object = viz.pick() #get the node object we hovered over
- if object is None: #If there isn't anything there
- textScreen.message('') #Clear the text
- return
- if object.valid: #otherwise if there is
- for myObjects in objectsCreated: #Go through our list of objects
- if myObjects.object == object: #If this object matches an object in our list
- name = myObjects.GetName() #get the name of this material
- if mouseState & viz.MOUSEBUTTON_LEFT: #If we left click
- setClickedObject(myObjects) #Select it
- if myObjects.selected == True: #If its selected
- textScreen.color(viz.GREEN) #Set the text to green
- else:
- textScreen.color(viz.WHITE) #otherwise white
- textScreen.message(name) #Put the name of the object on our screen
- return
- else:
- name = ('') #If this object isnt in our list (i.e. a switch or a door) remove the name
- if 'name' not in locals():
- textScreen.message('')
- return
- else:
- textScreen.message(name)
- else:
- textScreen.message('')
- return
- def CheckSwitches():
- for switches in switchesCreated: #For each of our switches
- intersections = viz.phys.intersectNode(switches.collisionShape) #Get any and all intersections with its collide mesh
- if len(intersections) > 0: #If there are any
- for IntersectObject in intersections: #For each one
- for objectsInList in objectsCreated: #Go through our objects
- if objectsInList.object == IntersectObject: #If one of these objects matches the object that has intersected the node
- if objectsInList.material.density > 4999: #if this object is heavy enough
- switches.active = True #Activate the switch
- if switches.holdSwitch == True and switches.active == False:
- switches.myLinkedObject.object.enable(viz.RENDERING) #Remove the door by disabling its renderer
- switches.myLinkedObject.object.enable(viz.PHYSICS) #And disabling its physics so we don't collide with it anymore
- if switches.active: #If any of the switches are active
- if switches.myLinkedObject == 0: #If this switch is an exit level switch (i.e its linked object == 0)
- global currentLevel #get the current level global
- currentLevel += 1 #Add 1 onto it for the next level
- if currentLevel is not totalLevels: #If this number is the last level
- myLevelManager.LoadLevel(currentLevel) #load the next level
- else:
- myLevelManager.LoadLevel(0) #Otherwise if we have completed the final level, load the original level
- elif switches.myLinkedObject != 0: #otherwise if this is a regular door switch
- switches.myLinkedObject.object.disable(viz.RENDERING) #Remove the door by disabling its renderer
- switches.myLinkedObject.object.disable(viz.PHYSICS) #And disabling its physics so we don't collide with it anymore
- switches.active = False #Deactivate the switch
- def ChangeMaterialControl(dir):
- global objectSelected
- if objectSelected != 0: #if there's an object selected
- for index, currentMaterial in enumerate(materials): #Go through all of our materials
- if index == materials.index(objectSelected.material): #If the index matches our current material
- if dir > 0: #if mouse wheel up
- if index == len(materials) - 1: #If at the end of the list
- objectSelected.ChangeMaterial(materials[0]) #Change it to the first material in the list
- break
- else:
- objectSelected.ChangeMaterial(materials[index + 1]) #Otherwise go up to the next material in the list
- break
- elif dir < 0: #if mouse wheel down
- if index == 0: # If at the start of the list
- objectSelected.ChangeMaterial(materials[-1]) #Go down a material
- break
- else:
- objectSelected.ChangeMaterial(materials[index - 1]) #otherwise go to the last material in the list
- break
- def DisplayMessage(message):
- panel = vizinfo.InfoPanel(message,align=viz.ALIGN_CENTER,fontSize=22,icon=False,key=None) #Add the level instructions
- yield viztask.waitMouseDown(viz.MOUSEBUTTON_LEFT) #Remove it at a mouse click
- panel.remove()
- def CheckDisplayMessage():
- global currentLevel
- if currentLevel == 0:
- yield DisplayMessage(INSTRUCTIONS)
- elif currentLevel == 1:
- yield DisplayMessage(INSTRUCTIONS1)
- elif currentLevel == 2:
- yield DisplayMessage(INSTRUCTIONS2)
- elif currentLevel == 3:
- yield DisplayMessage(INSTRUCTIONS3)
- def updateDescriptionText():
- desPanel.visible(viz.OFF)
- global objectSelected
- if objectSelected != 0:
- desPanel.visible(viz.ON)
- name = objectSelected.GetName()
- if name == 'Aluminium':
- message = """Aluminium is a VERY LIGHT metal. It is very easy to move around! It is NOT MAGNETIC."""
- elif name == 'Iron':
- message = """Iron(Fe) is HEAVY metal. You might not be able to move it just by yourself, luckily Iron is MAGNETIC!"""
- elif name == 'Copper':
- message = """Copper(Cu) is a HEAVY metal. It's heavier than IRON, but not as heavy as GOLD. You might be able to wobble it, but it's NOT MAGNETIC."""
- elif name == 'Gold':
- message = """Gold(Au) is a VERY HEAVY metal. You probably won't able to move it, and it's NOT MAGNETIC. It can help you activate those switches!"""
- if name is not None:
- desPanel.setText(message)
- ####################STARTING THE GAME####################
- if choice == 0:
- if fullscreen == 1:
- viz.go(viz.FULLSCREEN | viz.EMBEDDED)
- else:
- viz.go(viz.EMBEDDED)
- elif choice == 1:
- if fullscreen == 1:
- viz.go(viz.STEREO_HORZ | viz.FULLSCREEN | viz.EMBEDDED)
- else:
- viz.go(viz.STEREO_HORZ | viz.EMBEDDED)
- elif choice == 2:
- if fullscreen == 1:
- viz.go(viz.STEREO_VERT | viz.FULLSCREEN | viz.EMBEDDED)
- else:
- viz.go(viz.STEREO_VERT | viz.EMBEDDED)
- elif choice == 3:
- if fullscreen == 1:
- viz.go(viz.ANAGLYPHIC | viz.FULLSCREEN | viz.EMBEDDED)
- else:
- viz.go(viz.ANAGLYPHIC | viz.EMBEDDED)
- elif choice == 4:
- if fullscreen == 1:
- viz.go(viz.INTERLACE_HORZ | viz.FULLSCREEN | viz.EMBEDDED)
- else:
- viz.go(viz.INTERLACE_HORZ | viz.EMBEDDED)
- elif choice == 5:
- if fullscreen == 1:
- viz.go(viz.INTERLACE_VERT | viz.FULLSCREEN | viz.EMBEDDED)
- else:
- viz.go(viz.INTERLACE_VERT | viz.EMBEDDED)
- myLevelManager.LoadLevel(0) #Load the first level
- ####MAIN LOOP#####
- while not viz.done():
- mouseState = viz.mouse.getState() #Get the mouse location and state
- if objectSelected != 0: #if we have an object selected
- objectSelected.RotateCamera() #Rotate the camera
- objectSelected.DoPhysics() #Activate the physics
- objectSelected.SetScale() #Set the scale
- viz.callback(viz.MOUSEWHEEL_EVENT, ChangeMaterialControl) #Check if we move the mouse wheel
- CheckSwitches() #Check all our switches
- updateScreenText() #Update the text on screen
- updateDescriptionText() #Update the material description
- viz.callback(viz.BUTTON_EVENT,onButton) #Check the button presses
- viz.frame() #Go the next frame
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement