Mint_21.3 drawing-area和goocanvas的FB笔记(六)

FreeBASIC gfx 基本 graphics 绘图

一、旧故事

DOS时代PC技术将各类硬插卡限制在 640K到1MB的空间范围内,BIOS负责在相关位置写读测试卡的存在,那时期的Color Video在0xB800,Monochrome Video在0xB000,这是显卡的内存地址,字符方式下通常用2个byte共16位显示一个字符,首字节是ASCII值,另外一个字节(8BIT)为属性字节,高4位表示背景色、低4位表示前景色。因为用4位颜色表示,0xF种色彩就是16种颜色,编号 0 - 15。

QuickBASIC示例 - 白字蓝底:
Color 15, 1: Locate 12, 32: Print "Hello World!"

二、FreeBASIC进化

随着视窗的发展,一些复杂的内存管理交给了CPU处理,不再是原来与卡密切相关的固定显存地址,取而代之的是可大可小的窗口。FreeBASIC保留了原有的13种显示模式,同时增加到了21种,达到1280x1024, 160列x128行,256K颜色。

除此之外,继续演进,增加了screenres 指令,可以任意定义窗口尺寸,比如: screenres 1920, 1080, 32, 5, 0, 0 或简写为 screenres 1920, 1080, 32 , 其它参数均为 default 值。它创建一个 1920x1080像素的屏幕(不是实际意义上的屏幕,但仍称其为screen,是个绘图用的surface而已),用32位颜色,5个页面(一个活动可见页面,其它的在内存中不可见,考贝到可见页即可见), 接着的0表示全屏或显示驱动的选择。由于相关定义变得复杂,此时编程需使用 gfxlib 支持。

三、屏幕变为窗口后的编程

1、示例一:屏幕变为窗口

screen 9是640x480标准模式。过去,设置完屏幕方式后即可print或line绘图; 现在,它是一个窗口,因此,可以设置它的标题 WindowTitle "FreeBASIC example program",还可加一句非常简便的无限等待 sleep 语句,直到有按键动作时退出。

Locate 和 Line 都是传统 QBasic 使用的绘图语句。

'' examples/manual/gfx/windowtitle.bas
''
'' Example extracted from the FreeBASIC Manual
'' from topic 'WINDOWTITLE'
''
'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgWindowtitle
'' --------
'' Modified: Mongnewer 9, March 2024'Set screen mode 
Screen 9'Set the window title
WindowTitle "FreeBASIC example program"Locate 12, 35: Print "Hello World!"
line (200, 100) - (440, 220), 4, bSleep

2、绘图锁定与缩放

在屏幕绘图前先 screenlock, 绘图后 screenunlock, 并通过 window 函数改变座标系而circle本身的参数则无需变化。屏幕上显示一个连续缩放的黄色填充的圆形,锁定的目的是绘图完成后一次性显示到屏幕上,避免了绘制过程的拖慢效果。

'' examples/manual/gfx/window2.bas
''
'' Example extracted from the FreeBASIC Manual
'' from topic 'WINDOW'
''
'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgWindow
'' --------'' The program shows how changing the view coordinates mapping for the current viewport changes the size of a figure drawn on the screen.
'' The effect is one of zooming in and out:
''   - As the viewport coordinates get smaller, the figure appears larger on the screen, until parts of it are finally clipped,
''        because they lie outside the window.
''   - As the viewport coordinates get larger, the figure appears smaller on the screen.
'' ---------------------------------
'' Modified: Mongnewer 9, March 2024Declare Sub Zoom (ByVal X As Integer)
Dim As Integer X = 500, Xdelta = 50Screen 12
DoDo While X < 525 And X > 50X += Xdelta                      '' Change window size.Zoom(X)If Inkey <> "" Then Exit Do, Do  '' Stop if key pressed.Sleep 100LoopX -= XdeltaXdelta *= -1                       '' Reverse size change.
LoopSub Zoom (ByVal X As Integer)Window (-X,-X)-(X,X)               '' Define new window.ScreenLockClsCircle (0,0), 60, 14, , , 0.7, F   '' Draw ellipse with x-radius 60.ScreenUnlock
End Sub

3 、view and window, draw string

