Android实训案例(四)——关于Game,2048方块的设计,逻辑,实现,编写,加上色彩,分数等深度剖析开发过程!


关于2048,我看到很多大神,比如医生,郭神,所以我也研究了一段时间,还好是研究了一套逻辑,这是一整套的2048游戏从设计到逻辑再到编写的全部过程,小伙伴们看仔细咯,刚好今天是礼拜天,一天应该了一把这篇博客发表了,其实2048开发起来还是有点难度的,并且他的逻辑挺强的,我也是看了很多的资料偷学的,很适合来锻炼自己的逻辑性

我们首先先来选择开发环境,这里我们就以Eclipse为IDE,新建一个工程——Game2048

一.Score分数

既然是2048游戏,我们也就做一个简单的,他有一个分数,然后就是一个游戏的布局,我们也做一个简单的4*4的游戏,大概的设计图就是这样

二.游戏类:GameView

因为我们的游戏所使用到的布局就是GridLayout,所以我们新建一个GameView继承自GridLayout,然后通过算法动态添加方块,并且监听手势进行操作,这个重写的GridLayout就是游戏的布局了

<com.lgl.game2048.GameView
        android:id="@+id/game_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

三.实现交互逻辑

我们这里铁定是手势操作啦,这里我们就得区分手势是往上,往下,往左,往右,的手势,这时候,我们就需要用到手势监听——OnTouchListener了,也为了确保是实时监听,我们直接在initView的初始方法中处理

我们其实只要知道两点,用户手指按下的坐标点和手指离开的坐标点,然后进行比对,就能识别出用户的意图了

其实关于MotionEvent的几个方法,大家估计都见怪不怪了,因为用的太多了
// 初始化
    private void initView() {
        // 识别手势
        setOnTouchListener(new OnTouchListener() {

            // 起始点和偏移点
            private float startX, startY, offsetX, offsetY;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                /**
                 * 交互逻辑 :我们其实只要知道两点,用户手指按下的坐标点和手指离开的坐标点,然后进行比对,就能识别出用户的意图了
                 */
                switch (event.getAction()) {
                // 手指按下
                case MotionEvent.ACTION_DOWN:
                    // 记录按下的x,y坐标
                    startX = event.getX();
                    startY = event.getY();

                    break;
                // 手指离开
                case MotionEvent.ACTION_UP:
                    // 手指离开之后计算偏移量(离开的位置-按下的位置在进行判断是往哪个方向移动)
                    offsetX = event.getX() - startX;
                    offsetY = event.getY() - startY;

                    // 开始识别方向
                    // offsetX 的绝对值大于offsetY的绝对值 说明在水平方向
                    if (Math.abs(offsetX) > Math.abs(offsetY)) {
                        // (直接<0 会有些许误差,我们可以 <-5)
                        if (offsetX < -5) {
                            // 左
                            System.out.println("左");
                        } else if (offsetX > 5) {
                            // 右
                            System.out.println("右");
                        }
                        // 开始计算垂直方向上下的滑动
                    } else {
                        if (offsetY < -5) {
                            // 上
                            System.out.println("上");
                        } else if (offsetY > 5) {
                            // 下
                            System.out.println("下");
                        }
                    }
                    break;
                }
                return true;
            }
        });
    }
上面的逻辑是不是非常的简单,然后我们操作一下,看log

现在手势识别也是很精准了,当然,我们的代码设计也不能太过臃肿,所以,我们的操作逻辑就不在里面编写了,我们分别实现四个方向的方法

    // 左
    private void isLeft() {

    }

    // 右
    private void isRight() {

    }

    // 上
    private void isTop() {

    }

    // 下
    private void isButtom() {

    }
然后把输出语句替换掉,监听到哪个方向就执行哪个方法
//System.out.println("上,下,左,右");
 private void isXXX() {

    }

四.实现方块类CardView

