Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Змейка. Написание игры (http://forum.oszone.net/showthread.php?t=173840)

DaRiYs 22-04-2010 23:01 1398867

Змейка. Написание игры
 
Передомной появилась такая проблемма. Нада написать игру "Змейка" на Borland C++ 3.11 с использованием ООП и в графическом режиме. Помогите пожалуста разобратся с такими вопросами:
1. Как правильно спроэктировать самц игру, классы и тп?
2. Как реализовать движение змеи и изменение направлений при нажатии клавиш.

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

lxa85 23-04-2010 08:57 1399039

DaRiYs,
Цитата:

Цитата DaRiYs
1. Как правильно спроэктировать самц игру, классы и тп?
2. Как реализовать движение змеи и изменение направлений при нажатии клавиш. »

Рассуждай вслух, а дальше будет видно. Если можно будет на их основе что-нибудь конструктивное выделить, то запросто.
В противном случае это будет чужое решение, а не собственное.

DaRiYs 23-04-2010 10:22 1399087

Бы ло бы еще о чем рассуждать, я незнаю с какой стороны приступить... Хоть теорию реализации игры для начала скажите.

lxa85 23-04-2010 10:38 1399097

DaRiYs, теория реализации игры - это следующий шаг. А сейчас рассуждай о том, чего ты хочешь видеть на экране. Реализаций разновидностей много, а цель должна быть одна.
Начни рассказ со слов "Я хочу чтобы ...".
Чтобы змейка двигалась так-то и так-то. Для управления использовались кнопки такие-то и такие-то.
Змейка характеризуется так-то и так-то. Нямки появляются так-то.
Вопрос будет в том, в каком виде у тебя будет хранится поле и в каком виде будет представлена змейка. Но я этого не говорил! :)
Когда этап "Я хочу" будет пройден, будем думать над реализацией.
Не торопись, запрограммировать плевое дело, было бы что. :)
Т.ч. рассуждай, рисуй схемки, а о программировании пока не думай. (Рассуждения терминами С/С++ сейчас не нужны)

Drongo 23-04-2010 11:14 1399121

Я когда-то решал аналогичную задачку "траектория черепахи", но если честно, до конца не дорешал. Парочка мыслей:

1. Нужно поле по которому змейка будет двигаться - двухмерный массив
Код:

const int x = 10;
const int y = 10;

int boarb[x][y] = {0};

2. Нужен массив ходов (поскольку шаг у нас одна клетка то и значение будет 1 или -1) -
Код:

const int step = 2;

int step[step] = {1, -1};

3. Варианты ходов 4 варианта, вверх вниз, вправо, влево
4. переменная хода - currentStep = 0;
Код:

