class Sphere(GameObject):
	def __init__(self, world, parent, color, pos, dir, radius, density, posParent=None):
		GameObject.__init__(self, world)

		self.node = parent.attachNewNode("")
		if posParent == None:
			self.node.setPos(*pos)
		else:
			self.node.setPos(posParent, *pos)
		self.node.setColor(*color)
		self.node.setScale(radius)
		self.node.lookAt(self.node, *dir)
		self.parent = parent

		self.color = color
		self.scale = radius

		self.model = loader.loadModel("models/smiley.egg")
		self.model.reparentTo(self.node)

		self.mass = OdeMass()
		self.mass.setSphere(density, radius)
		self.body = OdeBody(world.world)
		self.body.setMass(self.mass)
		self.body.setPosition(self.node.getPos())
		self.body.setQuaternion(self.node.getQuat())
		self.body.setData(self)
		self.geom = OdeSphereGeom(world.space, radius)
		self.geom.setBody(self.body)
		world.space.setSurfaceType(self.geom, world.surfaces["sphere"])

	def onCollision(self, otherBody, entry):
		if otherBody.isEmpty(): # Collision on a wall
			geom = entry.getContactGeom(0)
			Ripple(self.parent, self.color, geom.getPos(), geom.getNormal() * -1, self.scale * 2.5)
class Sphere(GameObject):
    def __init__(self,
                 world,
                 parent,
                 color,
                 pos,
                 dir,
                 radius,
                 density,
                 posParent=None):
        GameObject.__init__(self, world)

        self.node = parent.attachNewNode("")
        if posParent == None:
            self.node.setPos(*pos)
        else:
            self.node.setPos(posParent, *pos)
        self.node.setColor(*color)
        self.node.setScale(radius)
        self.node.lookAt(self.node, *dir)
        self.parent = parent

        self.color = color
        self.scale = radius

        self.model = loader.loadModel("models/smiley.egg")
        self.model.reparentTo(self.node)

        self.mass = OdeMass()
        self.mass.setSphere(density, radius)
        self.body = OdeBody(world.world)
        self.body.setMass(self.mass)
        self.body.setPosition(self.node.getPos())
        self.body.setQuaternion(self.node.getQuat())
        self.body.setData(self)
        self.geom = OdeSphereGeom(world.space, radius)
        self.geom.setBody(self.body)
        world.space.setSurfaceType(self.geom, world.surfaces["sphere"])

    def onCollision(self, otherBody, entry):
        if otherBody.isEmpty():  # Collision on a wall
            geom = entry.getContactGeom(0)
            Ripple(self.parent, self.color, geom.getPos(),
                   geom.getNormal() * -1, self.scale * 2.5)