view 是在screen窗口中创建视图区,而window 语句是视图区的新座标系、不带参数时取消所建立的座标系,Draw string 与 print 类似但又不同, 它不同按行显示字符串,是按 x, y 位置绘制字符串。

'' examples/manual/gfx/window.bas
''
'' Example extracted from the FreeBASIC Manual
'' from topic 'WINDOW'
''
'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgWindow
'' --------Screen 13'' define clipping area
View ( 10, 10 ) - ( 310, 150 ), 1, 15    '' set view coordinates
Window ( -1, -1 ) - ( 1, 1 )             '' Draw X axis
Line (-1,0)-(1,0),7
Draw String ( 0.8, -0.1 ), "X"'' Draw Y axis
Line (0,-1)-(0,1),7
Draw String ( 0.1, 0.8 ), "Y"Dim As Single x, y, s'' compute step size (corresponds to a step of 1 pixel on x coordinate)
s = 2 / PMap( 1, 0 )'' plot the function
For x = -1 To 1 Step sy = x ^ 3PSet( x, y ), 14
Next x'' revert to screen coordinates
Window'' remove the clipping area
View'' draw title
Draw String ( 120, 160 ), "Y = X ^ 3"Sleep

4、在内存中绘像素后显示在屏幕窗口

image pixel , 简写 ip,ip = ImageCreate(64, 64),在内存中创建一个64x64像素的像素块,ip是它的指针。

QBasic原有的PSet后面带上参数 ip, 表示在 ip 内存块pset像素点

screensync 是等待场同步信号,在换场的间隙中把图显示在屏幕窗口上,从而最大限度地减小抖动发生(这个语句的受限点是变换速度被限定在了场频之内),在等待场同步时screenlock后绘图,绘好后screenunlock,将图显示到屏幕上,最后要imagedestroy(ip)销毁创建的像素块。因为在蓝框内有个view, 在view中显示的像素块。

'' examples/manual/gfx/view.bas
''
'' Example extracted from the FreeBASIC Manual
'' from topic 'VIEW (GRAPHICS)'
''
'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgViewgraphics
'' --------Screen 12
Dim ip As Any Ptr
Dim As Integer x, y'simple sprite
ip = ImageCreate(64,64)
For y = 0 To 63For x = 0 To 63PSet ip, (x, y), (x\4) Xor (y\4)Next x
Next y'viewport with blue border
Line (215,135)-(425,345), 1, bf
View (220,140)-(420,340)'move sprite around the viewport
Dox = 100*Sin(Timer*2.0)+50y = 100*Sin(Timer*2.7)+50ScreenSyncScreenLock'clear viewport and put imageCls 1Put (x, y), ip, PSetScreenUnlockLoop While Inkey = ""ImageDestroy(ip)

5、显示内存的考贝

screenres 创建屏幕窗口。screenset 1, 0 设置工作页为1页(0页为正在显示的画面)。screensync等待场同步信号。screencopy 将工作页面1考贝到显示页面0,完成显示一个移动的红方块。如果将一个跑步者的不同像素块放在不同的工作页面,然后随场同步显示,则是一幅跑步画面。

'' examples/manual/gfx/screenset.bas
''
'' Example extracted from the FreeBASIC Manual
'' from topic 'SCREENSET'
''
'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgScreenset
'' --------' Open graphics screen (320*200, 8bpp) with 2 pages
ScreenRes 320, 200, 8, 2' Work on page 1 while displaying page 0
ScreenSet 1, 0Dim As Integer x = -40Do'' Clear the screen, draw a box, update xClsLine (x, 80)-Step(39, 39), 4, BFx += 1: If (x > 319) Then x = -40' Wait for vertical sync: only used to control refresh rate, can be put anywhere in the Do loopScreenSync' Copy work page to visible pageScreenCopyLoop While Inkey = ""

6、显示窗口指针

一个正在显示的窗口,实际是一张像素块,它有对应的内存,而内存地址就是显示窗口的指针,在freebasic中用screenptr获得。screeninfo w, h, , bypp, pitch获得屏幕窗口的长、宽、色彩模式和一行的像素数(因此才能知道什么时候换行),在cairo绘图时也会看到这个参数的使用。移动指针、放置数据,即得到欲显示的图像。

