Gengo Girls #110: Shall We?

Gengo Girls #110: Shall We?

“mashou” is useful because it let’s you create very mild commands and suggestions.

Instead of coming right out and saying “I want to go to McDonalds” you can politely suggest “Let’s go to McDonald’s” or even more mildly “Shall we go to McDonald’s?”

So listen carefully the next time a movie or show has a scene where characters are debating what to do next. Odds are good you’ll hear a polite character making suggestions with “mashou”.

Vocabulary

東京 = とうきょう = Tokyo

Transcript

言語ガールズ #110

Shall We?

Blue: You can turn a polite verb into a suggestion or invitation by replacing ます with ましょう

Yellow: “Let’s play a game” would be ゲームを遊びましょう

Blue: I could suggest a group trip with 東京へ行きましょう

Yellow: “Let’s play a game” would be ゲームを遊びましょう

Blue: And of course you can add to make it a polite question.

Blue: “Shall we go to Tokyo?” with 行きましょうか

Yellow: “Let’s play a game” would be ゲームを遊びましょう

Blue: You’ve got a one-track mind today.

Yellow: I brought cards!

Gengo Girls #109: The Weather Outside Is Frightful

Gengo Girls #109: The Weather Outside Is Frightful

Winter this year has been crazy. That’s all I have to say.

Vocabulary

また = again

= ゆき = snow

そうですね = that’s right / is that right?

冷たい = つめたい = cold (to the touch)

Transcript

言語ガールズ #109

The Weather Outside Is Frightful

Yellow: また雪ですか

Blue: そうですね

Yellow: 雪は寒いです

Blue: 違います。雪は冷たいです。

Yellow: Huh? I thought 寒い meant cold?

Blue: 寒い only refers to things like cold weather and cold air.

Blue: You use 冷たい for things that are cold to the touch like snow and ice.

Yellow: So I use 寒い to complain about the weather and 冷たい to complain about everything else?

Blue: They can be used in a positive way too.

Yellow: Maybe when it’s

Let’s Program A JavaScript Game 18: Moving Pictures

Game animations are important.

First off, they look cool. Watching a warrior swing his ax is much more entertaining than just watching him sit still while you pretend he’s swinging his ax. (No offense to old school RPGs, of which I own an embarrassing amount.)

Second, they make the game feel more realistic. A character who stands perfectly still while falling hundreds of feet feels fake. It’s much more immersive when the character has billowing clothing or flailing limbs to drive home the fact that he’s falling.

Finally, and maybe most importantly, animations give the player information about what’s happening in the game. They show when and how enemies are attacking and give hints about what the character can and can’t do.

I mean, imagine a game with a two second delay between attacks that you just had to remember. Frustrating! Now imagine a game with a two second animation of your character reloading his giant shotgun after every attack. Now it’s easy to see exactly when you can and can’t attack.

Pseudo Code

Animations are created by showing related images one after another at high speed. Take four pictures of a walking man, cycle through them a couple times a second and the human brain will see one walking man instead of four different pictures.

But in a game it’s (usually) not enough to have one animation. You have to have multiple animations you can switch between as needed. If the player is walking along and suddenly hits the jump button you need to be able to instantly switch from your walking animation to your jumping animation.

But even with that complication the logic of 2D game animation is pretty simple:

  1. Store what animation state your sprite is in (ex: walking, jumping, shooting)
  2. Store how long it’s been in that state (ex: 17 frames)
  3. Use that information to decide what image to show (ex: jump-image-3)

Now in a professional game step 3 can get pretty complicated. A running animation might have logic that looks like:

  • If the sprite has been in “running” state for less than five frames show “warm up 1”
  • If the sprite has been in “running” state for between five and fifteen frames show“warm up 2”
  • If the sprite has been in “running” state for between fifteen and twenty two frames show “warm up 3”
  • If the sprite has been in “running” state for more than twenty two frames switch between “running 1” and “running 2” every three frames.

Fortunately for us our only goal is to make our virus enemies spin while being grazed. That means we only have to worry about two sprite states (grazed and not-grazed) and our step three logic is going to be a pretty simple cycle.

How To Store An Animation

To show an animation you need to quickly switch between multiple related images. And while you could create every one of these images as an independent file we’re going to be using a “sprite sheet” instead.

