Mouse Movement of Player Object

Blitz3D Forums/Blitz3D Beginners Area/Mouse Movement of Player Object

StOrM3(Posted 2004) [#1]
Hello, okay here it goes, I got all my collision and scaling problems solved thanks to a hefty rewrite using the Coldet lib which is awesome btw.

Anyways, here is my question now. Say you have a 2 dimensional array of objects in the center of a level, laid out in a square type pattern, each object 50 pixels exactly apart from each other. This square array is in the center of the level with room on top, bottom, left, right for movement of player around the outside.

I want to be able to use the mouse and move the player object around the outside of the objects, moving at 50 Pixel increments, so as to stay lined up with the objects in the center of the level. Also I want the player object to always be facing the center square array of objects so if you press the mouse button, it will fire the player object toward the row of objects that the player object is currently lined up with. Phew, I know this is alot to ask/understand, I have tried a few things and am unable to get the mouse movement smooth, to line up correctly, and to stay within the confines of the outside of the square array, like travelling around it in a track manner.

Please either provide a code example, or point me to a link, a tutorial or anything would be great.

Thanks in advance.

Ken


jfk EO-11110(Posted 2004) [#2]
Not sure if I misunderstood the question, but couldn't you just round the position? Something like x=int(x/50)*50 ?


AntonyWells(Posted 2004) [#3]
Something like

playX=playX+sgn(mousex())*50
playY=playY+sgn(mousey())*50

Which will inc the player's coords by 50 in the direction of mouse, no matter how fast/slow you move in that direction.

Though jfk is slightly off i think, as deviding something by 50 then multiplying by 50 will equal the same number ;)

try,

tileX =playX/50
tileY =playY/50



StOrM3(Posted 2004) [#4]
okay, and then how do I tell what side of the array of objects the player is on, and draw the player object accordingly. Like I want the mouse to follow a square or rectangular path around the outside of the objects. Say the objects are located at
for countx = 1 to 6
for countz = 1 to 6
object\locx# = (50 * countx) - 98
object\locz# = (50 * countz) - 88
next
next

Which makes a nice square grid layout of objects...

I want the object controlled by the mouse to follow a path
along the outside of these objects, like since the arrays
run from 1-6, I could use 0,0 - 7,0 for top Line
and 0,7 - 7,7 bottom line, 0,0 - 0,7 for left,
7,0 - 7,7 for right side. Okay I know this much, now how
do I make the mouse as it is moved follow this path along the outside edge, and only move in the 50 pixel increments.

I Hope this clears it up, and I hope someone can help.. I tried my own routines and it is not working, I am getting no movement..

Thanks,

Ken


StOrM3(Posted 2004) [#5]
for a test I used the following code below and it almost does an outline, some of my calculations are off somewhere though, hope you can spot my problems / bugs.

Graphics3D 800,600,16,0

Global CellX, CellY
Global checktopx, checktopy, checkbotx, checkboty
Global checkleftx, checklefty, checkrightx, checkrighty
Global playermoved
Global oldx, oldy

;Start out on bottom in the middle.
;3,7 starting position = middle / bottom
;Forget Y movement of mouse unless in bottom Left Or bottom Right corners.
;so set mouse To 3*25, 7*25 x,z respectively For start in middle.

MoveMouse 75,175 ; set to middle, bottom

While Not KeyDown (1)	; now entering main loop

RenderWorld	; setup everything that is to be displayed render it fully with textures and lights...

; Handle bottom row movement...
Repeat 
  cellx = MouseX() / 25
  celly = MouseY() / 25
  ; this gives us our grid location 3,7 hopefully
  If celly < 7 Or celly > 7
    celly = 7  ; make sure we stay on bottom line.
    MoveMouse cellx*25, celly*25  ; make sure we are not off screen or up in fruit territory.
    cellx = MouseX() / 25  ; update the cell variables to make them correct for next test.
    celly = MouseY() / 25
  EndIf
  If celly = 7
    MoveMouse cellx*25,celly*25
  EndIf
  ; even if the celly hasn't went out of range, we need to move mouse, draw rectangle.
  If cellx >= 1 Or cellx <= 6
    cellx = MouseX() / 25
    celly = 7
    ; ignore celly since it should be handled already.
    MoveMouse cellx*25, celly*25
    Rect cellx*25, celly*25, 25, 25, 1  ; solid rect to show player position.
  EndIf
Until cellx < 1 Or cellx > 6
  
If cellx < 1
  cellx = MouseX() / 25
  celly = MouseY() / 25
  If celly < 7 Then
    cellx = 0
    celly = MouseY() / 25
    MoveMouse cellx*25, celly*25
  EndIf
  MoveMouse cellx*25, celly*25
  Rect cellx*25, celly*25, 25, 25, 1
EndIf

If cellx > 6
  cellx = MouseX() / 25
  celly = MouseY() / 25
  If celly < 7 Then
    cellx = 0
    celly = MouseY() / 25
    MoveMouse cellx*25, celly*25
  EndIf
  MoveMouse cellx*25, celly*25
  Rect cellx*25, celly*25, 25, 25, 1
EndIf

; Handle TOP row movement...
Repeat 
  cellx = MouseX() / 25
  celly = MouseY() / 25
  ; this gives us our grid location 3,7 hopefully
  If celly > 0 Or celly < 0
    celly = 0  ; make sure we stay on bottom line.
    MoveMouse cellx*25, celly*25  ; make sure we are not off screen or up in fruit territory.
    cellx = MouseX() / 25  ; update the cell variables to make them correct for next test.
    celly = MouseY() / 25
  EndIf
  If celly = 0
    MoveMouse cellx*25,celly*25
  EndIf
  ; even if the celly hasn't went out of range, we need to move mouse, draw rectangle.
  If cellx >= 1 Or cellx <= 6
    cellx = MouseX() / 25
    celly = 0
    ; ignore celly since it should be handled already.
    MoveMouse cellx*25, celly*25
    Rect cellx*25, celly*25, 25, 25, 1  ; solid rect to show player position.
  EndIf
Until cellx < 1 Or cellx > 6
  
If cellx < 1
  cellx = MouseX() / 25
  celly = MouseY() / 25
  If celly > 0 Then
    cellx = 0
    celly = MouseY() / 25
    MoveMouse cellx*25, celly*25
  EndIf
  MoveMouse cellx*25, celly*25
  Rect cellx*25, celly*25, 25, 25, 1
EndIf

If cellx > 6
  cellx = MouseX() / 25
  celly = MouseY() / 25
  If celly > 0  Then
    cellx = 7
    celly = MouseY() / 25
    MoveMouse cellx*25, celly*25
  EndIf
  MoveMouse cellx*25, celly*25
  Rect cellx*25, celly*25, 25, 25, 1
EndIf

Flip	; have to use this because we are drawing to the backbuffer so the drawing won't be seen during game play...

Wend


Hope this helps you visualize what I am trying to do.


StOrM3(Posted 2004) [#6]
Feel free to email me your solution, if you don't want to post it here, my email is storm3@...


DJWoodgate(Posted 2004) [#7]
Here is my hastily contrived effort. Needs improvement, like smooth movement between grid positions and so on. Uses the cheap and cheerful array approach to store player paths and in this case a direction to point.

Graphics3D 640,480,0,2
SetBuffer BackBuffer()

Dim grid(11,11)

Readgriddata()

For countx = 1 To 11
For countz = 1 To 11

If grid(countx,countz)=9 Then
	count=count+1
	If count=1 Then obj=CreateCube() Else obj=CopyEntity(obj) 
	EntityColor obj,100,0,50
	PositionEntity obj,(countx)*4,0,(countz)*4
EndIf
Next 
Next 

player=CreateCone()
EntityColor player,255,255,0
RotateMesh player,90,0,0
gridx=1 : gridz=1
PositionEntity player,gridx*4,0,gridy*4

light=CreateLight(2,player) 
LightRange light,20
PositionEntity light,0,10,0

camera=CreateCamera()
PositionEntity camera,20,24,18
RotateEntity camera,90,0,0

MoveMouse GraphicsWidth()/2, GraphicsHeight()/2
Repeat

mxspd#=MouseXSpeed()*0.05
myspd#=MouseYSpeed()*0.05
MoveMouse GraphicsWidth()/2, GraphicsHeight()/2
mxpos# = mxpos + mxspd
mypos# = mypos - myspd
xmove = 0 : zmove = 0
If mxpos>1  Then mxpos=0 xmove=1 
If mxpos<-1 Then mxpos=0 xmove=-1
If mypos>1  Then mypos=0 zmove=1
If mypos<-1 Then mypos=0 zmove=-1

If grid(gridx+xmove,gridz)>0 And grid(gridx+xmove,gridz)<5 Then gridx=gridx+xmove 
If grid(gridx,gridz+zmove)>0 And grid(gridx,gridz+zmove)<5 Then gridz=gridz+zmove

Select grid(gridx,gridz)
	Case 1 RotateEntity player,0,0,0
	Case 2 RotateEntity player,0,270,0
	Case 3 RotateEntity player,0,90,0
	Case 4 RotateEntity Player,0,180,0
End Select


PositionEntity player,gridx*4,0,gridz*4

RenderWorld
Flip
Until KeyHit(1)

Function readgriddata()
Read g$
While g$<>""
	For x=1 To Len(g$)
		grid(x-1,y)=Mid(g$,x,1)
	Next
	y=y+1
	Read g$
Wend
End Function

Data "00000000000"
Data "01111111110"
Data "02999999930"
Data "02999999930"
Data "02999999930"
Data "02999999930"
Data "02999999930"
Data "02999999930"
Data "04444444440"
Data "00000000000"
Data ""



StOrM3(Posted 2004) [#8]
thank you very much, this was my next attempt at it using flags..
Graphics3D 800,600,16,0

; global flag indicating side we are on.
; start at 3,7 grid position, bottom middle.
global flag
global cellx = 3
global celly = 7

movemouse cellx*25, celly*25

flag = 2  ; bottom start with

while not keydown(1)

;RenderWorld

;cellx = MouseX() / 25
;celly = MouseY() / 25

If flag = 2
RenderWorld
  cellx = MouseX() / 25
  celly = 7
  If cellx < 1 Then
    flag = 3 ; on left side now.
    celly = 6
    cellx = 0
    MoveMouse cellx*25, celly*25
    Rect cellx*25,celly*25,25,25,1
  EndIf
  If cellx > 6 Then
    flag = 4 ; on right side now.
    celly = 6
    cellx = 7
    MoveMouse cellx*25, celly*25
    Rect cellx*25, celly*25, 25,25,1
  EndIf
  If flag <> 3 Or flag <> 4
    cellx = MouseX() / 25
    celly = 7
    MoveMouse cellx*25, celly*25
    Rect cellx*25,celly*25, 25,25,1
  EndIf
Flip 
EndIf

If flag = 1
RenderWorld
  cellx = MouseX() / 25
  celly = 0
  If cellx < 1 Then
    flag = 3 ; on left side now.
    celly = 1
    cellx = 0
    MoveMouse cellx*25, celly*25
    Rect cellx*25,celly*25,25,25,1
  EndIf
  If cellx > 6 Then
    flag = 4 ; on right side now.
    celly = 1
    cellx = 7
    MoveMouse cellx*25, celly*25
    Rect cellx*25, celly*25, 25,25,1
  EndIf
  If flag <> 3 Or flag <> 4
    cellx = MouseX() / 25
    celly = 0
    MoveMouse cellx*25, celly*25
    Rect cellx*25,celly*25, 25,25,1
  EndIf
Flip  
EndIf

If flag = 3 ;left side.
RenderWorld
  cellx = 0
  celly = MouseY() / 25
  If celly < 1 Then
    flag = 1 ; on top side now.
    celly = 0
    cellx = 1
    MoveMouse cellx*25, celly*25
    Rect cellx*25,celly*25,25,25,1
  EndIf
  If celly > 6 Then
    flag = 2 ; on bottom side now.
    celly = 7
    cellx = 1
    MoveMouse cellx*25, celly*25
    Rect cellx*25, celly*25, 25,25,1
  EndIf
  If flag <> 1 Or flag <> 2
    cellx = 0
    celly = MouseY() / 25
    MoveMouse cellx*25, celly*25
    Rect cellx*25,celly*25, 25,25,1
  EndIf
Flip  
EndIf

If flag = 4 ;right side.
RenderWorld
  cellx = 7
  celly = MouseY() / 25
  If celly < 1 Then
    flag = 1 ; on top side now.
    celly = 0
    cellx = 6
    MoveMouse cellx*25, celly*25
    Rect cellx*25,celly*25,25,25,1
  EndIf
  If celly > 6 Then
    flag = 2 ; on bottom side now.
    celly = 7
    cellx = 6
    MoveMouse cellx*25, celly*25
    Rect cellx*25, celly*25, 25,25,1
  EndIf
  If flag <> 1 Or flag <> 2
    cellx = 7
    celly = MouseY() / 25
    MoveMouse cellx*25, celly*25
    Rect cellx*25,celly*25, 25,25,1
  EndIf
Flip  
EndIf


Wend


It, almost works, kinda quirky not drawing a rect sometimes, smoothly as you move the mouse its like the mouse coords get lost or something.

Again thanks for your effort, if you have any other fixes, or patches to the above code, or a different way to do it, feel free to post away or send it to me via email posted above.

Thanks,

Ken


StOrM3(Posted 2004) [#9]
David, or DJ YOU ARE AWESOME, that is exactly what I wanted. Yea, it does need to be smoothed out, but oh, my you have my idea exactly like I envisioned it. Thank you so much.. if you fix it up, or have any changes to it, let me know, also I am going to study this as a learning experience, I like to learn where to improve my own code.

Thanks, you just made my weekend !!! Woo Hoo..

Ken


StOrM3(Posted 2004) [#10]
So there is no additions or changes to the code ? Anyone else have anythng to add to it or change ?

Thanks for the help,

Ken


DJWoodgate(Posted 2004) [#11]
Another attempt then. Still needs a bit of, er, fine tuning though :0

Edit(28/3). Improved it a bit.
Edit(29/3). Added use of a pivot so you can move/rotate it.
Edit(30/3). Load some geometrick models and put player movement in a function.
Edit(30/3). Allow you to specify grid resolution, object size and player size. Have not scaled movement though, so on a big grid it will move slower.

Graphics3D 640,480,0,2

Const keyLeftA=203, KeyRightA=205, KeyUpA=200, KeyDownA=208

Local GX#=4, GZ#=4 ; Grid Resolution
Local OX#=2.5, OY#=2.5, OZ#=2.5 ; Object Size
Local PX#=2, PY#=1, PZ#=3.5 ; Player Size

Type player
Field pxspd#,pzspd#,movex#,movez#
Field Entity,parent,move,moveovertime,CurrX,CurrZ
End Type

texture=CreateTexture(128,128)
ScaleTexture texture,16,16
SetBuffer TextureBuffer(texture)
Color 0,0,80 : Rect 0,0,128,128 : Color 0,0,150
For i=0 To 1000 : Plot Rand(0,127),Rand(0,127) : Next
SetBuffer BackBuffer()

plane=CreatePlane(10)
EntityTexture plane,texture

Dim grid(11,11)

arena=CreatePivot()
PositionEntity arena,0,OY,0

creategrid(arena, GX,GZ, OX,OY,OZ)

; create player entity and parent to arena

p1.player=New player
p1\entity = Loadamesh("fighter.3ds",arena) : p1\parent=arena
FitMesh p1\entity,-PX/2,-PY/2,-PZ/2, PX,PY,PZ
RotateMesh p1\entity,0,180,0 ; model specific tweak
;p1\entity=CreateCone(8,1,arena)
;EntityColor p1\entity,255,255,0
;RotateMesh p1\entity,90,0,0 ; Make the cone mesh point into the Z Axis
p1\CurrX=1 : p1\CurrZ=1 : p1\pxspd=0 : p1\pzspd=0 : p1\move=False
PositionEntity p1\entity, p1\CurrX * GX, 0, p1\CurrZ * GZ

light=CreateLight(2,p1\entity) 
LightRange light,Sqr(GX*GZ)*5
PositionEntity light, 0 ,PY +10, 0

camera=CreateCamera(arena)
PositionEntity camera,5*GX,6*Sqr(GX*GZ),4.4*GZ
RotateEntity camera,90,0,0
CameraClsColor camera,50,50,160

HidePointer()
MoveMouse GraphicsWidth()/2, GraphicsHeight()/2

Repeat
	; Acquire mouse speed
	mxspd=MouseXSpeed()
	myspd=MouseYSpeed()
	MoveMouse GraphicsWidth()/2, GraphicsHeight()/2
	
	; Uses arrow keys to rotate arena
	Rotate(arena,1.0)

	; Update player movement
	moveplayer(p1,mxspd,myspd,GX#,GZ#)
	
	RenderWorld
	
	Showinfo(p1, 0,0)

	Flip

Until KeyHit(1)

End

Function moveplayer(p.player, mxspd, myspd, GX#, GZ#)
	; accelerate
	p\pxspd=p\pxspd+mxspd*0.04 
	p\pzspd=p\pzspd-myspd*0.04
	p\pxspd=p\pxspd*0.8  ; apply drag
	p\pzspd=p\pzspd*0.8
	If Abs(p\pxspd)<0.01 Then p\pxspd=0 ; set zero when small
	If Abs(p\pzspd)<0.01 Then p\pzspd=0
	If Abs(p\pxspd)>2.0  Then p\pxspd=2.0 * Sgn(p\pxspd) ; limit max spd
	If Abs(p\pzspd)>2.0  Then p\pzspd=2.0 * Sgn(p\pzspd)
	; Say movement has stopped if there is no mouse activity for 250ms to allow for deceleration.
	If mxspd<>0 Or myspd<>0 Then 
		p\move=True
		p\moveovertime=MilliSecs()+250
	Else
		If MilliSecs()>=p\moveovertime Then p\move=False
	EndIf
	; Check player movement
	If p\move Then 
		If grid(p\currX,p\currZ+Sgn(p\pzspd))>0 And grid(p\currX,p\currZ+Sgn(p\pzspd))<5
			p\CurrZ=Int((EntityZ(p\entity)+p\pzspd)/GZ) ; Current grid Z Position	
		Else ; Z direction is blocked - Cancel movement
			p\pzspd=0 : PositionEntity p\entity,EntityX(p\entity),0,p\CurrZ * GZ
		EndIf
		If grid(p\currX+Sgn(p\pxspd),p\CurrZ)>0 And grid(p\currX+Sgn(p\pxspd),p\CurrZ)<5
			p\CurrX=Int((EntityX(p\entity)+p\pxspd)/GX) ; Current Grid X Position
		Else ; X direction is blocked - Cancel movement
			p\pxspd=0 : PositionEntity p\entity,p\CurrX * GX,0,EntityZ(p\entity)
		EndIf
		TranslateEntity p\entity,p\pxspd,0,p\pzspd ; Apply movement
	Else ; stopped moving - align to grid position.
		p\movex#=(p\CurrX * GX - EntityX(p\entity))*0.2
		p\movez#=(p\CurrZ * GZ - EntityZ(p\entity))*0.2
		TranslateEntity p\entity,p\movex,0,p\movez
		If Abs(p\movex)<0.1 And Abs(p\movez)<0.1 Then 
			PositionEntity p\entity,p\CurrX * GX, 0, p\CurrZ * GZ
		EndIf
	EndIf
	; Rotate player based on grid value.  Aligntovector works with world coords so...
	Select grid(p\CurrX,p\CurrZ) 
		Case 1	TFormVector  0,0,1,p\parent,0
		Case 2	TFormVector  1,0,0,p\parent,0
		Case 3	TFormVector -1,0,0,p\parent,0
		Case 4	TFormVector 0,0,-1,p\parent,0
	End Select
	; align the Z axis of the player object accordingly.
	AlignToVector p\entity,TFormedX(),TFormedY(),TFormedZ(),3,0.2
End Function	

Function rotate(entity,DEG#)
	If KeyDown(keyLeftA)	Then TurnEntity entity,0,-DEG,0
	If KeyDown(keyRightA)	Then TurnEntity entity,0,DEG,0
	If KeyDown(keyUpA)		Then TurnEntity entity,DEG,0,0
	If KeyDown(keyDownA)	Then TurnEntity entity,-DEG,0,0
End Function


Function creategrid(parent,GX#,GZ#, OX#,OY#,OZ#)
Readgriddata()
For countx = 1 To 11
	For countz = 1 To 11
		If grid(countx,countz)=9 Then
			count=count+1
		;	If count=1 Then obj=CreateCube(pivot) Else obj=CopyEntity(obj,pivot) 
			If count=1 Then 
				obj=loadamesh("wcrate1.3ds",parent)
				FitMesh obj,-OX/2,-OY/2,-OZ/2, OX,OY,OZ
			Else 
				obj=CopyEntity(obj,parent)
			EndIf
		;	EntityColor obj,100,0,50			
			PositionEntity obj,(countx) * GX, 0, (countz) * GZ
		EndIf
	Next 
Next 
End Function

Function readgriddata()
Read g$
While g$<>""
	For x=1 To Len(g$)
		grid(x-1,y)=Mid(g$,x,1)
	Next
	y=y+1
	Read g$
Wend
End Function

Data "00000000000"
Data "01111111110"
Data "02999999930"
Data "02999999930"
Data "02999999930"
Data "02999999930"
Data "02999999930"
Data "02999999930"
Data "04444444440"
Data "00000000000"
Data ""

Function Showinfo(p1.player, SX,SY)	
	Color 127,127,127
	Text SX,SY,EntityX(p1\entity)+" "+EntityZ(p1\entity)
	Text SX,SY+12,"Move? "+p1\Move
	Text SX,SY+24,"GRID    X "+p1\CurrX+" Z "+p1\CurrZ+" VAL "+Grid(p1\CurrX,p1\CurrZ)
	Text SX,SY+36,"Speed   X "+p1\pxspd+" Z "+p1\pzspd
	Text SX,SY+48,"Align   X "+p1\moveX+" Z "+p1\moveZ
End Function

Function loadamesh(file$,parent=0)
entity=LoadMesh(file$,parent)
If entity=0 Then RuntimeError "Failed to load "+file$
Return entity
End Function



_PJ_(Posted 2004) [#12]
You have to be careful with mouse-control, because the MouseX() and MouseY() can change so much between actually checking their positions.

This may be interesting:

http://www.blitzbasic.com/Community/posts.php?topic=31574


StOrM3(Posted 2004) [#13]
Thank you very much for all the help and info.. I think with all this info, I can paste something together to make it work for my game.

Thanks alot!!!

Ken


StOrM3(Posted 2004) [#14]
DJWoodgate or Malice, could one of you show me the example code above using models loaded from b3d files, and offset at 20 units, I am having a problem getting the example mouse code you posted to work using models I am loading from files, they seem to be offset incorrectly, and the mouse is not moving the player object around the outside, it just sits there stuck in the center of the screen.

I know I am a pain, but I really am stuck, I have looked at the code time and time again, and rewritten it so many times and am just plain stuck, don't know what is wrong, whether it is your code to move the mouse, that it doesn't work right with models, or something.

Ken


_PJ_(Posted 2004) [#15]
Graphics3D 640,480,0,2

Const keyLeftA=203, KeyRightA=205, KeyUpA=200, KeyDownA=208

texture=CreateTexture(128,128)
ScaleTexture texture,16,16
SetBuffer TextureBuffer(texture)
Color 0,0,80 : Rect 0,0,128,128 : Color 0,0,150
For i=0 To 1000 : Plot Rand(0,127),Rand(0,127) : Next

SetBuffer BackBuffer()

Dim grid(11,11)

arena=CreatePivot()
PositionEntity arena,0,10,0

Readgriddata()

For countx = 1 To 11
	For countz = 1 To 11
		If grid(countx,countz)=9 Then
			count=count+1
			If count=1 Then obj=CreateCube(arena) Else obj=CopyEntity(obj,arena) 
			EntityColor obj,100,0,50
			PositionEntity obj,(countx)*4,0,(countz)*4
		EndIf
	Next 
Next 

plane=CreatePlane(10)
EntityTexture plane,texture

player=LoadMesh("Mesh.b3d")
CurrX=1 : CurrZ=1 : pxspd#=0 : pzspd#=0
PositionEntity player,CurrX*4,0,CurrZ*4

light=CreateLight(2,player) 
LightRange light,20
PositionEntity light,0,10,0

camera=CreateCamera(arena)
PositionEntity camera,20,24,18
RotateEntity camera,90,0,0
CameraClsColor camera,50,50,160
move=False

HidePointer()
MoveMouse GraphicsWidth()/2, GraphicsHeight()/2

Repeat

If KeyDown(keyLeftA)	Then TurnEntity arena,0,-1,0
If KeyDown(keyRightA)	Then TurnEntity arena,0,1,0
If KeyDown(keyUpA)		Then TurnEntity arena,1,0,0
If KeyDown(keyDownA)	Then TurnEntity arena,-1,0,0


mxspd=MouseXSpeed()
myspd=MouseYSpeed()
MoveMouse GraphicsWidth()/2, GraphicsHeight()/2

pxSpd=pxSpd+mxspd*0.04 
pzSpd=pzSpd-myspd*0.04
pxSpd=pxSpd*0.8 
pzSpd=pzSpd*0.8

If Abs(pxspd)<0.01 Then pxspd=0
If Abs(pzspd)<0.01 Then pzspd=0
If Abs(pxspd)>2.0 Then pxspd=2.0 * Sgn(pxspd)
If Abs(pzspd)>2.0 Then pzspd=2.0 * Sgn(pzspd)

If mxspd<>0 Or myspd<>0 Then 
	move=True
	moveovertime=MilliSecs()+250
Else
	If MilliSecs()>=moveovertime Then move=False
EndIf

If move Then
	If grid(currX,currZ+Sgn(pzspd))>0 And grid(currX,currZ+Sgn(pzspd))<5
		CurrZ=Int((EntityZ(player)+Pzspd)/4.0)	
	Else 
		pzspd=0 : PositionEntity player,EntityX(player),0,CurrZ*4
	EndIf

	If grid(currX+Sgn(pxspd),CurrZ)>0 And grid(currX+Sgn(pxSpd),CurrZ)<5
		CurrX=Int((EntityX(player)+Pxspd)/4.0)
	Else
		pxSpd=0 : PositionEntity player,CurrX*4,0,EntityZ(player)
	EndIf
	
	TranslateEntity player,pxspd,0,pzspd
Else
	movex#=(CurrX*4-EntityX(player))*0.2
	movez#=(CurrZ*4-EntityZ(player))*0.2
	TranslateEntity player,movex#,0,movez#
	If Abs(movex#)<0.1 And Abs(movez#)<0.1 Then 
		PositionEntity player,CurrX*4,0,CurrZ*4
	EndIf
EndIf

Select grid(CurrX,CurrZ)
	
	Case 1	TFormVector  0,0,1,arena,0
	Case 2	TFormVector  1,0,0,arena,0
	Case 3	TFormVector -1,0,0,arena,0
	Case 4	TFormVector 0,0,-1,arena,0
	End Select

AlignToVector player,TFormedX(),TFormedY(),TFormedZ(),3,0.2

UpdateWorld
RenderWorld

Color 127,127,127
Text 0,0,EntityX(player)+" "+EntityZ(player)
Text 0,12,"Move? "+Move
Text 0,24,"GRID    X "+CurrX+" Z "+CurrZ+" VAL "+Grid(CurrX,CurrZ)
Text 0,36,"Speed   X "+PxSpd+" Z "+pzSpd
Text 0,48,"Align   X "+moveX#+" Z "+moveZ#

Flip
Until KeyHit(1)

End

Function readgriddata()
Read g$
While g$<>""
	For x=1 To Len(g$)
		grid(x-1,y)=Mid(g$,x,1)
	Next
	y=y+1
	Read g$
Wend
End Function

Data "00000000000"
Data "01111111110"
Data "02999999930"
Data "02999999930"
Data "02999999930"
Data "02999999930"
Data "02999999930"
Data "02999999930"
Data "04444444440"
Data "00000000000"
Data ""




Well I started, added an UpdateWorld, dunno if that affects it, but seeing as Im at work - I cannot test this. Also, I am a little wary of the AlignToVector commands and TForm stuff (I'm very new to these commands and am curious as to whether they affect the entity's ability to turn in this example - dunno, Dave!

I got a bit lost in this lot:
If move Then
	If grid(currX,currZ+Sgn(pzspd))>0 And grid(currX,currZ+Sgn(pzspd))<5
		CurrZ=Int((EntityZ(player)+Pzspd)/4.0)	
	Else 
		pzspd=0 : PositionEntity player,EntityX(player),0,CurrZ*4
	EndIf

	If grid(currX+Sgn(pxspd),CurrZ)>0 And grid(currX+Sgn(pxSpd),CurrZ)<5
		CurrX=Int((EntityX(player)+Pxspd)/4.0)
	Else
		pxSpd=0 : PositionEntity player,CurrX*4,0,EntityZ(player)
	EndIf
	
	TranslateEntity player,pxspd,0,pzspd
Else
	movex#=(CurrX*4-EntityX(player))*0.2
	movez#=(CurrZ*4-EntityZ(player))*0.2
	TranslateEntity player,movex#,0,movez#
	If Abs(movex#)<0.1 And Abs(movez#)<0.1 Then 
		PositionEntity player,CurrX*4,0,CurrZ*4
	EndIf
EndIf


_____________________________________________________



EDITED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!












Seems to work for me, though (the 'grid' data only allows for movement around the '0's outside edge if this is correct)


StOrM3(Posted 2004) [#16]
Malice, Could you explain how the Pivot thing actually works in your code, I have seen other people use them, but don't actually know what they are for. Also, would this code work the same, if instead of using cubes for the items, I loaded models for those items in the grid as well ? Note that all the models have to be scaled 3,3,3 when I load them, I think this is where I am running into problems with it, that and the fact the locations of the loaded models is not being set correctly, I think what is happening is the first model loaded is acting like the parent, is that what your pivot is for ? Arena that is . I'm sorry, I'm so lame about this, if it was in C/C++ I could figure it out probably faster, but some of the special things in Blitz trips me up, such as pivots etc..

Malice again, thanks for everything.


Ross C(Posted 2004) [#17]
A pivot is just a pont in 3d space. Just basically an invisible entity, that acts just like a normal entity. It can be scaled, moved ...etc etc. They are used as pointers and to hold places. Very useful stuff :)


DJWoodgate(Posted 2004) [#18]
Yes, Storm, I added the arena pivot, so you could move the whole kit and caboodle to wherever wanted in your world. Sorry to hear you are still having problems with it though, it was only an example. You may prefer a slightly different movement model (or indeed a completely different method) for your game. I make no claims for it being the definitive solution :)

Malice, Aligntovector expects world coords. As everything related to the grid is now parented to the arena pivot I needed to transform the alignment vectors from the arena to the world to account for the fact that the grid may not be aligned with the world axis. In any event it's all pretty rudimentary and player movement does not depend on orientation.

I got a bit lost in this lot:


Yes, probably needs a few more comments. :) Basicly it does not allow movement in a direction that is blocked. Player movement is only allowed on grid positions with the values 1 to 4. These values also define the direction to point the player. When movement has stopped for a certain amount of time it aligns the player position to the grid position. Other methods of movement could and perhaps should be used to ensure alignment. This was the easiest for me and it may correspond more or less well with Storms design goals :)

That being said I have modified the code above to load a couple of the Geometricks models that ship with blitz and now the player movement is in a function supported by the player type definition and I have added some variables to allow you to specify grid resolution, object sizes on the grid and the player size.


_PJ_(Posted 2004) [#19]
Thanks, David! That's really good, because I would liuke to get to grips with a lot of those vector-commands etc. I'm sure they'll be dead handy in th future!

It's a bit clearer, too, once I got home and was able to see it actually running!


StOrM3(Posted 2004) [#20]
YES, it worked great, I modified your original arena code to load one of my apple models for the cubes instead, and loaded my player bubble and it worked, they were a bit huge but it worked as expected with mouse control. I am going to copy and paste and check out your new code tonight, as I work during the days of the week, doing tech support. Thanks again for all your help, I think it is getting a bit more clear now.

Ken


StOrM3(Posted 2004) [#21]
I'm glad your adding comments, and helping to explain this vector stuff, and pivots etc.. I think I will definitely have to play with these, as these could be very useful in almost any game I write. Thanks alot! Both of you.. I really appreciate it, taking time to help a newbie to Blitz3D.. But oldie to programming in general. ;')


StOrM3(Posted 2004) [#22]
Tomorrow night I will be adding the latest code changes to the game, and hopefully after adding the player shoot code, and collision code, will be releasing the beta, DJ I would love to send you a copy free, for you to look at and tell me what you think, and for all your help, when I release the full version, I will send that as well.

Thanks,

Ken


StOrM3(Posted 2004) [#23]
Okay guys, one problem left. I have got all the movement working perfectly in my game project, and stuff, but the player shoot function... for some reason when I try to have the player move up and hit the objects, it is facing the wrong direction. No matter what I try, I even went to your case 1,2,3,4 statements and added a direction field to player, and put p1\direction = 1 etc.. in the case statement, then right after the moveplayer function in the main game loop I call PlayerShoot, which moves 0,0,10 which according to the docs, moveentity as long as the player is only rotated left or right, should move it forward 10 or -10 equals backwards, but for somereason, I made a simple test one, that only moves the player 1 to see where it is moving, and it will move 1 then return to original location which is what I want, but no matter whether I use rotateentity 0,90,0 or 180 or 270 whatever it is still facing either left or right or up depending whether on sides or top or bottom. Am I missing something here, how can I get the player pointed toward the objects in the center, and move the player up til it hits one, then remove the object and add points etc.. This msg is for DJWoodGate since you are most familiar with the code, that I based mine off of.

Thanks, if this is unclear, please let me know, I will try to elaborate more.

Ken