Exemplo n.º 3
0
class Box(GameObject):
	disableGracePeriod = 20
	
	def __init__(self, world, parent, color, pos, dir, size, density, unglueThreshold=None, shatterLimit=None, shatterThreshold=None):
		GameObject.__init__(self, world)

		if unglueThreshold == None: unglueThreshold = 20
		if shatterLimit == None: shatterLimit = 0
		if shatterThreshold == None: shatterThreshold = 30

		self.size = size
		self.density = density
		self.dir = dir
		self.parent = parent
		self.color = color = makeVec4Color(color)
		
		self.node = parent.attachNewNode("")
		self.node.setPos(*pos)
		self.node.setColorScale(color)
		self.node.setScale(*size)
		self.node.lookAt(self.node, *dir)

		self.model = loader.loadModel("models/box.egg")
		self.model.reparentTo(self.node)
		self.model.setScale(2.0)
		self.model.setPos(-1.0, -1.0, -1.0)

		self.applyTexture()

		self.mass = OdeMass()
		self.mass.setBox(density, Vec3(*size) * 2)
		self.body = OdeBody(world.world)
		self.body.setMass(self.mass)
		self.body.setPosition(self.node.getPos())
		self.body.setQuaternion(self.node.getQuat())
		self.body.setData(self)
		self.geom = OdeBoxGeom(world.space, Vec3(*size) * 2.0)
		self.geom.setBody(self.body)
		world.space.setSurfaceType(self.geom, world.surfaces["box"])

		# Adjust collision bitmasks.
		self.geom.setCategoryBits(GameObject.bitmaskBox)
		self.geom.setCollideBits(GameObject.bitmaskAll & ~GameObject.bitmaskTileGlued)

		# Tile, cement and shatter variables.
		self.tiles = []
		self.cements = []
		self.disableCount = 0
		self.unglueThreshold = unglueThreshold
		self.shatterLimit = shatterLimit
		self.shatterThreshold = shatterThreshold

	def applyTexture(self):
		self.texture = loader.loadTexture("media/brick_wall.tga")
		self.texture.setWrapU(Texture.WMRepeat)
		self.texture.setWrapV(Texture.WMRepeat)
		self.model.setTexture(self.texture, 1)
		self.model.setTexScale(TextureStage.getDefault(), max(self.size[0], self.size[1]), self.size[2])

	def addTile(self, tile):
		if tile not in self.tiles:
			self.tiles.append(tile)

	def removeTile(self, tile):
		if tile in self.tiles:
			self.tiles.remove(tile)

	def addCement(self, cement):
		if cement not in self.cements:
			self.cements.append(cement)

	def removeCement(self, cement):
		if cement in self.cements:
			self.cements.remove(cement)

	def destroy(self):
		for tile in self.tiles:
			tile.unglue()
		for cement in self.cements:
			cement.destroy()
		GameObject.destroy(self)

	def makeTiles(self, xNeg=False, xPos=False, yNeg=False, yPos=False, zNeg=False, zPos=False, thickness=0.1, unglueThreshold=None, shatterLimit=None, shatterThreshold=None):
		if xNeg: Tile(self, self.color, (-1,0,0), thickness, self.density, unglueThreshold, shatterLimit, shatterThreshold)
		if xPos: Tile(self, self.color, ( 1,0,0), thickness, self.density, unglueThreshold, shatterLimit, shatterThreshold)
		if yNeg: Tile(self, self.color, (0,-1,0), thickness, self.density, unglueThreshold, shatterLimit, shatterThreshold)
		if yPos: Tile(self, self.color, (0, 1,0), thickness, self.density, unglueThreshold, shatterLimit, shatterThreshold)
		if zNeg: Tile(self, self.color, (0,0,-1), thickness, self.density, unglueThreshold, shatterLimit, shatterThreshold)
		if zPos: Tile(self, self.color, (0,0, 1), thickness, self.density, unglueThreshold, shatterLimit, shatterThreshold)

	def onCollision(self, otherBody, entry):
		if otherBody.isEmpty():
			return
		self.disableCount = 0
		speed = otherBody.getData().body.getLinearVel()
		#if otherBody.getData().__class__ == Bullet: print speed.length(), self.shatterThreshold, self.shatterLimit #######
		if self.active and speed.length() >= self.shatterThreshold and self.shatterLimit > 0:
			adj = otherBody.getData().body.getMass().getMagnitude() / self.body.getMass().getMagnitude()
			speedMag = speed.length() * adj
			speedBase = ((speed * adj) + (self.body.getLinearVel() * 2) / 3)
			self.shatter(speedMag, speedBase)

	def shatter(self, speedMag, speedBase):
		#print 'box shatter' #########
		self.destroy()
		taskMgr.add(self.spawnTask, "box-spawn", extraArgs=[speedMag, speedBase])

		# Graphic (camera shake) and sound effects
		self.world.game.cameraHandler.shake((0,0,2), 0.1)
		sound = base.loader.loadSfx("media/shatter.wav")
		sound.setVolume(1.5)
		sound.play()

	def spawnTask(self, speedMag, speedBase):
		pos = self.node.getPos()
		size = Vec3(self.size) / 2
		w = 1
		for i in [-w, w]:
			for j in [-w, w]:
				for k in [-w, w]:
					box = Box(self.world, self.parent, self.color,
						(pos[0] + (i * size[0]), pos[1] + (j * size[1]), pos[2] + (k * size[2])),
						self.dir, size, self.density, self.unglueThreshold, self.shatterLimit - 1, self.shatterThreshold * 1)
					speed = (speedBase * (1.5 + random())) + (Vec3(i,j,k) * speedMag * (1 + random()))
					speed = speed / 2.0
					box.body.setLinearVel(speed)
					box.body.setAngularVel(speedMag * random(), speedMag * random(), speedMag * random())
					taskMgr.add(box.disableOnStopTask, "box-disableOnStop")

	def disableOnStopTask(self, task):
		if self.body.getLinearVel().length() > 0.1 or self.body.getAngularVel().length() > 0.1:
			self.disableCount = 0
			return task.cont
		elif self.disableCount < Box.disableGracePeriod:
			self.disableCount += 1
			return task.cont
		else:
			self.visibleAfterDestroy = True
			if DEBUG: self.node.setColorScale(1.0, 2.0, 1.0, 0.5)
			self.destroy()
			return task.done
