数独游戏开发(四)

(通过界面我们知道,点击new Game 进入新游戏 ,点击Continue我们可以吧刚玩的记录重现出来, 点击about 弹出Activity 游戏的介绍, exit代表退出)现在我们在游戏中设置Music+Activity显示+小九宫格数字颜色显示+界面+保存游戏进度+about 具体操作 如下:

  • 界面:(有点丑)

界面.jpg
  • 框架:

框架.jpg

以下是修改的Java代码,其它demo不作改动

  • MainActivity.java (我们的做法是吧Game.java的demo整合到MainActivity.java里面)

public class MainActivity extends Activity {

    // 数独初始化数据的基础
    private final String data = "360000000004230800000004200"
            + "070460003820000014500013020" + "001900000007048300000000045";

    private int sudoku[] = new int[9 * 9];

    // 用于存储每个单元格已经不可用的数据
    private int used[][][] = new int[9][9][];

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new MyView(this));
        int diff = getIntent().getIntExtra("contin", 0);
        // sudoku = fromPuzzleString(str);
        sudoku = getshuduku(diff);
        calculateAllUsedTiles();
    }

    private int[] getshuduku(int diff) {
        //spdata代表保存过的字符串
        String spdata = null;
        switch (diff) {
        case -1:
            SharedPreferences sp = getPreferences(MODE_PRIVATE);
            spdata=sp.getString("String", data);
            break;
        case 0:
            spdata=data;
            break;
        default:
            spdata=data;
            break;
        }
        //把字符串转换成字符数组
        return fromPuzzleString(spdata);
    }

    // 根据九宫格当中的坐标,返回该坐标所应该填写的数字
    private int getTile(int x, int y) {
        return sudoku[y * 9 + x];
    }

    public String getTileString(int x, int y) {
        int v = getTile(x, y);
        if (v == 0) {
            return "";
        } else
            return String.valueOf(v);
    }

    // 根据一个字符串数据,生成一个整形数组,所谓数独游戏的初始化数据
    protected int[] fromPuzzleString(String src) {
        int[] sudo = new int[src.length()];
        for (int i = 0; i < sudo.length; i++) {
            sudo[i] = src.charAt(i) - '0';
        }
        return sudo;
    }

    // 用于计算所有单元格对应的不可用数据
    public void calculateAllUsedTiles() {

        for (int x = 0; x < 9; x++) {
            for (int y = 0; y < 9; y++) {
                used[x][y] = calculateUsedTiles(x, y);
            }
        }
    }

    // 取出某一单元格当中已经不可用得到数据
    public int[] getUsedTilesByCoor(int x, int y) {
        return used[x][y];
    }

    // 计算某一单元格当中已经不可用的数据
    public int[] calculateUsedTiles(int x, int y) {
        int c[] = new int[9];

        for (int i = 0; i < 9; i++) {
            if (i == y)
                continue;
            int t = getTile(x, i);
            if (t != 0)
                c[t - 1] = t;
        }

        for (int i = 0; i < 9; i++) {
            if (i == x)
                continue;
            int t = getTile(i, y);
            if (t != 0)
                c[t - 1] = t;
        }

        int startx = (x / 3) * 3;
        int starty = (y / 3) * 3;
        for (int i = startx; i < startx + 3; i++) {
            for (int j = starty; j < starty + 3; j++) {
                if (i == x && j == y)
                    continue;
                int t = getTile(i, j);
                if (t != 0)
                    c[t - 1] = t;
            }
        }
        // compress
        int nused = 0;
        for (int t : c) {
            if (t != 0)
                nused++;
        }
        int c1[] = new int[nused];
        nused = 0;
        for (int t : c) {
            if (t != 0)
                c1[nused++] = t;
        }
        return c1;
    }

    protected boolean setTileIfValid(int x, int y, int value) {
        int tiles[] = getUsedTiles(x, y);

        if (value != 0) {
            for (int tile : tiles) {
                if (tile == value) {
                    return false;
                }
            }
        }
        settitle(x, y, value);
        System.out.println(settitle(x, y, value));
        Log.e("****************************", "shuduku " + sudoku[y * 9 + x]);
        calculateAllUsedTiles();

        return true;
    }

    private int settitle(int x, int y, int value) {
        return sudoku[y * 9 + x] = value;

    }

    // 该九宫格中使用过的数据(不能用的数据)
    protected int[] getUsedTiles(int x, int y) {
        return used[x][y];
    }

    @Override
    protected void onPause() {
        super.onPause();
        Music.stop(this);
        SharedPreferences sp = getPreferences(MODE_PRIVATE);
        Editor editor = sp.edit();
        editor.putString("String", zhuanhuanString(sudoku));
        editor.commit();
    }

    // 把数组转换成字符串
    private String zhuanhuanString(int[] num) {
        StringBuilder sb = new StringBuilder();
        for (int shudu : num) {
            sb.append(shudu);
        }
        return sb.toString();

    }

    @Override
    protected void onResume() {
        super.onResume();
        Music.play(this, R.raw.game);
    }
}
  • MyView.java(做些点击颜色改变)

