[swift实战入门]手把手教你编写2048(一)

苹果设备越来越普及,拿着个手机就想捣鼓点啥,于是乎就有了这个系列,会一步一步教大家学习swift编程,学会自己做一个自己的app,github地址:https://github.com/scarlettbai/2048.git

这篇文章需要大家了解一些swift基本语法,这里注重实践,就不讲太多基本语法了,不懂的大家可以Google一下,swift开发环境也很简单,直接在mac上安装一个XCode即可,首先我们来看下最终我们要实现的效果:

当然你也可以将其中的数字换成文字给你女票安手机上,还可以给个小惊喜,效果如下:

从上图可以看出来,最终效果其实主要分为计分板和游戏面板,游戏面板里是一个背景和很多的小块,小块中间有间隔,今天先教大家编写出游戏面板。

首先新建一个swift工程,这里就不多说了,然后新建文件NumbertailGameController.swift,这个文件主要处理游戏的初始化等逻辑

新建一个NumbertailGameController类继承UIViewController,其中包含如下属性:

class NumbertailGameController : UIViewController {
    var demension : Int  //2048游戏中每行每列含有多少个块
    var threshold : Int  //最高分数,判断输赢时使用,今天暂时不会用到,预留
    let boardWidth: CGFloat = 260.0  //游戏区域的长度和高度
    let thinPadding: CGFloat = 3.0  //游戏区里面小块间的间距
    let viewPadding: CGFloat = 10.0  //计分板和游戏区块的间距
    let verticalViewOffset: CGFloat = 0.0  //一个初始化属性,后面会有地方用到
}

接下来给NumbertailGameController添加init方法

init(demension d : Int , threshold t : Int) {
    demension = d < 2 ? 2 : d
    threshold = t < 8 ? 8 : t
    super.init(nibName: nil, bundle: nil)
    view.backgroundColor = UIColor(red : 0xE6/255, green : 0xE2/255, blue : 0xD4/255, alpha : 1)
}

这里主要是限制了最少两个块以及最低分数为8分,另外设置了整个面板的背景色,关于颜色,大家可以取自己喜欢的色和直接换掉上面的十六进制数值即可。

接下来我们在Main.storyboard里添加一个开始游戏的按钮,然后在默认的ViewController.swift中添加如下响应方法:

@IBAction func setupGame(sender: UIButton) {
    let game = NumbertailGameController(demension: 4 , threshold: 2048)
    self.presentViewController(game, animated: true , completion: nil)
}

然后我们点击XCode中的运行,就可以看到效果了,点击开始游戏,效果如下:

大家可以看到此处出现了背景色为我们设置的背景色的视图,下面我们来添加游戏区块:

新建GamebordView.swift文件,这个文件就是我们游戏区块的视图文件,在文件中添加如下代码:

import UIKit
class GamebordView : UIView {
    var demension : Int //每行(列)区块个数
    var tileWidth : CGFloat  //每个小块的宽度
    var tilePadding : CGFloat  //每个小块间的间距
    //初始化,其中backgroundColor是游戏区块的背景色,foregroundColor是小块的颜色
    init(demension d : Int, titleWidth width : CGFloat, titlePadding padding : CGFloat, backgroundColor : UIColor, foregroundColor : UIColor ) {
        demension = d
        tileWidth = width
        tilePadding = padding
        let totalWidth = tilePadding + CGFloat(demension)*(tilePadding + tileWidth)
        super.init(frame : CGRectMake(0, 0, totalWidth, totalWidth))
        self.backgroundColor = backgroundColor
    }
}

在这里我们是创建了一个游戏区块的模板,接下来我们在游戏的主控制器NumbertailGameController中添加如下代码来初始化一个游戏区块对象并添加到我们的面板中:

override func viewDidLoad() {
    super.viewDidLoad()
    setupGame()
}

