SFML и C++ Уроки \ Разработка игр › Форумы › SFML Graphics › Проблема с взаимодействием с картой. SFML.
В этой теме 7 ответов, 3 участника, последнее обновление Nikit_K 8 года/лет, 7 мес. назад.
-
АвторСообщения
-
Добрый день! Пишу код игры арканоид. Необходимо заставить шарик отскакивать от границ экрана. У меня получилось запустить шарик по оси Х – он летает и отскакивает от боковых стенок. Теперь проблема – Пытаясь запустить шар по оси Y, компилятор выдает ошибку(будет в приложении). Коды( полный и для оси Y) приложу. Объясните, в чем ошибка.
C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174#include <SFML/Graphics.hpp>//#include "Ball.h"using namespace sf;const int H = 16;const int W = 30;float offsetX=0, offsetY=0;String TileMap[H] = {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","B B","B B","B B","B B","B B","B B","B B","B B","B B","B B","B B","B B","B B","B B","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",};class Palka{public:float dx,dy;FloatRect rect;Sprite sprite;Palka(Texture &image){sprite.setTexture(image);rect = FloatRect(40,40,188,50);dx=dy=0;}void update(float time){rect.left += dx*time;Collision(0);Collision(1);sprite.setPosition(rect.left,rect.top);dx=0;}void Collision(int dir){for (int i=rect.top/32; i<(rect.top+rect.height)/32; i++)for (int j=rect.left/32; j<(rect.left+rect.width)/32; j++){if((TileMap[i][j] == 'B')||(TileMap[i][j] == 'C')){if ((dx>0) && (dir==0)) rect.left = j*32 - rect.width;if ((dx<0) && (dir==0)) rect.left = j*32 + 32;if ((dy>0) && (dir==1)) { rect.top = i*32 - rect.height; dy=0; }if ((dy<0) && (dir==1)) { rect.top = i*32 + 32; dy=0;}}}}};class Ball{public:float dx,dy;FloatRect rect;Sprite sprite;void set(Texture &image, int x, int y){sprite.setTexture(image);rect = FloatRect(x,y,82,82);dy=0.0003;}void update(float time){rect.top += dy * time;Collision();sprite.setPosition(rect.left - offsetX,rect.top - offsetY);}void Collision(){for (int i=rect.top/32; i<(rect.top+rect.height)/32; i++)for (int j=rect.left/32; j<(rect.left+rect.width)/32; j++){if((TileMap[i][j] == 'A')){if (dy>0){ /*rect.top = i*16 - rect.height; dy*=-1;*/rect.top = i*32 - 32; dy*=-1;}else if (dy<0){/*rect.top = i*16 + 16; dy*=-1;*/rect.top = i*32 + rect.height; dy*=-1;}}}}};int main(){RenderWindow window( VideoMode(1200, 800), "Test!");Texture t;t.loadFromFile("fang.png");Palka palka(t);Texture l;l.loadFromFile("ball.png");Ball ball;ball.set(l,600,140);Clock clock;RectangleShape rectangle( Vector2f(32,32));while (window.isOpen()){float time = clock.getElapsedTime().asMicroseconds();clock.restart();Event event;while(window.pollEvent(event)){if(event.type == Event::Closed)window.close();}if (Keyboard::isKeyPressed(Keyboard::Left)){palka.dx = -0.0006;}if (Keyboard::isKeyPressed(Keyboard::Right)){palka.dx = 0.0006;}palka.update(time);ball.update(time);window.clear(Color::White);for (int i=0; i<H; i++)for (int j=0; j<W ; j++){if (TileMap[i][j]=='B') rectangle.setFillColor(Color::Black);if (TileMap[i][j]=='A') rectangle.setFillColor(Color::Green);if (TileMap[i][j]==' ') continue;rectangle.setPosition(j*32-offsetX,i*32 - offsetY) ;window.draw(rectangle);}window.draw(palka.sprite);window.draw(ball.sprite);window.display();}return 0;}C++12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849class Ball{public:float dx,dy;FloatRect rect;Sprite sprite;void set(Texture &image, int x, int y){sprite.setTexture(image);rect = FloatRect(x,y,82,32);dx=-0.0003;}void update(float time){rect.left += dx * time;Collision();sprite.setPosition(rect.left - offsetX,rect.top - offsetY);//dx=0.0003;}void Collision(){for (int i=rect.top/32; i<(rect.top+rect.height)/32; i++)for (int j=rect.left/32; j<(rect.left+rect.width)/32; j++){if((TileMap[i][j] == 'B')){if (dx>0){ /*rect.top = i*16 - rect.height; dy*=-1;*/rect.left = j*32 - rect.width; dx*=-1;}else if (dx<0){/*rect.top = i*16 + 16; dy*=-1;*/rect.left = j*32 + 32; dx*=-1;}}}}};Вложения:
You must be logged in to view attached files.Добрый день. Насколько я понял, ты проверяешь столкновение только по Х во время движения
C++12rect.left += dx*time;Collision(0);А тебе надо по Y проверять сразу после движения по Y. Посмотри ф-цию update 20,21 уроков и попробуй сделать подобным образом.
Для движения по Х, да – я проверяю только для движения по горизонтали( rect.left). для движения по вертикали я использую rect.top.
<div id=”crayon-553ccc899b124779723178-85″ class=”crayon-line”>C++1234rect.top += dy * time;Collision();</div>
<div class=”crayon-line crayon-striped-line”>И я допустил ошибку в описании – приложен код полный с Y и отдельно class Ball с пуском по горизонтали</div>Так ты решил свою проблему?
Код вставлял через кнопку вставить код? Что то плагин подсветки кода обновился и косячит.Нет. Сейчас изучаю 20 и 21 уроки, мб что поможет. Как запущу, отпишусь.
Значит переписал код твоего 21 урока под свои цели и вылезла новая ошибка – не инециализирована переменная i в цикле Collision для Ball
C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169#include <SFML/Graphics.hpp>#include "map.h"//#include "Ball.h"using namespace sf;float offsetX=0, offsetY=0;class Entity{public:float dx, dy, x, y, speed,moveTimer;//добавили переменную таймер для будущих целейint w,h;//bool life, isMove, onGround;Texture texture;Sprite sprite;String name;Entity(Image &image, float X,float Y,int W,int H,String Name){x=X; y=Y; w=W; h=H; name = Name; moveTimer = 0;speed = 0; dx=0;dy=0;texture.loadFromImage(image);sprite.setTexture(texture);sprite.setOrigin(w / 2, h / 2);}};class Palka:public Entity{public:enum{left,right,stay} state;Palka(Image &image, float X, float Y,int W,int H,String Name):Entity(image,X,Y,W,H,Name){state=stay;if( name == "Plotik"){sprite.setTextureRect(IntRect(4,19,w,h));}}void control(){if(Keyboard::isKeyPressed){if (Keyboard::isKeyPressed(Keyboard::Left)) {state=left;speed = 0.0006;}if (Keyboard::isKeyPressed(Keyboard::Right)) {state = right; speed = 0.0006;}}}void Collision(float Dx,float Dy){for (int i=y/32; i<(y+h)/32; i++)for (int j=x/32; j<(x+w)/32; j++){if((TileMap[i][j] == 'B')||(TileMap[i][j] == 'C')){if (Dx>0){ x = j * 32 - w; }if (Dx<0){ x = j * 32 + 32; }}}}void update(float time){control();switch (state){case right:dx = speed; break;case left:dx = -speed;break;case stay: break;}x+=dx*time;Collision(dx, 0);sprite.setPosition(x+w/2, y + h / 2);}};class Ball:public Entity{public:Ball(Image &image, float X, float Y,int W,int H,String Name):Entity(image,X,Y,W,H,Name){if(name == "Ball"){sprite.setTextureRect(IntRect(0,0,w,h));dx = 0.0003;}}void Collision(float Dx,float Dy){for(int i;i<(y+h)/32;i++)for(int j;j<(x+w)/32;j++){if(TileMap[i][j] =='B'){if (Dy>0){ y = i * 32 - h; }//по Y вниз=>идем в пол(стоим на месте) или падаем. В этот момент надо вытолкнуть персонажа и поставить его на землю, при этом говорим что мы на земле тем самым снова можем прыгатьif (Dy<0){ y = i * 32 + 32; }//столкновение с верхними краями карты(может и не пригодиться)if (Dx>0){ x = j * 32 - w; dx = -0.1; sprite.scale(-1, 1); }//с правым краем картыif (Dx<0){ x = j * 32 + 32; dx = 0.1; sprite.scale(-1, 1); }// с левым краем карты}}}void update(float time){if(name=="Ball"){Collision(dx,0);x+=dx*time;sprite.setPosition(x + w / 2, y + h / 2);}}};int main(){RenderWindow window( VideoMode(1200, 800), "Test!");Image t;t.loadFromFile("fang.png");Image map_image;map_image.loadFromFile("map.png");Texture map;map.loadFromImage(map_image);Sprite s_map;s_map.setTexture(map);Image l;l.loadFromFile("ball.png");Palka p(t,0, 0,40,30,"Plotik");Ball Ball(l, 600,140,200,97,"Ball");Clock clock;//RectangleShape rectangle( Vector2f(32,32));while (window.isOpen()){float time = clock.getElapsedTime().asMicroseconds();clock.restart();Event event;while(window.pollEvent(event)){if(event.type == Event::Closed)window.close();}p.update(time);Ball.update(time);window.clear(Color::White);for (int i=0; i<H; i++)for (int j=0; j<W ; j++){if (TileMap[i][j]=='B') s_map.setTextureRect(IntRect(0, 0, 32, 32));if (TileMap[i][j]=='A') s_map.setTextureRect(IntRect(64, 0, 32, 32));if (TileMap[i][j]==' ') continue;s_map.setPosition(j*32,i*32) ;window.draw(s_map);}window.draw(p.sprite);window.draw(Ball.sprite);window.display();}return 0;}В твоем цикле переменная i только объявлена но не инициализирована.
void Collision(float Dx,float Dy)
for(int i;i<(y+h)/32;i++)// дай значение переменой i.
for(int j;j<(x+w)/32;j++)// и тут тоже j не известна .Окей, спасибо всем! Вроде как разобрался( сам не понял как, но это, черт возьми, работает!). Шар летает по экрану рикошетит от его стенок =)
-
АвторСообщения
Для ответа в этой теме необходимо авторизоваться.