Графіка в SDL. Урок 6: Космічний шутер |
- Statistics
- Participants
- Translate into Ukrainian
- Translation result
- 88% translated in draft. Almost done, let's finish it!
Hello and welcome to the 6th Cone3D SDL tutorial. This lesson will be about couple of things: scrolling background, frame rate independent movement, simple collision detection and playing sounds and music with the SDL_mixer library. This time we'll create a really simple 2D horizontal space shooter that you may later extend into a full game, if you wish (and are really bored). We'll use modified code from lesson 3 for the sprites, so if you don't remember anything about lesson 3, check it out first. We'll also use the font routines from lesson 4. Now, since the code for this tutorial will need SDL_mixer, let's learn how to include it your programs before we do anything else.
Using SDL_mixer in Dev-C++
First you must upgrade the SDL that you have in Dev-C++ to version 1.2.4 (see the first lesson). Then you must download the file sdl_mixer-DevCpp-1.2.4.zip and extract into your dev-c++ folder (c:\dev-c++\ on my system). Now open up the project options in your project and add -lSDL_mixer to the end of the "further object files and linker options" list. Also add "c:\Dev-C++\include\SDL" (repcace C:\Dev-C++\ with something else if Dev-C++ isn't installed in C:\Dev-C++ on your system) to the "Extra include directories" field. And now you should be all set.
Using SDL_mixer in Visual C++
To use SDL_mixer in Visual C++ you must first download this zip: SDL_mixer-devel-1.2.4-VC6.zip. Extract the file SDL_mixer.lib (from the SDL_mixer-1.2.4\lib folder in the zip) into your Visual C++ library folder (on my system it's c:\program files\microsoft visual studio\vc98\lib). Also, extract the file SDL_mixer.h (from the SDL_mixer-1.2.4\include folder in the zip) into your Visual C++ include folder (on my system it's c:\program files\microsoft visual studio\vc98\include). Also, know that this version of SDL_mixer only works with SDL version 1.2.4 (or newer). So if you have 1.2.3 or older, you must upgrade (see the first SDL tutorial on how to do that). One more thing that you should know is that starting now your SDL include files should be in the folder "include", not "include\SDL" like they have been up to this point (or they can be at both places). So, copy them into the folder "include" (from "include\SDL") as well to make everything work fine. Now, in Visual C++ go to the project settings (from the menu: project->settings). Click the 'LINK' tab and add 'sdl_mixer.lib' to the end of the long line of the other .lib's (Object/library modules). That should be it.
Використання SDL_mixer в Linux
To use SDL_mixer in linux, visit the SDL_mixer homepage at http://www.libsdl.org/projects/SDL_mixer/ and 1) download the SDL_mixer-x.x.x....rpm and the SDL_mixer-devel-x.x.x-....rpm and install them OR 2) download the source tarball and compile and install it yourself (configure; make; make install;). Both methods work fine.
Повернутися до уроку
The only things that have changed in the sprite code from lesson 3 are few lines in CSprite.h. The biggest change is that we now use floats instead of integers to store the sprite's position. And also I added some functions to get the position of the sprite (x and y coordiantes) and it's width and height. That's all.
Now let's start with lesson6.cpp. First we have some lines that include some files. time.h is used for the random number generator and math.h for the cosinus function.
// системные библиотеки
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
We now also include 2 files: SDL_mixer.h and SDL.h. We won't use the wrong <SDL/SDL.h> way of including the libraries, but we simply include them like "SDL_mixer.h" and tell the compiler (non-vc++ compilers) where to look for extra libraries. Altough including <SDL/SDL.h> might seem easier at first, the method we'll use now is better. Plus I got some error when including SDL_mixer.h using the old <SDL/...> method...
// библиотеки SDL
#include "SDL_mixer.h"
#include "SDL.h"
Мы должны также включать CSprite.h и CSpriteBase.h если мы хотим использовать Sprite процедур и font.h если мы хотим использовать этот шрифт.
// Sprite classes and font
#include "CSprite.h"
#include "CSpriteBase.h"
#include "font.h"
Как вы могли видеть на скриншоте выше, мы будем использовать пули / или враги и выводить экран. Чтобы предотвратить переполнение экрана мы должны ограничивать количество пуль / врагов, которые могут быть на экране одновременно.Мы используем лимит 10. Заносим значения в константы.
// тут ми встановлюємо обмеження на кількість куль і ворогів
// які можуть бути на екрані одночасно
#define BULLETS 10
#define ENEMIES 10
Теперь у нас есть некоторые жуткие переменные, которые будут использоваться с частоту кадров независимое движение. Мы имеем 2 переменные: ТД и TD2 (TD = разница во времени).Мы привыкли вычеслять, сколько времени продолжалаеться один кадр. Мы храним длину одного кадра в переменную DT (Delta время), если игра не приостановлена, а затем мы увеличим sdlgt (сокращенно SDL_GetTicks ()) с DT.
int td=0,td2=0; //Используется при проверке Разници во времени
// (Сколько времени прошло с последнего кадра)
float dt=0; // Время, прошедшее с того момента
//предыдущий кадр
float sdlgt=0; // переменная времени, которое прошло
Теперь у нас есть пара SDL_Surfaces. Экран занимает весь дисплей, что обратно занимает большое изображение, которое мы помещаем в фон, логотип сохраняет логотип в верхней части экрана, smallship есть образ, который мы используем, когда мы покажем, как много жизней осталось и gameoverimg является Crappy изображение, которое вы видите, когда вы умираете.
SDL_Surface *screen, *back, *logo, *smallship, *gameoverimg;
Далее идут 2 шрифта - белый шрифт и тот же шрифт, но в желтом цвете.
SDLFont *font,*yellowfont;// White and yellow fonts
Теперь наступил спрайты. shipbase хранит все судно графика и графику корабля, bulletbase переменная которая содержит графику пуль. Массив CSprites, пули, хранит все отдельные пули, что вы можете стрелять из вашего корабля.Массив bdraw оповещает нас о том, местоположение пули в настоящее время на экране (1) или нет (0).
CSpriteBase shipbase; // находиться картинки корабля
CSprite ship; // нахождение корабля
CSpriteBase bulletbase; // картинки пуль
CSprite bullets[BULLETS]; //переменные отдельные пули
int bdraw[BULLETS]; // Показывает, какие элементы пули
// array are in use
Как и с пулями, enemybase находиться графика противника спрайты и враги массив хранит все отдельные враги.EDraw показывает нам то, находится ли враг на экране или нет, Elife рассказывает нам, как много жизни враг оставил (сумма определяется случайным, когда создается противника) и einfo рассказывает нам о том, враг синий (а движение вверх и вниз , стоимость einfo является> 0) или фиолетовый (не двигаясь вверх и вниз, стоимость einfo равно 0 в этом случае).
CSpriteBase enemybase; //спрайт врагов
CSprite enemies[ENEMIES]; //спрайт для каждого врага
int edraw[ENEMIES]; //отмечает активных врагов
int espeed[ENEMIES]; //скорость каждого врага
int elife[ENEMIES]; //жизнь каждого врага
int einfo[ENEMIES]; // тип ворога - чиній чи ні
1 приостановлены это когда игра приостанавливается, и 0, если это не так. То же самое с GameOver, которая сообщает нам о том, на этом игра заканчивается, или нет.
int paused=0; //остановлена игра или нет
int gameover=0; //конец игры?
Выделите простой Float, которая сообщает нам, сколько фон, был прокручен(или обновлен). ELAST помнит, когда последний противник вышел.Мы используем это, чтобы новый противник появился после 750 миллисекунд (3 / 4 сек.) Это предотвращает выскакивание врагов слишком быстро. DTIME подобен Elast, но он помнит, когда вы в последний получи жизнь.Мы используем это, чтобы вы были бессмертны в течение 3 секунд после смерти (мигающий судно эффект).Оценка и жизней должно быть очевидно - оценка хранит ваши оценки и живет по числу загубленных жизней вы оставили. Если жизнь опускается ниже нуля, то вы умрете.
float scroll=0; //сколько раз была картинка обновлена(прокручена)
Uint32 elast; //запоминает когда последний вышел
Uint32 dtime; //запоминает когда вы возрадились
int score=0,lives=5; //оценка и жизнь
Следующий 3 переменные должны быть для нас новые. Mix_Music это музыка от типа данных SDL_mixer и Mix_Chunk простые звуковые файлы, которые мы можем проигрывать, когда мы хотим.
Mix_Music *music; //"music" это содержит нашу музыку
Mix_Chunk *shot; //содержит наши звуки
Mix_Chunk *explode; //содержит звуки взрыва
И вот в конце глобальные переменные. Первая функция в наш список называется Sprite_Collide. Она принимает ссылки на 2 CSprite объекты в качестве параметров и возвращает 1, если они являются встречными или 0, если они не являются.Мы делаем обнаружение столкновения с ограниченным прямоугольником, на 80% ширины и высоты спрайты. Это означает, что если 2 спрайты связаны на своих внешних границах затем столкновения не произойдет.Мы обнаружаем столкновения с ограниченным прямоугольником вместо полного прямоугольники, потому что нашы спрайты не в полной мере прямоугольные (есть пустое пространство в углах спрайты).http://www.gamedev.net/reference/articles/article735.asp. Там ASCII изображение есть, что может сделать его более ясным, почему мы используем сокращение прямоугольники вместо полного прямоугольники при проверке на столкновения.
Хотя этот метод определения столкновений работает, она не может работать на старых машинах, где все очень-очень медленно.Представьте себе пулю перед врагом на одной кадре и та же самая пуля на другой стороне противника на следующий кадре.Это так, потому что с частоту кадров независимого движения мы движемся вещи в зависимости от времени, которое прошло, а не на количество кадров, которые прошли.Так возможно перемещения объекта через другой объект после одного кадра и тем самым не вызывая никаких столкновений хотя на самом деле должно было ...
short int Sprite_Collide(CSprite &object1, CSprite &object2)
{
Мы сохраняем наши координаты сокращен прямоугольников в переменных left1, right1, top1 и bottom1 на один спрайт и left2, right2, top2 и bottom2 для второго спрайта.Тогда мы сделать их равными соответствующим значениям от нашего спрайты
// Мы сохраняем наши координаты сокращен прямоугольники здесь
double left1, left2;
double right1, right2;
double top1, top2;
double bottom1, bottom2;
left1 = object1.getx()+object1.getw()*0.1;
left2 = object2.getx()+object2.getw()*0.1;
top1 = object1.gety()+object1.geth()*0.1;
top2 = object2.gety()+object2.geth()*0.1;
right1 = object1.getx()+object1.getw()*0.9;
right2 = object2.getx()+object2.getw()*0.9;
bottom1 = object1.gety()+object1.geth()*0.9;
bottom2 = object2.gety()+object2.geth()*0.9;
И, наконец, мы делаем некоторые "магические", сравнивая и вернуться 1, если спрайты делать на самом деле сталкиваемся или 0, если они не делают.ПРИМЕЧАНИЕ: Вы вполне может заменить "bottom1", "top2", "top1", и т.д. с "object1.gety () + object1.geth () * 0.9", и т.д. на следующей 4 линий. Я не сделал на этот раз, потому что я хотела посмотреть код четкое ... Вы должны сделать нечто подобное в своем коде.
if (bottom1 < top2) return 0;
if (top1 > bottom2) return 0;
if (right1 < left2) return 0;
if (left1 > right2) return 0;
return 1;
};
Следующие 3 функции являются общими для всех уроков, поэтому не потратим многовремени на этот раз. ImageLoad загружает изображение и преобразует его в формат отображения для быстрого и blitting BLIT изображение двух DrawIMG's на экран.
//Загрузить картинку и конвертировать в формат дисплея
// для ускорения мерцания
SDL_Surface * ImageLoad(char *file)
{
SDL_Surface *temp1, *temp2;
temp1 = SDL_LoadBMP(file);
temp2 = SDL_DisplayFormat(temp1);
SDL_FreeSurface(temp1);
return temp2;
