【c语言小项目】基于easyX的俄罗斯方块

news2024/11/26 0:59:52

EeayX是针对 C/C++ 的简单图形库插件,本项目基于easyX游戏框架下实现俄罗斯方块游戏。 

俄罗斯方块功能实现中主要运用了二维数组的循环遍历。能够实现基本功能,暂未实现旋转

c语言系列专栏:c语言之路重点知识整合  

更多相关:c语言贪吃蛇游戏

创作不易,本篇文章如果帮助到了你,还请点赞支持一下♡>𖥦<)!! 

主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步!

给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ

目录

运行结果:

代码: 

main.cpp

game_function.cpp 

date_type.h

 game_function.h

global_var.h

图片文件:

EasyX游戏框架:


 运行结果:

代码: 

main.cpp

#define _CRT_SECURE_NO_WARNINGS 1
#include <easyx.h>
#include <time.h>
#include <conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<string>
#include<graphics.h>
#include "game_function.h"
/*游戏界面绘制*/
void gamePaint();
/*游戏初始化绘制*/
void gameInit();
/*游戏定时处理*/
void gameInterval();
/*游戏键盘按下*/
void gameKeypress(int key);
/*游戏鼠标按下*/
void gameMouseDown(int mouseX, int mouseY);
/*游戏鼠标右键按下*/
void gameMouseRightDown(int mouseX, int mouseY);
/*游戏鼠标抬起*/
void gameMouseUp(int mouseX, int mouseY);
/*游戏鼠标移动*/
void gameMousemove(int mouseX, int mouseY);

/*
含透明的图的绘制
x为要载入图片的X坐标,y为Y坐标
*/
void drawImage(int  picture_x, int picture_y, IMAGE* picture);
/*调整图片透明度
  角度转弧度:PI/180*角度
  弧度转角度:180/PI*弧度
*/
void drawImageAlpha(int x0, int y0, IMAGE* img, double f);
/*两个矩形碰撞检测
即两个矩形是否相交。
 x1, y1, w1, h1是第一个矩形的xy宽高的四个参数
 x2, y2, w2, h2是第二个矩形的xy宽高的四个参数
 返回0代表不相交 返回1代表相交
*/
int testHit(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2);

/*设置100即每隔100毫秒刷新以下界面绘图。*/
int interval = 100;//TODO: 1 设置定时器时间间隔(单位毫秒)
// TODO: 1 设置窗口: 宽度 高度
int screenWidth = 470;
int screenHeight = 616;
int stop = 0;//是否停止游戏
//-----------------------------------//
int times = 0;
/*初始化游戏 */
void initgame()
{
	srand((unsigned)time(NULL));//随机数初始化
	setbkcolor(NULL);//背景色
	setbkmode(TRANSPARENT);// 设置背景混合模式: TRANSPARENT为透明
	gameInit();
}
/*
	界面绘图演示案例
*/


/*绘制显示游戏界面*/
void paint()
{
	BeginBatchDraw();//打开双缓冲
	cleardevice();// 清屏

	gamePaint();
	//-----------------------------//
	EndBatchDraw();//关闭双缓冲
}



/*游戏运行*/
void run()
{
	ExMessage msg;
	//ExMessage key;
	while (1)	// 游戏主循环  可借助break 结束循环
	{
		if (peekmessage(&msg, -1, true))
		{
			switch (msg.message)
			{
			case WM_MOUSEMOVE://鼠标移动
				gameMousemove(msg.x, msg.y);
				break;
			case WM_LBUTTONDOWN://左键按下
				gameMouseDown(msg.x, msg.y);
				break;
			case WM_LBUTTONUP://左键抬起
				gameMouseUp(msg.x, msg.y);
				break;
			case WM_LBUTTONDBLCLK://左键双击

				break;
			case WM_RBUTTONDOWN://右键按下

				break;
			case WM_RBUTTONUP://右键抬起
				gameMouseRightDown(msg.x, msg.y);
				break;
			case WM_RBUTTONDBLCLK://右键双击

				break;
			case WM_KEYDOWN:
				gameKeypress(msg.vkcode);
				break;
			}
			paint();
			continue;
		}


		//------时间处理 勿动-----------//
		Sleep(1);
		times++;
		if (times % (interval / 10) != 0) {
			continue;
		}
		times = 0;
		if (stop)
		{
			break;
		}
		gameInterval();

		//-------------------------------//
		paint();// 刷新显示游戏界面
	}
}



