DevC++ easyx实现视口编辑,在超过屏幕大小的地图上画点,与解决刮刮乐bug效果中理解C语言指针的意义

news2024/9/26 5:23:18

继上篇文案,

DevC++ easyx实现地图拖动,超过屏幕大小的巨大地图的局部显示在屏幕的方法——用悬浮窗的原理来的实现一个视口-CSDN博客

实现了大地图拖动,但是当时野心不止,就想着一气能搓啥就继续搓啥,看着地图移动都搓出来了,像素点也画上了,能不能就着直接编辑地图,给超过屏幕大小的地图画画。

上节文案从拖动复制粘贴实现悬浮窗,通过img3进行缓存覆盖前的位置的样子,在下次粘贴之前先用img3粘贴到原来位置恢复,在重新采样给img3,然后粘贴img2.两种图片的复制粘贴。

一个是恢复图片的复制粘贴,一个是图像的不断粘贴,念着念着,就自然而然,看到了大地图,复制粘贴,不就能实现大地图的修改了吗?

于是这样才继续就着复制粘贴的思路,小地图绘制完,贴回到大地图去,然后再从大地图复制,再粘贴回来,就刚刚好。

其实代码就是之前的DevC++ easyx实现地图拖动,超过屏幕大小的巨大地图的局部显示在屏幕的方法——用悬浮窗的原理来的实现一个视口-CSDN博客

的最后一个代码块 ,

而且就是这上一篇文案的刮刮乐效果的bug原理也是这个:bug根源在于函数参数

void check(struct ExMessage m,struct pircle *save,IMAGE ak,struct showplace *show) 

IMAG  ak的参数

IMAG ak指的是ak图片调用之后,图片会自动备份,相当于复制了一个,原件不受影响。

这个用法就是所谓的形参,只是说明用的是数据来源备份。数据来源不受更改。

这样原来的大地图就压根没有被修改。

但是刮刮乐效果呢?打印了ak图像,去对比像素,然后按下去鼠标不松,发现ak上没有打印图像,松开鼠标,才有轨迹粘贴进去,试了试几次,发现总是视口的图片粘贴到ak上面。想起来之前实现复制粘贴,肯定不能原样复制,不然画面不会动,就没有拖动效果。这样肯定采样的位置变化了,假设新旧采样位置都之差一个像素的宽度。然后假设一个像素,复制粘贴有位置差距,然后描述一遍:是取样的时候,先取样ak平面上偏移一个像素的位置,粘贴到视口上,然后重新调用ak,这样ak是一个全是蓝色背景的,然后又把视口的图片粘贴到ak上,这样总是有新的备份产生,总是在新的备份中切除一个像素,然后切除剩下的像素重新粘贴到新的备份当中。就出现了。

原来是采样才是真正实现刮刮乐的效果的原因,采样总是会多出来一个像素的蓝色边,这样视口里相应就是蓝色像素覆盖边缘的黄色像素。然后把这个多出来蓝色像素的图片粘到原来位置,这样就无中生有了新的蓝色像素,实现刮刮乐效果。

鼠标左键点击,不移动鼠标,不会打印,但是只要松开,才会打印。显然这样就是从视口复制粘贴到底图,那样bug就来自从底图到视口的这仅有的两个可能范围里的这唯一一种情况了。

bug或刮刮乐效果代码,其实就是传入的是ak图片的备份。ak永远都是蓝色。

#include<stdio.h>
#include<conio.h>
#include<graphics.h>
#include<windows.h>
struct pircle {
	IMAGE img2;
	IMAGE img3;
	const int orilx=0,orily=0;
	int nowlx=0,nowly=0;
	const int a=300,h=300;
//	原有图片的左上角坐标
	int m1x=0,m1y=0;

	int  putflag=0;
	int  drawflag=0;

} save;

struct showplace {
	int x=100;
	int y=100;
	const int a=300;
	const int h=300;

} show;
void gameplace(IMAGE *ak) {
	SetWorkingImage(ak);
	setbkcolor(BLUE);
	cleardevice();
	setlinecolor(BLACK);
	rectangle(0,0,1499,1499);
	line(0, 0, 800, 1400);

}


