主要要实现如下几个功能:方块的移动控制、方块变形、判定方块是否接触边界和进行方块堆积、对方块进行消除。

1.方块的移动控制
上下左右四个方向
上-->变形,下-->加速下落,左-->向左移动,右-->向右移动
注意在移动的时候,还要判定是否接触边界,特别是向下移动,除了需要确定是否接触底部边界外,还要注意是否发生方块堆积。

 void Piece::show(){
fd_set set;
FD_ZERO(&set);
FD_SET(, &set);
struct timeval timeout;
timeout.tv_sec = ;
timeout.tv_usec= ;
if (select(, &set, NULL, NULL, &timeout) == ){
//mvwprintw(game_win,21,20,"+");
pos_x++;
if(reachBottom()){
pos_x--;
int x=;
for(int i=;i<shape_x;i++){
for(int j=;j<shape_y;j++){
if(shape[i][j]==){
map[pos_x+i+][pos_y+j+]=;
mvwaddch(game_win,pos_x+i+,pos_y+j+,'#');
}
}
}
pos_x=;
srand((int)time());
pos_y=rand()%(map_y-);
while(pos_y==){
pos_y=rand()%(map_y-);
}
next_shape_id=rand()%;
//shape_id=3;
nextShape();
wrefresh(game_win);
int flag=;
int lines=;
if(flag==){
for(int i=map_x-;i>=;i--){
while(fullLine(i)){
lines++;
int k=i-;
while(fullLine(k)){
k--;
lines++;
}
for(int j=;j<(map_y-);j++){
map[k+][j+]=;
mvwaddch(game_win,k+,j+,' ');
}
int kk=k+;
for(;kk>=;kk--){
for(int jj=;jj<(map_y-);jj++){
if(map[kk][jj+]==){
map[kk+][jj+]=;
mvwaddch(game_win,kk+,jj+,'#');
}else{
map[kk+][jj+]=;
mvwaddch(game_win,kk+,jj+,' ');
}
}
}
score+=(lines*);
std::string tempS;
std::ostringstream ex_msg;
ex_msg<<"score: "<<score;
tempS=ex_msg.str();
mvwprintw(score_win,,,tempS.c_str());
wrefresh(score_win);
//mvwaddch(game_win,k+1,j,' ');
wrefresh(game_win);
}
}
}
}else{
//mvwprintw(game_win,21,20,"-");
for(int i=;i>=;i--){
for(int j=;j>=;j--){
if(shape[i][j]==){
int x=;
mvwaddch(game_win,pos_x+i,pos_y++j,' ');
mvwaddch(game_win,pos_x+i+,pos_y++j,'#');
}
}
}
wrefresh(game_win);
}
}
if(FD_ISSET(,&set)){
while((key=getch())==-); if(key==KEY_RIGHT){
//clearShape();
pos_y++;
if(reachBottom()){
pos_y--;
}else{
for(int i=;i<=;i++){
for(int j=;j>=;j--){
if(shape[i][j]==){
//列上的移动
mvwaddch(game_win,pos_x+i+,pos_y+j,' ');
mvwaddch(game_win,pos_x+i+,pos_y+j+,'#');
}
}
}
wrefresh(game_win);
}
} if(key==KEY_LEFT){
//clearShape();
pos_y--;
if(reachBottom()){
pos_y++;
}else{
for(int i=;i<=;i++){
for(int j=;j<=;j++){
if(shape[i][j]==){
//列上的移动
mvwaddch(game_win,pos_x+i+,pos_y+j+,' ');
mvwaddch(game_win,pos_x+i+,pos_y+j+,'#');
}
}
}
wrefresh(game_win);
}
} if(key==KEY_UP){
changeShape();
}
if(key==KEY_DOWN){
pos_x++;
if(reachBottom()){
pos_x--;
}else{
for(int i=;i>=;i--){
for(int j=;j>=;j--){
if(shape[i][j]==){
int x=;
mvwaddch(game_win,pos_x+i,pos_y++j,' ');
mvwaddch(game_win,pos_x+i+,pos_y++j,'#');
}
}
}
wrefresh(game_win);
}
}
}
}

