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

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. 解读经典《C#高级编程》第七版 Page50-68.核心C#.Chapter2

    前言 本篇讲述Main方法,控制台,注释,预处理指令,编程规范等.这些概念比较琐碎,为避免长篇大论,主要以列举要点的方式来说明. 01 Main方法 Main方法并不是所有应用类型的入口方法,它只是控 ...

  2. maven安装、配置及创建工程

    准备工作 java开发环境(JDK) maven下载地址:http://maven.apache.org/release-notes-all.html 一.安装 安装maven超级简单,总共分三步: ...

  3. Java编程思想——异常

    1.异常对象的方法printStackTrace 作用是打印Throwable和Throwable的调用栈轨迹. 2.finally 不管抛没抛出异常,都会执行finally中的代码.前提是出异常的代 ...

  4. .net 后台判断是否要替换

    Response.Write("<script>window.onload=function (){if(confirm(\"该文件已经存在,确定要替换吗吗?\&quo ...

  5. Windows 10 安装 Mongod

    因为新换了Windows 10 电脑,需要在新电脑重新安装所有的软件,包括mongodb 下载文件:首先在mongodb的官方网站上下载最新版本的mongodb安装程序,https://www.mon ...

  6. [android] 帧布局

    /*******************2016年5月3日 更新**************************************/ 知乎:如何理解andriod中的View和framela ...

  7. mybatis_ The content of element type association must match (constructor,id,result,ass ociation,collection,discriminator)

    一般遇到这种问题肯定要看一看association中元素编写顺序, <resultMap id="orderRslMap" type="orders"&g ...

  8. 发生服务器错误: Error loading MySQLdb module: libmysqlclient.so.18: cannot open shared object file: No such file or directory

    在hue上配置Mysql的时候,出现的错误:  发生服务器错误: Error loading MySQLdb module: libmysqlclient.so.18: cannot open sha ...

  9. 将Y-m-d转换为Y年m月d日

    自己编写的,不能直接套用,理解后可自行变化: $var=explode(' ',$res['act_starting']); $var1=$var[0];          $time=explode ...

  10. 小程序 lazy-load 不生效的问题

    最近在开发家里喵喵的小程序(娱乐),本想抽一小部分时间做个懒加载.看了小程序官网 API,给 image 标签加上 lazy-load 就能实现懒加载.但从微信开发者工具看,似乎并没有生效.搜了一下, ...