void check(struct ExMessage m,struct pircle *save,IMAGE ak,struct showplace *show) {
	printf("putflag = %d\n",save->putflag);
	printf("%d %d\n",m.x,m.y);
	printf("%d %d\n",save->nowlx,save->nowly);

	if(save->putflag==true) {
		SetWorkingImage();
		getimage(&save->img3,show->x,show->y,show->a,show->h);
		BeginBatchDraw();
		SetWorkingImage(&ak);
		putimage(save->nowlx,save->nowly,&save->img3);

		save->nowlx=save->nowlx-(m.x-save->m1x);
		save->nowly=save->nowly-(m.y-save->m1y);
		save->m1x=m.x;
		save->m1y=m.y;
		getimage(&save->img2,save->nowlx,save->nowly,save->a,save->h);

//		putimage(save->nowlx,save->nowly,&save->img2);
		SetWorkingImage();
		putimage(show->x,show->y,&save->img2);
		putimage(500,500,&ak) ;
		
//		在默认桌面程序的界面上打印ak底图效果 
		EndBatchDraw();

//			一次绘图出来,没有屏闪了
	}
	switch(m.message) {

		case WM_LBUTTONDOWN:
			if(m.x>show->x&&m.x<show->x+show->a&&m.y>show->y&&m.y<show->y+show->h&&m.ctrl) {
				save->putflag=true;
//					启动批复制粘贴
				SetWorkingImage(&ak);
				getimage(&save->img2,save->nowlx,save->nowly,save->a,save->h);
//				save->img2=ak;
				save->m1x=m.x;
				save->m1y=m.y;
				SetWorkingImage();

			}
			break;
		case WM_LBUTTONUP:

			save->putflag=0;


			break;
	}

}

void draw(struct ExMessage m,struct pircle *save,struct showplace *show,IMAGE *ak) {

//	printf("draw = %d\n",save->drawflag);
//		SetWorkingImage(ak);
	if(save->drawflag==true) {
//		save.drawflag=1;
		putpixel(m.x,m.y,RGB(255,155,4));
	}


	switch(m.message) {
		case WM_LBUTTONDOWN:
			if(m.x>show->x&&m.x<show->x+show->a&&m.y>show->y&&m.y<show->y+show->h) {
//
				printf("m.x = %d\tm.y = %d\t%d\t%d\n",m.x,m.y,save->m1x,save->m1y);
				save->drawflag=true;

//				printf("drawflag = %d\n",save->drawflag);
			}

			break;

		case WM_LBUTTONUP:

			save->drawflag=false;
//			printf("%d\n",save->drawflag);
			break;
	}

}


int main() {
	// 初始化绘图窗口
	initgraph(1640, 1480);
	IMAGE ak(1500,1500);
	IMAGE b(300,300);

	gameplace(&ak);
	getimage(&b,0,0,300,300);

	SetWorkingImage();
	putimage(0,0,&ak);
	putimage(100,100,&b);
	setlinecolor(BLACK);


	rectangle(show.x,show.y,show.x+show.a,show.y+show.h);



	ExMessage m;

	while(1) {
		m=getmessage(EX_MOUSE);

		check(m,&save,ak,&show);
		draw(m,&save,&show,&ak);
	}
	_getch();
	closegraph();
}

代码对应序号15.5解决画不上去....文件里的代码

ctrl+鼠标左键视口实现拖动,

可以看到另一部分也有个相同的图片,这个右下角的图片就是img3的内容。相当于除了复制粘贴原来地方,还在500,500的位置再次复制粘贴图像。

对比代码蓝色的参数,可以知道传入的ak多了一个符号*,实现了ak的操作,而不再是ak复印件的操作。

当然由于ak图片大小太大,实际上传入的*ak是ak的引用凭证,这样通过引用凭证到ak所实际存储的地方。而原来的ak的样本,实际上就是通过直接复制ak的数据。

