Форум «Всё о Паскале» _ Написание игр _ НЛО на звездном небе
Автор: Анастасия 4.03.2006 2:20
У меня вопрос по Visualpage. Cейчас рисую НЛО на фоне мерцающего неба. Проблема в том, что когда с помощью putimage вставляю рандомайзом свой НЛО, затирается мое небо. Не уверена, поэтому хочу спросить,как мне сделать небо основным фоном(чтобы не затиралось). Наверное это связано с Visualpage.
Автор: volvo 4.03.2006 2:25
Ни при чем здесь VisualPage ... Если ты сделаешь "небо" и "НЛО" на разных страницах - то будешь видеть ИЛИ одно, ИЛИ другое... Я бы на твоем месте (чтобы PutImage не затирал изображение под собой), выводил его так:
PutImage(x_pos, y_pos, buffer, XorPut);
(а не NormalPut, что ты скорее всего делаешь).
P.S. Еще одно преимущество XorPut - в том, что для того, чтобы затереть объект (и оставить фон ТОЧНО таким же, каким он был до отображения объекта) достаточно просто еще раз отрисовать объект:
PutImage(x_pos, y_pos, buffer, XorPut); { Это мы объект рисуем } { Здесь - пауза } PutImage(x_pos, y_pos, buffer, XorPut); { А здесь объект "стираем" }
Преимущество очевидно - не надо заморачиваться с буферами для хранения фона ПОД изображением, чтобы потом его восстанавливать...
Автор: Анастасия 4.03.2006 20:29
Код
program ddd; uses crt,graph; var d,m,x,y:integer; p:pointer;sz,x1,y1:word;i:integer; begin d:=detect; initgraph( d,m,'d:\bp70\bgi' ); setviewport(0,0,640,80,true); clearviewport; setbkcolor(0); setcolor(15); setfillstyle(1,1); fillellipse(310,250,70,30); fillellipse(310,240,70,30); setfillstyle(1,14); fillellipse(270,270,20,20); fillellipse(350,270,20,20); fillellipse(370,250,20,20); fillellipse(250,250,20,20); arc(310,230,0,180,70); line(240,230,380,230); setfillstyle(1,5); floodfill(280,210,15); setfillstyle(1,12); floodfill(280,227,15);
repeat delay(5000); For i:=1 to 70 do begin PutPixel(Random(700),Random (500),White);end; putimage( random(640) ,random(400) ,p^,xorput); delay(60000); cleardevice; until keypressed;
readln; closegraph; end.
Вот такая получилась программка, только не понятно, почему звезды просвечиваются через НЛО. Может и так сойдет... Вобщем не знаю.
Автор: volvo 4.03.2006 20:56
Анастасия, я же написал, в чем преимущество XorPut, а ты свела его на НЕТ... Да и мотается у тебя НЛО непонятно как по экрану, это так задумано? Может, лучше сделать, чтобы НЛО появлялось и двигалось в случайном направлении, а не появлялось в случайном месте?
Да, кстати, можно попробовать сделать так, чтобы звезды не меняли свое положение каздый раз, а именно мерцали, оставаясь на своих местах.
Автор: Анастасия 5.03.2006 3:02
1-Попытка сделать звезды мерцающими
Код
j:=1;{[size=1][b]Неправильно[/b][/size]}{Ошибка heap overflow} while j<=600 do begin Randomize; For i:=1 to 70 do begin PutPixel(Random(700),Random (400),White);end; rectangle(0,0,640,480); sz:=imagesize(0,0,640,480); getmem(p,sz); getimage(0,0,640,480,p^); putimage(0,0,p^,xorput); putimage(0,0,p^,xorput); j:=j+1; end;
Скорее всего для сдачи мне подойдет и то, что я уже нарисовала. Но мне самой уже интересно как можно сделать по-другому. 2-движение НЛО- Наверное нужно задавать сложные формулы движения типа Лиссажу и т.п. Я такое сама не придумаю , да и хочется чтобы попроще было. Вот . 2-й вариант этой же моей задачи только без putimage:
Код
program ddd; uses crt,graph; var d,m,x,y:integer; p:pointer;sz,x1,y1:word;i,j:integer; begin d:=detect; initgraph( d,m,'d:\bp70\bgi' ); setviewport(0,0,640,80,true); clearviewport; setbkcolor(0); Randomize; For i:=1 to 70 do begin PutPixel(Random(700),Random (480),White);end;
x:=0;y:=0; while x<=640 do begin while y<=480 do begin setcolor(15); setfillstyle(1,1); fillellipse(45+x,25+y,70,30); fillellipse(45+x,15+y,70,30); setfillstyle(1,14); fillellipse(40+x,40+y,20,20); fillellipse(85+x,40+y,20,20); fillellipse(95+x,25+y,20,20); fillellipse(25+x,25+y,20,20);
For i:=1 to 70 do begin PutPixel(Random(700),Random (400),White);end; delay(6000); x:=random(600); y:=random(300);end;end; readln; closegraph; end.
Звезд стало больше и они меньше просвечиваются через обьект. Но может тогда на этой задаче можете подсказать, как задать движение рандомайзом, а то тут у меня тоже прыганье получается.
Автор: volvo 5.03.2006 3:20
Насчет случайного движения - никаких Лиссажу, зачем это?
Вот самая простая реализация: __NLO.PAS ( 1.21 килобайт )
Кол-во скачиваний: 769
(немного подмаргивает, но это скорее всего из-за размеров НЛО, просто PutImage достаточно медленная операция, и отрисовка больших фрагментов занимает время)... Но сам принцип понятен?
Автор: Анастасия 5.03.2006 15:19
Я точно такое же делала(просто не писала в прорамме, думала, можете круче подсказать). Ладно, оставим, а то мне кажется вы уже устали на мои вопросы отвечать. Тем более я просто ленюсь сама подумать.
Автор: Бродяжник 6.03.2006 13:17
Анастасия, тема еще интересна?
Автор: Анастасия 7.03.2006 2:49
Бродяжник,интересна!
Автор: Бродяжник 7.03.2006 14:02
Тогда вот. Режим XOR хорошая вещь, но у него есть та особенность, что при наложении картинки на сложный фон этот фон будет просвечивать. Вот еще возможный вариант. Для изображения НЛО используем PutImage в режиме NormalPut. Это достаточно быстро. Для того, чтобы его убирать, можно использовать еще один спрайт - черный прямоугольник (если небо у нас черное). Тогда возникает проблема - при движении НЛО будет затирать звезды. Значит, их надо восстанавливать. А заодно надо решить и задачу мигания звезд. Что бы я сделал: создал бы массив Nx2 (Stars: array[1..2][1..N] of word), где N - число звезд (штук 100). Перед началом основного цикла заполняем этот массив случайными координатами звезд:
For i:=1 to N do begin Stars[ i ][1] := random(640); Stars[ i ][2] := random(480); end;
Теперь основной цикл программы выглядит так: - вычисляем новые координаты НЛО - затираем НЛО - пробегаемся по массиву и в точках с координатами звезд выводим случайный цвет:
For i:=1 to N do PutPixel(Stars[i][1],Stars[i][2],random(16));
- рисуем НЛО - выдерживаем паузу Теперь осталась еще та проблема, что при выводе НЛО звезды затираются по всей площади прямоугольника, а ведь НЛО у нас не прямоугольный. Ну... может, этим стоит пренебречь? Как только НЛО улетит с этого места, звезды восстановятся. По поводу движения: если хватит сил замутить фигуры Лиссажу, это будет здорово, но стоит ли? Проще сделать так: пусть Х и У - текущие координаты НЛО. Определяем новые случайные координаты, Х1 и У1. А затем вычисляем шаг перемещения
If X < X1 then DX := 1 else if X = X1 then DX := 0 else DX := -1;
Аналогично для Y, Y1 и DY. Потом в цикле движения проверяем, достигли ли мы уже точки назначения? Если нет, тогда вычисляем новые координаты там, где это необходимо:
If X <> X1 then X := X + DX; If Y <> Y1 then Y := Y + DY;
А если достигли, тогда выбираем новые случайные Х1 и Y1. При такой схеме НЛО будет не спеша летать по некоторой ломаной линии. Не спеша, потому что шаг единичный. Если шаг увеличить, то потребуются дополнительные усилия с определением того, достигли ли мы точки назначения. А еще можно просто выбрать случайное направление и лететь, пока не упремся в стенку. Когда упремся, выбрать новое направление, и т.д.