хочу написать простую игру (дано допустим 2 танка 1 управляется пользователем а 2 компьютером ) в ходе написания возник ряд вопросов 1) как сделать чтобы одновременно выполнялось несколько действий допустим я стреляю и пока летит снаряд я хочу переместить свой танк а враг может попытаться увернутся от снаряда.на данном этапе написания когда я стреляю я не могу переместить танк пока не далетит снаряд.2)как установить границы экрана чтобы танк не заезжал за границы и вообще как разграничить экран я пробовал спомощью setviewport но чето ничего не получилось.
вот то что я уже написал набрОсал танки 1им из них можно управлять стрелками и стрелять на пробел выход на esc.танки я нарисовал линиями чтоб легче было работать с координатами
program igra;объяснити хоть на словах как сделать то о чем я написал.спасибо!
uses graph,crt;
var
ch:char;
tx,ty,tx2,ty2:integer;
d,m,i,x,y,k:integer;
procedure vistrel;
var
vx,vy,i,k:integer;
begin
vx:=tx;
vy:=ty;
for i:=1 to 640-(vx+60) do begin
setcolor(15);
circle(vx+64+i,vy+23,3);
setcolor(0);
circle(vx+64+i-1,vy+23,3);
delay(200);
if (vy+23>=ty2) and (vy+23<=ty+48) then
circle(213,120,2);
end;
setcolor(15);
end;
begin
d:=detect;
initgraph(d,m,'e:\tp7.1\bgi');
tx:=1;
ty:=120;
tx2:=610;
ty2:=120;
{kab}
repeat
{\\\\\\\\\\\\\\\\\tank22\\\\\\\\\\\\\\\\\\\\\ }
{kab}
line(tx2,ty2,tx2+23,ty2);
line(tx2+23,ty2,tx2+23,ty2+48);
line(tx2,ty2+48,tx2+23,ty2+48);
line(tx2,ty2,tx2,ty2+48);
arc(tx2+11,ty2+6,23,154,13);
arc(tx2+11,ty2+42,206,337,13);
{pil}
line(tx2+10,ty2+9,tx2+10,ty2+39);
line(tx2+17,ty2+9,tx2+10,ty2+9);
line(tx2+10,ty2+39,tx2+17,ty2+39);
{puh}
line(tx2,ty2+12,tx2-12,ty2+12);
line(tx2,ty2+36,tx2-12,ty2+36);
line(tx2-12,ty2+12,tx2-12,ty2+36);
{dulo}
line(tx2-12,ty2+26,tx2-29,ty2+26);
line(tx2-29,ty2+20,tx2-29,ty2+28);
line(tx2-12,ty2+22,tx2-29,ty2+22);
{gluh}
line(tx2-29,ty2+20,tx2-36,ty2+20);
line(tx2-29,ty2+28,tx2-36,ty2+28);
line(tx2-36,ty2+20,tx2-36,ty2+28);
{\\\\\\\\\\\=tank\\\\\\\\\\\\\\\\}
line(tx,ty,tx+23,ty);
line(tx+23,ty,tx+23,ty+48);
line(tx,ty+48,tx+23,ty+48);
line(tx,ty,tx,ty+48);
arc(tx+11,ty+6,23,154,13);
arc(tx+11,ty+42,206,337,13);
{pil}
line(tx+17,ty+9,tx+17,ty+39);
line(tx+10,ty+9,tx+17,ty+9);
line(tx+10,ty+39,tx+17,ty+39);
{puh}
line(tx+23,ty+12,tx+35,ty+12);
line(tx+23,ty+36,tx+35,ty+36);
line(tx+35,ty+12,tx+35,ty+36);
line(tx+35,ty+22,tx+53,ty+22);
{dulo}
line(tx+35,ty+26,tx+53,ty+26);
line(tx+53,ty+20,tx+53,ty+28);
{gluh}
line(tx+53,ty+20,tx+60,ty+20);
line(tx+53,ty+28,tx+60,ty+28);
line(tx+60,ty+20,tx+60,ty+28);
ch:=readkey;
case ch of
#72:ty:=ty-5;
#75:tx:=tx-5;
#77:tx:=tx+5;
#80:ty:=ty+5;
#32:vistrel;
#27:halt;
end;{case}
cleardevice;
until ch=#27;
readln;
closegraph;
end.
Игры так не пишут.
В игре должен быть ОДИН цикл. В нем ты, например, если нажат пробел, устанавливаеш флаг, например fVystrel. А потом, в том же цикле смотриш, если флаг возведен, то пересчитываеш координаты выстрела. Когда попадет в цель или выйдет за пределы экрана, сбрасываеш флаг.
Ты бы хоть, прежде чем писать, почитал темы, находящиеся рядом. На многие твои вопросы там уже есть ответы.
Любая игра строится по единому шаблону: все действия выполняются в основном игровом цикле. Сам цикл может организовываться по-разному, скажем, в DOS и Windows, но сути это не меняет.
В цикле определяется состояние органов управления (нажата клавиша, передвинута мышь, отклонен джойстик...), текущее время и на основании этого состояние системы изменяется по определенным формулам. Например, если скорость объекта (Vx,Vy) а координаты (X,Y), то через время dt, прошедшее с предыдущей отрисовки кадра, новые координаты станут (X+Vx*dt, Y+Vy*dt). При необходимости создаются новые объекты (пуля при выстреле, новый враг ...) и уничтожаются старые (сначала пуля при попадании, а затем и враг, в которого она попала).
Анализируется состояние каждого объекта (для обеспечения возможности перебора ведется список объектов). Когда посчитано новое состояние, оно отображается на экране.
Затем цикл повторяется.
Пример можно посмотреть несколькими темами ниже: "про кораблики".
И опять мне нужна помощь. теперь проблема с ИИ ну то что я сделал нельзя конечно назвать ИИ ну в общем у меня 2 объекта 1 можно управлять а 2 перемещается вдоль оси У я написал для этого вот такую процедуру
procedure move2;идея тут втом что есть 3 состояния движение вверх вниз и наместе состояние задается случайным образом как d:=random(3); а t:=random(30); задает сколько это перемещение будет длится. в теории вроде все хорошо токо на практике как всегда круг дальше нижней половины экрана не выходит и движется рывками .
var
d:integer;
begin
if t=0 then begin
d:=random(3);
t:=random(30);
end;
if (d=1) and (t<>0) then begin
dec(t);
ty2:=ty2-5;
circle(tx2,ty2,10);
setcolor(black);
circle(tx2,ty2+5,10);
end;
if (d=2) and (t<>0) then begin
dec(t);
ty2:=ty2+5;
circle(tx2,ty2,10);
setcolor(black);
circle(tx2,ty2-5,10);
end;
if (b=0) and (t<>0) then
begin
dec(t);
circle(tx2,ty2,10);
end;
if ty2=0 then ty2:=300;
setcolor(15);
end;
program igra;
uses graph,crt;
var
ch:char;
b,tx2,ty2:integer;
d,m,t,x,y,k,q:integer;
procedure move1;
begin
if q=1 then begin
y:=y-5;
circle(x,y,10);
setcolor(black);
circle(x,y+5,10);
setcolor(15);
q:=0;
end;
if q=2 then begin
x:=x-5;
circle(x,y,10);
setcolor(black);
circle(x+5,y,10);
setcolor(15);
q:=0;
end;
if q=3 then begin
x:=x+5;
circle(x,y,10);
setcolor(black);
circle(x-5,y,10);
setcolor(15);
q:=0;
end;
if q=4 then begin
y:=y+5;
circle(x,y,10);
setcolor(black);
circle(x,y-5,10);
setcolor(15);
q:=0;
end;
end;
procedure move2;
var
i,d:integer;
begin
if t=0 then begin
d:=random(3);
t:=random(30);
end;
if (d=1) and (t<>0) then begin
dec(t);
ty2:=ty2-5;
circle(tx2,ty2,10);
setcolor(black);
circle(tx2,ty2+5,10);
end;
if (d=2) and (t<>0) then begin
dec(t);
ty2:=ty2+5;
circle(tx2,ty2,10);
setcolor(black);
circle(tx2,ty2-5,10);
end;
if (b=0) and (t<>0) then
begin
dec(t);
circle(tx2,ty2,10);
end;
if ty2=0 then ty2:=300;
setcolor(15);
end;
begin
d:=detect;
initgraph(d,m,'e:\tp7.1\bgi');
x:=30;
y:=120;
tx2:=300;
ty2:=320;
{kab}
t:=0;
circle(x,y,10);
repeat
if keypressed then
begin
ch:=readkey;
case ch of
#72:q:=1;
#75:q:=2;
#77:q:=3;
#80:Q:=4;
#27:halt;
end;{case}
end;
move1;
move2;
delay(5000);
until ch=#27;
readln;
closegraph;
end.
Вот твои ошибки:
1. Используй Randomize один раз в начале программы, или числа не будут случайными
2. Переменная D в процедуре MOVE1 - ЛОКАЛЬНАЯ! то есть при каждом вызове она создается заново и ее значение не определено. Сделай ее глобольной
Добавлено через 19 мин.
И вот еще что надо бы переделать. Анимация делается по-другому.
Алгоритм:
1. Пересчитать координаты
2. Нарисовать объект
3. Подождать
4. Стереть
У тебя должны быть такие процедуры:
1. Нарисовать объект в определенных координатах
Draw (X, Y).
Если хочешь, чтобы противники были разного цвета, или еще как различать, можешь передавать еще и цвет.
2. Стереть объект в определенных координатах
Cleare (X, Y)
3. Пересчитать координаты противника
MovePr
Тут, в зависимости от переменных T и D пересчитываешь координаты, но НЕ рисуешь.
И общий алгоритм:
1. Нарисовать оба танка
2. Цикл
2.1. Пересчитываешь координаты
2.1.1. Читаешь клавиатуру
2.1.2. Вызываешь MovePr
2.2. Рисуешь оба танка
2.3. Ждешь
2.4. Стираешь оба танка в текущих координатах
Такой алгоритм применяется почти во всех подобных программах
Да пожалуйста, если что, обращайся еще.
Кстати, если делать вообще по науке, то нужно вот как:
Для каждого объекта кроме координат X и Y должна быть пара DX и DY, которой задается вектор перемещения объекта. Тогда при анализе клавы или генерации очередного хода противника изменяешь DX или DY (Если ход вверх, то DX = 0, DY = -5; Если вправо, то DX = 5, DY = 0 и т.д.). А потом пересчитываешь координаты X := X + DX; Y := Y + DY.
Это позволит сделать анализ границ. То есть, пересчитывать координаты нужно только в том случаи, если следующий ход попадает в границы экрана (псевдокод):
Именно с массивом.
Прикинь, какая у твоего танка максимальная скорострельность, с какой скоростью летит пуля и соотнеси это с диагональю экрана (как наибольшим возможным расстоянием). Отсюда получишь максимально возможное количество пуль на экране (наверное еще надо умножить на максимальное количество стреляющих танков).
Определи структуру из двух координат, двух составляющих скорости и признака, что пулю нужно рисовать.
Создай массив структур величиной с максимальное количество пуль. При выстреле ищешь в массиве не рисуемую пулю, присваиваешь ей нужные координаты (срез ствола), нужные скорости (вдоль направления ствола) и признак "рисовать". При попадании пули в цель или достижении края экрана устанавливаешь признак в "не рисовать".
Я решил переделать игру.Теперь обьекты у меня это отдельные изображения которые сохраняются в памяти.И возник вопрос как при таком методе сделать анимацию?Я вот написал небольшую програмку где анимация делается так как в предыдущем варианте игры.Т.Е вначале перещитываются координаты потом рисуется изображение программа ждет и стирает это изображение.вот только тут изображение упорно не хочит стераться
program igra;единственный способ которым у меня получилось сделать анимацию это использовать cleardevice; но это выглядит жутко не красиво.помогите правильно сделать анимацию!
uses graph,crt;
var
ch:char;
b,tx2,ty2:integer;
blank:pointer;
size:word;
d,m,t,x,y,k,q,v,vx,vy,av,i,i1,i2:integer;
{shute sistem from tank}
procedure pereshet1;
begin
if q=1 then
begin
y:=y-{5}8;
if (y=70) or (y<70) then y:=75;
q:=0;
end;
if q=2 then
begin
x:=x-{5}8;
if (x=9) or (x<9) then x:=12;
q:=0;
end;
if q=3 then
begin
x:=x+{5}8;
if (x=625-60) or (x>625-60) then x:=625-60;
q:=0;
end;
if q=4 then
begin
y:=y+{5}8;
if (y=460-46) or (y>460-46) then y:=460-46;
q:=0;
end;
end;
procedure move1(x,y,i:integer);
begin
putimage(x,y,blank^,0);
end;
procedure clr1(x,y:integer);
begin
if (q<>0) and (q<>5) then
begin
putimage(x,y,blank^,3);
end;
end;
begin
d:=detect;
initgraph(d,m,'e:\tp7.1\bgi');
x:=12;
y:=230;
tx2:=625;
ty2:=320;
vx:=x;
vy:=y;
{kab}
t:=0;
i:=0;
i1:=0;
i2:=0;
rectangle(12,230,12+23,230+48);
arc(12+11,230+6,23,154,13);
arc(12+11,230+42,206,337,13);
line(12+17,230+9,12+17,y+39);
line(12+10,230+9,12+17,230+9);
line(12+10,230+39,12+17,230+39);
rectangle(12+23,230+12,12+35,230+36);
rectangle(12+35,230+22,12+53,230+26);
rectangle(12+53,230+20,12+60,230+28);
setfillstyle(9,2);
floodfill(13,232,15);
size:=imagesize(11,230-8,73,278+8);
new(blank);
getmem(blank,size);
getimage(11,230-8,73,278+8,blank^);
cleardevice;
repeat
randomize;
pereshet1;
if keypressed then
begin
ch:=readkey;
case ch of
#72:q:=1;
#75:q:=2;
#77:q:=3;
#80:q:=4;
#27:halt;
end;
end;
move1(x,y,i);
delay(80);
clr1(x,y);
until ch=#27;
readln;
closegraph;
dispose(blank);
end.
Поясни, пожалуйста, как именно ты стираешь изображение?
Это я вижу.
Но ты сам сказал, что это не работает. Значит, где-то есть ошибка. Вот чтобы ее найти и надо сформулировать, что именно ты делаешь, словами по-русски.
Третий раз спрашиваю: как именно стираешь изображение?
Дергается или мерцает?
Если дергается, что-то не в порядке с измерением времени или синхронизацией, а если мерцает - это в морг: надо отказываться от модуля graph.
Только что разместил ссылки на статьи в соответствующем разделе форума и обнаружил, что исходники оттуда опять пропали.
Буду разбираться.
А пока даю ссылку на тот же материал в другом месте:
http://pascal.sources.ru/articles/087.htm
Теперь я решил сделать чтобы у меня там солдатики бегали так вот как правильно сделать: нарисовать 1го сохранить это изображения а потом егоже и для всех остальных выводить на экран или для каждого солдата нужно создавать свое собственное изображение?
Попробуй сделать обьект солдат и метод paint
Создай список солдат и работай с ним .
Так удобней выходит.
(Если не лень конечно)
А можно както в подобной игре сделать нормальный звук?
Игра - имеется в виду под DOS?
Пробежал глазами тему.
"Нормальный звук" сделать труднее, чем "нормальную графику".
Поскольку "нормальной графики" пока нет, то и за звук браться, думаю, не стоит.