/*绘制透明背景图*/
void drawImage(int  picture_x, int picture_y, IMAGE* picture) //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; //在显存里像素的角标
				if (dstX < 0) continue;
				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
			}
		}
	}
}
/*调整图片透明度*/
void drawImageAlpha(int x0, int y0, IMAGE* img, double f)
{
	//获得图片尺寸
	int qwidth, qheight;
	qwidth = img->getwidth();
	qheight = img->getheight();


	//P图为背景图,RS为目标图片
	static IMAGE RS(qwidth, qheight);
	static IMAGE P(qwidth, qheight);


	//背景图的绘制
	getimage(&P, x0, y0, qwidth, qheight);


	//获取指针,作为透明度计算
	DWORD* M = GetImageBuffer(&P);
	DWORD* N = GetImageBuffer(img);
	DWORD* R = GetImageBuffer(&RS);


	// 开启批量绘图模式,解决闪烁问题
	BeginBatchDraw();


	//计算与赋值
	int i, j;
	for (i = 0; i < qheight; i++) {
		for (j = 0; j < qwidth; j++) {
			int r, g, b;
			int ij;
			//计算
			ij = i * qwidth + j;
			r = (int)((GetRValue(N[ij])) * (1 - f) + GetRValue(M[ij]) * f);
			g = (int)((GetGValue(N[ij])) * (1 - f) + GetGValue(M[ij]) * f);
			b = (int)((GetBValue(N[ij])) * (1 - f) + GetBValue(M[ij]) * f);
			R[ij] = RGB(r, g, b);
		}
	}


	//贴出图片并释放内存
	putimage(x0, y0, &RS);
	FlushBatchDraw();// 绘制
}
//检测两个矩形是否相碰撞
int testHit(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2)
{
	return !(x1 + w1 < x2 ||
		y1 + h1 < y2 ||
		x2 + w2 < x1 ||
		y2 + h2 < y1);
}
// 主函数,开启游戏
int main()
{
	initgraph(screenWidth, screenHeight, EW_DBLCLKS | EW_SHOWCONSOLE);
	initgame();					// 初始化游戏
	paint();// 刷新显示游戏界面

	flushmessage();		// 清空鼠标缓冲区
	while (_kbhit()) _getch();	// 清空键盘缓冲区
	run();						// 开始游戏
	closegraph();//关闭图形环
	return 0;
}


