C++ 制作FlappyBird

Feb.04 UPDATE:
修复了内存泄漏问题

简介

界面:TUI
界面库: curses.h
git仓库: https://github.com/EricEricEricJin/FlappyBird/tree/master

效果

设计

  • 隔一段距离有一堵墙,墙上开口位置随机
  • 鸟飞,j按键向下移动鸟,k按键向上移动鸟
  • 鸟不可以飞出屏幕外
  • 鸟撞到墙会死
  • 要显示分数

实现

  • 头文件:

    • screen.h
    • map.h
    • mainloop.h
  • 源文件:
    • screen.cpp
    • map.cpp
    • mainloop.cpp
    • main.cpp
  • 编译Makefile
    • Makefile

screen.h

#include <stdio.h>
#include <stdlib.h>
#include <curses.h>#define WALL_PIX 42
#define BIRD_PIX 62class Screen
{public:Screen(int bird_x);void set_bird_y(int *bird_y);int get_width();int get_height();void set_map(int **map, int width, int height);void update(int score);void die();private:int _bird_x;int *_bird_y;int **_map;int _map_w;int _map_h;
};

screen.cpp

#include "screen.h"Screen::Screen(int bird_x)
{_bird_x = bird_x;initscr();cbreak();timeout(0);noecho();
}void Screen::set_bird_y(int *bird_y)
{_bird_y = bird_y;
}void Screen::set_map(int **map, int width, int height)
{_map = map;_map_w = width;_map_h = height;
}void Screen::update(int score)
{clear();for (int row = 0; row < _map_h; row++){for (int col = 0; col < _map_w; col++){if (*(*(_map + row) + col) == 1){move(row, col);addch(WALL_PIX);}}}move(*_bird_y, _bird_x);addch(BIRD_PIX);move(_map_h - 2, _map_w - 6);char score_str[5];sprintf(score_str, "%d", score);addstr(score_str);refresh();
}void Screen::die()
{// printf("HAMA");clear();move(_map_h / 2, _map_w / 2);addstr("DIE");refresh();
}

map.h

#include <stdio.h>
#include <stdlib.h>
#include <ctime>
#include <unistd.h>struct map_struct
{int **_map;int _map_h;int _map_w;
};struct obstacle_struct
{int empty_y_0;int empty_y_1;
};class Map
{public:Map(int height, int width);void setup();void step_fwd();map_struct _map;private:const int obstacle_num = 6;int obstacle_width;const int bird_height = 4;obstacle_struct *_obstacles;int x_shift;int first_obstacle_index;void create_obstacle(obstacle_struct *obstacle);void draw_line(int x, int y_0, int y_1);void clear_map();
};

map.cpp

#include "map.h"int rand_seed = 0;int _random_number(int low_b, int high_b)
{rand_seed += 1;srand(rand_seed);// printf("seed: %d", time(0));int ret = rand() % (high_b - low_b) + low_b;// printf("%d\n", ret);return ret;
}Map::Map(int height, int width)
{_map._map = (int **)malloc(sizeof(int *) * height);for (int i = 0; i < height; i++){*(_map._map + i) = (int *)malloc(sizeof(int) * width);}_map._map_h = height;_map._map_w = width;_obstacles = (obstacle_struct *)malloc(sizeof(obstacle_struct) * 10);obstacle_width = width / obstacle_num;
}void Map::setup()
{clear_map();for (int i = 0; i < obstacle_num; i++){create_obstacle(_obstacles + i);}x_shift = 0;first_obstacle_index = 0;
}void Map::step_fwd()
{clear_map();for (int i = first_obstacle_index; i < first_obstacle_index + obstacle_num; i++){int index = i % obstacle_num;draw_line((i - first_obstacle_index) * obstacle_width + (obstacle_width / 2) - x_shift, (_obstacles + index)->empty_y_0, (_obstacles + index)->empty_y_1);}x_shift += 1;if (x_shift >= obstacle_width){create_obstacle(_obstacles + first_obstacle_index);first_obstacle_index += 1;x_shift = 0;}if (first_obstacle_index >= obstacle_num){first_obstacle_index = 0;}
}void Map::create_obstacle(obstacle_struct *obstacle)
{obstacle->empty_y_0 = _random_number(0, _map._map_h - bird_height);obstacle->empty_y_1 = _random_number(obstacle->empty_y_0 + bird_height, _map._map_h);
}void Map::draw_line(int x, int y_0, int y_1)
{if (x >= 0 and x < _map._map_w){for (int row = 0; row < y_0; row++){*(*(_map._map + row) + x) = 1;}for (int row = y_1; row < _map._map_h; row++){*(*(_map._map + row) + x) = 1;}}
}void Map::clear_map()
{for (int row = 0; row < _map._map_h; row++){for (int col = 0; col < _map._map_w; col++){*(*(_map._map + row) + col) = 0;}}
}

mainloop.h

#include "map.h"
#include "screen.h"
#include <unistd.h>#define KEY_UP 107
#define KEY_DOWN 106#define WIN_W 80
#define WIN_H 24void main_loop();

mainloop.cpp