...
  const int x = 10;
  const int y = 10;
  const int step = 2;

  int boarb[x][y] = {0};
  int step[step] = {1, -1};

  int currentStep = 0, move = 0;
 
  cout<<"\n  Введите шаг змейки от '0' или '4':  ";
  cin>>move ;

  while(move != 9999){ // 9999 ходов
      if(move == 1){
        currentStep += 1; // Вверх
        }
    else if(move == 2){
        currentStep += 1; // Вправо
        }
    else if(move == 3){
        currentStep += -1; // Вниз
        }
    else if(move == 4){
        currentStep += -1; // Влево
        }
...

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

Реализации хода шахматного коня
Код:

// Задачи главы 4. Задача 4.24
//Программа реализации хода шахматного коня
#include <vcl.h>
#include <iostream>
using std::cout;
using std::cin;
using std::endl;

#include <cstdlib>

const int row=8;
const int column=8;

void print(int [][column], int, int);

int main()
{
  int board[row][column]={0},
      horisontal[8]={2, 1, -1, -2,
                    -2, -1, 1, 2},
      vertical[8]={-1, -2, -2, -1,
                  1, 2, 2, 1};
  int curentRow=0,
      curentColumn=0,
      moveNumber,
      controlRow=0,
      controlColumn=0,
      counter=0,
      z;

  cout<<"  PROGRAMMA SHACHMATNOGO KONYA  ";
  cout<<"\n  ENTER '0' START  FINISH  '-1':  ";
  cout<<"\n  ENTER  NUMBER  CHODA KONYA  OT '0' DO '7':  ";
    cin>>moveNumber;
  while(moveNumber != 9999){

    curentRow += vertical[moveNumber];
    curentColumn += horisontal[moveNumber];
    if((curentRow >= 0 && curentRow <= 7) && (curentColumn >= 0 && curentColumn <= 7)){
        controlRow=curentRow;
        controlColumn=curentColumn;
        board[curentRow][curentColumn]=1;
        print(board, row, column);
      }
    else{
        cout<<"\n    ENTER PRAVILNIY CHOSD";
        curentRow=controlRow;
        curentColumn=controlColumn;
      }
    cout<<"\n  ENTER  NUMBER  CHODA KONYA  OT '0' DO '7':  ";
    cin>>moveNumber;
    }

    print(board, row, column);

    cin>>z;
        return 0;
}
//Функция печати массива
void print(int boarde[][column], int rowe, int columne)
{
 for(int i=0; i<rowe; i++){
    for(int j=0; j<columne; j++)
      cout<<boarde[i][j];
      cout<<endl;
    }
}
//---------------------------------------------------------------------------


Awejk 23-04-2010 11:20 1399126

Это у тебя лабораторная работа/курсовая/диплом или ты просто ради фана хочешь разобраться в игростроении? Если учёба тогда какие сроки, если ради фана то, можешь начать примерно со следующего.

Какие ключевые понятия в игре Змейка (да и вообще в любой игре)? Есть карта или просто поле по которому ползает червяк в области ограниченного пространства. На этом поле он собирает объекты (бонусы) которые по разному влияют на червяка. Исходя из этого у нас будет один общий базовый класс для объектов. К объекту можно также отнести и самого червяка, а что он разве не объект? Ещё какой объект только со своим набором атрибутов, поэтому для начало возьмём базовый объект, некий
Код:

СBaseObject
{
...
};

Какие общие черты у каждого объекта, пусть это бонус, червяк или его враги (другой червяк который ползает по полю и стреляет):
1. координаты на сетке (x,y)
2. скорость (velocity)
3. тип объекта (type) (мы же должны как-то узнавать в игре что это или кто это, бонус или враг или просто камень в который нужно врезаться и отнять пару поинтов жизни у червяка)
4. Угол (angle) - в ту сторону будет идти червяк меняется угол меняется и направления червяка.
5. ширина и высота объекта (width and height)

а теперь имеем
Код:

CBaseObject
{
        private:
                int x,y;
                float velocity;
                ETypeObject type;
                float angle;
                int width, height;
};

ETypeObject
{
        BONUS,
        ENEMY,
        USER
};

Это я взял самые основные свойства объекта, которые будут у любого объекта в игре. Разумеется что в зависимости от сложности игры количество свойств в базовом объекте может меняться. Теперь тебе надо будет наследоваться от этого базового объекта и расширять функционал для каждого отдельного объекта. Например, ты решил добавить бонус для увеличениятела червяка,

Код:

СDecreaseBody : public CBaseObject
{

}

А что собственно расширять, спросишь ты. Ну давай подумаем, что должен делать этот бонус увеличивать тело червяка, значит вывод напрашивается сам на себя
Код:

СDecreaseBody : public CBaseObject
{
        private:
                int enlarge;
}

вот такой вот простой бонус будет, он очень примитивный поэтому пока в голову больше ничего не приходит что сюда ещё добавить, но поверь что на протяжении написания игры будет постепенно разрастаться этот класс. На самом деле ещё нужно было в базовый объект кроме свойств добавить базовые методы такие как
Код:

render();
logic();
init();

ну и ещё что-нибудь. А у наследника CDecreaseBody реализовать метод logic(); а может и ещё что-нибудь.

Теперь тебе есть от чего оталкиваться.

Цитата:

Цитата Drongo
currentStep += 1; »

нужно расчитывать скорость передвижения на основе делта времени, иначе в игру можно будет играть только на 400 пентиумах. Т.е. она будет слишком быстро работать.

Drongo 23-04-2010 12:04 1399152

Цитата:

Цитата Modnyi_Keks
нужно расчитывать скорость передвижения на основе делта времени, иначе в игру можно будет играть только на 400 пентиумах. Т.е. она будет слишком быстро работать. »

Скорость шага в моём примере неиспользуется, т.е. пока один ход, одно нажатие клавиши.

Awejk 23-04-2010 12:07 1399157

Цитата:

Цитата Drongo
Скорость шага в моём примере неиспользуется, т.е. пока один ход, одно нажатие клавиши. »

но змейка же идёт непрерывно и управлять нужно только поворотом. А не хотьбой. Хотя возможно Вы просто общий случай написали.

Drongo 23-04-2010 13:11 1399192

Цитата:

Цитата Modnyi_Keks
Хотя возможно Вы просто общий случай написали. »

Конечно, отталкиваясь от задачки
Цитата:

Цитата Drongo
траектория черепахи »


DaRiYs 26-04-2010 00:16 1400640

Спсиб всем за помощь и идеи, разобрался наконец то, написал

Awejk 26-04-2010 10:04 1400823

ну тогда выкладывай исходники на все общее обозрение и критику, нам же интересно узнать как ты разобрался :)

btf 17-11-2010 19:46 1545133

Всем доброго времени суток!
Мне вот тоже стало интересно написать земйку.
Я начал делать все по мануалу: придумал что я хочу и вроде составил 2 класса.

Червяк должен ползать сам. Пользователь лишь выбирает направление червя с помощью клавиатуры.
Яблоки будут появлятся в случайных кооодинатах и через некоторое время исчезать. Съев одно яблоко червяк становится длинее на еденицу.
Скорость червя увеличивается по мере увеличения его длины.
Камни так же будут появляться в случайных местах. Если червь врежется в камень - игра закончена.
Если червяк врежется в границы поля - игра закончена.
За всю игру появляется N яблок.
Игра считается успешно законченной, если длина червяк собрал M яблок (M<N).

Поле - массив[40][40]

Характеристики червя:
Х координата, У координата, длина червя, скорость червя, количество собранных яблок.

Характеристики объекта:
Х коррдината, У координата, время жизни, тип объекта(яблоко или камень).

Код:

class Worm
{
int xPos, yPos, length, speed, apples;
public:
 Worm();
 ~Worm();
 void SetX(int X) {xPos=X;}
 int GetX() const {return xPos;}
 void SetY(int Y) {yPos=Y;}
 int GetY() const {return yPos;}
 void SetLength(int len) {length=len;}
 int GetLength() const {return length;}
 void SetSpeed(int spd) {speed=spd;}
 int GetSpeed() const {return speed;}
 void SetApples(int apls) {apples=apls;}
 int GetApples() const {return apples;}
}

class Obj
{
int xPos, yPos, existTime, objType;
public:
 Obj();
 ~Obj();
 void SetX(int X) {xPos=X;}
 int GetX() const {return xPos;}
 void SetY(int Y) {yPos=Y;}
 int GetY() const {return yPos;}
 void SetTime(int time) {existTime=time;}
 int GetTime() const {return existTime;}
 void SetType(int type) {objTye=type;}
 int GetType() const {return objType;}
}

Что делать дальше - я не знаю. Подскажите как сделать управление червем с помощью клавиатуры и как реализовать все это на экране? И еще хотелось бы наследование задействовать, но я не придумал как.

Подскажите, пожалуйста.

pva 17-11-2010 21:58 1545218

Вот червяк:
Код:

.........
..x......
..x......
..xxxx...
.....x...
.....X...
.........
.........

можно узнать его координаты GetX(), GetY()? Или я на другую игру подумал?

btf 17-11-2010 23:02 1545260

Я не знаю, про какую игру ты подумал. Я имею ввиду обычную змейку, как на старых моделях телефона nokia. Я хочу использовать не псевдографику, а какие-нибудь стандартные графические функции с++.
Перед тем как узнать координаты их надо установить...

Admiral 17-11-2010 23:51 1545299

Btf если проект под Win32, то в событии WM_CHAR оконной функции обрабатывать нажатия клавиш. В той же функции, но в другом событии (WM_PAINT), реализовать вывод на экран.
Для данной задачи, если требуется что было задействовано наследование, можно наследовать яблоко и камень от одного класса (того же Obj), или же все классы (включая Worm) наследовать от одного интерфейсного класса. Второй вариант упрощает менеджмент объектов.
Если идти по пути ООП далее, то для решения данной задачи стоит создать ещё один класс, который будет управлять всеми игровыми процессами. Он же будет хранить все объекты, характеристики игрового поля, условия игры в своих полях.

В стандарте С++ не заложено графических функций. Графический вывод осуществляют дополнительные библиотеки. Под Win32 такие как GDI, GdiPlus, Direct3D, OpenGL и прочие.

btf 18-11-2010 01:28 1545346

Блин, как-то трудно. А если делать с помощью псевдографики? Как это реализовать?

DaRiYs 18-11-2010 03:15 1545377

Цитата:

Цитата btf
И еще хотелось бы наследование задействовать, но я не придумал как. »

Есть одна замечательная фраза "Если в архитектуре приложения ненужно использовать наследование то ненада его придумывать" Тоесть если логически это там ненада то незачем это привинчивать ибо реализация избыточна

Sashochok 20-01-2012 13:22 1840294

а можите дать исходник, интересно)


Время: 17:18.

Время: 17:18.
© OSzone.net 2001-