'' examples/manual/gfx/screenptr2.bas
''
'' Example extracted from the FreeBASIC Manual
'' from topic 'SCREENPTR'
''
'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgScreenptr
'' --------'Const SCREEN_WIDTH = 256, SCREEN_HEIGHT = 256
Const SCREEN_WIDTH = 1024, SCREEN_HEIGHT = 768
Dim As Long w, h, bypp, pitch'' Make 32-bit screen.
ScreenRes SCREEN_WIDTH, SCREEN_HEIGHT, 32'' Get screen info (w and h should match the constants above, bypp should be 4)
ScreenInfo w, h, , bypp, pitch'' Get the address of the frame buffer. An Any Ptr 
'' is used here to allow simple pointer arithmetic
Dim buffer As Any Ptr = ScreenPtr()
If (buffer = 0) ThenPrint "Error: graphics screen not initialized."SleepEnd -1
End If'' Lock the screen to allow direct frame buffer access
ScreenLock()'' Set row address to the start of the bufferDim As Any Ptr row = buffer'' Iterate over all the pixels in the screen:For y As Integer = 0 To h - 1'' Set pixel address to the start of the row'' It's a 32-bit pixel, so use a ULong PtrDim As ULong Ptr pixel = rowFor x As Integer = 0 To w - 1'' Set the pixel value*pixel = RGB(x, x Xor y, y) '' Get the next pixel address '' (ULong Ptr will increment by 4 bytes)pixel += 1Next x'' Go to the next rowrow += pitchNext y'' Unlock the screen.
ScreenUnlock()'' Wait for the user to press a key before closing the program
Sleep

7、获得鼠标和键盘事件

需要 fbgfx.bi 支持,event 是freebasic中的一个type类,它含有事件的名称和附带参数。 Dim e as event 定义 e 为 event 类 ;  if (screenEvent(@e)) then 是如果有事件发生; e.type 是查看发生的事件。 e.scancode 是查看键盘扫描码; e.ascii 是按下键的ascii值; e.dx, e.dy是鼠标的位置; e.button是按的左键或右键, 如果左右键同时按,被视为中间键。

'' examples/manual/gfx/screenevent.bas
''
'' Example extracted from the FreeBASIC Manual
'' from topic 'SCREENEVENT'
''
'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgScreenevent
'' --------'' include fbgfx.bi for some useful definitions
#include "fbgfx.bi"
#if __FB_LANG__ = "fb"
Using fb '' constants and structures are stored in the FB namespace in lang fb
#endifDim e As EventScreenRes 640, 480
DoIf (ScreenEvent(@e)) ThenSelect Case e.typeCase EVENT_KEY_PRESSIf (e.scancode = SC_ESCAPE) ThenEndEnd IfIf (e.ascii > 0) ThenPrint "'" & e.ascii & "'";ElsePrint "unknown key";End IfPrint " was pressed (scancode " & e.scancode & ")"Case EVENT_KEY_RELEASEIf (e.ascii > 0) ThenPrint "'" & e.ascii & "'";ElsePrint "unknown key";End IfPrint " was released (scancode " & e.scancode & ")"Case EVENT_KEY_REPEATIf (e.ascii > 0) ThenPrint "'" & e.ascii & "'";ElsePrint "unknown key";End IfPrint " is being repeated (scancode " & e.scancode & ")"Case EVENT_MOUSE_MOVEPrint "mouse moved to " & e.x & "," & e.y & " (delta " & e.dx & "," & e.dy & ")"Case EVENT_MOUSE_BUTTON_PRESSIf (e.button = BUTTON_LEFT) ThenPrint "left";ElseIf (e.button = BUTTON_RIGHT) ThenPrint "right";ElsePrint "middle";End IfPrint " button pressed"Case EVENT_MOUSE_BUTTON_RELEASEIf (e.button = BUTTON_LEFT) ThenPrint "left";ElseIf (e.button = BUTTON_RIGHT) ThenPrint "right";ElsePrint "middle";End IfPrint " button released"Case EVENT_MOUSE_DOUBLE_CLICKIf (e.button = BUTTON_LEFT) ThenPrint "left";ElseIf (e.button = BUTTON_RIGHT) ThenPrint "right";ElsePrint "middle";End IfPrint " button double clicked"Case EVENT_MOUSE_WHEELPrint "mouse wheel moved to position " & e.zCase EVENT_MOUSE_ENTERPrint "mouse moved into program window"Case EVENT_MOUSE_EXITPrint "mouse moved out of program window"Case EVENT_WINDOW_GOT_FOCUSPrint "program window got focus"Case EVENT_WINDOW_LOST_FOCUSPrint "program window lost focus"Case EVENT_WINDOW_CLOSEEndCase EVENT_MOUSE_HWHEELPrint "horizontal mouse wheel moved to position " & e.wEnd SelectEnd IfSleep 1
Loop