Exemplo n.º 4
0
class Bullet(GameObject):
	lifetime = 120.0

	def __init__(self, world, parent, color, pos, dir, radius, density, posParent=None):
		GameObject.__init__(self, world)

		self.color = makeVec4Color(color)
		self.scale = radius
		self.collisionCount = 0

		diameter = 2 * radius
		length = 1.815 * diameter

		self.node = parent.attachNewNode("")
		if posParent == None:
			self.node.setPos(*pos)
		else:
			self.node.setPos(posParent, *pos)
		self.node.setColorScale(self.color)
		self.node.setTransparency(TransparencyAttrib.MAlpha)
		self.node.setScale(radius)
		self.node.lookAt(self.node, *dir)
		self.node.setHpr(self.node.getHpr() + Vec3(0, 270, 0))

		self.model = loader.loadModel("models/bullet.egg")
		self.model.reparentTo(self.node)
		self.model.setPos(-0.1, -0.1, 0.15)
		self.model.setScale(0.4)

		self.mass = OdeMass()
		self.mass.setCylinder(density, 3, radius, length)
		self.body = OdeBody(world.world)
		self.body.setMass(self.mass)
		self.body.setPosition(self.node.getPos())
		self.body.setQuaternion(self.node.getQuat())
		self.body.setData(self)
		self.body.setGravityMode(False)
		self.geom = OdeCylinderGeom(world.space, radius, length)
		self.geom.setBody(self.body)
		world.space.setSurfaceType(self.geom, world.surfaces["bullet"])

		# Adjust collision bitmasks.
		self.geom.setCategoryBits(GameObject.bitmaskBullet)
		self.geom.setCollideBits(GameObject.bitmaskAll & ~GameObject.bitmaskCharacter)

		# Keep the bullet hidden for a split second so it doesn't appear too close to the camera.
		self.node.hide()
		taskMgr.doMethodLater(0.1, self.showTask, 'show-bullet')

	def onCollision(self, otherBody, entry):
		self.body.setGravityMode(True)

		# Dissipate energy based on collision impact.
		factor = 1.0 - (min(entry.getContactGeom(0).getDepth(), 0.8) * 0.7)
		factor = min(factor, 0.98)
		base.taskMgr.doMethodLater(0.05, self.dissipateTask, "bullet-dissipate", extraArgs=[factor])
		
		# Reduce the lifespan.
		self.collisionCount += 1
		if self.collisionCount == 25:
			self.life = Bullet.lifetime
			taskMgr.add(self.fadeTask, "bullet-fade")
				
	def dissipateTask(self, factor):
		self.dissipate(factor)

	def fadeTask(self, task):
		if self.life > 0:
			self.life -= 1
			self.node.setAlphaScale(4.0 * self.life / Bullet.lifetime)
			return task.cont
		else:
			self.destroy()
			return task.done

	def showTask(self, task):
		if self.node != None:
			self.node.show()
