1、准备游戏需要的背景图片
//shader.frag uniform vec2 frag_LightOrigin; uniform vec3 frag_LightColor; uniform float frag_LightAttenuation; uniform vec2 frag_ScreenResolution; uniform sampler2D texture; void main() { vec2 baseDistance = gl_FragCoord.xy; baseDistance.y = frag_ScreenResolution.y-baseDistance.y; float d = length(frag_LightOrigin - baseDistance); float a = 1.0/(frag_LightAttenuation * d); vec4 color = vec4(a,a,a,1.0) * vec4(frag_LightColor, 1.0); vec4 t = texture2D(texture, gl_TexCoord[0].xy); if (t[0]>color[0]) color[0]=t[0]; if (t[1]>color[1]) color[1]=t[1]; if (t[2]>color[2]) color[2]=t[2]; gl_FragColor=color; }
2、绘制一个600x400的屏幕
#include<SFML/Graphics.hpp>
#include<time.h>
using namespace sf;
const int W = 600;
const int H = 400;
int speed = 4;
bool field[W][H] = { 0 };
struct player
{
int x;
int y;
int dir;
Color color;
player(Color c)
{
x = rand() % W;
y = rand() % H;
color = c;
dir = rand() % 4;
}
void tick()
{
if (dir == 0)
{
y += 1;
}
if (dir == 1)
{
x -= 1;
}
if (dir == 2)
{
x += 1;
}
if (dir == 3)
{
y -= 1;
}
}
Vector3f getColor()
{
return Vector3f(color.r, color.g, color.b);
}
};
int main()
{
srand(time(0));
RenderWindow window(VideoMode(W, H), "The Tron Game!");
window.setFramerateLimit(60);
Texture texture;
texture.loadFromFile("./Resources/images/background.jpg");
Sprite sBackground(texture);
player p1(Color::Red);
player p2(Color::Green);
Sprite sprite;
RenderTexture t;
t.create(W, H);
t.setSmooth(true);
sprite.setTexture(t.getTexture());
t.clear();
t.draw(sBackground);
bool Game = 1;
while (window.isOpen())
{
Event e;
while (window.pollEvent(e))
{
if (e.type == Event::Closed)
{
window.close();
}
}
if (Keyboard::isKeyPressed(Keyboard::Left))
{
if (p1.dir != 2)
{
p1.dir = 1;
}
}
if (Keyboard::isKeyPressed(Keyboard::Right))
{
if (p1.dir != 1)
{
p1.dir = 2;
}
}
if (Keyboard::isKeyPressed(Keyboard::Up))
{
if (p1.dir != 0)
{
p1.dir = 3;
}
}
if (Keyboard::isKeyPressed(Keyboard::Down))
{
if (p1.dir != 3)
{
p1.dir = 0;
}
}
if (Keyboard::isKeyPressed(Keyboard::A))
{
if (p2.dir != 2)
{
p2.dir = 1;
}
}
if (Keyboard::isKeyPressed(Keyboard::D))
{
if (p2.dir != 1)
{
p2.dir = 2;
}
}
if (Keyboard::isKeyPressed(Keyboard::W))
{
if (p2.dir != 0)
{
p2.dir = 3;
}
}
if (Keyboard::isKeyPressed(Keyboard::S))
{
if (p2.dir != 3)
{
p2.dir = 0;
}
}
if (!Game)
{
continue;
}
for (int i = 0; i < speed; i++)
{
p1.tick();
p2.tick();
if (field[p1.x][p1.y] == 1)
{
Game = 0;
}
if (field[p2.x][p2.y] == 1)
{
Game = 0;
}
field[p1.x][p1.y] = 1;
field[p2.x][p2.y] = 1;
CircleShape c(3);
c.setPosition(p1.x, p2.y);
c.setFillColor(p1.color);
t.draw(c);
c.setPosition(p2.x, p2.y);
c.setFillColor(p2.color);
t.draw(c);
t.display();
}
//draw
window.clear();
window.draw(sprite);
window.display();
}
return 0;
}
效果图:
3、添加文字:
#include<SFML/Graphics.hpp>
#include<time.h>
using namespace sf;
const int W = 600;
const int H = 400;
int speed = 4;
bool field[W][H] = { 0 };
struct player
{
int x;
int y;
int dir;
Color color;
player(Color c)
{
x = rand() % W;
y = rand() % H;
color = c;
dir = rand() % 4;
}
void tick()
{
if (dir == 0)
{
y += 1;
}
if (dir == 1)
{
x -= 1;
}
if (dir == 2)
{
x += 1;
}
if (dir == 3)
{
y -= 1;
}
if (x >= W)
{
x = 0;
}
if (x < 0)
{
x = W - 1;
}
if (y >= H)
{
y = 0;
}
if (y < 0)
{
y = H - 1;
}
}
Vector3f getColor()
{
return Vector3f(color.r, color.g, color.b);
}
};
int main()
{
srand(time(0));
RenderWindow window(VideoMode(W, H), "The Tron Game!");
window.setFramerateLimit(60);
Texture texture;
texture.loadFromFile("./Resources/images/background.jpg");
Sprite sBackground(texture);
player p1(Color::Red);
player p2(Color::Green);
Sprite sprite;
RenderTexture t;
t.create(W, H);
t.setSmooth(true);
sprite.setTexture(t.getTexture());
t.clear();
t.draw(sBackground);
Font font;
font.loadFromFile("./Resources/font/arial.ttf");
Text text("YOU WIN!", font, 35);
text.setPosition(W / 2 - 80, 20);
bool Game = 1;
while (window.isOpen())
{
Event e;
while (window.pollEvent(e))
{
if (e.type == Event::Closed)
{
window.close();
}
}
if (Keyboard::isKeyPressed(Keyboard::Left))
{
if (p1.dir != 2)
{
p1.dir = 1;
}
}
if (Keyboard::isKeyPressed(Keyboard::Right))
{
if (p1.dir != 1)
{
p1.dir = 2;
}
}
if (Keyboard::isKeyPressed(Keyboard::Up))
{
if (p1.dir != 0)
{
p1.dir = 3;
}
}
if (Keyboard::isKeyPressed(Keyboard::Down))
{
if (p1.dir != 3)
{
p1.dir = 0;
}
}
if (Keyboard::isKeyPressed(Keyboard::A))
{
if (p2.dir != 2)
{
p2.dir = 1;
}
}
if (Keyboard::isKeyPressed(Keyboard::D))
{
if (p2.dir != 1)
{
p2.dir = 2;
}
}
if (Keyboard::isKeyPressed(Keyboard::W))
{
if (p2.dir != 0)
{
p2.dir = 3;
}
}
if (Keyboard::isKeyPressed(Keyboard::S))
{
if (p2.dir != 3)
{
p2.dir = 0;
}
}
if (!Game)
{
window.draw(text);
window.display();
continue;
}
for (int i = 0; i < speed; i++)
{
p1.tick();
p2.tick();
if (field[p1.x][p1.y] == 1)
{
Game = 0;
text.setColor(p2.color);
}
if (field[p2.x][p2.y] == 1)
{
Game = 0;
text.setColor(p1.color);
}
field[p1.x][p1.y] = 1;
field[p2.x][p2.y] = 1;
CircleShape c(3);
c.setPosition(p1.x, p2.y);
c.setFillColor(p1.color);
t.draw(c);
c.setPosition(p2.x, p2.y);
c.setFillColor(p2.color);
t.draw(c);
t.display();
}
//draw
window.clear();
window.draw(sprite);
window.display();
}
return 0;
}
效果图:
4、添加着色器完善游戏逻辑
#include<SFML/Graphics.hpp>
#include<time.h>
using namespace sf;
const int W = 600;
const int H = 400;
int speed = 4;
bool field[W][H] = { 0 };
struct player
{
int x;
int y;
int dir;
Color color;
player(Color c)
{
x = rand() % W;
y = rand() % H;
color = c;
dir = rand() % 4;
}
void tick()
{
if (dir == 0)
{
y += 1;
}
if (dir == 1)
{
x -= 1;
}
if (dir == 2)
{
x += 1;
}
if (dir == 3)
{
y -= 1;
}
if (x >= W)
{
x = 0;
}
if (x < 0)
{
x = W - 1;
}
if (y >= H)
{
y = 0;
}
if (y < 0)
{
y = H - 1;
}
}
Vector3f getColor()
{
return Vector3f(color.r, color.g, color.b);
}
};
int main()
{
srand(time(0));
RenderWindow window(VideoMode(W, H), "The Tron Game!");
window.setFramerateLimit(60);
Texture texture;
texture.loadFromFile("./Resources/images/background.jpg");
Sprite sBackground(texture);
player p1(Color::Red);
player p2(Color::Green);
Sprite sprite;
RenderTexture t;
t.create(W, H);
t.setSmooth(true);
sprite.setTexture(t.getTexture());
t.clear();
t.draw(sBackground);
Font font;
font.loadFromFile("./Resources/font/arial.ttf");
Text text("YOU WIN!", font, 35);
text.setPosition(W / 2 - 80, 20);
Shader *shader = new Shader;
shader->loadFromFile("./Resources/files/shader.frag", Shader::Fragment);
shader->setParameter("frag_ScreenResolution", Vector2f(W, H));
shader->setParameter("frag_LightAttenuation", 100);
RenderStates states;
states.shader = shader;
bool Game = 1;
while (window.isOpen())
{
Event e;
while (window.pollEvent(e))
{
if (e.type == Event::Closed)
{
window.close();
}
}
if (Keyboard::isKeyPressed(Keyboard::Left))
{
if (p1.dir != 2)
{
p1.dir = 1;
}
}
if (Keyboard::isKeyPressed(Keyboard::Right))
{
if (p1.dir != 1)
{
p1.dir = 2;
}
}
if (Keyboard::isKeyPressed(Keyboard::Up))
{
if (p1.dir != 0)
{
p1.dir = 3;
}
}
if (Keyboard::isKeyPressed(Keyboard::Down))
{
if (p1.dir != 3)
{
p1.dir = 0;
}
}
if (Keyboard::isKeyPressed(Keyboard::A))
{
if (p2.dir != 2)
{
p2.dir = 1;
}
}
if (Keyboard::isKeyPressed(Keyboard::D))
{
if (p2.dir != 1)
{
p2.dir = 2;
}
}
if (Keyboard::isKeyPressed(Keyboard::W))
{
if (p2.dir != 0)
{
p2.dir = 3;
}
}
if (Keyboard::isKeyPressed(Keyboard::S))
{
if (p2.dir != 3)
{
p2.dir = 0;
}
}
if (!Game)
{
window.draw(text);
window.display();
continue;
}
for (int i = 0; i < speed; i++)
{
p1.tick();
p2.tick();
if (field[p1.x][p1.y] == 1)
{
Game = 0;
text.setColor(p2.color);
}
if (field[p2.x][p2.y] == 1)
{
Game = 0;
text.setColor(p1.color);
}
field[p1.x][p1.y] = 1;
field[p2.x][p2.y] = 1;
t.display();
shader->setParameter("frag_LightOrigin", Vector2f(p1.x, p1.y));
shader->setParameter("frag_LightColor", p1.getColor());
t.draw(sprite, states);
shader->setParameter("frag_LightOrigin", Vector2f(p2.x, p2.y));
shader->setParameter("frag_LightColor", p2.getColor());
t.draw(sprite, states);
}
//draw
window.clear();
window.draw(sprite);
window.display();
}
return 0;
}
结果图:
PS:如果出现关于setColor的错误:Project Properties > Configuration Properties > C/C++ > General > SDL checks选否