Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

Практическая работа № 34





«Игра»

 

Цель работы - создать программу – игру. Игрок управляет пушкой зенитки, его боевое задание – справиться с нашествием воздушных шаров. Воздушные шары несут бомбы, которые они сбросят, как только окажутся над пушкой. Необходимо не допустить этого и уничтожить их все на подлете. Снаряды не ограничены, но следующий выстрел можно делать только после того, как выпущенный снаряд поразит цель, упадет на землю или уйдет из зоны видимости.

В игре участвуют:

· воздушные шары,

· знитная пушка,

· пушечный снаряд,

· бомба,

· внешняя среда.

Для шаров введен специальный тип TBalloon., в котором содержатся данные о координатах шара, его скорости, состоянии и цвете. Массив переменных Balloons типа TBalloon будет содержать полную информацию обо всех шарах. Индексирование идет, начиная с нуля. Общее число шаров в массиве задается соответствующей константой.

Кроме того, к шарам относятся константы, определяющие:

· количество шаров,

· их возможные цвета,

· возможную высоту над землей (всего предполагается четыре уровня),

· интервал между шарами и их радиус.

Type

TBalloon = record

x, y, v, Explosion: integer;

Color: TColor;

End;

Const

BallCount = 10;
BallColors: array [0.. 9] of TColor = (clRed, clGreen, clNavy, clMaroon, clPurple, clOlive, clLime, clYellow, clFuchsia, clSilver);
BallAltitude: array [0.. 3] of integer = (240, 160, 200, 120);
BallInterval = 40;
BallRadius = 15;
V = 150;
g = -9.8 * 3;
dt = 0.1;
var
Form1: TForm1;
x, y, Vx, Vy, BombY, BombV: double;
Angle, GunPosition, GunExplosion: integer;
Balloons: array [0.. BallCount - 1] of TBalloon;

 

Зенитная пушка описывается переменными:

· угол наклона пушки,

· ее положение

· ее состояние.

Пушечный снаряд описывается переменными:

· координатами,

· текущей скоростью,

· начальной скоростью при выстреле.

Бомба, сбрасываемая с воздушного шара, имеет:

· координату,

· скорость.

Для расчета положений объектов нужно знать ускорение падения и шаг по времени.

В качестве состояния шара и пушки мы используем переменные TBalloon. В определенный момент времени каждый элемент должен находиться в каком-то состоянии, определяющем то, как элемент выглядит на экране. Шары и пушка могут быть боеспособными, взрывающимися и уничтоженными.

Если Explosion = 0 - шар боеспособен, если Explosion = 10, то он уничтожен, а значения от 1 до 9 обозначают фазы взрыва. Чтобы инициировать взрыв боеспособного шара, нужно присвоить Explosion:= 1. То же самое касается и пушки.

Состояние, в котором скорость снаряда равна нулю: Vx = 0 и Vy = 0. В этом случае считают, что можно сделать новый выстрел. Пока же снаряд летит (то есть скорость его не нулевая), новый выстрел сделать нельзя.

Бомба будет сбрасываться шаром, когда он поравняется с пушкой. Таким образом, X - координата бомбы всегда равна X - координате пушки. Следовательно, необходимо хранить только Y-координату бомбы. Бомба не сброшена, если BombY = 1000. Если BombY < 1000, то она считается сброшенной и начинает падать.

Поместите на форму TrackBar, Button, Image и Timer и настройте их параметры.

Timer: Interval = 100; Image: Width = 440, Heigth = 260; Button: Caption = ‘Новая игра’; TrackBar: Min = -90, Max = 90, Frequency = 10.

Image - сражение в реальном времени. Timer - реальное время. Button - запуск новой игры. TrackBar - управление зенитной пушкой.

В обработчике нажатия на кнопку "Новая игра" необходимо обнулить параметры, расставить пушку и шары. Для каждого шара устанавливается случайное направление движения: v = 1 или –1. В зависимости от направления, определяется высота, на которой находится шар (на одном и том же уровне шары летят в одну сторону). По x-координате шары расставляются так, чтобы они шли с примерно равным интервалом в направлении пушки из-за границ экрана.

Каждый шар Balloons[i], элемент массива Balloons, имеет тип записи TBalloon, и для того, чтобы получить доступ к его элементам, нужно писать: Balloons[i].Explosion:= 0, Color:= BallColors[random(10)] и т.д. Конструкция with Balloons[i] do begin.. end позволяет избежать повторения.

procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
begin
Caption:= 'Нашествие';
TrackBar1.Position:= 0;
GunPosition:= 170 + random(100);
Vx:= 0;
Vy:= 0;
GunExplosion:= 0;
for i:= 0 to BallCount – 1 do
with Balloons[i] do
begin
if random < 0.5 then v:= –1 else v:= 1;
y:= BallAltitude[1 + v + random(2)] + random(10);
x:= 220 - v * (220 + i * BallInterval + random(20));
Explosion:= 0;
Color:= BallColors[random(10)];
end;
BombY:= 1000;
end;

 

В обработчик события формы OnCreate вводится датчик случайных чисел, устанавливается клиентский размер формы (ClientWidth:= 455; ClientHeight:= 315;). Размер клиентской области формы в приложениях определяется автоматически как Width и Height формы минус ширина заголовка и бордюров.

procedure TForm1.FormCreate(Sender: TObject);
begin
Randomize;
ClientWidth:= 455;
ClientHeight:= 315;
Button1.Click;
end;

 

Пушка танка будет управляться с помощью компонента TrackBar. Выстрел производится нажатием пробела на клавиатуре. При этом фокус ввода должен быть у TrackBar. В обработчике OnKeyPress реализуется выстрел, задавая начальную скорость и положение снаряду, а также издавая звук выстрела.

Процедура, проигрывающая этот звук из wav-файла, описана в модуле, который необходимо подключить в разделе uses. В модуле MMSystem имеется функция PlaySound, с помощью которой можно проигрывать файлы wav. Для асинхронного воспроизведения (приложение не приостанавливает работу на время воспроизведения, а проигрывает его в фоновом режиме) вызов выглядит так:

PlaySound(PChar('имяфайла.wav'), 0, SND_ASYNC).

В стандартных звуках Microsoft Office можно подобрать звуки для выстрела и взрыва. В зависимости от версии программы, эти файлы хранятся в C:\Windows\Media\ Microsoft Office 2000, C:\Program Files\Microsoft Office\Office\Media или в какой-то подобной папке. Найдите звуки для выстрела (условно назовем GunShot.wav) и взрыва (условно назовем Explode.wav) и скопируйте их в папку, в которой сохранен проект.

procedure TForm1.TrackBar1KeyPress(Sender: TObject; var Key: Char);
var
i: integer;
begin
if (Key = ' ') and (Vx = 0) and (Vy = 0) and (GunExplosion = 0) then
begin
try

PlaySound(PChar('GunShot.wav'), 0, SND_ASYNC);
except
end;
Vx:= V * Sin(Angle * pi / 180);
Vy:= V * Cos(Angle * pi / 180);
x:= GunPosition + 15 * Sin(Angle * pi / 180);
y:= 20 + 15 * Cos(Angle * pi / 180);
end;

if (Key = 'Q') then
begin
try
PlaySound(PChar('Explode.wav'), 0, SND_ASYNC);
except
end;
for
i:= 0 to BallCount - 1 do
if
Balloons[i].Explosion = 0 then
Balloons[i].Explosion:= 1;
Caption:= 'Уничтожен';
end;
end
;

 

В обработчике изменения положения бегунка TrackBar меняем наклон пушки.

procedure TForm1.TrackBar1Change(Sender: TObject);
begin
Angle:= TrackBar1.Position;
end;

 

Выстрел происходит, если:
1) нажат пробел;
2) снаряд готов (Vx = 0) и (Vy = 0);
3) пушка боеспособна (GunExploion = 0).

 

Процедура MoveAll, вызываемая каждый такт таймера, отвечает за то, чтобы все процессы шли своим чередом. Вставьте ее сразу после implementation.

 

procedure MoveAll;
var i: integer;
begin
for i:= 0 to BallCount - 1 do
with Balloons[i] do
if Explosion = 0 then
x:= x + v
else begin
if Explosion < 10 then
inc(Explosion);
end;
if (Vx <> 0) or (Vy <> 0) then
begin
x:= x + Vx * dt;
y:= y + Vy * dt;
Vy:= Vy + g * dt;
end;
if BombY < 1000 then
begin
BombY:= BombY + BombV * dt;
BombV:= BombV + g * dt
end;
if (GunExplosion > 0) and (GunExplosion < 10) then
inc(GunExplosion);
end;

 

Процедура пододвигает все шары, которые живы (у них Explosion = 0), в направлении вектора их скорости. Остальные шары, если они находятся в фазе взрыва (0 < Explosion < 10), переходят в следующую фазу.

Если снаряд выпущен (Vx <> 0) или (Vy <> 0), то его координата и скорость изменяются согласно законам природы.

