Wednesday, March 3, 2010

Doodle Blast! - Day 3 - Flicks

Stats: 52 code files, 4436 lines of code, 2 textures, 20 sounds

Today I introduced visual damage model on the player. Interestingly enough, most people playing Doodle Blast! for the first time completely miss it. I wanted to avoid having a health-meter bar or a number somewhere on the top of the screen, so I tried to solve this problem visually instead:

But as I said, most people miss it, so I might need to add a health bar after all.

The other big change in today’s build was the addition of flicking. Following the initial sketch of the game, I wanted to have little soldiers running around. I also wanted them to be flickable as flicking seems to be a popular gesture these days. The implementation was pretty simple.

Each soldier had a state variable, which could contain one of the following values:

  • ATTACKING – the soldier is all gong-ho in trying to get the player
  • GRABBED – the soldier is “grabbed” by a touch and is now following that touch around the screen
  • FALLING – the touch that “grabbed” a soldier ended, and the soldier is now falling
  • RECOVERING – the soldier hit the ground, but under some magic threshold speed. A timer has been set, after which the soldier will resume its attack.

To calculate how and whether a soldier was flicked after it was grabbed, I kept track of the movement of each touch. When I received a TouchMoved event, I used the last touch position along with the last touch time-stamp to compute the speed thusly:

touchSpeed = (currentLocation – lastLocation) / touchTimeDelta;

When the touch ended, I used the touchSpeed, clamped by some max value, and simply set the released soldier off in that direction.

This approach, however, created a problem. You suddenly couldn’t just shoot a soldier, because every touch near a soldier’s vicinity turned into a flick gesture. To solve this problem, I defined two constants: FLICK_TIME_EPSYLON and FLICK_DISTANCE_EPSYLON. If a given touch event took less time than FLICK_TIME_EPSYLON (0.3 secs) and if that touch event moved a total of less than FLICK_DISTANCE_EPSYLON (20 pixels), I wouldn’t consider that gesture a flick, but I would consider it a tap instead and still direct one of the guns to shoot at that location.

Finally, there was one more interesting change that I introduced the day before but didn’t get a chance to talk about yet. I wanted the tank and the stack of guns to feel like they are barely holding together as they clank along moving forward on a bumpy road. What I ended up doing was giving a random small impulse to the tank and to a random gun in the stack every 0 – 2 secs. You can see those bumps in the video from yesterday.

4 comments:

  1. Hello again!

    Just wanted to know how you measure the time of a touch event? Is there function like getNanoTimeNow() or something like that?

    Thanks.

    ReplyDelete
  2. Yes. You can get a time stamp using the following method:

    struct timeval time;
    if (gettimeofday(&startTime, NULL) != 0) { /* We got it! */ }

    Or, if you are using Cocos2D, you can simply aggregate the time delta's sent into your update method. That's what I actually end up doing.

    ReplyDelete
  3. I just noticed a typo. It should be:

    if (gettimeofday(&time, NULL) ...

    instead of

    if (gettimeofday(&startTime, NULL) ...

    ReplyDelete
  4. Awesome! thanks gc! Works well.

    ReplyDelete