Code: Select all
import sys
import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject
from direct.showbase.InputStateGlobal import inputState
from panda3d.core import *
from panda3d.bullet import *
#from GameObject import *
class Game(DirectObject):
def __init__(self):
base.setBackgroundColor(0.5, 0.5, 0.5, 1)
base.setFrameRateMeter(True)
base.cam.setPos(0, 0, 32)
base.cam.setP(-90)
base.cam.lookAt(0, 0, 0)
# Light
aLight = AmbientLight('ambientLight')
aLight.setColor(Vec4(0.5, 0.5, 0.5, 1))
aLightNP = render.attachNewNode(aLight)
dLight = DirectionalLight('directionalLight')
dLight.setDirection(Vec3(1, 1, -1))
dLight.setColor(Vec4(1, 1, 1, 1))
dLightNP = render.attachNewNode(dLight)
render.clearLight()
render.setLight(aLightNP)
render.setLight(dLightNP)
# Task
taskMgr.add(self.update, 'updateWorld')
# defines input vars
self.wsad = {"w" : False, "s" : False, "a" : False, "d" : False}
self.arrows = {"arrow_up" : False, "arrow_down" : False, "arrow_left" : False, "arrow_right" : False}
# updates input vars
for i in self.wsad:
self.accept(i, self.updateKeyMap, [i, True])
self.accept(i + "-up", self.updateKeyMap, [i, False])
for i in self.arrows:
self.accept(i, self.updateKeyMap, [i, True])
self.accept(i + "-up", self.updateKeyMap, [i, False])
# Physics
self.setup()
def update(self, task):
dt = globalClock.getDt()
# update input forces for each box that existes
self.updateBox(dt, self.box[0], self.wsad, 0.2)
self.updateBox(dt, self.box[1], self.arrows, 0.2)
self.world.doPhysics(dt, 5, 1.0/180.0)
return task.cont
def updateKeyMap(self, controlName, controlState):
self.wsad[controlName] = controlState
self.arrows[controlName] = controlState
def setup(self):
self.worldNP = render.attachNewNode('World')
self.world = BulletWorld()
self.world.setGravity(Vec3(0, 0, -9.81))
# Ground (static)
shape = BulletPlaneShape(Vec3(0, 0, 1), 1)
self.groundNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Ground'))
self.groundNP.node().addShape(shape)
self.groundNP.setPos(0, 0, -2)
self.groundNP.setCollideMask(BitMask32.allOn())
self.world.attachRigidBody(self.groundNP.node())
# creates a list of adressable boxes and balls
self.box = []
self.ball = []
self.createBox(4,0,0)
self.createBox(-4,0,0)
self.createBall(0,0,0)
def createBox(self, x, y, z):
# Box (dynamic)
shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5))
boxNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Box'))
boxNP.node().setMass(1.0)
boxNP.node().addShape(shape)
boxNP.setPos(x, y, z)
#self.boxNP.setScale(2, 1, 0.5)
boxNP.setCollideMask(BitMask32.allOn())
#self.boxNP.node().setDeactivationEnabled(False)
self.world.attachRigidBody(boxNP.node())
visualNP = loader.loadModel('Models/Box/plainbox.egg')
visualNP.clearModelNodes()
visualNP.reparentTo(boxNP)
self.box.append(boxNP)
def updateBox(self, dt, NP, keys, speed):
force = Vec3(0, 0, 0)
torque = Vec3(0, 0, 0)
k=list(keys.keys())
if keys[k[0]]:
force.setY(speed)
if keys[k[1]]:
force.setY(-speed)
if keys[k[2]]:
force.setX(-speed)
if keys[k[3]]:
force.setX(speed)
force *= 30.0
torque *= 10.0
force = render.getRelativeVector(NP, force)
torque = render.getRelativeVector(NP, torque)
NP.node().setActive(True)
NP.node().applyCentralForce(force)
NP.node().applyTorque(torque)
def createBall(self, x, y, z):
# Ball (dynamic)
shape = BulletSphereShape(1)
ballNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Ball'))
ballNP.node().setMass(1.0)
ballNP.node().addShape(shape)
ballNP.setPos(x, y, z)
#self.ballNP.setScale(2, 1, 0.5)
ballNP.setCollideMask(BitMask32.allOn())
#self.ballNP.node().setDeactivationEnabled(False)
self.world.attachRigidBody(ballNP.node())
visualNP = loader.loadModel('Models/Ball/ball.egg')
visualNP.clearModelNodes()
visualNP.reparentTo(ballNP)
self.ball.append(ballNP)
game = Game()
run()