C++借助curses库实现俄罗斯方块
主要要实现如下几个功能:方块的移动控制、方块变形、判定方块是否接触边界和进行方块堆积、对方块进行消除。
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库实现俄罗斯方块的更多相关文章
- 编程利用利用curses库编程开始
时间紧张,先记一笔,后续优化与完善. curses库常用函数: 注意编译时要用这样的格式:gcc xxx.c -l curses -o xxx 第一个小例子: include <stdio.h& ...
- [C++]基于Curses库的实时系统监测可视化系统-2017-12-09 15-07-42
Congratulations 0.0 技术记录 [1] [C++]Linux之Ubuntu下编译C程序出现错误:“ stray ‘\302'或者'\240' in program”的解决方案 [2 ...
- [C++]Linux之图形界面编程库[curses库]之入门教程
1. 安装 //方法一 sudo apt-get install libncurses5-dev [ ubuntu 16.04:亲测有效] //方法二 sudo apt-get install ncu ...
- python安装curses库
windows系统在安装curses库时,如果直接使用conda或者pip安装,总是失败,到如下网址直接下载.whl文件,然后再用pip安装即可. https://www.lfd.uci.edu/~g ...
- Windows下使用Python的Curses库时 No module named _curses问题
这个问题产生的 根本原因 是 curses 库不支持 windows.所以我们在下载完成python后(python 是自带 curses 库的),虽然在 python目录\Lib 中可以看到 c ...
- curses库--libncurses5-dev--游标移动及屏幕的显示
curses是一个在Linux/Unix下广泛应用的图形函数库.,作用是可以绘制在DOS下的用户界面和漂亮的图形. curses的名字起源于"cursor optimization" ...
- Linux下的Curses库的源码下载与安装
curses库是可以在linux终端中写出字符用户界面的一个库,现在较新的版本应该是ncurses库,现在已经很少有人再去使用他了,所以想拥有这个库并且在linux下写出自己用户界面的可以参考一下本博 ...
- Linux curses库使用
相信您在网路上一定用过如 tin,elm 等工具, 这些软体有项共同的特色, 即他们能利用上下左右等方向键来控制游标的位置. 除此之外, 这些程式的画面也较为美观. 对Programming 有兴趣 ...
- Linux学习笔记13——使用curses函数库
一 安装curses库 如果你的Linux系统中curses库,直接敲入命令sudo apt-get install libncurses5-dev,然后就会自动安装curses库,安装好之后敲入命令 ...
随机推荐
- MySQL中间件之ProxySQL(9):ProxySQL的查询缓存功能
返回ProxySQL系列文章:http://www.cnblogs.com/f-ck-need-u/p/7586194.html ProxySQL支持查询缓存的功能,可以将后端返回的结果集缓存在自己的 ...
- Perl正则表达式引用
正则表达式两篇: 基础正则 Perl正则 本文是对Perl正则的一点扩展,主要内容是使用qr//创建正则对象,以及一些其它的技巧. qr//创建正则对象 因为可以在正则模式中使用变量替换,所以我们可以 ...
- HBase简介及原理
HBase简介 1.HBase是一个万亿行,百万列大表(Big Table),数据存放在hdfs集群中: 写操作使用MapReduce处理,将(增删改)处理结果放入HBase中,读就直接读HBase: ...
- python的一些内置模块
整理了几种python的常用内置模块. 内置函数思维导图:https://www.processon.com/view/link/5c7902b1e4b0168e4200846a re模块 re(re ...
- AngularJs_自定义注入对象_笔记1
A-自定义控件示例: 我的自定义控件文件为:angular-seagull2-common.js (function (window, angular) { 'use strict'; $urlPro ...
- asp.net-缓存技术-20180409
asp.net缓存技术有三种 1.页面输出缓存 2.页面部分缓存 3.页面数据缓存 ---------------------------------------------------------- ...
- PHP程序员解决问题的能力
这个话题老生长谈了,在面试中必然考核的能力中,我个人认为解决问题能力是排第一位的,比学习能力优先级更高.解决问题的能力既能看出程序员的思维能力,应变能力,探索能力等,又可以看出他的经验.如果解决问题能 ...
- 定时任务Task
使用注解@EnableScheduling开启定时任务,会自动扫描 定义@Component作为组件被容器扫描 对于EnableScheduling是注解在启动类上,很多开关配置都会再启动类中进行设置 ...
- linux /mac 下 go环境变量配置
安装了go语言之后,还要设置路径,如果不设置路径,则执行 go 的时候会提示 go: command not found,提示的意思是没有这个命令行.这个是因为还没有设置PATH路径. 设置路径的方式 ...
- EF中更新操作 ID自增但不是主键 ;根据ViewModel更新实体的部分属性
//ID自增但不是主键的情况 public int Update_join<TEntity>(TEntity entity) where TEntity : class { dbconte ...