C++五子棋(二)——游戏界面与棋子渲染
准备
我们首先要在程序中定义一个名为drawPNG的函数,用于输出png格式图片并使背景透明
- 引入头文件(需要提前安装EasyX)
#include <graphics.h>
- 定义函数 drawPNG
void drawPNG(IMAGE* picture, int picture_x, int picture_y) //x为载入图片的X坐标,y为Y坐标
{
// 变量初始化
DWORD* dst = GetImageBuffer(); // GetImageBuffer()函数,用于获取绘图设备的显存指针,EASYX自带
DWORD* draw = GetImageBuffer();
DWORD* src = GetImageBuffer(picture); //获取picture的显存指针
int picture_width = picture->getwidth(); //获取picture的宽度,EASYX自带
int picture_height = picture->getheight(); //获取picture的高度,EASYX自带
int graphWidth = getwidth(); //获取绘图区的宽度,EASYX自带
int graphHeight = getheight(); //获取绘图区的高度,EASYX自带
int dstX = 0; //在显存里像素的角标
// 实现透明贴图 公式: Cp=αp*FP+(1-αp)*BP , 贝叶斯定理来进行点颜色的概率计算
for (int iy = 0; iy < picture_height; iy++)
{
for (int ix = 0; ix < picture_width; ix++)
{
int srcX = ix + iy * picture_width; //在显存里像素的角标
int sa = ((src[srcX] & 0xff000000) >> 24); //0xAArrggbb;AA是透明度
int sr = ((src[srcX] & 0xff0000) >> 16); //获取RGB里的R
int sg = ((src[srcX] & 0xff00) >> 8); //G
int sb = src[srcX] & 0xff; //B
if (ix >= 0 && ix <= graphWidth && iy >= 0 && iy <= graphHeight && dstX <= graphWidth * graphHeight)
{
dstX = (ix + picture_x) + (iy + picture_y) * graphWidth; //在显存里像素的角标
int dr = ((dst[dstX] & 0xff0000) >> 16);
int dg = ((dst[dstX] & 0xff00) >> 8);
int db = dst[dstX] & 0xff;
draw[dstX] = ((sr * sa / 255 + dr * (255 - sa) / 255) << 16) //公式: Cp=αp*FP+(1-αp)*BP ; αp=sa/255 , FP=sr , BP=dr
| ((sg * sa / 255 + dg * (255 - sa) / 255) << 8) //αp=sa/255 , FP=sg , BP=dg
| (sb * sa / 255 + db * (255 - sa) / 255); //αp=sa/255 , FP=sb , BP=db
}
}
}
}
初始化游戏
创建游戏界面
素材大小
- 通过查看res素材文件夹下的棋盘2.jpg可知,图片大小为897*895
- 通过图片大小计算可得一个格子的大小为67.4
- 先记下这些参数,后面对我们开发特别重要
创建窗口
- 首先,定义 float类型常量 BLOCKSIZE,即格子大小
const float BLOCKSIZE = 67.4;
- 然后定义 init() 如下
void init(){
initgraph(897,895); //创建897*895大小的窗口,与棋盘2.jpg大小对应
loadimage(0,"res/棋盘2.jpg"); //加载图片到窗口
}
加载音乐
- 引入播放音乐的 头文件 mmsystem.h
#include <mmsystem.h>
- 加载库 winmm.lib
#pragma comment(lib,"winmm.lib");
- 继续在 init() 函数中添加播放 提示语音(res/start.wav) 的语句(注意添加位置)
mciSendString("play res/start.wav",0,0,0); //提示下棋语音
棋子渲染
加载素材
- 定义 IMAGE 类型的全局变量 chessWhite 和 chessBlack
IMAGE chessWhite; //黑棋子变量
IMAGE chessBlack; //白棋子变量
- 在 init() 函数定义中添加加载图片语句如下(将black.png白棋子素材和white.png黑棋子素材加载到变量)
//长和宽都是BLOCKSIZE,最后一个true参数表示原比例缩放防止图片被截断
loadimage(&chessBlack, "res/black.png",BLOCKSIZE,BLOCKSIZE,true);
loadimage(&chessWhite, "res/white.png", BLOCKSIZE, BLOCKSIZE, true);
实现渲染
- 定义棋子种类
typedef enum{
CHESS_WHITE = -1,
CHESS_BLACK = 1
} chess_kind_t;
- 在实现输出棋子之前我们需要来看几个数据

