New Version messes up code?

Blitz3D Forums/Blitz3D Beginners Area/New Version messes up code?

Black Hydra(Posted 2004) [#1]
Well, mine at least. Something must have changed in the new version as when I updated my rotation is no longer smooth and nice but barely working and appears like it is running at .01 FPS (A check says it is still running normally though...)

Here is my rotation code, maybe if someone can see if I've made a wrong move that is causing this, or perhaps my understanding of it is wrong. Because as far as I can tell my rotation code was unchanged after I updated.

Here it is:

M# = User\Manuever
;Movement style using mouse speed rather than position
YAng# = EntityYaw(User\ObjectNum)-M#*MouseXSpeed()
XAng# = EntityPitch(User\ObjectNum)+M#*MouseYSpeed()
If XAng# > 70 And XAng# < 180 Then XAng# = 70
If XAng# < 290 And XAng# > 180 Then XAng# = 290
RotateEntity User\ObjectNum, XAng#, YAng#, 0

The User\ObjectNum is my handle for my spaceship object, and the User\Maneuver is currently a constant at 0.5 (basically a mouse-sensitivity value). The weirdest thing is that it worked fine before I updated. Now it looks awful.

Here is my full code. While I don't expect anyone to read it, you guys are the experts not me, so if the error would lie somewhere else maybe you guys can help.

Start.bb is the starting code that comes with the Blitz demo (a very handy bit of code I must say ;) )

I'll post vector.bb at the end, however I can't see how it affects this.

;Include the vector mathematics library
Include "vector.bb"
;Include the blitz basic demo start code
Include "start.bb"

;Setup all non-type global variables
Global CameraHandle = 0
Global ScreenWidth = 640
Global ScreenHeight = 480
;Friction will be used to slow the ship. 1 is no friction, 0 is absolute friction
Global Friction# = .5
;Default Sync
Global SyncRate# = 100

;Collision Variables
Global TYPE_BOX = 1
Global TYPE_PLAYER = 2
Global TYPE_BULLET = 3
Collisions TYPE_PLAYER, TYPE_BOX, 3, 1

;--------------------------------
;---------MAIN PROGRAM-----------
;--------------------------------
GameEnds = 0
User.Player = SetupGame()
Repeat
StartSync# = MilliSecs()
;===========

ControlPlayer(User)
UpdateCamera()
;===========

;Use a counter as AI modifications aren't necessary every loop
AICounter = AICounter+1
If AICounter > 5
AICounter = 0
RunAllAI()
EndIf
;The AI is modified every 5 loops. Enemies are controlled every loop, however.
RunAllEnemies()

;===========

RunAllMissles(User)
RunAllExplosions()

;===========

GameEnds = Triggers()

