Gengo Girls #23: Electronic Induced ADD

Gengo Girls #23: Electronic Induced ADD

Computers are amazing all-purpose devices. Maybe a little too all-purpose.

Anyways, if you want to try out an electronic kanji dictionary I suggest http://jisho.org/kanji/radicals/. It’s free, easy to use and has an excellent database of both common and uncommon kanji. It’s my go-to resource when I need to translate something. Why not grab a kanji from a previous strip and see if you can find it?

Transcript

言語ガールズ #23

Electronic Induced ADD

Yellow: The computer lab?

Blue: Digital kanji dictionaries have certain advantages over normal paper dictionaries.

Blue: One big advantage is that electronic dictionaries let you search for multiple radicals at the same time.

Blue: This let’s you pinpoint the exact kanji you’re looking for.

Blue: There might be a hundred kanji with the radical but there are only two with both the AND the radical.

Blue: Even you can’t complain about results like that.

Blue: So, do you want to give it a try?

Yellow: I found a video of a stuck in a box!

Gengo Girls #22: Totally Rad

Gengo Girls #22: Totally Rad

I think we’ve all experienced the feeling that a hard thing should be easier than it is.

A lot of the time that’s just us suffering form unrealistic expectations. Some things are just plain hard and there’s not much you can do about it except grit your teeth and keep working.

But sometimes there really is an easier way to solve your problems. Which is actually the topic of the next comic.

Vocabulary

= よる = evening, night

Transcript

言語ガールズ #22

Totally Rad

Yellow: Looking kanji up by stroke count is frustrating.

Blue: You could try looking them up with radicals instead.

Blue: Radicals are the simple symbols that get combined together to make complicated kanji, like this symbol here.

Yellow: So I just flip to the section of the dictionary and…

Yellow: What!? There’s over a hundred different kanji in this list!

Yellow: This isn’t radical at all. This is just as slow and frustrating as stroke counting.

Blue: Patience is a virtue, especially when studying 日本語.

Gengo Girls #21: Relative VS Absolute

Gengo Girls #21: Relative VS Absolute

I was planning on giving you some useful tips on how to count brush strokes only to realize that I’m not 100% sure myself. I guess my best advice would be to look up some tutorials on how to properly draw the basic three and four stroke kanji. That might give you a feel for what sort of stoke shapes are and aren’t common. Example: a lot of kanji have strokes that go to the right and then angle down, but very few have strokes that start out moving down and then angle right.

Or you could just give up on stroke counting for now and try a different kanji look up method.

Vocabulary

= = eye

Transcript

言語ガールズ #21

Relative VS Absolute

Blue: Let’s try looking up this kanji by stroke count.

Yellow: I count six lines, so is that a six stroke kanji?

Blue: It’s actually a five stroke kanji. The top and right lines were drawn with one angled stroke.

Yellow: So I just flip to the list of five stroke kanji and… WOAH!

Yellow: There must be a hundred of these things! How is this helpful?

Blue: Searching a list of 100 symbols is easier than searching a full list of thousands of symbols.

Yellow: Easier doesn’t mean easy!

Let’s Program A JavaScript Game 7: When Worlds Collide For Real

Knowing Is Only Half The Battle

 

Last time we covered the theory behind hitboxes and decided that our digital motorcycle needs three different hitboxes:

Hitbox Diagram For A Motorcycle

Remember This?

So now let’s actually put that idea into practice with some code.

 

Hitbox Creation Functions

 

Obviously our game is going to keep track of where the player is on the screen. But for collision detection what we really need is a way to transform that position into a set of three hitboxes.

 

The most straightforward solution is to write three functions that each accept an x and y coordinate representing the player’s position and then returns a complete hitbox object.

 

Now to be honest creating a bunch of new rectangle objects every everyt ime we want to do a collision check strikes me as potentially wasteful. Maybe it would be smarter to just create the hitboxes at the beginning of the script and then update them every time the character moves.

 

But I don’t want to waste time obsessing about how to run this code fast until I know for sure that the easy approach really is too slow. So I’m just going to build the hitbox creator functions and see how that runs. I can always optimize later.

 

Now it’s time for some math.

 

Our “cycle.png” image (which I recently flipped to face right instead of left) is 75 pixels wide and 48 pixels tall. We want to put a a five pixel tall “feet hitbox” along the bottom of the motorcycle for detecting when we hit platforms. Since the player’s position is measured from the top-left corner of the image that means the feet hitbox needs to be 43 pixels lower than then the player position.

 