至此,应该可以写个简单的石头剪刀布游戏了。

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

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

相关文章

Java中介者模式剖析及使用场景

中介者模式 一、介绍二、智能家居系统项目实现三、总结1.优点2.缺点3.使用经验4.Spring框架类似使用思想 一、介绍 介者模式是一种行为型设计模式&#xff0c;它允许对象之间通过一个中介者对象进行通信&#xff0c;而不是直接相互引用。将多对多的关系转化为一对多的关系&…

iOS17.4获取UDID安装mobileconfig描述文件失败 提示“安全延迟进行中”问题 | 失窃设备保护

iOS17.4这两天已经正式发布&#xff0c; 在iOS 17.4版本中新增了一个名为"失窃设备保护"的功能&#xff0c;并提供了一个"需要安全延迟"的选项。 iOS17.4获取UDID安装mobileconfig描述文件失败 提示“安全延迟进行中”问题 | 失窃设备保护 当用户选择启用…

美洲狮优化算法(Puma Optimizar Algorithm ,POA)求解机器人栅格地图最短路径规划(提供MATLAB代码)

一、美洲狮优化算法 美洲狮优化算法&#xff08;Puma Optimizar Algorithm &#xff0c;POA&#xff09;由Benyamin Abdollahzadeh等人于2024年提出&#xff0c;其灵感来自美洲狮的智慧和生活。在该算法中&#xff0c;在探索和开发的每个阶段都提出了独特而强大的机制&#xf…

MySQL在报表统计中的综合实践:SQL语句与函数应用

引言 在数据分析与报表制作领域&#xff0c;MySQL因其出色的性能和丰富的统计功能&#xff0c;成为了众多企业构建报表系统的首选数据库引擎。本篇文章将深度剖析如何利用MySQL的SQL语句和统计函数完成日常报表统计任务&#xff0c;包括但不限于按天、周、月、季度和年的数据汇…

【LeetCode: 212. 单词搜索 II - dfs】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

华为OD机试C卷“跳步-数组”Java解答

描述 示例 算法思路1 不断移动数组将元素删去&#xff08;并未彻底删除&#xff0c;而是将数字元素前移实现“伪删除”&#xff09;这样删除元素的位置就呈现一定规律&#xff0c;详细见下图&#xff08;潦草的画&#xff09; 答案1 import java.util.*;public class Main {…

Neovim基本介绍

目录 Neovim出现的原因优化点安装1.源代码安装2.管理包安装3.下载安装包安装 配置运行健康检查Oni Neovim出现的原因 neovim代码库不需要向后兼容,方便开发维护解决vim插件编写困难,特别是异步操作解决vim插件编写困难,不再要求插件开发者需要熟悉vimscript默认配置适应现代开…

【MySql学习之路】window环境下MySql安装和安装过程中出现的问题

environment:windows software:mysql 本文主要分享mysql关系型数据库在干净的环境下,第一次安装以及在安装过程中出现的常见问题和解决方法。目前官网给出的安装包有两种格式,一个是msi格式,一个是zip格式的。很多人下了zip格式的解压发现没有setup.exe,面对一堆文件无从…

最全NVIDIA Jetson开发板参数配置和购买指南

NVIDIA开发的GPU不仅在电脑显卡领域占据大量份额&#xff0c;在嵌入式NVIDIA的Jeston系列开发板也近乎是领先的存在&#xff0c;特别是NVIDIA Jeston系列开发板在算力和成本的平衡上都要优于其他厂家&#xff0c;性价比很高&#xff0c;设备体积小。本博文旨在给采购NVIDIA Jes…

2024年华为OD机试真题- 项目排期-Python-OD统一考试(C卷)