2.方块变形
做法很简单,首先,4x4整体按左右对称,再交换方块实际长和宽的值,在实际的长和宽这个范围内再进行左右对称。
同样这里要注意是否发生了越界和方块堆积,如果发生了,就恢复原形状。

 void Piece::changeShape(){
int temp[][]={};
int temp1[][]={};
int temp2[][]={};
for(int i=;i<;i++){
for(int j=;j<;j++){
temp[j][i]=shape[i][j];
temp2[i][j]=shape[i][j];//保存shape数组
}
}
for(int i=;i<;i++){
for(int j=;j<;j++)
shape[i][j]=;
}
int temp3=shape_x;
shape_x=shape_y;
shape_y=temp3;
for(int i=;i<shape_x;i++){
for(int j=;j<shape_y;j++){
temp1[i][shape_y--j]=temp[i][j];
}
}
for(int i=;i<;i++){
for(int j=;j<;j++)
shape[i][j]=temp1[i][j];
}
if(reachBottom()){
for(int i=;i<;i++){
for(int j=;j<;j++)
shape[i][j]=temp2[i][j];
}
int temp3=shape_x;
shape_x=shape_y;
shape_y=temp3;
}else{
for(int i=;i<;i++){
for(int j=;j<;j++){
if(temp2[i][j]==){
mvwaddch(game_win,pos_x+i+,pos_y++j,' ');
}
}
}
wrefresh(game_win);
for(int i=;i>=;i--){
for(int j=;j>=;j--){
if(shape[i][j]==){
mvwaddch(game_win,pos_x+i+,pos_y++j,'#');
wrefresh(game_win);
}
}
}
}
}

3.判定方块是否接触边界和进行方块堆积
这里主要是要考虑到,左右上下类似装饰条的行。方块堆积就是判定下一行方块要占据的位置是否已经有其他方块占据了。

 bool Piece::reachBottom(){
for(int i=;i<shape_x;i++){
for(int j=;j<shape_y;j++){
if(shape[i][j]==){
if(pos_x+i>(map_x-)){
return true;
}
if(pos_y+j>(map_y-)||pos_y+j<){
return true;
}
if(map[pos_x+i+][pos_y+j+]==){
return true;
}
}
}
}
return false;
}

4.对方块进行消除
从最后一行放置方块的行号开始,依次判定此行是否需要消除,消除后还要继续判定本行的情况(应对连续消除多行的情况)。

 for(int i=map_x-;i>=;i--){
while(fullLine(i)){
lines++;
int k=i-;
while(fullLine(k)){
k--;
lines++;
}
for(int j=;j<(map_y-);j++){
map[k+][j+]=;
mvwaddch(game_win,k+,j+,' ');
}
int kk=k+;
for(;kk>=;kk--){
for(int jj=;jj<(map_y-);jj++){
if(map[kk][jj+]==){
map[kk+][jj+]=;
mvwaddch(game_win,kk+,jj+,'#');
}else{
map[kk+][jj+]=;
mvwaddch(game_win,kk+,jj+,' ');
}
}
}
score+=(lines*);
std::string tempS;
std::ostringstream ex_msg;
ex_msg<<"score: "<<score;
tempS=ex_msg.str();
mvwprintw(score_win,,,tempS.c_str());
wrefresh(score_win);
//mvwaddch(game_win,k+1,j,' ');
wrefresh(game_win);
}
}

完整代码:https://github.com/JsonZhangAA/shiyanlou/tree/master/C%2B%2B_%E4%BF%84%E7%BD%97%E6%96%AF%E6%96%B9%E5%9D%97