// Get a 5x75 hitbox along the bottom of a 48x75 sprite.
// Used for detecting when the player has landed on a platform
// If you change the player sprite dimension you should update this function too
function getFeetHitbox(xPos, yPos){
   var feetHitbox = new Object();
   feetHitbox.x = xPos;
   feetHitbox.y = yPos+43;
   feetHitbox.width = 75;
   feetHitbox.height = 5;
   return feetHitbox
}

 

Next we want a relatively small “death hitbox” along the middle of the cycle. It will take some play testing to decide what the best size for it is but for now let’s say… 24 by 50 pixels. That’s about 12 pixels away from each side of the motorcycle which tells us everything we need for setting up the offsets.

 

// Get a 24x50 hitbox in the middle of a 48x75 sprite.
// Used for detecting when the player has hit an enemy
// If you change the player sprite dimension you should update this function too
function getDeathHitbox(xPos, yPos){
   var deathHitbox = new Object();
   deathHitbox.x = xPos+12;
   deathHitbox.y = yPos+12;
   deathHitbox.width = 50;
   deathHitbox.height = 24;
   return deathHitbox;
}

 

Finally we need to build the “graze hitbox” to track when the player is close enough to an enemy to start getting bonus points. This box actually need to be larger than the motorcycle graphic. Once again we’ll have to actually play test the game to fine tune the size of the graze box, but for starters lets give it 20 extra pixels on every side of the motorcycle (for an extra 40 pixels of width and height). Note that this actually requires negative offsets in order to put the graze box above and to the left of the player’s main position.

 

// Get a 88x115 hitbox centered around a 48x75 sprite.
// Used for detecting when the player is grazing an enemy
// If you change the player sprite dimension you should update this function too
function getGrazeHitbox(xPos, yPos){
   var grazeHitbox = new Object();
   grazeHitbox.x = xPos-20;
   grazeHitbox.y = yPos-20;
   grazeHitbox.width = 115;
   grazeHitbox.height = 88;
   return grazeHitbox;
}

 

Quick Test

 

Collision detection function? Check!

 

Hitbox creation function? Check!

 

Hitbox testing code? Let’s write it!

 

For starters you’re going to need to update your global variables to this:

 

var loopCount=0;
var playerInput = new Object();

var player = new Object();
player.x = 100;
player.y = 100;

var testObject = new Object();
testObject.x = 200;
testObject.y = 200;
testObject.width = 50;
testObject.height = 50;

var feetCollision = false;
var grazeCollision = false;
var deathCollision = false;

var cycleImage = new Image();
cycleImage.src = "cycle.png";

 

And then you’ll need to change your update method in two ways. First, when the user presses a key you need to update the player object instead of the generic xPos and yPos variables. Second, you need to check for collisions and update the global collision variables.

 

//Update the game by one step
function updateGame(){
   loopCount++;
   if(playerInput.right){
      player.x+=5;
   }

   if(playerInput.left){
      player.x-=5;
   }

   if(playerInput.up){
      player.y-=5;
   }

   if(playerInput.down){
      player.y+=5;
   }

   feetCollision = false;
   grazeCollision = false;
   deathCollision = false; 

   if(intersectRect(testObject, getFeetHitbox(player.x, player.y))){
      feetCollision = true;
   }

   if(intersectRect(testObject, getDeathHitbox(player.x, player.y))){
      deathCollision = true;
   }

   if(intersectRect(testObject, getGrazeHitbox(player.x, player.y))){
      grazeCollision = true;
   }
}

 

And finally we need to update our draw code to draw the player motorcycle, the test obstacle and a list of what hitboxes are and aren’t being hit:

 

//Draw the screen
function drawScreen(){
   var canvas = document.getElementById('gameCanvas');
   var context = canvas.getContext('2d');

   //Draw background
   context.fillStyle = '#dcdcdc';
   context.fillRect(0,0,600,400);

   //Draw black text
   context.fillStyle = '#000000';
   context.fillText("Loop Count: "+loopCount, 20, 20);

   if(feetCollision){
      context.fillText("Feet Collision: True", 20, 40);
   }
   else{
      context.fillText("Feet Collision: False", 20, 40);
   }
   
   if(deathCollision){
      context.fillText("Death Collision: True", 20, 60);
   }
   else{
      context.fillText("Death Collision: False", 20, 60);
   }

   if(grazeCollision){
      context.fillText("Graze Collision: True", 20, 80);
   }
   else{
      context.fillText("Graze Collision: False", 20, 80);
   }

   //Draw a red square the player can run into
   context.fillStyle = '#FF0000';
   context.fillRect(testObject.x, testObject.y, testObject.width, testObject.height);

   //Draw a motorcycle as the player's avatar
   context.drawImage(cycleImage, player.x, player.y);
}

 

