Blender itself does a lot of maths. Every time you move an object, it has to store the location, rotations,scales and everything else about what you've done. For a computer, all this is maths.
Maths is also a large part of game programming. Thankfully, blender game engine does all the hard stuff (like physics), leaving us to just do the easy things (like how fast you want an object to go).
So let's have a look at how we can edit logic bricks, and do some simple maths as well.
You have a motion logic brick, and want to change the speed more smoothly, like a throttle for a car, rather than on or off.
How do we do this? Well, the simpelest way is to have a game property (something like speed), and to feed it's value into the speed you want your car/player/object to move.
Set up the blend:Edit
We want a dynamic object with the following logic:
- Always -> Python (script mode) -> Motion Actuator (servo motion mode)
- Keyboard(uparrow) -> AND -> property ('speed' add 1)
- Keyboard(downarrow) -> AND -> property ('speed' minus 1)
An image of this setup is to the right.
In our script we need to do several things:
- Get the value of the speed property
- Get the motion logic brick
- Do some maths on the speed property
- Set the Y speed value of the logic brick to equal the new value
So let's start the way we normally do:
import bge cont = bge.logic.getCurrentController() own = cont.owner
Here's a new bit, how to get the motion actuator. We know that it belongs to the object we called 'own', we know it's an actuator, and we know it's called 'Motion.' We can put this knowledge in python syntax and get it like:
movement_brick = own.actuators['Motion']
Notice the similarities to how we get an object property? That's because both the property list and the actuator list are dictionaries. I'll explain how to use dictionaries later.
Now we get the speed value:
speed = own['speed']
If we plug this value straight into our logic brick, it will go pretty fast. We want to smooth things out a bit, maybe give it a different speed model, say, as it goes faster, the rate at which speed increases goes down. We can do this by taking the sqare-root of the speed value. To avoid importing the math module for a single function, we can instead do the speed to the power of a half:
speed = speed ** 0.5
As you can see, the syntax for 'the power of' is two asterisks. So if we want to square something, we use **2. If we want to cube something, it's **3 and so on. Other useful operators are: + (add), - (subtract), * (multiply), / (divide), % (modulus/remainder).
Now we have this value, we want to send it to the motion actuator. We do this by setting the linear velocity:
motion_brick.linV = [0,speed,0]
Notice the extra zero's? Those are for the x and y components of the motion actuator.
You may think you're done now and try to play the game, but if you do, nothing will happen. Do you know why? It's because you haven't activated the actuator yet!
Most sensors will automatically activate any controller plugged into them, because, well, otherwise they wouldn't do anything. But with a python controller, we can specify whether to activate an actuator or not.
So let's activate it:
Now our cube should move like we expect.
If you ever want to deactivate it, you can do so using:
How did I know?Edit
How did I know that to access the motion of a motion brick I had to use .linV? How did I know that there is the attribute '.actuators' for a game object?
Simply, I looked at the game engine API . In there you can see a list of all the various attributes each type of object has. In this case it was a servo motion logic brick , but there are loads of others ....
- Make the speed half the square root.
- Add in side to side motion using a similar method
- Instead of setting the speed equal to the property, use the property to specify how much you want the speed to change. (so if the property is 1, it will increase speed every frame until the property is 0). Tip: Get the existing speed of the actuator.