检测方法也好说,其实就是把ak图片的大小改大,大概10000*10000像素,应该就有100mb了,这样在运行两个代码,看看是不是一个比另一个1多出100mb的内存。然后再改改图片大小20000*10000,20000*20000,看看是不是对应又多了一倍,还多了一倍。

然后就是改参数属性,从IMAG ak 到IMAG *ak的故事了。

直接替换完事。

 完整代码,解决刮刮乐效果,而且成功绘制到原来的ak图片上了。

#include<stdio.h>
#include<conio.h>
#include<graphics.h>
#include<windows.h>
struct pircle {
	IMAGE img2;
//	old 
	IMAGE img3;
	const int orilx=0,orily=0;
	int nowlx=0,nowly=0;
	const int a=400,h=400;
//	原有图片的左上角坐标
	int m1x=0,m1y=0;

	int  putflag=0;
	int  drawflag=0;

} save;


struct showplace {
	int x=100;
	int y=100;
	const int a=400;
	const int h=400;
} show;

void gameplace(IMAGE *ak) {
	SetWorkingImage(ak);
	setbkcolor(BLUE);
	cleardevice();
	setlinecolor(BLACK);
	rectangle(0,0,1499,1499);
	line(0, 0, 800, 1400);

}


void check(struct ExMessage m,struct pircle *save,IMAGE *ak,struct showplace *show) {



	printf("putflag = %d\n",save->putflag);
	printf("%d %d\n",m.x,m.y);
	printf("%d %d\n",save->nowlx,save->nowly);

	if(save->putflag==true) {
		BeginBatchDraw();
		SetWorkingImage();
		getimage(&save->img3,show->x,show->y,show->a,show->h);

		SetWorkingImage(ak);
//			SetWorkingImage(&ak);
		putimage(save->nowlx,save->nowly,&save->img3);

		save->nowlx=save->nowlx-(m.x-save->m1x);
		save->nowly=save->nowly-(m.y-save->m1y);
		save->m1x=m.x;
		save->m1y=m.y;
		getimage(&save->img2,save->nowlx,save->nowly,save->a,save->h);

//		putimage(save->nowlx,save->nowly,&save->img2);
		SetWorkingImage();
		putimage(show->x,show->y,&save->img2);
		putimage(500,500,&save->img3);

		EndBatchDraw();

//			一次绘图出来,没有屏闪了
	}
	switch(m.message) {

		case WM_LBUTTONDOWN:
			if(m.x>show->x&&m.x<show->x+show->a&&m.y>show->y&&m.y<show->y+show->h&&m.ctrl) {
				save->putflag=true;
//					启动批复制粘贴
				SetWorkingImage(ak);
				getimage(&save->img2,save->nowlx,save->nowly,save->a,save->h);
//				save->img2=ak;
				save->m1x=m.x;
				save->m1y=m.y;
				SetWorkingImage();

			}
			break;
		case WM_LBUTTONUP:

			save->putflag=0;


			break;
	}

}

void draw(struct ExMessage m,struct pircle *save,struct showplace *show,IMAGE *ak) {

//	printf("draw = %d\n",save->drawflag);
//		SetWorkingImage(ak);
	if(save->drawflag==true) {
//		save.drawflag=1;
		putpixel(m.x,m.y,RGB(255,155,4));
	}


	switch(m.message) {
		case WM_LBUTTONDOWN:
			if(m.x>show->x&&m.x<show->x+show->a&&m.y>show->y&&m.y<show->y+show->h) {
//
				printf("m.x = %d\tm.y = %d\t%d\t%d\n",m.x,m.y,save->m1x,save->m1y);
				save->drawflag=true;

//				printf("drawflag = %d\n",save->drawflag);
			}

			break;

		case WM_LBUTTONUP:

			save->drawflag=false;
//			printf("%d\n",save->drawflag);
			break;
	}

}