If you’ve managed to properly copy all the code so far you should be able to hit the canvas test button and then control the motorcycle graphic by using the arrow keys. Move it towards and over the red box and watch how the three different collision variables react.

 

A sample screenshot of the collision test.

Close enough to graze and land on the square, but not close enough to hit the “death hitbox”.

 

I Hope You Remember High School Physics

 

With collisions working the next big piece of our simulation is a simple gravity system to pull the motorcycle downwards and give the player a reason to jump from platform to platform. So tune in next week as we try to find a gravity algorithm that walks the fine line between realistic and fun.

Gengo Girls #20: Priorities

Gengo Girls #20: Priorities

If your main goal is to speak and listen to Japanese the kanji probably aren’t a big deal. But if your goal is to read Japanese the sooner you learn how to use a kanji dictionary the better. Being able to look words up on demand is a lot easier than having to memorize 2,000 kanji before even thinking about reading your first Japanese comic or news article.

Transcript

言語ガールズ #20

Priorities

Blue: Alphabetic dictionaries are useful when you know how a word is spelled.

Blue: But what if you needed to look up a word based only on its kanji, or symbol?

Yellow: I would ask you.

Blue: What if I wasn’t here?

Yellow: I would wait until you showed up.

Blue: What if I was dead?

Yellow: I’d be too sad to care about a dumb kanji.

Blue: Well, if you did want to look up a kanji, you could use a kanji dictionary.

Yellow: Why would you be dead anyways?

Blue: Kanji dictionaries organize Japanese symbols by things like the number of brush strokes in each kanji. They’re really useful.

Yellow: Was it the lizard-clones? Did you know too much about their plans?

Gengo Girls #19: Be Prepared

Gengo Girls #19: Be Prepared

I won’t lie; Electronic dictionaries are incredibly useful. I personally use jisho.org for 99% of my Japanese needs and only break out my physical dictionary on those rare days when I’m tired of staring at a computer screen and need to give my eyes a break.

Still, knowing how to alphabetize words is a useful skill. You never know when you’ll need to do something low-tech like find a book in an alphabetized shelf or look someone up in a company registry.

Vocabulary

寒い = さむい= cold

Transcript

言語ガールズ #19

Be Prepared

Blue: Why don’t you try your dictionary skills by looking up the word さむい?

Yellow: Let’s see… It starts with an “S” sound which comes after the vowel and “K” sounds, so that’s the third section of the dictionary.

Yellow: あいうえおorder means that is the first S sound, so I should focus on the beginning of the “S” section.

Yellow: Next is. “M” sounds are near the middle of the Japanese alphabet, so さむいshould be in the middle of the words.

Yellow: comes after and so… Here it is: さむい means “cold”.

Blue: That wasn’t so bad, was it?

Yellow: Typing SAMUI into an electronic dictionary would have been faster.

Blue: But… umm… what if you need to look up a word during a power outage? That coul happen, right?

Yellow: Good point! I might need to talk to with a samurai during the zombie apocalypse.

Gengo Girls #18: Method Acting

Gengo Girls #18: Method Acting

For anyone too lazy to look it up on their own, the order of the hiragana groups is: Vowels, K, S, T, N, H, M, Y, R, W. Congratulations, you can now alphabetize in Japanese.

A lot of Japanese-to-English dictionaries actually spell the Japanese words with the Latin alphabet and Latin alphabetization. So you would look up “neko = cat” under “N” instead of looking up “ねこ = cat” under .

As a beginner a Latin alphabet dictionary will probably seem easier to use, but I strongly suggest getting a hiragana based Japanese-to-English dictionary instead. Forcing yourself to use Japanese characters is tough at first but will help you master the hiragana. It will also prevent you from accidentally mixing up English and Japanese pronunciation rules. It’s just too easy to see a word like “are” and immediately think of how you would read it in English instead of how it should sound in Japanese. That’s also why this comic has been using hiragana since the very start. In the long run it really pays off.

Transcript

言語ガールズ #18

Method Acting

Yellow: Now that I’m dressed properly learning 日本語 should be easy.

Blue: That’s why you’re wearing that?

Yellow: To speak like the Japanese you must dress like the Japanese.

Blue: If you say so…

