Самая простая вещь, которую вы можете сделать, для шаров - это hitTestPoint с третьим аргументом true, который включает определение формы.
ground.hitTestPoint (x, y, true);
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/DisplayObject.html#hitTestPoint()
Хорошо, так что, хм, вы можете проверить одну точку на шаре, например, его нижнюю точку, или вы можете проверить массив точек вдоль нижней части шара для более легкой точности.Это самый быстрый способ сделать это, если вы не планируете ничего более сложного, чем это.Однако, если вы хотите создать полноценную игру, оставьте ее в 2d библиотеке физики, такой как http://www.box2dflash.org/.
Забудьте обнаружение столкновений скинов для более крупной игры (что-то маленькое, подобное этому, может с этим справитьсяхотя), поскольку он основан на растровом изображении и будет снижать производительность намного больше, чем box2D, это хороший пример маски, но его не рекомендуется использовать из соображений производительности.
Я немного изменил ваш код,Я проверил несколько точек в нижней части шара, имейте в виду, что шарик 0,0 внутри мувиклипа центрирован по центру шариков.
package
{
import flash.display.MovieClip;
import flash.events.*;
import flash.geom.Point;
public class ball extends MovieClip
{
public var vX:Number = 0;
public var vY:Number = 2;
private var gravity:Number = 0;
public function ball()
{
// constructor code
addEventListener(Event.ENTER_FRAME, loop);
}
public function loop(e:Event)
{
this.x += vX;
this.y += vY;
this.vY += gravity;
if (this.x > stage.stageWidth || this.x < 0 || this.y < 0 || this.y > stage.stageHeight)
{
removeSelf();
}
/*we will now check something like 18 points on the bottom side of the ball for colision
instead of just the bottom, you can probably guess why... if you cant, replace i on line
43 (var angleInRadians...) with 270 to test and then drop balls on a slopped ground surface... of course
you should definitely juse a physics engine like http://www.box2dflash.org/ for anything more complex.
*/
for (var i:int = 180; i<=360; i+=10)
{
/*keep in mind that ball.rotation property has 0 at the top of the ball, while here for these we are using the standard
Cartesian coordinate system. The effect of this on rotation would be that it is +90 and for X(yes, X) it would be Math.SIN(),
not Math.COS()!!!, and for Y it would be Math.sin() with a minus in front because of the flash coordinate system y axis rotation.
It's not really related to this, but it's a point that has anoyed me to no end in trig related stuff in flash when I was starting.
*/
var angleInRadians:Number = i / 180 * Math.PI;
var posX:Number = this.x + Math.round(Math.cos(angleInRadians) * width / 2);
var posY:Number = this.y - Math.round(Math.sin(angleInRadians) * height / 2);//minus because y in flash is upside down
Engine.ground.hitTestPoint(posX,posY, true);
if (Engine.ground.hitTestPoint(posX,posY, true))
{
stopBall();
}
else
{
}
}
/*if (Engine.ground.hitTestObject(this))
{
trace('yep')
stopBall()
}
else
{
trace('nope')
}*/
}
public function removeSelf()
{
removeEventListener(Event.ENTER_FRAME, loop);
this.parent.removeChild(this);
}
public function stopBall()
{
gravity = 0;
vY = 0;
vX = 0;
}
}
}
Вы не связаны с этим выше, вынужно немного переосмыслить ООП, вы делаете что-то немного неправильно :).Этот маленький проект справится, но все, что больше, даст вам головную боль.Не воспринимайте это как атаку, я хочу попытаться направить вас по «правильному» пути и показать логические ошибки в вашем коде, я не упоминаю это как «pwn», потому что ваш упор плохой :).
Например, гравитация, внутри класса мяч?Да ... что если ты хочешь иметь гравитацию для ниндзя, сюрикенов, тряпичных кукол и т. Д.?Собираетесь ли вы подкласса ниндзя вне класса мяча?
Ниндзя расширяет мяч?Это было бы весело.
Как вы думаете, могло бы быть лучшее место для этой гравитации?Является ли «гравитация» свойством шара вообще (да, технически это так, но не той однородной гравитацией, которую вы здесь вкладываете, это больше похоже на проникающую, все существующую вещь, потому что есть какое-то огромное тело, к которому мы слишком близки))?Это должно быть в Engine ...
Кроме того, вы сделали Engine.ground вещь ... теперь, это статическая переменная ... это еще одна плохая вещь, очень плохая вещь:)
Причина аналогична предыдущему примеру, но немного обернулась.Что, если вы хотите повторно использовать мяч внутри, скажем, Engine2?Или двигатель Crytek?или УДК?Я думаю, это может быть проблематично, не правда ли?Вам нужно было бы пойти и изменить класс мяча ... Представьте, что каждый код, который вы использовали, заставлял вас делать это ...
В принципе, вы, вероятно, могли бы сделать что-то вроде этого:
var bla: ball = новый шар (земля);
это лучше, намного лучше ... теперь мы можем легко использовать его в crytek, udk и Engine2 ...
Технически,Вы хотите избежать таких вещей, как статические переменные в своем коде, идея называется инкапсуляция.Идея состоит в том, что вы скрываете внутреннюю работу классов от других классов, которые не связаны с ним или не должны знать об этом.Чем меньше вы ДОЛЖНЫ знать, тем более переносимы и пригодны для повторного использования (yada yada) ваши занятия.Engine.ground - огромный разрушитель инкапсуляции, потому что у шара нет абсолютно никакой нужды знать класс Engine, он должен касаться только ссылки на саму землю ...
Со временем вы узнаете все это,паттерны в программировании и, в частности, какие паттерны экономят время, а какие ужасны и почему (статические переменные имеют свое применение, но только для сверхпростых вещей, избегайте также Singletons, если вы знаете, что они есть).
http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)
Извините за головную боль, которую я вам причинил ...
Помните, используйте физический движок для более сложного кода, не изобретайте колесо (повторно используйте все для ваших проектов, что хорошо для них / достаточно для них) ... Интересно тестировать подобные вещи, но другие людисделали это лучше перед вами, и если вам специально не нужно углубляться в их область, вам не нужно заботиться о каждой мелочи.Вы, вероятно, пытаетесь создавать игры / что-то, не заботясь о ньютоновской динамике ...
HitTest - это просто хорошо для простых вещей, но это граничит с простыми ...:) мы уже немного в физикездесь, и вы можете обнаружить, что вам нужно более надежное решение в ближайшее время ...
Поэтому, как правило, старайтесь сделать свой код "надежным", думая о инкапсуляции и зависимостях между вашими классами.Если зависимость кажется неестественной (то есть мяч зависит от движка), то, возможно, что-то не так, и она сломается позже, сломается для другой игры или движка или ... Я закончу это здесь ...
Взятьзаботиться и веселиться.