public class MyView extends View {

    private float widht, height;
//  private Game game = new Game();
    private final MainActivity game;
    private int selectx, selecty;
    private final Rect selectRect = new Rect();

    // 构造方法
    public MyView(Context context) {
        super(context);
        this.game=(MainActivity)context;
    }

    // 得到改变的视图宽和高
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        this.widht = w / 9f;
        this.height = h / 9f;
        super.onSizeChanged(w, h, oldw, oldh);
    }

    // 画视图,⑨宫格
    @Override
    protected void onDraw(Canvas canvas) {
        // 用于生成背景色的画笔(共4种颜色的画笔)
        Paint backgroundpaint = new Paint();
        // 设置画笔颜色
        backgroundpaint.setColor(getResources().getColor(R.color.background));
        // 画出背景
        canvas.drawRect(0, 0, getWidth(), getHeight(), backgroundpaint);

        Paint darkpaint = new Paint();
        darkpaint.setColor(getResources().getColor(R.color.dark));

        Paint lightpaint = new Paint();
        lightpaint.setColor(getResources().getColor(R.color.light));

        Paint hilitepaint = new Paint();
        hilitepaint.setColor(getResources().getColor(R.color.hilite));

        // 下面开始画线
        for (int i = 0; i < 9; i++) {
            // 画横线
            canvas.drawLine(0, i * height, getWidth(), i * height, lightpaint);
            canvas.drawLine(0, i * height + 1, getWidth(), i * height + 1,
                    hilitepaint);
            // 画竖线
            canvas.drawLine(i * widht, 0, i * widht, getHeight(), lightpaint);
            canvas.drawLine(i * widht + 1, 0, i * widht + 1, getHeight(),
                    hilitepaint);
        }
        // 画外面的最清楚的4个深色的线
        for (int i = 0; i < 9; i++) {
            if (i % 3 != 0) {
                continue;
            }
            // 画横线
            canvas.drawLine(0, i * height, getWidth(), i * height, darkpaint);
            canvas.drawLine(0, i * height + 1, getWidth(), i * height + 1,
                    hilitepaint);
            // 画竖线
            canvas.drawLine(i * widht, 0, i * widht, getHeight(), darkpaint);
            canvas.drawLine(i * widht + 1, 0, i * widht + 1, getHeight(),
                    hilitepaint);
        }
        // 框框里添加文本
        Paint numpaint = new Paint();
        numpaint.setColor(Color.BLACK);
        numpaint.setStyle(Paint.Style.STROKE);
        numpaint.setTextAlign(Paint.Align.CENTER);
        numpaint.setTextSize(height * 0.75f);
        // 數字的位置
        FontMetrics fm = numpaint.getFontMetrics();
        
        float x = widht / 2;
        float y = height / 2 - (fm.ascent + fm.descent) / 2;
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                canvas.drawText(game.getTileString(i, j), i * widht + x, j
                        * height + y, numpaint);
            }
        }
        
        //我们进行绘制小矩形框 ,数字提示颜色
        Paint rectPaint = new Paint();
        int c[] = {getResources().getColor(R.color.puzzle_hint_0),
                   getResources().getColor(R.color.puzzle_hint_1),
                   getResources().getColor(R.color.puzzle_hint_2)};
        //生成矩形对象
        Rect r = new Rect();
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                //我们得到可用数字的个数用moveleft来表示
                int moveleft = 9 - game.getUsedTilesByCoor(i, j).length;
                //如果可用数字小于3 我们用颜色来提示用户
                if(moveleft<c.length){
                    getRect(i,j,r);
                    rectPaint.setColor(c[moveleft]);
                    canvas.drawRect(r,rectPaint);
                }
            }
        }
        
        //我们给选定的九宫格绘制颜色(橙色)
        Paint selectPaint = new Paint();
        selectPaint.setColor(getResources().getColor(R.color.puzzle_selected));
        canvas.drawRect(selectRect,selectPaint);
        
        super.onDraw(canvas);
    }
    //进行绘制矩形,某一个小矩形
    private void getRect(int x,int y,Rect r){
        r.set((int)(x*widht), (int)(y*height),(int)(x*widht+widht), (int)(y*height+height));
    }

    // 触摸每个单元格 则触发此方法
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() != MotionEvent.ACTION_DOWN) {
            return super.onTouchEvent(event);
        }
        selectx = (int) (event.getX() / widht);
        selecty = (int) (event.getY() / height);

        // 我们进行选中的时候来进行颜色变化
        getRect(selectx,selecty,selectRect);
        invalidate(selectRect);
        
        // 调用GAME类的方法(得到使用过的数字)
        int used[] = game.getUsedTilesByCoor(selectx, selecty);
        // 吧使用过的数字加载到 StringBuffer 里面去
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < used.length; i++) {
            sb.append(used[i]);
        }
        KeyDialog dialog = new KeyDialog(getContext(), used, this);
        dialog.show();
        return true;
    }

    // 无参的 直接把传过来的数字 写到九宫格当中
    public void setselecttile(int tile) {
        // 写数字
        if (game.setTileIfValid(selectx, selecty, tile)){
            invalidate();
        }
    }
}

  • Music.java(音乐播放,此方法调用放在需要调用的Activity里)

