返回顶部
首页 > 资讯 > 移动开发 >Android游戏源码分享之2048
  • 798
分享到

Android游戏源码分享之2048

源码分享源码Android 2022-06-06 10:06:36 798人浏览 安东尼
摘要

引言 程序猿们,是否还在为你的老板辛辛苦苦的打工而拿着微薄的薪水呢,还是不知道如何用自己的应用或游戏来赚钱呢! 在这里IQuick将教您如何同过自己的应用来赚取自己的第

引言

  程序猿们,是否还在为你的老板辛辛苦苦的打工而拿着微薄的薪水呢,还是不知道如何用自己的应用或游戏来赚钱呢!  
在这里IQuick将教您如何同过自己的应用来赚取自己的第一桶金!  
你是说自己的应用还没有做出来?  
不,在這里已经为你提供好了一个完整的游戏应用了,在文章的下面有源码的地址哦。你只要稍做修改就可以变成一个完全属于自己的应用了,比如将4*4换成5*5,甚至是其它的。如果你实在是慵懒至极的话,你只要将本应用的包名及广告换成自己的,就可以上传到市场上轻轻松松赚取自己的第一桶金了。  
如果你觉得本文很赞的话,就顶一下作者吧,从下面的安装地址中下载应用,或者在导入本工程运行的时候,从广告中安装一个应用。动一动你的手指,就能让作者更进一步,也能让作者以后更加有动力来分享吧。

安装



项目结构

重要代码解读MainView游戏的主体类


//初始化方法,里面初始化了一些常量,字体颜色等 
name="code" class="java">public MainView(Context context) {
    super(context);
    Resources resources = context.getResources();
    //Loading resources
    game = new MainGame(context, this);
    try {
      //Getting assets
      backgroundRectangle = resources.getDrawable(R.drawable.background_rectangle);
      lightUpRectangle = resources.getDrawable(R.drawable.light_up_rectangle);
      fadeRectangle = resources.getDrawable(R.drawable.fade_rectangle);
      TEXT_WHITE = resources.getColor(R.color.text_white);
      TEXT_BLACK = resources.getColor(R.color.text_black);
      TEXT_BROWN = resources.getColor(R.color.text_brown);
      this.setBackgroundColor(resources.getColor(R.color.background));
      Typeface font = Typeface.createFromAsset(resources.getAssets(), "ClearSans-Bold.ttf");
      paint.setTypeface(font);
      paint.setAntiAlias(true);
    } catch (Exception e) {
      System.out.println("Error getting assets?");
    }
    setOnTouchListener(new InputListener(this));
    game.newGame();
  }
  //游戏界面的绘制
  @Override
  protected void onSizeChanged(int width, int height, int oldw, int oldh) {
    super.onSizeChanged(width, height, oldw, oldh);
    getLayout(width, height);
    createBitmapCells();
    createBackgroundBitmap(width, height);
    createOverlays();
  }


MianGame游戏主要逻辑