题目描述: 项目组共有N个开发人员,项目经理接到了M个独立的需求,每个需求的工作量不同,且每个需求只能由一个开发人员独立完成,不能多人合作。假定各个需求直接无任何先后依赖关系,请设计算法帮助项目经理进行工作安排,使整个项目能用最少的时间交付。 输入描述: 第一行…

【LeetCode每日一题】299. 猜数字游戏

文章目录 [299. 猜数字游戏](https://leetcode.cn/problems/bulls-and-cows/)思路&#xff1a;代码&#xff1a; 299. 猜数字游戏 思路&#xff1a; 遍历两个字符串 secret 和 guess&#xff0c;若字符既在相同位置上又相等&#xff0c;则位置和数字都正确&#xff0c;对应的 …

FPGA 图像亮度、对比度、饱和度调节

1 亮度 1.1 亮度简介 亮度是指图像的光度学或感觉上的属性&#xff0c;它反映了图像的明暗程度。在图像处理中&#xff0c;亮度通常用灰度值表示&#xff0c;灰度值越高&#xff0c;图像看起来越亮&#xff1b;反之&#xff0c;越低则越暗。 对图像进行亮度调节&#xff0c;…

宝塔一键迁移报错创建失败问题完美解决

很多站长朋友在使用宝塔面板迁移的时候总是出错&#xff0c;如图&#xff1a; 遇到这样的问题不要慌&#xff0c;我们已经完美处理&#xff0c;详细解决教程&#xff1a;宝塔一键迁移报错问题完美解决教程

力扣爆刷第90天之hot100五连刷36-40

力扣爆刷第90天之hot100五连刷36-40 文章目录 力扣爆刷第90天之hot100五连刷36-40一、94. 二叉树的中序遍历二、104. 二叉树的最大深度三、26. 翻转二叉树四、101. 对称二叉树五、543. 二叉树的直径 一、94. 二叉树的中序遍历 题目链接&#xff1a;https://leetcode.cn/proble…

【洛谷千题详解】P1838 三子棋I

题目总览 题目描述 小 a 和 uim 喜欢互相切磋三子棋。三子棋大家都玩过是吗&#xff1f;就是在九宫格里面 OOXX&#xff08;别想歪了&#xff09;&#xff0c;谁连成 3 个就赢了。 由于小 a 比较愚蠢&#xff0c;uim 总是让他先。 我们用 9 个数字表示棋盘位置&#xff1a;…

微信小程序跳转到其他小程序

有两种方式&#xff0c;如下&#xff1a; 一、appid跳转 wx.navigateToMiniProgram({appId: 目标小程序appid,path: 目标小程序页面路径,//不配的话默认是首页//develop开发版&#xff1b;trial体验版&#xff1b;release正式版envVersion: release, success(res) {// 打开成功…

JDBC的学习记录

JDBC就是使用java语言操作关系型数据库的一套API。 JDBC&#xff08;Java Database Connectivity&#xff09;是Java语言中用于连接和操作数据库的一种标准接口。它提供了一组方法和类&#xff0c;使Java程序能够与各种不同类型的关系型数据库进行交互。 JDBC的主要功能包括建…

QT 笔记 QGraphicsItem 介绍

介绍 QGraphicsItem是Qt中用于在图形视图框架中表示可视图形项的基类。在Qt的图形视图框架中&#xff0c;你可以使用QGraphicsItem及其派生类来创建可在图形场景中显示的图形元素。下面是关于QGraphicsItem的一些重要信息&#xff1a; 作用&#xff1a;QGraphicsItem是所有在…

Dockerfile指令大全

Dockerfile文件由一系列指令和参数组成。指令的一般格式为INSTRUCTION arguments。具体来说&#xff0c;包括"配置指令"(配置镜像信息)和"操作指令"(具体执行操作)。每条指令&#xff0c;如FROM&#xff0c;都是大小写不敏感的。但是为了区分指令和参数&am…

Angular基础---HelloWorld---Day3

文章目录 0.ng-model 的几种不同的class属性1.ng-model 的引用与属性的调用2.表单验证&#xff1a; (模版引用变量、ngModel 、ngif一起使用&#xff09;3.根据class属性的值ng-invalid &#xff0c;设置动态变化的样式 0.ng-model 的几种不同的class属性 引用ng-model 元素的c…