Monthly Archives: June 2013

Back To Front (Scrolling a Vertical Game Background Using Windows 8, Javascript & HTML5)

I’m currently trying to write my first game using the Windows 8 platform. I’ve just finished a painful time trying to work out how to vertically scroll a repeating background. In my case, it’s a star-scape, but this should work for anything.

 

The Problem

 

Imagine you have a single image as a background to your game, but you want to make it look like your game is moving forwards (literally). However, also imagine that you’re incredibly bad at drawing, or manipulating images in any way – so you want to just use one image.

 

Caveat

 

This works for a star-scape because stars look pretty much the same unless you pay very close attention – obviously if you have a vertical shoot ’em up then this might not work, depending how innocuous you make the background.

 

The Solution

 

Okay, so my solution here was to simply scroll the background into itself. In order to do this, you have to visualise the background as a large sheet of paper, and the screen canvas as a small magnifying glass (but square). Strictly speaking, you don’t have to actually visualise it at all, because I’ve drawn it below:

 

background_1

Now, we can scroll that image downward, giving the impression that it’s moving (or we are):

background_2

That’s going to look like we’ve moved across the image. However, the eagle eyed amongst you may notice that we’ve now ran out of image! Actually, this is quite straightforward, just do what the BBC do when they run out of programs – repeat:

background_3

In Detail

Okay, so how do we do all that? It’s alarmingly difficult actually. I’ve marked this as a javascript post, but I don’t see why it wouldn’t work for any language – the principle and maths should be the same.

First, create a variable; for example:

var backgroundOffset = 0;

Inside your game loop, this needs to be iterated:

var gameLoop = function () {        
    canvasContext.clearRect(0, 0, canvas.width, canvas.height);

    // Draw Background
    ++backgroundOffset;
}

Then you need to actually draw the background. This does work, but I’m not claiming it’s the most efficient way of doing it:


canvasContext.drawImage(backgroundImage, 0, backgroundOffset);

if (backgroundOffset >= 0 &amp;&amp; backgroundOffset <= canvasHeight) {
    canvasContext.drawImage(backgroundImage, 0, backgroundOffset - backgroundImage.height);
}

// Scrolling off the bottom of the screen
if (backgroundOffset > canvasHeight) {
    backgroundOffset = canvasHeight - backgroundImage.height;
}

Conclusion

If, like me, you’re just dabbling in game development and want something that gives the impression of moving, then this will do it. If you want Call Of Duty then you’re going to need something more complex!

What are you referring to Wilbur? (Passing classes by reference in C#)

I found this test project while doing a spring clean, and thought it would be ripe for a blog post.  To illustrate the problem that this is trying to address, I’m going to introduce you to two characters: Wilbur and Wright.  Wilbur is an enthusiastic junior developer just out of college, and Wright is a cranky old goat who’s been in the industry too long (these characters are not based on anyone I might know, have known or ever will know – so put that lawsuit down and keep your hands where I can see them).

 

Wilbur: What the…?  I’ve just tried to change this class inside a function and it doesn’t change!
Wright: What do you mean “change this class”?
Wilbur: I want to alter the class from what it was to something else, and it doesn’t work – why not?
Wright:  Show me the code then!


    class MyFunkyClass
    {
        public int MyNumber { get; set; }
    } 

    class Program
    {
        MyFunkyClass testClass = new MyFunkyClass(); 
        testClass.MyNumber = 10; 

        Console.WriteLine("Call ChangeClass()"); 
        ChangeClass(testClass); 
        Console.WriteLine("After ChangeClass(): {0}", testClass.MyNumber); 

        static void ChangeClass(MyFunkyClass myclass) 
        { 
            myclass = new MyFunkyClass(); 
            myclass.MyNumber = 3; 
        }
    }

Wilbur: See, it doesn’t change – it starts at 10, and finishes at 10.
Wright: You need to pass by reference if you’re going to change it!
Wilbur: No I don’t – this works – it prints 20, which is correct:


        static void Main(string[] args) 
        { 
            MyFunkyClass testClass = new MyFunkyClass(); 
            testClass.MyNumber = 10; 
 
            Console.WriteLine("Call ChangeNumber()"); 
            ChangeNumber(testClass); 
            Console.WriteLine("After ChangeNumber(): {0}", testClass.MyNumber); 
        }

        static void ChangeNumber(MyFunkyClass myclass) 
        { 
            myclass.MyNumber += 10; 
        } 

Wright: You’re not changing the class, you’re changing a property. You’re passing the address of the class. If you intend to change the address of the class, then you need to pass that by reference, like this:

        ...
            Console.WriteLine("Call ChangeClassRef()"); 
            ChangeClassRef( ref testClass); 
            Console.WriteLine("After ChangeClassRef(): {0}", testClass.MyNumber); 
        }

        static void ChangeClassRef(ref MyFunkyClass myclass)
        {
            myclass = new MyFunkyClass();
            myclass.MyNumber = 5;
        }

Wilbur: Let’s have a look what the difference is in the IL. Here’s mine:


.method private hidebysig static void  ChangeClass(class ConsoleApplication2.MyFunkyClass myclass) cil managed
{
  // Code size       17 (0x11)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  newobj     instance void ConsoleApplication2.MyFunkyClass::.ctor()
  IL_0006:  starg.s    myclass
  IL_0008:  ldarg.0
  IL_0009:  ldc.i4.3
  IL_000a:  callvirt   instance void ConsoleApplication2.MyFunkyClass::set_MyNumber(int32)
  IL_000f:  nop
  IL_0010:  ret
} // end of method Program::ChangeClass

Wilbur: And here’s yours:


.method private hidebysig static void  ChangeClassRef(class ConsoleApplication2.MyFunkyClass&amp; myclass) cil managed
{
  // Code size       18 (0x12)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  newobj     instance void ConsoleApplication2.MyFunkyClass::.ctor()
  IL_0007:  stind.ref
  IL_0008:  ldarg.0
  IL_0009:  ldind.ref
  IL_000a:  ldc.i4.5
  IL_000b:  callvirt   instance void ConsoleApplication2.MyFunkyClass::set_MyNumber(int32)
  IL_0010:  nop
  IL_0011:  ret
} // end of method Program::ChangeClassRef

Wilbur: So what’s the difference?
Wright: You called your app ConsoleApplication2!? WTF?
Wilbur: Hey, these posts take a while to wright, Wright! Anyway, you haven’t answered.
Wright: Well, it’s been a while, but thinking back to my C days, doesn’t the ampersand (&) mean address of?
Wilbur: Are you telling me or asking me?
Wright: If I pass the address of the class, I can change the class, because I simply change the address that it points to, but if I pass the class itself, I don’t have that reference, I only have the class. Make sense?
Wilbur: No.
Wright: Okay, think of it like this. Say you go to an estate agent, and they show you around a nice three bed semi-detached. While you’re in the house, you ask the agent if they could move the house three streets away. That’s what you’re doing when you don’t pass the class by reference.

Now, imagine that instead of taking you to the house, the estate agent gives you a piece of paper with the address of the house on. If you want a house three streets away, you simply overwrite what’s written on the paper with the new address.

THE END