Форум 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=180089)

HardCoder 27.05.2012 13:37

Как узнать объекты на условной линии
 
Вложений: 1
Здравствуйте! Банальный пример: мужик стреляет в монстров, попал - убил. Времени на полет пули нет (тоесть в одном кадре выстрел и сразу смерть монстра). Просто кликать по монстрам и убивать того, на ком кликнул не подходит, потому что могут возникнуть следующие ситуации как на картинке ниже.
Подскажите, пожалуйста, как найти первый попавшийся объект на траектории пули.

strangedk 27.05.2012 13:48

1. Даете импульс пули по вектору
2. Проверяете на hitTest с противниками
3. При столкновении уничтожаете пулю

Добавлено через 4 минуты
Цитата:

Сообщение от HardCoder (Сообщение 1081623)
Времени на полет пули нет

Цитата:

Сообщение от HardCoder (Сообщение 1081623)
первый попавшийся объект на траектории пули.

а это как, времени нет, но траектория есть?

HardCoder 27.05.2012 14:00

Цитата:

Сообщение от strangedk (Сообщение 1081626)
а это как, времени нет, но траектория есть?

Представьте себе что это не пуля, а каким-то лазером стреляют.
Код AS3:

первый попавшийся объект на траектории пули.

Значит первый объект, пересекающийся с лучом.

Добавлено через 3 минуты
strangedk, спасибо, но если скорострельность будет большая, то мне придется в каждом кадре проверять тысячи пуль на столкновения с массивом объектов. Так что это немного не то.
Интересует именно - возможно ли создать какой-то цикл, который в момент выстрела, который, я даже не знаю что бы он делал... поэтому и спросил здесь.

strangedk 27.05.2012 14:12

Если лазер, тогда это не траектория а вектор.

А вообще, смотреть в сторону пресечения луча, скорее всего.

HardCoder 27.05.2012 14:15

Цитата:

Сообщение от strangedk (Сообщение 1081631)
А вообще, смотреть в сторону пресечения луча, скорее всего.

Именно, но так как мои познания в геометрии заканчиваются на расчетах треугольников, прошу помощи у людей, которые знают немного об этом.

wvxvw 27.05.2012 14:15

А не достаточно будет считать пересечения траектории пули и линий (диаметров) мишеней проведенных перпендикулярно линии с которой стреляют? Ну или для большего реализма перпендикулярно прямой проведенной от стрелка до центра круга?

HardCoder 27.05.2012 14:33

Спасибо, я вижу, что без прохождения по каждому объекту здесь не обойтись в любом случае...

PainKiller 27.05.2012 14:47

Я делал лазер так. Писал класс Laser, в его конструктор экэемпляра передавал массив целей. Сам класс приаттачивал к спрайту - полоске в IDE. При выстреле в классе Laser хиттестом перебирались цели, если по одной срабатывало true, до нее высчитывалось расстояние, и width полоски становился равным расстоянию до цели. Ну а в главном герое, при выстреле просто создавался new Laser с координатами, так, чтобы наложить его на пушку,и по таймеру я его его убирал. (независимо от того, попал герой или нет). Так делать удобно, если двухмерная игра и враги появляются только с одной стороны (т.е. развороты не предусмотрены), иначе конечно все усложняется. При таком подходе никаких проблем приведенных в первом топике не возникало. Если надо могу выложить код, но я думаю и так логика понятна.

wvxvw 27.05.2012 16:38

Вложений: 1
Вот, собственно, накидал приме, но на Хексе, в качестве стимула к изучению :P
Код AS3:

package ;
 
import flash.display.Sprite;
import flash.Lib;
import flash.display.Graphics;
 
class Target extends Sprite
{
        private var _color:UInt;
 
        public var angle:Float;
 
        public var speed:Float;
 
        public var radius:Int;
 
        public function new(radius:Int)
        {
                super();
                this.radius = radius;
                _color = Std.int(Math.random() * 4294967295.0);
                speed = Math.random() + 1;
                draw();
        }
 
