欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android游戏源码分享之2048

程序员文章站 2022-08-17 18:34:48
引言 程序猿们,是否还在为你的老板辛辛苦苦的打工而拿着微薄的薪水呢,还是不知道如何用自己的应用或游戏来赚钱呢! 在这里iquick将教您如何同过自己的应用来赚取...

引言

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

安装

Android游戏源码分享之2048

Android游戏源码分享之2048

Android游戏源码分享之2048

Android游戏源码分享之2048

项目结构

Android游戏源码分享之2048

重要代码解读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