我们可以把这一个个卡片看作是一个对象,我们每次操作,他都要进行实例化
首先,我们新建一个类CardView继承自FrameLayout,再里面我们要考虑三点

1.卡片

2.卡片上的数字

卡片相同的比较

package com.lgl.game2048;

import android.content.Context;
import android.widget.FrameLayout;
import android.widget.TextView;

public class CardView extends FrameLayout {

    // 卡片数量
    private int num = 0;
    // 卡片文字
    private TextView tv_num;

    public CardView(Context context) {
        super(context);
        // 初始化TextView
        tv_num = new TextView(getContext());
        // 卡片文字大小
        tv_num.setTextSize(20);
        // 布局控制器,填充满整个父容器
        LayoutParams lp = new LayoutParams(-1, -1);
        addView(tv_num, lp);

        setNum(0);
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;

        // 要呈现出来的文字(这里要注意是String类型的)
        tv_num.setText(num + "");
    }

    // 两卡片相同的比较方法
    public boolean equals(CardView card) {

        return getNum() == card.getNum();
    }

}

五.动态分配方块的宽高以及添加方块

1.动态分配方块的宽高

写到这里,就有一个梗了,还是Android的老毛病,屏幕的适配问题,所以我们队卡牌的宽高是不能做限定的,也就是说我们要去根据手机屏幕动态分配卡片的width和height,在这里我们就得用到我之前一篇博客

Android绘图机制(一)——自定义View的基础属性和方法

中提到的一个方法了

@Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        // TODO Auto-generated method stub
        super.onSizeChanged(w, h, oldw, oldh);
    }

他负责我们的View在父容器的位置,所以我们动态分配高宽也是在他这里面完成,首先,位置发生改变之后,我们得到的位置是一个确定数,但是为了防止用户是横放这手机,这就蛋疼了,所以我们得进行一个设置了

我们打开AndroidManifest.xml的activity标签中加入

//禁止屏幕横屏
android:screenOrientation="portrait"    

好的,现在可以计算了

宽高求最小值 因为考虑到,我们的方阵他是正方形的,而手机屏幕是长方形的,这样,我们的正方形要设置变长就得求长方形的宽,也就是最小值了

并且我们也不需要他填满宽度,我们需要一点空隙,所以我们减去10个像素

再让他除以4,通过这种方式,我们就可以动态平分这个宽度了
int cardWidth = (Math.min(w, h)-10)/4;

2.添加方块

-1.添加卡片

    // 添加卡片,参数为卡片的宽高,因为他是正方形,所以宽高都是cardWidth
    private void addCard(int cardWidth, int cardHeight) {
        // 创建方块
        CardView c;
        // 循环添加
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                c = new CardView(getContext());
                // num为随机数
                c.setNum(2);
                addView(c, cardWidth, cardHeight);
            }
        }
    }
好的,我们来运行一下(换个AS2.0的模拟器感觉萌萌哒)

-2.方块换行

你会发现,并没有4*4,而且一排没有换行,我们回到GameView的initView()方法中添加
//换行
setColumnCount(4);
现在再看看

-3.文字居中

现在我们调整一下,让文字居中,在CardView中
    //文字居中
    tv_num.setGravity(Gravity.CENTER);

现在是不是好看多了

-4.方块颜色

既然是玩2048我们怎么能少了颜色尼,我们就根据这

Android高效率编码-细节,控件,架包,功能,工具,开源汇总



中的色彩表来,自己觉得什么颜色好看可以自行替换,我们直接来到CardView里面

//设置文字背景(暗卡其色)
tv_num.setBackgroundColor(0xffBDB76A);

-5.方块间距

既然是方块间隔,我们还是回到CardView里面,还记得我们设置的LayoutParams吗?你可能想到了吧,我们用Margins
//设置间距
lp.setMargins(10, 10, 0, 0);

-6.记忆方块