//--------------优雅的警戒线 以上为雷区 非专业 勿进------------------// 
//TODO: 2 全局变量声明位置 
//TODO: 2 全局变量声明位置 
IMAGE imgbg;//背景色
IMAGE imgfk[11];//方块图片
TCHAR imgPath[100];
int luoKuai[20][10] = { 0 };//下落的方块
int shiKuai[20][10] = { 0 };//落实不动的方块
int color;
int score = 0;//得分
int level = 1;
//TODO: 3 游戏初始化位置  
void gameInit()
{
	loadimage(&imgbg, L".\\images\\2\\bg-3.png"); //自己的图片路径
	for (int c = 0; c < 11; c++)
	{
		_stprintf(imgPath, L".\\images\\2\\%d.png", c);//自己的的图片路径
		loadimage(&imgfk[c], imgPath);
	}

	//color = rand() % 10 + 1;//随机颜色 1~10
	//luoKuai[0][3] = luoKuai[0][4] = luoKuai[0][5] = color;
	//				luoKuai[1][4] = color;
	createNewLuoKuai();
}
//TODO: 4 绘图处理位置  
void gamePaint()
{
	putimage(0, 0, &imgbg);

	//---------显示下落方块-------------//

	int h, l;
	for (h = 0; h < 20; h++)
	{
		for (l = 0; l < 10; l++)
		{
			if (luoKuai[h][l] != 0)
			{
				drawImage(30 + l * 30, 5 + h * 30, &imgfk[luoKuai[h][l]]);
			}
			if (shiKuai[h][l] != 0)
			{
				drawImage(30 + l * 30, 5 + h * 30, &imgfk[shiKuai[h][l]]);
			}
		}
	}
	//---------显示  得分 等级-------------//
	settextstyle(18, 0, _T("黑体"));
	settextcolor(0xffffff);
	TCHAR str[100];
	_stprintf(str, L"%d分", score);
	outtextxy(390, 228, str);
	_stprintf(str, L"Level %d", level);
	outtextxy(390, 294, str);
}
//TODO: 5 定时处理位置
void gameInterval()
{
	if (downNotOut()&&downNotStop())
	{
		downMove();
	}
	else
	{
		merge();
		updateScore(clearLine());
		if (isOver())
		{
			gameover();
		}
		else
		{
			createNewLuoKuai();
		}
	}
}
//TODO: 6 处理键盘控制位置
void gameKeypress(int key)
{
	switch (key)
	{
	case VK_LEFT:
		if (leftNotOut() && leftNotStop())
		{
			leftMove();
		 }
		break;
	case VK_RIGHT:
		if (rightNotOut() && rightNotStop())
		{
			rightMove();
		}
		break;
	case VK_UP:
		 
		break;
	case VK_DOWN:
		 
		break;
	}

 
}

//TODO: 7 处理鼠标控制位置
void gameMouseDown(int mouseX, int mouseY)
{
	 

}
void gameMouseUp(int mouseX, int mouseY)
{

}
void gameMousemove(int mouseX, int mouseY)
{

}

void gameMouseRightDown(int mouseX, int mouseY)
{

}

game_function.cpp 

#include "game_function.h"
#include <stdlib.h>
/*向左移动*/
void leftMove()
{
	for (int k = 1; k < 10; k++)
	{
		for (int h = 0; h < 20; h++)
		{
			luoKuai[h][k - 1] = luoKuai[h][k];
			luoKuai[h][k] = 0;
		}
	}
}
/* 左不出界 */
_BOOL_ leftNotOut()
{
	for (int h = 0; h < 20; h++)
	{
		if (luoKuai[h][0])
		{
			return FALSE;
		}
	}
	return TRUE;
}
/*左不阻挡*/
_BOOL_ leftNotStop()
{
	for (int k = 1; k < 10; k++)
	{
		for (int h = 0; h < 20; h++)
		{
			if (luoKuai[h][k] && shiKuai[h][k - 1])
			{
				return FALSE;
			}
		}
	}
	return TRUE;
}
/*向右移动*/
void rightMove()
{
	for (int k = 8; k >= 0; k--)
	{
		for (int h = 0; h < 20; h++)
		{
			luoKuai[h][k+1] = luoKuai[h][k];
			luoKuai[h][k] = 0;
		}
	}
}
/* 右不出界 */
_BOOL_ rightNotOut()
{
	for (int h = 0; h < 20; h++)
	{
		if (luoKuai[h][9])
		{
			return FALSE;
		}
	}
	return TRUE;
}
/* 右不阻挡 */
_BOOL_ rightNotStop()
{
	for (int k = 8; k >= 0; k--)
	{
		for (int h = 0; h < 20; h++)
		{
			if (luoKuai[h][k] && shiKuai[h][k + 1])
			{
				return FALSE;
			}
		}
	}
    return TRUE;
}
/*向下移动*/
void downMove()
{
	for (int h = 18; h >= 0; h--)
	{
		for (int k = 0; k < 10; k++)
		{
			luoKuai[h + 1][k] = luoKuai[h][k];
			luoKuai[h][k] = 0;
		}
	}
}
/*下不出界*/
_BOOL_ downNotOut()
{
	for (int k = 0; k < 10; k++)
	{
		if (luoKuai[19][k] != 0)
		{
			return FALSE;
		}
	}
	return TRUE;
}
/*下不阻挡*/
_BOOL_ downNotStop()
{
	for (int h = 18; h >= 0; h--)
	{
		for (int k = 0; k < 10; k++)
		{
			if (luoKuai[h][k] && shiKuai[h+1][k])
			{
				return FALSE;
			}
		}
	}
	return TRUE;
}
/* 合并 */
void merge()
{
	for (int h = 0; h < 20; h++)
	{
		for (int k = 0; k < 10; k++)
		{
			if (luoKuai[h][k])
			{
				shiKuai[h][k] = luoKuai[h][k];
				luoKuai[h][k] = 0;
			}
		}
	}
}
/*消除行*/
int clearLine()
{
	int count = 0;//记录消除了多少行
	for (int xh = 0; xh < 20; xh++)
	{
		//检验本行是否能消除
		_BOOL_ can = TRUE;//假设能消除
		//验证假设
		for (int i = 0; i < 10; i++) //10列
		{
			if (shiKuai[xh][i] == 0)
			{
				can = FALSE; //假设不成立
				break;
			}
		}
		if (can == TRUE)
		{
			count++;
			//消除行:整体向下一行
			for (int h = xh - 1; h >= 0; h--)
			{
				for (int k = 0; k < 10; k++)
				{
					shiKuai[h + 1][k] = shiKuai[h][k];//覆盖下一行
					shiKuai[h][k] = 0;
				}
			}
		}
	}
	return count;
}
/*更新得分*/
void updateScore(int lines)
{
	switch (lines)
	{
	case 1:
		score += 20;
		level++;
		break;
	case 2:
		score += 50;
		level++;
		break;
	case 3:
		score += 100;
		level++;
		break;
	case 4:
		score += 150;
		level++;
		break;
	case 5:
		score += 200;
		level++;
		break;
	}
	if (lines >= 6)
	{
		score +=200;
	}
}