int main() {
	// 初始化绘图窗口
	initgraph(840, 880);



	IMAGE ak(1500,1500);
	IMAGE b(300,300);

	gameplace(&ak);
	getimage(&b,0,0,400,400);

	SetWorkingImage();
	putimage(0,0,&ak);
	putimage(100,100,&b);
	setlinecolor(BLACK);


	rectangle(show.x,show.y,show.x+show.a,show.y+show.h);



	ExMessage m;

	while(1) {
		m=getmessage(EX_MOUSE);

		check(m,&save,&ak,&show);
		draw(m,&save,&show,&ak);


	}
	_getch();
	closegraph();
}



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

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

相关文章

转录组无参比对教程

写在前面 2023年将结束&#xff0c;小杜的生信笔记分享个人学习笔记也有2年的时间。在这2年的时间中&#xff0c;分享算是成为工作、学习和生活中的一部分。自己为了运行和维护社群也算花费大量的时间和精力&#xff0c;自己认为还算满意吧。对于个人来说&#xff0c;自己一直…

Docker介绍、常用命令与操作

Docker介绍、常用命令与操作 学习前言为什么要学习DockerDocker里的必要基础概念常用命令与操作1、基础操作a、查看docker相关信息b、启动或者关闭docker 2、容器操作a、启动一个镜像i、后台运行ii、前台运行 b、容器运行情况查看c、日志查看d、容器删除 3、镜像操作a、镜像拉取…

使用 Docker 部署企业培训系统 PlayEdu

1&#xff09;PlayEdu 介绍 官网&#xff1a;https://www.playedu.xyz/ GitHub&#xff1a;https://github.com/PlayEdu/PlayEdu PlayEdu 是一款适用于搭建内部培训平台的开源系统&#xff0c;旨在为企业/机构打造自己品牌的内部培训平台。PlayEdu 基于 Java MySQL 开发&…

C语言--直接插入排序【排序算法|图文详解】

一.直接插入排序介绍&#x1f357; 直接插入排序又叫简单插入排序&#xff0c;是一种简单直观的排序算法&#xff0c;它通过构建有序序列&#xff0c;对于未排序的数据&#xff0c;在已排序序列中从后向前扫描&#xff0c;找到相应位置并插入。 算法描述&#xff1a; 假设要排序…

Golang实现JAVA虚拟机-运行时数据区

一、运行时数据区概述 JVM学习&#xff1a; JVM-运行时数据区 运行时数据区可以分为两类&#xff1a;一类是多线程共享的&#xff0c;另一类则是线程私有的。 多线程共享的运行时数据区需要在Java虚拟机启动时创建好&#xff0c;在Java虚拟机退出时销毁。对象实例存储在堆区类信…

2023.12.22 关于 Redis 数据类型 String 常用命令

目录 引言 String 类型基本概念 SET & GET SET 命令 GET 命令 MSET & MGET MSET 命令 MGET 命令 SETNX & SETEX & PSETEX SETNX 命令 SETEX 命令 PSETEX 命令 计数命令 INCR 命令 INCRBY 命令 DECR 命令 DECRBY 命令 INCRBYFLOAT 命令 总结…

【GoLang】Go语言几种标准库介绍(一)

你见过哪些令你膛目结舌的代码技巧&#xff1f; 文章目录 你见过哪些令你膛目结舌的代码技巧&#xff1f;前言几种库bufio&#xff08;带缓冲的 I/O 操作&#xff09;特性示例 bytes (实现字节操作)特性示例 总结专栏集锦写在最后 前言 随着计算机科学的迅猛发展&#xff0c;编…

复试情报准备

英语自我介绍&#xff0c;介绍完老师会根据你的回答用英语问你问题&#xff0c;比如介绍一下你的本科学校&#xff0c;或者家乡什么的。计网过一遍&#xff0c;会问两道题。接下来是重点&#xff0c;我当时是根据我成绩单&#xff0c;问了我本科学过的科目&#xff0c;比如pyth…

【Docker容器精解篇 】深入探索Docker技术的概念与容器思想

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《docker容器精解篇》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 前言一、Docker 的介绍1.1 Docker 的由来1.1.1 环境不一致1.1.2 隔离性1.1.3 弹性伸缩1.1.4 学习成本 1.2 Doc…

