SGL基本思路讲解

2023-10-29

SGL图形库是为Windows图形界面编程服务的,而且一切都是考虑到对新手友好的。在具体介绍提供给用户的函数之前,需要先说明一下应该以什么样的思路来构思我们的SGL程序。


作为C语言程序,main函数总是需要在最开始就了解一下的。在SGL库中,可以将main理解为

void main(){
    sgSetup();
    while(1){
        sgLoop();
    }
}


其中sgSetup函数和sgLoop函数都是需要由用户来完成的,也就是说我们负责初始化我们的SGL程序然后完成其中的循环逻辑就可以了。其根本思路就是,setup函数里设置与窗口鼠标键盘有关的属性,loop函数绘制每一帧的图案。所以,SGL程序是不会自动结束的,要结束程序的话,可以调用exit(0)这样的函数来实现。


至于loop函数里的逻辑该怎么实现,有两种方法。举个抽象点的例子,比如y = x的平方,我们要依次求出x为1,2,3…的y值,我们既可以每次直接计算x的平方,也可以根据上一次计算的y’来计算当前的y = y’ + 2*x - 1。那么这两种思路也可以应用到我们的SGL程序中。我们既可以直接算出每次loop中需要计算的变量,也可以根据上一次loop的结果进行迭代。两种方法的主要区别在于效率,需要具体情况具体分析。


下面给大家贴一个用SGL实现的简单小游戏,可以简单了解一下程序的结构,里面函数的具体用法后续文章会讨论。

#include "winsgl.h"

#define inRect(x, y, x1, y1, x2, y2) ((x>=x1&&x<=x2)&&(y>=y1&&y<=y2))
#define speedUp(e) (e+=e>0?2:-2)

void movePlayer(int x, int y);
void moveEnemy();
int hasCollision();

struct _player {
	vecTwo pos;
	bitMap *oldImage;
}player;
struct _enemy {
	vecTwo pos;
	vecTwo vel;
	bitMap *oldImage;
}enemy1, enemy2, enemy3, enemy4;
int liveTime = 0;

void sgSetup() {
	initWindow(640, 640, "Collision --SGL Sample Game", BIT_MAP);
	initMouse(SG_COORDINATE);
	player.oldImage = (bitMap*)malloc(sizeof(bitMap));
	enemy1.oldImage = (bitMap*)malloc(sizeof(bitMap));
	enemy2.oldImage = (bitMap*)malloc(sizeof(bitMap));
	enemy3.oldImage = (bitMap*)malloc(sizeof(bitMap));
	enemy4.oldImage = (bitMap*)malloc(sizeof(bitMap));
}
void sgLoop() {
	static int first = 1, cont = 0, drag = 0;
	vecTwo position;
	int press;

	if (first) {
		loadBmp(0, 0, "Source\\collision\\background.bmp");
		player.pos.x = player.pos.y = 290;
		enemy1.pos.x = 120;
		enemy1.pos.y = 100;
		enemy2.pos.x = 432;
		enemy2.pos.y = 120;
		enemy3.pos.x = 100;
		enemy3.pos.y = 432;
		enemy4.pos.x = 480;
		enemy4.pos.y = 480;
		enemy1.vel.x = enemy1.vel.y = enemy2.vel.y = enemy3.vel.x = 4;
		enemy4.vel.x = enemy4.vel.y = enemy3.vel.y = enemy2.vel.x = -4;
		getImage(player.pos.x, player.pos.y, player.pos.x + 59, player.pos.y + 59, player.oldImage);
		getImage(enemy1.pos.x, enemy1.pos.y, enemy1.pos.x + 83, enemy1.pos.y + 63, enemy1.oldImage);
		getImage(enemy2.pos.x, enemy2.pos.y, enemy2.pos.x + 135, enemy2.pos.y + 31, enemy2.oldImage);
		getImage(enemy3.pos.x, enemy3.pos.y, enemy3.pos.x + 59, enemy3.pos.y + 95, enemy3.oldImage);
		getImage(enemy4.pos.x, enemy4.pos.y, enemy4.pos.x + 63, enemy4.pos.y + 51, enemy4.oldImage);
		setColor(255, 0, 0);
		putQuad(player.pos.x, player.pos.y, player.pos.x + 59, player.pos.y + 59, SOLID_FILL);
		setColor(0, 0, 255);
		putQuad(enemy1.pos.x, enemy1.pos.y, enemy1.pos.x + 83, enemy1.pos.y + 63, SOLID_FILL);
		putQuad(enemy2.pos.x, enemy2.pos.y, enemy2.pos.x + 135, enemy2.pos.y + 31, SOLID_FILL);
		putQuad(enemy3.pos.x, enemy3.pos.y, enemy3.pos.x + 59, enemy3.pos.y + 95, SOLID_FILL);
		putQuad(enemy4.pos.x, enemy4.pos.y, enemy4.pos.x + 63, enemy4.pos.y + 51, SOLID_FILL);
		first = 0;
	}

	press = mouseStatus(SG_LEFT_BUTTON);
	position = mousePos();

	setColor(0, 0, 0);
	putQuad(0, 0, 639, 39, SOLID_FILL);
	setColor(255, 255, 0);
	putNumber(liveTime, 640, 0, 'r');

	if (hasCollision()) {
		first = 1;
		cont = 0;
		drag = 0;
		return;
	}
	if (press==SG_BUTTON_DOWN&&(inRect(position.x, position.y, player.pos.x, player.pos.y, player.pos.x+59, player.pos.y+59)||drag)) {
		if(!cont)liveTime = 0;
		cont = drag = 1;
		movePlayer(position.x - 29, position.y - 29);
	}
	if (press == SG_BUTTON_UP && inRect(position.x, position.y, player.pos.x, player.pos.y, player.pos.x + 59, player.pos.y + 59))drag = 0;
	if (!cont)return;
	else {
		moveEnemy();
		delayEnd(20);
		delayBegin();
		liveTime += 24;
	}
}

