Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   forum.boolean.name > Программирование игр для мобильных телефонов > MidletPascal > Проекты на MidletPascal

Ответ
 
Опции темы
Старый 20.03.2010, 20:31   #1
nil0q
ПроЭктировщик
 
Аватар для nil0q
 
Регистрация: 30.06.2009
Адрес: Челябинская обл.
Сообщений: 111
Написано 32 полезных сообщений
(для 99 пользователей)
Sola Rola: напишем свою версию

В этой игрушке (Sola Rola) довольно необычный физический движок, но всего 25 уровней. Хотел написать свою версию, добавить что-нибудь новое (в т.ч. редактор уровней). Вот пробная версия моего движка
program SRR;

// время везде в секундах, единицы длины - пиксели,
// формат real имеет точность 3-4 знака после запятой, предел значения около 500000

type ground=record
	x,y,r:real;
	t:integer; // 1 - простой, 2 - камень, 3 - радиация
end;

type ball=record
	x,y,vx,vy,ax,ay:real;
	r: real;
	l1,l2: real; // исходная длина связи
	b1,b2: integer; // номер связанного или 0
	t: integer; // 1 - простой, 2 - камень, 3 - радиация
end;

const g=100; // ускорение силы тяжести
const k=5000; // жёсткость

var gr: array [1..1023] of ground;
var ngr: integer;
var b: array [1..255] of ball;
var nb: integer;

var i,j:integer;

var x,y,ax,ay: real; // для расчёта столкновений
var dx,dy,r,rr,a,da:real;


var t0:integer; // учёт времени
var t:integer;
var dt:real;


var w,h:integer; // размеры экрана
var cx,cy:integer; // камера


begin

	// initium
	w:=getwidth;
	h:=getheight;
	
	ngr:=10;
	for i:=1 to ngr do begin
		gr[i].x:=random(150);
		gr[i].y:=random(333)+100.0;
		gr[i].r:=random(30)+5.0;
		gr[i].t:=1;
	end;
	nb:=10;
	for i:=1 to nb do begin
		b[i].x:=random(150);
		b[i].y:=random(111);
		b[i].vx:=0;
		b[i].vy:=0;
		b[i].ax:=0;
		b[i].ay:=0;
		b[i].r:=random(20)+5.0;
		b[i].b1:=0;
		b[i].b2:=0;
		b[i].t:=1;
	end;
	t:=getrelativetimems;
	
  repeat
  
		for i:=1 to nb do begin
			x:=b[i].x;
			y:=b[i].y;
			r:=b[i].r;
			ax:=0.0;
			ay:=g;
			for j:=1 to ngr do begin
				dx:=x-gr[j].x;
				dy:=y-gr[j].y;
				if (dx<400.0) and (dx>-400.0) and (dy<400.0) and (dy>-400.0) then begin // ограничение, чтобы при возведении в квадрат не было переполнения
					rr:=sqrt(dx*dx+dy*dy);
					a:=r+gr[j].r-rr;
					if (a>0.0) and (rr>0) then begin
						ax:=ax+a*k*dx/rr/r;
						ay:=ay+a*k*dy/rr/r;
					end;
				end;
			end;
			for j:=1 to nb do begin
				if i<>j then begin
					dx:=x-b[j].x;
					dy:=y-b[j].y;
					if (dx<400.0) and (dx>-400.0) and (dy<400.0) and (dy>-400.0) then begin
						rr:=sqrt(dx*dx+dy*dy);
						a:=r+b[j].r-rr;
						if (a>0.0) and (rr>0) then begin
							ax:=ax+a*k*dx/rr/r;
							ay:=ay+a*k*dy/rr/r;
						end;
					end;
				end;
			end;
			b[i].ax:=ax;
			b[i].ay:=ay;
		end;
		
		
		setcolor(110,200,255);
		fillrect(0,0,w,h);
		
		//cx:=w/2-trunc(b[1].x);
		//cy:=h/2-trunc(b[1].y);
		
		setcolor(0,0,0);
		for i:=1 to ngr do begin
			r:=gr[i].r;
			fillellipse(trunc(gr[i].x-r)+cx,trunc(gr[i].y-r)+cy,trunc(r*2),trunc(r*2));
		end;
		setcolor(10,110,20);
		for i:=1 to ngr do begin
			r:=gr[i].r;
			fillellipse(trunc(gr[i].x-r)+cx+3,trunc(gr[i].y-r)+cy+3,trunc(r*2)-6,trunc(r*2)-6);
		end;
		
		
		t0:=t;
		t:=getrelativetimems;
		dt:=(t-t0)/1000.0;
		
		for i:=1 to nb do begin
			r:=b[i].r;
			b[i].vx:=b[i].vx+b[i].ax*dt;
			b[i].vy:=b[i].vy+b[i].ay*dt;
			b[i].x:=b[i].x+b[i].vx*dt;
			b[i].y:=b[i].y+b[i].vy*dt;
			setcolor(0,0,0);
			fillellipse(trunc(b[i].x-r)+cx,trunc(b[i].y-r)+cy,trunc(r*2),trunc(r*2));
			setcolor(150,150,140);
			fillellipse(trunc(b[i].x-r)+cx+3,trunc(b[i].y-r)+cy+3,trunc(r*2)-6,trunc(r*2)-6);
		end;
		
		setcolor(0,0,0);
		drawtext(integertostring(t-t0)+' ms',0,0);
		
		repaint;
		
  until false;