我们所操作之后,会有新生成的卡片,为了不重合,我们得做一个记忆功能
    // 记录卡片的二维数组
     private CardView[][] cards = new CardView[4][4];
然后在addCard()方法中
//记忆
    cards[j][i] = c;

六.随机数

我们先来思考一下这个随机数的逻辑,我们玩2048的时候,是不是开始新游戏的时候会随机出现两个方块,而这两个方块,他是随机出现在4*4的任意位置的,所以,我们确定下来,一开始是两个方块的随机出现,再接下来,我们会发现,他有时候是两个2,但是有时候是一个2,一个4,这个4出现的几率有点小,而且我们作为游戏规则制定者,这个也是我们控制的,这里,我不想他出现的很容易,所以我这里的逻辑就设置成1-9,这样4出现的概率会小很多,好了,基本确定了,我们就开始写代码了,我们写一个方法,在此之前,我们要对之前的代码进行调整一下,在CardView中setNum方法中,我们默认为0就占一格,

// 要呈现出来的文字(这里要注意是String类型的)
        if (num <= 0) {
            tv_num.setText("");
        } else {
            tv_num.setText(num + "");
        }
然后把刚才的文字设置换成0
// c.setNum(2);
   c.setNum(0);
然后我们就可以添加随机数了,我们新建一个方法addRandom();
    // 随机数
    private void addRandom() {
        // 我们新建一个lsit存放空的方块,操作之前清空
        point.clear();
        // 对所有的位置进行遍历
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                // 空方块才可以添加数字,有值我们就不添加
                if (cards[j][i].getNum() <= 0) {
                    point.add(new Point(j, i));
                }
            }
        }
        // for循环走完之后我们要取方块
        Point p = point.remove((int) (Math.random() * point.size()));
        // 我们用Math.random()返回一个0-1的数,当大于0.1的时候是2否则就是4,也就是4出现的概率为十分之一
        cards[p.x][p.y].setNum(Math.random() > 0.1 ? 2 : 4);
    }
这个时候我们就可以开始游戏了,为了方便等下我们需要重新开始游戏,我们就新建一个startGame()方法,让他在onSizeChanged()调用
// 开启游戏
    private void startGame() {
        // 既然是开始游戏,我们就要对所有的值进行清理
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                cards[j][i].setNum(0);
            }
        }
        // 重新添加随机数
        addRandom();
        // 我们要添加两个
        addRandom();
    }
好的,我们现在运行一下啊

这正是我们要的效果,每次进入游戏随机生成两个方块,他会出现在不同的位置,而且会出现2和4,4的概率小很多

七.实现方块滑动,递加逻辑

