HomeHome  ­FAQFAQ  ­SearchSearch  ­MemberlistMemberlist  ­RegisterRegister  ­Log inLog in  
Share | 
 

 How to make an ITEM move and touch walls

View previous topic View next topic Go down 
AuthorMessage
Revan
Admin


Posts: 22
Join date: 2008-06-18
Age: 15
Location: In your head messing with your thoughts!

PostSubject: How to make an ITEM move and touch walls   Thu Jun 26, 2008 9:34 pm

Hi Revan here... im gonna show you how to make a item in flash move by using the arrow keys on your keyboard...

There is not collision detection, so char can walk outside from stage, but dont worry about that, we will fix that later... anyways...

First lets set up our char. Create 3 new movie clips. You will need one movie clip for character moving left (or right, I chose left), 1 movie clip for character moving up, and final movie clip for moving down. Inside those movie clips place the animations of your item moving.



There is no code needed for those movie clips.

Now edit your "char" movie clip and create total of 5 keyframes inside it:



In keyframe 1 place the "char_up" movie clip, in keyframe 2 place "char_left", keyframe 4 gets "char_right" and keyframe 5 "item_down". You can use same movie clip for both left and right movement, you only flip one of the instances horisontally. Now make sure every instance with movement animation has instance name "char". Check the frames 1, 2, 4 and 5 again. They all are named "char"? Dont worry, if you dont understand yet why certain movement is suppose to be in certain frame, we explain it when we look at the movement code.



Coding
Our hero will move and movement needs speed, so add speed property to hero object:

char={xtile:2, ytile:1, speed:4};
Speed is the number of pixels our hero will move on the screen, higher speed means he moves faster and slower speed makes him move like a snail. Its good practise to use integer as speed or you might get weird results and you wont see any difference between 10 pixels and 10,056873 pixels anyway.

As you remember (if you dont remember, please look in the previous chapter), we have created object _root.char to hold char info, and we have placed "char" movie clip in the "tiles" movie clip. To make our hero wake up and start to move, we need two more functions and controller movie clip to check for keys in each step.

Drag instance of "empty" movie clip to the stage. You can place it outside of visible area. Its only going to call the function so it doesnt matter where it stands. Write code to this mc:

onClipEvent (enterFrame) {
_root.detectKeys();
}

You can see that in every frame we are calling function detectKeys. Now lets write it:

function detectKeys() {
var ob = _root.char;
var keyPressed = false;
if (Key.isDown(Key.RIGHT)) {
keyPressed=_root.moveChar(ob, 1, 0);
} else if (Key.isDown(Key.LEFT)) {
keyPressed=_root.moveChar(ob, -1, 0);
} else if (Key.isDown(Key.UP)) {
keyPressed=_root.moveChar(ob, 0, -1);
} else if (Key.isDown(Key.DOWN)) {
keyPressed=_root.moveChar(ob, 0, 1);
}
if (!keyPressed) {
ob.clip.char.gotoAndStop(1);
} else {
ob.clip.char.play();
}
}

First we declare two variables. We set variable ob to point to _root.char (remember, thats where we hold all the info about hero) and we set variable keyPressed to false. Variable keyPressed we use to check if in the end of the function some arrow keys have been pressed or not.

Next we have 4 similar if statements. Each of them checks if one of arrow keys is pressed down. If key is down, they call another function moveChar, using lines like:

keyPressed=_root.moveChar(ob, 1, 0);
This line calls the function moveChar using 3 arguments. First argument is the variable ob, that points to our char object. Last two arguments are always set -1, 1 or 0. Those determine if we should move hero horisontally by changing its x coordinate (second argument) or vertically by changing y coordinate (third argument). Last we set the return value of function moveChar to the variable keyPressed. You can soon see that moveChar function always returns "true", so if any of the arrow keys are pressed, variable keyPressed will be set to true.

Last piece of code checks, if variable keyPressed is false, meaning no arrow keys has been pressed, in which case we stop the movement animation using gotoAndStop(1). If variable keyPressed is however true, we continue to play the movement animation.

Now the second function:

