Tag Archives: code snippet

Avoiding Cracking Under Pressure

Sometimes, when working on a project, you get stuck.

The Problem

Recently, I was working on (what should have been) an elementary programming exercise: get the player to rotate around an object in 3D when a key is held down. I’d immediately started tackling the problem from the angle of “OK, how do I rotate around an arbitrary axis?”. Big mistake.

It’s pretty easy to make an error (or twenty) when you’re writing this out in code: (Image source)

For days, I just could not get the code to work. The player quickly developed a knack for teleporting all over the place, but despite his new-found skills with wizardry, he still wouldn’t rotate around the ball.

The Solution

Eventually, I gave up and stepped away from the problem for a while. A few days later, after a full night’s rest, I sat down in front of my laptop, scrapped all the code I had, and started from scratch. I got it working in less than an hour.

Lesson learned: Sometimes, you need to step back and take a break. In retrospect, I feel kind of silly for getting stuck for a few days on this one. :)

Here’s the (somewhat unoptimized) code to calculate the offset to move by each frame:

// Helper method to re-calculate the translation vector each frame while the
// player is rotating around the ball
// returns the offset the camera should move by
Ogre::Vector3 FrameUpdateListener::calculateRotation() {
 // get player position
 const Ogre::Vector3 playerPosition = GameState::getInstance()->getPlayerCamera()->getPosition();

 // get ball position
 const Vector3D* const pBallPosition =
 GameState::getInstance()->getBall()->getBoundingVolume()->getCenter();
 const Ogre::Vector3 ballPosition(pBallPosition->x, pBallPosition->y, pBallPosition->z);

 // get vector for player relative to ball
 const Ogre::Vector3 localPlayerPosition = playerPosition - ballPosition;

 // get theta (angle to rotate by)
 const int direction = isRotatingClockwise ? 1 : -1;
 const Ogre::Radian theta(static_cast<Ogre::Real>(direction * 0.05f)); // angle to adjust by

 // store cos/sin in temp variables to save calculations
 const Ogre::Real cosTheta = Math::Cos(theta);
 const Ogre::Real sinTheta = Math::Sin(theta);

 // calculate new player position
 // (rotate player position around Y axis)
 Ogre::Vector3 newPlayerPosition;
 newPlayerPosition.x = cosTheta * localPlayerPosition.x - sinTheta * localPlayerPosition.z;
 newPlayerPosition.z = sinTheta * localPlayerPosition.x + cosTheta * localPlayerPosition.z;
 // newPlayerPosition.y = localPlayerPosition.y; // commented to save the calculation, uncomment if you need this later for some bizarre reason

 // calculate dx and dz
 Ogre::Real dx = newPlayerPosition.x - localPlayerPosition.x;
 Ogre::Real dz = newPlayerPosition.z - localPlayerPosition.z;

 // return the offset vector
 return Ogre::Vector3(dx, 0, dz);
}

Lua – Guess My Number

I was messing around with Lua tonight, and as a basic exercise threw together a Guess My Number game. Unfortunately, WordPress.com doesn’t have syntax highlighting for Lua. C’est la vie!

I also learned that the first number you grab from math.random() may not be properly randomized after seeding. Running my code in the interpreter generated 36 five times in a row as the answer, which clued me in to this :) Calling math.random() once after seeding seems to fix it, though.

-- Guess My Number
-- Author: Zachary Hoefler

--INITIALIZATION
-- Generate a random number
math.randomseed( os.time() )
math.random(); -- make sure first number is actually randomized (some implementations
               -- require this, but it doesn't break ones that don't)
local THE_NUMBER = math.random(1,100) -- generates a number from 1 to 100, inclusive

-- Welcome the user
print("Guess My Number, by Zach Hoefler")

-- MAIN GAME LOOP
local guess = nil -- explicitly declared to make it local
while (guess ~= THE_NUMBER) do
   -- prompt for a guess; use io.write() so there's no newline after the prompt
   io.write("Please enter a guess from 1-100: ");
   guess = io.read("*number")

   -- Compare to the correct number
   if guess > THE_NUMBER then
      print("You guessed too high!")
   elseif guess < THE_NUMBER then
      print("You guessed too low!")
   end
end
-- Number was guessed correctly
assert(guess == THE_NUMBER)

-- Congratulate the user
print("Congratulations, you guessed correctly!")

Strictly speaking, I could’ve used repeat-until instead of while, but the while loop felt a bit more readable.

Learning Lua

Sticking to my plans, I’ve begun teaching myself Lua. Although it’s a bit odd to wrap my head around after just diving head-first into C++, it’s pretty cool!

One lesson I’ve learned (or, rather, had reaffirmed) is how important writing clean code is. Given Lua doesn’t require semicolons to separate statements and doesn’t use braces, you can get away with some really sloppy, hard-to-read stuff. The following are all equivalent:

-- Easy to read factorial function
function fact (n)
   if n == 0 then
      return 1
   else
      return n * fact(n-1)
   end
end
-- Hard to read, but simple enough where you could probably figure it out
function fact (n) if n == 0 then return 1 else return n * fact(n-1) end end
-- Oh boy.
function
fact
(n) if n ==
0 then return
1 else
return n *
fact(n
-1) end

end

Having only really worked with C#, C++, Java, and ActionScript, it’s going to take some effort getting used to the syntax of Lua; however, I’m up for the challenge!