Созданные ответы форума
-
АвторСообщения
-
Спасибо, тот пример натолкнул меня на светлую мысль.
Получилось как то так:
C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960//trun on / turn off red lightif(event.type == Event::KeyPressed)if((event.key.code == Keyboard::Num1)){switch(status){case true:{glEnable(GL_LIGHT0);status = false;break;}case false:{glDisable(GL_LIGHT0);status = true;break;}}}//trun on / turn off green lightif(event.type == Event::KeyPressed)if((event.key.code == Keyboard::Num2)){switch(status){case true:{glEnable(GL_LIGHT1);status = false;break;}case false:{glDisable(GL_LIGHT1);status = true;break;}}}//trun on / turn off normal(white) lightif(event.type == Event::KeyPressed)if((event.key.code == Keyboard::Num3)){switch(status){case true:{glEnable(GL_LIGHT2);status = false;break;}case false:{glDisable(GL_LIGHT2);status = true;break;}}}проблему решил, написав три войда и сделав шарик и кирпичики глобальными переменными (чтоб их параметры можно было юзать вне int main())
C++12345678910111213141516171819RectangleShape ball, brick1, brick2, brick3, brick4, brick5;void resetBall(){ball.setPosition(640/2, 480/2);}void resetBricks(){brick1.setPosition(40,40);brick2.setPosition(150,40);brick3.setPosition(260,40);brick4.setPosition(370,40);brick5.setPosition(480,40);}void resetGame(){resetBall();resetBricks();}Как это сделать?
Я тут решил добавить возможность рестарта игры, когда ты победил или проиграл, нажимаешь на R и заново, только вот почему то GameState не меняется, хотя и должен.
C++1234567891011121314Event event;while (window.pollEvent(event)){if ( (event.type == Event::Closed) ||((event.type == Event::KeyPressed) && (event.key.code==Keyboard::Escape)) )window.close();else if((event.type == Event::KeyPressed) && (event.key.code==Keyboard::Space) && (gameState == STARTSCREEN))gameState = GAME;else if((event.type == Event::KeyPressed) && (event.key.code==Keyboard::R) && (gameState == GAMEOVER))gameState = GAME;else if((event.type == Event::KeyPressed) && (event.key.code==Keyboard::R) && (gameState == WIN))gameState = GAME;}Да, всё работает. Хочу теперь раскидать всё по хедерам, что посоветуешь?
Вот зацените:
C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311#include <SFML\Graphics.hpp>#include <iostream>using namespace sf; using namespace std;/*AABB-Circle DistanceStep one:Vector dist = B.centre - A.centreStep two:clamp dist to A.extendsif(dist.x >= 0)clamp.x = min(dist.x,extents.x)if(dist.x < 0) clamp.x = max(dist.x,-extents.x)if(dist.y >= 0)clamp.y = min(dist.y,extents.x)if(dist.y < 0) clamp.y = max(dist.y,-extents.x)Step three:Take the differencediff = dist - clampFinal step:Find the distance between A and BDistance = diff.magnitude - B.radius*/void updateBallPhysics();bool intersects (const RectangleShape & rect1,const RectangleShape & rect2){FloatRect r1=rect1.getGlobalBounds();FloatRect r2=rect2.getGlobalBounds();return r1.intersects (r2);}int clamp (const int x, const int a, const int b){return min(max(a,x),b);}bool win();int main(){const int width = 640;const int height= 480;Font font;if(!font.loadFromFile("assets/comic.ttf"))cout << "ERROR" << endl;Texture back;if(!back.loadFromFile("assets/background.jpg"))return -1;Texture redball;if(!redball.loadFromFile("assets/ball.png"))return -1;Sprite background;background.setTexture(back);background.setPosition(0,0);VideoMode videoMode(width, height);ContextSettings antialiasing;antialiasing.antialiasingLevel = 8;RenderWindow window(videoMode,"Rectangle Collision", Style::Default, antialiasing);//wallsRectangleShape top;RectangleShape left;RectangleShape right;RectangleShape bottom;//RectangleShape bottom;//bricksRectangleShape brick1;brick1.setSize(Vector2f(60,12));brick1.setPosition(40,40);brick1.setFillColor(Color(255,255,255,128));brick1.setOutlineColor(Color::Black);brick1.setOutlineThickness(3);RectangleShape brick2;brick2.setSize(Vector2f(60,12));brick2.setPosition(150,40);brick2.setFillColor(Color(255,255,255,128));brick2.setOutlineColor(Color::Black);brick2.setOutlineThickness(3);RectangleShape brick3;brick3.setSize(Vector2f(60,12));brick3.setPosition(260,40);brick3.setFillColor(Color(255,255,255,128));brick3.setOutlineColor(Color::Black);brick3.setOutlineThickness(3);RectangleShape brick4;brick4.setSize(Vector2f(60,12));brick4.setPosition(370,40);brick4.setFillColor(Color(255,255,255,128));brick4.setOutlineColor(Color::Black);brick4.setOutlineThickness(3);RectangleShape brick5;brick5.setSize(Vector2f(60,12));brick5.setPosition(480,40);brick5.setFillColor(Color(255,255,255,128));brick5.setOutlineColor(Color::Black);brick5.setOutlineThickness(3);//paddleRectangleShape paddle;paddle.setPosition(width/2-45, height-50-12);paddle.setSize(Vector2f(90, 12));paddle.setFillColor(Color::Red);paddle.setOutlineColor(Color::Green);paddle.setOutlineThickness(3);//ballRectangleShape ball;ball.setPosition(width/2, height/2);ball.setSize(Vector2f(20,20));//ball.setOutlineColor(Color(255,255,255,128));//ball.setFillColor(Color(255,255,255,128));//ball.setOutlineThickness(1);ball.setTexture(&redball);Vector2<float> ballSpeed(0.15, 0.15);top.setPosition(0, 0);top.setSize(Vector2f(640, 5));top.setFillColor(Color(0,151,255));top.setOutlineColor(Color(0,151,255));top.setFillColor(Color::Yellow);bottom.setPosition(0, 475);bottom.setSize(Vector2f(640, 5));bottom.setFillColor(Color(0,151,255));bottom.setOutlineColor(Color(0,151,255));bottom.setFillColor(Color::Yellow);left.setPosition(0, 0);left.setSize(Vector2f(5, height));left.setFillColor(Color(0,151,255));left.setOutlineColor(Color(0,151,255));left.setFillColor(Color::Yellow);right.setPosition(635,0);right.setSize(Vector2f(5, height));right.setFillColor(Color(0,151,255));right.setOutlineColor(Color(0,151,255));right.setFillColor(Color::Yellow);Text gamename, start, won, lost;gamename.setFont(font);gamename.setString("Arkanoid");gamename.setCharacterSize(48);gamename.setColor(Color::Red);gamename.setPosition(210, 100);//startstart.setFont(font);start.setString("Press SPACE to start");start.setCharacterSize(32);start.setColor(Color::Green);start.setPosition(165, 200);//wonwon.setFont(font);won.setString("You won!");won.setCharacterSize(32);won.setStyle(Text::Bold);won.setColor(Color::Green);won.setPosition(250, 200);//lostlost.setFont(font);lost.setString("Game Over!");lost.setCharacterSize(24);lost.setStyle(Text::Bold);lost.setColor(Color::Red);lost.setPosition(250, 200);//GameStatesenum GameStates {STARTSCREEN, GAME, WIN, GAMEOVER};int gameState = STARTSCREEN;while (window.isOpen()){window.clear(Color::White);switch(gameState){case STARTSCREEN:window.draw(background);window.draw(gamename);window.draw(start);break;case GAME:window.draw(background);window.draw(top);//window.draw(bottom);window.draw(left);window.draw(right);window.draw(brick1);window.draw(brick2);window.draw(brick3);window.draw(brick4);window.draw(brick5);window.draw(paddle);window.draw(ball);break;case WIN:window.draw(background);window.draw(won);break;case GAMEOVER:window.draw(background);window.draw(lost);break;}window.display();Event event;while (window.pollEvent(event)){if ( (event.type == Event::Closed) ||((event.type == Event::KeyPressed) && (event.key.code==Keyboard::Escape)) )window.close();else if((event.type == Event::KeyPressed) && (event.key.code==Keyboard::Space) && (gameState == STARTSCREEN))gameState = GAME;}if(gameState!=GAME)continue;ball.move(ballSpeed.x, ballSpeed.y);//move paddleif(Keyboard::isKeyPressed(Keyboard::Left)){paddle.move(-0.3, 0);}else if (Keyboard::isKeyPressed(Keyboard::Right)){paddle.move(0.3, 0);}//keep paddle inside the windowif (intersects(paddle, left) || intersects(paddle, right)){FloatRect leftWall = left.getGlobalBounds();FloatRect rightWall = right.getGlobalBounds();Vector2f p = paddle.getPosition();p.x = clamp(p.x, leftWall.left + leftWall.width+5, rightWall.left-paddle.getGlobalBounds().width-5);paddle.setPosition(p.x, p.y);}//ball collides with wallsif(intersects(ball, top)){ballSpeed.y = -ballSpeed.y;}if(intersects(ball, left) || intersects(ball, right)){ballSpeed.x = -ballSpeed.x;}//ball collides with paddleif(intersects(ball, paddle)){ballSpeed.y= -ballSpeed.y;}//ball collides with bricksif(intersects(ball, brick1)){FloatRect b1 = brick1.getGlobalBounds();FloatRect bBall = ball.getGlobalBounds();brick1.move(width+1, height+1);ballSpeed.y= -ballSpeed.y;}if(intersects(ball, brick2)){FloatRect b2 = brick2.getGlobalBounds();FloatRect bBall = ball.getGlobalBounds();brick2.move(width+1, height+1);ballSpeed.y= -ballSpeed.y;}if(intersects(ball, brick3)){FloatRect b3 = brick3.getGlobalBounds();FloatRect bBall = ball.getGlobalBounds();brick3.move(width+1, height+1);ballSpeed.y= -ballSpeed.y;}if(intersects(ball, brick4)){FloatRect b4 = brick4.getGlobalBounds();FloatRect bBall = ball.getGlobalBounds();brick4.move(width+1, height+1);ballSpeed.y= -ballSpeed.y;}if(intersects(ball, brick5)){FloatRect b5 = brick5.getGlobalBounds();FloatRect bBall = ball.getGlobalBounds();brick5.move(width+1, height+1);ballSpeed.y= -ballSpeed.y;}//Game wonif(brick1.getPosition().x > width && brick2.getPosition().x > width && brick3.getPosition().x > width && brick4.getPosition().x > width && brick5.getPosition().x > width){gameState = WIN;}//game overif(ball.getPosition().y > 480){gameState = GAMEOVER;}}return EXIT_SUCCESS;}Что я имею ввиду под этим? Вот что:
Таков мой прямоугольник, нарисованный с помощью VertexArray:
C++123456789VertexArray rectangle (Quads, 4);rectangle[0].position = Vector2f(240, 440);rectangle[0].color = Color::Yellow;rectangle[1].position = Vector2f(380,440);rectangle[1].color = Color::Green;rectangle[2].position = Vector2f(380,460);rectangle[2].color = Color::Blue;rectangle[3].position = Vector2f(240,460);rectangle[3].color = Color::Red;Вопрос, можно ли доказать пересечение CircleShape ball(10); где радиус 10, с линией соединяющую rectangle[0] и rectangle[1]???
Вопрос: можно ли двигать фигуру(клавиатурой в функции update), нарисованную с помощью VertexArray?
И если эта фигура прямоугольник, можно ли напиать функцию для пересечения окружности и одной из граней прямоугольника?
Вот здесь наглядно показаны примеры пересечения фигур: Collision Detection in Games
Принцип-то у него совсем другой. Ну да ладно, я уже заставил мячик летать по экрану и отталкиваться от краёв окна.
Осталось теперь сделать отталкивание от прямоугольников.
А вот и код, который я имею, взгляните, может подскажите чего:
C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170#include <SFML\Graphics.hpp>using namespace sf; using namespace std;bool intersects (const RectangleShape & rect1,const RectangleShape & rect2){FloatRect r1=rect1.getGlobalBounds();FloatRect r2=rect2.getGlobalBounds();return r1.intersects (r2);}int clamp (const int x, const int a, const int b){return min(max(a,x),b);}int main(){const int width = 640;const int height= 480;Texture back;if(!back.loadFromFile("background.jpg"))return -1;Sprite background;background.setTexture(back);background.setPosition(0,0);VideoMode videoMode(width, height);ContextSettings antialiasing;antialiasing.antialiasingLevel = 8;RenderWindow window(videoMode,"Rectangle Collision", Style::Default, antialiasing);//wallsRectangleShape top;RectangleShape left;RectangleShape right;//RectangleShape bottom;//bricksRectangleShape brick1;brick1.setSize(Vector2f(60,12));brick1.setPosition(40,40);brick1.setFillColor(Color(255,255,255,128));brick1.setOutlineColor(Color::Black);brick1.setOutlineThickness(3);RectangleShape brick2;brick2.setSize(Vector2f(60,12));brick2.setPosition(150,40);brick2.setFillColor(Color(255,255,255,128));brick2.setOutlineColor(Color::Black);brick2.setOutlineThickness(3);RectangleShape brick3;brick3.setSize(Vector2f(60,12));brick3.setPosition(260,40);brick3.setFillColor(Color(255,255,255,128));brick3.setOutlineColor(Color::Black);brick3.setOutlineThickness(3);RectangleShape brick4;brick4.setSize(Vector2f(60,12));brick4.setPosition(370,40);brick4.setFillColor(Color(255,255,255,128));brick4.setOutlineColor(Color::Black);brick4.setOutlineThickness(3);RectangleShape brick5;brick5.setSize(Vector2f(60,12));brick5.setPosition(480,40);brick5.setFillColor(Color(255,255,255,128));brick5.setOutlineColor(Color::Black);brick5.setOutlineThickness(3);RectangleShape paddle;top.setPosition(0, 0);top.setSize(Vector2f(640, 5));top.setFillColor(Color(0,151,255));top.setOutlineColor(Color(0,151,255));/*bottom.setPosition(0, 475);bottom.setSize(Vector2f(640, 5));bottom.setFillColor(Color(0,151,255));bottom.setOutlineColor(Color(0,151,255));*/left.setPosition(0, 0);left.setSize(Vector2f(5, height));left.setFillColor(Color(0,151,255));left.setOutlineColor(Color(0,151,255));right.setPosition(635,0);right.setSize(Vector2f(5, height));right.setFillColor(Color(0,151,255));right.setOutlineColor(Color(0,151,255));//paddlepaddle.setPosition(width/2-45, height-50-12);paddle.setSize(Vector2f(90, 12));paddle.setFillColor(Color::Red);paddle.setOutlineColor(Color::Green);paddle.setOutlineThickness(3);//ballCircleShape ball(10);ball.setPosition(width/2, height/2);ball.setFillColor(Color(255,255,255,128));ball.setOutlineColor(Color::Yellow);ball.setOutlineThickness(3);Vector2<float> ballSpeed(0.1,0.1);Time deltaTime;Clock clock;while (window.isOpen()){deltaTime = clock.restart();float dtAsSeconds = deltaTime.asSeconds();window.clear(Color::White);window.draw(background);window.draw(top);/*window.draw(bottom);*/window.draw(left);window.draw(right);window.draw(brick1);window.draw(brick2);window.draw(brick3);window.draw(brick4);window.draw(brick5);window.draw(paddle);window.draw(ball);window.display();Event event;while (window.pollEvent(event)){if ( (event.type == Event::Closed) ||((event.type == Event::KeyPressed) && (event.key.code==Keyboard::Escape)) )window.close();}//move paddleif(Keyboard::isKeyPressed(Keyboard::Left)){paddle.move(-5/50.0, 0);}else if (Keyboard::isKeyPressed(Keyboard::Right)){paddle.move(5/50.0, 0);}//keep paddle inside the windowif (intersects(paddle, left) || intersects(paddle, right)){FloatRect l = left.getGlobalBounds();FloatRect r = right.getGlobalBounds();Vector2f p = paddle.getPosition();p.x = clamp(p.x, l.left + l.width+5, r.left-paddle.getGlobalBounds().width-5);paddle.setPosition(p.x, p.y);}}return EXIT_SUCCESS;}Вот примерно так будет выглядеть моя версия. Осталось всё это заставить двигаться.
Вложения:
You must be logged in to view attached files.Твой вариант мне очень нравится, из-за своей хитрожопости, но я хочу использовать как можно более точную реализацию физики столкновений. Без спрайтов =)
Проблема решена. Напомню, в чём она заключалась: программа отказывалась использовать шрифты и выводить текст на экран, выдавая следующую ошибку: SFML (32-bit VS12) – Unhandled exception at 0x701ADEF8 (msvcr110.dll) in SFML.exe: 0xC0000005: Access violation reading location 0x0526. LoadFromFile.
Как оказалось такая хрень возникает из-за путаницы sfml-библиотек в Debug и Release модах. Собственно, чтобы исправить данный касяк нужно в пропертях проекта в Debug указать библиотеки с суффиксом -d, а для релиза оставить без суффикса.
Таким образом, библиотеки дебага выглядят так:
sfml-main-d.lib
sfml-system-d.lib
sfml-graphics-d.lib
sfml-window-d.libИсточник решения проблемы по ссылке здесь.
Update: я заменил все случаи вывода текста на экран с помощью шрифта на вывод текста в консоль через обычный cout, про ведение счёта я не запаривался. Как не трудно догадаться всё работает как часы. Так что подтвердилось, что проблема только с использованием шрифта и выводом текста на экран. в SFML для этого есть Font и Text соответственно, только вот в чём конкретно проблема я не знаю
-
АвторСообщения