function moveChar(ob, dirx, diry) {
ob.x += dirx*ob.speed;
ob.y += diry*ob.speed;
ob.clip.gotoAndStop(dirx+diry*2+3);
ob.clip._x = ob.x;
ob.clip._y = ob.y;
return (true);
}

See, moveChar function accepts 3 arguments, variable ob will be the object to move, dirx and diry are values to move in x or y direction. This is very universal function, we can use it to move everything on the game. If we had bullet flying, we could call moveChar with bullets direction, if we had enemy walking, we can again use same function to move it.

Next two lines adds value of ob.speed to objects x or y variable. Again, if we had different objects (bullet, enemy), they can each have their own speeds. So, when we detected right arrow key and called the moveChar function using 1, 0 then dirx=1 and diry =0. Now the x will be increased by speed while y remains the same. If we called moveChar function using 0, -1 (thats what up arrow uses), the y would be decreased by speed and x remains same.

Note that if we would have more movement stuff, like collision or gravity, we would calculate the values of x and y right here, before even replacing the actual movie clips. Thats much better way then using simple mc.hitTest method.

The line

ob.clip.gotoAndStop(dirx+diry*2+3);
sends character movie clip to correct frame to face to the direction it moves. You can calculate all the variations of dirx/diry (there are 4 different pairs so it wont take long to check) and you see that character movie clip is sent to right frame just like we did set it up earlier.

Dont have calculator? Lets see if it works: right arrow key was pressed, dirx = 1, diry = 0. Find the frame. diry * 2 = 0. dirx + 0 + 3 = 1 + 3 = 4. Its going to show frame 4. And frame 4 is where we did put our char_right animation.

Next two lines set the _x/_y properties of character movie clip to the values of x/y variables.

And finally we return "true" so we get the variable keyPressed to have correct value.

Now i will show you how to add walls...

Its no fun having hero that can walk, but cant hit the wall. We will make our hero to feel the power of solid brick wall. Or any other tile we decide to be not walkable:

When object representing tile in current position has property walkable set to "false", hero cant go there. But then again, if the walkable property is "true", then hero can walk there (thats called "logic", people learn it in the school, some even in the university, poor, poor devils).

In order this magic to work, we will do following: after arrow key has been pressed, we check if the tile, where char will walk, is walkable. If it is, we will move the hero. If the tile is not walkable (the hard brick wall type), then we will ignore the arrow keys pressed.

This is perfect collision with wall:



Hero stands next to wall and in next step he would be inside the wall. We cant let it happen, so we wont. No moving, man! But world is not perfect, what if only part of hero would be colliding:



That requires us to check for collision between hero and wall with all 4 characters corner points. If any of hero's corners (lower left corner in this example), would be inside the wall, we will stop the hero.

Or if hero is not next to wall yet, but would still go inside the wall if you allow him to step there:



We will have to place hero by the wall:



Give me my Corners
We dont want parts of our character go inside wall so we have to check collision between hero and the unwalkable object using not one, but four points. We will use corner points, expecting most of heroes look like rectangles (they DO!).

For the purpose lets make new function called getMyCorners:

function getMyCorners (x, y, ob) {
ob.downY = Math.floor((y+ob.height-1)/game.tileH);
ob.upY = Math.floor((y-ob.height)/game.tileH);
ob.leftX = Math.floor((x-ob.width)/game.tileW);
ob.rightX = Math.floor((x+ob.width-1)/game.tileW);
//check if they are walls
ob.upleft = game["t_"+ob.upY+"_"+ob.leftX].walkable;
ob.downleft = game["t_"+ob.downY+"_"+ob.leftX].walkable;
ob.upright = game["t_"+ob.upY+"_"+ob.rightX].walkable;
ob.downright = game["t_"+ob.downY+"_"+ob.rightX].walkable;
}

This function accepts 3 arguments: x/y position of the center point of object on stage (pixels) and name of the object. Wait, we already know x/y position of the object, we have it saved inside the char object, you may wonder. Thats true, but we have saved the CURRENT position of the char, here we are dealing with the position char WOULD BE if it would move.