end.
Здесь массив gr - "земляные" (неподвижные) шары, ngr - их количество, массив b - подвижные шары; l1, l2, b1, b2 - предполагается использовать для связывания одного шарика с другим.
Алгоритм - мягкое столкновение: если два шарика столкнулись, они отталкиваются, сила пропорциональна глубине столкноветия.

Запустил я его на КЭмуляторе (кол-во подвижных шариков=10), работает, время цикла 40-70 мс. Запустил на телефоне, время цикла 90-120 мс, тормозит заметно.

Как оптимизировать алгоритм, чтобы скорость была как в самой игрушке?
(Реально больше всего времени занимает расчёт столкновения каждого шарика с каждым, строки 90-103; репаинт занимает 4-7 мс, остальное 1-2 мс)
Думаю, надо от квадратного корня избавляться, но без него нельзя рассчитать силы.


Для тех, кто не играл в оригинальную игру, см. во вложении.
Вложения
Тип файла: zip Game.zip (874.2 Кб, 487 просмотров)
__________________
Аинéжарбази овокáсьф имятнэ́меле как, имякщтóт и имяини́ль оклёт ими́ньдо сяюзлёп, ильсы́м эынэвьтспóс ышáн мóнян тягалзи, эы́жущт тят-ищт сант-ищтý анакаккáт; áкызэй овóваримь авотэ́ як итя́ммарг тыжýлс аирьтэмяег аянлетя́трэщтанот, мадóраи мынавóзарбо мэ́сьф мынтáняп авокáныдя, икиньхэ́ть мóкызэй астэя́львэй шóтрэщт ильсэ́й.
Щамóпф раткáдэрь оидюá!
(Offline)
 
Ответить с цитированием
Старый 21.03.2010, 01:04   #2
cherepets
Бывалый
 
Регистрация: 18.08.2009
Сообщений: 745
Написано 146 полезных сообщений
(для 215 пользователей)
Ответ: Sola Rola: напишем свою версию

ну, по оптимизации алгоритма могу сказать что ты не в школе на физике, так что корень можешь заменить чем-нить дающим приблизительный результат. например деление какое-нить.
вобще будем надеяться ща те добрые люди лог сдвигом помогут
(Offline)
 
Ответить с цитированием
Ответ


Опции темы

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

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


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


vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com