Moving backgrounds, different speeds

Back when I was younger (which is an obtuse way of saying “I haven’t the friggin’ idea exactly when”), I dabbled a bit in game development. There was a period when I was studying side scroller games. Remember those? The classic Super Mario Brothers was one of them.

I also noticed that in some of the games, the backgrounds moved. Yes, backgrounds, plural. I could understand forming a background “tile” made up of hills, clouds, trees, grass, flowers, rocks and whatever suited the game as background. But there was something, else, moving in the (for lack of a better word) background.

There was another background layer, moving at a different speed. Wait. Oh, it’s moving at a slower speed.

When I moved that little sprite (that’s representing my sole means of interacting with the game) on the screen to the right, the flowers and trees and rocks sped past to the left. But that faraway mountain was moving to the left at a slower speed. And the overall effect was a realistic simulation of 3D, a semblance of depth in an essentially 2D game.

Now that I think about it, I have one question. How do you calculate how slow the other background should be? I searched high and low, though I found what this effect is called (parallax scrolling), I found no trace of any suggestion to the relative speeds between the 2 backgrounds.

So I did a little thinking. And drawing. I was trying to work out mathematically the slower speed, given the “distance” between the background layers (there’s practically no distance in implementation. Maybe 0.01 units…) and the speed of the background that’s “in front”.

It didn’t make sense, because no matter how I pivot the movement, the calculations don’t work out.

Parallax scrolling backgrounds

L1 and L2 are the “distances” between the respective layers. d1 and d2 are the distances from the objects in question to the perpendicular line formed by the sprite position. v1 and v2 are the velocities of the respective layers moving to the left (or right, depending on how you view this whole thing and how you define the direction… never mind).

The layers aren’t really separate. There is a tiny distance between the layers, say 0.01 units. If you’re in a fully 2D environment, then the farthest layer is drawn, then the next closest layer is drawn, subject to transparency to allow elements from the farthest layer to be shown, and then the playing layer is drawn (where our sprite and other objects are). There’s no distance (between the layers) to speak of in a true 2D rendering environment.

I started with the “don’t move the focus, move everything else” approach, keeping the sprite in place, and moving both backgrounds to the left. This meant pivoting around the sprite. The objects drawn on the other two layers are what our sprite would see in a straight line towards somewhere forward. Those objects should coincide at the “perpendicular” line together.

Since the distances d1 and d2 are obviously different, therefore the velocity (or speed. I’m just trying to be scientifically correct here) of the two objects moving to the left must be different. There lies my problem. It meant the farthest object had to travel faster, contradicting our original observation.

What if we pivoted around the object in the “front” layer? The sprite moves to the right, and the object on the “back” layer moves to the left, and all three line up in a perpendicular line (perpendicular to the layers anyway). Too troublesome. Same with pivoting around the farthest object.

I toyed with the idea of pivoting around the vanishing point. At this point (no pun intended), I decided to give up.

So I assumed that the background image(s) in the “back” layer are appropriately sized with respect to the “front” layer. I decided a simple ratio probably worked best. Thus we have
v2 = v1 / (L1 + L2)
which should give an appropriately slowed velocity.

And now, finally, I’m telling you this. It might not matter. What matters is that you test the velocities, and if the 2 background layers scroll at a pleasing velocity, then there you have it. Ultimately, we’re just trying to simulate a 3D perspective given a 2D environment. If it’s believable, then that’s the correct velocity.

Math, culture and programming languages

Can a programmer’s background determine whether he’ll be a great programmer? By background, I mean his upbringing, the values learnt, his primary (and perhaps secondary) spoken/written language and so on.

I don’t know. However, I have arguments for and against the proposition. Let’s start with…

Learning to count

You think counting is easy? Apparently not. Recently I read a book, Outliers by Malcolm Gladwell. According to Gladwell, American children the age of four can, on average, count up to fifteen. Chinese children at that age can, on average, count up to forty.

His reasoning is that, the system of naming numbers is different in English and in Chinese.

For example, think about counting from twenty to thirty (I’m deliberately using the English form instead of the Arabic numerals to highlight the difference). You have twenty, twenty one, twenty two and so on till twenty nine and thirty. How about thirty to forty? Thirty, thirty one, thirty two and so on till thirty nine and forty.

Consider counting from ten to twenty. Ten, eleven, twelve, thirteen and so on till eighteen, nineteen and twenty. The pattern is different and irregular.

Before I show you the Chinese method of counting, let me show you the first 10 numbers, shown by the Arabic numeral, the English name and the (closest) Chinese pronunciation I can give:

1 one (yi, like in “yeast”)
2 two (er, like in “brighter”)
3 three (san, “sahn”)
4 four (si, do a short hissing sound with the s)
5 five (wu, “woo” and keep it short)
6 six (liu, “li” and “ou” as in “shoulder”, and string li-ou together quickly)
7 seven (qi, “cheese” without the s, and shorter in length)
8 eight (ba, as in “barter”)
9 nine (jiu, “gi” as in “gin” and “ou” as in “shoulder”. Like that of six.)
10 ten (shi, like that of four, with the h)

There are actually 4 tonal inflections for a Chinese character pronunciation, and we’ll ignore that for this discussion.