Exemplo n.º 5
0
class Character(GameObject):	
	def __init__(self, world):
		GameObject.__init__(self, world)

		# Set the speed parameters
		self.vel = Vec3(0, 0, 0)
		self.strafespeed = 20.0
		self.forwardspeed = 32.0
		self.backspeed = 24.0
		self.jumpspeed = 20
		self.wasJumping = False

		# Set character dimensions
		self.size = (4.0, 3.0, 10.0)
		self.eyeHeight = 9.0
		self.offset = Point3(0, 0, self.eyeHeight - (self.size[2]/2))

		# Create character node
		self.node = base.render.attachNewNode("character")
		self.node.setPos(0, 0, self.eyeHeight)
		self.node.lookAt(0, 1, self.eyeHeight)

		# Create physics representation
		self.mass = OdeMass()
		self.mass.setBox(50, *self.size)
		self.body = OdeBody(world.world)
		self.body.setMass(self.mass)
		self.updatePhysicsFromPos()
		self.body.setData(self)
		self.geom = OdeBoxGeom(world.space, Vec3(*self.size))
		self.geom.setBody(self.body)
		world.space.setSurfaceType(self.geom, world.surfaces["box"])

		# Adjust collision bitmasks.
		self.geom.setCategoryBits(GameObject.bitmaskCharacter)
		self.geom.setCollideBits(GameObject.bitmaskAll & ~GameObject.bitmaskBullet)

		# Setup event handling
		self.keys = [0, 0, 0, 0, 0]
		self.setupKeys()
		base.taskMgr.add(self.moveTask, "character-move")

		# Create footsteps sound
		self.footstepsSound = base.loader.loadSfx("media/footsteps.wav")
		self.footstepsSound.setLoop(1)
		self.footsteps = SoundWrapper(self.footstepsSound)

		# Create other sounds.
		self.jumpSound = base.loader.loadSfx("media/jump_start.wav")
		self.landSound = base.loader.loadSfx("media/jump_fall.wav")

	def updatePosFromPhysics(self):
		self.node.setPos(render, self.body.getPosition() + self.offset)
		self.body.setAngularVel(0, 0, 0)

	def updatePhysicsFromPos(self):
		self.body.setPosition(self.node.getPos() - self.offset)
		self.body.setQuaternion(self.node.getQuat())

	def getDir(self):
		return base.render.getRelativeVector(self.node, (0, 1, 0))

	def moveTo(self, pos):
		self.node.setPos(pos)
		self.updatePhysicsFromPos()

	def recoil(self, mag):
		vel = self.body.getLinearVel()
		diff = self.getDir() * mag
		
		# Limit recoil
		if sign(vel[0]) != sign(diff[0]) and abs(vel[0]) > 15: diff[0] = 0
		if sign(vel[1]) != sign(diff[1]) and abs(vel[1]) > 15: diff[1] = 0
		diff[2] = 0

		self.body.setLinearVel(vel - diff)

	def jump(self):
		vel = self.body.getLinearVel()
		self.body.setLinearVel(vel[0], vel[1], vel[2] + self.jumpspeed)
		self.jumpSound.play()

	def isJumping(self):
		return abs(self.body.getLinearVel()[2]) > 0.05

	def setKey(self, button, value):
		self.keys[button] = value

	def setupKeys(self):
		base.accept("w", self.setKey, [0, 1]) #forward
		base.accept("s", self.setKey, [1, 1]) #back
		base.accept("a", self.setKey, [2, 1]) #strafe left
		base.accept("d", self.setKey, [3, 1]) #strafe right
		base.accept("space", self.setKey, [4, 1]) #jump
		base.accept("w-up", self.setKey, [0, 0])
		base.accept("s-up", self.setKey, [1, 0])
		base.accept("a-up", self.setKey, [2, 0])
		base.accept("d-up", self.setKey, [3, 0])
		base.accept("space-up", self.setKey, [4, 0])

	def moveTask(self, task):
		# Initialize variables
		elapsed = globalClock.getDt()
		x = 0.0
		y = 0.0
		jumping = self.isJumping()

		# Calculate movement vector.
		if self.keys[0] != 0:
			y = self.forwardspeed
		if self.keys[1] != 0:
			y = -self.backspeed
		if self.keys[2] != 0:
			x = -self.strafespeed
		if self.keys[3] != 0:
			x = self.strafespeed
		self.vel = Vec3(x, y, 0)
		self.vel *= elapsed

		# Move the character along the ground.
		hpr = self.node.getHpr()
		self.node.setP(0)
		self.node.setR(0)
		self.node.setPos(self.node, self.vel)
		self.updatePhysicsFromPos()
		self.node.setHpr(hpr)

		# Play landing sound (if applicable).
		if self.wasJumping and not jumping:
			pass #Landing detection not working.
			#self.landSound.play()

		# Jump (if applicable).
		if self.keys[4] and not jumping:
			self.jump()
		self.wasJumping = jumping

		# Play footsteps if walking.
		if not jumping and (self.keys[0] != 0 or self.keys[1] != 0 or self.keys[2] != 0 or self.keys[3] != 0):
			self.footsteps.resume()
		else:
			self.footsteps.pause()

		return task.cont