func setupGame(){
    let viewWidth = view.bounds.size.width
    let viewHeight = view.bounds.size.height
    //获取游戏区域左上角那个点的x坐标
    func xposition2Center(view v : UIView) -> CGFloat{
        let vWidth = v.bounds.size.width
        return 0.5*(viewWidth - vWidth)

    }
    //获取游戏区域左上角那个点的y坐标
    func yposition2Center(order : Int , views : [UIView]) -> CGFloat {
        assert(views.count > 0)
        let totalViewHeigth = CGFloat(views.count - 1)*viewPadding +
            views.map({$0.bounds.size.height}).reduce(verticalViewOffset, combine: {$0 + $1})
        let firstY = 0.5*(viewHeight - totalViewHeigth)

        var acc : CGFloat = 0
        for i in 0..<order{
            acc += viewPadding + views[i].bounds.size.height
        }
        return acc + firstY
    }
    //获取具体每一个区块的边长,即:(游戏区块长度-间隙总和)/块数
    let width = (boardWidth - thinPadding*CGFloat(demension + 1))/CGFloat(demension)
    //初始化一个游戏区块对象
    let gamebord = GamebordView(
        demension : demension,
        titleWidth: width,
        titlePadding: thinPadding,
        backgroundColor:  UIColor(red : 0x90/255, green : 0x8D/255, blue : 0x80/255, alpha : 1),
        foregroundColor:UIColor(red : 0xF9/255, green : 0xF9/255, blue : 0xE3/255, alpha : 0.5)
    )
    //现在面板中所有的视图对象,目前只有游戏区块,后续加入计分板
    let views = [gamebord]
    //设置游戏区块在整个面板中的的绝对位置,即左上角第一个点
    var f = gamebord.frame
    f.origin.x = xposition2Center(view: gamebord)
    f.origin.y = yposition2Center(0, views: views)
    gamebord.frame = f
    //将游戏对象加入当前面板中
    view.addSubview(gamebord)

}

上面的代码中注释已经很详细了,大家可能疑问的就是x和y坐标的计算,x坐标很简单,其实就是:当前面板总宽度减去游戏区块宽度,剩下的就是空余的宽度,再除以2就是x点的坐标了。y坐标稍微复杂点在于,以后会加入计分面板,所以他的值应该是:当前面板总高度减去所有视图的总高度除以2然后在加上在游戏区块之前的视图的总高度,就是游戏区域的y坐标值

其他地方都很简单,其中的foregroundColor是注释中有,是下面给游戏区块添加默认小方块时用的颜色。

我们来运行看效果:

可以看到面板已经有了,接下来我们要给面板中加入初始化的半透明小方块,我们在GamebordView中添加如下方法:

func setColor(backgroundColor bgcolor : UIColor, foregroundColor forecolor : UIColor){
    self.backgroundColor = bgcolor
    var xCursor = tilePadding
    var yCursor : CGFloat

    for _ in 0..<demension{
        yCursor = tilePadding
        for _ in 0..<demension {
            let tileFrame = UIView(frame : CGRect(x: xCursor, y: yCursor, width: tileWidth, height: tileWidth))
            tileFrame.backgroundColor = forecolor
            tileFrame.layer.cornerRadius = 8
            addSubview(tileFrame)
            yCursor += tilePadding + tileWidth
        }
        xCursor += tilePadding + tileWidth
    }

}

这个方法其实就是在游戏区块中添加了demension*demension个小块,每个小块的颜色是我们传入的foregroundColor

来运行下看效果:

可以看到基本的游戏面板已经有了,今天先讲到这里,大家可以尝试自己把计分板添加进来,当然后续我也会讲到。

我的博客:blog.scarlettbai.com

我的微信公众号:读书健身编程

欢迎扫码关注我的公众号查看更多文章

时间: 2024-10-07 21:55:42

[swift实战入门]手把手教你编写2048(一)的相关文章

[swift实战入门]手把手教你编写2048(三)

上篇地址:swift实战入门之手把手教你编写2048(二) github地址:https://github.com/scarlettbai/2048.git. 今天给大家带来2048最后一篇,之前已经实现了向游戏区域中随机插入数字块,接下来要做的,就是当我们滑动屏幕时移动及合并数字块以及插入一个新的数字块.本篇的难点就是移动时的算法问题,首先来给大家讲一下算法. 2048的算法实现其实很简单,假如我们当前数字格的格式如下: | |4| | | | | |4| | |2| |2|2| |2| |

[swift实战入门]手把手教你编写2048(二)

上篇地址:swift实战入门之手把手教你编写2048(一) github地址:https://github.com/scarlettbai/2048.git. 上篇文章已经中已经把2048的游戏区块画好了,这篇来加入计分板以及往游戏面板中插入数字块 计分板同样作为一个view,我们新建一个ScoreView.swift文件,代码如下: import UIKit //这里协议的作用是方便别的类中调用计分板的scoreChanged方法 protocol ScoreProtocol{ func sc

CSS3实战开发: 手把手教大家实战开发鼠标划过图片动画特效