- MARGIN_X为上边界大小,MARGIN_Y为左边界大小,因此我们定义同名全局常量
const int MARGIN_X = 44;
const int MARGIN_Y = 43;
const int BOARD_GRAD_SIZE = 13; //13*13棋盘大小
- 之后定义函数 chessDown() 用于打印棋子图片
void chessDown(int row, int col, chess_kind_t kind){
mciSendString("play res/down7.wav",0,0,0); //播放下棋音乐
//EasyX是以窗口左上角为坐标原点
//定义棋子x横坐标
int x = MARGIN_X + col * BLOCKSIZE - 0.5 * BLOCKSIZE;
//定义棋子y纵坐标
int y = MARGIN_Y + row * BLOCKSIZE - 0.5 * BLOCKSIZE;
//判断棋子种类并打印
if(kind == CHESS_WHITE){
drawPNG(&chessWhite,x,y);
}else{
drawPNG(&chessBlack,x,y);
}
}
结束
到了这里,我们已经实现了游戏界面的初始化和棋子渲染了,接下来我们就要实现获取鼠标信息来判断有效点击了
C++五子棋(二)——游戏界面与棋子渲染的更多相关文章
- Solon Web 开发,十二、统一的渲染控制
Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...
- 从壹开始前后端分离 [ Vue2.0+.NetCore2.1] 二十六║Client渲染、Server渲染知多少{补充}
前言 书接上文,昨天简单的说到了 SSR 服务端渲染的相关内容<二十五║初探SSR服务端渲染>,主要说明了相关概念,以及为什么使用等,昨天的一个小栗子因为时间问题,没有好好的给大家铺开来讲 ...
- Qt 2D绘图之二:抗锯齿渲染和坐标系统
一.抗锯齿渲染 1.1 逻辑绘图 图形基元的大小(宽度和高度)始终与其数学模型相对应,下图示意了忽略其渲染时使用的画笔的宽度的样子. 1.2 物理绘图(默认情况) 在默认的情况下,绘制会产生锯齿,并且 ...
- 二、Vue 页面渲染过程
前言 上篇博文我们依葫芦画瓢已经将hello world 展现在界面上啦,但是是不是感觉新虚虚的,总觉得这么多文件,项目怎么就启动起来了呢?怎么访问到8080 端口就能进入到我们的首页呢.整个的流程是 ...
- 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十五║初探SSR服务端渲染(个人博客二)
缘起 时间真快,现在已经是这个系列教程的下半部 Vue 第 12 篇了,昨天我也简单思考了下,可能明天再来一篇,Vue 就基本告一段落了,因为什么呢,这里给大家说个题外话,当时写博文的时候,只是想给大 ...
- html+js+node实现五子棋线上对战,五子棋最简易算法
首先附上我的github地址,https://github.com/jiangzhenfei/five,线上实例:http://47.93.103.19:5900/client/ 线上实例,你可以随意 ...
- Jquery.Qrcode在客户端动态生成二维码并添加自定义Logo
0 Jquery.Qrcode简介 Jquery.Qrcode.js是一个在浏览器端基于Jquery动态生成二维码的插件,支持Canvas和Table两种渲染方式,它的优点是在客户端动态生成,减轻了服 ...
- 离屏渲染学习笔记 /iOS圆角性能问题
离屏渲染学习笔记 一.概念理解 OpenGL中,GPU屏幕渲染有以下两种方式: On-Screen Rendering 意为当前屏幕渲染,指的是GPU的渲染操作是在当前用于显示的屏幕缓冲区中进行. O ...
- [转]浏览器渲染机制——一定要放在body底部的js引用
转自:http://blog.csdn.net/u012251421/article/details/50536265 说明: 本文提到的浏览器均是指Chrome. “script标签“指的都是普通的 ...
随机推荐
- Nebula Graph 在网易游戏业务中的实践
本文首发于 Nebula Graph Community 公众号 当游戏上知识图谱,网易游戏是如何应对大规模图数据的管理问题,Nebula Graph 又是如何帮助网易游戏落地游戏内复杂的图的业务呢? ...
- badusb
badusb介绍 BadUSB是利用伪造HID设备执行攻击载荷的一种攻击方式.HID(Human InterfaceDevice)设备通常指的就是键盘鼠标等与人交互的设备,用户插入BadUSB,就会 ...
- GitHub如何选择合适的license(许可证)
license译为许可证,也可作为开源协议,它可以将自己创作的东西,授权给他人使用,并约定了使用者可以有的权利和必须遵从的义务.现在很多优秀的开源项目都有设置license,不同的license所约束 ...
- manjaro下使用scrcpy安卓设备投屏
scrcpy 安卓版本要大于等于 5.0 安装scrcpy及安卓工具包 yay -S scrcpy-git android-tools 打开手机 开发者模式->USB调试,将手机通过数据线连接电 ...
- HashMap 链表和红黑树的转换
HashMap在jdk1.8之后引入了红黑树的概念,表示若桶中链表元素超过8时,会自动转化成红黑树:若桶中元素小于等于6时,树结构还原成链表形式. 原因: 红黑树的平均查找长度是log(n),长度为8 ...
- MySQL 数据库作发布系统的存储,一天五万条以上的增量, 预计运维三年,怎么优化?
1.设计良好的数据库结构,允许部分数据冗余,尽量避免 join 查询,提高效率. 2.选择合适的表字段数据类型和存储引擎,适当的添加索引. 3.MySQL 库主从读写分离. 4.找规律分表,减少单表中 ...
- MariaDB InnoDB基本介绍
InnoDB锁定模式 事务获取锁,以防止并发事务修改甚至读取某些行或行范围.这样做是为了确保并发写入操作不会冲突. 共享锁(S)和排他锁(X) 两种标准的行级锁是共享锁(S)和排他锁(X) 获取共享锁 ...
- Redis 集群会有写操作丢失吗?为什么?
Redis 并不能保证数据的强一致性,这意味这在实际中集群在特定的条件下可能会丢失写操作.
- Netty学习摘记 —— UDP广播事件
本文参考 本篇文章是对<Netty In Action>一书第十三章"使用UDP广播事件"的学习摘记,主要内容为广播应用程序的开发 消息POJO 我们将日志信息封装成名 ...
- 【动态规划】洛谷P1802 5 倍经验日(01背包问题)
一个洛谷普及-的题目,也是我刚刚入门学习动态规划的练习题. 下面发一下我的思路和代码题解: 我的思路及伪代码: 我的AC图: 接下来上代码: 1 //动态规划 洛谷P1802 五倍经验日 2 #inc ...