A “sprite sheet” is one large image made up of multiple, related images glued together. For example, here’s a sprite sheet showing four different stages of a rotating virus enemy:

Load this into your virusImage object instead of the old single virus graphic

Load this into your virusImage object instead of the old single virus graphic

We load the image into the game once and can then create an animation by drawing different parts to the screen at different times. In JavaScript we do this by adding extra arguments to our drawImage calls.

You hopefully remember that by default drawImage accepts three arguments: the image we want to draw and the x and y coordinates of where we want to draw it on the canvas.

But there is also a nine argument version of drawImage. The first argument is still an image. The next four arguments define what part of the image we want to draw by creating a rectangle inside of the image. Then the last four arguments define a rectangle inside of the canvas showing where we want our sub-image to be draw and what size we want it to be stretched to.

So to draw the third frame of our 50×50 rotating virus at canvas coordinate (127, 33) we would do something like this:

context.drawImage(virusImage, 100, 0, 50, 50, 127, 33, 50, 50);

This nine argument function is really just asking for an image and two rectangles.

This nine argument function is really just asking for an image and two rectangles.

In other words: Grab the 50×50 sub image found at point (100, 0) of the virusImage and then draw it inside a 50×50 square at point (127, 33) on the canvas.

Make It So

With that we’re ready to upgrade our viruses so that they spin whenever the player grazes them.

First off, let’s define a new constant at the top of our code to help us keep track of what animation state our viruses are in. Since at the moment they can only be in state “grazed” or “not grazed” we really only need one constant:

var VIRUS_GRAZED = 1; //Used to identify a virus that is being grazed

Now we drop down into the graze logic of updateGame and have the viruses keep track of their current animation state:

//Virus logic
for( i = 0; i < viruses.length; i++){
   //Have all viruses move towards the player
   viruses[i].x-=VIRUS_SPEED;

   //See if the player is grazing this virus
   if(intersectRect(viruses[i], grazeHitbox)){
      grazeCollision = true;
      viruses[i].state = VIRUS_GRAZED;
      viruses[i].stateCounter++;
   }
   else{
      viruses[i].state = 0;
      viruses[i].stateCounter = 0;
   }

   //See if the player has had a lethal collission with this virus
   if(intersectRect(viruses[i], deathHitbox)){
      deathCollision = true;
   }
}

This is mostly the same virus enemy logic as before. But now when a virus is grazed it will set it’s state to VIRUS_GRAZED and increment a counter. And when a virus is not grazed it will erase that state and reset the counter.

Now that we know which viruses are being grazed and how long they’ve been grazed we can update our virus drawing logic down in drawScreen:

//Draw viruses
//Virus has a 200 pixel wide sprite sheet with four different 50x50 rotations all in a row
for(i = 0; i < viruses.length; i++){
   //By default draw the first virus
   virusSheetOffset = 0;

   //If the virus is being grazed make it spin by switching between rotations
   if(viruses[i].state = VIRUS_GRAZED){
      if( viruses[i].stateCounter % 8 < 2){
        virusSheetOffset = 0;
      }
      else if(viruses[i].stateCounter % 8 < 4){
         virusSheetOffset = 50;
      }
      else if(viruses[i].stateCounter % 8 < 6){
         virusSheetOffset = 100;
      }
      else{
         virusSheetOffset = 150;
      }
   }

   context.drawImage(virusImage, virusSheetOffset, 0, 50, 50, viruses[i].x, viruses[i].y, 50, 50);
}

Let’s analyze this by looking at the last line first:

context.drawImage(virusImage, virusSheetOffset, 0, 50, 50, viruses[i].x, viruses[i].y, 50, 50);

We always want to draw a 50×50 virus image at the x and y location of the current virus enemy. That’s why the last four arguments are viruses[i].x, viruses[i].y along with 50 width and 50 height.

We then choose between our four different virus sub-images by changing the “virusSheetOffset”. Since our sprite-sheet is just one big row we always leave the y coordinate of our frame as 0. Larger sprite sheets often have multiple rows and would need to calculate both an x and a y offset.