First we calculate the tiles where character extends. Its center might be on one tile, but its left side might be on other tile, its highest point might be on third tile. Adding variable y with the height of hero and dividing it with height of tile, we will get the number of tile where objects lowest point (downY) will stand.

Last 4 lines use points we calculated to get the value of walkable property in each tile on the corners. For example upleft corner uses upY and leftX variables. As you can see all the points are also saved in the ob object and we can access them later when moving the char. I would again like to point out, how getMyCorners function will work with any moving object, not only the hero.

Move
When we know the types of tile each corner of character will be on, we can easily write movement for the char: if all the corners are walkable, then move, else dont move. More work is needed to place the hero right next to wall if the collision would happen. Our modified moveChar function to handle all 4 possible directions might look a bit confusing, but most of it is written 4 times over for each direction. Lets look at the function:

function moveChar(ob, dirx, diry) {
getMyCorners (ob.x, ob.y+ob.speed*diry, ob);
if (diry == -1) {
if (ob.upleft and ob.upright) {
ob.y += ob.speed*diry;
} else {
ob.y = ob.ytile*game.tileH+ob.height;
}
}
if (diry == 1) {
if (ob.downleft and ob.downright) {
ob.y += ob.speed*diry;
} else {
ob.y = (ob.ytile+1)*game.tileH-ob.height;
}
}
getMyCorners (ob.x+ob.speed*dirx, ob.y, ob);
if (dirx == -1) {
if (ob.downleft and ob.upleft) {
ob.x += ob.speed*dirx;
} else {
ob.x = ob.xtile*game.tileW+ob.width;
}
}
if (dirx == 1) {
if (ob.upright and ob.downright) {
ob.x += ob.speed*dirx;
} else {
ob.x = (ob.xtile+1)*game.tileW-ob.width;
}
}
ob.clip._x = ob.x;
ob.clip._y = ob.y;
ob.clip.gotoAndStop(dirx+diry*2+3);
ob.xtile = Math.floor(ob.clip._x/game.tileW);
ob.ytile = Math.floor(ob.clip._y/game.tileH);
return (true);
}

Like before, moveChar function gets object and directions from the detected keys. The line:

getMyCorners (ob.x, ob.y+ob.speed*diry, ob);
calculates the corner points for vertical movement (when diry is not equal to 0). After we have calculated the corners, we can use the values from each tiles walkable property to check if hero can step there:

if (diry == -1) {
if (ob.upleft and ob.upright) {
ob.y += ob.speed*diry;
} else {
ob.y = ob.ytile*game.tileH+ob.height;
}
}

This block of code works for up movement. When up arrow key was pressed, value for diry = -1. We use values of ob.upleft and ob.upright calculated in the getMyCorners function, if they are both "true" meaning both tiles are walkabale, we let char move like we did before adding speed*diry to char's y property.

But if one of corners happens to be inside the wall and so value of ob.upleft or ob.upright is "false", we place object near the wall. For char to be next to wall above it, its center point must be placed below the current tiles upper border by char.height.



ob.ytile*game.tileH would place character's center on the line between two tiles, we add height property of object to move it further down. Same way moveChar function goes through movements for down (diry == 1), left (dirx == -1) and right (dirx == 1).

Last lines place actual clip of character on the position calculated, make character show correct frame with animation and calculate new values for characters center point (xtile, ytile). Just like before, function returns "true".

I'M PRETTY SURE YOUR ALL THERE GOING HOW MUCH LONGER CAN THIS GO FOR RIGHT? BUT HAVE NO FEAR FOR YOU HAVE FINISHED IT!!! YAY!!!

Hope this helps you all... if you have any questions about this PM me! Very Happy

_________________
90% of teens today would die if Myspace or Bebo had a system failure and was completely destroyed. If you are one of the 10% that would be laughing, copy and paste this to your signature.


Back to top Go down
View user profile http://pro-flash-beat.darkbb.com/
 

How to make an ITEM move and touch walls

View previous topic View next topic Back to top 
Page 1 of 1

Permissions of this forum:You cannot reply to topics in this forum
Pro Flash Beat :: Animation :: Tutorials :: Flash-