![]() |
|
||||||||||
|
|||||||
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | Опции просмотра |
|
![]() |
![]() |
|
|||||
|
Здравствуйте! Банальный пример: мужик стреляет в монстров, попал - убил. Времени на полет пули нет (тоесть в одном кадре выстрел и сразу смерть монстра). Просто кликать по монстрам и убивать того, на ком кликнул не подходит, потому что могут возникнуть следующие ситуации как на картинке ниже.
Подскажите, пожалуйста, как найти первый попавшийся объект на траектории пули.
__________________
Я мало чего умею, но зато хорошо умею учиться... |
|
|||||
|
1. Даете импульс пули по вектору
2. Проверяете на hitTest с противниками 3. При столкновении уничтожаете пулю Добавлено через 4 минуты а это как, времени нет, но траектория есть?
__________________
adobe AS3 manual |
|
|||||
|
Представьте себе что это не пуля, а каким-то лазером стреляют.
Значит первый объект, пересекающийся с лучом.
Добавлено через 3 минуты strangedk, спасибо, но если скорострельность будет большая, то мне придется в каждом кадре проверять тысячи пуль на столкновения с массивом объектов. Так что это немного не то. Интересует именно - возможно ли создать какой-то цикл, который в момент выстрела, который, я даже не знаю что бы он делал... поэтому и спросил здесь.
__________________
Я мало чего умею, но зато хорошо умею учиться... |
|
|||||
|
Если лазер, тогда это не траектория а вектор.
А вообще, смотреть в сторону пресечения луча, скорее всего.
__________________
adobe AS3 manual |
|
|||||
|
Именно, но так как мои познания в геометрии заканчиваются на расчетах треугольников, прошу помощи у людей, которые знают немного об этом.
__________________
Я мало чего умею, но зато хорошо умею учиться... |
|
|||||
|
Modus ponens
|
А не достаточно будет считать пересечения траектории пули и линий (диаметров) мишеней проведенных перпендикулярно линии с которой стреляют? Ну или для большего реализма перпендикулярно прямой проведенной от стрелка до центра круга?
__________________
Hell is the possibility of sanity |
|
|||||
|
Я делал лазер так. Писал класс Laser, в его конструктор экэемпляра передавал массив целей. Сам класс приаттачивал к спрайту - полоске в IDE. При выстреле в классе Laser хиттестом перебирались цели, если по одной срабатывало true, до нее высчитывалось расстояние, и width полоски становился равным расстоянию до цели. Ну а в главном герое, при выстреле просто создавался new Laser с координатами, так, чтобы наложить его на пушку,и по таймеру я его его убирал. (независимо от того, попал герой или нет). Так делать удобно, если двухмерная игра и враги появляются только с одной стороны (т.е. развороты не предусмотрены), иначе конечно все усложняется. При таком подходе никаких проблем приведенных в первом топике не возникало. Если надо могу выложить код, но я думаю и так логика понятна.
|
|
|||||
|
Modus ponens
|
Вот, собственно, накидал приме, но на Хексе, в качестве стимула к изучению :P
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()); } }
__________________
Hell is the possibility of sanity Последний раз редактировалось wvxvw; 27.05.2012 в 16:42. |
|
|||||
|
wvxvw, спасибо, тоько вот как узнать какой из них был первым на пути?
Добавлено через 48 минут Вычислять дистанцию от круга до героя. Сортировать массив кругов по этой дистанции. И выбирать первый/последний?
__________________
Я мало чего умею, но зато хорошо умею учиться... |
![]() |
![]() |
Часовой пояс GMT +4, время: 23:37. |
|
|
« Предыдущая тема | Следующая тема » |
|
|