推荐五个免费的网络安全工具

导读&#xff1a; 在一个完美的世界里&#xff0c;信息安全从业人员有无限的安全预算去做排除故障和修复安全漏洞的工作。但是&#xff0c;正如你将要学到的那样&#xff0c;你不需要无限的预算取得到高质量的产品。这里有SearchSecurity.com网站专家Michael Cobb推荐的五个免费…

网站检测有哪些好用的监测工具

目前网站监测工具良莠不齐&#xff0c;网站监控工具有很多&#xff0c;选择合适功能强大的网站监控工具&#xff0c;对我们的业务安全有非常大的帮助。目前市场上好用的一些网站监测工具如德迅云眼、观测云等&#xff0c;它们都提供了网站性能监测、安全防护、故障预警等功能&a…

天呐,我找到财务报表开发的通关密码了!

要问我们IT最不愿做的报表开发有哪些&#xff0c;首当其冲的一定是财务分析。我对开发财务报表这事就一个态度&#xff1a;只要不谈开发财务报表&#xff0c;我们就还是好朋友&#xff0c;谈了会怎样&#xff1f;不好意思&#xff0c;我会破大防。 1、财务的分析逻辑和需求&am…

Azure Machine Learning - 如何使用 GPT-4 Turbo with Vision

介绍如何在Azure中使用GPT-4 Turbo with Vision 关注TechLead&#xff0c;分享AI全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管理经验&#xff0c;同济本复旦硕&#xff0c;复旦机器人智能实验室成员&#xff0c;阿里云认证的资深架构师&#xff0c;项目管理…

加速计算,为何会成为 AI 时代的计算力“新宠”

随着科技的发展&#xff0c;处理大量数据和进行复杂计算的需求越来越高&#xff0c;人工智能、大数据和物联网等领域更是如此&#xff0c;传统的计算方式已经无法满足这些需求。因此&#xff0c;加速计算作为一种现代计算方式&#xff0c;成了必要的手段。加速计算具有前所未有…

项目应用多级缓存示例

前不久做的一个项目&#xff0c;需要在前端实时展示硬件设备的数据。设备很多&#xff0c;并且每个设备的数据也很多&#xff0c;总之就是数据很多。同时&#xff0c;设备的刷新频率很快&#xff0c;需要每2秒读取一遍数据。 问题来了&#xff0c;我们如何读取数据&#xff0c…

AutoBookmark Adobe Acrobat快速自动批量添加书签/目录

前言 解决问题&#xff1a;Adobe Acrobat快速自动批量添加书签/目录, 彻底告别手动添加书签的烦恼 AutoBookmark 前言1 功能简介2 实现步骤2.1 下载插件2.2 将插件复制到Acrobat文件夹下2.3 自动生成书签 1 功能简介 我们在查看PDF版本的论文或者其他文件的时候, 虽然相比较于…

傻瓜式教学Docker 使用docker compose部署 php nginx mysql

首先你可以准备这个三个服务,也可以在docker compose 文件中 直接拉去指定镜像,这里演示的是镜像服务已经在本地安装好了,提供如下: PHP # 设置基础镜像 FROM php:8.2-fpm# install dependencies RUN apt-get update && apt-get install -y \vim \libzip-dev \libpng…

goland错误:该版本的1%与您运行的windows版本不兼容

创建第一个go语言的hello world后&#xff0c;报错。 需要将 package gotest1 改为 package main main是主程序的入口

【leetcode100-020】【矩阵】旋转图像

【题干】 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 【思路】 怎么还整上小学奥数题了&#xff08;不是对角翻转水平/垂…

第11章 GUI Page436 使用缓冲DC, wxBufferedPaintDC

所谓“缓冲DC”&#xff0c;是指将所有图元都先划到一个人眼看不到的“设备上下文”之上&#xff0c;最后再一次性复制到真正的屏幕DC之上&#xff0c;这样我们就看不到中间画的过程了&#xff0c;也就不会感到闪烁了。 注意&#xff0c;这时不能解除ScrolledWindow1的背景擦除…