好的,终于到了核心的东西了,这次我们就要用到之前所写的上下左右方向方法了
// 左
    private void isLeft() {
        /**
         * 这里的逻辑有三种情况 1.左边为空,直接左滑到最后一格 2.左边碰到的第一个数是相等的,就相加 3.左边碰到的第一个数是不相等的,靠在旁边
         */
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                // 往左滑是一行一行去遍历的
                for (int j2 = j + 1; j2 < 4; j2++) {
                    // 如果说遍历到值
                    if (cards[j2][i].getNum() > 0) {
                        // 如果当前位置上为0,就放在这个位置上去
                        if (cards[j][i].getNum() <= 0) {
                            cards[j][i].setNum(cards[j2][i].getNum());
                            // 把原来位置上的数字清除
                            cards[j2][i].setNum(0);
                            // 让图形继续遍历
                            j--;

                            // 有值,并且还相同
                        } else if (cards[j][i].equals(cards[j2][i])) {
                            // 合并,这里做了一个很巧妙的写法,我们相加,其实2048方块上的数字都是双倍的,所以我们只要原数据*2就可以了
                            cards[j][i].setNum(cards[j][i].getNum() * 2);
                            // 把原来位置上的数字清除
                            cards[j2][i].setNum(0);

                        }
                        break;
                    }
                }
            }
        }
    }

    // 右
    private void isRight() {
        /**
         * 这里的逻辑有三种情况 1.左边为空,直接左滑到最后一格 2.左边碰到的第一个数是相等的,就相加 3.左边碰到的第一个数是不相等的,靠在旁边
         */
        for (int i = 0; i < 4; i++) {
            for (int j = 3; j >= 0; j--) {
                // 往左滑是一行一行去遍历的
                for (int j2 = j - 1; j2 >= 0; j2--) {
                    // 如果说遍历到值
                    if (cards[j2][i].getNum() > 0) {
                        // 如果当前位置上为0,就放在这个位置上去
                        if (cards[j][i].getNum() <= 0) {
                            cards[j][i].setNum(cards[j2][i].getNum());
                            // 把原来位置上的数字清除
                            cards[j2][i].setNum(0);
                            // 让图形继续遍历
                            j++;

                            // 有值,并且还相同
                        } else if (cards[j][i].equals(cards[j2][i])) {
                            // 合并,这里做了一个很巧妙的写法,我们相加,其实2048方块上的数字都是双倍的,所以我们只要原数据*2就可以了
                            cards[j][i].setNum(cards[j][i].getNum() * 2);
                            // 把原来位置上的数字清除
                            cards[j2][i].setNum(0);

                        }
                        break;
                    }
                }
            }
        }
    }

    // 上
    private void isTop() {
        /**
         * 这里的逻辑有三种情况 1.左边为空,直接左滑到最后一格 2.左边碰到的第一个数是相等的,就相加 3.左边碰到的第一个数是不相等的,靠在旁边
         */
        for (int j = 0; j < 4; j++) {
            for (int i = 0; i < 4; i++) {
                // 往左滑是一行一行去遍历的
                for (int i2 = i + 1; i2 < 4; i2++) {
                    // 如果说遍历到值
                    if (cards[j][i2].getNum() > 0) {
                        // 如果当前位置上为0,就放在这个位置上去
                        if (cards[j][i].getNum() <= 0) {
                            cards[j][i].setNum(cards[j][i2].getNum());
                            // 把原来位置上的数字清除
                            cards[j][i2].setNum(0);
                            // 让图形继续遍历
                            i--;

                            // 有值,并且还相同
                        } else if (cards[j][i].equals(cards[j][i2])) {
                            // 合并,这里做了一个很巧妙的写法,我们相加,其实2048方块上的数字都是双倍的,所以我们只要原数据*2就可以了
                            cards[j][i].setNum(cards[j][i].getNum() * 2);
                            // 把原来位置上的数字清除
                            cards[j][i2].setNum(0);

                        }
                        break;
                    }
                }
            }
        }
    }

    // 下
    private void isButtom() {
        /**
         * 这里的逻辑有三种情况 1.左边为空,直接左滑到最后一格 2.左边碰到的第一个数是相等的,就相加 3.左边碰到的第一个数是不相等的,靠在旁边
         */
        for (int j = 0; j < 4; j++) {
            for (int i = 3; i >= 0; i--) {
                // 往左滑是一行一行去遍历的
                for (int i2 = i - 1; i2 >= 0; i2--) {
                    // 如果说遍历到值
                    if (cards[j][i2].getNum() > 0) {
                        // 如果当前位置上为0,就放在这个位置上去
                        if (cards[j][i].getNum() <= 0) {
                            cards[j][i].setNum(cards[j][i2].getNum());
                            // 把原来位置上的数字清除
                            cards[j][i2].setNum(0);
                            // 让图形继续遍历
                            i++;

                            // 有值,并且还相同
                        } else if (cards[j][i].equals(cards[j][i2])) {
                            // 合并,这里做了一个很巧妙的写法,我们相加,其实2048方块上的数字都是双倍的,所以我们只要原数据*2就可以了
                            cards[j][i].setNum(cards[j][i].getNum() * 2);
                            // 把原来位置上的数字清除
                            cards[j][i2].setNum(0);

                        }
                        break;
                    }
                }
            }
        }
    }