void movePlayer(int x, int y) {
	putImage(player.pos.x, player.pos.y, player.oldImage, COPY_PUT);
	setColor(255, 0, 0);
	player.pos.x = x;
	player.pos.y = y;
	free(player.oldImage->data);
	getImage(player.pos.x, player.pos.y, player.pos.x + 83, player.pos.y + 63, player.oldImage);
	putQuad(player.pos.x, player.pos.y, player.pos.x + 59, player.pos.y + 59, SOLID_FILL);
}
void moveEnemy() {
	putImage(enemy1.pos.x, enemy1.pos.y, enemy1.oldImage, COPY_PUT);
	putImage(enemy2.pos.x, enemy2.pos.y, enemy2.oldImage, COPY_PUT);
	putImage(enemy3.pos.x, enemy3.pos.y, enemy3.oldImage, COPY_PUT);
	putImage(enemy4.pos.x, enemy4.pos.y, enemy4.oldImage, COPY_PUT);

	if (liveTime % 10000 < 24) {
		speedUp(enemy1.vel.x);
		speedUp(enemy1.vel.y);
		speedUp(enemy2.vel.x);
		speedUp(enemy2.vel.y);
		speedUp(enemy3.vel.x);
		speedUp(enemy3.vel.y);
		speedUp(enemy4.vel.x);
		speedUp(enemy4.vel.y);
	}

	enemy1.pos.x += enemy1.vel.x;
	enemy1.pos.y += enemy1.vel.y;
	enemy2.pos.x += enemy2.vel.x;
	enemy2.pos.y += enemy2.vel.y;
	enemy3.pos.x += enemy3.vel.x;
	enemy3.pos.y += enemy3.vel.y;
	enemy4.pos.x += enemy4.vel.x;
	enemy4.pos.y += enemy4.vel.y;

	if (enemy1.pos.x < 0) {
		enemy1.pos.x = -enemy1.pos.x;
		enemy1.vel.x = -enemy1.vel.x;
	}
	if (enemy1.pos.x > 555) {
		enemy1.pos.x = 1110-enemy1.pos.x;
		enemy1.vel.x = -enemy1.vel.x;
	}
	if (enemy1.pos.y < 0) {
		enemy1.pos.y = -enemy1.pos.y;
		enemy1.vel.y = -enemy1.vel.y;
	}
	if (enemy1.pos.y > 575) {
		enemy1.pos.y = 1150 - enemy1.pos.y;
		enemy1.vel.y = -enemy1.vel.y;
	}

	if (enemy2.pos.x < 0) {
		enemy2.pos.x = -enemy2.pos.x;
		enemy2.vel.x = -enemy2.vel.x;
	}
	if (enemy2.pos.x > 503) {
		enemy2.pos.x = 1006 - enemy2.pos.x;
		enemy2.vel.x = -enemy2.vel.x;
	}
	if (enemy2.pos.y < 0) {
		enemy2.pos.y = -enemy2.pos.y;
		enemy2.vel.y = -enemy2.vel.y;
	}
	if (enemy2.pos.y > 607) {
		enemy2.pos.y = 1214 - enemy2.pos.y;
		enemy2.vel.y = -enemy2.vel.y;
	}

	if (enemy3.pos.x < 0) {
		enemy3.pos.x = -enemy3.pos.x;
		enemy3.vel.x = -enemy3.vel.x;
	}
	if (enemy3.pos.x > 579) {
		enemy3.pos.x = 1158 - enemy3.pos.x;
		enemy3.vel.x = -enemy3.vel.x;
	}
	if (enemy3.pos.y < 0) {
		enemy3.pos.y = -enemy3.pos.y;
		enemy3.vel.y = -enemy3.vel.y;
	}
	if (enemy3.pos.y > 543) {
		enemy3.pos.y = 1086 - enemy3.pos.y;
		enemy3.vel.y = -enemy3.vel.y;
	}

	if (enemy4.pos.x < 0) {
		enemy4.pos.x = -enemy4.pos.x;
		enemy4.vel.x = -enemy4.vel.x;
	}
	if (enemy4.pos.x > 575) {
		enemy4.pos.x = 1150 - enemy4.pos.x;
		enemy4.vel.x = -enemy4.vel.x;
	}
	if (enemy4.pos.y < 0) {
		enemy4.pos.y = -enemy4.pos.y;
		enemy4.vel.y = -enemy4.vel.y;
	}
	if (enemy4.pos.y > 588) {
		enemy4.pos.y = 1176 - enemy4.pos.y;
		enemy4.vel.y = -enemy4.vel.y;
	}

	free(enemy1.oldImage->data);
	free(enemy2.oldImage->data);
	free(enemy3.oldImage->data);
	free(enemy4.oldImage->data);
	getImage(enemy1.pos.x, enemy1.pos.y, enemy1.pos.x + 83, enemy1.pos.y + 63, enemy1.oldImage);
	getImage(enemy2.pos.x, enemy2.pos.y, enemy2.pos.x + 135, enemy2.pos.y + 31, enemy2.oldImage);
	getImage(enemy3.pos.x, enemy3.pos.y, enemy3.pos.x + 59, enemy3.pos.y + 95, enemy3.oldImage);
	getImage(enemy4.pos.x, enemy4.pos.y, enemy4.pos.x + 63, enemy4.pos.y + 51, enemy4.oldImage);
	setColor(0, 0, 255);
	putQuad(enemy1.pos.x, enemy1.pos.y, enemy1.pos.x + 83, enemy1.pos.y + 63, SOLID_FILL);
	putQuad(enemy2.pos.x, enemy2.pos.y, enemy2.pos.x + 135, enemy2.pos.y + 31, SOLID_FILL);
	putQuad(enemy3.pos.x, enemy3.pos.y, enemy3.pos.x + 59, enemy3.pos.y + 95, SOLID_FILL);
	putQuad(enemy4.pos.x, enemy4.pos.y, enemy4.pos.x + 63, enemy4.pos.y + 51, SOLID_FILL);
}
int hasCollision() {
	if (inRect(player.pos.x, player.pos.y, enemy1.pos.x, enemy1.pos.y, enemy1.pos.x + 83, enemy1.pos.y + 63))return 1;
	if (inRect(player.pos.x, player.pos.y + 29, enemy1.pos.x, enemy1.pos.y, enemy1.pos.x + 83, enemy1.pos.y + 63))return 1;
	if (inRect(player.pos.x, player.pos.y + 59, enemy1.pos.x, enemy1.pos.y, enemy1.pos.x + 83, enemy1.pos.y + 63))return 1;
	if (inRect(player.pos.x + 29, player.pos.y, enemy1.pos.x, enemy1.pos.y, enemy1.pos.x + 83, enemy1.pos.y + 63))return 1;
	if (inRect(player.pos.x + 29, player.pos.y + 59, enemy1.pos.x, enemy1.pos.y, enemy1.pos.x + 83, enemy1.pos.y + 63))return 1;
	if (inRect(player.pos.x + 59, player.pos.y, enemy1.pos.x, enemy1.pos.y, enemy1.pos.x + 83, enemy1.pos.y + 63))return 1;
	if (inRect(player.pos.x + 59, player.pos.y + 29, enemy1.pos.x, enemy1.pos.y, enemy1.pos.x + 83, enemy1.pos.y + 63))return 1;
	if (inRect(player.pos.x + 59, player.pos.y + 59, enemy1.pos.x, enemy1.pos.y, enemy1.pos.x + 83, enemy1.pos.y + 63))return 1;

	if (inRect(player.pos.x, player.pos.y, enemy2.pos.x, enemy2.pos.y, enemy2.pos.x + 135, enemy2.pos.y + 31))return 1;
	if (inRect(player.pos.x, player.pos.y + 29, enemy2.pos.x, enemy2.pos.y, enemy2.pos.x + 135, enemy2.pos.y + 31))return 1;
	if (inRect(player.pos.x, player.pos.y + 59, enemy2.pos.x, enemy2.pos.y, enemy2.pos.x + 135, enemy2.pos.y + 31))return 1;
	if (inRect(player.pos.x + 29, player.pos.y, enemy2.pos.x, enemy2.pos.y, enemy2.pos.x + 135, enemy2.pos.y + 31))return 1;
	if (inRect(player.pos.x + 29, player.pos.y + 59, enemy2.pos.x, enemy2.pos.y, enemy2.pos.x + 135, enemy2.pos.y + 31))return 1;
	if (inRect(player.pos.x + 59, player.pos.y, enemy2.pos.x, enemy2.pos.y, enemy2.pos.x + 135, enemy2.pos.y + 31))return 1;
	if (inRect(player.pos.x + 59, player.pos.y + 29, enemy2.pos.x, enemy2.pos.y, enemy2.pos.x + 135, enemy2.pos.y + 31))return 1;
	if (inRect(player.pos.x + 59, player.pos.y + 59, enemy2.pos.x, enemy2.pos.y, enemy2.pos.x + 135, enemy2.pos.y + 31))return 1;

	if (inRect(player.pos.x, player.pos.y, enemy3.pos.x, enemy3.pos.y, enemy3.pos.x + 59, enemy3.pos.y + 95))return 1;
	if (inRect(player.pos.x, player.pos.y + 29, enemy3.pos.x, enemy3.pos.y, enemy3.pos.x + 59, enemy3.pos.y + 95))return 1;
	if (inRect(player.pos.x, player.pos.y + 59, enemy3.pos.x, enemy3.pos.y, enemy3.pos.x + 59, enemy3.pos.y + 95))return 1;
	if (inRect(player.pos.x + 29, player.pos.y, enemy3.pos.x, enemy3.pos.y, enemy3.pos.x + 59, enemy3.pos.y + 95))return 1;
	if (inRect(player.pos.x + 29, player.pos.y + 59, enemy3.pos.x, enemy3.pos.y, enemy3.pos.x + 59, enemy3.pos.y + 95))return 1;
	if (inRect(player.pos.x + 59, player.pos.y, enemy3.pos.x, enemy3.pos.y, enemy3.pos.x + 59, enemy3.pos.y + 95))return 1;
	if (inRect(player.pos.x + 59, player.pos.y + 29, enemy3.pos.x, enemy3.pos.y, enemy3.pos.x + 59, enemy3.pos.y + 95))return 1;
	if (inRect(player.pos.x + 59, player.pos.y + 59, enemy3.pos.x, enemy3.pos.y, enemy3.pos.x + 59, enemy3.pos.y + 95))return 1;

	if (inRect(player.pos.x, player.pos.y, enemy4.pos.x, enemy4.pos.y, enemy4.pos.x + 63, enemy4.pos.y + 51))return 1;
	if (inRect(player.pos.x, player.pos.y + 29, enemy4.pos.x, enemy4.pos.y, enemy4.pos.x + 63, enemy4.pos.y + 51))return 1;
	if (inRect(player.pos.x, player.pos.y + 59, enemy4.pos.x, enemy4.pos.y, enemy4.pos.x + 63, enemy4.pos.y + 51))return 1;
	if (inRect(player.pos.x + 29, player.pos.y, enemy4.pos.x, enemy4.pos.y, enemy4.pos.x + 63, enemy4.pos.y + 51))return 1;
	if (inRect(player.pos.x + 29, player.pos.y + 59, enemy4.pos.x, enemy4.pos.y, enemy4.pos.x + 63, enemy4.pos.y + 51))return 1;
	if (inRect(player.pos.x + 59, player.pos.y, enemy4.pos.x, enemy4.pos.y, enemy4.pos.x + 63, enemy4.pos.y + 51))return 1;
	if (inRect(player.pos.x + 59, player.pos.y + 29, enemy4.pos.x, enemy4.pos.y, enemy4.pos.x + 63, enemy4.pos.y + 51))return 1;
	if (inRect(player.pos.x + 59, player.pos.y + 59, enemy4.pos.x, enemy4.pos.y, enemy4.pos.x + 63, enemy4.pos.y + 51))return 1;

	if (!inRect(player.pos.x, player.pos.y, 40, 40, 539, 539))return 1;
	return 0;
}

