Saturday, September 29, 2012

Falling Letters

‹prev | My Chain | next›

Oh, what the hey? Or is that what the hay?

Anyway, why not make a learn-to-type game? I spent the last few days going into text sprites in excruciating detail. I had done so simply for my own edification, but perhaps there is something more immediate that I can do with that knowledge. And it might make a good intro game for Gaming JavaScript.

I leave my center marker in place, just as a point of reference while I am building things:
  var wrapper = new THREE.MeshNormalMaterial();
  var shape = new THREE.SphereGeometry(10);
  var center_marker = new THREE.Mesh(shape, wrapper);
  scene.add(center_marker);
For the overall structure of the game, I will store a list of letters in an array, then animate and run through steps of the game:
  var letters = [];  
  
  animate();
  gameStep();
For starters, animation is just the usual request animation:
  function animate() {
    requestAnimationFrame(animate);
    
    // Now, show what the camera sees on the screen:
    renderer.render(scene, camera);
  }
In the game loop, I will add a new letter every three seconds and continuous update the location of the falling letters:
  var step = 0;
  function gameStep() {
    if ((step % (3*60)) == 0) {
      addLetter();
    }
  
    lettersFall();
    
    step++;  
    setTimeout(gameStep, 1000 / 60); // process the game logic
                                    // at a target 60 FPS.    
  }
To add letters, I create a new sprite for each new letter. As I found the past few days, this is a bit involved (create canvas, create 2D drawing context, draw letter, make texture from canvas, use in Three.js):
  function addLetter() {
    var canvas = document.createElement('canvas');
    var size = 50;
    canvas.width = size;
    canvas.height = size;
    var context = canvas.getContext('2d');
    context.textAlign = 'center';
    context.font = '48px Arial';
    context.fillText("f", size/2, size);

    var texture = new THREE.Texture(canvas);
    texture.needsUpdate = true;
    var sprite = new THREE.Sprite({
      map: texture,
      transparent: true,
      useScreenCoordinates: false
    });
    scene.add(sprite);
    sprite.position.set(0.5* window.innerWidth - Math.random() * window.innerWidth ,window.innerHeight/2,0);
    letters.push(sprite);
  }
At the very end of that function, I add the sprite to the scene and to the letters array. This allows me to continuously update the position of the letters in the lettersFall() function:
  function lettersFall() {
    letters.forEach(function(letter) {
      letter.position.y = letter.position.y - 1;
    });
  }
And that seems to do the trick:


I am unsure if creating a new canvas element for each letter is wise, but it seems to work for now. Then again, that might be a prohibitive amount of typing for a kids game. I'll sleep on that thought and pick back up tomorrow.

Day #524

No comments:

Post a Comment