喵宅苑 MewoGarden × 技术宅社区II | Z站 Z Station 棒棒哒纯文字二次元技术社区

正文

Go与SDL写小游戏(三)----井字游戏

作者:foodszhu
[i=s] 本帖最后由 foodszhu 于 2013-4-2 01:03 编辑 无聊啊无聊啊$38$、 前面两篇: 配置篇 Hello World篇 ----------------------------------------------------------------------------------------------------------------------- 这次我们真正尝试一个稍微像游戏的东西--井字游戏。。。就是那种在 3 X 3方格中画O和X,如果三个连成一线就是胜利。。虽然这东西已经证明先手必胜(不败),但是作为最基础的游戏。就来稍微做一下吧 首先准备一个3 X 3的网格。。。大小为600 X 600[attach]154551[/attach] 好吧。。。。我不会用GIMP。。。。。自己手画就这么丑。。。。求不喷死。。。 再准备一下O和X的图片。。。这次我们把他们放到一起,一个200 X 400 的图片[attach]154553[/attach] (如果能自己画的话还是自己画吧。。。我这个太丑了。。泪奔) 这次我们将尝试事件驱动的编程 [mw_shl_code=applescript,true]package main import ( "github.com/banthar/Go-SDL/sdl" ) func main() { var back_ground, ox, screen *sdl.Surface[/mw_shl_code] 包名,引入包名,主函数,界面surface声明 [mw_shl_code=applescript,true] logic_plane := [3][3]int{} running := true turn := true[/mw_shl_code] 逻辑板的声明。。一个3X3的数组。。。 Go语言中数组定义方方式 "[n]<type>" 有点古怪。长度下标 n 必须是编译期正整数常量 (或常量表达式)。 长 度是类型的组成部分,也就是说 "[10]int" 和 "[20]int" 是完全不同的两种数组类型。数组是值类型,也就是说会拷⻉贝整个数组内存进行行值传递。可用用 slice 或指针代替。(跟C不同哦) 可以用用 new() 创建数组,返回数组指针。var a = new([10]int) [mw_shl_code=applescript,true] sdl.Init(sdl.INIT_EVERYTHING) defer sdl.Quit() screen = sdl.SetVideoMode(600, 600, 32, sdl.SWSURFACE) back_ground = sdl.Load("back_ground.png") ox = sdl.Load("ox.png") defer back_ground.Free() defer ox.Free() sdl.WM_SetCaption("井字游戏", "")[/mw_shl_code] 依旧是老套的初始化与图片的读取,释放。窗口标题的设置。。 下面进入核心事件循环 在SDL中,每当有一个事件发生, 它会被置于事件队列中。事件队列为每个发生的事件保存了事件数据。 所以如果你按一下鼠标按钮,再移动一下鼠标,接着再按下键盘上某个按键,事件队列看起来会像这样: 我们将用一个循环反复捕捉事件。。并且读取事件来驱动整个程序的运作 首先,先说Go的循环 for 支持三种形式: for init; condition; post {} for condition {} for {} 第一种就是C语言的for循环,初始化,判断条件,步进值 第二种就类似while循环,当condition = false时退出循环 第三种就是 while(1),无限循环,只能通过break来退出循环(goto也可,不推荐) 当然go还提供range保留字和for搭配产生迭代器的效果。(很类似python,不过没那么好用,而且基本都是提前算好,不是真正意义上的迭代器) 我们利用running变量判断程序是否进行 [mw_shl_code=applescript,true]for running { event := sdl.PollEvent() switch e := event.(type) { //switch a.(type)检查接口a的类型,然后e就相当于转换了接口的类型 case *sdl.QuitEvent: running = false return[/mw_shl_code] sdl.PollEvent函数左右是从消息队列里提取出一个事件,并返回。返回值是sdl.Event,sdl.Event是一个接口。。。 这里接口解释起来比较复杂。。。 所谓接口。。我们简单认为就是满足一定特性的一系列事物,对于Go,就是他一定拥有某些方法,对于一个接口,它实际存储的可能是任何类型,但都必须有某个方法。。这样便实现了多态。。这里因为还没说方法。。就先不多说接口问题, switch语句用于多路选择,在各个语言中都有涉及,不过Go语言明显吸取了C的教训,switch中case语句可以跟任何类型的常量/变量,而且默认case语句后自带break,也就是不会从一个case语句跑到另一个中,如果真需要这样做,必须显式使用fallthrough来修饰。。。同样有default来进行默认情况的匹配 而我们这里,用一个switch比较特别的用法,swith a.(type) a.(type)这种用法仅能在switch语句中使用,用来匹配a的类型 结果返回a的类型。 而这里我们由于event是一个接口,所以它返回的一定是它所存储的数据的类型,由于接口存储的必然是指针,所以我们就可以由此判断 sdl.QuitEvent是离开的事件,也就是窗口点x,右键退出等所响应的事件 我们将running = false。意味循环结束 [mw_shl_code=applescript,true] case *sdl.MouseButtonEvent: if e.Type == sdl.MOUSEBUTTONDOWN { switch e.Button { case sdl.BUTTON_RIGHT: for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { logic_plane[j] = 0 } } case sdl.BUTTON_LEFT: i := e.X / 200 j := e.Y / 200 if logic_plane[j] == 0 { if turn { turn = !turn logic_plane[j] = 1 } else { turn = !turn logic_plane[j] = 2 } } } } }[/mw_shl_code] 下面我们匹配鼠标事件,如果鼠标右键单击,则游戏重新开始, 左键单击,则在逻辑板中进行变化。每点一次turn切换一次,意味这两个人交替下子。 最后我们将一下精灵图的概念 当我们需要一系列较小图片来组成整个程序时,我们往往不希望每一个小图片都是一个独立的文件,这样无疑使得读取更加费时,操作更加复杂,所以提出了精灵图的概念,将一个子图集合放入一个单独的图片文件中,并blit你想要使用的部分。 [mw_shl_code=applescript,true] screen.Blit(nil, back_ground, nil) for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { if logic_plane[j] == 1 { screen.Blit(&sdl.Rect{int16(i*200 + 10), int16(j*200 + 10), 180, 180}, ox, &sdl.Rect{0, 0, 170, 170}) } else if logic_plane[j] == 2 { screen.Blit(&sdl.Rect{int16(i*200 + 10), int16(j*200 + 10), 180, 180}, ox, &sdl.Rect{0, 200, 170, 170}) } } } screen.Flip() } }[/mw_shl_code] 首先我们将背景贴到屏幕上。 我们知道方法Blit中,调用者是目标界面,第二个参数是源界面,那么第一个参数和第三个参数是干什么的呢? 这两个参数是接受一个sdl.Rect结构,第一个参数表示将要贴在目标界面的哪个部分,第三个参数表示取自源界面的哪个部分。这样就完成了精灵图的操作了。 每次只要根据图片选择一定矩形区域内的图片,就可以部分显示了。。 至于其实最后还应该写一下胜利逻辑。。。由于跟SDL就没什么关系了。。。所以也就懒得写了。。。。 效果图 [attach]154573[/attach] [attach]154574[/attach] 全部源码: [mw_shl_code=applescript,true]package main import ( "github.com/banthar/Go-SDL/sdl" ) func main() { var back_ground, ox, screen *sdl.Surface logic_plane := [3][3]int{} running := true turn := true sdl.Init(sdl.INIT_EVERYTHING) defer sdl.Quit() screen = sdl.SetVideoMode(600, 600, 32, sdl.SWSURFACE) back_ground = sdl.Load("back_ground.png") ox = sdl.Load("ox.png") defer back_ground.Free() defer ox.Free() sdl.WM_SetCaption("井字游戏", "") for running { event := sdl.PollEvent() switch e := event.(type) { //switch a.(type)检查接口a的类型,然后e就相当于转换了接口的类型 case *sdl.QuitEvent: running = false return case *sdl.MouseButtonEvent: if e.Type == sdl.MOUSEBUTTONDOWN { switch e.Button { case sdl.BUTTON_RIGHT: for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { logic_plane[j] = 0 } } case sdl.BUTTON_LEFT: i := e.X / 200 j := e.Y / 200 if logic_plane[j] == 0 { if turn { turn = !turn logic_plane[j] = 1 } else { turn = !turn logic_plane[j] = 2 } } } } } screen.Blit(nil, back_ground, nil) for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { if logic_plane[j] == 1 { screen.Blit(&sdl.Rect{int16(i*200 + 10), int16(j*200 + 10), 180, 180}, ox, &sdl.Rect{0, 0, 170, 170}) } else if logic_plane[j] == 2 { screen.Blit(&sdl.Rect{int16(i*200 + 10), int16(j*200 + 10), 180, 180}, ox, &sdl.Rect{0, 200, 170, 170}) } } } screen.Flip() } } [/mw_shl_code] ———————————————————————————————————————————————————————————————————————— 越写到后面越累啊。。。。最后就懒得说话了。。。。 下次应该就是打砖块了。。。。不过应该就分很多期写了。。。一起说起来太麻烦。。。 反应不好。。不爽求发糖@Whisper1166 @Mr_Alex

回复

晚上回去再看代码

作者:foodszhu
moxiagy 发表于 2013-4-2 16:49 嗯 嗯 晚上回去再看代码
写的非常丑。。。。捂脸。。。求轻喷。。。$61$
查看回复

晚上回去再看代码

作者:moxiagy
嗯 嗯 晚上回去再看代码
查看回复

是什么啊

作者:foodszhu
langyxxl 发表于 2013-4-2 16:41 这个IDE是什么啊,看上去很不错啊
sublime text。。。。一款非常不错的文本编辑器。。。但不是IDE。。。不过配置配置可以达到IDE的效果的说 虽然说更喜欢vim,但是vim的配色实在比不上这个。。。
查看回复

是什么啊

作者:langyxxl
这个IDE是什么啊,看上去很不错啊
查看回复

只是写很简单的东西吧

作者:晓晓酱
foodszhu 发表于 2013-4-2 12:04 只是写很简单的东西吧。。。。 我才是尸横遍野啊!
可能是因为我太渣了_(:3」∠)__(:3」∠)__(:3」∠)__(:3」∠)__(:3」∠)__(:3」∠)_
查看回复

虽然我还没用过

作者:jimsshom
支持下go语言,虽然我还没用过:90:
查看回复

看到大师后吓到尸横遍野

作者:foodszhu
晓晓酱 发表于 2013-4-2 02:24 _(:3」∠)__(:3」∠)__(:3」∠)__(:3」∠)__(:3」∠)__(:3」∠)_【看到大师后吓到尸横遍野】 ...
只是写很简单的东西吧。。。。 我才是尸横遍野啊!
查看回复

看到大师后吓到尸横遍野

作者:晓晓酱
_(:3」∠)__(:3」∠)__(:3」∠)__(:3」∠)__(:3」∠)__(:3」∠)_【看到大师后吓到尸横遍野】
查看回复
上一页
下一页
0%
站点地图友情链接:
喵宅苑
喵空间社区程序
喵宅苑 静态版
宅喵RPG地图编辑器
络合兔
Lanzainc
技术宅
小五四博客
莉可POI
Mithril.js
枫の主题社
Project1
午后少年
机智库
七濑胡桃
xiuno
幻想の日常
魂研社
Nothentai
0xffff
欲望之花
泽泽社长
淀粉月刊
HAYOU