Если бомба сброшена (BombY < 1000), то она также подчиняется закону всемирного тяготения.

Если танк находится в фазе взрыва (0 < GunExplosion < 10), он переходит в следующую фазу.

Ошибки, возникающие в обработчике таймера или процедурах, которые вызываются из обработчика, не останавливают таймер и, значит, через секунду возникают опять. Чтобы их остановить, приходится использовать Ctrl-Alt-Del…

В этой процедуре мы работаем с массивом. Одной из самых частых ошибок, которые не так-то просто найти, является выход за границы массива. Для предотвращения подобных ситуаций включите проверку на выход из диапазона допустимых значений (Project => Options => Compiler => Runtime errors => Range checking), которая по умолчанию отключена.

Перемещения сами по себе могли бы продолжаться бесконечно. Необходимо проконтролировать:

· не попал ли снаряд в шар, следовательно, взорвать его;

· не уничтожены ли все шары, следовательно, выдать надпись о победе;

· не поравнялся ли шар с пушкой, следовательно, сбросить бомбу;

· не упал ли снаряд и не вышел ли он из зоны контроля, следовательно, перезарядить пушку;

· не упала ли бомба на пушку, следовательно, закончить игру.

Для контроля за передвижениями предусмотрена процедура:

procedure CheckCollisions;
var
i, j: integer;
HappyEnd: boolean;
begin
for i:= 0 to BallCount - 1 do
with Balloons[i] do
begin
if (Explosion = 0) then
begin
if (sqr(x - Unit1.x) + sqr(y - Unit1.y) < sqr(BallRadius)) then
begin
try
PlaySound(PChar('Explode.wav'), 0, SND_ASYNC);
except end;
Explosion:= 1;
Unit1.x:= 0;
Unit1.y:= 0;
Unit1.Vx:= 0;
Unit1.Vy:= 0;
HappyEnd:= (GunExplosion = 0);
for j:= 0 to BallCount - 1 do
HappyEnd:= HappyEnd and (Balloons[j].Explosion > 0);
if HappyEnd then
Form1.Caption:= 'Победа!';
end;
if (x = GunPosition) and (BombY = 1000) and (GunExplosion = 0) then
begin
BombY:= y - BallRadius - 5;
BombV:= 0;
end;
end;
end;
if (y < 0) or (x < 0) or (x > 440) then
begin
x:= 0;
y:= 0;
Vx:= 0;
Vy:= 0;
end;
if BombY < 10 then
begin
BombY:= 1000;
GunExplosion:= 1;
try
PlaySound(PChar('Explode.wav'), 0, SND_ASYNC);
except end;
Form1.Caption:= 'Увы...';
end;
end;

В этом блоке возможная ошибка связана с использованием with … do begin … end.

X-координата снаряда хранится в глобальной переменной x, X-координата воздушного шара – в переменной Balloons[i].x. Однако когда пишут код внутри with Balloons[i] do begin … en d, то именно к координате шара обращаются просто как к x. Если нужно добраться до глобальной переменной, то теперь уже перед ней нужно ставить уточнение: Unit1.x, где Unit1 – имя модуля.

Рисование отдельных элементов баталии также разумно поместить в специализированные для этого процедуры.

Художественные образы шаров, пушки и взрыва передаются с помощью процедур:

procedure DrawBalloon(x, y: integer; Color: TColor);
begin
with Form1.Image1.Canvas do
begin
Pen.Color:= clBlack;
Brush.Color:= Color;
Ellipse(x - BallRadius, y - BallRadius, x + BallRadius, y + BallRadius);
Pen.Color:= clWhite;
Brush.Color:= clWhite;
Ellipse(x - BallRadius div 2 - 3, y - BallRadius div 2 - 3, x - BallRadius div 2 + 3, y - BallRadius div 2 + 3);
Pen.Color:= clBlack;
Brush.Color:= clOlive;
Rectangle(x - 5, y + BallRadius + 5, x + 5, y + BallRadius + 10);
MoveTo(x - 5, y + BallRadius + 5);
LineTo(x - BallRadius, y);
MoveTo(x, y + BallRadius + 5);
LineTo(x, y);
MoveTo(x + 5, y + BallRadius + 5);
LineTo(x + BallRadius, y);
end;
end;

