Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 17.11.2015, 20:35
PsychoTech вне форума Посмотреть профиль Отправить личное сообщение для PsychoTech Найти все сообщения от PsychoTech
  № 1  
Ответить с цитированием
PsychoTech
 
Аватар для PsychoTech

Регистрация: Aug 2014
Адрес: Где-то на поверхности планеты, какой хз
Сообщений: 113
По умолчанию Помогите с алгоритмом пожалуйста

Доброго времени суток, друзья.
Решил написать небольшую игрушку. Все в принципе нормально но хотелось бы немного красоты. Задача простая. Игрок стреляет, но к сожалению пока когда он стреляет очередью у меня все происходит моментально. Я почему-то не могу придумать алгоритм по которому можно было бы разделить выстрелы друг от друга. то есть если стрелять из автомата то все 30 выстрелов проходят менее чем за секунду. Помогите с алгоритмом как сделать действительно похожее на очередь. Уже второй день мозг ломаю, но чет до сих пор не родилось действительно стоящего алгоритма. Может кто поделиться опытом. Буду благодарен. Заранее спасибо.

Старый 17.11.2015, 21:15
ZackMercury вне форума Посмотреть профиль Отправить личное сообщение для ZackMercury Найти все сообщения от ZackMercury
  № 2  
Ответить с цитированием
ZackMercury
 
Аватар для ZackMercury

блогер
Регистрация: Jul 2013
Адрес: Север
Сообщений: 1,918
Записей в блоге: 23
Отправить сообщение для ZackMercury с помощью ICQ Отправить сообщение для ZackMercury с помощью Skype™
Первое, что нужно знать автомату - это сколько пуль в секунду он выстреливает.

Код AS3:
private var bulletsPerSecond:int = 5;
Затем, ему нужно знать, стреляет ли он в данный момент.

Код AS3:
public var shooting:Boolean = false;
И последнее - это сколько секунд прошло с последнего выстрела.

Код AS3:
private var cooldown:Number = 0;
Затем, всё делается в этом методе.

Код AS3:
public function update(dt:Number = 0):void
{
   if(shooting && cooldown >= 1/bulletsPerSecond)
   {
      ... // Стреляем.
      cooldown -= 1/bulletsPerSecond;
   }
   if(cooldown < 1/bulletsPerSecond) cooldown += dt;
}
__________________
There is no thing in this world that is not simple.

Старый 17.11.2015, 22:20
PsychoTech вне форума Посмотреть профиль Отправить личное сообщение для PsychoTech Найти все сообщения от PsychoTech
  № 3  
Ответить с цитированием
PsychoTech
 
Аватар для PsychoTech

Регистрация: Aug 2014
Адрес: Где-то на поверхности планеты, какой хз
Сообщений: 113
идея интересная. в принципе даже вполне осуществимая в моем варианте. Вот только немного затруднительная. Дело в том что у меня есть оружие, но оно не оружие как таковое а карточка с параметрами. У меня выстрел подразумевает получение урона игроком, то есть оружие по сути не стреляет. можно конечно поместить кулдаун на получение урона, но это вроде то же самое что и ваш вариант.
Одна из лучших моих идей подразумевала под собой процесс выстрела, но я не могу придумать как организовать повторную инициацию выстрела после его окончания. То есть хотелось бы организовать что-то вроде

Код:
function vistrel(col: number){
// процесс выстрела
vistrel(col-1);
}
Вот только я не уверен что такая конструкция допустима в плане работы и в плане чистоты кода. Или я ошибаюсь?

Старый 17.11.2015, 23:06
ZackMercury вне форума Посмотреть профиль Отправить личное сообщение для ZackMercury Найти все сообщения от ZackMercury
  № 4  
Ответить с цитированием
ZackMercury
 
Аватар для ZackMercury

