Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Помогите правильно настроить отбивание мяча от палки (http://www.flasher.ru/forum/showthread.php?t=186574)

boldusev 05.11.2012 21:18

Помогите правильно настроить отбивание мяча от палки
 
Вложений: 1
Я новичок в ас3, нубчик.
Пишу игру пинтбол.
При написании кода столкнулся с маленькой проблемой. А именно поведение объекта на сцене.
Грубо говоря - мячик отбивается от правой и левой стенки по y. По х бегают 2 пада, плеера и кома, они отбивают мячик, и при пропуске им засчитывается проигрыш.
Не могу не как настроить правильное отбивание. А так же убрать проваливание мячика. Кто может помочь?

Вот сам код класса.
Код AS3:

package  
{
        import flash.display.DisplayObject;
        import flash.display.MovieClip;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.MouseEvent;
        /**
        * ...
        * @author ZiK
        */

        public class GameScreen extends gamefull_swc
        {
 
                private var goSpeedX:int = 5; //скорость движения по Х
                private var goSpeedY:int = 5;// по У
                private var destX:int;//
                private var destY:int;//
                private var isHit:Boolean = false;// если ударяется то, мячик отбивается?
                private var easing:uint = 3;// анимация
                public var endGamper:uint = 3;
                private var isHit_bottom:Boolean;
                private var ball_ax:Number = 5;
                public var scorePlayer:uint;
                public var scoreComps:uint;
 
                public function GameScreen()
                {
                        if (stage) init();
                        else addEventListener(Event.ADDED_TO_STAGE, init);
                }
 
                private function init(e:Event = null):void
                {
                        removeEventListener(Event.ADDED_TO_STAGE, init);
 
                        trace("Игра создана");
                        addEventListener(Event.REMOVED_FROM_STAGE, destroy);
 
                        stage.addEventListener (Event.ENTER_FRAME, ballGo);// создание слушателя ентерфрейм
                        uPlayer.addEventListener (Event.ENTER_FRAME, uplayerGo);// применяем листенер к юплееру для анимации
                        uPad.addEventListener (Event.ENTER_FRAME, moveEnemy);
 
                        uPlayer.y = 43;// выставляем координаты появления на сцене
 
                        uPad.y = stage.stageHeight - uPad.height - 25;
 
                        playerScore.x = 25;//
 
                        playerScore.title_txt.text = "Player Score";//
                        resetBallposition();
 
                        compScore.x = stage.stageWidth - compScore.width - 25;//
                        compScore.title_txt.text = "Comp Score";//
                        setScore();       
                }
 
 
 
                ///<summary>Меняет очки игроков на экране</summary>
                private function setScore():void
                {
                        playerScore.com_txt.text = String(scorePlayer);
                        compScore.com_txt.text = String(scoreComps);
                        if (scorePlayer != 0 || scoreComps != 0)
                        {
                                resetBallposition();
                        }
 
                }
 
                ///<summary>Восстанавливать позицию мяча на экране!!!!!</summary>
                private function resetBallposition():void
                {
                        stage.removeEventListener (Event.ENTER_FRAME, ballGo);
                        uball.x = stage.stageWidth  / 2;
                        uball.y = stage.stageHeight  / 2;
                        stage.addEventListener (MouseEvent.CLICK, resetBall);
                }
 
                private function resetBall(e:MouseEvent):void
                {
                        stage.removeEventListener (MouseEvent.CLICK, resetBall);
                        stage.addEventListener (Event.ENTER_FRAME, ballGo);
                        if (scoreComps == endGamper || scorePlayer == endGamper)
                        {
                                endGame();
                        }
                }
 
                private function endGame():void
                {
                        dispatchEvent(new Event(CustomEvent.END_GAME));
                }
 
 
                ///<summary>Не позволяет заходить игроку за экран, и добавляет плавную анимацию</summary>
                private function uplayerGo(e:Event):void
                {
 
                        if (uPlayer.x > stage.stageWidth - uPlayer.width)//если игрок по у выходит по всоте, то мы восоту эт отнимаем?
                        {
                                uPlayer.x > stage.stageWidth - uPlayer.width;//
                        }
 
                        uPlayer.x += (mouseX - uPlayer.x) / easing;// сама анимация
 
                }
 
                ///<summary>все действия связанные с мячиком</summary>
                private function ballGo(e:Event):void
                {
 
                        trace ("Высота" +uball.x, "стейдж" + stage.stageWidth);
                        // Отбивание от нижней стенки.
                        if (uball.x > 798)
                        {
                                goSpeedX *= -1;
 
                        }
                        // Отбивание от правой стенки
                        else if (uball.y > (stage.stageHeight - uball.height))
                        {
                                goSpeedY *= -1;
                                scorePlayer++;
                                setScore();
                                //isHit = !isHit;
 
 
                        }
                        // отбивание от верхней
                        else if (uball.x <= 0)
                        {
                                goSpeedX *= -1;
                                scoreComps++;
                                setScore();
                        }
                        // От левой
                        else if (uball.x <= 0)
                        {
                                goSpeedX *= -1;
 
 
 
 
                        }
                        // отбивание от панели игрока
                        else if (uPlayer.hitTestObject(uball))
                        {
                                goSpeedY *= -1;
                                checkHitLocation(uPlayer);
                        }
                        else if (uPad.hitTestObject(uball))
                        {
                                goSpeedY *= -1;
                                checkHitLocation(uPad);
                        }
 
 
                        uball.x += goSpeedX;
                        uball.y += goSpeedY;
 
                }
 
                private function moveEnemy(e:Event):void
                {
                        var enemyTargetX:Number;
                        var enemyuPadX:Number = Math.random() * 10 - 5;
 
                        enemyTargetX = uball.x - uPad.height/2 + enemyuPadX;
 
                        if(enemyTargetX <= 0)
                        {
                                enemyTargetX = 0;
                        }
                        else if(enemyTargetX >= stage.stageWidth - uPad.width)
                        {
                                enemyTargetX = stage.stageWidth - uPad.width;
                        }
 
                        uPad.x += (enemyTargetX - uPad.x) / easing;
                }
                /// <summary>Изменяет угол отскока мяча от панели</summary>
                private function checkHitLocation(paddle:MovieClip):void
                {
                        var hitPercent:Number; // Cоздержит степень изменения угла отскока
                        var ballPosition:Number = paddle.y - uball.y; // вычисляем разницу между положением панели и мячика
                        hitPercent = (ballPosition / (paddle.width - uball.width)) - .5;
                        goSpeedY = hitPercent * ball_ax;       
                        goSpeedY *= Math.round(Math.random() - 1);
                        goSpeedX *= 1.05;
                        ball_ax++;
                }
 
                private function destroy(e:Event):void
                {
                        removeEventListener(Event.REMOVED_FROM_STAGE, destroy);
                        stage.removeEventListener (Event.ENTER_FRAME, ballGo);// создание слушателя ентерфрейм
                        uPlayer.removeEventListener (Event.ENTER_FRAME, uplayerGo);// применяем листенер к юплееру для анимации
                        uPad.removeEventListener (Event.ENTER_FRAME, moveEnemy);
                }
        }
 
}

Функция отвечающая за отбивания мяча ballGo.
За рандомное отбивание от падов checkHitLocation.

Цитата:

я думаю последнюю строку нужно убрать
Код AS3:

goSpeedY *= Math.round(Math.random() - 1);

Пробовал, но мячик стал вообще странно себя вести.
прошу прощения за неправильно оформление первой темы, исправлюсь.

ping.swf   (17.1 Кб)

spirit2 06.11.2012 04:55

Лучше/проще взять какой-нить готовый движок, разобраться один раз...
box2d
box2d уроки
nape
nape уроки
...и выбросить из головы физику перемещений и столкновений :D

boldusev 06.11.2012 05:55

Проблема в том, что я учу ас3, и это надо для моего дальнейшего развития)

