用sfml(c++)写消消乐游戏(三消)
Posted wangz76
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用sfml(c++)写消消乐游戏(三消)相关的知识,希望对你有一定的参考价值。
程序运行的样子,以下是原程序。
#include <SFML/Graphics.hpp>
#include <time.h>
using namespace std;
int total=0; //总共消了多少棋子,数字显示在标题栏
int ts= 80; //格子大小
sf::Vector2i offset(48,48); //偏差48,24
class piece //棋子对象
{
public:
int x,y; //棋子画图坐标
int col,row; //棋子所在棋盘的行、列
int kind; //棋子类型
int match,alpha; //是否有>3的相同棋子,如有match=1,alpha为透明度,255是不透明
piece(){match=0;alpha=255;}
}grid[10][10];
void swap(piece p1,piece p2) //交换两个棋子在棋盘的行、列
{
std::swap(p1.col,p2.col);
std::swap(p1.row,p2.row);
grid[p1.row][p1.col]=p1; //棋子所在棋盘的行、列调整,但棋子画图坐标未调整。通过程序中移动片段来移动。
grid[p2.row][p2.col]=p2;
}
int main()
{
sf::RenderWindow app(sf::VideoMode(730, 730), "SFML window");
app.setFramerateLimit(60); //设置帧率
for(int i=1;i<=8;i++) //积木初始化
{
for(int j=1;j<=8;j++)
{
grid[i][j].kind=rand()%7;
grid[i][j].col=j;
grid[i][j].row=i;
grid[i][j].x=j*ts;
grid[i][j].y=i*ts;
}
}
int x0,y0,x,y;
int click=0;
sf::Vector2i pos;
bool isSwap=false,isMoving=false; //是否交换,是否移动
while (app.isOpen())
{
sf::Event event;
while (app.pollEvent(event))
{
if (event.type == sf::Event::Closed)
app.close();
if(event.type==sf::Event::MouseButtonPressed)
{
if(event.key.code==sf::Mouse::Left)
{
if(!isSwap && !isMoving ) click++;
pos=sf::Mouse::getPosition(app)-offset;
}
}
}
if(click==1) // 鼠标左击1次,位置计算行、列
{
x0=pos.x/ts+1;
y0=pos.y/ts+1;
}
if(click==2) // 鼠标左击2次,位置计算行、列
{
x=pos.x/ts+1;
y=pos.y/ts+1;
if((abs(x-x0)+abs(y-y0))==1) //判断是否相邻
{
swap(grid[y0][x0],grid[y][x]); //grid[][]相邻积木对调,但未更新x,y画图坐标,所以才有下面判断dx,dy,来调整画图坐标值
isSwap=1;
click=0;
}
else
click=1;
}
for(int i=1;i<=8;i++) //判断相邻积木是否相同,相同match=1
for(int j=1;j<=8;j++)
{
if (grid[i][j].kind==grid[i+1][j].kind)
if (grid[i][j].kind==grid[i-1][j].kind)
for(int n=-1;n<=1;n++) grid[i+n][j].match++;
if (grid[i][j].kind==grid[i][j+1].kind)
if (grid[i][j].kind==grid[i][j-1].kind)
for(int n=-1;n<=1;n++) grid[i][j+n].match++;
}
isMoving=false;
for(int i=1;i<=8;i++)
{
for(int j=1;j<=8;j++)
{
piece &p=grid[i][j];
int dx,dy;
for(int n=0;n<4;n++) //n是速度,4就是每次走4个像素。
{
dx=p.x-p.col*ts; //判断画图坐标和行列计算坐标是否有差异,有差异就调整画图坐标值。
dy=p.y-p.row*ts;
if(dx)
p.x-=dx/abs(dx);
if(dy)
p.y-=dy/abs(dy);
}
if(dx||dy) isMoving=1; //说明处在移动中
}
}
if(!isMoving) //如果移动到位了,不移动了
{
for(int i=1;i<=8;i++)
{
for(int j=1;j<=8;j++)
{
if(grid[i][j].match) //待销积木颜色变浅
{
if(grid[i][j].alpha>10)
{
grid[i][j].alpha-=10;
isMoving=true;
}
}
}
}
}
int score=0;
for (int i=1;i<=8;i++)
for (int j=1;j<=8;j++)
score+=grid[i][j].match; //待销积木统计
if(isSwap && !isMoving) //条件为已交换并且还没有移动,判断一下移动的积木是否三个相同,如不同交换回去。
{
if (!score)
swap(grid[y0][x0],grid[y][x]);
isSwap=0;
}
if(!isMoving) //如果移动到位了,不移动了
{
for (int i=8;i>0;i--) //match=1的积木从下向上移动
for (int j=1;j<=8;j++)
{
if(grid[i][j].match)
{
for(int n=i;n>0;n--)
{
if(!grid[n][j].match)
{
swap(grid[n][j],grid[i][j]);
break;
}
}
}
}
for(int j=1;j<=8;j++) //match=1的积木,变更为新积木,坐标位置放到棋盘外。新积木实际行、列(row,col)未变,通过上面dx,dy移动到(row*54,col*54)处。
for(int i=8,n=0;i>0;i--)
if (grid[i][j].match)
{
grid[i][j].kind = rand()%7; //新图形
grid[i][j].y = -ts*n++; //新y坐标
grid[i][j].match=0;
total++; //统计消灭积木数
grid[i][j].alpha = 255;
}
}
app.clear(); //图形清空
for(int i=1;i<=8;i++) //根据积木对象信息,重新绘制
{
for(int j=1;j<=8;j++)
{
piece p=grid[i][j];
sf::Color color7;
switch(p.kind)
{
case 0:
color7=sf::Color(255,0,0,p.alpha);
break;
case 1:
color7=sf::Color(0,255,0,p.alpha);
break;
case 2:
color7=sf::Color(0,0,255,p.alpha);
break;
case 3:
color7=sf::Color(0,255,255,p.alpha);
break;
case 4:
color7=sf::Color(255,0,255,p.alpha);
break;
case 5:
color7=sf::Color(255,255,0,p.alpha);
break;
case 6:
color7=sf::Color(0,199,140,p.alpha);
break;
}
sf::CircleShape shape(35.f); //画园
shape.setFillColor(color7);
shape.setPosition(p.x-ts+offset.x,p.y-ts+offset.y);
app.setTitle(to_string(total));
app.draw(shape);
}
}
app.display();
}
return EXIT_SUCCESS;
}
以上是关于用sfml(c++)写消消乐游戏(三消)的主要内容,如果未能解决你的问题,请参考以下文章