_BOOL_ isOver()
{
	for (int k = 0; k < 8; k++)
	{
		if (shiKuai[0][k] != 0)
		{
			return TRUE;
		}
	}
	return FALSE;
}
/* 创建新落块 */
void createNewLuoKuai()
{
	//1方块种类随机
	BLOCK_TYPE bt = (BLOCK_TYPE)(rand() % 7);
	//2方块颜色随机
	color = rand() % 10 + 1;
	switch (bt)
	{
	case L:
		luoKuai[0][3] = luoKuai[1][3] = luoKuai[2][3] =luoKuai[2][4]= color;
		break;
	case Z:
		luoKuai[0][3] = luoKuai[0][4] = luoKuai[1][4] = luoKuai[1][5] = color;
		break;
	case TIAN:
		luoKuai[0][3] = luoKuai[0][4] = luoKuai[1][3] = luoKuai[1][4] = color;
		break;
	case T:
		luoKuai[0][3] = luoKuai[0][4] = luoKuai[1][4] = luoKuai[0][5] = color;
		break;
	case I:
		luoKuai[0][3] = luoKuai[1][3] = luoKuai[2][3] = luoKuai[3][3] = color;
		break;
	case YI:
		luoKuai[0][3] = luoKuai[0][4] = luoKuai[0][5] = luoKuai[0][6] = color;
		break;
	case J:
		luoKuai[0][4] = luoKuai[1][4] = luoKuai[2][3] = luoKuai[2][4] = color;
		break;
	}
	

}

void gameover()
{
	stop = TRUE;
}

date_type.h

#pragma once
//创建逻辑布尔类型
#define TRUE 1
#define FALSE 0
typedef int _BOOL_;

//枚举类型:方块样式
typedef 
enum block_type { L,Z,TIAN,T,I,YI,J } BLOCK_TYPE;

 game_function.h

#pragma once
#include "date_type.h"
#include "global_var.h"
//功能模块

/*左移动*/
void leftMove();
/**/
_BOOL_ leftNotOut();
/*左不阻挡*/
_BOOL_ leftNotStop();


/*右移动*/
void rightMove();
/*右*/
_BOOL_ rightNotOut();
/*右不阻挡*/
_BOOL_ rightNotStop();
/*下移动*/
void downMove();

/*下*/
_BOOL_ downNotOut();
/*下不阻挡*/
_BOOL_ downNotStop();