блогер
Регистрация: Jul 2013
Адрес: Север
Сообщений: 1,918
Записей в блоге: 23
Отправить сообщение для ZackMercury с помощью ICQ Отправить сообщение для ZackMercury с помощью Skype™
Цитата:
Дело в том что у меня есть оружие, но оно не оружие как таковое а карточка с параметрами.
Мой код будет одинаковым для всех случаев, где игра происходит в реальном времени.
Ключ тут именно отталкивание от дельты.

Цитата:
Одна из лучших моих идей подразумевала под собой процесс выстрела, но я не могу придумать как организовать повторную инициацию выстрела после его окончания.
Плохой алгоритм мышления для программиста игр.
Если бы вы не игру писали, а баннер, то я бы посоветовал почитать про функцию setTimeout(...). Но в играх нужно отталкиваться от дельты, иначе всё станет запутанным, ужасно запутанным.

Цитата:
function vistrel(col: number){
// процесс выстрела
vistrel(col-1);
}
А это уже рекурсия. Так можно, но такая запись убьёт плеер(тут есть ошибочка в логике), но задачу это никак не решает, если только не поместить вызов функции в setTimeout(...).
__________________
There is no thing in this world that is not simple.


Последний раз редактировалось ZackMercury; 17.11.2015 в 23:19.
Старый 17.11.2015, 23:58
PsychoTech вне форума Посмотреть профиль Отправить личное сообщение для PsychoTech Найти все сообщения от PsychoTech
  № 5  
Ответить с цитированием
PsychoTech
 
Аватар для PsychoTech

Регистрация: Aug 2014
Адрес: Где-то на поверхности планеты, какой хз
Сообщений: 113
Цитата:
Одна из лучших моих идей подразумевала под собой процесс выстрела, но я не могу придумать как организовать повторную инициацию выстрела после его окончания.
Плохой алгоритм мышления для программиста игр.
здесь я полностью согласен, и я не стал даже пытаться реализовать нечто подобное.

Если не будет других более интересных и элегантных примеров то использую ваш.

Меня только заинтересовал вопрос, поскольку пока не сталкивался с этим и даже не думал об этом, как рекурсия убивает плеер? можешь обьяснить в кратце если можно.

Старый 18.11.2015, 00:04
ZackMercury вне форума Посмотреть профиль Отправить личное сообщение для ZackMercury Найти все сообщения от ZackMercury
  № 6  
Ответить с цитированием
ZackMercury
 
Аватар для ZackMercury

блогер
Регистрация: Jul 2013
Адрес: Север
Сообщений: 1,918
Записей в блоге: 23
Отправить сообщение для ZackMercury с помощью ICQ Отправить сообщение для ZackMercury с помощью Skype™
Ну, на самом деле, не убьёт, но рантайм ошибку выбьет после определённого количества рекурсий, от этого они защиту поставили.

Почему по идее должна убить?
Потому, что конструкция идентична
Код AS3:
while(true)
{
... // процесс выстрела
col --;
}
col уйдёт в минус бесконечность математически, так как ничто не останавливает рекурсию.
Рекурсия не убивает ничего, если нет ошибки в логике.

Исправленный вариант рекурсии(который так или иначе никак не решает задачу)
Код AS3:
function vistrel(col: number){
// процесс выстрела
if(col > 0) vistrel(col-1);
}
__________________
There is no thing in this world that is not simple.

Старый 18.11.2015, 01:01
PsychoTech вне форума Посмотреть профиль Отправить личное сообщение для PsychoTech Найти все сообщения от PsychoTech
  № 7  
Ответить с цитированием
PsychoTech
 
Аватар для PsychoTech

Регистрация: Aug 2014
Адрес: Где-то на поверхности планеты, какой хз
Сообщений: 113
с рекурсией понятно. я думал дело обстоит куда серьезнее и глубиннее чем просто бесконечный цыкл. Я вот одного понять не могу. Смотрю на ваш код и не могу понять одного
Код AS3:
1/bulletsPerSecond
что значит единица? 1 секунда?