Blue: Anyways, today I wanted to talk about dictionaries.

Yellow: What is there to talk about? They’re just big lists of alphabetized words and definition.

Blue: That’s true, but 日本語 has different alphabetization rules than English.

Blue: For example, their vowels are organized あいうえお instead of A E I O U.

Blue: In fact, each letter group follows the sameあいうえお pattern. So for the “K” sounds the order isかきく け こ.

Blue: So if you remember the あいうえお pattern and the order the letter groups go in you’re done.

Yellow: I guess I’d better go find a hiragana chart to study.

Let’s Program A JavaScript Game 6: When Worlds Collide

Mom! He’s Touching Me!

 

Now that I think about it, none of my childhood family vacations ever involved the classic game of “How much can you invade your sibling’s personal space before they try to get you in trouble with Mom”. I feel deprived.

 

Anyways, this week’s topic is collision detection: the art of figuring out when two virtual objects are touching each other or overlapping. This is a very important element of game programming and really comes in handing when you need to know things like:

  1. Is the player standing on solid ground?
  2. Did the player just run into an enemy?
  3. Did the player just touch a power up?
  4. Is the player trying to walk through a wall?
  5. Did the player jump high enough to hit the ceiling?
  6. Did the player’s bullets hit an enemy?

 

Without collision detection a videogame would just be an interactive piece of art where you float around a world without physics watching things happen more or less at random. Which actually sounds kind of cool now that I think about it but that’s not what we’re aiming for right now.

 

Simple Collision Detection

 

We can’t detect if two objects are touching each other without two objects to touch. And no object is easier to work with than a rectangle which can be represented as a single x and y coordinate (representing the upper-left corner of the rectangle) along with a width and height.

 

//Sample Rectangle Code: Don't Put In Your Game
var testRect = new Object();
testRect.x = 5;
testRect.y = 20;
testRect.width = 10;
testRect.height = 30;

 

Now if we build two objects like this we can test if they are touching or not with this neat little math function, which is logically equal to this function from Wikipedia.

 

//Test if two rectangles intersect
//Arguments are two objects which much have x, y, width and height variables
function intersectRect(r1, r2) {
   return !(r2.x > r1.x+r1.width ||
            r2.x+r2.width < r1.x ||
            r2.y > r1.y+r1.height ||
            r2.y+r2.height < r1.y);
}

 

This function runs four quick tests that can each prove that the two rectangles ARE NOT touching each other. The first line tests if the second rectangle is too far right to touch the first rectangle. The second line tests if the second rectangle is too far left to touch the first rectangle. The third line tests if the second rectangle is too low to be touching the first rectangle and finally the fouth line tests if the first rectangle is too high up to be touching the first rectangle.

 

If all the tests fail then the second rectangle must be touching the first rectangle and the function overall returns true. Come up with a few samples and run the logic by hand if you like. It’s not like this articles going anywhere.

 

How Many Hitboxes Does One Character Need?

 

With that function we have everything we need to tell when rectangles collide. Now all we have to do is wrap all of our game graphics inside of invisible rectangles and it’ll be easy to tell when the player is running into enemies or crashing into platforms.

 

These invisible rectangles are called “hitboxes” and they are a vital game 2D* programming trick.

 

But there are certain problems with having your entire character represented by just one big hitbox.

 

For example: Imagine You detect that your one-hitbox character has run into a one-hitbox floating block. What happens next should depend on what direction the character hit the block from.

 

If they collided with the block from above they should land on the block and treat it like ground.

 

If they collided with the block from below they should stop moving upwards and instead start falling down.

 

If they collided with the block from the side they should stop moving and then slide downwards.

 

But since the character has just one big hit-box it’s really hard to figure out what kind of collision just happened. All you know is that the character and the block are touching; you don’t know where they are touching or what part of the character hit the block first.

 

There is also the big issue that giving a character one big hitbox usually creates a hitbox that is larger than the character’s graphics. This can lead to frustrating scenarios where the player winds up dead because an attack hit the blank space near his character’s head. It looks like it shouldn’t count as a hit but it’s inside of the invisible hitbox so it counts.

A Diagram Of A Robot With One Hitbox

One Hitbox Per Character: Simple But Flawed

So one big hitbox makes it hard to tell exactly what is going on with your character and can lead to frustrating collisions for the player. This is a problem!

 

The simple solution is to give each character multiple hitboxes for different logic.

 

Some common hitbox types include:

 

