مشاكل الكشف عن الاصطدام القائم على البلاط في لعبة فون 2-D

StackOverflow https://stackoverflow.com/questions/1501844

سؤال

نصب:
أنا أعمل على لعبة قائمة على البلاط 2 د (عرض عين الطير) لفون. يقرأ التطبيق في ملف Tilemap Tile-D ( أذكر أكثر من كل بلاط في الخريطة وإنشاء مجموعة مائية م 2 درجة مئوية تمثل صفوف البلاط وعقد العقارات المحظورة (صحيح / خطأ) من كل بلاط. عندما أقوم بنقل البطل في جميع أنحاء اللوحة، أتحقق من موقع البطل مع مجموعة لمعرفة ما إذا كان البلاط الذي نقله محظور أم لا. إذا تم حظره، يتم عكس موقف البطل بقدر ما كانت متقدمة.

الفترة:
المشكلة هي، عندما دخل البطل على بلاط محظور، لا يستطيع الانتقال منه. مواقف البلاط صحيحة بمعنى أن البلاط المحظور يتم اكتشافه حيث يجب أن يكونوا سوى بطل عالق. Hero Survences 'by Pixel' وليس "بالبلاط". هذا عن كل شيء. الشيء الوحيد المتبقي هو عرض الرمز: (البطل 28 بكسل بحجم 36 بكسل)

//Code from GameScreen.m





-(void)generateCollisionMap
{




for(int layer=0; layer < 2; layer++) {
            for(int yy=0; yy < _screenTilesHeight; yy++) {

                NSLog(@"Row %i", yy);

                for(int xx=0; xx < _screenTilesWide; xx++) {
                    int _globalTileID = [[[tileMap layers] objectAtIndex:layer] getGlobalTileIDAtX:xx y:yy];
                    NSString *_value = [tileMap getTilePropertyForGlobalTileID:_globalTileID key:@"blocked" defaultValue:@"false"];
                    if([_value isEqualToString:@"true"]) {

                        _blocked[xx][yy] = YES;
                        NSLog(@"Cell %i = YES", xx);

                    }else{

                        if(_blocked[xx][yy] == YES){
                        NSLog(@"Leaving Cell %i as = YES", xx);
                            //Leave As Is

                        }else{

                         _blocked[xx][yy] = NO;
                        NSLog(@"Cell %i = NO", xx);

                        }

                    }
                }
            }
            }
}





//Code from Hero.m


-(void)moveHero
{

            // Up

            if(moveDirection == 1 && !doesNeedShiftWorld) {
                heroY += _playerSpeed;
                [self checkBlocked:1];
                _currentAnimation = _upAnimation;
                _moving = YES;
            }

            // Down
            if(moveDirection == 2 && !doesNeedShiftWorld) {
                heroY -= _playerSpeed;
                [self checkBlocked:2];
                _currentAnimation = _downAnimation;
                _moving = YES;
            }

            // Left
            if(moveDirection == 3 && !doesNeedShiftWorld) {
                heroX -= _playerSpeed;
                [self checkBlocked:3];
                _currentAnimation = _leftAnimation;
                _moving = YES;
            }

            // Right
            if(moveDirection == 4 && !doesNeedShiftWorld) {
                heroX += _playerSpeed;
                [self checkBlocked:4];
               _currentAnimation = _rightAnimation;
                _moving = YES;
            }



}   



//  ... 


- (void) checkBlocked:(int)checkDirection
{

    float xx = (heroX+160.0f+_tileWidth) / _tileWidth;
    float yy = 11-((heroY+300.0f+_tileHeight) / _tileHeight); 


    switch (checkDirection) {

        case 1:

            yy -= 1;

            if([_scene isBlocked:xx y:yy] ||
               [_scene isBlocked:(heroX+160.0f) y:yy]) {
                NSLog(@"Scene Blocked at %i, %i!", (int)xx, (int)yy);
                heroY -= _playerSpeed;

            }else{

                NSLog(@"Clear at %i, %i!", (int)xx, (int)yy);

            }

            break;

        case 2:


            if([_scene isBlocked:xx y:yy] ||
               [_scene isBlocked:xx y:(heroY+300.0f)] ||
               [_scene isBlocked:(heroX+160.0f) y:(heroY+300.0f)]) {
                NSLog(@"Scene Blocked at %i, %i!", (int)xx, (int)yy);
                heroY += _playerSpeed;

            }else{

                NSLog(@"Clear at %i, %i!", (int)xx, (int)yy);

            }


            break;

        case 3:

            xx += 1;

            if([_scene isBlocked:xx y:yy] ||
               [_scene isBlocked:(heroX+160.0f) y:yy] || 
               [_scene isBlocked:(heroX+160.0f) y:(heroY+300.0f)]) {
                NSLog(@"Scene Blocked at %i, %i!", (int)xx, (int)yy);
                heroX += _playerSpeed;

            }else{

                NSLog(@"Clear at %i, %i!", (int)xx, (int)yy);

            }


            break;

        case 4:


            if([_scene isBlocked:xx y:yy] || 
               [_scene isBlocked:xx y:(heroY+300.0f)]) {
                NSLog(@"Scene Blocked at %i, %i!", (int)xx, (int)yy);
                heroX -= _playerSpeed;

            }else{

                NSLog(@"Clear at %i, %i!", (int)xx, (int)yy);

            }


            break;

    }

}
هل كانت مفيدة؟

المحلول

مشكلتك هي أنك تتحرك اللاعب، من ثم التحقق لمعرفة ما إذا كانت المساحة التي انتقل إليها حظرها. بدلا من ذلك، فأنت ترغب في معرفة الموضع الذي سيعمل عليه الانتقال إليه، راجع ما إذا كان محظورا، ثم حركه فقط إذا لم يتم حظره. أيضا، يمكنك دائما إضافة بند لاستبعاد مساحته الحالية. أي طالما أن شخصيتك لا تتغير مساحات الشبكة، فيمكنه دائماً التحرك، ولكن بمجرد أن يكون على وشك تغيير مساحات الشبكة، يجب عليك التحقق لمعرفة ما إذا كان سوف يصطدم بشيء ما.

هنا هو الكود الخاص بك أدناه:

if(moveDirection == 1 && !doesNeedShiftWorld) {
    heroY += _playerSpeed;
    [self checkBlocked:1];
    _currentAnimation = _upAnimation;
    _moving = YES;
}

يجب أن يكون شيء مثل هذا:

if(moveDirection == 1 && !doesNeedShiftWorld)
{
    //Figure out if the player is changing grid spaces.
    BOOL isChangingSpaces = ((int)((heroY + _playerSpeed) / myGridSizeVariable) != (int)(heroY / myGridSizeVariable));

    //The player should be able to move either if he isn't
    //changing grid spaces or if his destination space is free.
    if ( !isChangingSpaces || (spaceIsOpenAtX:heroX andY:heroY+_playerSpeed) )
    {
        heroY += _playerSpeed;
        _currentAnimation = _upAnimation;
        _moving = YES;
    }
}

ويجب حقا محاولة جعل الكود الخاص بك كثيراً المزيد من وجوه المنحى. في هذه المرحلة، يبدو أنه إجرائي تماما وجميع المتغيرات الخاصة بك هي Globals، وهي بالتأكيد ليست طريقة جيدة للذهاب. يجب إعادة كتابة "checkbbeblocked" ك "SPAYISOPENATX: أندي:" لأنه بعد ذلك يمكنك وضع أي x و y بالتنسيق الذي تريده من أجل معرفة ما إذا تم حظر هذا الموضع. كما فعلت ذلك الآن، رمزك مجردة للغاية (يمر حول الأعداد الصحيحة دون أي إشارة إلى ما هم تعني بخلاف الشيكات الفعلية إذا كان الاختبارات) ولا يمكن تطبيقها على أي موقف على الإطلاق من الاستخدام الوحيد الذي أعطيته فيه.

حقا، يجب أن يكون لديك player.speed واللاعب. طريقة OO.

نصائح أخرى

أعتقد أن المشكلة هي أنك تسمح للاعب بالانتقال إلى البلاط المحظور ويتعثر.

وأود أن تحقق لمعرفة ما إذا كان الاتجاه يتحرك اللاعب يتحرك قبل محاولة نقل اللاعب هناك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top