Exemplo n.º 6
0
class Character(GameObject):
    def __init__(self, world):
        GameObject.__init__(self, world)

        # Set the speed parameters
        self.vel = Vec3(0, 0, 0)
        self.strafespeed = 20.0
        self.forwardspeed = 32.0
        self.backspeed = 24.0
        self.jumpspeed = 20
        self.wasJumping = False

        # Set character dimensions
        self.size = (4.0, 3.0, 10.0)
        self.eyeHeight = 9.0
        self.offset = Point3(0, 0, self.eyeHeight - (self.size[2] / 2))

        # Create character node
        self.node = base.render.attachNewNode("character")
        self.node.setPos(0, 0, self.eyeHeight)
        self.node.lookAt(0, 1, self.eyeHeight)

        # Create physics representation
        self.mass = OdeMass()
        self.mass.setBox(50, *self.size)
        self.body = OdeBody(world.world)
        self.body.setMass(self.mass)
        self.updatePhysicsFromPos()
        self.body.setData(self)
        self.geom = OdeBoxGeom(world.space, Vec3(*self.size))
        self.geom.setBody(self.body)
        world.space.setSurfaceType(self.geom, world.surfaces["box"])

        # Adjust collision bitmasks.
        self.geom.setCategoryBits(GameObject.bitmaskCharacter)
        self.geom.setCollideBits(GameObject.bitmaskAll & ~GameObject.bitmaskBullet)

        # Setup event handling
        self.keys = [0, 0, 0, 0, 0]
        self.setupKeys()
        base.taskMgr.add(self.moveTask, "character-move")

        # Create footsteps sound
        self.footstepsSound = base.loader.loadSfx("media/footsteps.wav")
        self.footstepsSound.setLoop(1)
        self.footsteps = SoundWrapper(self.footstepsSound)

        # Create other sounds.
        self.jumpSound = base.loader.loadSfx("media/jump_start.wav")
        self.landSound = base.loader.loadSfx("media/jump_fall.wav")

    def updatePosFromPhysics(self):
        self.node.setPos(render, self.body.getPosition() + self.offset)
        self.body.setAngularVel(0, 0, 0)

    def updatePhysicsFromPos(self):
        self.body.setPosition(self.node.getPos() - self.offset)
        self.body.setQuaternion(self.node.getQuat())

    def getDir(self):
        return base.render.getRelativeVector(self.node, (0, 1, 0))

    def moveTo(self, pos):
        self.node.setPos(pos)
        self.updatePhysicsFromPos()

    def recoil(self, mag):
        vel = self.body.getLinearVel()
        diff = self.getDir() * mag

        # Limit recoil
        if sign(vel[0]) != sign(diff[0]) and abs(vel[0]) > 15:
            diff[0] = 0
        if sign(vel[1]) != sign(diff[1]) and abs(vel[1]) > 15:
            diff[1] = 0
        diff[2] = 0

        self.body.setLinearVel(vel - diff)

    def jump(self):
        vel = self.body.getLinearVel()
        self.body.setLinearVel(vel[0], vel[1], vel[2] + self.jumpspeed)
        self.jumpSound.play()

    def isJumping(self):
        return abs(self.body.getLinearVel()[2]) > 0.05

    def setKey(self, button, value):
        self.keys[button] = value

    def setupKeys(self):
        base.accept("w", self.setKey, [0, 1])  # forward
        base.accept("s", self.setKey, [1, 1])  # back
        base.accept("a", self.setKey, [2, 1])  # strafe left
        base.accept("d", self.setKey, [3, 1])  # strafe right
        base.accept("space", self.setKey, [4, 1])  # jump
        base.accept("w-up", self.setKey, [0, 0])
        base.accept("s-up", self.setKey, [1, 0])
        base.accept("a-up", self.setKey, [2, 0])
        base.accept("d-up", self.setKey, [3, 0])
        base.accept("space-up", self.setKey, [4, 0])

    def moveTask(self, task):
        # Initialize variables
        elapsed = globalClock.getDt()
        x = 0.0
        y = 0.0
        jumping = self.isJumping()

        # Calculate movement vector.
        if self.keys[0] != 0:
            y = self.forwardspeed
        if self.keys[1] != 0:
            y = -self.backspeed
        if self.keys[2] != 0:
            x = -self.strafespeed
        if self.keys[3] != 0:
            x = self.strafespeed
        self.vel = Vec3(x, y, 0)
        self.vel *= elapsed

        # Move the character along the ground.
        hpr = self.node.getHpr()
        self.node.setP(0)
        self.node.setR(0)
        self.node.setPos(self.node, self.vel)
        self.updatePhysicsFromPos()
        self.node.setHpr(hpr)

        # Play landing sound (if applicable).
        if self.wasJumping and not jumping:
            pass  # Landing detection not working.
            # self.landSound.play()

            # Jump (if applicable).
        if self.keys[4] and not jumping:
            self.jump()
        self.wasJumping = jumping

        # Play footsteps if walking.
        if not jumping and (self.keys[0] != 0 or self.keys[1] != 0 or self.keys[2] != 0 or self.keys[3] != 0):
            self.footsteps.resume()
        else:
            self.footsteps.pause()

        return task.cont