#include "mainloop.h"void main_loop()
{Map M(WIN_H, WIN_W);Screen S(10);int bird_y;bird_y = WIN_H / 2;S.set_bird_y(&bird_y);S.set_map(M._map._map, M._map._map_w, M._map._map_h);int score = 0;while (true){M.setup();for (int i = 0;; i++){char key = getch();switch (key){case KEY_UP:if (bird_y > 0)bird_y -= 1;break;case KEY_DOWN:if (bird_y < WIN_H - 1)bird_y += 1;break;default:break;}if (i % 100 == 0)M.step_fwd();if (i % 10 == 0)score += 1;S.update(score);if (M._map._map[bird_y][10] == 1)break;usleep(1000);}S.die();sleep(1);// endwin();}
}

main.cpp

#include "mainloop.h"int main()
{main_loop();return 0;
}

编译Makefile

main:g++ main.cpp mainloop.cpp screen.cpp map.cpp -lcurses -o fb.out

C++ 制作FlappyBird相关推荐

  1. 关于制作FlappyBird无限地面的一些问题

    目录 存在的问题 解决问题的过程 最终效果 总结 存在的问题 在跟着老师的教程学习并制作FlappyBird无限地面这一块内容时,一开始还比较顺利,但是当查看效果时我发现了一些问题 我所用的教程是[手 ...

  2. 我的Unity3D学习日记-06(自己动手制作FlappyBird)

    自从上次跟着敲了官方示例拾荒者之后,开始对Unity制作2D游戏感兴趣了起来,虽然本文标题叫做Unity3D学习日记.但是Unity其实本来名字里是没有3D这俩字的--很有名的雨血前传 蜃楼就是一个使 ...

  3. FlappyBird游戏介绍

    FlappyBird游戏介绍 <flappy bird>是一款由来自越南的独立游戏开发者Dong Nguyen所开发的作品,游戏于2013年5月24日上线,并在2014年2月突然暴红.20 ...

  4. 学习日常FlappyBird:正常起飞的阻力

    项目场景: FlappyBird小鸟重新起飞 问题描述 当按照老师教程自行进行制作FlappyBird的起飞时没有做出预想的效果,我做出的小鸟并不是如上图所示的直上直下的飞翔,而是斜着飞的,下落时小鸟 ...

  5. 我在CSDN和Unity有个约会

    如果可以,就当是博主的首篇文章吧 我来自哪里?来CSDN想收获什么? 我的昵称/头像有什么特殊意义吗? 我在技术学习中遇到的最大问题是什么?怎么解决的? 忍不住推荐给朋友们的开源项目 有什么事情想做很 ...

  6. 坚持#第13天~触控培训结束 满载而归

    昨天是2016年8月12日!昨天晚上不小心睡着了,早上来补回来. 啊,今天是培训的最后一天,舍不得走啊!~ 短暂而充实的1个月的时光脚步具体如下: 7-12:对JS一脸懵逼的我 ①完成了小鸟的PDF内 ...

  7. Unity3d制作2D游戏飞翔的小鸟(FlappyBird)

    目录 一.学习方向 二.制作步骤 1.新建项目 3.设置为精灵模式 4.精灵图像分割 5.场景布局设置 6.录制小鸟飞翔动画 7.构建飞翔的小鸟让其响应 8.构建UI对象并让其响应 9.构建游戏背景并 ...

  8. Unity入门之U2D——FlappyBird游戏制作

    首先新建项目,并下载资源 将资源移到Assets文件夹下 将Sprites里的BirdHero的Sprite Mode改为Multiple,因为这是多幅图 点击Sprite Editor,进行图片切割 ...

  9. python3小游戏源代码_Python3制作仿“FlappyBird”小游戏|python3教程|python入门|python教程...

    https://www.xin3721.com/eschool/pythonxin3721/ 本文转载至知乎ID:Charles(白露未晞)知乎个人专栏 下载W3Cschool手机App,0基础随时随 ...

  10. Unity制作2D游戏FlappyBird

    写在前面: 生活就是这样忙忙碌碌,有所期盼的日子真好.感悟一波之后,进入正题. 1.开发前的准备 在Game面板中调节分辨率为9:16 2.通过2D Sprite制作动画,实现物体运动效果 打开Ani ...

最新文章

  1. 【Java 网络编程】Socket TCP UDP 联系
  2. struts深入原理之RequestProcessor与xml
  3. 面试官问:能否模拟实现JS的call和apply方法
  4. 一起学Windows Phone7开发(十三.三 输入控件)
  5. C++多线程编程(3) 异步操作类 std::future std::promise std::async
  6. 2016年10月20日 .NET Core 1.0.2 更新
  7. 书评第001篇:《C++黑客编程揭秘与防范》
  8. 拼多多破1000亿美金,黄峥自述:我的人生经历和创业理念
  9. Matlab之双坐标轴绘制plotyy
  10. SylixOS移植常见问题——编译过多文件导致报错
  11. allegro加泪滴方法
  12. 多准则决策问题评估方法 | 层次分析法(含代码)
  13. pip 查看某个包有哪些版本
  14. java 使用FileAlterationMonitor监控目录中的文件
  15. Git和SourceTree入门教程
  16. 免费数据上新 | CnOpenData中国上市公司信息披露评分数据
  17. 计算机基础应用知识ppt,计算机应用基础【计算机基础知识】课件.ppt
  18. Ubuntu18.04+python3.6+pcl-1.8+opencv3+realsense D415环境搭建
  19. Python程序员:代码写的好,丝滑的壁纸少不了
  20. cocos2d-iphone之魔塔20层第十部分

热门文章

  1. 【架构设计】简单设计原则(Kent Beck)
  2. vb访问服务器文件,VB6打开远程服务器文件
  3. 解决mac备忘录会自动将英文双引号转化为中文双引号
  4. 学习...笔记05:时间,空间,时空傅里叶变换的基本技巧、获取自旋波的频谱图和色散图
  5. html的nofollow、noindex标签
  6. 感知机为什么不能表示“异或”?
  7. QA | R做生存分析如何取最佳cutoff(截断)
  8. 从有状态应用(Session)到无状态应用(JWT),以及 SSO 和 OAuth2
  9. AI吻合度100%,某业余6段棋手吊打围甲7段,疑似AI附体-0
  10. 一张图解释DNS域名服务器的作用