Death box: A small, central hitbox for checking whether attacks hit the player or not. By making it smaller than the character graphics we give the player a little wiggle room and avoid the “phantom hits” we would get if the hitbox covered whitespace.

 

Bonus Box: A large hitbox that is used for detecting whether the player has touched bonus items or not. Slightly larger than the player so that they can grab coins and power ups just by getting really close without having to worry about exact pixels.

 

Feet Box: A short but wide hitbox used for detecting whether the player is touching the ground. We put it in the bottom center of the sprite.

 

Head Box: A short but wide hit box used for detecting whether the player has just bumped his head against the ceiling. We put it at the top center of the sprite.

 

Side Boxes: Two tall but thing hit boxes used for detecting whether the player has run into a solid obstacle. We put them on the left and right sides of the player.

A Diagram Of A Robot With Multiple Hitboxes

Multiple Hitboxes: Much More Elegant

Hitboxes For Defrag Cycle

 

So how many of those common hitbox types doe we need for our game? Let’s see…

 

We need to be able to jump from platform to platform, so we’re going to need some sort of “foot hitbox” running along the bottom of the motorcycle.

 

We need to keep track of when the player runs into a virus and loses, so we’re going to need a small “death hitbox” in the center of the motorcycle.

 

We want to give players bonus points for grazing viruses, so we’re going to need a large “bonus hitbox” that’s actually a little bit bigger than the motorcyle. When a virus is inside this box but outside the “death hitbox” is when we give graze points.

 

We want players to be able to jump through platforms from below to land on top, so we DON’T need any sort of “head hitbox”.

 

The game has no walls, so we don’t need any “side hitboxes”.

 

So our final hitbox model for debug cycle has three hitboxes and will look something like this:

 

Hitbox Diagram For A Motorcycle

I think this should work

 

From Theory To Practice

 

Not a lot of code today, but that’s OK because we’ve laid down the groundwork we need to actually do some collision detection next time. Maybe throw is some gravity and get the player’s motorcycle to actually jump between platforms if I have the time.

 

 

* 3D games have a similar collision technique based around wrapping things with invisible cubes, cylinders and spheres.

Gengo Girls #17: Scholastic Stereotype

Gengo Girls #17: Scholastic Stereotype

Remember that 何です is pronounced “nan des” instead of “nani desu”, probably due to a phenomenon I have dubbed “The Efficiency Slur”.

My guess is that most people hate using more syllables than they have to, especially for very common words and phrases. So they drop a few letters, slur a few sounds together and suddenly everyone is going around saying “It’s” instead of “It is” and “nan des” instead of “nani desu”.

So here’s a fun project for any really bored linguists out there: Calculate how many syllables the average person “saves” by using contracted words. I’m betting the savings from “It’s” alone will be enough to add an entire day to my lifespan that would have otherwise been wasted on two syllable “It is”.

Vocabulary

制服 = せいふく = uniform, usually a school uniform

Transcript

言語ガールズ #17

Scholastic Stereotype

Yellow: おはよう

Blue: それは何ですか

Yellow: これは制服です

Blue: I can see that it’s a 制服. But why are you wearing it?

Yellow: It IS a school uniform, isn’t it?

Blue: It’s a JAPANESE school uniform! This is an American school.

Blue: We don’t wear uniforms. I’m not even sure we have a dress code.

Yellow: Then there aren’t any rules saying I can’t wear a 制服 to school, are there?

Gengo Girls #16: Curiosity Killed The Cat

Gengo Girls #16: Curiosity Killed The Cat

Don’t you love it when a foreign language has easy grammar? Just add one syllable to the end of a sentence and it’s a question. No messy conjugations or word rearranging. Of course, not all Japanese grammar is this simple so enjoy it while you can.

Although to be honest I wouldn’t call any part of Japanese grammar genuinely “hard”. It’s mostly just “different”, which can make it seem harder than English related languages like Spanish or German.

Vocabulary

= ねこ = cat

Transcript

言語ガールズ #16

Curiosity Killed The Cat

Yellow: My grandpa always said “The only dumb question is the one you don’t ask”, but I don’t know how to ask questions in 日本語.

Blue: It’s easy! Just add to the end of a sentence and it turns into a question.

Blue: For example: それは猫です means “That is a cat.”

Blue: But それは猫ですか means “Is that a cat?”

Yellow: So the is like a spoken question mark?

Blue: That’s a good way to think of it.

Yellow: I wonder what a spoken question mark would sound like in 英語

Yellow: Maybe something like “?”

Blue: How did you even make that sound!?