/*合并*/
void merge();
/*消除行
 返回消除的行数
*/
int clearLine();
/*更新得分
lines:消除的行数*/
void updateScore(int lines);

_BOOL_ isOver();
/*创建新方块*/
void createNewLuoKuai();

void gameover();

global_var.h

#pragma once
#include "game_function.h"
#include"date_type.h"
//集中管理全局变量声明 共享使用
extern int luoKuai[20][10];//下落的方块
extern int shiKuai[20][10];//落实不动的方块
extern int color;
extern int stop;//是否停止游戏
extern int score;
extern int level;

图片文件:

 

 

EasyX游戏框架:

#define _CRT_SECURE_NO_WARNINGS 1
#include <easyx.h>
#include <time.h>
#include <conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<string>
#include<graphics.h>
 
/*游戏界面绘制*/
void gamePaint();
/*游戏初始化绘制*/
void gameInit();
/*游戏定时处理*/
void gameInterval();
/*游戏键盘按下*/
void gameKeypress(int key);
/*游戏鼠标按下*/
void gameMouseDown(int mouseX,int mouseY);
/*游戏鼠标右键按下*/
void gameMouseRightDown(int mouseX,int mouseY);
/*游戏鼠标抬起*/
void gameMouseUp(int mouseX,int mouseY);
/*游戏鼠标移动*/
void gameMousemove(int mouseX,int mouseY);
 
/*
含透明的图的绘制
x为要载入图片的X坐标,y为Y坐标
*/
void drawImage(int  picture_x, int picture_y,IMAGE* picture);  
/*调整图片透明度
  角度转弧度:PI/180*角度
  弧度转角度:180/PI*弧度
*/
void drawImageAlpha(int x0, int y0, IMAGE* img, double f);
/*两个矩形碰撞检测
即两个矩形是否相交。
 x1, y1, w1, h1是第一个矩形的xy宽高的四个参数
 x2, y2, w2, h2是第二个矩形的xy宽高的四个参数
 返回0代表不相交 返回1代表相交
*/
int testHit(int x1,int y1,int w1,int h1,int x2,int y2,int w2,int h2 );
 
/*设置100即每隔100毫秒刷新以下界面绘图。*/
int interval = 100;//TODO: 1 设置定时器时间间隔(单位毫秒)
// TODO: 1 设置窗口: 宽度 高度
int screenWidth = 800;
int screenHeight=600;
int stop = 0;//是否停止游戏
//-----------------------------------//
int times = 0; 
/*初始化游戏 */
void initgame()
{
	srand((unsigned)time(NULL));//随机数初始化
	setbkcolor(NULL);//背景色
	setbkmode(TRANSPARENT);// 设置背景混合模式: TRANSPARENT为透明
	gameInit();
}
/*
	界面绘图演示案例
*/
 
 
/*绘制显示游戏界面*/
void paint()
{
	BeginBatchDraw();//打开双缓冲
	cleardevice();// 清屏
	 
	gamePaint();
	//-----------------------------//
	EndBatchDraw();//关闭双缓冲
}
 
 
 
/*游戏运行*/
void run()
{
	ExMessage msg ;
	//ExMessage key;
	while (1)	// 游戏主循环  可借助break 结束循环
	{
		if (peekmessage(&msg,-1,true))
		{
			switch (msg.message)
			{
			case WM_MOUSEMOVE://鼠标移动
				gameMousemove(msg.x, msg.y);
				break;
			case WM_LBUTTONDOWN://左键按下
				gameMouseDown(msg.x, msg.y);
				break;
			case WM_LBUTTONUP://左键抬起
				gameMouseUp(msg.x, msg.y);
				break;
			case WM_LBUTTONDBLCLK://左键双击
				 
				break;
			case WM_RBUTTONDOWN://右键按下
				 
				break;
			case WM_RBUTTONUP://右键抬起
				gameMouseRightDown(msg.x, msg.y);
				break;
			case WM_RBUTTONDBLCLK://右键双击
				 
				break;
			case WM_KEYDOWN:
				gameKeypress(msg.vkcode);
				break;
			}
			paint();
			continue;
		}
		
		 
		//------时间处理 勿动-----------//
		Sleep(1);
		times++;
		if(times%(interval/10)!=0){
			continue;
		}
		times=0;
		if(stop)
		{
			break;
		}
		gameInterval();
		 
		//-------------------------------//
		paint();// 刷新显示游戏界面
	}
}
 
 
 