So to count in Chinese from ten to twenty, we have shi, shi yi, shi er, shi san, shi si, shi wu, shi liu, shi qi, shi ba, shi jiu, er shi. They are literally “ten”, “ten one”, “ten two”, “ten three” and so on till “ten nine” and “two ten”. There’s an implicit “one” in front of the “ten”, so it’s “one ten one” for eleven. For twenty three, it’s “er shi san”, or literally “two tens and three”.

Gladwell says this gives structure to the counting system, so children are able to grasp larger numbers quicker. The faster you can count to larger numbers, the more operations you can do on them. Additions, subtractions, summations and so on.

Ok, I’m not saying the Chinese number naming system is better than the English system. It’s just different. Gladwell says this difference also makes memorising short number sequences easier. For example, I can remember my Identification Card Number (equivalent to the Social Security Number in America) easier in Chinese than in English.

It explains why when someone asks for my phone number in English, I have a problem. Because I’m mentally translating my memory of the phone number from Chinese to English. Did you know it’s kinda hard to say out 8 digits in English while translating them from a Chinese memory? I can even mentally picture the numbers. It’s the speaking out that’s taking up mental processing time.

Gladwell also made a point about Cantonese (a Chinese dialect) pronunciation of numbers. So I tried saying out numbers in Cantonese (yes, I’m multilingual), and wow, it is easier to say and memorise! The Cantonese pronunciation of numbers are short in length, which makes it easier to spit them out *smile*

And the relation to programming? Programming is made up largely of counting and solutions formed from abstract ideas. When I first learned C, I was surprised that many fellow students had difficulty counting the number of iterations in say,

for (i=0; i<10; ++i)
	if (i>7) break;
	// do something

Counting and iterating leads to lists of data, or sets of data. In SQL, you can manipulate sets of data as if it’s one unit, abstracting away the fact that the data is actually iterated one by one. For example, you can select information from another data set, or a subquery as it’s known.

Of course, there are still some people who have difficulty visualising SQL data sets as one unit, hence their need to iterate over that one record by one record at a time, even when there’s no need. What does that tell you about these people?

Hard work is valued

Gladwell also made a point about culture. That successful people seem to grow up with a culture of valuing hard work. The ability to think on a problem long enough to come up with a solution.

He said something worth thinking about. There’s a educational researcher by the name of Erling Boe at the University of Pennsylvania. Boe says that one can know if a child will do well in math without asking that child a single math question.

The example in the book was a fictional Math Olympics. Before the test, there was a questionnaire to be filled in. There were tons of questions inside, none related to math. Boe asserts that a child who finishes that questionnaire will also do correspondingly just as well in the math test.

It’s a question of perseverance, the willingness to put one’s mind to work, even if one doesn’t feel like it.

Hard work is something valued in the countries of “wet-rice agriculture and meaningful work”, as Gladwell puts it. Based on the research of Boe, the top countries are Singapore (yay!), South Korea, Taiwan, Hong Kong and Japan. Though I’m not so sure of my fellow countryman’s motivations… The parents and children could be driven more by the race for top scores rather than the culture passed on by our forefathers.

Well, I haven’t read much on Boe’s research, but the hardworking nature of my countrymen is fairly accurate. Students are willing to study for long periods of time (most of them anyway…). Adults are willing to work just a little longer, a little harder at work. For example, I recently knew that my friend worked overtime till 4 am at the office. Personally, I think that’s crazy, but to each his (in this case, her) own.

The native language

There was a question in StackOverflow about coding in other spoken languages, which was highlighted in Jeff and Joel’s recent podcast.

The reserved words in a programming language are fixed. Usually they are in English, though there are programming languages in say Chinese. I didn’t know there was a Chinese version of BASIC!

Once, I took up an SQL reference book, written in Chinese. I want to mention that I cannot read a programming reference book written in Chinese. That is to say, I can certainly read the Chinese characters, but I can’t understand the heck what it means.

I need a reference book written in English for SQL, because the native (human) language for SQL is English! Unless there’s a variant I don’t know about…

I’ve seen some code written in Spanish before, I think. Can’t remember. Anyway, the native language for the programming language (C, I think) was English, so the code reads fine. The variable names look different, but I didn’t have too much difficulty.

My guess is that my math background prepared me for abstract notions and symbols, and still be able to work with them. So I treated variables named in a foreign language as just another symbol. And continued to read the code based on that.

And this brings me full circle to…

So does background really matter?

I am unfamiliar with how an American (or English, or French) grows up. I don’t really know the values valued, or the culture surrounding the upbringing of a child.

I do know mine. I’m brought up learning two languages (English and Chinese), two Chinese dialects (Hokkien and Cantonese). I taught myself to read Japanese characters. I’m brought up around people who wake up before dawn to work, and work long hours, regularly and consistently and over long periods of time.

Personal values, personality, genes and luck. I agree they play a part in the makings of a great programmer. In particular, I believe that one’s background influences personal values and personality, so in that sense, background does matter.

And specifically, I think my math background makes grasping programming concepts easier for me.

Of course, everything you’ve just read could be hogwash, because I’m still telling (interesting, I hope) anecdotes to illustrate points as Joel points out vehemently. I haven’t read a lot about computer science and its history in America (or pretty much anywhere in the world). I research just enough so that what I write is as true as I understand it (sometimes I don’t research at all!).

I admit that I’m still naive and easily impressed. I still pretty much trust what I read as true. It’s only when I start internalising the information that I really think about them.

So what do you think?