(通过界面我们知道,点击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