/
Tut-Simple-FPS.py
160 lines (144 loc) · 5.61 KB
/
Tut-Simple-FPS.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
"""
awsd - movement
space - jump
mouse - look around
"""
import direct.directbase.DirectStart
from pandac.PandaModules import *
from direct.gui.OnscreenText import OnscreenText
import sys
class FPS(object):
"""
This is a very simple FPS like -
a building block of any game i guess
"""
def __init__(self):
""" create a FPS type game """
self.initCollision()
self.loadLevel()
self.initPlayer()
base.accept( "escape" , sys.exit)
base.disableMouse()
OnscreenText(text="Simple FPS Movement", style=1, fg=(1,1,1,1),
pos=(1.3,-0.95), align=TextNode.ARight, scale = .07)
OnscreenText(text=__doc__, style=1, fg=(1,1,1,1),
pos=(-1.3, 0.95), align=TextNode.ALeft, scale = .05)
def initCollision(self):
""" create the collision system """
base.cTrav = CollisionTraverser()
base.pusher = CollisionHandlerPusher()
def loadLevel(self):
""" load the self.level
must have
<Group> *something* {
<Collide> { Polyset keep descend }
in the egg file
"""
self.level = loader.loadModel('level.egg')
self.level.reparentTo(render)
self.level.setTwoSided(True)
def initPlayer(self):
""" loads the player and creates all the controls for him"""
self.node = Player()
class Player(object):
"""
Player is the main actor in the fps game
"""
speed = 50
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
def __init__(self):
""" inits the player """
self.loadModel()
self.setUpCamera()
self.createCollisions()
self.attachControls()
# init mouse update task
taskMgr.add(self.mouseUpdate, 'mouse-task')
taskMgr.add(self.moveUpdate, 'move-task')
taskMgr.add(self.jumpUpdate, 'jump-task')
def loadModel(self):
""" make the nodepath for player """
self.node = NodePath('player')
self.node.reparentTo(render)
self.node.setPos(0,0,2)
self.node.setScale(.05)
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)
def createCollisions(self):
""" create a collision solid and ray for the player """
cn = CollisionNode('player')
cn.addSolid(CollisionSphere(0,0,0,3))
solid = self.node.attachNewNode(cn)
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,-.2)
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)
self.nodeGroundHandler = CollisionHandlerQueue()
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])
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] )
def mouseUpdate(self,task):
""" this task updates the mouse """
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)
return task.cont
def moveUpdate(self,task):
""" this task makes the player move """
# move where the keys set it
self.node.setPos(self.node,self.walk*globalClock.getDt()*self.speed)
self.node.setPos(self.node,self.strafe*globalClock.getDt()*self.speed)
return task.cont
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)
z = entry.getSurfacePoint(render).getZ()
if z > highestZ and entry.getIntoNode().getName() == "Cube":
highestZ = z
# gravity effects and jumps
self.node.setZ(self.node.getZ()+self.jump*globalClock.getDt())
self.jump -= 1*globalClock.getDt()
if highestZ > self.node.getZ()-.3:
self.jump = 0
self.node.setZ(highestZ+.3)
if self.readyToJump:
self.jump = 1
return task.cont
FPS()
run()