想敲代码又怕女朋友找?那就让她去玩桌面图标贪吃蛇,再也不用担心打扰自己敲代码了
想敲代码又怕女朋友找?那就让她去玩桌面图标贪吃蛇,再也不用担心打扰自己敲代码了
最近在逛博客的时候看见了一个有趣的项目,使用桌面图标进行贪吃蛇游戏。采用的代码是vb,但我实在不会vb,就找了C++中关于桌面图标获取句柄的文章进行查看(第一次接触这个,实属菜鸟)。效果还行 一步步获取到了想要的东西,然后偶然性看见了一位python大佬的博客,这就很OK了,看python代码就没啥问题了,然后就复制复制复制,看了一遍他的代码,接着就是来一个golang版的了。
在这里附上这位python版大佬的文章地址:用Windows10桌面图标玩python贪吃蛇
程序简单,思路算明确,至少我一遍就看懂了整个流程。然后就来一个golang吧。
一、定义一个航线结构体
type Vector struct {x int32y int32
}func (vector *Vector) Add(vec Vector) Vector {return Vector{vector.x + vec.x, vector.y + vec.y}
}func (vector *Vector) Set(vec Vector) {vector.x = vec.xvector.y = vec.y
}func (vector *Vector) Mult(num int32) Vector {return Vector{vector.x * num, vector.y * num}
}
这里就不累赘了,简单的来说就是一个步伐坐标点。
二、获取窗体句柄、窗体大小以及图标数
这里使用了 “github.com/lxn/win” 包。下载吧,直接go get
至于这里如何获取桌面的句柄吧,给为可参考spy++如何使用的。
从spy++中可以看见,要获取viewlist窗口的句柄,只需要从"Program Manager"获取两级子窗口即可。
var hwnd win.HWNDhwnd = win.FindWindow(nil, syscall.StringToUTF16Ptr("Program Manager"))hwnd = win.GetWindow(hwnd, win.GW_CHILD)
hwnd = win.GetWindow(hwnd, win.GW_CHILD)
var rect win.RECT
win.GetWindowRect(hwnd, &rect)
count := win.SendMessage(hwnd, win.LVM_GETITEMCOUNT, 0, 0)
代码如上,其中LVM_GETITEMCOUNT对于这个常量在,lxn/win这个包中并没有,所有我们就手动给他加一个即可。listview.go文件。
LVM_GETITEMCOUNT = LVM_FIRST + 4
三、给每一个图标进行位置重定位
pos = make([]Vector, count)
pos[0] = Vector{rect.Right / 2, rect.Bottom / 2}
pos[1] = Vector{rect.Right / 2, rect.Bottom / 2}
pos[2] = Vector{rand.Int31n(rect.Right-400) + 200, rand.Int31n(rect.Bottom-400) + 200}
win.SendMessage(hwnd, win.LVM_SETITEMPOSITION, 0, MAKELPARAM(pos[0].x, pos[0].y))
win.SendMessage(hwnd, win.LVM_SETITEMPOSITION, 1, MAKELPARAM(pos[1].x, pos[1].y))
lcur := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&cur))))
fmt.Println(lcur)
win.SendMessage(hwnd, win.LVM_SETITEMPOSITION, lcur, MAKELPARAM(pos[cur].x, pos[cur].y))
var i int
countInt = *(*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&count))))
for i = cur + 1; i < countInt; i++ {pos[i] = Vector{0, -100}lp := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&i))))win.SendMessage(hwnd, win.LVM_SETITEMPOSITION, lp, MAKELPARAM(pos[i].x, pos[i].y))
}
代码如上,其中LVM_SETITEMPOSITION对于这个常量在,lxn/win这个包中并没有,所有我们就手动给他加一个即可。listview.go文件。
LVM_SETITEMPOSITION = LVM_FIRST + 15
四、实现一个键盘监听
这个简单,直接上代码了:
func getKey() {for {if windev.KeyDownUp(windev.VK_LEFT) == 1 {key = 37}if windev.KeyDownUp(windev.VK_UP) == 1 {key = 38}if windev.KeyDownUp(windev.VK_RIGHT) == 1 {key = 39}if windev.KeyDownUp(windev.VK_DOWN) == 1 {key = 40}}
}
五、实现一个贪吃蛇了
首先是当蛇头位置改变时,后面的蛇身也需要跟着变化,那么剧需要对每一个位置重新赋值。
func run(pv Vector) {for i := cur - 1; i > 0; i-- {pos[i].Set(pos[i-1])}pos[0] = pos[0].Add(pv.Mult(60))for i := 0; i < countInt; i++ {lp := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&i))))win.SendMessage(hwnd, win.LVM_SETITEMPOSITION, lp, MAKELPARAM(pos[i].x, pos[i].y))}time.Sleep(time.Millisecond * 200)
}func MAKELPARAM(x, y int32) uintptr {xt := int(x)yt := int(y)tem := yt << 16a := (*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&tem))))b := (*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&xt))))return *a | *b
}
然后将键盘控制结合:
for {// var v Vectorv := Vector{0, 0}if key == 37 {v = Vector{-1, 0}}if key == 38 {v = Vector{0, -1}}if key == 39 {v = Vector{1, 0}}if key == 40 {v = Vector{0, 1}}run(v)f1, _ := strconv.ParseFloat(fmt.Sprintf("%d", pos[0].x-pos[cur].x), 64)f2, _ := strconv.ParseFloat(fmt.Sprintf("%d", pos[0].y-pos[cur].y), 64)// fmt.Println(math.Sqrt(math.Pow(f1, 2) + math.Pow(f2, 2)))if math.Sqrt(math.Pow(f1, 2)+math.Pow(f2, 2)) < 60 {fmt.Println("jinru")cur++pos[cur].Set(Vector{rand.Int31n(rect.Right-400) + 200, rand.Int31n(rect.Bottom-400) + 200})lp := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&cur))))win.SendMessage(hwnd, win.LVM_SETITEMPOSITION, lp, MAKELPARAM(pos[cur].x, pos[cur].y))}fmt.Printf("当前蛇头地址坐标:%d,%d\n", pos[0].x, pos[0].y)fmt.Printf("当前食物地址坐标:%d,%d\n", pos[cur].x, pos[cur].y)
}
六、全部实现代码
package mainimport ("fmt""math""math/rand""strconv""syscall""time""unsafe""github.com/cppdebug/windev""github.com/lxn/win"
)type Vector struct {x int32y int32
}func (vector *Vector) Add(vec Vector) Vector {return Vector{vector.x + vec.x, vector.y + vec.y}
}func (vector *Vector) Set(vec Vector) {vector.x = vec.xvector.y = vec.y
}func (vector *Vector) Mult(num int32) Vector {return Vector{vector.x * num, vector.y * num}
}var cur = 2
var key intfunc getKey() {for {if windev.KeyDownUp(windev.VK_LEFT) == 1 {key = 37}if windev.KeyDownUp(windev.VK_UP) == 1 {key = 38}if windev.KeyDownUp(windev.VK_RIGHT) == 1 {key = 39}if windev.KeyDownUp(windev.VK_DOWN) == 1 {key = 40}}
}var pos []Vector
var countInt int
var hwnd win.HWNDfunc main() {rand.Seed(time.Now().UnixNano())hwnd = win.FindWindow(nil, syscall.StringToUTF16Ptr("Program Manager"))hwnd = win.GetWindow(hwnd, win.GW_CHILD)hwnd = win.GetWindow(hwnd, win.GW_CHILD)var rect win.RECTwin.GetWindowRect(hwnd, &rect)count := win.SendMessage(hwnd, win.LVM_GETITEMCOUNT, 0, 0)fmt.Println(count)pos = make([]Vector, count)pos[0] = Vector{rect.Right / 2, rect.Bottom / 2}pos[1] = Vector{rect.Right / 2, rect.Bottom / 2}pos[2] = Vector{rand.Int31n(rect.Right-400) + 200, rand.Int31n(rect.Bottom-400) + 200}win.SendMessage(hwnd, win.LVM_SETITEMPOSITION, 0, MAKELPARAM(pos[0].x, pos[0].y))win.SendMessage(hwnd, win.LVM_SETITEMPOSITION, 1, MAKELPARAM(pos[1].x, pos[1].y))lcur := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&cur))))fmt.Println(lcur)win.SendMessage(hwnd, win.LVM_SETITEMPOSITION, lcur, MAKELPARAM(pos[cur].x, pos[cur].y))var i intcountInt = *(*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&count))))for i = cur + 1; i < countInt; i++ {pos[i] = Vector{0, -100}lp := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&i))))win.SendMessage(hwnd, win.LVM_SETITEMPOSITION, lp, MAKELPARAM(pos[i].x, pos[i].y))}go getKey()print(key)for {// var v Vectorv := Vector{0, 0}if key == 37 {v = Vector{-1, 0}}if key == 38 {v = Vector{0, -1}}if key == 39 {v = Vector{1, 0}}if key == 40 {v = Vector{0, 1}}run(v)f1, _ := strconv.ParseFloat(fmt.Sprintf("%d", pos[0].x-pos[cur].x), 64)f2, _ := strconv.ParseFloat(fmt.Sprintf("%d", pos[0].y-pos[cur].y), 64)// fmt.Println(math.Sqrt(math.Pow(f1, 2) + math.Pow(f2, 2)))if math.Sqrt(math.Pow(f1, 2)+math.Pow(f2, 2)) < 60 {fmt.Println("jinru")cur++pos[cur].Set(Vector{rand.Int31n(rect.Right-400) + 200, rand.Int31n(rect.Bottom-400) + 200})lp := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&cur))))win.SendMessage(hwnd, win.LVM_SETITEMPOSITION, lp, MAKELPARAM(pos[cur].x, pos[cur].y))}fmt.Printf("当前蛇头地址坐标:%d,%d\n", pos[0].x, pos[0].y)fmt.Printf("当前食物地址坐标:%d,%d\n", pos[cur].x, pos[cur].y)}
}func run(pv Vector) {for i := cur - 1; i > 0; i-- {pos[i].Set(pos[i-1])}pos[0] = pos[0].Add(pv.Mult(60))for i := 0; i < countInt; i++ {lp := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&i))))win.SendMessage(hwnd, win.LVM_SETITEMPOSITION, lp, MAKELPARAM(pos[i].x, pos[i].y))}time.Sleep(time.Millisecond * 200)
}func MAKELPARAM(x, y int32) uintptr {xt := int(x)yt := int(y)tem := yt << 16a := (*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&tem))))b := (*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&xt))))return *a | *b
}
最后执行的时候别忘了,把这个取消了。点个赞收藏一波哦
如有需要改程序.exe执行文件的,可点击免费下载:桌面贪吃蛇go版.exe
想敲代码又怕女朋友找?那就让她去玩桌面图标贪吃蛇,再也不用担心打扰自己敲代码了相关推荐
- Idea代码自动补全!插件推荐:Codota,再也不用担心写不出代码了。
前言 最近,有小伙伴推荐给D哥一款IDEA插件,叫我一定得给大家分享一下,简直太好用了~ 这款插件解决的痛点:当你不知道一个类该怎么用的时候,它能帮你快速找到想要的实例代码. 群里有不少同学说,&qu ...
- Idea代码自动补全,良心插件推荐:Codota,再也不用担心写不出代码了。
这款插件就是 Codota.基于AI技术,通过对大量开源的项目学习,帮助开发者提供更可靠的智能推荐,让编程变得更easy! 官网:https://www.codota.com 看官方发现,目前支持的语 ...
- 看完这篇文章再也不用担心代码格式不对无法合并了
本文由RT-Thread论坛用户@RTT_逍遥原创发布:https://club.rt-thread.org/ask/article/3121.html GITHUB仓库: git_auto_scri ...
- php你们想不到的强大,找电影的好网站,再也不用担心下不到好电影了!
找电影的好网站,再也不用担心下不到好电影了! 首先要声明一点,往前方不会推荐PT站或者其他需要邀请注册的网站,本文提到的一定都是无需注册或者开放注册的.简单实用的网站. 如果你不是那么热爱电影,只是闲 ...
- 自媒体人必备的4个素材网站,再也不用担心找不到素材
经常看到很多自媒体人问,不知道怎么找素材,每次写文章的时候都觉得灵感枯竭,素材不够用,文章没有足够的内容支撑.不慌,今天就给大家介绍5个实用的素材网站,让你再也不用担心找不到素材: 01 热文素材-- ...
- 自助定制OpenWRT,麻麻再也不用担心我找不到固件用辣
博客地址:自助定制OpenWRT,麻麻再也不用担心我找不到固件用辣 - 黄·BLOG (huanggame.top) 众所周知,OpenWRT是一款出色的路由器固件,他可以安装许多插件以提升用户体验. ...
- 重装系统后桌面找不到计算机,电脑重装找不到桌面文件了?教你一招,再也不用担心文件消失!...
原标题:电脑重装找不到桌面文件了?教你一招,再也不用担心文件消失! 在工作中,我们习惯性的都会将一些文件直接保存在桌面,这样方便我们去查找,但是也会遇到电脑系统崩溃,需要重装电脑,不过这时候在登录到桌 ...
- 有了这套模板,女朋友再也不用担心我刷不动 LeetCode 了
作者 | 李威 来源 | https://www.liwei.party/ 整理 | 五分钟学算法 全文包含 12000+ 字.30 张高清图片,预计阅读时间为 40 分钟,强烈建议先收藏再仔细阅读. ...
- c++贪吃蛇游戏-详细解释-非单纯贴代码
先说明下:本文来源:https://blog.csdn.net/silence1772/article/details/55005008 写在前面,这个项目,希望大家先下载下来,玩一玩.然后2天左右把 ...
最新文章
- 数据结构Stack:关系以及方法
- 第八周项目二-用对象数组操作长方柱类
- .Net 之匿名类(AnonymousType)(转载)
- 监控服务器登录用户的操作脚本(linux下shell.sh)
- js中函数的参数为函数的情况即回调函数
- 【图数据结构的遍历】java实现广度优先和深度优先遍历
- Android中用GridView实现九宫格的两种方法(转)
- 新手学完Java可以面试哪些岗位?
- Oracle在JavaOne上宣布Java EE 8将会延期至2017年底
- ecshop二次开发 给商品添加自定义字段【包含我自己进一步的开发实例详解】
- 一般处理程序在VS2012中打开问题
- 量子计算机美国华裔科学家,量子计算机很神?18岁华裔少年用经典计算机算得一样快...
- ADL SDK V10.2 中文文档
- 前端九年老司机的一天作息
- 购买服务器不显示d盘,购买云服务器后d盘
- Android测试——(下篇)
- 二十三种设计模式之原型模式
- 从正多面体到斐波拉契网格
- 大工21春《船舶制图》大作业离线作业
- 网络通信面试题详细解答