Старый 18.11.2015, 10:17
caseyryan вне форума Посмотреть профиль Отправить личное сообщение для caseyryan Найти все сообщения от caseyryan
  № 8  
Ответить с цитированием
caseyryan
 
Аватар для caseyryan

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
Цитата:
Первое, что нужно знать автомату - это сколько пуль в секунду он выстреливает.
Зак, так, на заметку, темп стрельбы измеряется в выстрелах в минуту, а не в секунду.
Если будешь пытаться сымитировать реальное оружие, то сразу поймешь, что везде указывается именно минута. То есть для того, чтобы указать реальный тем стрельбы, тебе сначала из минуты придется перевести в секунду, и уже потом считать промежутки между выстрелами. По мне, так это ненужная заморочка.


По теме: вот уж не думал, что такая простая задача, может вызывать такие трудности
Код AS3:
package {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.utils.getTimer;
 
	public class AutomaticWeapon extends Sprite {
 
		private var _isShooting:	Boolean = false;
		// количество выстрелов в минуту, именно так измеряется темп стрельбы в реальном оружии, а не в секундах
		private var _tempo:			int		= 0; 
		// время между выстрелами
		private var _delta:			int		= 0;
		// время совершения последнего выстрела
		private var _lastShot:		int 	= 0;
 
 
		private var _counter:int = 0;
 
		public function AutomaticWeapon() {
			// например у автомата калашникова, темп стрельбы 600 / мин
			tempo = 600;
			stage ? init() : addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
		private function init(e:Event = null):void {
			removeEventListener(Event.ADDED_TO_STAGE, init);
			stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseAction);
			stage.addEventListener(MouseEvent.MOUSE_UP, onMouseAction);
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
 
		private function onEnterFrame(e:Event):void {
			if (isShooting) {
				var curTime:int = getTimer();
				if (curTime >= _lastShot + _delta) {
					shoot();
					_lastShot = curTime;
				}
			}
		}
 
		private function shoot():void {
			trace("выстрел", ++_counter);
		}
 
		private function onMouseAction(e:MouseEvent):void {
			isShooting = (e.type == MouseEvent.MOUSE_DOWN);
		}
 
		public function get tempo():Number {
			return _tempo;
		}
 
		public function set tempo(value:Number):void {
			_tempo 	= value;
			_delta	= (60000 / _tempo);
		}
 
		public function get isShooting():Boolean {
			return _isShooting;
		}
 
		public function set isShooting(value:Boolean):void {
			_isShooting = value;
			if (value) _counter = 0;
		}
 
	}
 
}


Последний раз редактировалось caseyryan; 18.11.2015 в 12:38.
Старый 18.11.2015, 18:50
ZackMercury вне форума Посмотреть профиль Отправить личное сообщение для ZackMercury Найти все сообщения от ZackMercury
  № 9  
Ответить с цитированием
ZackMercury
 
Аватар для ZackMercury

блогер
Регистрация: Jul 2013
Адрес: Север
Сообщений: 1,918
Записей в блоге: 23
Отправить сообщение для ZackMercury с помощью ICQ Отправить сообщение для ZackMercury с помощью Skype™
Цитата:
что значит единица? 1 секунда?
Да, у меня дельта всегда измеряется в секундах, мне так удобно.
__________________
There is no thing in this world that is not simple.

Старый 18.11.2015, 21:06
PsychoTech вне форума Посмотреть профиль Отправить личное сообщение для PsychoTech Найти все сообщения от PsychoTech
  № 10  
Ответить с цитированием
PsychoTech
 
Аватар для PsychoTech

Регистрация: Aug 2014
Адрес: Где-то на поверхности планеты, какой хз
Сообщений: 113
ладно. мне все понятно. правда у caseyryan пример более подробно описан и более понятен. Всем спасибо пойду дальше кодить.

Создать новую тему Ответ Часовой пояс GMT +4, время: 23:08.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


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


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