package com.tpcstld.twozerogame;
import Android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MainGame {
  public static final int SPAWN_ANIMATION = -1;
  public static final int MOVE_ANIMATION = 0;
  public static final int MERGE_ANIMATION = 1;
  public static final int FADE_GLOBAL_ANIMATION = 0;
  public static final long MOVE_ANIMATION_TIME = MainView.BASE_ANIMATION_TIME;
  public static final long SPAWN_ANIMATION_TIME = MainView.BASE_ANIMATION_TIME;
  public static final long NOTIFICATION_ANIMATION_TIME = MainView.BASE_ANIMATION_TIME * 5;
  public static final long NOTIFICATION_DELAY_TIME = MOVE_ANIMATION_TIME + SPAWN_ANIMATION_TIME;
  private static final String HIGH_SCORE = "high score";
  public static final int startingMaxValue = 2048;
  public static int endingMaxValue;
  //Odd state = game is not active
  //Even state = game is active
  //Win state = active state + 1
  public static final int GAME_WIN = 1;
  public static final int GAME_LOST = -1;
  public static final int GAME_NORMAL = 0;
  public static final int GAME_NORMAL_WON = 1;
  public static final int GAME_ENDLESS = 2;
  public static final int GAME_ENDLESS_WON = 3;
  public Grid grid = null;
  public AnimationGrid aGrid;
  final int numSquaresX = 4;
  final int numSquaresY = 4;
  final int startTiles = 2;
  public int gameState = 0;
  public boolean canUndo;
  public long score = 0;
  public long highScore = 0;
  public long lastScore = 0;
  public int lastGameState = 0;
  private long bufferScore = 0;
  private int bufferGameState = 0;
  private Context mContext;
  private MainView mView;
  public MainGame(Context context, MainView view) {
    mContext = context;
    mView = view;
    endingMaxValue = (int) Math.pow(2, view.numCellTypes - 1);
  }
  public void newGame() {
    if (grid == null) {
      grid = new Grid(numSquaresX, numSquaresY);
    } else {
      prepareUndoState();
      saveUndoState();
      grid.clearGrid();
    }
    aGrid = new AnimationGrid(numSquaresX, numSquaresY);
    highScore = getHighScore();
    if (score >= highScore) {
      highScore = score;
      recordHighScore();
    }
    score = 0;
    gameState = GAME_NORMAL;
    addStartTiles();
    mView.refreshLastTime = true;
    mView.resyncTime();
    mView.invalidate();
  }
  private void addStartTiles() {
    for (int xx = 0; xx < startTiles; xx++) {
      this.addRandomTile();
    }
  }
  private void addRandomTile() {
    if (grid.isCellsAvailable()) {
      int value = Math.random() < 0.9 ? 2 : 4;
      Tile tile = new Tile(grid.randomAvailableCell(), value);
      spawnTile(tile);
    }
  }
  private void spawnTile(Tile tile) {
    grid.insertTile(tile);
    aGrid.startAnimation(tile.getX(), tile.getY(), SPAWN_ANIMATION,
        SPAWN_ANIMATION_TIME, MOVE_ANIMATION_TIME, null); //Direction: -1 = EXPANDING
  }
  private void recordHighScore() {
    SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(mContext);
    SharedPreferences.Editor editor = settings.edit();
    editor.putLong(HIGH_SCORE, highScore);
    editor.commit();
  }
  private long getHighScore() {
    SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(mContext);
    return settings.getLong(HIGH_SCORE, -1);
  }
  private void prepareTiles() {
    for (Tile[] array : grid.field) {
      for (Tile tile : array) {
        if (grid.isCellOccupied(tile)) {
          tile.setMergedFrom(null);
        }
      }
    }
  }
  private void moveTile(Tile tile, Cell cell) {
    grid.field[tile.getX()][tile.getY()] = null;
    grid.field[cell.getX()][cell.getY()] = tile;
    tile.updatePosition(cell);
  }
  private void saveUndoState() {
    grid.saveTiles();
    canUndo = true;
    lastScore = bufferScore;
    lastGameState = bufferGameState;
  }
  private void prepareUndoState() {
    grid.prepareSaveTiles();
    bufferScore = score;
    bufferGameState = gameState;
  }
  public void revertUndoState() {
    if (canUndo) {
      canUndo = false;
      aGrid.cancelAnimations();
      grid.revertTiles();
      score = lastScore;
      gameState = lastGameState;
      mView.refreshLastTime = true;
      mView.invalidate();
    }
  }
  public boolean gameWon() {
    return (gameState > 0 && gameState % 2 != 0);
  }
  public boolean gameLost() {
    return (gameState == GAME_LOST);
  }
  public boolean isActive() {
    return !(gameWon() || gameLost());
  }
  public void move(int direction) {
    aGrid.cancelAnimations();
    // 0: up, 1: right, 2: down, 3: left
    if (!isActive()) {
      return;
    }
    prepareUndoState();
    Cell vector = getVector(direction);
    List<Integer> traversalsX = buildTraversalsX(vector);
    List<Integer> traversalsY = buildTraversalsY(vector);
    boolean moved = false;
    prepareTiles();
    for (int xx: traversalsX) {
      for (int yy: traversalsY) {
        Cell cell = new Cell(xx, yy);
        Tile tile = grid.getCellContent(cell);
        if (tile != null) {
          Cell[] positions = findFarthestPosition(cell, vector);
          Tile next = grid.getCellContent(positions[1]);
          if (next != null && next.getValue() == tile.getValue() && next.getMergedFrom() == null) {
            Tile merged = new Tile(positions[1], tile.getValue() * 2);
            Tile[] temp = {tile, next};
            merged.setMergedFrom(temp);
            grid.insertTile(merged);
            grid.removeTile(tile);
            // Converge the two tiles' positions
            tile.updatePosition(positions[1]);
            int[] extras = {xx, yy};
            aGrid.startAnimation(merged.getX(), merged.getY(), MOVE_ANIMATION,
                MOVE_ANIMATION_TIME, 0, extras); //Direction: 0 = MOVING MERGED
            aGrid.startAnimation(merged.getX(), merged.getY(), MERGE_ANIMATION,
                SPAWN_ANIMATION_TIME, MOVE_ANIMATION_TIME, null);
            // Update the score
            score = score + merged.getValue();
            highScore = Math.max(score, highScore);
            // The mighty 2048 tile
            if (merged.getValue() >= winValue() && !gameWon()) {
              gameState = gameState + GAME_WIN; // Set win state
              endGame();
            }
          } else {
            moveTile(tile, positions[0]);
            int[] extras = {xx, yy, 0};
            aGrid.startAnimation(positions[0].getX(), positions[0].getY(), MOVE_ANIMATION, MOVE_ANIMATION_TIME, 0, extras); //Direction: 1 = MOVING NO MERGE
          }
          if (!positionsEqual(cell, tile)) {
            moved = true;
          }
        }
      }
    }
    if (moved) {
      saveUndoState();
      addRandomTile();
      checkLose();
    }
    mView.resyncTime();
    mView.invalidate();
  }
  private void checkLose() {
    if (!movesAvailable() && !gameWon()) {
      gameState = GAME_LOST;
      endGame();
    }
  }
  private void endGame() {
    aGrid.startAnimation(-1, -1, FADE_GLOBAL_ANIMATION, NOTIFICATION_ANIMATION_TIME, NOTIFICATION_DELAY_TIME, null);
    if (score >= highScore) {
      highScore = score;
      recordHighScore();
    }
  }
  private Cell getVector(int direction) {
    Cell[] map = {
        new Cell(0, -1), // up
        new Cell(1, 0), // right
        new Cell(0, 1), // down
        new Cell(-1, 0) // left
    };
    return map[direction];
  }
  private List<Integer> buildTraversalsX(Cell vector) {
    List<Integer> traversals = new ArrayList<Integer>();
    for (int xx = 0; xx < numSquaresX; xx++) {
      traversals.add(xx);
    }
    if (vector.getX() == 1) {
      Collections.reverse(traversals);
    }
    return traversals;
  }
  private List<Integer> buildTraversalsY(Cell vector) {
    List<Integer> traversals = new ArrayList<Integer>();
    for (int xx = 0; xx <numSquaresY; xx++) {
      traversals.add(xx);
    }
    if (vector.getY() == 1) {
      Collections.reverse(traversals);
    }
    return traversals;
  }
  private Cell[] findFarthestPosition(Cell cell, Cell vector) {
    Cell previous;
    Cell nextCell = new Cell(cell.getX(), cell.getY());
    do {
      previous = nextCell;
      nextCell = new Cell(previous.getX() + vector.getX(),
          previous.getY() + vector.getY());
    } while (grid.isCellWithinBounds(nextCell) && grid.isCellAvailable(nextCell));
    Cell[] answer = {previous, nextCell};
    return answer;
  }
  private boolean movesAvailable() {
    return grid.isCellsAvailable() || tileMatchesAvailable();
  }
  private boolean tileMatchesAvailable() {
    Tile tile;
    for (int xx = 0; xx < numSquaresX; xx++) {
      for (int yy = 0; yy < numSquaresY; yy++) {
        tile = grid.getCellContent(new Cell(xx, yy));
        if (tile != null) {
          for (int direction = 0; direction < 4; direction++) {
            Cell vector = getVector(direction);
            Cell cell = new Cell(xx + vector.getX(), yy + vector.getY());
            Tile other = grid.getCellContent(cell);
            if (other != null && other.getValue() == tile.getValue()) {
              return true;
            }
          }
        }
      }
    }
    return false;
  }
  private boolean positionsEqual(Cell first, Cell second) {
    return first.getX() == second.getX() && first.getY() == second.getY();
  }
  private int winValue() {
    if (!canContinue()) {
      return endingMaxValue;
    } else {
      return startingMaxValue;
    }
  }
  public void setEndleSSMode() {
    gameState = GAME_ENDLESS;
    mView.invalidate();
    mView.refreshLastTime = true;
  }
  public boolean canContinue() {
    return !(gameState == GAME_ENDLESS || gameState == GAME_ENDLESS_WON);
  }
}