public class Music {
    private static MediaPlayer mp = null;
    public static void play(Context context,int resoce){
        stop(context);
        mp = MediaPlayer.create(context, resoce);
        mp.setLooping(true);
        mp.start();
    }
    public static void stop(Context context){
        if(mp!=null){
            mp.stop();
            mp.release();
            mp=null;
        }
    }
}
  • OperationActivity.java(首界面)

public class OperationActivity extends Activity implements
 OnClickListener{

    private Button continuee,new_game,about,exit;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.operation);
        iviview();
        
    }
    private void iviview() {
        continuee = (Button) findViewById(R.id.continuee);
        new_game = (Button) findViewById(R.id.new_game);
        about = (Button) findViewById(R.id.about);
        exit = (Button) findViewById(R.id.exit);
        continuee.setOnClickListener(this);
        new_game.setOnClickListener(this);
        about.setOnClickListener(this);
        exit.setOnClickListener(this);
    }
    public void onClick(View v) {
        if(v==continuee){
            Intent j = new Intent(OperationActivity.this,MainActivity.class);
            j.putExtra("contin", -1);
            startActivity(j);
        }
        if(v==new_game){
            Intent i = new Intent(OperationActivity.this,MainActivity.class);
            startActivity(i);
        }
        if(v==about){
            Intent i_1 = new Intent(OperationActivity.this,AboutActivity.class);
            startActivity(i_1);
        }
        if(v==exit){
            finish();
        }
    }
    @Override
    protected void onPause() {
        super.onPause();
        Music.stop(this);
    }
    @Override
    protected void onResume() {
        super.onResume();
        Music.play(this, R.raw.main);
    }
}
  • AboutActivity.java(点击About弹出此Activity)

public class AboutActivity extends Activity {

    private TextView about;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.about);
        about = (TextView) findViewById(R.id.about);
        about.setText("Sudoku disk is a house, every house is divided into nine compartments. In these eighty-one spaces are given a certain number of known figures and problem solving conditions, the use of logic and reasoning, in other spaces on the 1-9 numbers. "
                + "The 1-9 of each number in each row, "
                + "each column and each palace only once, so called squares.");
    }
}

下面就是布局了:(其它布局不变)

  • operation.xml(首界面)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#226207"
    android:orientation="vertical" >
    <TextView 
        android:layout_marginTop="70dp"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textColor="#ffffff"
        android:textSize="40sp"
        android:text="Android shudu"/>
    <Button 
        android:layout_marginTop="85dp"
        android:id="@+id/continuee"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Continuee"/>
    <Button 
        android:id="@+id/new_game"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="new game"/>
    <Button 
        android:id="@+id/about"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="About"/>
    <Button 
        android:id="@+id/exit"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="EXIT"/>
    
</LinearLayout>
  • about.xml(关于的布局)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/about"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" 
        />

</LinearLayout>
  • AndroidManifest.xml(修改首起Activity,配置属性)

 <activity android:name=".MainActivity"></activity>
         <activity android:name=".AboutActivity"
             android:theme="@android:style/Theme.Dialog"
             ></activity>
        <activity
            android:name=".OperationActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
  • 演示:

xiaoguo.gif
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,427评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,551评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,747评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,939评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,955评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,737评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,448评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,352评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,834评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,992评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,133评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,815评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,477评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,022评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,147评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,398评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,077评论 2 355

推荐阅读更多精彩内容