各位网友大家好,我是陌上花会开,当然大家也可以叫我陌陌.今天这篇文章,我将手把手带领大家实战开发一个鼠标划过图片时的动画特效.在这里我不会给大家提供案例的源码下载,但是本人可以保证,只要大家跟着我的思路,一步步将代码复制到本地,一定会得到同样的运行效果.希望大家明白我的用心.好了不废话,直接进入今天的主题吧. 在今天这个案例里,我准备3个素材,一张背景图,两张风景图片.这个大家可以到网上自行下载. 在写代码之前,我先给大家展示一下,动画特效的效果图. 鼠标花过前: 当鼠标划过图片时,图片将逐渐变

CSS3实战开发:手把手教你鼠标滑动特效开发

各位网友,如果你已经看过我的CSS3实战开发系列教程,我相信你对CSS3已经有了非常全面深刻的了解.有些人可能CSS3语法掌握了不少,但是真正实际用起来还有点生疏,甚至无从下手.请别担心,我会不断更新一系列实战开发案例,我会为大家分步骤剖析特效开发过程. 今天我将手把手带领大家开发一个鼠标滑动的特效案例,废话不多说,直接上效果动画: 你有没有觉得上面的这个特效很棒呢! 好,现在咱们就开始分步骤实战开发这个动画特效吧: 首先,我们先准备好html页面代码: <!DOCTYPE html> <

CSS3实战开发:手把手教你照片墙实战开发

在<CSS3 2D转换技术之translate实战开发>文章中,我给大家列出了CSS3中的2D转换方法: 1.    translate() 2.    rotate() 3.    scale() 4.    skew() 5.    matrix() 同时对第一个方法 translate()做了非常详尽的介绍,并带领大家实战开发了一个导航条.如果你对translate不了解或不是太熟悉,请阅读我的博文 <CSS3 2D转换技术之translate实战开发> . 在讲解知识点之前

CSS3实战开发:手把手教大家折角效果实战开发

各位网友,大家好,我是陌上花会开,今天这篇文章,我将手把手教大家如何开发一套纯CSS的折角效果.一如往常,我不提供代码下载,但是我可以保证,只要将教程中的代码复制到本地,绝对百分百获得与我演示的效果一样,希望各位明白我的用意. 好了,直接开始今天的教程吧.首先,我先给大家演示一下今天实战案例的效果: 有人会说这是什么?这就是我们今天的实战开发,我将带领大家开发上图中的右上角折叠效果. 在我讲解完之前,有些人可能觉得很难,不可思议.我想跟你们说:真的so easy.下面就请跟着我的分解步骤一步步学

手把手教你编写一个简单的PHP模块形态的后门

看到Freebuf 小编发表的用这个隐藏于PHP模块中的rootkit,就能持久接管服务器文章,很感兴趣,苦无作者没留下PoC,自己研究一番,有了此文 0×00. 引言 PHP是一个非常流行的web server端的script语言.目前很多web应用程序都基于php语言实现.由于php是个开源软件并易于扩展,所以我们可以通过编写一个PHP模块(module 或者叫扩展 extension)来实现一个Backdoor. 本文就简单介下如何一步步编写一个简单的php 动态扩展后门. 0×01. p

Hexo+NexT(六):手把手教你编写一个Hexo过滤器插件

Hexo+NexT介绍到这里,我认为已经可以很好地完成任务了.它所提供的一些基础功能及配置,都已经进行了讲解.你已经可以随心所欲地配置一个自己的博客环境,然后享受码字的乐趣. 把博客托管到Github上,是个很好的想法,没有自己空间的博主肯定很欢迎.其实文章编译之后,他就是一个非常简单的静态网站.部署的目的就是简单的把静态网站文件夹拷贝到Github的一个仓库里,然后把这个仓库当作一个网站文件夹,仅此而已,非常简单.所以,没有讲的价值. 但是,作为一个Coder,研究了Hexo,总得来点真本事,

Java入门 手把手教你配置环境变量

很多人觉得配置Java开发的环境变量很麻烦,很容易忘记,时常被它搞得晕头转向.如果出现这样的情况,那么原因只有一个,你不了解为毛需要配置环境变量,不配置环境变量就不能开发了吗? 答案是:NO!,那么下面就带大家一起来分析一下原因所在. 先确定一个概念.编译一个Java源程序需要使用到javac 命令:运行启动一个Java程序需要使用到java命令.以我本机为例,这两个命令工具存在于 : D:\java\jdk\jdk1.7.0_06\bin路径下 在命令提示符下有这样一个特点,那就是只能够访问到