如何加载广告

项目结构上提到的对应平台的广告Lib加入到项目中在AndroidManifest.xml中加入权限及必要组件


<!--需要添加的权限 -->
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.READ_PHONE_STATE" /><!-- ismi -->
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.GET_TASKS" /><!-- TimeTask -->
  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /><!-- WindowManager -->
  <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
  <supports-screens android:anyDensity="true" />



<!-- 酷果广告组件 -->
  <activity android:name="com.phkg.b.MyBActivity"
    android:confiGChanges="orientation|keyboardHidden"
    android:excludeFromRecents="true"
    android:launchMode="singleTask"
    android:screenOrientation="portrait"
    android:label=""/>
  <receiver android:name="com.phkg.b.MyBReceive">
    <intent-filter>
      <action android:name="android.intent.action.PACKAGE_ADDED" />
      <data android:scheme="package" />
    </intent-filter>
    <intent-filter>
      <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
    </intent-filter>
  </receiver>
  <!-- 有米广告组件 -->
  <activity android:name="net.youmi.android.AdBrowser" 
    android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
    android:theme="@android:style/Theme.Light.NoTitleBar" >
  </activity>
  <service 
    android:name="net.youmi.android.AdService" 
    android:exported="false" >
  </service>
  <receiver android:name="net.youmi.android.AdReceiver" >
    <intent-filter>
      <action android:name="android.intent.action.PACKAGE_ADDED" />
      <data android:scheme="package" />
    </intent-filter>
  </receiver>

