View Full Version : Making walls, the fast way. Tips?
jns.johansson
February 25th, 2009, 09:00 AM
hi,
i have a school assignment where I am told to re-interpret "little red riding hood", now i want to make a great composition of different RPG's where Link plays the main character but i have to present a demo soon and won't have time to create a fully functional tile-system.
so, i need to do it a speedy way.
i took a background for a village, placed the character, made him walk, now i need to make borders/"walls" really quick. at first i thought i could just do it like thishttp://jonasjohansson.se/1.png
With a movieclip called "border" and then character.hitTestObject(border), but ofcourse the bounding box of the movieclip is all the small fields together, so this results true always.
Then i thought i could make a for loop which checked all the children of border, like for (i = 0; i < border.numChildren; i++) { hitTest(border.getChildAt(i)) } sortof.
but no luck either.
i am terribly stressed and there has to be a simple solution for this no?
so, i would be ever so grateful if someone could assist me :)
dandylion13
February 25th, 2009, 05:35 PM
Have you tired hitTestPoint?
If you set the shapeflag variable to true and you can check whether the character is touching the area of the background (the shape of the background itself, rather than its bounding box). It won't give you pixel perfect accuracy but you probably don't need that in this project... ?
jns.johansson
February 25th, 2009, 07:34 PM
hey, an answer, nice!
i think i have tried it, but i will try one more time!!
thanks in advance, and no, pixel perfection is not necessary :P
jns.johansson
February 25th, 2009, 08:00 PM
nope, it does not work.. but i am having some hard time understand HitTestPoint.. i will link to the source (it's basic and easy to overlook!).
http://jonasjohansson.se/hittest.fla (http://jonasjohansson.se/hittest.fla)
if (char.hitTestPoint(border.x, border.y, true))
{
trace("Hit!");
}
I tried this but it only gives true when i am at the point given, border.x, border.y which is not the complete shape.
if you or anyone else has the time.. :)
jns.johansson
February 25th, 2009, 08:05 PM
oh wait.. i did it backwards, i re-read the livedocs and did some logical thinking..
i check if the walls are touching the moving object.. sure, makes sense..
hey, thanks for the answer, i think i got it solved :):)
i knew i was stupid in at least one way when i thought about this.. :P
dandylion13
February 25th, 2009, 08:48 PM
Glad you got it solved :) Yeah, it's a neat trick.. congrats! Hope your game goes well.
jns.johansson
February 26th, 2009, 07:34 AM
well.. let's just say for a while that i would like it to be pixel-perfect, how would i accomplish that? I read another post you had written and it made sense, except I can't check the halfwidths of both the wall and the character since the width of the wall will be the width of the bounding box.
i also read the tonypa-tutorial but that way of doing things seems rather.. not cool.
if (border.hitTestPoint(character.x, (character.y - 0.5*character.height) - speed, true))
i did this for all the different directions, with different equations ofcourse and it works but not completely, tonypa's talk about making the four corners make sense but i dont understand how i can replicate it using hitTestPoint,
unless i nest "if" and test for several values.
you got any pointers? now, it's not necessary but i would really like to know :D
jns.johansson
February 26th, 2009, 08:16 AM
I ended up doing it like this, so if the character approeaches from the right, it checkes the top-left-corner and the bototm-left-corner of the character.
is this a correct way to approach the problem? :D
switch (e.keyCode)
{
case LEFT:
if (border.hitTestPoint(character.x - speed, character.y + character.height, true)
|| border.hitTestPoint(character.x - speed, character.y, true))
{
}
else
{
character.x -= speed;
}
break;
case UP:
if (border.hitTestPoint(character.x, character.y - speed, true)
|| border.hitTestPoint(character.x + character.width, character.y - speed, true))
{
}
else
{
character.y -= speed;
}
break;
case RIGHT:
if (border.hitTestPoint(character.x + character.width + speed, character.y + character.height, true)
|| border.hitTestPoint(character.x + character.width + speed, character.y, true))
{
}
else
{
character.x += speed;
}
break;
case DOWN:
if (border.hitTestPoint(character.x, character.y + character.height + speed, true)
|| border.hitTestPoint(character.x + character.width, character.y + character.height + speed, true))
{
}
else
{
character.y += speed;
}
break;
}
jns.johansson
February 26th, 2009, 08:31 AM
http://jonasjohansson.se/littleredrpg.fla
it works towards walls, sortof, there is a small gap that appears sometimes.. i'm really at a loss here.. it feels like i'm close to pixel-perfection and it feels stupid to just abondon it if i can do it :)
please do have a look.
http://jonasjohansson.se/littleredrpg.swf
dandylion13
February 26th, 2009, 11:46 AM
Hi,
The gaps are there because the object is being pushed back to a position where it was before the objects were colliding (your speed value.) To make it more precise you need to figure out by how much the objects are acutally overlapping when the collision occurs.
This is the difference between their distances and their combined half-widths (or half-heights). Once you've got that value the object's new position is its current x/y position minus the overlap. The only hitch is that you also need to know the direction of the collision so that you can add or subract the overlap correctly.
Anyway, that's the general idea, but you're on the right track :)
jns.johansson
February 26th, 2009, 01:04 PM
yo,
but how can i get the half-width of an object of which i can't target? the border-movieclip in the .fla has it's width according to it's boundingbox..
i'm really trying to understand your pointers, and i do, to a certain degree. But I can't grasp the concept of the halfWidths really..
http://jonasjohansson.se/littleredrpg.swf
what would you change here? can you give an example? still the gap appears but this time i dont have a pushback, i just check "if i increment with 1 will it collide? no? increment. yes? don't increment".
function keyHandler(e:KeyboardEvent) {
var halfWidth:Number = 0.5 * character.width;
var halfHeight:Number = 0.5 * character.height;
var fullWidth:Number = character.width;
var fullHeight:Number = character.height;
switch (e.keyCode) {
case LEFT :
if (border.hitTestPoint(character.x - moveRate, character.y, true)
|| border.hitTestPoint(character.x - moveRate, character.y + fullHeight, true)) {
}
else
{
character.x -= moveRate;
}
break;
case RIGHT :
if (border.hitTestPoint(character.x + fullWidth + moveRate, character.y, true)
|| border.hitTestPoint(character.x + fullWidth + moveRate, character.y + fullHeight, true)) {
}
else
{
character.x += moveRate;
}
break;
case UP :
if (border.hitTestPoint(character.x, character.y - moveRate, true)
|| border.hitTestPoint(character.x + fullWidth, character.y - moveRate, true)) {
}
else
{
character.y -= moveRate;
}
break;
case DOWN :
if (border.hitTestPoint(character.x, character.y + fullHeight + moveRate, true)
|| border.hitTestPoint(character.x + fullWidth, character.y + fullHeight + moveRate, true))
{
}
else
{
character.y += moveRate;
}
break;
}
}
and again, thanks for the help! feels like i'm almost there.
jns.johansson
February 26th, 2009, 02:54 PM
i understand that if i adjust the speed of the character to say 10 px, he will always be 10 px away from the borders, since my check is "currentX + speed".
but since i don't work with tiles i can't compute the distance, i cant get the value of the specific border to subtract from the characters value.
if border.x = 100 and character.x = 105 i can see that 5 is the difference, as it is now i can only understand that the distance is less than 10px (speed)..
sigh.. but i have gotten far, but would be cool to get it completely uberdone :D
dandylion13
February 26th, 2009, 05:32 PM
Here's a quick example:
var combinedHalfwidths = (objectA.width/2) + (objectB.width/2);
You can get the distance between them like this:
var distanceX = Math.abs(objectA.x - objectB.x);
(you will need to check on the y axis too.)
If distanceX is less than combinedHalfwidths then you know the objects are colliding The difference is the amount of overlap. Then you subtract or add the overlap to the object's position to get the exact position where it touches the object.
jns.johansson
February 26th, 2009, 06:33 PM
yo again :)
if ObjectA is the "character" and let us say ObjectB is a table which "character" can't touch then I understand what you are saying.
but ObjectB for me is a big movieclip called border, with rectangles inside which makes up for tables, chairs and what not, so if I follow your example like ObjectB.width/2 would not give me half the with of a table, it would give me half of the boundingbox for all the objects.
like in this example (http://jonasjohansson.se/littleredrpg.swf)
now this code works, but it's not pixelperfect, at the moment the "speed" is set to one pixel so it's as close as it gets but if i change to a larger number the gap will be more significant.
and since i can't "see" which objects i can only make hitTestPoint-tests to see if i will bump in to anything.
or, did i just not understand what you wrote? perhaps i got it all wrong.. :) can't believe it's this hard.. perhaps it's just because i am making a lazy-version.. (depth-sorting like this isnt really possible.. :P)
dandylion13
February 26th, 2009, 06:59 PM
Sorry, I didn't understand your first explaintion.. you're right, it's my mistake :)
Yes.. pixel perfect collision detection is a pretty big topic. I'm not sure how to do it using your current setup.. maybe there is a way though... ?
jns.johansson
February 26th, 2009, 07:26 PM
or you do know! but it's easier to say u don't to avoid more trouble! :)
no, just kiddin', yeah sure there is a way.. it's a really stupid way though, it's like this.
if (will it hit if i go 10 px to the left)
{
if (will it hit if i go 8 px to the left)
{
if (will it hit if i go 6 px to the left) ...........
}
else
{
go 8 px to the left
}
}
else
{
go 10 px to the left
}
but, if i were to write a function which made an automatic check, which distance in pixels is the highest without making a collision it could be smoother..
but still.. it's a hell of a way of doing things!
thanks for all the help, just msg me if u need any help with css/html or what not.
tapioca
March 1st, 2009, 12:51 PM
ive done this before when i had irregular clipping boundries and no other way of finding the edges.
if (border.hitTestPoint(character.x, character.y - speed, true)
|| border.hitTestPoint(character.x + character.width, character.y - speed, true))
{
for (i = speed; i > 0; i--)
{
if (!border.hitTestPoint(character.x, character.y - i, true)
|| !border.hitTestPoint(character.x + character.width, character.y - i, true))
{
character.y -= i;
}
}
}
else
{
character.y -= speed;
}
it just tests every point along your trajectory until it finds one that doesn't collide.
edit: oh i didn't see the last post. this is a way of doing that with a loop, it's much shorter.
Powered by vBulletin® Version 4.1.10 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.