四个方法的逻辑都是大同小异的,不过逻辑性还是很强的,大家可以适当的去研究一下然后我们多增加几个方块先来模拟下效果

八.计分

方块的逻辑差不多写完了,我们先来就在MainActivity里面来实现我们的Score计分

MainActivity

package com.lgl.game2048;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity {

    private TextView tv_score;
    //外界可以访问的实例
    private static MainActivity mainActivity = null;
    //积分器
    private int score = 0;

    public MainActivity() {
        mainActivity = this;
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tv_score = (TextView) findViewById(R.id.tv_score);

    }
    public static MainActivity getMainActivity() {
        return mainActivity;
    }
    public static void setMainActivity(MainActivity mainActivity) {
        MainActivity.mainActivity = mainActivity;
    }

    //清除分数
    public void clearScore(){
        score = 0;
        showScore();
    }
    //分数
    public void showScore(){
        tv_score.setText("分数:"+score);
    }

    public void addScore(int s){
        score += s;
        showScore();
    }
}
这是我们计分的过程,我们思考一下在什么时候计分呢?想想就知道在滑动的时候俩值相加的时候开始计分,所以我们在四个滑动方法有值的判断句中添加
//开始计分                                     MainActivity.getMainActivity().addScore(cards[j][i].getNum());
同时,我们在开始游戏的时候要清零,所以我们在startGame方法中要添加
//计分清零
MainActivity.getMainActivity().clearScore();

九.滑动后增加方块

我们默认进来是两个方块,但是滑动之后我们应该也要随机增加方块才能达到游戏的逻辑,你说是吧!
所以,只要你滑动了,我们就要添加,一直到gameover结束为止,那我们依然在那四个方向方法里写
private void isxx(){
    // 加个判断是否可以添加
    boolean isAdd = false;
    for(....){
        for(....){
            for(....){
                if(....){
                    if(....){
                        ....
                    // 可以添加
                    isAdd = true;
                    }else if(....){
                        ....
                        // 可以添加
                        isAdd = true;
                    }
                }
            }
        }
    }
    // 开始进行判断
        if (isAdd) {
            // 如果可以合并,我们添加随机数
            addRandom();
        }
}
好的,我们现在来运行一下

游戏现在大体上是OK的了

十.游戏结束

游戏有始有终,我们现在就来判断游戏结束,游戏结束有两个前提
1.16个格子都是满的
2.上下左右相邻的格子都不相同
这样的话我们就可以写一个endGame方法,然后让他在每次增加方块的时候调用了

    // 游戏结束
    private void endGame() {
        // 在每次添加新的方块的时候判断一下
        // 是否结束?
        boolean isEnd = true;
        ALL: // 标签,让break跳出整个循环
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                // 等于0的话游戏没有结束,或者上下左右还是有相同的数
                if (cards[j][i].getNum() == 0
                // 左
                        || (j > 0 && cards[j][i].equals(cards[j - 1][i]))
                        // 右
                        || (j < 3) && cards[j][i].equals(cards[j + 1][i])
                        // 上
                        || (i > 0 && cards[j][i].equals(cards[j][i - 1]))
                        // 下
                        || (i < 3 && cards[j][i].equals(cards[j][i + 1]))) {
                    // 说明游戏没有结束
                    isEnd = false;
                    break ALL;

                }
            }
        }
        if (isEnd) {
            // 当isEnd = true的时候游戏结束
            new AlertDialog.Builder(getContext())
                    .setTitle("Sorry,游戏结束!")
                    .setMessage("是否重新开始?")
                    .setPositiveButton("是",
                            new DialogInterface.OnClickListener() {

                                @Override
                                public void onClick(DialogInterface dialog,
                                        int which) {
                                    // 重新开始
                                    startGame();
                                }
                            })
                    .setNegativeButton("否",
                            new DialogInterface.OnClickListener() {

                                @Override
                                public void onClick(DialogInterface dialog,
                                        int which) {
                                }
                            }).show();
        }
    }