        public function draw()
        {
                var canvas:Graphics = graphics;
 
                canvas.clear();
                canvas.beginFill(_color);
                canvas.drawCircle(0, 0, radius);
                canvas.endFill();
 
                if (!Math.isNaN(angle))
                {
                        var cos:Float = Math.cos(angle);
                        var sin:Float = Math.sin(angle);
                        canvas.lineStyle(1, 0);
                        canvas.moveTo(-cos * radius, sin * radius);
                        canvas.lineTo(cos * radius, -sin * radius);
                }
        }
 
        public function setAngle(angle:Float)
        {
                this.angle = angle;
                draw();
        }
}
 
class Hunter extends Sprite
{
        public function new()
        {
                super();
                draw();
        }
 
        public function draw()
        {
                var canvas:Graphics = graphics;
                canvas.clear();
                canvas.beginFill(0xFF0000);
                canvas.drawRect(-10, -10, 20, 20);
                canvas.endFill();
        }
}
 
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.ui.Keyboard;
 
class ShootingGame extends Sprite
{
        private var _targets:Array<Target>;
 
        private var _hunter:Hunter;
 
        public function new()
        {
                super();
                addEventListener(Event.ADDED_TO_STAGE, init);
        }
 
        private function init(_)
        {
                super.removeEventListener(Event.ADDED_TO_STAGE, init);
                createTargets();
                startGame();
                createHunter();
        }
 
        private function createHunter()
        {
                _hunter = new Hunter();
                super.addChild(_hunter);
                stage.addEventListener(KeyboardEvent.KEY_DOWN, keyHandler);
                stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
        }
 
        private function keyHandler(event)
        {
                if (event.keyCode == Keyboard.UP && _hunter.y > 0)
                {
                        _hunter.y -= 5;
                }
                else if (event.keyCode == Keyboard.DOWN && _hunter.y < stage.stageHeight)
                {
                        _hunter.y += 5;
                }
        }
 
        private function mouseDownHandler(_)
        {
                var canvas:Graphics = Lib.current.graphics;
                canvas.clear();
                canvas.lineStyle(1, 0);
                canvas.moveTo(0, _hunter.y);
                canvas.lineTo(mouseX, mouseY);
                for (t in _targets)
                {
                        if (lineIntersects(t, mouseX, mouseY))
                        {
                                t.x = Math.random() * 1000 + stage.stageWidth;
                        }
                }
        }
 
        private inline function lineIntersects(target:Target,
        clickX:Float, clickY:Float):Bool
        {
                var clickAngle:Float = Math.atan2(clickX, clickY - _hunter.y);
                var cos:Float = Math.cos(target.angle);
                var sin:Float = Math.sin(target.angle);
                var radius:Float = target.radius;
                var low:Float = Math.atan2(target.x - cos * radius,
                target.y + sin * radius - _hunter.y);
                var high:Float = Math.atan2(target.x + cos * radius,
                target.y - sin * radius - _hunter.y);
                return clickAngle >= low && clickAngle <= high;
        }
 
        private function createTargets()
        {
                if (_targets == null)
                        _targets = new Array<Target>();
                for (i in 0...20)
                        _targets[i] = new Target(Std.random(25) + 25);
        }
 
        private function startGame()
        {
                super.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
                for (t in _targets)
                {
                        t.y = Math.random() * stage.stageHeight;
                        t.x = Math.random() * 1000.0 + stage.stageWidth;
                        super.addChild(t);
                }
        }
 
        private function enterFrameHandler(_)
        {
                for (t in _targets)
                {
                        t.x -= t.speed;
                        if (t.x <= 0)
                                t.x = stage.stageWidth + Math.random() * 1000;
                        t.setAngle(calculateAngle(t.x, t.y));
                }
        }
 
        private inline function calculateAngle(tx:Float, ty:Float):Float
        {
                return Math.atan2(tx, ty - _hunter.y);
        }
 
        private function stopGame()
        {
                for (t in _targets) super.removeChild(t);
                _targets = null;
                super.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }
 
        public static function main()
        {
                Lib.current.addChild(new ShootingGame());
        }
}

Код:

-main ShootingGame
-debug
-swf-version 10
-swf-header 800:600:31
-swf ./bin/shooting-game.swf


HardCoder 27.05.2012 20:11

wvxvw, спасибо, тоько вот как узнать какой из них был первым на пути?

Добавлено через 48 минут
Вычислять дистанцию от круга до героя. Сортировать массив кругов по этой дистанции. И выбирать первый/последний?


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

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