代码是很久很久之前写的了,看起来冗余程度很高,不过我也懒得优化了。


里面用到的背景图片我上传了,可以根据自己的审美p图,让这个程序看起来好看一点。需要注意的一点就是四周那个黑框是有作用的,需要保留,中间的空白可以换成自己喜欢的图片。但是,我没换过背景图片,不保证没有bug。

空白背景图片

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SGL基本思路讲解 的相关文章

随机推荐

  • ABIs [armeabi] are not supported for platform 的解决

    解决方法 在app的build gradle的ndk标签下 将armeabi 删除掉 修改前 ndk abiFilters armeabi armeabi v7a 修改后 ndk abiFilters armeabi v7a 附详细出错lo
  • matlab textscan读结构化.txt文件

    要用 matlab 读之前处理的 COCO 的 ID map 1 将 sample ID 映射去 image name 用来读图片 ID map 文件每一行的形如 0 9 000000000009 jpg 空格间开 第一列是 sample
  • (安装pclpy)pclpy+windows+anaconda

    pclpy 0 12 0版本 支持windows的python3 6和3 7版本 但pclpy 0 12 0移除了可视化模块 即看不到点云效果了 安装方法 进入对应python版本的虚拟环境 然后输入 pip install pclpy 0
  • kylin在hadoop 中的架构图_kylin跨集群配置实现读写分离

    社区提供的读写分离架构图如下 通过架构图可以看到Kylin会访问两个集群的HDFS 建议两个集群的NameService务必不能相同 尤其是集群启用NameNode HA时 相同的NameService会导致组件在跨集群访问HDFS时因无法
  • nginx配置ssl证书https解决公网ip可以访问但是域名不行的问题

    进入nginx文件夹 将下载得到的crt和key文件放到这个目录下 以下来自腾讯云官方 https cloud tencent com document product 400 35244 server SSL 访问端口号为 443 lis
  • 警告:[SetPropertiesRule]Setting property 'source' to xxx did not find a matching property.的消除

    启动JSP页面时报错 全文如下 九月 25 2016 7 47 39 下午 org apache tomcat util digester SetPropertiesRule begin 警告 SetPropertiesRule Serve
  • Python(练习七)

    一 max 0 count 0 while True num int input Enter a number 0 for end of input if num 0 break if num gt max max num count 1
  • mongodb如何使用授权登录

    前言 mongodb默认是不需要授权登录的 这样在实际生产环境中是非常危险的一件事情 接下来就来讲一下如何开启安全授权访问 1 第一次登录不启动授权 默认就是不启动 我们先来创建admin和root账号 他们是用来开启授权后操作用户 创建数
  • PWNHUB 一场新鲜赛事速达【六月内部赛】 web - login game + Misc - 伏羲八卦

    PWNHUB 一场新鲜赛事速达 六月内部赛 web login game Misc 伏羲八卦 web login game Misc 伏羲八卦 本文来自csdn的 shu天 平时会记录ctf 取证和渗透相关的文章 欢迎大家来我的主页 shu
  • thinkpad笔记本如何进bios设置u盘启动步骤

    thinkpad笔记本从u盘启动有两种方法 一种是使用u盘启动快捷键直接进入u盘装系统 另一种则需要进bios设置u盘为第一启动项 但首先要下载个u盘启动盘制作工具制作成启动u盘在进行 下面详细为大家介绍如何操作 方法一 使用u盘启动快捷键
  • 脚本一:编写一个脚本要求检测文件类型(简化版)

    要求 1 命名为check file sh 2 检测判断它是否存在 3 判断它是否为普通文件 4 判断其是否为目录 5 判断其是否为软链接 6 如没有文件名则报错 编写脚本如下 验证文件如下 可见如果文件不存在 直接报错 如果符合条件直接给
  • 《Web安全基础》05. XSS · CSRF · SSRF · RCE

    web 1 XSS 1 1 简介 1 2 防护与绕过 1 2 1 HttpOnly 1 2 2 WAF 绕过 1 3 相关资源 2 CSRF 3 SSRF 4 RCE 本系列侧重方法论 各工具只是实现目标的载体 命令与工具只做简单介绍 其使
  • 行人属性识别的一个调研

    行人属性识别的一个调研 知乎 前言 我感觉我掌握了财富密码 从知乎的后台数据来看 大家貌似更喜欢看综述多一点 因此这次给大家整个 行人属性识别 PAR 的综述 同样的 这次的综述比较老 是19年的 大家酌情看 适合入门用 首先还是保命时刻
  • 【会议分享】2022年智能车国际会议(ICoIV 2022)

    2022年智能车国际会议 ICoIV 2022 重要信息 会议网址 www icoiv org 会议时间 2022年10月14 16日 召开地点 中国成都 截稿时间 2022年8月30日 录用通知 投稿后2周内 收录检索 EI Scopus
  • 爬虫从入门到精通(8)

    文章目录 一 多进程和多线程介绍 二 普通爬虫 三 多线程爬虫 1 普通方法调用 2 线程类调用 四 多进程爬虫 1 普通方法调用 2 进程类写法 五 gevent协程爬虫 1 gevent模块简介 2 安装和依赖 3 gevent协程爬虫
  • 【深度学习】AlexNet

    从AlexNet开始 一 不可否认 深度学习的热潮正是由2012年AlexNet的出现而引发的 因此 学习AlexNet网络的结构 对于CNN的学习与理解是不可或缺的 在本篇博客中 将会对AlexNet的论文进行翻译与解读 并在下一篇博客中
  • android 壁纸服务,Android-Service实现手机壁纸自动更换

    本文实例为大家分享了Android Service实现自动更换手机壁纸的具体代码 供大家参考 具体内容如下 先看下效果 使用界面 划重点 使用service前别忘了给相应的service添加服务 具体实现 首先定义ChangeService
  • Dialog的exec和open

    今天在使用窗口时 发现了这样一个问题 抽象代码如下 结果第一次调用窗口时 一切正常 但是第二次调用时 窗口里的内容全部消失了 只有一个空白窗口 解决方法 调用open 函数 exec 函数会将程序卡到那里 open 函数生成窗口后立即返回
  • 祭旗之作

    渺小的我 一如原来那样的懒散 我拼命的使自己跟的牛人学习 但是 我总是掉队 我不愿意平庸 但是对于任何事情感觉都是没有坚持到最后 应该更加的坚持 犹豫与多虑 是我的性格 我渴望一直坚持下去 但好多时候 由于时间的关系 选择了放弃 我依然是我
  • SGL基本思路讲解

    SGL图形库是为Windows图形界面编程服务的 而且一切都是考虑到对新手友好的 在具体介绍提供给用户的函数之前 需要先说明一下应该以什么样的思路来构思我们的SGL程序 作为C语言程序 main函数总是需要在最开始就了解一下的 在SGL库中