Sintesis 06.11.2012 17:45

Советую найти книгу Keith Peters - ActionScript 3.0 Animation - Making Things Move! (FED 2007) ничего, что она на английском только, там всё понятно и куча примеров и всё связано с физикой.

Koopa 06.11.2012 22:47

смущает море else if

Universe 07.11.2012 02:08

Цитата:

смущает море else if
лол)) С каких это пор 6 ифов это уже море)))

Цитата:

Лучше/проще взять какой-нить готовый движок, разобраться один раз...
box2d
box2d уроки
nape
nape уроки
...и выбросить из головы физику перемещений и столкновений
Если к вам первоклассник подойдёт с вопросом как посчитать 2+2 вы наверное его в институт направите учится, чтобы уже наверняка таких вопросов не возникало)
Мяч двигается по событию EnterFrame, которое само по себе дискретно. В какой то момент времени мяч оказывается в том же положении что и панель, "залипает" в ней и просто не может выйти на ружу т.к. условие продолжает срабатывать. Для того чтобы мяч не застревал в панелях есть 2 способа: либо просчитывать вектор до панели, либо при столкновении с панелью явно "вытаскивать" его на нужное место, перед панелью. Второе проще и в контексте уровня сложности данной задачи вполне приемлемо.


Часовой пояс GMT +4, время: 13:45.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.