好的,现在我们可以来检测一下了

十一.优化之色块

我们的数字每个数字代表一种颜色,这里我就简单的写点颜色,你们要是喜欢可以自己想改什么就改什么
在CardView中setnum方法里
        switch (num) {
        case 0:
            tv_num.setBackgroundColor(0xffBDB76A);
            break;
        case 2:
            tv_num.setBackgroundColor(0xffeee4da);
            break;
        case 4:
            tv_num.setBackgroundColor(0xffede0c8);
            break;
        case 8:
            tv_num.setBackgroundColor(0xfff2b179);
            break;
        case 16:
            tv_num.setBackgroundColor(0xfff59563);
            break;
        case 32:
            tv_num.setBackgroundColor(0xfff67c5f);
            break;
        case 64:
            tv_num.setBackgroundColor(0xfff65e3b);
            break;
        case 128:
            tv_num.setBackgroundColor(0xffedcf72);
            break;
        case 256:
            tv_num.setBackgroundColor(0xffedcc61);
            break;
        case 512:
            tv_num.setBackgroundColor(0xffedc850);
            break;
        case 1024:
            tv_num.setBackgroundColor(0xffedc53f);
            break;
        case 2048:
            tv_num.setBackgroundColor(0xffedc22e);
            break;
        default:
            tv_num.setBackgroundColor(0xff3c3a32);
            break;
        }
我们运行下

Demo下载地址:http://download.csdn.net/detail/qq_26787115/9409068