/*绘制透明背景图*/
 void drawImage(int  picture_x, int picture_y,IMAGE* picture  ) //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; //在显存里像素的角标
				if (dstX<0) continue;
				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
			}
		}
	}
}
/*调整图片透明度*/
void drawImageAlpha(int x0, int y0, IMAGE* img, double f)
{
	//获得图片尺寸
	int qwidth, qheight;
	qwidth = img->getwidth();
	qheight = img->getheight();
 
 
	//P图为背景图,RS为目标图片
	static IMAGE RS(qwidth, qheight);
	static IMAGE P(qwidth, qheight);
 
 
	//背景图的绘制
	getimage(&P, x0, y0, qwidth, qheight);
 
 
	//获取指针,作为透明度计算
	DWORD* M = GetImageBuffer(&P);
	DWORD* N = GetImageBuffer(img);
	DWORD* R = GetImageBuffer(&RS);
 
 
	// 开启批量绘图模式,解决闪烁问题
	BeginBatchDraw();
 
 
	//计算与赋值
	int i, j;
	for (i = 0; i < qheight; i++) {
		for (j = 0; j < qwidth; j++) {
			int r, g, b;
			int ij;
			//计算
			ij = i * qwidth + j;
			r = (int)((GetRValue(N[ij])) * (1 - f) + GetRValue(M[ij]) * f);
			g = (int)((GetGValue(N[ij])) * (1 - f) + GetGValue(M[ij]) * f);
			b = (int)((GetBValue(N[ij])) * (1 - f) + GetBValue(M[ij]) * f);
			R[ij] = RGB(r, g, b);
		}
	}
 
 
	//贴出图片并释放内存
	putimage(x0, y0, &RS);
	FlushBatchDraw();// 绘制
}
//检测两个矩形是否相碰撞
int testHit(int x1,int y1,int w1,int h1,int x2,int y2,int w2,int h2 )
{
 return !(x1 + w1 < x2||
		 y1 + h1 < y2 ||
		 x2 + w2 <x1 ||
		 y2 + h2<y1 );
}
// 主函数,开启游戏
int main  ()
{
	initgraph(screenWidth, screenHeight,SHOWCONSOLE);		
	initgame();					// 初始化游戏
	paint();// 刷新显示游戏界面
	 
	flushmessage();		// 清空鼠标缓冲区
	while (_kbhit()) _getch();	// 清空键盘缓冲区
	run();						// 开始游戏
	closegraph();//关闭图形环
	return 0;
}
 
 
//--------------------------------// 
//TODO: 2 全局变量声明位置 
 
 
//TODO: 3 游戏初始化位置  
 void gameInit()
{
	 
}
 //TODO: 4 绘图处理位置  
void gamePaint()
{
  
}
 //TODO: 5 定时处理位置
void gameInterval()
{
	 
}
//TODO: 6 处理键盘控制位置
void gameKeypress(int key)
{
	switch (key )
	{
	case VK_LEFT:
		printf("按 左\n");
		break;
	case VK_RIGHT:
		printf("按 右\n");
		break;
	case VK_UP:
		printf("按 上\n");
		break;
	case VK_DOWN:
		printf("按 下\n");
		break;
	}
 
	switch (key )
	{
	case 'A':
	case 'a':
		printf("按 A\n");
		break;
	case 'B':
	case 'b':
		printf("按 B\n");
		break;
	case 'c':
	case 'C':
		printf("按 C\n");
		break;
	case 'D':
	case 'd':
		printf("按 d\n");
		break;
	}
}
 
//TODO: 7 处理鼠标控制位置
void gameMouseDown(int mouseX,int mouseY)
{
	printf("按下鼠标左键\n");
 
}
void gameMouseUp(int mouseX,int mouseY)
{
	 
}
void gameMousemove (int mouseX,int mouseY)
{
	 
}
 
