当前位置: 移动技术网 > 移动技术>移动开发>Android > Android游戏源码分享之2048

Android游戏源码分享之2048

2019年07月24日  | 移动技术网移动技术  | 我要评论

引言

  程序猿们,是否还在为你的老板辛辛苦苦的打工而拿着微薄的薪水呢,还是不知道如何用自己的应用或游戏来赚钱呢!  
在这里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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网