We choose our virusSheetOffest, and thus our sub-image, by seeing how long the virus has been grazed and switching every two frames. Four different sub-images at two frames each mean we complete a full cycle every eight frames so we calculate our current sub-image by using modulo eight to see whether we are at frame 0-1 of a cycle (image 1), 2-3 (image 2) 4-5 (image 3) or 6-7 (image 4).

Of course, all this only happens if the virus is being grazed. If not we just stick with an offset of 0 to get the default first frame. This means that only grazed viruses spin. The rest just sit there.

An Unrelated Tweak

Before we finish up this Let’s Program there’s one last little game flaw I want to fix.

Currently we start and restart the game by having the player press the up arrow key. Unfortunately if the player happens to already pressing the up key when he dies or wins he will immediately restart the game without any time to see the “game over”, “you win” or “start” screens.

To solve this I created a new global variable

var menuFrames = 0; //Has the player been on the menu long enough to press a button?

I then use this variable to force every menu screen to wait twenty frames before letting the player move on. Here’s an example from the win screen, but the other two functions were modified in the same way:

//Check to see if the user is ready to restart the game
//Slightly delay user input so they don't accidentally skip this screen
function updateWinScreen(){
   menuFrames++;
   if(playerInput.up && menuFrames >= 20){
      gameState = STATE_START_SCREEN;
      menuFrames = 0;
   }
}

Resetting the “menuFrames” counter before switching states is very important. Otherwise only the first menu of the game would have the input delay and then we’d be right back to being able to accidentally skip past important screens.

YOU WIN THE META-GAME!

We now have a complete game that shows off everything from basic animations, collision detection and sounds to real-time world generation and physics simulations. You can play the full version here and I strongly recommend downloading the page source so you can see the complete code.

And with that done all that’s left is a few final thoughts on what to do next.

Gengo Girls #108: Close One Door, Open Another

Gengo Girls #108: Close One Door, Open Another

If you ask for permission and get it the answer will usually be a pretty straightforward “Sure, that’s fine”. But if you don’t get permission things can get a bit strange.

Since the Japanese tend to avoid conflict they will almost never directly say “no” to a request even when they want to. Instead they will kind of stall and mumble something like “Well… you see… maybe… but it’s kind of… I guess you could… but still…”

As an American you might take that kind of wishy washy answer as a weak “yes”. But what you are actually supposed to do is notice their reluctance and withdraw your request without forcing them to say no. That way everybody saves face and there is no conflict.

Vocabulary

入る = はいる = to enter

Transcript

言語ガールズ #108

Close One Door, Open Another

Blue: Time for another pattern.

Blue: verb-て いい です means “It’s okay to do that verb”.

Yellow: I remember いい. It means “good”.

Blue: So if someone knocked on your door you could us て いい です to give them permission to come in.

Yellow: 入っていいです

Blue: You can also add a to the end of the pattern to make a request.

Blue: So you could ask “Can I come in?” with 入っていいですか

Yellow: But if you learn a little ninjitus you don’t have to worry about permission. Just smoke bomb your way in and out!

Blue: I worry that real world 日本 won’t be able to live up to the image in your head.

Gengo Girls #107: Goldfish

Gengo Girls #107: Goldfish

When you think about it the present tense in both English and Japanese has two uses:

1) To talk about something you do in general. “I write a blog.”

2) To talk about instantaneous actions. “I push the button”.

In English “to know” is used as a general present tense. “Yeah, I know the first ten digits of Pi. That’s a generally true statement about me.”

But in Japanese they prefer the ongoing “I am knowing” form instead of the general “I know”. Which is both fine and logical… but sure takes some getting used to. Just remember that “shitteru” and “shitteimasu” both mean “to know” and don’t worry too much about the grammar specifics.

Vocabulary

知る = しる = to know

Transcript

言語ガールズ #107

Goldfish

Yellow: So anytime I would use a “-ing” verb in English I use a て います verb in 日本語?

Blue: There are also times where you should use て います even when you wouldn’t use “-ing” in English.

Blue: One important example is “to know”. In English we just use the present tense to talk about things we know.

Yellow: I know a lot of movie trivia.

Blue: But in 日本語 you use the ongoing 知っています conjugation instead.

Yellow: I am knowing a lot of movie trivia?

Blue: Think of it this way: When you know something you keep knowing it. You don’t just forget three seconds later.

Yellow: Actually…