procedure DrawGun;
begin
with Form1.Image1.Canvas do
begin
if (Vx = 0) and (Vy = 0) then
Pen.Color:= RGB(0, 70, 0) else Pen.Color:= clBlack;
Brush.Color:= Pen.Color;
Pen.Width:= 5;
MoveTo(GunPosition, 240);
LineTo(GunPosition + round(15 * sin(Angle * pi / 180)), 240 - round(15 * cos(Angle * pi / 180)));
Pen.Width:= 1;
Ellipse(GunPosition - 8, 232, GunPosition + 8, 248);
Rectangle(GunPosition - 10, 240, GunPosition + 10, 260);
end;
end;

Процедура DrawExplosion обеспечивает доступ к координатам снаряда.

procedure DrawExplosion(x, y, Phase: integer);
var
i, xx, yy, Size: integer;
a, b: double;
begin
with Form1.Image1.Canvas do
for i:= 0 to Phase * 10 do
begin
a:= random * 2 * pi;
b:= random * sqr(Phase) / 3 + 5;
xx:= x + round(l * sin(a));
yy:= y + round(l * cos(a));
Size:= round(sqr(10 - Phase) / 8 + 2);
Pen.Color:= RGB(random(100), 0, 0);
Brush.Color:= Pen.Color;
Ellipse(xx - random(Size) - 1, yy - random(Size) - 1, xx + random(Size), yy + random(Size));
end;
end;

Кроме того, пушка меняет цвет, когда готов очередной снаряд. В довершение, нужно соединить все написанное воедино.

Процедуры рисования объединяются в процедуре, рисующей все поле боя:

· небо,

· шары,

· пушка,

· ядро,

· бомба.

Объединять все вместе обработчик таймера.

 

procedure DrawBattleField;
var
i: integer;
begin
with Form1.Image1.Canvas do
for i:= 0 to 259 do
begin
Pen.Color:= RGB(i div 2, i div 2, 255);
MoveTo(0, i);
LineTo(440, i);
end;
for i:= 0 to BallCount - 1 do
with Balloons[i] do
if Explosion = 0 then DrawBalloon(x, 260 - y, Color) else if Explosion < 10 then DrawExplosion(x, 260 - y, Explosion);
if GunExplosion = 0 then DrawGun else if GunExplosion < 10 then DrawExplosion(GunPosition, 240, GunExplosion);
with Form1.Image1.Canvas do
begin
Pen.Color:= clMaroon;
Brush.Color:= clRed;
if (Vx <> 0) or (Vy <> 0) then Ellipse(round(x) - 2, 260 - round(y) - 2, round(x) + 3, 260 - round(y) + 3);
if (BombY <> 1000) then Ellipse(GunPosition - 2, 260 - round(BombY) - 2, GunPosition + 3, 260 - round(BombY) + 3);
end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
MoveAll;
CheckCollisions;
DrawBattleField;
end;

 

 







Дата добавления: 2015-09-04; просмотров: 488. Нарушение авторских прав; Мы поможем в написании вашей работы!




Шрифт зодчего Шрифт зодчего состоит из прописных (заглавных), строчных букв и цифр...


Картограммы и картодиаграммы Картограммы и картодиаграммы применяются для изображения географической характеристики изучаемых явлений...


Практические расчеты на срез и смятие При изучении темы обратите внимание на основные расчетные предпосылки и условности расчета...


Функция спроса населения на данный товар Функция спроса населения на данный товар: Qd=7-Р. Функция предложения: Qs= -5+2Р,где...

Этапы творческого процесса в изобразительной деятельности По мнению многих авторов, возникновение творческого начала в детской художественной практике носит такой же поэтапный характер, как и процесс творчества у мастеров искусства...

Тема 5. Анализ количественного и качественного состава персонала Персонал является одним из важнейших факторов в организации. Его состояние и эффективное использование прямо влияет на конечные результаты хозяйственной деятельности организации.

Билет №7 (1 вопрос) Язык как средство общения и форма существования национальной культуры. Русский литературный язык как нормированная и обработанная форма общенародного языка Важнейшая функция языка - коммуникативная функция, т.е. функция общения Язык представлен в двух своих разновидностях...

Методы прогнозирования национальной экономики, их особенности, классификация В настоящее время по оценке специалистов насчитывается свыше 150 различных методов прогнозирования, но на практике, в качестве основных используется около 20 методов...

Методы анализа финансово-хозяйственной деятельности предприятия   Содержанием анализа финансово-хозяйственной деятельности предприятия является глубокое и всестороннее изучение экономической информации о функционировании анализируемого субъекта хозяйствования с целью принятия оптимальных управленческих...

Образование соседних чисел Фрагмент: Программная задача: показать образование числа 4 и числа 3 друг из друга...

Studopedia.info - Студопедия - 2014-2025 год . (0.008 сек.) русская версия | украинская версия