;===========
UpdateWorld
UpdateVariables(User)
RenderWorld
Flip
;===========
SetSync(StartSync#)
Until GameEnds Or KeyHit(1)
End
;--------------------------------
;================================
;--------------------------------

;TYPES
;Player Type
Type Player
Field X# ;x position
Field Y# ;y position
Field Z# ;z position
Field Move.Vector ;vector controlling movement
Field Rotation.Vector ;vector controlling current rotation
Field Thrust.Vector ;vector controlling the thrusting
Field Manuever# ;regulates the factor by which the object can pivot
Field Speed# ;regulates speed by using this as a maximum value
Field Health ;the players health
Field ObjectNum ;the object number
Field CameraPivot ;the entity number of the pivot controlling camera movement
Field BrushNum ;the brush number holding texture and data
Field AttackReflex ;controls time since last attacking
Field StunReflex ;controls time since recovering from an attack
Field Lasers.Missle
End Type

;Enemy Type
Type Enemy
Field X# ;x position
Field Y# ;y position
Field Z# ;z position
Field Move.Vector ;vector controlling movement
Field Rotation.Vector ;vector controlling current rotation
Field Impulse.Vector ;vector controlling AI impulse behavior
Field Speed# ;regulates speed by using this as a maximum value
Field Manuever# ;regulates the factor by which the object can pivot
Field Health ;the enemy's health
Field ObjectNum ;the object number
Field BrushNum ;the brush number holding texture and data
Field AttackReflex ;controls time since last attacking
Field StunReflex ;controls time since recovering from an attack
Field Species ;used to regulate what type of AI actions to take
; 0 = Red (swarming) :: 1 = Blue (sneaker) :: 2 = Green (missler)
Field Projectile.Missle ;stores the type of projectile the object uses
Field AI ;This value is used to determine what action the enemy performed
End Type

;Missle Type
;A type used to represent projectile fire
Type Missle
Field X# ;x position
Field Y# ;y position
Field Z# ;z position
Field Move.Vector ;vector controlling movement
Field Rotation.Vector ;vector controlling rotation (arcing projectile)
Field Speed# ;controls the speed of the missle
Field Maneuverability# ;controls the pivoting capabilities of arcing projectiles
Field ObjectNum ;stores the object number of the projectile
Field BrushNum ;stores the brush number (or texture number) of the projectile
Field Detonate.Explosion ;stores the explosion type of the projectile on impact
Field Damage ;controls the power of the missle
Field Effect ;controls the effect of the missle
Field Reflex ;controls the time since firing the missle
Field Species ;used to regulate what type of movement the missle follows
Field Initialized ;Flag storing whether the missle has been initialized or not
End Type

;Explosion Type
Type Explosion
Field X# ;x position
Field Y# ;y position
Field Z# ;z position
Field Damage ;controls the damage of the explosion
Field Size# ;controls the maximum size of the explosion,speed and duration
Field ObjectNum ;stores the object number of the explosion
Field BrushNum ;stores the brush number of the explosion
Field SoundHandle ;stores the sound handle of the explosion
Field Effect ;controls the effect of the explosion
End Type

;Functions
Function ControlPlayer(User.Player)
;This function acts upon the user input and applies the appropriate
;action
;INPUT
Firing = 0
Thrusting = 0
Strafe = 0
If Not KeyDown(2) Then MoveMouse ScreenWidth/2, ScreenHeight/2
If KeyDown(57) Then Firing = 1
If MouseDown(1) Then Thrusting = 1
If MouseDown(2) Then Strafe = 1
;Position the camera pivot
PositionEntity User\CameraPivot, User\X#, User\Y#, User\Z#
;Fire lasers
If Firing = 1 And MilliSecs()-User\AttackReflex > 500
User\AttackReflex = MilliSecs()
;Set up the basic missle. It will be run in RunAllMissles()
;Add more code if the missle has explosions, arcing, ect.
Laser.Missle = New Missle
Laser\X# = User\X#
Laser\Y# = User\Y#
Laser\Z# = User\Z#
Laser\Speed# = User\Lasers\Speed#
Laser\ObjectNum = CopyEntity(User\Lasers\ObjectNum)
PositionEntity Laser\ObjectNum, Laser\X#, Laser\Y#, Laser\Z#
Laser\Move = New Vector
Laser\Rotation = New Vector
Laser\Move = CopyVect(Laser\Move, User\Rotation)
Laser\Move = ScaleVect(Laser\Move, Sync(Laser\Speed#))
Laser\Initialized = 1
EntityType Laser\ObjectNum, TYPE_BULLET
EntityRadius Laser\ObjectNum, .5
EndIf
;Apply Rotation
If Not Strafe
M# = User\Manuever
;Movement style using mouse speed rather than position
YAng# = EntityYaw(User\ObjectNum)-M#*MouseXSpeed()
XAng# = EntityPitch(User\ObjectNum)+M#*MouseYSpeed()
If XAng# > 70 And XAng# < 180 Then XAng# = 70
If XAng# < 290 And XAng# > 180 Then XAng# = 290
RotateEntity User\ObjectNum, XAng#, YAng#, 0

;Set the rotation vector to the current orientation
User\Rotation = AngToVect(WrapAngle(YAng#-90), XAng#, User\Rotation)
;AlignToVector User\CameraPivot, User\Rotation\X#, User\Rotation\Y#, User\Rotation\Z#, 1, .5
;AlignToVector User\CameraPivot, User\Rotation\X#, User\Rotation\Y#, User\Rotation\Z#, 2, .5
EndIf

;Add to Thrust Vectors
If Thrusting
If Strafe
;If the player has strafing engines on the thrust vectors will lie perpendicular to the rotation

Else
;For normal movement the thrust vector is simply a magnitude of the rotation vector
User\Thrust = CopyVect(User\Thrust, User\Rotation)
User\Thrust = ScaleVect(User\Thrust, (Sync(User\Speed#)-VectLength(User\Move))*.025)
EndIf
EndIf

;Calculate and reposition movement
User\Move = ScaleVect(User\Move, 1.0-Sync(Friction#))
;Stop ship if it is moving too slowly
If VectLength(User\Move) < 3*Sync(Friction#) Then User\Move = ScaleVect(User\Move, 0)
User\Move = AddVect(User\Move, User\Thrust, User\Move)
User\Thrust\X# = 0
User\Thrust\Y# = 0
User\Thrust\Z# = 0
User\X# = User\X# + User\Move\X#
User\Y# = User\Y# + User\Move\Y#
User\Z# = User\Z# + User\Move\Z#
PositionEntity User\ObjectNum, User\X#, User\Y#, User\Z#
;Update Camera
PointEntity CameraHandle, User\ObjectNum
End Function

Function UpdateCamera()
;This function updates the camera


End Function

Function EnemyAI(AI.Enemy)
;This function will be run to determine what the enemies will do
;It will send the result to the ControlEnemy() function

End Function

Function ControlEnemy(Num.Enemy)
;This will control physics for the enemy based on their AI reaction

End Function

Function ControlExplosion(Num.Explosion)
;This will run a specified explosion

End Function

Function RunAllAI()
;This will run all of the specified AI's

End Function

Function RunAllEnemies()
;This will run all of the enemies

End Function

Function RunAllMissles(User.Player)
;This will run every missle

For Missles.Missle = Each Missle
If Missles\ObjectNum > 0 And Missles\Initialized = 1
If EntityDistance(Missles\ObjectNum, User\ObjectNum) < 500
;If the missle is still active then run it
X# = Missles\X# + Missles\Move\X#
Y# = Missles\Y# + Missles\Move\Y#
Z# = Missles\Z# + Missles\Move\Z#
PositionEntity Missles\ObjectNum, X#, Y#, Z#
Missles\X# = X#
Missles\Y# = Y#
Missles\Z# = Z#
If EntityCollided(Missles\ObjectNum, TYPE_BOX)
DestructEntity = CollisionEntity(Missles\ObjectNum, 1)
FreeEntity Missles\ObjectNum
Delete Missles
FreeEntity DestructEntity
DebugLog "A cube has been destroyed!"
EndIf
Else
FreeEntity Missles\ObjectNum
Delete Missles
EndIf
EndIf
Next
End Function

Function RunAllExplosions()
;This will run every explosion

End Function

Function Triggers()
;This function basically checks to see whether the player has reached the goal
;and to see whether the player has died.
;It may serve as a simple template for other triggers in the full version

End Function

Function SetupGame.Player()
;This function sets up the game it is used as a more primitive function which
;will later be used for more advanced world loading commands
;Set up the player object
SeedRnd(MilliSecs())
User.Player = New Player
User\Move = New Vector
User\Thrust = New Vector
User\Rotation = New Vector
User\Health = 6
User\ObjectNum = LoadMesh("spaceship.x")
User\BrushNum = LoadBrush("spaceship.bmp")
User\CameraPivot = CreatePivot()
EntityType User\ObjectNum, TYPE_PLAYER
EntityRadius User\ObjectNum, 2.0
PaintEntity User\ObjectNum, User\BrushNum
User\AttackReflex = MilliSecs()
User\StunReflex = MilliSecs()
User\Speed# = 60.0
User\Manuever# = .5
User\Lasers = New Missle
User\Lasers\ObjectNum = LoadSprite("big_spark.bmp")
HideEntity User\Lasers\ObjectNum
User\Lasers\Speed# = 100.0
;Setup Camera stuff
CameraHandle = CreateCamera(User\CameraPivot)
PositionEntity CameraHandle, 0, 0, -30
PointEntity CameraHandle, User\ObjectNum
;Set up some cubes for spacial orientation
For Counter = 1 To 100
Num = CreateCube()
X# = Rnd(-150, 150)
Y# = Rnd(-150, 150)
Z# = Rnd(-150, 150)
PositionEntity Num, X#, Y#, Z#
EntityBox Num, X#, Y#, Z#, 5.0, 5.0, 5.0
EntityType Num, TYPE_BOX
Next
Return User
End Function

Function UpdateVariables(User.Player)
;This will refresh all the variables for positions after collisions
;Refresh the player
User\X# = EntityX(User\ObjectNum)
User\Y# = EntityY(User\ObjectNum)
User\Z# = EntityZ(User\ObjectNum)
;Refresh the missles
For Missle.Missle = Each Missle
Missle\X# = EntityX(Missle\ObjectNum)
Missle\Y# = EntityY(Missle\ObjectNum)
Missle\Z# = EntityZ(Missle\ObjectNum)
Next
End Function

;////////Sync Functions/////////

Function Sync#(Value#)
;This function will sync a value based on the syncrate
Return Value#/SyncRate#
End Function

Function SetSync(StartSync)
;This will set up the SyncRate values and smooth them with the last sync value
;to prevent jerkiness
If MilliSecs()-StartSync > 1
SyncRate# = (SyncRate#*.5)+((1000.0/(MilliSecs()-StartSync))*.5)
Else
SyncRate# = 1000.0
EndIf
DebugLog SyncRate#
End Function

-----------------------------

Vector.bb, Yeah I know I need to cleanup the function set. It may seem a little rough, but I didn't want any of the functions to be creating new Vectors for there calculations. I'll probably just make a calculatory vector later, but anyways here it is:

;Vector Library#

;------VECTOR MATHS------
;Vector Ty#pe used for 3D mathematics
Type Vector
Field x#
Field y#
Field z#
End Type

;Simple 3D maths functions
;This function adds two vectors together
Function AddVect.Vector(Vect1.Vector, Vect2.Vector, Transfer.Vector)
Transfer\x# = Vect1\x# + Vect2\x#
Transfer\y# = Vect1\y# + Vect2\y#
Transfer\z# = Vect1\z# + Vect2\z#
Return Transfer
End Function

;This function subtracts the second vector from the first
Function SubVect.Vector(Vect1.Vector, Vect2.Vector, Transfer.Vector)
Transfer\x# = Vect1\x# - Vect2\x#
Transfer\y# = Vect1\y# - Vect2\y#
Transfer\z# = Vect1\z# - Vect2\z#
Return Transfer
End Function

;This function multiplies the vector by a scalar
Function ScaleVect.Vector(Vect1.Vector, Value#)
Place.Vector = New Vector
Place\x# = Vect1\x# * Value#
Place\y# = Vect1\y# * Value#
Place\z# = Vect1\z# * Value#
Vect1\x# = Place\x#
Vect1\y# = Place\y#
Vect1\z# = Place\z#
Delete Place
Return Vect1
End Function

;This function will determine the length of the given vector
Function VectLength#(Vect1.Vector)
Length# = Sqr(Vect1\x#^2 + Vect1\y#^2 + Vect1\z#^2)
Return Length#
End Function

;This function will turn a set of x# and y# angles into a normal
Function AngToVect.Vector(yAngle#, xAngle#, Vect1.Vector)
;Find the YValue and Radius
Vect1\Y# = -Sin(XAngle#)
Radius# = Cos(XAngle#)
Vect1\X# = -Cos(YAngle#)*Radius#
Vect1\Z# = -Sin(YAngle#)*Radius#
Return Vect1
End Function

;This function normalizes a vector
Function Normalize.Vector(Vect1.Vector)
Length = Sqr(Vect1\x#^2 + Vect1\y#^2 + Vect1\z#^2)
Vect1\x# = Vect1\x# / Length
Vect1\y# = Vect1\y# / Length
Vect1\z# = Vect1\z# / Length
Return Vect1
End Function

;This function will return an equality based on the vectors
Function Equality(Vect1.Vector, Vect2.Vector, Transfer.Vector)
Vect1 = SubVect.Vector(Vect1, Vect2, Transfer)
If Not Vect1\x# = 0
Return False
Else If Not Vect1\y# = 0
Return False
Else If Not Vect1\z# = 0
Return False
Else
Return True
EndIf
End Function

;This Function turns the vector into a formatted String For debug purposes
Function FormatVect$(Vect1.Vector)
VectorString$ = "[x#]"+Vect1\x#+" [y#]"+Vect1\y#+" [z#]"+Vect1\z#
Return VectorString$
End Function

;This function will return a rotation vector given an entity
Function EntityRotVect.Vector(Entity, StoreVect.Vector)
Pivot = CreatePivot(Entity)
RotateEntity(Pivot, EntityPitch(Entity), EntityRoll(Entity), 0)
MoveEntity(Pivot, 0, 0, 1)
StoreVect\X# = EntityX(Pivot, True) - EntityX(Entity, True)
StoreVect\Y# = EntityY(Pivot, True) - EntityY(Entity, True)
StoreVect\Z# = EntityZ(Pivot, True) - EntityZ(Entity, True)
FreeEntity(Pivot)
Return StoreVect

End Function

;This function sets the length of a vector
Function SetVectLength.Vector(Vect.Vector, Length)
Vect = Normalize(Vect)
Vect = ScaleVect(Vect, Length)
Return Vect
End Function

;This function returns the relative angle between 0 and 360 degrees
Function WrapAngle#(Angle#)
;First turn the angle into a value between -360 and 360
Angle# = Angle# Mod 360
;Now turn negative values into positive ones
If Angle# < 0 Then Angle# = Angle#+360
Return Angle#
End Function

;This function copies the contents of one vector to another
Function CopyVect.Vector(Hold.Vector, Copy.Vector)
Hold\X# = Copy\X#
Hold\Y# = Copy\Y#
Hold\Z# = Copy\Z#
Return Hold

End Function


DJWoodgate(Posted 2004) [#2]
Your pitch control looks suspect. Please explain what it is supposed to do (bearing in mind that Entitypitch will never return values less than -90 or more than +90).


Because as far as I can tell my rotation code was unchanged after I updated.


Gremlins?


WolRon(Posted 2004) [#3]
Check the FAQ page What are the forum codes? for the forum codes such as [codebox][/codebox[


DJWoodgate(Posted 2004) [#4]
Looking at the code you are using movemouse just before you capture mousexspeed and mouseyspeed. They will not have much time to capture movement unless you move the mouse a lot. Maybe that is what you changed, in which case your rotation code may be ok.


Black Hydra(Posted 2004) [#5]
Okay I'll try some of your guys suggestions.

I didn't realize EntityPitch() only returned -90 to 90 degrees, I'll have to take that into account when I plan future code.

I don't think I changed the Move Mouse code, however placing it after the rotation calculation code couldn't hurt.

I'll try all of that and then tell you if it worked, thanks guys.


Black Hydra(Posted 2004) [#6]
Thanks guys, the object rotation works now. Onto my multitude of other problems and bugs!