Это все в actionscript 3.0 и кодируется во flash cs5.5. Я делаю игру «тяни-толкай», в которой игрок толкает блок. Уровни в конечном итоге будут очень большими и будут иметь множество экземпляров каждого класса, поэтому нецелесообразно называть каждый символ именем экземпляра на сцене. У меня есть этот файл engine.as, который я написал, но я не могу понять, почему он не работает. Вот весь класс, но я пытаюсь использовать функцию hitTestClass; упаковка {
import flash.display.DisplayObject;
import flash.display.MovieClip;
import flash.events.Event;
public class Engine extends MovieClip
{
private static var _instance:MovieClip;
public function Engine()
{
stop();
_instance = this;
}
public static function add(object:Object):void
{
if (object!=DisplayObject) return;
_instance.addChild(object as DisplayObject);
}
public static function remove(object:Object):void
{
if (object is Array) {
removeList(object as Array);
return;
}
if (!(object is DisplayObject) || object.parent!=_instance) return;
_instance.removeChild(object as DisplayObject);
}
public static function removeList(objects:Array):void
{
while (objects.length>0) remove(objects.pop());
//trace(objects.length);
}
public static function getByName(name:String):Object {
if (_instance) {
for (var i:int = 0; i < _instance.numChildren; i++)
{
if (_instance.getChildAt(i).name==name) {
return _instance.getChildAt(i);
}
}
}
return null;
}
public static function getAllByName(name:String):Array {
var list:Array = new Array();
if (_instance) {
for (var i:int = 0; i < _instance.numChildren; i++)
{
if (_instance.getChildAt(i).name==name) {
list.push(_instance.getChildAt(i));
}
}
}
return list;
}
public static function getByClass(className:Class):Object {
if (_instance) {
for (var i:int = 0; i < _instance.numChildren; i++)
{
if (_instance.getChildAt(i) is className) {
return _instance.getChildAt(i);
}
}
}
return null;
}
public static function getAllByClass(className:Class):Array {
var list:Array = new Array();
if (_instance) {
for (var i:int = 0; i < _instance.numChildren; i++)
{
if (_instance.getChildAt(i) is className) {
list.push(_instance.getChildAt(i));
}
}
}
return list;
}
public static function hitTestName(object:DisplayObject, name:String):Object
{
var list:Array = getAllByName(name);
return hitTestList(object, list);
}
public static function hitTestClass(object:DisplayObject, className:Class):Object
{
var list:Array = getAllByClass(className);
return hitTestList(object, list);
}
public static function hitTestList(object:DisplayObject, list:Array):Object
{
var hits:Array = new Array();
for (var i:int=0; i<list.length; i++) {
if (object != list[i] && object.hitTestObject(list[i])) {
hits.push(list[i]);
}
}
return hits;
}
}
}
На протяжении всей игры я использую функции обновления, которые находятся внутри класса каждого «блока», и именно здесь они проверяют наличие тестов попадания. Вот пример из класса wallBlock, который гарантирует, что персонаж не сможет пройти через wallBlock. функция способнаяToCheckSides () {
if ((this).x-_root.mcChar.x<63.5 && (this).x-_root.mcChar.x>-63.5)
{
//trace("booty");
//ableToCheckXSides=false;
if((this).y-_root.mcChar.y >=-63 && (this).y-_root.mcChar.y<0 && ableToCheckXSides==false)
{
//ableToCheckXSides=false;
//_root.mcChar.x=_root.mcChar.x;
if(hitTestObject(_root.mcChar)==true)
{
_root.mcChar.y=(this).y+63.5;
}
//if char is moving down and hits the top side of tile
}
else if((this).y-_root.mcChar.y<=63 && (this).y-_root.mcChar.y>0 && ableToCheckXSides==false)
{
//ableToCheckXSides=false;
//_root.mcChar.x=_root.mcChar.x;
if(hitTestObject(_root.mcChar)==true)
{
_root.mcChar.y=(this).y-63.5;
}
//if char is moving up and hits the bottom side of tile
}
}
if ((this).y-_root.mcChar.y<63.5 && (this).y-_root.mcChar.y>-63.5)
{
//trace("YYYYYY");
ableToCheckXSides=true;
if((this).x-_root.mcChar.x >=-63 && (this).x-_root.mcChar.x<0)
{
//trace("inside function");
//ableToCheckYSides=false;
if(hitTestObject(_root.mcChar)==true)
{
_root.mcChar.x=(this).x+63.5;
}
//if char is moving left and hits the right side of tile
}
else if((this).x-_root.mcChar.x<=63 && (this).x-_root.mcChar.x>0)
{
//ableToCheckYSides=false;
if(hitTestObject(_root.mcChar)==true)
{
_root.mcChar.x=(this).x-63.5;
}
//if char is moving right and hits the left side of tile
}
}
else
{
ableToCheckXSides=false;
}
Вот где проблема вступает в игру, в той же функции «обновления», которая возникает в каждом кадре, я пытался использовать свою функцию hitTestClass, чтобы увидеть, попадает ли crateBlock в wallBLock, но она никогда не вернет true. (Если я изменю if( hits.length>0) на if(hits), он всегда возвращает true.)
var hits = Engine.hitTestClass(this, crateBlock);
if (hits.length>0)
{
Engine.remove(hits);
trace("hitting crate");
}
hitTestObject()
будет непрактичным и смехотворно медленным с большим набором объектов. О том, почемуif (hits)
возвращает true.hits
— это массив, в худшем случае — массив нулевой длины, ноhits
не равно null, поэтомуif (hits)
равноif (hits!=null)
и действительно верно. Кроме того, исправьте функциюadd()
, у вас есть сравнение класса и объекта вместо сравненияis
. - person Vesper   schedule 19.12.2013_instance
равен нулю. Для отладки используйте функциюtrace(list.length)
в функцииhitTestClass()
- по-видимому, она тоже пуста. - person Vesper   schedule 19.12.2013