在MainView中加入广告加载代码


  //有米广告
  private void loadYMAds() {
    // 实例化 LayoutParams(重要)
    FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams( 
      FrameLayout.LayoutParams.FILL_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
    // 设置广告条的悬浮位置
    layoutParams.gravity = Gravity.BOTTOM | Gravity.RIGHT; // 这里示例为右下角
    // 实例化广告条
    AdView adView = new AdView(this, AdSize.FIT_SCREEN);
    adView.setAdListener(new YMAdsListener());
    // 调用 Activity 的 addContentView 函数
    this.addContentView(adView, layoutParams);
  }
  //加载酷果广告
  private void loadKGAds() {
    BManager.showTopBanner(MainActivity.this, BManager.CENTER_BOTTOM, 
      BManager.MODE_APPIN, Const.COOID, Const.QQ_CHID);
    BManager.setBMListner(new ADSListener());
  }

别忘了将Const中的Appkey换成自己在广告申请的Appkey

广告平台推荐

有米(如果想加入有米广告,力荐从此链接注册,有惊喜等着你哦)https://www.youmi.net/account/reGISter?r=NDg0ODA=酷果Http://www.kuguopush.com/

导入

如果是Android Studio的话可以直接导入。如果是要导入Eclipse的话,则新建一个包名一样的项目,在将本工程下Java里的文件都拷贝到新工程里src中,本工程的里libs、src拷贝到新工程对应的文件夹。并将本工程里的AndroidManifest.xml文件覆盖新项目AndroidManifest.xml文件。至此你就可以迁移完毕,你可以运行游戏了。

注意

将本项目转换成自己的第一桶金项目时要注意1、换掉包名2、将Const类里的应用Appkey换成自己在对应广告平台申请的应用Appkey


源码地址https://github.com/iQuick/2048

您可能感兴趣的文章:Android仿开心消消乐大树星星无限循环效果Unity3D游戏引擎实现在Android中打开WEBView的实例Android游戏开发实践之人物移动地图的平滑滚动处理Android 游戏开发canvas画布的介绍及方法Android开发之经典游戏贪吃蛇Android游戏开发之碰撞检测(矩形碰撞、圆形碰撞、像素碰撞)Android五子棋游戏程序完整实例分析以一个着色游戏展开讲解Android中区域图像填色的方法Android高仿2048小游戏实现代码Android开心消消乐代码实例详解


--结束END--

本文标题: Android游戏源码分享之2048

本文链接: https://lsjlt.com/news/26899.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Android游戏源码分享之2048
    引言 程序猿们,是否还在为你的老板辛辛苦苦的打工而拿着微薄的薪水呢,还是不知道如何用自己的应用或游戏来赚钱呢! 在这里IQuick将教您如何同过自己的应用来赚取自己的第...
    99+
    2022-06-06
    源码分享 源码 Android
  • JS原生2048小游戏源码分享(全网最新)
    最近在学习算法方面的知识,看到了一个由算法主导的小游戏,这里给大家分享下代码: 效果: 代码: <head> <meta charset="UTF-8...
    99+
    2024-04-02
  • 2048小游戏成品源码
    2048小游戏,可以自选背景颜色,方框颜色,音乐播放。 还可以展示当前玩家的排名,动态排名,及历史玩家的排名。 前期需求: 使用pygame加载目录音乐。MP3文件: def music_play...
    99+
    2023-08-30
    pygame python 开发语言
  • Android编写2048小游戏
    先来说说2048游戏规则: 开始时棋盘内随机出现两个数字,出现的数字仅可能为2或4 玩家可以选择上下左右四个方向,若棋盘内的数字出现位移或合并,视为有效移动 玩家选择的方向上若...
    99+
    2022-06-06
    小游戏 Android
  • 14 个Python小游戏 源码分享
    目录1、吃金币2、打乒乓3、滑雪4、并夕夕版飞机大战5、打地鼠6、小恐龙7、消消乐8、俄罗斯方块9、贪吃蛇10、24点小游戏11、平衡木12、外星人入侵13、贪心鸟14、井字棋888...
    99+
    2024-04-02
  • Android高仿2048小游戏实现代码
    刚开始进入Splash界面: 1.SplashActivity.Java(两秒后进入开始界面,Splash界面的布局只有一个图片,在博客后,会展示给大家看) public c...
    99+
    2022-06-06
    小游戏 Android
  • Unity游戏开发之2048游戏的实现
    目录一、前言二、游戏开发知识储备2-1技术栈三、休闲类游戏《2048》开发实战3-1玩法概述3-2实现分析3-3搭建场景3-4实现代码一、前言 写今天这篇文章的缘由,其实是来自于前段...
    99+
    2024-04-02
  • 二十种Python代码游戏源代码分享
    学Python中,自我感觉学的还不错的亚子~想做点什么来练练手,然后我疯狂的找各种小游戏的教程源码什么的,于是我就疯狂的找呀找呀,就找到了一大堆,哈哈哈 毕竟我是从小就有一个游戏梦,...
    99+
    2024-04-02
  • Android实现消水果游戏代码分享
    消水果游戏大家都玩过吧,今天小编给大家分享实现消水果游戏的代码,废话不多说了,具体代码如下所示: #include "InGameScene.h" #include "Pa...
    99+
    2022-06-06
    水果 Android
  • linux实现的猜数字小游戏源码分享
    本篇内容主要讲解“linux实现的猜数字小游戏源码分享”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“linux实现的猜数字小游戏源码分享”吧!一个简单的linux猜数字小游戏源码游戏规则:猜数字...
    99+
    2023-06-05
  • Java实现经典游戏2048的示例代码
    目录前言主要设计功能截图代码实现界面布局类业务逻辑类总结前言 2014年Gabriele Cirulli利用周末的时间写2048这个游戏的程序,仅仅只是好玩而已。他想用一种不同的视觉...
    99+
    2024-04-02
  • android微信支付源码分享
    本文为大家分享了android微信支付源码,供大家参考,具体内容如下 参数配置 public static final String APP_ID ; public sta...
    99+
    2022-06-06
    源码分享 源码 Android
  • c++实现扫雷小游戏代码分享
    分成两个源文件和一个头文件 注意:这串代码并不完整,不能够实现当所查坐标周围雷的数量为0时,直接展开周围坐标; 头文件:game.h #include <stdio.h>...
    99+
    2024-04-02
  • Java实现扫雷游戏的代码分享
    目录效果展示主类:GameWin类底层地图MapBottom类顶层地图MapTop类底层数字BottomNum类初始化地雷BottomRay类工具GameUtil类总结效果展示 主...
    99+
    2024-04-02
  • Android Volley框架使用源码分享
    过去在Android上网络通信都是使用的Xutils 因为用它可以顺道处理了图片和网络这两个方面,后来发觉Xutils里面使用的是HttpClient  而Googl...
    99+
    2022-06-06
    volley框架 volley 源码分享 源码 Android
  • 基于Unity实现3D版2048游戏的示例代码
    分享三个无聊的时候用Unity写的小游戏 包含 2048 2D版本和3D版本 Voodoo的小游戏 Sticky block 开源仓库: https://gitee.com/wel...
    99+
    2023-02-02
    Unity实现2048游戏 Unity 2048游戏 Unity 2048 Unity 游戏
  • c/c++小游戏源代码
    翻到开学之初写的一些小游戏,陆续给大家发出来,也便提高新手们的编程兴趣。(已详细注释) 几个对应头文件需要注意一下,但不必太过恐慌,因为,,,很多,用的时候找需要的即可 (在Dev,...
    99+
    2024-04-02
  • Python:游戏:扫雷(附源码)
    这次我们基于 pygame 来做一个扫雷,上次有园友问我代码的 python 版本,我说明一下,我所有的代码都是基于 python 3.6 的。 先看截图,仿照 XP 上的扫雷做的,感觉 XP 上的样式比 win7 上的好看多了。 原谅...
    99+
    2023-01-30
    源码 游戏 Python
  • Java实战之贪吃蛇小游戏(源码+注释)
    目录一、工程文件二、Main.java三、Mpanel.java四、效果一、工程文件 二、Main.java package com.company; import java...
    99+
    2024-04-02
  • Android 之游戏开发流程
    游戏开发流程在不同的项目中会有一些差异,但是一般来说,Android 游戏开发流程可以大致分为以下几个步骤:1. 设计阶段:在这个阶...
    99+
    2023-09-28
    Android
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作