void gameMouseRightDown(int mouseX,int mouseY)
{
	 
}

大家的点赞、收藏、关注将是我更新的最大动力!欢迎留言或私信建议或问题。
大家的支持和反馈对我来说意义重大,我会继续不断努力提供有价值的内容!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/473097.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI VS 好莱坞?新时代电影工作流;MJ制作微信表情包的麻瓜教程;关于ControlNet的一切;AI创业真钱景 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f916; 『OpenAI通过了一大批GPT-4申请』大量放号ing~快去看邮箱&#xff01; &#x1f916; 『小马智行 | 广州南沙区开启车内无安全员的自动…

opencv-python加载pytorch训练好的onnx格式线性回归模型

opencv是一个开源的图形库&#xff0c;有针对java,c,python的库依赖&#xff0c;它本身对模型训练支持的不好&#xff0c;但是可以加载其他框架训练的模型来进行预测。 这里举一个最简单的线性回归的例子&#xff0c;使用深度学习框架pytorch训练模型&#xff0c;最后保存模型为…

【软考备战·希赛网每日一练】2023年4月28日

文章目录 一、今日成绩二、错题总结第一题第二题第三题 三、知识查缺 题目及解析来源&#xff1a;2023年04月28日软件设计师每日一练 一、今日成绩 二、错题总结 第一题 解析&#xff1a; 大体了解即可&#xff0c;题目要考察的核心意思&#xff1a;确定的有限自动机和不确定的…

js 操作数组内容

js 操作数组内容 数组添加元素&#xff08;更改原数组&#xff09; push和unshift会返回添加了新元素的数组长度 push从数组最后加入&#xff0c;unshift从数组最前面加入 const arr ["a", "b", "c"]; arr.push("d"); //返回4…

数据结构基础day9

题目&#xff1a;187. 重复的DNA序列 解法1&#xff1a;哈希表 class Solution { public:vector<string> findRepeatedDnaSequences(string s) {vector<string> ans;unordered_map<string, int> mp;int ns.size(), L10;for(int i0; i<n-L; i){ //从开头…

【fluent UDF】warning: unused variable警报:存在未使用的变量

一、问题背景 在编译UDF时&#xff0c;出现如下错误 curing_heat_v3.c: In function ‘iter_ending’: curing_heat_v3.c:105:14: warning: unused variable ‘volume_sum’ [-Wunused-variable] real volume_sum0.0; curing_heat_v3.c:104:14: warning: unused variable ‘…

【Python零基础学习入门篇②】——第二节:Python的常用语句

⬇️⬇️⬇️⬇️⬇️⬇️ ⭐⭐⭐Hello&#xff0c;大家好呀我是陈童学哦&#xff0c;一个普通大一在校生&#xff0c;请大家多多关照呀嘿嘿&#x1f601;&#x1f60a;&#x1f618; &#x1f31f;&#x1f31f;&#x1f31f;技术这条路固然很艰辛&#xff0c;但既已选择&…

网络编程之简单socket通信

一.什么是Socket? Socket&#xff0c;又叫套接字&#xff0c;是在应用层和传输层的一个抽象层。它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用以实现进程在网络中通信。 socket分为流socket和数据报socket&#xff0c;分别基于tcp和udp实现。 SOCK_STREAM 有以下…

苦学58天,最后就这结果......

背景 非计科大专一枚&#xff0c;当初学的机械自动化专业。大学完全可以说是玩过来的&#xff0c;临近毕业开始慌了&#xff0c;毕业后一直没能找到工作&#xff0c;在高中同学&#xff08;211 计科&#xff09;的引领下&#xff0c;入坑程序员&#xff0c;学的软件测试。 从…

Lombok简介

Lombok简介 1、lombok简介2、springboot整合lombok 1、lombok简介 Lombok是一个第三方的Java工具库&#xff0c;会自动插入编辑器和构建工具。Lombok提供了一组非常有用的注解&#xff0c;用来消除Java类中的大量样板代码&#xff0c;比如setter和getter方法、构造方法等。只需…

