how do I move acube around?
Blitz3D Forums/Blitz3D Beginners Area/how do I move acube around?
| ||
I was suprized to find out that there is no examples on how to push objects around like in tomb raider, or resident evil. like when they move blocks or pillars and stuff. If anyone would like to help me with this code I will post it in the code base. Here is what I have so far. A sphere and a cube; player controls sphere with keys w,s,a and d; What I want to happen is when sphere collides with box (for example from the top of the cube, the cube should move down)or vise versa. I think I need to use the comands collision x,y,z but not sure how to do that. Another way I tried is if sphere is to check if sphere is higher or lower, to the right of or to the left of box at time of collision, so that box would move acordingly. Do I at least have a clue? Graphics3D 640,480,16 SetBuffer BackBuffer() Const cube_col=1 Const sphere_col=2 light= CreateLight() camera=CreateCamera() PositionEntity camera,0,40,0 Type cubedata Field x#,y# End Type Type circledata Field x#,y# End Type box.cubedata = New cubedata box\x#=-10 box\y#=40 cube= CreateCube() ScaleEntity cube,1,2,2 PositionEntity cube,box\x#,box\y#,20 EntityColor cube,255,0,0 EntityType cube,cube_col;colitionccccccccccccccccccccccccccccc ;EntityBox entity,x#,y#,z#,width#,height#,depth# EntityBox cube,-10,40,20,1,2,2 ;CollisionX# ( entity,index ) ;CollisionX# ( cube,1 ) ;CollisionY# ( cube,1 ) ;player circle.circledata = New circledata circle\x#=10 circle\y#=40 sphere= CreateSphere() EntityColor sphere,0,0,255 PositionEntity sphere,circle\x#,circle\y#,20 EntityType sphere,sphere_col;colitionccccccccccccccccccccccccccccc Collisions sphere_col,cube_col,2,3 Global rsx#=-.25 Global lsx#=.25 Global rsy#=-.25 Global lsy#=.25 While Not KeyHit(1) If KeyDown(30) MoveEntity sphere,rsx#,0,0 If KeyDown(32) MoveEntity sphere,lsx#,0,0 If KeyDown(17) MoveEntity sphere,0,lsy#,0 If KeyDown(31) MoveEntity sphere,0,rsy#,0 UpdateWorld() RenderWorld() Text 10,20,circle\x + circle\y If EntityCollided(sphere,cube_col) Text 370,80,"Collided !!!" TranslateEntity cube,-.25+(bx#*2),0,0 EndIf Text 335,500,"Collision Detection" Flip Wend End Lost in space........................ |
| ||
This might help..Graphics3D 640,480,16 SetBuffer BackBuffer() Const cube_col=1 Const sphere_col=2 light= CreateLight() camera=CreateCamera() PositionEntity camera,0,40,0 Type cubedata Field x#,y# End Type Type circledata Field x#,y# End Type box.cubedata = New cubedata box\x#=-10 box\y#=40 cube= CreateCube() ScaleEntity cube,1,2,2 PositionEntity cube,box\x#,box\y#,20 EntityColor cube,255,0,0 EntityType cube,cube_col;colitionccccccccccccccccccccccccccccc ;EntityBox entity,x#,y#,z#,width#,height#,depth# EntityBox cube,-10,40,20,1,2,2 ;CollisionX# ( entity,index ) ;CollisionX# ( cube,1 ) ;CollisionY# ( cube,1 ) ;player circle.circledata = New circledata circle\x#=10 circle\y#=40 sphere= CreateSphere() EntityColor sphere,0,0,255 PositionEntity sphere,circle\x#,circle\y#,20 EntityType sphere,sphere_col;colitionccccccccccccccccccccccccccccc Collisions sphere_col,cube_col,2,3 Global rsx#=-.25 Global lsx#=.25 Global rsy#=-.25 Global lsy#=.25 While Not KeyHit(1) If KeyDown(30) MoveEntity sphere,rsx#,0,0 If KeyDown(32) MoveEntity sphere,lsx#,0,0 If KeyDown(17) MoveEntity sphere,0,lsy#,0 If KeyDown(31) MoveEntity sphere,0,rsy#,0 UpdateWorld() RenderWorld() Text 10,20,circle\x + circle\y If EntityCollided(sphere,cube_col) Text 370,80,"Collided !!!" If EntityX(sphere) > EntityX(cube) Then ; Check on wich side the sphere is TranslateEntity cube,-.25+(bx#*2),0,0 EndIf If EntityX(sphere) < EntityX(cube) Then ; Check on wich side the sphere is TranslateEntity cube,.25+(bx#*2),0,0 EndIf EndIf Text 335,500,"Collision Detection" Flip Wend End |
| ||
Yep works perfect. Thanks for the help. |
| ||
Well, you could store the players current x,y,z position, before they move. Then check to see if the player has collided with the box. Then compare the players last x,y,z with their current, and move the box according to this. Or, you could work on a grid based system like tomb raider. Every piece of scenary is grid based. To push something you check for a collision, find the direction the player is facing, then move the player and the cube a grid unit in that direction. The player obviously (like tomb raider) move smoothly and isn't confine to grid squares. |
| ||
Ross C The latter seems like more what I'm looking for. Not sure if start over to do it. I'll try it, and see if I can do it. ps: sorry about the duel posts, fustration drove me to it! |
| ||
;) What you could try is this. Create the player. Create the boxes. Parent all the box to a pivot. When you press the keys to move the player, move the level instead. |
| ||
Thats very easy way of doing it, i learned something from this too. Thanks Ross :) |
| ||
Check this out. Surprised that it actually worked. Each cube when pushed, will push others too. Blitz collisions are cool :DGraphics3D 640,480,16 SetBuffer BackBuffer() Const cube_col=1 Const sphere_col=2 Global light= CreateLight() Global camera=CreateCamera() PositionEntity camera,0,40,0 RotateEntity camera,90,0,0 Global sphere=CreateSphere() EntityType sphere,sphere_col Global level=CreatePivot() Dim cube(10) For loop=0 To 10 cube(loop)=CreateCube() PositionEntity cube(loop),-10,0,-10+loop*2 EntityType cube(loop),cube_col EntityParent cube(loop),level Next Collisions 1,2,2,2 Collisions 1,1,2,2 Collisions 1,3,2,2 While Not KeyHit(1) If KeyDown(30) MoveEntity level,0.1,0,0 If KeyDown(32) MoveEntity level,-0.1,0,0 If KeyDown(17) MoveEntity level,0,0,-0.1 If KeyDown(31) MoveEntity level,0,0,0.1 UpdateWorld updatecubes() ; make sure collisions doesn't push the cubes downwards or upwards RenderWorld Flip Wend End Function updatecubes() For loop=0 To 10 PositionEntity cube(loop),EntityX(cube(loop)),0,EntityZ(cube(loop)) Next End Function |
| ||
Very nice Ross. Here's an alternative which pushes the cubes directly but doesn't allow the cubes to affect each other (apart from stopping). Graphics3D 800,600,0,2 sphere=CreateCone() RotateMesh sphere,90,0,0 PositionEntity sphere,5,0,-10 EntityType sphere,1 Dim cubes(6) For n=0 To 6 cubes(n)=CreateCube() EntityType cubes(n),2 PositionEntity cubes(n),0,0,-25+(n*3) Next light=CreateLight() PositionEntity light,-5,-5,-5 PointEntity light, cubes(1) cam=CreateCamera() PositionEntity cam,0,25,0 PointEntity cam,cubes(1) Collisions 1,2,3,2 Collisions 2,2,3,2 While Not KeyHit(1) If KeyDown(200) MoveEntity sphere,0,0,0.2 If KeyDown(208) MoveEntity sphere,0,0,-0.2 If KeyDown(203) TurnEntity sphere,0,3,0 If KeyDown(205) TurnEntity sphere,0,-3,0 If EntityCollided(sphere,2) For n=1 To CountCollisions(sphere) ent = CollisionEntity(sphere,n) x#=CollisionNX(sphere,n)/10 y#=CollisionNY(sphere,n)/10 z#=CollisionNZ(sphere,n)/10 TranslateEntity ent,-x#,-y#,-z# Next EndIf UpdateWorld RenderWorld Flip Wend |
| ||
Hey you gues ar amasing. Just slinen code like nothin. Here is what I ended up with kinda basic but does what I wanted. mabye a little longer than nessesary. ;sphere moveing a box around by Matt Anthony Graphics3D 640,480,16 SetBuffer BackBuffer() Const cube_col=1 Const sphere_col=2 light= CreateLight() camera=CreateCamera() PositionEntity camera,0,40,0 Type cubedata Field x#,y# End Type Type circledata Field x#,y# End Type AutoMidHandle =True box.cubedata = New cubedata box\x#=-10 box\y#=40 cube= CreateCube() ScaleEntity cube,3,3,3 PositionEntity cube,box\x#,box\y#,20 EntityColor cube,255,0,0 EntityType cube,cube_col;collisionccccccccccccccccccccccccccccc ;player circle.circledata = New circledata circle\x#=10 circle\y#=40 sphere= CreateSphere() EntityColor sphere,0,0,255 PositionEntity sphere,circle\x#,circle\y#,20 EntityType sphere,sphere_col;collisionccccccccccccccccccccccccccccc Collisions sphere_col,cube_col,2,3 Global rsx#= .25 ;right movment value Global lsx#=-.25 ;left movment value Global usy#=-.25 ;up movement value Global dsy#= .25 ;down movement value ;Const bx#=1 While Not KeyHit(1);Main MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM If KeyDown(30) MoveEntity sphere,lsx#,0,0 If KeyDown(32) MoveEntity sphere,rsx#,0,0 If KeyDown(17) MoveEntity sphere,0,dsy#,0 If KeyDown(31) MoveEntity sphere,0,usy#,0 UpdateWorld() RenderWorld() Color 255,255,0 Text 335,500,"Collision Detection" Text 10,20,circle\x + circle\y If EntityCollided(sphere,cube_col);collision Text 370,80,"Collided !!!" If EntityX(sphere)+1.5 > EntityX(cube) Then ; Check on wich side the sphere is TranslateEntity cube,-.25,0,0 EndIf If EntityX(sphere)-1.5 < EntityX(cube) Then ; Check on wich side the sphere is TranslateEntity cube,.25,0,0 EndIf EndIf If EntityCollided(sphere,cube_col);collision Text 370,80,"Collided !!!" If EntityY(sphere)+1.5 < EntityY(cube) Then ; Check on wich side the sphere is TranslateEntity cube,0,.25,0 EndIf If EntityY(sphere)-1.5 > EntityY(cube) Then ; Check on wich side the sphere is TranslateEntity cube,0,-.25,0 EndIf EndIf Flip Wend ;End of Main MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM End |
| ||
cool :) |
| ||
Here's a little tweak that uses the collision normals to decide which direction to move the cubeGraphics3D 640,480,16 SetBuffer BackBuffer() Const cube_col=1 Const sphere_col=2 light= CreateLight() camera=CreateCamera() PositionEntity camera,0,40,0 Type cubedata Field x#,y# End Type Type circledata Field x#,y# End Type AutoMidHandle =True box.cubedata = New cubedata box\x#=-10 box\y#=40 cube= CreateCube() ScaleEntity cube,3,3,3 PositionEntity cube,box\x#,box\y#,20 EntityColor cube,255,0,0 EntityType cube,cube_col;collisionccccccccccccccccccccccccccccc ;player circle.circledata = New circledata circle\x#=10 circle\y#=40 sphere= CreateSphere() EntityColor sphere,0,0,255 PositionEntity sphere,circle\x#,circle\y#,20 EntityType sphere,sphere_col;collisionccccccccccccccccccccccccccccc Collisions sphere_col,cube_col,2,3 Global rsx#= .25 ;right movment value Global lsx#=-.25 ;left movment value Global usy#=-.25 ;up movement value Global dsy#= .25 ;down movement value ;Const bx#=1 While Not KeyHit(1);Main MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM If KeyDown(30) MoveEntity sphere,lsx#,0,0 If KeyDown(32) MoveEntity sphere,rsx#,0,0 If KeyDown(17) MoveEntity sphere,0,dsy#,0 If KeyDown(31) MoveEntity sphere,0,usy#,0 UpdateWorld() RenderWorld() Color 255,255,0 Text 335,500,"Collision Detection" Text 10,20,circle\x + circle\y If EntityCollided(sphere,cube_col);collision Text 370,80,"Collided !!!" TranslateEntity cube,CollisionNX(sphere,1)*lsx#,CollisionNY(sphere,1)*usy,0 EndIf Flip Wend ;End of Main MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM End |
| ||
Thats a sweet little tweak you just replaced 6 lines of code with one line !!! I like it! |
| ||
ok, so why isn't this working????? the collisions I meen Graphics3D 640,480,16 SeedRnd MilliSecs() light=CreateLight() cam=CreateCamera() ;position camera looking straight down on plane grid_tex=CreateTexture( 32,32,8 ) ScaleTexture grid_tex,10,10 SetBuffer TextureBuffer( grid_tex ) Color 0,0,64:Rect 0,0,32,32 Color 200,20,255:Rect 0,0,32,32,False plane=CreatePlane() EntityTexture plane,grid_tex EntityBlend plane,1 EntityAlpha plane,.6 EntityFX plane,1 ;mirror=CreateMirror() ;RotateEntity plane,0,90,0 PositionEntity cam,0,40,0 PointEntity cam,plane ;create player Global sphere=CreateSphere() ScaleEntity sphere,1.5,1.5,1.5 PositionEntity sphere,0,EntityY(plane)+4,0 ;EntityType sphere,1 EntityType sphere,1 Dim cubes(6) For n=1 To 6 cubes(n)=CreateCube() EntityType cubes(n),2 ;EntityType cubes(n),2 PositionEntity cubes(n),10+Rnd(-50,50),EntityY(plane)+6 ,0+Rnd(-50,50) ScaleEntity cubes(n),6,6,6 Next Global camangle camangle=0 Global rsx#= .25 ;right movment value Global lsx#=-.25 ;left movment value Global usz#=-.25 ;up movement value Global dsz#= .25 ;down movement value Collisions 1,2,3,2 Collisions 2,2,3,2 ;Collisions sphere,cube_col,2,3 While Not KeyHit(1) ;check for movement by user If KeyDown(30) TranslateEntity sphere,lsx#,0,0 If KeyDown(32) TranslateEntity sphere,rsx#,0,0 If KeyDown(17) TranslateEntity sphere,0,0 ,dsz# If KeyDown(31) TranslateEntity sphere,0,0,usz# If EntityCollided(sphere,2) For n=1 To CountCollisions(sphere) ent = CollisionEntity(sphere,n) x#=CollisionNX(sphere,n)/10 y#=CollisionNY(sphere,n)/10 z#=CollisionNZ(sphere,n)/10 TranslateEntity cubes(n),CollisionNX(sphere,2)*lsx#,0,CollisionNZ(sphere,2)*usz TranslateEntity ent,-x#,-y#,-z# Next EndIf updatePosition(cam,sphere) UpdateWorld RenderWorld Flip Wend ;This function checks to see if sphere is going to far away in any ;direction and if it does resets it on the oposit side of the screen ;also controls camera angle view of world Function updatePosition(cam,sphere) If KeyHit(42) Then camangle=camangle+1 If camangle>2 Then camangle=0 If camangle=1 Then PositionEntity cam,EntityX(sphere),40,EntityZ(sphere) EndIf If camangle=2 Then PositionEntity cam,EntityX(sphere)-15,40,EntityZ(sphere)-15 EndIf PointEntity cam,sphere If EntityX(sphere)=60 PositionEntity sphere,-50,EntityY(sphere),EntityZ(sphere) If EntityX(sphere)=-60 PositionEntity sphere,50,EntityY(sphere),EntityZ(sphere) If EntityZ(sphere)=60 PositionEntity sphere,EntityX(sphere),EntityY(sphere),-50 If EntityZ(sphere)=-60 PositionEntity sphere,EntityX(sphere),EntityY(sphere),50 End Function |
| ||
Hi Matthew, It's that you have scaled and repositioned the entities - but not their boundingboxes or collision radius (see entityradius() and entitybox() - they aren't colliding because they are on slightly different y planes with the original collision radius/boundingboxes setup. |
| ||
Here's the fix Matthew - with the scaled up bounding boxes/radii... (;TranslateEntity cubes(n),CollisionNX(sphere,n) - I commented out this line - no idea what you mean it to do) Graphics3D 640,480,16 SeedRnd MilliSecs() light=CreateLight() cam=CreateCamera() ;position camera looking straight down on plane grid_tex=CreateTexture( 32,32,8 ) ScaleTexture grid_tex,10,10 SetBuffer TextureBuffer( grid_tex ) Color 0,0,64:Rect 0,0,32,32 Color 200,20,255:Rect 0,0,32,32,False plane=CreatePlane() EntityTexture plane,grid_tex EntityBlend plane,1 EntityAlpha plane,.6 EntityFX plane,1 ;mirror=CreateMirror() ;RotateEntity plane,0,90,0 PositionEntity cam,0,40,0 PointEntity cam,plane ;create player Global sphere=CreateSphere() ScaleEntity sphere,1.5,1.5,1.5 PositionEntity sphere,0,EntityY(plane)+4,0 ;EntityType sphere,1 EntityType sphere,1 EntityRadius sphere,1.5 Dim cubes(6) For n=1 To 6 cubes(n)=CreateCube() EntityType cubes(n),2 ;EntityType cubes(n),2 PositionEntity cubes(n),10+Rnd(-50,50),EntityY(plane)+6 ,0+Rnd(-50,50) ScaleEntity cubes(n),6,6,6 EntityBox cubes(n),-6,-6,-6,12,12,12 EntityRadius cubes(n),6 Next Global camangle camangle=0 Global rsx#= .25 ;right movment value Global lsx#=-.25 ;left movment value Global usz#=-.25 ;up movement value Global dsz#= .25 ;down movement value Collisions 1,2,3,2 Collisions 2,2,3,2 ;Collisions sphere,cube_col,2,3 While Not KeyHit(1) ;check for movement by user If KeyDown(30) TranslateEntity sphere,lsx#,0,0 If KeyDown(32) TranslateEntity sphere,rsx#,0,0 If KeyDown(17) TranslateEntity sphere,0,0 ,dsz# If KeyDown(31) TranslateEntity sphere,0,0,usz# If EntityCollided(sphere,2) For n=1 To CountCollisions(sphere) ent = CollisionEntity(sphere,n) x#=CollisionNX(sphere,n)/10 y#=CollisionNY(sphere,n)/10 z#=CollisionNZ(sphere,n)/10 ;TranslateEntity cubes(n),CollisionNX(sphere,n)*lsx#,0,CollisionNZ(sphere,n)*usz ; DUNNO what you intend with this line TranslateEntity ent,-x#,-y#,-z# Next EndIf updatePosition(cam,sphere) UpdateWorld RenderWorld Flip Wend ;This function checks to see if sphere is going to far away in any ;direction and if it does resets it on the oposit side of the screen ;also controls camera angle view of world Function updatePosition(cam,sphere) If KeyHit(42) Then camangle=camangle+1 If camangle>2 Then camangle=0 If camangle=1 Then PositionEntity cam,EntityX(sphere),40,EntityZ(sphere) EndIf If camangle=2 Then PositionEntity cam,EntityX(sphere)-15,40,EntityZ(sphere)-15 EndIf PointEntity cam,sphere If EntityX(sphere)=60 PositionEntity sphere,-50,EntityY(sphere),EntityZ(sphere) If EntityX(sphere)=-60 PositionEntity sphere,50,EntityY(sphere),EntityZ(sphere) If EntityZ(sphere)=60 PositionEntity sphere,EntityX(sphere),EntityY(sphere),-50 If EntityZ(sphere)=-60 PositionEntity sphere,EntityX(sphere),EntityY(sphere),50 End Function |
| ||
Thanks for the fix Brendan. I think I understand what you said about scaling the bounding box but I just have a few questions about your code. 1. Why do the position values in the line EntityBox cubes(n),-6,-6,-6,12,12,12 have a negative value. Does that mean its being drawn from that point -6 Xon the cube,-6 y on the cube, -6z on the cube and has nothing to do with the global xyz position of the cube it's self? 2.x#=CollisionNX(sphere,n)/10 y#=CollisionNY(sphere,n)/10 z#=CollisionNZ(sphere,n)/10 How did you come up with dividing by 10? I have tried diferent values that has a diferent efect each time. |
| ||
Hi Matt, 1. Since you scaled the cube by 6 (the cube was originally from -1 to 1 on it's local axis) the -6's are the start position of the collision box (since 0,0,0 is the exact centre of the cube, in it's local axis of course)... not sure if I have explained that clearly enough - but essentially the midpoint of the cube is 0,0,0 - using EntityBox you have to specify the start point of the collision box (ie. one corner) and tell it the size. In this case the new scaled up corner is now -6,-6,-6 and the new size is 12,12,12. It's much easier to grasp this if you draw it on paper - in effect it means that your collision box can be anywhere relative to your actual geometry. 2. The collision normal will always be of length 1. Now, since my character was moving by 0.2 units each frame I just scaled down this length to make an arbitrary but reasonable effect of pushing the boxes at half the speed of the player - ie. 1/10 = 0.1 - this gives the effect that the boxes have friction against the floor. In your instance you are moving the character by 0.25 units each frame - therefore if you divide the collision normal values by 4 you will be moving the boxes at the exact speed of the player (1/4 = 0.25). Sorry for waffling, hope that was a reasonable explanation. |
| ||
You were not "waffling". You were in fact responding to a waffly question. Thanks for helping me out. I think I understand the first one(I'll experiment with it.) The second one I get completly. It controls the speed during contact. Now I'm going to try to make my first puzzle game. Don't worry, When I make my millions from it I'll share the glorry! Ha Ha |
| ||
Hey no problem. Good luck! |
| ||
I am new to Blitz3d and so am not sure if I will be much help, but I thought it looked silly not to have the cubes rotate. The physics of this are way off, but I kind of liked the effect this code gave me.Graphics3D 640,480,16 SetBuffer BackBuffer() Const cube_col=1 Const sphere_col=1 Global light= CreateLight() Global camera=CreateCamera() PositionEntity camera,0,40,0 RotateEntity camera,90,0,0 Global sphere=CreateSphere() EntityType sphere,sphere_col Global level=CreatePivot() Dim cube(10) For loop=0 To 10 cube(loop)=CreateCube(level) PositionEntity cube(loop),-10,0,-10+loop*2 EntityType cube(loop),cube_col Next Collisions 1,1,2,2 While Not KeyHit(1) If KeyDown(30) MoveEntity level,0.1,0,0 If KeyDown(32) MoveEntity level,-0.1,0,0 If KeyDown(17) MoveEntity level,0,0,-0.1 If KeyDown(31) MoveEntity level,0,0,0.1 If EntityCollided(sphere,1) Then colliderotate(sphere,EntityCollided(sphere,1)) UpdateWorld RenderWorld Flip Wend End Function colliderotate(srcentity,dstentity) x#=CollisionX(dstentity,1) y#=CollisionY(dstentity,1) z#=CollisionZ(dstentity,1) RotateEntity dstentity,-y-EntityY(dstentity)*5,-z-EntityZ(dstentity)*5,-x-EntityX(dstentity)*5 End Function If you have a more interesting or more acurate idea, I would be glad to see some code or hear a theory! |
| ||
>I was suprized to find out that there is no examples on >how to push objects around like in tomb raider, or >resident evil. http://www.blitzbasic.com/codearcs/codearcs.php?code=943 Andy |
| ||
You guys realize this was posted one year ago, right? |
| ||
Yeah, isn't it great! |
| ||
one thing to say. Tokamak... |