C++借助curses库实现俄罗斯方块的更多相关文章

  1. 编程利用利用curses库编程开始

    时间紧张,先记一笔,后续优化与完善. curses库常用函数: 注意编译时要用这样的格式:gcc xxx.c -l curses -o xxx 第一个小例子: include <stdio.h& ...

  2. [C++]基于Curses库的实时系统监测可视化系统-2017-12-09 15-07-42

    Congratulations 0.0 技术记录 [1]  [C++]Linux之Ubuntu下编译C程序出现错误:“ stray ‘\302'或者'\240' in program”的解决方案 [2 ...

  3. [C++]Linux之图形界面编程库[curses库]之入门教程

    1. 安装 //方法一 sudo apt-get install libncurses5-dev [ ubuntu 16.04:亲测有效] //方法二 sudo apt-get install ncu ...

  4. python安装curses库

    windows系统在安装curses库时,如果直接使用conda或者pip安装,总是失败,到如下网址直接下载.whl文件,然后再用pip安装即可. https://www.lfd.uci.edu/~g ...

  5. Windows下使用Python的Curses库时 No module named _curses问题

    这个问题产生的 根本原因 是 curses 库不支持 windows.所以我们在下载完成python后(python 是自带 curses 库的),虽然在  python目录\Lib  中可以看到 c ...

  6. curses库--libncurses5-dev--游标移动及屏幕的显示

    curses是一个在Linux/Unix下广泛应用的图形函数库.,作用是可以绘制在DOS下的用户界面和漂亮的图形. curses的名字起源于"cursor optimization" ...

  7. Linux下的Curses库的源码下载与安装

    curses库是可以在linux终端中写出字符用户界面的一个库,现在较新的版本应该是ncurses库,现在已经很少有人再去使用他了,所以想拥有这个库并且在linux下写出自己用户界面的可以参考一下本博 ...

  8. Linux curses库使用

     相信您在网路上一定用过如 tin,elm 等工具, 这些软体有项共同的特色, 即他们能利用上下左右等方向键来控制游标的位置. 除此之外, 这些程式的画面也较为美观. 对Programming 有兴趣 ...

  9. Linux学习笔记13——使用curses函数库

    一 安装curses库 如果你的Linux系统中curses库,直接敲入命令sudo apt-get install libncurses5-dev,然后就会自动安装curses库,安装好之后敲入命令 ...

随机推荐

  1. 如何快速使用Access实现一个登录验证界面?

    大三上学期期末总结,嗯,没错,上学期,写在新学期开始,hhhh. 上学期末的时候信管班的一个同学问我会不会Access,能不能它实现一个登录验证界面,说实话,之前对Access只是有所耳闻,随便敷衍了 ...

  2. vue_drf之多级过滤、排序、分页

    一.前端代码 1,父组件free_course.vue <template> <div id="free_course"> <el-container ...

  3. Linux中安装Oracle11g后出现监听的问题及解决办法

    软件安装: 参考文章: linux安装Oracle11G 错误如下: [oracle@iz2f570bi1k56uz admin]$ lsnrctl start LSNRCTL for Linux: ...

  4. 特征脸是怎么提取的之主成分分析法PCA

    机器学习笔记 多项式回归这一篇中,我们讲到了如何构造新的特征,相当于对样本数据进行升维. 那么相应的,我们肯定有数据的降维.那么现在思考两个问题 为什么需要降维 为什么可以降维 第一个问题很好理解,假 ...

  5. ElasticSearch集群环境搭建

    一 .单机部署 1.下载安装包.解压 2.在window下运行bin/elasticsearch.bat 3.访问localhost:9200 页面显示结果 { "name" : ...

  6. AFNetworking封装-项目使用

    本篇博客是接着上一篇AFNetworking源码解析的后续,如果想对AFNetworking源码有所了解. 请读一下https://www.cnblogs.com/guohai-stronger/p/ ...

  7. IdentityServer4 中文文档 -11- (快速入门)添加基于 OpenID Connect 的用户认证

    IdentityServer4 中文文档 -11- (快速入门)添加基于 OpenID Connect 的用户认证 原文:http://docs.identityserver.io/en/releas ...

  8. input type=file 上传文件样式美化(转载)

    input type=file 上传文件样式美化 来源:https://www.jianshu.com/p/6390595e5a36 在做input文本上传时,由于html原生的上传按钮比较丑,需要对 ...

  9. ORA-00959: tablespace 'PSAPTEMP' does not exist

    错误 : ORA-00959: tablespace 'PSAPTEMP' does not exist 解决办法: CREATE TEMPORARY TABLESPACE PSAPTEMP  TEM ...

  10. 8.异常_EJ

    第57条: 只针对异常情况才使用异常 异常是为了在异常情况下使用而设计的,不要将它们用于普通的控制流,也不要编写迫使它们这么做的API. 第58条: 对可恢复的情况使用受检异常,对编程错误使用运行时异 ...