Opening door
Blitz3D Forums/Blitz3D Programming/Opening door
| ||
Not really a programming question just some general advice/recommendation wanted. How do you guys make your doors open? (and don't say with the door knob! lol) I guess there are two ways: 1. Create the whole door in your 3d package and animate it in the 3d package also, and then just call the animation function in your game. 2. Create the door frame and door seperately with no animation. Then animate the static models actually in your Blitz3D code (ie using MoveEntity/ RotateEntity or something fancier if you wish) So my question is what method do people use, or is there another way people do this? Cheers |
| ||
That depends on how you want it to open, I mean 'when' you want it to open. Do you want the door to slide aside when the player or other unit moves near it (in which case I'd build the animation into the door model and simply turn collisions off for the door when it is open)? Or do you want the player to have to walk up to it and collide with it - in which case a single blitz3d entity used combined with rotate/moveentity commands may be used. If you do it in your 3d package you can have a lot of nice effects when the door opens - particularly if it is a fancy sci fi door with pipes and twisty bits that rotate and disconnect which would be quite difficult I would imagine to perform with simply move/rotate entity commands. If you are going for the traditional rpg door as seen in Morrowind then I guess rotateentity/moveentity should be pretty easy to implement. It also makes collisions easier as blitz doesn't handle sphere->poly collisions very well against animated entities (I think it only tests against the position of the mesh based on the first frame of animation meaning.) |
| ||
I use 2. Each door has a start and end position, plus a start and end rotation...I set these attributes in Gile[s]. This allows doors to open by rotating (like normal doors) or moving (like sliding doors) or a combination of both. A variable that goes between 0.0 and 1.0 is used to determine where the door currently is in regard to the start/end rotation/position and is also used to trigger opening/closing sounds. The door also has 2 speed parameters so all doors can open/close at different speeds...useful for something like a portcullis door to open it slowly but drop it quickly. Be sure that when you model your door you pay attention to the origin point 0,0,0 since this is what the door will rotate around. |
| ||
The following is how I do doors that hinge on one side, and open by swinging, and also for portcullis that go up and down. These doors/portcullis are being created inside B3D with no external meshes. The textures (ie t_door, t_port, etc) I use are just freebie royalty-free things, which you can get off the web at any number of sites. The variable EastWest is for whether the door should align itself in an East-West direction, or a North-South direction Yeah, it's a bit more code, but it works. Then, when someone "activates" the door/portcullis, I just run the animation that captured the movement (ie rotate or up-down). Finally, here's some code that I use to "activate" the door/portcullis (I click on the object in question). If it's within a certain range, ie within arm's reach, then the animation is run. Notice that I just use a negative value to run the animation "backwards" to close the doors. There may be a few extra code snippets in the folowing, so if you have any questions, post me.Type entity ;a type to tell us what entity category we're looking at Field parent Field entity Field child Field kind ;wall, portcullis, door, fountian Field state ;closed=1, opened=2 ; Field del ;True/False, i.e. flag to delete this object Field seq End Type .createdoor e.entity = New entity ;create a new instance of the entity type variable e\parent=CreatePivot() e\entity=CreateCube(e\parent) NameEntity e\entity,"Door" EntityPickMode e\entity,2 PositionMesh e\entity,1,1,1 ;move "door" so that it hinges on left side ScaleMesh e\entity,1.6,1.8,.125 ;reshape cube to look like door (flatten, etc) EntityTexture e\entity,t_door ;paint the door to look like one EntityType e\entity,2 If EastWest=False Then RotateEntity e\entity,0,90,0 epitch= EntityPitch(e\entity) eyaw = EntityYaw(e\entity) eroll = EntityRoll(e\entity) For frame=1 To 45 TurnEntity e\entity,0,2.0,0 ;turn door on its hinges SetAnimKey e\entity,frame Next e\seq = AddAnimSeq(e\entity,frame-1) ;minus 1 because For-Next loops end 1 too many e\kind = door e\state = closed RotateEntity e\entity,epitch,eyaw,eroll ;undo the positioning done by the animation Return .createdoorframe e.entity = New entity ;create a new instance of the entity type variable e\entity=CreateCube() ;store entity handle in the Type variable NameEntity e\entity,"Door Frame" ScaleMesh e\entity,0.2,2.0,0.4 ;reshape it into a doorpost column PositionMesh e\entity,0,.5,0 EntityPickMode e\entity,2 topframe = CreateCube(e\entity) ScaleMesh topframe,1.6,0.2,0.4 PositionMesh topframe,1.8,2.3,0 doorframe2 = CopyMesh(e\entity,e\entity) ;copy the doorpost column PositionMesh doorframe2,3.6,0,0 AddMesh topframe,e\entity AddMesh doorframe2,e\entity EntityTexture e\entity,t_stone ;paint doorframe with concrete pic EntityType e\entity,2 FreeEntity topframe FreeEntity doorframe2 Return .createportcullis ;for now, just re-using code for vertical door opening Const slatspace#=.291 e.entity = New entity ;create a new instance of the entity type variable e\parent=CreatePivot() e\entity=CreateCube(e\parent) NameEntity e\entity,"Portcullis" ScaleMesh e\entity,.16,1.8,.05 ;reshape cube to look like port slat (flatten, etc) PositionMesh e\entity,.4,1.8,.1 ;move "portcullis" EntityPickMode e\entity,2 ; EntityTexture e\entity,t_port ;paint the port slat to look like one bar1=CreateCube(e\entity) ScaleMesh bar1,1.6,.16,.05 PositionMesh bar1,1.6,3.2,0 ; EntityTexture bar1,t_port ;paint the port slat to look like one bar2=CreateCube(e\entity) ScaleMesh bar2,1.6,.16,.05 PositionMesh bar2,1.6,3.2-slatspace*2,0 ; EntityTexture bar2,t_port ;paint the port slat to look like one bar3=CreateCube(e\entity) ScaleMesh bar3,1.6,.16,.05 PositionMesh bar3,1.6,3.2-slatspace*4,0 ; EntityTexture bar3,t_port ;paint the port slat to look like one bar4=CreateCube(e\entity) ScaleMesh bar4,1.6,.16,.05 PositionMesh bar4,1.6,3.2-slatspace*6,0 ; EntityTexture bar4,t_port ;paint the port slat to look like one bar5=CreateCube(e\entity) ScaleMesh bar5,1.6,.16,.05 PositionMesh bar5,1.6,3.2-slatspace*8,0 ; EntityTexture bar5,t_port ;paint the port slat to look like one bar6=CreateCube(e\entity) ScaleMesh bar6,1.6,.16,.05 PositionMesh bar6,1.6,3.2-slatspace*10,0 ; EntityTexture bar6,t_port ;paint the port slat to look like one slat1=CreateCube(e\entity) ScaleMesh slat1,.16,1.8,.05 ;reshape cube to look like port slat (flatten, etc) PositionMesh slat1,.4+slatspace*2,1.8,.1 ;move "portcullis" ; EntityTexture slat1,t_port ;paint the port slat to look like one slat2=CreateCube(e\entity) ScaleMesh slat2,.16,1.8,.05 ;reshape cube to look like port slat (flatten, etc) PositionMesh slat2,.4+slatspace*4,1.8,.1 ;move "portcullis" ; EntityTexture slat2,t_port ;paint the port slat to look like one slat3=CreateCube(e\entity) ScaleMesh slat3,.16,1.8,.05 ;reshape cube to look like port slat (flatten, etc) PositionMesh slat3,.4+slatspace*6,1.8,.1 ;move "portcullis" ; EntityTexture slat3,t_port ;paint the port slat to look like one slat4=CreateCube(e\entity) ScaleMesh slat4,.16,1.8,.05 ;reshape cube to look like port slat (flatten, etc) PositionMesh slat4,.4+slatspace*8,1.8,.1 ;move "portcullis" ; EntityTexture slat4,t_port ;paint the port slat to look like one AddMesh bar1,e\entity : FreeEntity bar1 AddMesh bar2,e\entity : FreeEntity bar2 AddMesh bar3,e\entity : FreeEntity bar3 AddMesh bar4,e\entity : FreeEntity bar4 AddMesh bar5,e\entity : FreeEntity bar5 AddMesh bar6,e\entity : FreeEntity bar6 AddMesh slat1,e\entity: FreeEntity slat1 AddMesh slat2,e\entity: FreeEntity slat2 AddMesh slat3,e\entity: FreeEntity slat3 AddMesh slat4,e\entity: FreeEntity slat4 EntityType e\entity,2 ; UpdateNormals e\entity EntityTexture e\entity,t_port If EastWest=False Then RotateEntity e\entity,0,90,0 ex=EntityX(e\entity) ey=EntityY(e\entity) ez=EntityZ(e\entity) d=0.05 For frame=1 To 68 MoveEntity e\entity,0,d,0 ;for vertical portcullis effect SetAnimKey e\entity,frame Next e\seq = AddAnimSeq(e\entity,frame-1) ;minus 1 because For-Next loops end 1 too many e\kind = port e\state = closed PositionEntity e\entity,ex,ey,ez ;undo the positioning done by the animation Return .animate If MouseDown(1)=True CameraPick(camera,MouseX(),MouseY()) message$="PickedEntity is " pe=PickedEntity() px# = (EntityX(pcam)-PickedX#()) pz# = (EntityZ(pcam)-PickedZ#()) seerange# = Sqr((px*px)+(pz*pz)) If pe = 0 message$ = message$+"nothing." ElseIf seerange => fogrange-3 message$ = message$+"Out of Range" Else message$ = message$+EntityName$(pe)+"." For e.entity = Each entity If e\entity=pe If seerange <4.5 If e\kind = door If Animating(e\entity) = False ;if door is not moving If e\state=closed Animate e\entity,3,.5 e\state = opened ElseIf e\state = opened Animate e\entity,3,-.5 e\state = closed EndIf EndIf ElseIf e\kind = port If Animating(e\entity) = False If e\state=closed Animate e\entity,3,.5 ;play animationm forward (ie raise port) e\state = opened ElseIf e\state = opened Animate e\entity,3,-.5 e\state = closed EndIf EndIf EndIf Else Text 0,220,"Too far to operate!" EndIf EndIf Next EndIf picked$="PickedX: "+PickedX#() picked$=picked$+" PickedY: "+PickedY#() picked$=picked$+" PickedZ: "+PickedZ#() Text 0, 200, message$ ;text here, so that renderworld does not overwrite it EndIf cam$="Camera X: "+EntityX(pcam)+" Camera Y: "+EntityY(pcam)+" Camera Z: "+EntityZ(pcam) Text 0,100,cam$ Text 0,120, picked$ Text 0,140,"See Range = "+seerange Flip Wend |
| ||
I use both methods. For standard doors I use a polling system that will open a door and close it after a certain time automaticly. It's using simple angles, but the door is parented to a pivot. the pivot defines the doors orientation in space. So the door may use simple local angles. It's important to set the center of the door mesh right, eg: fitmesh door,0,-meshheight(door)/2.0,-meshdepth(door)/2.0,meshwidth(door),meshheight(door),meshdepth(door) Animated Meshes for doors are very flexible, but they also lack of some features. For example, when in motion the player may walk trough geometry. An animated door mesh should contain two animations (open and close) this way it will be easier to play a sound when the door will open and close. |