1
$\begingroup$

I have been trying to make a speedometer for a racing game I'm making, but all the methods of making a speedometer I know of don't work on the vehicle wrapper for some reason. It may be that there are either too little solutions to this problem posted to the internet or I'm terrible at coding in Python.

Here are some of the resources I've tried to use in several attempts.

Number one

Number 2

Number 3

Thanks to anyone who helps.

$\endgroup$
3
  • $\begingroup$ What is the issue: A) measuring the speed B) the display C) the communication between the A) and B) $\endgroup$
    – Monster
    Jan 10, 2017 at 6:32
  • $\begingroup$ Mostly A, I've tried a lot of ways to measure the speed to no avail. However I would love to have B explained as well, to know how to make a display like a real car speedometer. $\endgroup$ Jan 10, 2017 at 16:14
  • $\begingroup$ I will focus on A). You can find a possible solution on B) and C) at blenderartists.org/forum/showthread.php?249078 $\endgroup$
    – Monster
    Jan 11, 2017 at 6:29

1 Answer 1

4
$\begingroup$

How to measure speed

Speed by build-in Physics

When you let the build-in Physics engine calculate the motion of your game object (dynamic, rigid body etc.) you can directly ask the game object.

The object will provide you the current linear velocity (there is an angular velocity too). The linear velocity is a vector that tells you the direction and the speed the object traveled since the last frame. The speed is the length of the vector (speed can never become negative!).

import bge 

object = bge.logic.getCurrentController().owner
velocity = object.getLinearVelocity()
speed = velocity.length

Speed by positional change

In some situations you can't or do not want to use the build-in physics engine. In that case you can "manually" calculate the speed from positional changes.

This method assumes the object traveled from the location of the last frame to the current location with constant speed on a direct line. Typically this is a pretty save assumption (but it does not consider if the object really moved or teleported such as static objects do).

Here we use the school math:

speed = distance (last position, current position) / time

We need to record the current position, to be used within the formula of he next frame, while we use the recorded position of the last frame. The time is the reciprocity of the frame rate (typically 60):

time = 1/frame rate

This means you can calculate the speed this way:

import bge 

object = bge.logic.getCurrentController().owner
lastPosition = object.get("lastPosition", object.worldPosition)
object["lastPosition"] = object.worldPosition.copy()

step = object.worldPosition - lastPosition
speed = step * bge.logic.getLogicTicRate()

What to do with the speed?

Just now the speed is in a local variable and will get lost as soon as you leave local space.

From here you can place it in a property:

object["speed"] = speed

to be used within other Logic Bricks (including other Python code).

or you send it in a message:

bge.logic.sendMessage("speed changed", str(speed))

You can do that even with a message actuator:

messageActuator.body = str(speed)
controller.activate(messageActuator)

or any other logic brick.

How to get the speed for displaying?

Dependent what you did with the value, you can retrieve it an use it e.g. in a Text Object:

for body in messageSensor.bodies:
    textObject.text = body

or as property to play an action: for body in messageSensor.bodies: actionPlayer["frame"] = float(body)

.... There are really many options.

The message method is described in detail in the BGE Guide to Messages

$\endgroup$
1
  • $\begingroup$ I just noticed that there is a small mistake within the code you gave. In the one that says ' speed = velocity.length()' There should be no parentheses on this. $\endgroup$ Jan 14, 2017 at 20:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .