Созданные ответы форума
Просмотр 3 сообщений - с 1 по 3 (из 3 всего)
-
АвторСообщения
-
В общем классы вынес в отдельный файл, чтоб не мешали.
Никак не могу придумать нормальные алгоритм для задержки выстрелов игрока и алгоритм для огня целей по игроку :/Код main.cpp и Entities.h
C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596#include <SFML/Graphics.hpp>#include <iostream>#include <sstream>#include <vector>#include <list>#include "Entities.h"int main(){RenderWindow window(sf::VideoMode(480, 640), "GAME");float CurrentFrame = 0;//хранит текущий кадрlist<Entity*> entities;list<Entity*>::iterator it; //итератор для "пробегания по списку"list<Entity*>::iterator it2; //второй итератор, для реализации модели столкновений элементов списка//Player s("ship.png", 90, 0, 90, 30, 240, 600);//создаем объект p класса player,задаем "hero.png" как имя файла+расширение, далее координата Х,У, ширина, высота.Image shipImage;shipImage.loadFromFile("textures/ship.png");Player s(shipImage, 90, 0, 90, 30, "Player", 240, 600);//объект класса игрокаImage BulletImage;//изображение для пулиBulletImage.loadFromFile("textures/bullet_test.png");//загрузили картинку в объект изображенияImage enemyImage;enemyImage.loadFromFile("textures/enemy_test.png");const int n = 4; const int m = 8;int i, j;for (i = 0; i < n; i++){for (j = 0; j < m; j++){entities.push_back(new Enemy(enemyImage, 0, 0, 30, 30, "Enemy", 15 + j * 30 + j * 15, 20 + i * 30 + i * 15));}}float bullettimer = 0;Clock clock;while (window.isOpen()){float time = clock.getElapsedTime().asMicroseconds();clock.restart();time = time / 800;//bullettimer += time;sf::Event event;while (window.pollEvent(event)){if (event.type == Event::Closed)window.close();// if (s.isShoot == true) { s.isShoot = false; entities.push_back(new Bullet(BulletImage, 0, 0, 10, 10, "Bullet", s.sx+s.w/2-5, s.sy, 0)); }//если выстрелили, то появляется пуля. enum передаем как intif (event.type == Event::KeyPressed){if (event.key.code == Keyboard::Space){entities.push_back(new Bullet(BulletImage, 0, 0, 10, 10, "Bullet", s.sx + s.w / 2 - 5, s.sy, 0));}}}s.update(time);for (it = entities.begin(); it != entities.end();)//говорим что проходимся от начала до конца{Entity *b = *it;//для удобства, чтобы не писать (*it)->b->update(time);//вызываем ф-цию update для всех объектов (по сути для тех, кто жив)if (b->life == false) { it = entities.erase(it); delete b; }// если этот объект мертв, то удаляем егоelse it++;//и идем курсором (итератором) к след объекту. так делаем со всеми объектами списка}for (it = entities.begin(); it != entities.end(); it++)//проходимся по эл-там списка{for (it2 = entities.begin(); it2 != entities.end(); it2++){if ((*it)->getRect() != (*it2)->getRect())//при этом это должны быть разные прямоугольникиif (((*it)->getRect().intersects((*it2)->getRect())) && ((*it)->name == "Enemy") && ((*it2)->name == "Bullet"))//если столкнулись два объекта и они враги{(*it)->health -= 25;//меняем направление движения врага//(*it)->sprite.scale(-1, 1);//отражаем спрайт по горизонтали(*it2)->life = false;}}}for (it = entities.begin(); it != entities.end(); it++){if (((*it)->name == "Enemy") && ((*it)->life == true)) { int a = rand() % 1000; if (a > 99 && a < 101) entities.push_back(new Bullet(BulletImage, 0, 0, 10, 10, "EnemyBullet", (*it)->sx + s.w / 2 - 5, (*it)->sy, 1)); }}window.clear();for (it = entities.begin(); it != entities.end(); it++){window.draw((*it)->sprite);}window.draw(s.sprite);//рисуем спрайт объекта p класса playerwindow.display();}return 0;}C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152#define ENTITIES_H#include <SFML/Graphics.hpp>#include <iostream>#include <sstream>using namespace sf;//включаем пространство имен sf, чтобы постоянно не писать sf::using namespace std;class Entity {public:float dx, dy, x, y, sx, sy, speed, moveTimer;//добавили переменную таймер для будущих целейint w, h, health;bool life, isMove;Texture texture;Sprite sprite;String name;//враги могут быть разные, мы не будем делать другой класс для врага.всего лишь различим врагов по имени и дадим каждому свое действие в update в зависимости от имениEntity(Image &image, float X, float Y, int W, int H, String Name, float SX, float SY){x = X; y = Y; w = W; h = H; name = Name; moveTimer = 0;sx = SX; sy = SY;speed = 0; health = 100; dx = 0; dy = 0;life = true; isMove = false;texture.loadFromImage(image);sprite.setTexture(texture);sprite.setOrigin(w / 2, h / 2);}FloatRect getRect(){return FloatRect(sx, sy, w, h);}virtual void update(float time) = 0;//все потомки переопределяют эту ф-цию};class Player :public Entity {public:enum { left, right, stay } state;//добавляем тип перечисления - состояние объектаint playerScore;//эта переменная может быть только у игрокаbool isShoot;Player(Image &image, float X, float Y, int W, int H, String Name, float SX, float SY) :Entity(image, X, Y, W, H, Name, SX, SY){playerScore = isShoot = 0; state = stay;if (name == "Player"){sprite.setTextureRect(IntRect(x, y, w, h));}}void checkCollision(float Dx)//ф ция проверки столкновений с картой{if ((dx < 0) & (sx <= 3)) { sx = 3; state = stay; }if ((dx > 0) & (sx >= 477 - 90)) { sx = 477 - 90; state = stay; }}void control(){if (Keyboard::isKeyPressed){//если нажата клавишаif (Keyboard::isKeyPressed(Keyboard::Left)) { state = left; speed = 0.5; sprite.setTextureRect(IntRect(0, 0, 90, 30)); }//первая координата Х отрицательна =>идём влевоif (Keyboard::isKeyPressed(Keyboard::Right)) { state = right; speed = 0.5; sprite.setTextureRect(IntRect(180, 0, 90, 30)); }if (Keyboard::isKeyPressed(Keyboard::Right) & Keyboard::isKeyPressed(Keyboard::Left)) { state = stay; sprite.setTextureRect(IntRect(90, 0, 90, 30)); } //первая координата Х положительна =>идём вправоif (Keyboard::isKeyPressed(Keyboard::Space)) {isShoot = true;}}else { state = stay;; }}void update(float time) //функция "оживления" объекта класса. update - обновление. принимает в себя время SFML , вследствие чего работает бесконечно, давая персонажу движение.{control();//функция управления персонажемswitch (state)//реализуем поведение в зависимости от направления. (каждая цифра соответствует направлению){case right:dx = speed; break;//состояние идти вправоcase left:dx = -speed; break;//состояние идти влево// case up: break;//будет состояние поднятия наверх (например по лестнице)// case down: dx = 0; break;//будет состояние во время спуска персонажа (например по лестнице)case stay: dx = 0; sprite.setTextureRect(IntRect(x, y, w, h)); break;//и здесь тоже}if (!isMove){ state = stay; }sx += dx*time;checkCollision(dx);//обрабатываем столкновение по Хsprite.setPosition(sx + (w / 2), sy + (h / 2));if (health <= 0){ life = false; }}};class Enemy :public Entity{public:enum { left, right, up, down, stay } state;float way, xmax, xmin;Enemy(Image &image, float X, float Y, int W, int H, String Name, float SX, float SY) :Entity(image, X, Y, W, H, Name, SX, SY){state = right;way = 140;xmin = sx;xmax = sx + way;if (name == "Enemy"){sprite.setTextureRect(IntRect(x, y, w, h));speed = dx = 0.1;//даем скорость.этот объект всегда двигается}}void wayCheck()//ф ция проверки столкновений с картой{if ((dx < 0) & (sx <= xmin)) { state = right; sy += 10; }if ((dx > 0) & (sx >= xmax)) { state = left; sy += 10; }}void update(float time) //функция "оживления" объекта класса. update - обновление. принимает в себя время SFML , вследствие чего работает бесконечно, давая персонажу движение.{wayCheck();switch (state)//реализуем поведение в зависимости от направления. (каждая цифра соответствует направлению){case right:dx = speed; break;//состояние идти вправоcase left:dx = -speed; break;//состояние идти влево}sx += dx*time;sprite.setPosition(sx + (w / 2), sy + (h / 2));if (health <= 0){ life = false; }}};class Bullet :public Entity{//класс пулиpublic://enum { up, down } state;int direction;Bullet(Image &image, float X, float Y, int W, int H, String Name, float SX, float SY, int dir) :Entity(image, X, Y, W, H, Name, SX, SY){//всё так же, только взяли в конце состояние игрока (int dir)//obj = lvl.GetObjects("solid");//инициализируем .получаем нужные объекты для взаимодействия пули с картоx = X; y = Y;sx = SX, sy = SY;direction = dir;//state = up;speed = 1;w = W, h = H;;life = true;//выше инициализация в конструкторе}void update(float time){switch (direction){case 0: dy = -speed; break;//интовое значение state = upcase 1: dy = speed; break;//интовое значение state = down}//state = up;//sx += dx*time;//само движение пули по хsy += dy*time;//по уif ((sy <= 0) | (sy >= 640)) life = false;sprite.setPosition(sx + w / 2, sy + h / 2);//задается позицию пуле}};Вложения:
You must be logged in to view attached files.можно поподробнее про это?
О да, точно. Потерял 😀
Спасибо.
Хм. Если клавишу огня зажать, то будет стрелять бесконечной очередью. Если зажать в движении, то будет стрелять когда меняется направление. Как то не солидно. Надо наверно через определённое время опрашивать нажатость кнопки (чтобы стреляло допустим не чаще раза в секунду). -
АвторСообщения
Просмотр 3 сообщений - с 1 по 3 (из 3 всего)