做出来一个贪吃蛇,圣诞之俄罗斯方块好难难吗

航母下水,大飞机上天,“大唐盛世”复苏有望。
再过不到一个月的时间,我们就将迎来苹果在今年的第一次盛会 —— WWDC 2017 开发者大...
如果平时多和孩子们沟通,了解他们的心理,那么他们又怎么会想到去参与这个游戏呢?
台积电是苹果重要的芯片制造供应商,iPhone的销量自然也影响着其营收。
国内的iBooks商店,什么时候能够回归?
请不要说难怪会被苹果拒绝。
随着 HTC U11 正式发布日期 5 月 16 日的日益临近,关于新机的消息也开始变得越来越多...
看来,苹果终于知道“GIF斗图”的重要性了。
现在随着交通越发的发达便利,全球化的步伐加快,出国旅游成为了大家享受生活,认识世...
最近 Sanrio Digital Europe 推出了一款新作《Hello Kitty 音乐派对》,Hello Kitty ...
集合了 Detective Comics (DC漫画)与华纳兄弟两大行业巨头功力于一身的超级英雄格斗...
这是一款需要用心玩的游戏,用你捏出来的人物,去闯荡你的江湖,喜欢或者讨厌,是不是...
要想经营好一家电视台或者一个频道可不是一件容易的事情,尤其是在如今生活节奏加快,...
《炫动城市(City Mania Town Building Game)》是由知名厂商Gameloft推出的一款模拟...
《Knot 3D》就是为了致敬“孔明锁”这个让他们玩到根本停不下来的中国传统玩具,虽然...
一个好的配件绝对能提高iPhone的使用体验~
你的Smart Keyboard还好吗?
你的iPad Pro的Smart Keyboard还好吗?
Swimpad 是一款专为 iPad mini 设计的防水套,让用户在游泳池也可以随时使用 iPad min...
你也想要HomeKit家居吗?
相信大部分的Apple Watch用户,都拥有不止一条的Apple Watch表带。
Apple Watch、AirPods 和 Beats 耳机产品线年收入惊人,堪比世界500强。
乍一看,俨然一台缩小迷你版的imac,可谓苹果元素满满。
教你用终端玩贪吃蛇和俄罗斯方块(更新步骤图)
注册时间 最后登录
在线时间977 小时 UID
主题帖子人气
红苹果, 积分 493, 距离下一级还需 7 积分
首先在应用程序--实用工具中找到终端
按下esc+x(光标会移动最下方)
2.png (85 KB, 下载次数: 0)
17:12 上传
输入tetris就是俄罗斯方块,输入snake就是贪吃蛇
3.png (86 KB, 下载次数: 0)
17:12 上传
回车之后就可以进入游戏了
5.png (61 KB, 下载次数: 0)
17:12 上传
(100 KB, 下载次数: 0)
17:12 上传
<p id="rate_2270" onmouseover="showTip(this)" tip="果断收藏。牛B~&人气 + 5
" class="mtn mbn">
<p id="rate_3797" onmouseover="showTip(this)" tip="这都被你发现了,牛X&人气 + 1
" class="mtn mbn">
<p id="rate_5177" onmouseover="showTip(this)" tip="这个确实很牛逼。我怎么第一次发现?是什么原理啊?是苹果留下的彩蛋吗?&人气 + 3
" class="mtn mbn">
果断收藏。牛B~
这都被你发现了,牛X
这个确实很牛逼。我怎么第一次发现?是什么原理啊?是苹果留下的彩蛋吗?
注册时间 最后登录
在线时间923 小时 UID
主题帖子人气
貌似很牛逼。。。对小白来说,
注册时间 最后登录
在线时间3264 小时 UID
主题帖子人气
提示: 作者被禁止或删除 内容自动屏蔽
注册时间 最后登录
在线时间201 小时 UID
主题帖子人气
注册时间 最后登录
在线时间16 小时 UID
主题帖子人气
注册时间 最后登录
在线时间2081 小时 UID
主题帖子人气
回 楼主(会飞的2) 的帖子
lz 输入snake 回车无反应啊引用楼主会飞的2于 21:59发表的
:首先在应用程序--实用工具中找到终端输入emacs=700) window.open(
注册时间 最后登录
在线时间2784 小时 UID
主题帖子人气
An exchange student at SFU
這是emacs這個披著編輯器外衣的操作系統內置的遊戲呢。。。不是mac獨有的。。。
注册时间 最后登录
在线时间1647 小时 UID
主题帖子人气
注册时间 最后登录
在线时间528 小时 UID
主题帖子人气
对会飞的2于 10:45在楼主发表的主题评分:人气:+3;
首先在应用程序--实用工具中找到终端
按下esc+x(光标会移动最下方)
输入tetris就是俄罗斯方块,输入snake就是贪吃蛇
..这个确实很牛逼。我怎么第一次发现?是什么原理啊?是苹果留下的彩蛋吗?
注册时间 最后登录
在线时间1427 小时 UID
主题帖子人气
怎么我玩不了
威锋旗下产品
Hi~我是威威!
沪公网安备 29号 | 沪ICP备号-1
新三板上市公司威锋科技(836555)
增值电信业务经营许可证:
Powered by Discuz!博客访问: 1123710
博文数量: 121
博客积分: 3526
博客等级: 中校
技术积分: 1824
注册时间:
认证徽章:
记录总结自己的工作
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: 嵌入式
&& &前几天看Android自带的例子代码,其中有个贪吃蛇的游戏,看了其代码后觉得写得非常好,同时又有了想写一个俄罗斯方块游戏的想法。俄罗斯方块的游戏我以前曾经用JAVA实现过,当时实现得很复杂,而现在有了这个贪吃蛇的例子后,实现起来就简单多了。在贪吃蛇游戏中有个类TileView.java,这个类基本实现了对单个方块的操作,因此我就直接拿来用了,并没有做任何的修改,这个类的代码就不在这里贴出了。
&& &俄罗斯方块游戏比贪吃蛇稍微复杂一些,其主要的难点主要有:
&& &1.实现方块的旋转。我们都知道在游戏中按上方块是要旋转的,我对方块的旋转就是选择一个方块作为中心,另外3个方块都绕着它顺时针旋转90度。需要注意的一点就是田形的方块是不需要旋转的,如果按照我的方法旋转田形方块就会造成方块平移的结果。
&& &2.边界的判定。就是判断一下方块是否可以移动,这包含两方面的内容,一方面是水平方向的移动,这里需要注意的就是在边界上旋转方块又可能使方块旋转出边界,所以在旋转前必要预先判断一下旋转后的方块是否已经超出了边界;另一方面是往下移动,一旦不能移动了就需要冻结方块并产生新的方块。
&& &3.消行。每落下一个方块都需要判断一下是否可以消行。而消行后上面的方块又都要垂直下落,同时原来的位置也要被清空。
&& &下面说一下实现这个游戏的步骤:
&& &1.创建一个新的ANDROID工程,命名为Tetris,包名为com.test。
&& &2.创建一个activity类,命名为:Tetris.java。
package com.test;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Tetris extends Activity {
&&&&private String TAG = "Tetris";
&&&&private TetrisView tetrisView;
&&&&private TextView highestScore;
&&&&private TextView info;
&&&&private TextView currentScore;
&&&&private TextView currentLevel;
&&&&String NAME = "score.txt";
&&&&&* 保存数据时用到的key
&&&&private static String ICICLE_KEY = "tetris-view";
&&&&&* 游戏的主要activity
&&&&public void onCreate(Bundle savedInstanceState) {
&&&&&&&&super.onCreate(savedInstanceState);
&&&&&&&&setContentView(R.layout.tetris_layout);
&&&&&&&&tetrisView = (TetrisView)findViewById(R.id.tetris);
&&&&&&&&highestScore = (TextView)findViewById(R.id.highest_score);
&&&&&&&&currentScore = (TextView)findViewById(R.id.current_score);
&&&&&&&&info = (TextView)findViewById(R.id.info);
&&&&&&&&currentLevel = (TextView)findViewById(R.id.current_level);
&&&&&&&&// 为view实例化这些文本框
&&&&&&&&tetrisView.setTextView(currentScore, highestScore, info, currentLevel);
&&&&&&&&if (savedInstanceState == null) {
&&&&&&&&&&&&// 开始一个新游戏,将游戏的状态设为READY
&&&&&&&&&&&&tetrisView.setMode(TetrisView.READY);
&&&&&&&&} else {
&&&&&&&&&&&&// 如果存储了一个游戏的状态,则将状态读出来,可以继续游戏
&&&&&&&&&&&&Bundle map = savedInstanceState.getBundle(ICICLE_KEY);
&&&&&&&&&&&&if (map != null) {
&&&&&&&&&&&&&&&&tetrisView.restoreState(map);
&&&&&&&&&&&&} else {
&&&&&&&&&&&&&&&&tetrisView.setMode(TetrisView.PAUSE);
&&&&&&&&&&&&}
&&&&&&&&// 读取历史最高分
&&&&&&&&FileInputStream in;
&&&&&&&&byte[] by = new byte[10];
&&&&&&&&try {
&&&&&&&&&&&&in = openFileInput(NAME);
&&&&&&&&&&&&in.read(by);
&&&&&&&&&&&&StringBuffer buffer = new StringBuffer();
&&&&&&&&&&&&for (int i = 0; i < 10; i++) {
&&&&&&&&&&&&&&&&if (by[i] != 0) {
&&&&&&&&&&&&&&&&&&&&buffer.append(by[i] - 48);
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&&&&&Log.d("dd", buffer.toString());
&&&&&&&&&&&&tetrisView.historyScore = Long.valueOf(buffer.toString());
&&&&&&&&} catch (FileNotFoundException e) {
&&&&&&&&} catch (IOException e) {
&&&&&&&&&&&&// TODO Auto-generated catch block
&&&&&&&&&&&&e.printStackTrace();
&&&&@Override
&&&&protected void onPause() {
&&&&&&&&//如果分数超出了历史最高分,则保存数据
&&&&&&&&if (tetrisView.overhistroy) {
&&&&&&&&&&&&FileOutputStream fos;
&&&&&&&&&&&&try {
&&&&&&&&&&&&&&&&fos = openFileOutput(NAME, Context.MODE_PRIVATE);
&&&&&&&&&&&&&&&&fos.write(String.valueOf(TetrisView.historyScore).getBytes());
&&&&&&&&&&&&&&&&fos.close();
&&&&&&&&&&&&} catch (FileNotFoundException e) {
&&&&&&&&&&&&&&&&// TODO Auto-generated catch block
&&&&&&&&&&&&&&&&e.printStackTrace();
&&&&&&&&&&&&} catch (IOException e) {
&&&&&&&&&&&&&&&&// TODO Auto-generated catch block
&&&&&&&&&&&&&&&&e.printStackTrace();
&&&&&&&&&&&&}
&&&&&&&&super.onPause();
&&&&&&&&// 暂停游戏
&&&&&&&&tetrisView.setMode(TetrisView.PAUSE);
&&&&@Override
&&&&public void onSaveInstanceState(Bundle outState) {
&&&&&&&&// 保存游戏状态
&&&&&&&&outState.putBundle(ICICLE_KEY, tetrisView.saveState());
package com.test;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.TextView;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
public class TetrisView extends TileView {
&&&&private static final String TAG = "TetrisView";
&&&&&* 游戏的四种状态
&&&&private int mMode = READY;
&&&&public static final int PAUSE = 0;
&&&&public static final int READY = 1;
&&&&public static final int RUNNING = 2;
&&&&public static final int LOSE = 3;
&&&&&* 三种背景图片,由这些图片拼装成游戏的基本界面
&&&&private static final int RED_STAR = 1;
&&&&private static final int YELLOW_STAR = 2;
&&&&private static final int GREEN_STAR = 3;
&&&&&* 产生随机数,根据随机数决定方块的形状
&&&&private static final Random RNG = new Random();
&&&&&* 当前游戏的分数
&&&&private long mScore = 0;
&&&&&* 历史最高分
&&&&public static long historyScore = 0;
&&&&&* 是否超出了最高分,如果超出了,则在退出时会保存数据
&&&&public static boolean overhistroy=false;
&&&&&* 方块移动的速度,数值越小则方块的速度越高,难度也就越大
&&&&private long mMoveDelay;
&&&&&* 当前方块移动的速度,和mMoveDelay配合使用,在游戏中更改游戏的速度都是更改此变量值
&&&&&* 在每个方块产生的时候,将此变量值赋给mMoveDelay。之所以采用两个变量是因为当按下加速 方块落下之后,下一个方块的速度还要保持原来的速度。
&&&&private long currentDelay;
&&&&&* 预先显示的方块,在前一个方块落下后,使其变为当前方块
&&&&private ArrayList<Coordinate> preShape = new ArrayList<Coordinate>();
&&&&&* 当前正在下落的方块
&&&&private ArrayList<Coordinate> mShape = new ArrayList<Coordinate>();
&&&&private ArrayList<Coordinate> oldShape = new ArrayList<Coordinate>();
&&&&&* 显示历史最高分的文本框
&&&&private TextView highestScore;
&&&&&* 显示当前分数的文本框
&&&&private TextView currentScore;
&&&&&* 显示当前游戏级别的文本框
&&&&private TextView currentLevel;
&&&&&* 记录游戏的级别
&&&&private int gameLevel = 1;
&&&&&* 在屏幕中央显示提示信息的文本框
&&&&private TextView info;
&&&&&* 记录目前落下的方块的最高层数
&&&&private int highLevel = 0;
&&&&&* 当前方块类型,主要用来标示田形方块,从而在旋转方块的时候可以让田形方块不旋转
&&&&private int shapeType;
&&&&&* 预先显示方块的类型
&&&&private int preType;
&&&&&* 构造方法
&&&&public TetrisView(Context context, AttributeSet attrs) {
&&&&&&&&super(context, attrs);
&&&&&&&&initGame();
&&&&public TetrisView(Context context, AttributeSet attrs, int defStyle) {
&&&&&&&&super(context, attrs, defStyle);
&&&&&&&&initGame();
&&&&&* 通过一个handler来更新界面的显示,以及方块下落的速度
&&&&private RefreshHandler mRedrawHandler = new RefreshHandler();
&&&&class RefreshHandler extends Handler {
&&&&&&&&@Override
&&&&&&&&public void handleMessage(Message msg) {
&&&&&&&&&&&&TetrisView.this.update();
&&&&&&&&&&&&TetrisView.this.invalidate();
&&&&&&&&public void sleep(long delayMillis) {
&&&&&&&&&&&&this.removeMessages(0);
&&&&&&&&&&&&sendMessageDelayed(obtainMessage(0), delayMillis);
&&&&&* 初始化游戏
&&&&private void initGame() {
&&&&&&&&setFocusable(true);
&&&&&&&&Resources r = this.getContext().getResources();
&&&&&&&&resetTiles(4);
&&&&&&&&loadTile(RED_STAR, r.getDrawable(R.drawable.redstar));
&&&&&&&&loadTile(YELLOW_STAR, r.getDrawable(R.drawable.yellowstar));
&&&&&&&&loadTile(GREEN_STAR, r.getDrawable(R.drawable.greenstar));
&&&&&* 开始一个新游戏,重置各种数据
&&&&private void startGame() {
&&&&&&&&clearTiles();
&&&&&&&&gameLevel = 1;
&&&&&&&&highLevel = 0;
&&&&&&&&currentDelay = 600;
&&&&&&&&mScore = 0;
&&&&&&&&currentScore.setText("当前分数:\n" + mScore);
&&&&&&&&currentLevel.setText("当前级别:\n" + gameLevel);
&&&&&&&&highestScore.setText("最高分数:\n"+historyScore);
&&&&&&&&setMode(RUNNING);
&&&&&* 将arraylist转换为数组,从而可以将该部分数据保存起来
&&&&private int[] coordArrayListToArray(ArrayList<Coordinate> cvec) {
&&&&&&&&int count = cvec.size();
&&&&&&&&int[] rawArray = new int[count * 2];
&&&&&&&&for (int index = 0; index < count; index++) {
&&&&&&&&&&&&Coordinate c = cvec.get(index);
&&&&&&&&&&&&rawArray[2 * index] = c.x;
&&&&&&&&&&&&rawArray[2 * index + 1] = c.y;
&&&&&&&&return rawArray;
&&&&&* 将已经落下来的方块的坐标保存在一个ArrayList中
&&&&private ArrayList<Coordinate> tailsToList(int[][] tileGrid) {
&&&&&&&&ArrayList<Coordinate> tranList = new ArrayList<Coordinate>();
&&&&&&&&for (int i = 0; i < mXTileCount - 6; i++) {
&&&&&&&&&&&&for (int j = 1; j < mYTileCount - 1; j++) {
&&&&&&&&&&&&&&&&if (tileGrid[i][j] == RED_STAR) {
&&&&&&&&&&&&&&&&&&&&Coordinate cor = new Coordinate(i, j);
&&&&&&&&&&&&&&&&&&&&tranList.add(cor);
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&return tranList;
&&&&&* 保存游戏的状态,从而在切换游戏后还可以继续游戏
&&&&&* @return a Bundle with this view's state
&&&&public Bundle saveState() {
&&&&&&&&Bundle map = new Bundle();
&&&&&&&&map.putIntArray("preShapeList", coordArrayListToArray(preShape));
&&&&&&&&map.putIntArray("mShapeList", coordArrayListToArray(mShape));
&&&&&&&&map.putLong("mMoveDelay", Long.valueOf(mMoveDelay));
&&&&&&&&map.putLong("mScore", Long.valueOf(mScore));
&&&&&&&&map.putLong("hisScore", Long.valueOf(historyScore));
&&&&&&&&map.putInt("mLevel", highLevel);
&&&&&&&&map.putIntArray("tailList", coordArrayListToArray(tailsToList(mTileGrid)));
&&&&&&&&return map;
&&&&&* 将数组转换为Arraylist,从而将保存的数据转化为游戏的状态
&&&&&* @param rawArray : [x1,y1,x2,y2,...]
&&&&&* @return a ArrayList of Coordinates
&&&&private ArrayList<Coordinate> coordArrayToArrayList(int[] rawArray) {
&&&&&&&&ArrayList<Coordinate> coordArrayList = new ArrayList<Coordinate>();
&&&&&&&&int coordCount = rawArray.length;
&&&&&&&&for (int index = 0; index < coordCount; index += 2) {
&&&&&&&&&&&&Coordinate c = new Coordinate(rawArray[index], rawArray[index + 1]);
&&&&&&&&&&&&coordArrayList.add(c);
&&&&&&&&return coordArrayList;
&&&&&* 从保存的数据中读取已经落下的方块坐标,并重新在界面上画出这些方块
&&&&private void listToTail(ArrayList<Coordinate> cor) {
&&&&&&&&int count = cor.size();
&&&&&&&&for (int index = 0; index < count; index++) {
&&&&&&&&&&&&Coordinate c = cor.get(index);
&&&&&&&&&&&&mTileGrid[c.x][c.y] = RED_STAR;
&&&&&* 切换到游戏的时候,读取所保存的数据,重现游戏先前的状态
&&&&&* @param icicle a Bundle containing the game state
&&&&public void restoreState(Bundle icicle) {
&&&&&&&&setMode(PAUSE);
&&&&&&&&historyScore = icicle.getLong("hisScore");
&&&&&&&&highLevel = icicle.getInt("mLevel");
&&&&&&&&mMoveDelay = icicle.getLong("mMoveDelay");
&&&&&&&&mScore = icicle.getLong("mScore");
&&&&&&&&preShape = coordArrayToArrayList(icicle.getIntArray("preShapeList"));
&&&&&&&&mShape = coordArrayToArrayList(icicle.getIntArray("mShapeList"));
&&&&&&&&listToTail(coordArrayToArrayList(icicle.getIntArray("tailList")));
&&&&&* 对按键的响应
&&&&public boolean onKeyDown(int keyCode, KeyEvent msg) {
&&&&&&&&// 按下了上键
&&&&&&&&if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
&&&&&&&&&&&&if (mMode == READY | mMode == LOSE) {
&&&&&&&&&&&&&&&&startGame();
&&&&&&&&&&&&&&&&setMode(RUNNING);
&&&&&&&&&&&&&&&&return (true);
&&&&&&&&&&&&} else if (mMode == RUNNING) {
&&&&&&&&&&&&&&&&transShape();
&&&&&&&&&&&&&&&&update();
&&&&&&&&&&&&&&&&return (true);
&&&&&&&&&&&&}
&&&&&&&&&&&&if (mMode == PAUSE) {
&&&&&&&&&&&&&&&&setMode(RUNNING);
&&&&&&&&&&&&&&&&update();
&&&&&&&&&&&&&&&&return (true);
&&&&&&&&&&&&}
&&&&&&&&// 按下了下键
&&&&&&&&if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
&&&&&&&&&&&&moveDown();
&&&&&&&&&&&&return (true);
&&&&&&&&// 按下了左键
&&&&&&&&if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
&&&&&&&&&&&&moveLeft();
&&&&&&&&&&&&updateShape();
&&&&&&&&&&&&return (true);
&&&&&&&&// 按下了右键
&&&&&&&&if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
&&&&&&&&&&&&moveRight();
&&&&&&&&&&&&updateShape();
&&&&&&&&&&&&return (true);
&&&&&&&&return super.onKeyDown(keyCode, msg);
&&&&&* 加速方块的下落
&&&&private void moveDown() {
&&&&&&&&mMoveDelay = 50;
&&&&&* 将方块向右移动,在移动前要判断一下是否可以移动
&&&&private void moveRight() {
&&&&&&&&newToOld(mShape, oldShape);
&&&&&&&&for (Coordinate c : mShape) {
&&&&&&&&&&&&c.x = c.x + 1;
&&&&&&&&// 如果不可以移动,则保持位置不变
&&&&&&&&if (!isMoveAble(mShape)) {
&&&&&&&&&&&&for (Coordinate c : mShape) {
&&&&&&&&&&&&&&&&c.x = c.x - 1;
&&&&&&&&&&&&}
&&&&&* 将方块向左移动
&&&&private void moveLeft() {
&&&&&&&&newToOld(mShape, oldShape);
&&&&&&&&for (Coordinate c : mShape) {
&&&&&&&&&&&&c.x = c.x - 1;
&&&&&&&&if (!isMoveAble(mShape)) {
&&&&&&&&&&&&for (Coordinate c : mShape) {
&&&&&&&&&&&&&&&&c.x = c.x + 1;
&&&&&&&&&&&&}
&&&&&* 旋转方块
&&&&private void transShape() {
&&&&&&&&Coordinate core = mShape.get(0);
&&&&&&&&if (shapeType == 3) {
&&&&&&&&&&&&// 田形,不用做任何事情
&&&&&&&&} else {
&&&&&&&&&&&&newToOld(mShape, oldShape);
&&&&&&&&&&&&for (Coordinate c : mShape) {
&&&&&&&&&&&&&&&&int x = core.x + (core.y - c.y);
&&&&&&&&&&&&&&&&int y = core.y + (c.x - core.x);
&&&&&&&&&&&&&&&&c.x = x;
&&&&&&&&&&&&&&&&c.y = y;
&&&&&&&&&&&&}
&&&&&&&&&&&&// 如果可以旋转,则旋转90度并更新显示
&&&&&&&&&&&&if (isMoveAble(mShape)) {
&&&&&&&&&&&&&&&&updateShape();
&&&&&&&&&&&&&&&&TetrisView.this.invalidate();
&&&&&&&&&&&&} else {
&&&&&&&&&&&&&&&&for (Coordinate c : mShape) {
&&&&&&&&&&&&&&&&&&&&int x = core.x + (c.y - core.y);
&&&&&&&&&&&&&&&&&&&&int y = core.y + (core.x - c.x);
&&&&&&&&&&&&&&&&&&&&c.x = x;
&&&&&&&&&&&&&&&&&&&&c.y = y;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&* 将一个方块的形状赋给另外一个
&&&&&* @param mShape2
&&&&&* @param oldShape2
&&&&private void newToOld(ArrayList<Coordinate> mShape2, ArrayList<Coordinate> oldShape2) {
&&&&&&&&oldShape2.clear();
&&&&&&&&for (int i = 0; i < 4; i++) {
&&&&&&&&&&&&Coordinate c1 = mShape2.get(i);
&&&&&&&&&&&&Coordinate c2 = new Coordinate(c1.x, c1.y);
&&&&&&&&&&&&oldShape2.add(c2);
&&&&&* 处理游戏的更新
&&&&public void update() {
&&&&&&&&if (mMode == RUNNING) {
&&&&&&&&&&&&// clearTiles();
&&&&&&&&&&&&updateBlackGround();
&&&&&&&&&&&&if (mXTileCount != 0) {
&&&&&&&&&&&&&&&&// 如果是刚开始游戏,则初始化方块形状
&&&&&&&&&&&&&&&&if (mShape.size() == 0) {
&&&&&&&&&&&&&&&&&&&&shapeType = RNG.nextInt(7);
&&&&&&&&&&&&&&&&&&&&mShape = getShape(shapeType);
&&&&&&&&&&&&&&&&&&&&preType = RNG.nextInt(7);
&&&&&&&&&&&&&&&&&&&&preShape = getShape(preType);
&&&&&&&&&&&&&&&&&&&&mMoveDelay = currentDelay;
&&&&&&&&&&&&&&&&&&&&// 设置方块的初始位置
&&&&&&&&&&&&&&&&&&&&for (Coordinate c : mShape) {
&&&&&&&&&&&&&&&&&&&&&&&&c.x = c.x + mXTileCount / 3;
&&&&&&&&&&&&&&&&&&&&&&&&c.y = c.y + 1;
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&// 将方块往下移动一格
&&&&&&&&&&&&&&&&newToOld(mShape, oldShape);
&&&&&&&&&&&&&&&&for (Coordinate c : mShape) {
&&&&&&&&&&&&&&&&&&&&c.y++;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&// 如果方块可以往下移动,则更新图形
&&&&&&&&&&&&&&&&if (canMoveDown(mShape)) {
&&&&&&&&&&&&&&&&&&&&updateShape();
&&&&&&&&&&&&&&&&} else {
&&&&&&&&&&&&&&&&&&&&// 如果不可以往下移动则将方块的状态改为已落下并开始落下新方块
&&&&&&&&&&&&&&&&&&&&updateBlew();
&&&&&&&&&&&&&&&&&&&&mShape = preShape;
&&&&&&&&&&&&&&&&&&&&shapeType = preType;
&&&&&&&&&&&&&&&&&&&&for (Coordinate c : mShape) {
&&&&&&&&&&&&&&&&&&&&&&&&c.x = c.x + mXTileCount / 3;
&&&&&&&&&&&&&&&&&&&&&&&&c.y = c.y + 1;
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&preType = RNG.nextInt(7);
&&&&&&&&&&&&&&&&&&&&preShape = getShape(preType);
&&&&&&&&&&&&&&&&&&&&mMoveDelay = currentDelay;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&updatePreShape();
&&&&&&&&&&&&}
&&&&&&&&// 设置方块落下的速度
&&&&&&&&mRedrawHandler.sleep(mMoveDelay);
&&&&// 方块落下过程中颜色为黄色
&&&&private void updateShape() {
&&&&&&&&for (Coordinate c : oldShape) {
&&&&&&&&&&&&setTile(0, c.x, c.y);
&&&&&&&&&&&&Log.d(TAG, "old" + c.x + c.y);
&&&&&&&&for (Coordinate c : mShape) {
&&&&&&&&&&&&Log.d(TAG, "new" + c.x + c.y);
&&&&&&&&&&&&if (mXTileCount != 0) {
&&&&&&&&&&&&&&&&setTile(YELLOW_STAR, c.x, c.y);
&&&&&&&&&&&&}
&&&&// 方块落下后颜色为红色
&&&&private void updateBlew() {
&&&&&&&&for (Coordinate c : mShape) {
&&&&&&&&&&&&if (mXTileCount != 0) {
&&&&&&&&&&&&&&&&setTile(RED_STAR, c.x, c.y - 1);
&&&&&&&&&&&&&&&&if (mYTileCount - c.y > highLevel) {
&&&&&&&&&&&&&&&&&&&&highLevel = mYTileCount - c.y;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&// GAME OVER
&&&&&&&&if (highLevel > mYTileCount - 3) {
&&&&&&&&&&&&setMode(LOSE);
&&&&&&&&// 已经消去的行数
&&&&&&&&int deleRows = 0;
&&&&&&&&for (int i = 1; i <= highLevel + 1; i++) {
&&&&&&&&&&&&int redCount = 0;
&&&&&&&&&&&&for (int x = 1; x < mXTileCount - 7; x++) {
&&&&&&&&&&&&&&&&if (mTileGrid[x][mYTileCount - i] == RED_STAR) {
&&&&&&&&&&&&&&&&&&&&redCount++;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&&&&&// 如果某一行的红色方格数等于列总数,则该列需要消去
&&&&&&&&&&&&if (redCount == mXTileCount -8 ) {
&&&&&&&&&&&&&&&&deleRows++;
&&&&&&&&&&&&&&&&continue;
&&&&&&&&&&&&} else {
&&&&&&&&&&&&&&&&// 将不需要消去的行向下移动,移动的幅度取决于前面消去的行数
&&&&&&&&&&&&&&&&if (deleRows != 0) {
&&&&&&&&&&&&&&&&&&&&for (int x = 1; x < mXTileCount - 6; x++) {
&&&&&&&&&&&&&&&&&&&&&&&&mTileGrid[x][mYTileCount - i + deleRows] = mTileGrid[x][mYTileCount - i];
&&&&&&&&&&&&&&&&&&&&&&&&mTileGrid[x][mYTileCount - i] = 0;
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&// 更改分数,一次性消去的行数越多,得到的分数就越多
&&&&&&&&switch (deleRows) {
&&&&&&&&&&&&case 1:
&&&&&&&&&&&&&&&&mScore = mScore + 100;
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&case 2:
&&&&&&&&&&&&&&&&mScore = mScore + 300;
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&case 3:
&&&&&&&&&&&&&&&&mScore = mScore + 500;
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&case 4:
&&&&&&&&&&&&&&&&mScore = mScore + 800;
&&&&&&&&&&&&&&&&break;
&&&&&&&&// 更新最高分
&&&&&&&&if (mScore > historyScore) {
&&&&&&&&&&&&overhistroy=true;
&&&&&&&&&&&&historyScore = mScore;
&&&&&&&&&&&&highestScore.setText("最高分数: \n" + historyScore);
&&&&&&&&// 更新当前分
&&&&&&&&currentScore.setText("当前分数:\n" + mScore);
&&&&&&&&// 当级别达到一定的程度后不再增加方块下落的速度
&&&&&&&&if (mScore >= (500 * (gameLevel * 2 - 1))) {
&&&&&&&&&&&&gameLevel++;
&&&&&&&&&&&&currentDelay -= 50;
&&&&&&&&&&&&if (currentDelay < 50)
&&&&&&&&&&&&&&&&currentDelay = 50;
&&&&&&&&// 更新当前级别
&&&&&&&&currentLevel.setText("当前级别:\n" + gameLevel);
&&&&&* 设置游戏的状态
&&&&&* @param newMode
&&&&public void setMode(int newMode) {
&&&&&&&&int oldMode = mMode;
&&&&&&&&mMode = newMode;
&&&&&&&&if (newMode == RUNNING & oldMode != RUNNING) {
&&&&&&&&&&&&info.setVisibility(View.INVISIBLE);
&&&&&&&&&&&&update();
&&&&&&&&&&&&return;
&&&&&&&&Resources res = getContext().getResources();
&&&&&&&&CharSequence str = "";
&&&&&&&&if (newMode == PAUSE) {
&&&&&&&&&&&&str = res.getText(R.string.mode_pause);
&&&&&&&&if (newMode == READY) {
&&&&&&&&&&&&str = res.getText(R.string.mode_ready);
&&&&&&&&if (newMode == LOSE) {
&&&&&&&&&&&&str = res.getString(R.string.mode_lose_prefix) + mScore
&&&&&&&&&&&&&&&&&&&&+ res.getString(R.string.mode_lose_suffix);
&&&&&&&&// 显示提示信息
&&&&&&&&info.setText(str);
&&&&&&&&info.setVisibility(View.VISIBLE);
&&&&&* 更新预先显示方块
&&&&private void updatePreShape() {
&&&&&&&&for (int x = mXTileCount - 4; x < mXTileCount; x++) {
&&&&&&&&&&&&for (int y = 1; y < 6; y++) {
&&&&&&&&&&&&&&&&setTile(0, x, y);
&&&&&&&&&&&&}
&&&&&&&&for (Coordinate c : preShape) {
&&&&&&&&&&&&if (mXTileCount != 0) {
&&&&&&&&&&&&&&&&setTile(YELLOW_STAR, c.x + mXTileCount - 3, c.y + 2);
&&&&&&&&&&&&}
&&&&&* 判断方块是否可以移动
&&&&&* @param list
&&&&&* @return
&&&&private boolean isMoveAble(ArrayList<Coordinate> list) {
&&&&&&&&boolean moveAble = true;
&&&&&&&&for (Coordinate c : list) {
&&&&&&&&&&&&if (mTileGrid[c.x][c.y] != GREEN_STAR && mTileGrid[c.x][c.y] != RED_STAR) {
&&&&&&&&&&&&&&&&continue;
&&&&&&&&&&&&} else {
&&&&&&&&&&&&&&&&moveAble = false;
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&}
&&&&&&&&return moveAble;
&&&&&* 判断方块是否可以往下移动
&&&&&* @param list
&&&&&* @return
&&&&private boolean canMoveDown(ArrayList<Coordinate> list) {
&&&&&&&&boolean moveAble = true;
&&&&&&&&for (Coordinate c : list) {
&&&&&&&&&&&&if (c.y < mYTileCount - 1 && mTileGrid[c.x][c.y] != RED_STAR) {
&&&&&&&&&&&&&&&&continue;
&&&&&&&&&&&&} else {
&&&&&&&&&&&&&&&&moveAble = false;
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&}
&&&&&&&&return moveAble;
&&&&&* 画出游戏的背景.即游戏的边框
&&&&private void updateBlackGround() {
&&&&&&&&for (int x = 0; x < mXTileCount - 5; x++) {
&&&&&&&&&&&&setTile(GREEN_STAR, x, 0);
&&&&&&&&&&&&setTile(GREEN_STAR, x, mYTileCount - 1);
&&&&&&&&for (int y = 1; y < mYTileCount - 1; y++) {
&&&&&&&&&&&&setTile(GREEN_STAR, 0, y);
&&&&&&&&&&&&setTile(GREEN_STAR, mXTileCount - 6, y);
&&&&&* 根据随机数产生各种形状的方块
&&&&&* @param n
&&&&&* @return
&&&&private ArrayList<Coordinate> getShape(int n) {
&&&&&&&&ArrayList<Coordinate> shape = new ArrayList<Coordinate>();
&&&&&&&&switch (n) {
&&&&&&&&&&&&case 1:
&&&&&&&&&&&&&&&&// 反Z拐角
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(1, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 1));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(-1, 1));
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&case 2:
&&&&&&&&&&&&&&&&// 正Z拐角
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(-1, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 1));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(1, 1));
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&case 3:
&&&&&&&&&&&&&&&&// 田形
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 1));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(1, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(1, 1));
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&case 4:
&&&&&&&&&&&&&&&&// 长条
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(-1, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(1, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(2, 0));
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&case 5:
&&&&&&&&&&&&&&&&// 长左拐形
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(-1, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 1));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 2));
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&case 6:
&&&&&&&&&&&&&&&&// 长右拐形
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(1, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 1));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 2));
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&case 0:
&&&&&&&&&&&&&&&&// 凸形
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(-1, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(1, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 1));
&&&&&&&&&&&&&&&&break;
&&&&&&&&return shape;
&&&&public void setTextView(TextView curView, TextView higView, TextView infView, TextView levView) {
&&&&&&&&currentScore = curView;
&&&&&&&&highestScore = higView;
&&&&&&&&info = infView;
&&&&&&&&currentLevel = levView;
&&&&&* 用来标示某一坐标上的方块
&&&&private class Coordinate {
&&&&&&&&public int x;
&&&&&&&&public int y;
&&&&&&&&public Coordinate(int newX, int newY) {
&&&&&&&&&&&&x = newX;
&&&&&&&&&&&&y = newY;
&&&&&&&&public boolean equals(Coordinate other) {
&&&&&&&&&&&&if (x == other.x && y == other.y) {
&&&&&&&&&&&&&&&&return true;
&&&&&&&&&&&&}
&&&&&&&&&&&&return false;
&&&&&&&&public String toString() {
&&&&&&&&&&&&return "Coordinate: [" + x + "," + y + "]";
&& 4.创建类TileView.java。该类是从贪吃蛇中复制过来的,没做任何修改,可以直接拿来用。可
以在sdk的smples/android 2.x.x/Snake目录中找到。
&& 5.将贪吃蛇游戏res/drawable目录下的三个图片文件复制到自己工程的res/drawable目录中,如果没有这个目录可以创建或者放在其他的drawable-xxx目录中。
&& 6.创建布局文件tetris_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
&&&&xmlns:android="/apk/res/android"
&&&&android:layout_width="match_parent"
&&&&android:layout_height="match_parent">
&&&&<com.test.TetrisView
&&&&&&&&android:id="@+id/tetris"
&&&&&&&&android:layout_width="match_parent"
&&&&&&&&android:layout_height="match_parent"
&&&&&&&&tileSize="24" />
&&&&<RelativeLayout
&&&&&&&&android:layout_width="match_parent"
&&&&&&&&android:layout_height="match_parent">
&&&&&&&&<TextView
&&&&&&&&&&&&android:id="@+id/info"
&&&&&&&&&&&&android:text="@string/mode_ready"
&&&&&&&&&&&&android:visibility="visible"
&&&&&&&&&&&&android:layout_width="wrap_content"
&&&&&&&&&&&&android:layout_height="wrap_content"
&&&&&&&&&&&&android:layout_centerInParent="true"
&&&&&&&&&&&&android:gravity="center_horizontal"
&&&&&&&&&&&&android:textColor="#ff8888ff"
&&&&&&&&&&&&android:textSize="20sp" />
&&&&&&&&<TextView
&&&&&&&&&&&&android:id="@+id/current_score"
&&&&&&&&&&&&android:text="当前分数:\n 0"
&&&&&&&&&&&&android:visibility="visible"
&&&&&&&&&&&&android:layout_width="wrap_content"
&&&&&&&&&&&&android:layout_height="wrap_content"
&&&&&&&&&&&&android:layout_centerVertical="true"
&&&&&&&&&&&&android:layout_alignParentRight="true"
&&&&&&&&&&&&android:textColor="#ff8888ff"
&&&&&&&&&&&&android:textSize="16sp" />
&&&&&&&&<TextView
&&&&&&&&&&&&android:id="@+id/highest_score"
&&&&&&&&&&&&android:text="最高分数:\n 0"
&&&&&&&&&&&&android:visibility="visible"
&&&&&&&&&&&&android:layout_width="wrap_content"
&&&&&&&&&&&&android:layout_height="wrap_content"
&&&&&&&&&&&&android:layout_above="@id/current_score"
&&&&&&&&&&&&android:layout_alignParentRight="true"
&&&&&&&&&&&&android:textColor="#ff8888ff"
&&&&&&&&&&&&android:textSize="16sp" />
&&&&&&&&<TextView
&&&&&&&&&&&&android:id="@+id/current_level"
&&&&&&&&&&&&android:text="当前级别:\n 1"
&&&&&&&&&&&&android:visibility="visible"
&&&&&&&&&&&&android:layout_width="wrap_content"
&&&&&&&&&&&&android:layout_height="wrap_content"
&&&&&&&&&&&&android:layout_below="@id/current_score"
&&&&&&&&&&&&android:layout_alignParentRight="true"
&&&&&&&&&&&&android:textColor="#ff8888ff"
&&&&&&&&&&&&android:textSize="16sp" />
&&&&</RelativeLayout>
</FrameLayout>
&&7.打开res/values/strings.xml,将其修改为以下内容:
<?xml version="1.0" encoding="utf-8"?>
<resources>
&&&&<string
&&&&&&&&name="app_name">Tetris</string>
&&&&<string
&&&&&&&&name="mode_ready">\n按上开始游戏 </string>
&&&&<string
&&&&&&&&name="mode_pause"> 暂停\n按上继续游戏 </string>
&&&&<string
&&&&&&&&name="mode_lose_prefix">Game Over\nScore: </string>
&&&&<string
&&&&&&&&name="mode_lose_suffix">\n按上重新开始游戏 </string>
</resources>
&& &8.打开AndroidManifest.xml,修改其内容如下:
<?xml version="1.0" encoding="utf-8"?>
&&&&xmlns:android="/apk/res/android"
&&&&package="com.test"
&&&&android:versionCode="1"
&&&&android:versionName="1.0">
&&&&<application
&&&&&&&&android:icon="@drawable/icon"
&&&&&&&&android:label="@string/app_name">
&&&&&&&&<activity
&&&&&&&&&&&&android:name=".Tetris"
&&&&&&&&&&&&android:theme="@android:style/Theme.NoTitleBar"
&&&&&&&&&&&&android:screenOrientation="portrait"
&&&&&&&&&&&&android:configChanges="keyboardHidden|orientation">
&&&&&&&&&&&&<intent-filter>
&&&&&&&&&&&&&&&&<action
&&&&&&&&&&&&&&&&&&&&android:name="android.intent.action.MAIN" />
&&&&&&&&&&&&&&&&<category
&&&&&&&&&&&&&&&&&&&&android:name="android.intent.category.LAUNCHER" />
&&&&&&&&&&&&</intent-filter>
&&&&&&&&</activity>
&&&&</application>
</manifest>
&& &至此,一个简单的俄罗斯方块游戏就完成了,游戏运行时的图片为:
& & 项目源码请移步
阅读(10680) | 评论(2) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
:您好,可以分享这整个项目所有资源给我吗?我是个初学者
源码已经附上了 |
您好,可以分享这整个项目所有资源给我吗?我是个初学者
请登录后评论。}

我要回帖

更多关于 贪吃蛇 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信