Vue(简单了解Cookie、生命周期)

一、了解Cookie 类似于对象响应携带数据 输入用户名密码跳转到指定页面 点击指定页面中其中一个按钮跳转到另一个指定页面&#xff08;再不需用输入用户名密码&#xff09; 例如现在很多浏览器实现七天免密登录 简单理解&#xff1a;就是在网站登录页面之后&#xff0c;服务…

新建Django项目

1. 创建项目 使用Django提供的命令&#xff0c;可以创建一个Django项目实例需要的配置项——包括数据库配置、Django配置和应用程序配置的集合。新建Django项目命令的语法格式如下&#xff1a; django-admin startproject 工程名称例如&#xff1a;想要在D:\的pythonProject目…

Mysql 存储过程 / 存储函数

目录 0 课程视频 1 基本语法 1.0 作用 ->在数据库中 封装sql语句 -> 复用 -> 减少网络交互 ->可接收参数返回数据 1.1 创建 1.2 调用 1.3 查看 1.4 删除 1.5 ; 封号结束符 改成 $$ 双刀符合结束语句 -> 因为打包封号结束有冲突 1.6 在cmd 中定义 存储过…

基于 SpringBoot+Vue+Java 的财务管理系统(附源码,教程)

文章目录 一 简介第二.主要技术第三、部分效果图第四章 系统设计4.1功能结构4.2 数据库设计4.2.1 数据库E/R图4.2.2 数据库表 第五章 系统功能实现5.1管理员功能模块 一 简介 财务管理系统的需求和管理上的不断提升&#xff0c;财务管理系统的潜力将无限扩大&#xff0c;财务管…

Postman预请求脚本、测试脚本(pre-request scripts、tests常用工作总结)

文章目录 Postman预请求脚本&#xff08;pre-request scripts工作常用总结&#xff09;Postman预请求脚本Postman测试脚本预请求脚本和测试脚本有什么区别常用工作总结登录接口返回的是Set-Cookie标头 Postman预请求脚本&#xff08;pre-request scripts工作常用总结&#xff0…

Spring Boot配置文件及日志信息

目录 前言&#xff1a; Spring Boot优点 配置文件 配置文件格式 读取配置文件 properties配置文件格式 properties优缺点分析 yml配置文件格式&#xff08;另一种标记语言&#xff09; yml优缺点分析 Spring Boot 不同平台配置文件规则 日志信息 日志的功能 Sprin…

Springboot +Flowable,设置任务处理人的四种方式(一)

一.简介 学习下UserTask 设置用户的三种方式&#xff0c;至于如何设置用户组&#xff0c;下篇文章再聊。 现在&#xff0c;假设我有如下一个简单的流程图&#xff1a; 那么该如何设置这个用户节点的处理人&#xff1f; 二.第一种&#xff1a;指定具体用户 第一种方式&…

电路中噪声来源

电路包括不同的部件和芯片&#xff0c;所有都有可能成为噪声的来源。例如&#xff0c;电阻会带来热噪声&#xff0c;这个噪声为宽频噪声&#xff0c;几乎涵盖所有频率范围&#xff1b;运算放大器其芯片内部会产生噪声&#xff1b;而 ADC产生的量化噪声相较于其他器件&#xff0…

【】右值引用完美转发

文章目录 右值引用和左值引用左值和右值概念左值引用 && 右值引用右值引用使用场景和意义左值引用的使用场景**左值引用的短板:**右值引用和移动语义STL容器增加的接口move函数右值引用的其他使用场景 完美转发万能引用完美转发保持值的属性完美转发的使用场景 右值引用…

【Linux】进程信号 --- 信号产生 信号递达和阻塞 信号捕捉

&#x1f34e;作者&#xff1a;阿润菜菜 &#x1f4d6;专栏&#xff1a;Linux系统编程 文章目录 一、预备知识二、信号产生1. 通过终端按键产生信号1.1 signal()1.2 core dump标志位、核心存储文件 2.通过系统调用向进程发送信号3.由软件条件产生信号3.1 alarm函数和SIGALRM信号…