Android实训案例(四)——关于Game,2048方块的设计,逻辑,实现,编写,加上色彩,分数等深度剖析开发过程!的更多相关文章

  1. Android实训案例(九)——答题系统的思绪,自己设计一个题库的体验,一个思路清晰的答题软件制作过程

    Android实训案例(九)--答题系统的思绪,自己设计一个题库的体验,一个思路清晰的答题软件制作过程 项目也是偷师的,决心研究一下数据库.所以写的还是很详细的,各位看官,耐着性子看完,实现结果不重要 ...

  2. Android实训案例(八)——单机五子棋游戏,自定义棋盘,线条,棋子,游戏逻辑,游戏状态存储,再来一局

    Android实训案例(八)--单机五子棋游戏,自定义棋盘,线条,棋子,游戏逻辑,游戏状态存储,再来一局 阿法狗让围棋突然就被热议了,鸿洋大神也顺势出了篇五子棋单机游戏的视频,我看到了就像膜拜膜拜,就 ...

  3. Android实训案例(五)——四大组件之一ContentProvider的使用,通讯录的实现以及ListView的优化

    Android实训案例(五)--四大组件之一ContentProvider的使用,通讯录的实现 Android四大组件是啥这里就不用多说了,看图吧,他们之间通过intent通讯 我们后续也会一一的为大 ...

  4. Android实训案例(六)——四大组件之一BroadcastReceiver的基本使用,拨号,短信,SD卡,开机,应用安装卸载监听

    Android实训案例(六)--四大组件之一BroadcastReceiver的基本使用,拨号,短信,SD卡,开机,应用安装卸载监听 Android中四大组件的使用时重中之重,我这个阶段也不奢望能把他 ...

  5. Android实训案例(三)——实现时间轴效果的ListView,加入本地存储,实现恋爱日记的效果!

    Android实训案例(三)--实现时间轴效果的ListView,加入本地存储,实现恋爱日记的效果! 感叹离春节将至,也同时感叹时间不等人,一年又一年,可是我依然是android道路上的小菜鸟,这篇讲 ...

  6. Android实训案例(二)——Android下的CMD命令之关机重启以及重启recovery

    Android实训案例(二)--Android下的CMD命令之关机重启以及重启recovery Android刚兴起的时候,着实让一些小众软件火了一把,切水果,Tom猫,吹裙子就是其中的代表,当然还有 ...

  7. Android实训案例(一)——计算器的运算逻辑

    Android实训案例(一)--计算器的运算逻辑 应一个朋友的邀请,叫我写一个计算器,开始觉得,就一个计算器嘛,很简单的,但是写着写着发现自己写出来的逻辑真不严谨,于是搜索了一下,看到mk(没有打广告 ...

  8. Android实训案例(七)——四大组件之一Service初步了解,实现通话录音功能,抽调接口

    Service Service的神奇之处,在于他不需要界面,一切的操作都在后台操作,所以很多全局性(手机助手,语音助手)之类的应用很长需要这个,我们今天也来玩玩 我们新建一个工程--ServiceDe ...

  9. Android实训案例(七)——四大组件之中的一个Service初步了解,实现通话录音功能,抽调接口

    Service Service的奇妙之处.在于他不须要界面,一切的操作都在后台操作,所以非常多全局性(手机助手,语音助手)之类的应用非常长须要这个.我们今天也来玩玩 我们新建一个project--Se ...

随机推荐

  1. JQuery 初探

    放暑假了,终于有时间能学点前端的东西了.JQuery就是我第一个选择,锋利的JQuery.这本书真的很好.下面以一个ToggleButton形式的小例子开场吧. 引入JQuery库 在网页上引用JQu ...

  2. GDAL书籍中删除数据勘误(C#语言)

    GDAL书籍中关于C#版本删除数据的时候,不能完全删除数据,由于我对C#不了解导致代码有点问题,非常感谢@Bingoyin指出并给出修改方案.此外对于栅格图像的删除.重命名,矢量数据的删除和重命名都有 ...

  3. 02_MyBatis项目结构,所需jar包,ehcache.xml配置,log4j.properties,sqlMapConfig.xml配置,SqlMapGenerator.xml配置

     项目结构(所需jar包,配置文件) sqlMapConfig.xml的配置内容如下: <?xmlversion="1.0"encoding="UTF-8&qu ...

  4. UNIX网络编程——非阻塞connect:时间获取客户程序

    #include "unp.h" int connect_nonb(int sockfd, const SA *saptr, socklen_t salen, int nsec) ...

  5. jquery实战---标签页效果

    在前面的博客中,小编主要简单的介绍了jquery的一些基本知识,今天这篇博文,小编继续来学习jquery的相关知识,今天我们来学习一个标签页的小例子,相关源码小编已经上传,有需要的小伙伴可以自己去下载 ...

  6. 数值分析:Hermite多项式

    http://blog.csdn.net/pipisorry/article/details/49366047 Hermite埃尔米特多项式 在数学中,埃尔米特多项式是一种经典的正交多项式族,得名于法 ...

  7. JAVA之旅(十七)——StringBuffer的概述,存储,删除,获取,修改,反转,将缓存区的数据存储到数组中,StringBuilder

    JAVA之旅(十七)--StringBuffer的概述,存储,删除,获取,修改,反转,将缓存区的数据存储到数组中,StringBuilder 讲完String,我们来聊聊他的小兄弟 一.StringB ...

  8. android的PackageManagerService详解

    PackageManagerService主要是一个包的管理服务,在开机的时候会解析以前保存的一些安装包的相关数据,android运行过程中新安装的apk也会保存到PackageManagerServ ...

  9. Android Studio查看应用数字签名-android学习之旅(76)

    Android Studio和Eclispe还是有比较大的区别,在这地方,eclipse可以直接在设置里面,而AS就需要通过Terminal来查看 步骤 1.首先定位到.android 一般都是在C盘 ...

  10. 【一天一道LeetCode】#74. Search a 2D Matrix

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Write a ...