1. 程式人生 > >Android 小遊戲2048 程式碼簡單實現

Android 小遊戲2048 程式碼簡單實現

package com.my2048;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;

/**
2048簡單實現的小遊戲 —> 在佈局裡的引用下就可以了
*/

public class My2048View extends View {

//TODO 先畫出一個整體的檢視出來  --> 整體的一個圖案畫出來
//TODO 建立畫筆,快取一個數組,記錄數字以便下一次計算
//TODO 建立四個方向的計算演算法 上下左右不同的移動的計算(最核心的)  ---> 關聯手勢
//TODO 繪製
//TODO 這裡主要使用了一個二維陣列進行對方格的數字管理,進行一個變化
//TODO 例如:進行一個右移,我對二維陣列的第一個以為陣列進行處理 ---> 即判斷數是否要相加
//這裡沒有做回退上一步的功能,你可以用一個ArrayList儲存 每一步的 陣列arr就可以
Paint strokePaint; //畫線的筆
Paint textPaint;  //畫數字的筆
int width; //記錄螢幕容器給我分配的寬
int height; //記錄螢幕容器分配的高
int gridWidth; //格子的寬高  --->一般為螢幕寬度的四分之一
int[][] arr = new int[4][4]; //對格子的數進行對應
int textSize = 50;  //數字的大小,這裡沒采用sp,最好可以採用sp單位
float textHeight;   //記錄數字大小文字的高度
public My2048View(Context context) {
    this(context, null);
}

public My2048View(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public My2048View(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init(); //初始化一些配置
}

private void init() { //初始化一些配置
    strokePaint = new Paint();
    strokePaint.setAntiAlias(true); //設定是否使用抗鋸齒功能,會消耗較大資源,繪製圖形速度會變慢
    strokePaint.setColor(Color.GRAY); //設定顏色為灰色
    strokePaint.setStrokeCap(Paint.Cap.ROUND);//設定線開始和結束點為圓弧樣式
    strokePaint.setStyle(Paint.Style.STROKE); //設定為線條樣式
    textPaint = new Paint();
    textPaint.setAntiAlias(true); //設定是否使用抗鋸齒功能,會消耗較大資源,繪製圖形速度會變慢
    textPaint.setColor(Color.BLUE); //設定顏色為藍色
    textPaint.setStyle(Paint.Style.STROKE); //設定線條樣式
    textPaint.setTextSize(textSize); //最好可以轉成sp
    textPaint.setFakeBoldText(true);//設定文字為粗體
    textPaint.setTextAlign(Paint.Align.CENTER);//設定為畫文字的x軸為中心點,y軸向下擴充套件 所以後面y軸向下點才可以

    Rect rect=new Rect();
    textPaint.getTextBounds(arr[0][0]+"", 0, 1, rect);
    textHeight = rect.height();//文字的高度
    randomNumber();//隨機位置生成數
}

@Override//佈局
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    super.onLayout(changed, left, top, right, bottom);
}

@Override//測量
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

int startX;
int startY;
int endX;
int endY;

@Override//測量之後呼叫的方法  ----> 一般在這裡得到view的寬高
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    width = w; //螢幕分配給我的width
    height = h; //螢幕分配給我的height
    gridWidth = w / 4;  //設定為寬度的四分之一,可以自己更改
    startX = (width - gridWidth * 4) / 2;  //記錄我開始畫框的座標點 -->X軸
    startY = 0;  //記錄我開始畫框的座標點 -->Y軸
    endX = w - startX; //記錄我結束畫框的座標點 -->X軸
    endY = 4 * gridWidth;  //記錄我結束畫框的座標點 -->Y軸
}

@Override//繪製
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawColor(Color.parseColor("#FFFFFFAA")); //繪製背景
    drawStroke(canvas); //繪製線條,整體的一個框架
    drawText(canvas); //繪製格子中間的數字變化
}
private void drawStroke(Canvas canvas) {
    for (int i = 0; i < 5; i++) {
        canvas.drawLine(startX + i * gridWidth, startY, startX + i * gridWidth, endY, strokePaint);//畫橫線
        canvas.drawLine(startX, startY + i * gridWidth, endX, startY + i * gridWidth, strokePaint);//畫豎線
    }
}
private void drawText(Canvas canvas) { //畫數字
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            if (arr[i][j]!=0)
            canvas.drawText(arr[i][j]+"", startX +gridWidth/2+gridWidth*j, startY +gridWidth/2+gridWidth*i+textHeight/2,textPaint);
        }
    }
}
float downX,downY,moveX,moveY; //   記錄手勢點下/移動的座標
@Override
public boolean onTouchEvent(MotionEvent event) { //這裡的處理不怎麼好 ---> 你可能點動一下就有反應了
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            downX =event.getX();
            downY =event.getY();
            break;
        case MotionEvent.ACTION_MOVE:
            moveX=event.getX();
            moveY =event.getY();
            break;
        case MotionEvent.ACTION_UP:
            float v = Math.abs(downX - moveX) - Math.abs(downY - moveY); //手勢判斷使用者向哪裡移動
            if(v > 0) {
                if(downX > moveX) {
                    left(); //左移
                }else {
                    right();//右移
                }
            }else{
                if(downY > moveY) {
                    up(); //向上移動
                }else {
                    down();//向下移動
                }
            }
            downX=0;downY=0;moveX=0;moveY=0;
            randomNumber(); //隨機位置生數
            break;
    }
    invalidate(); //重繪製
    return true;
}
Random r = new Random();        //生成隨機數的類
int[] value = new int[2];
HashMap<Integer,int[]> hashMap = new HashMap<>();
private void randomNumber() {    //隨機位置生成一個2
    hashMap.clear();
    int count = 0;
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            if (0==arr[i][j]) {
               value=new int[2];//一定要不同的物件,不然會有問題
               value[0]=i;
               value[1]=j;
               hashMap.put(count,value); //記錄可以隨機生成的座標點 的集合
               count++;
            }
        }
    }
    if (hashMap.size() > 0) {   //隨機選一個座標點生成數
        int i = r.nextInt(hashMap.size());//生成的數包頭不包尾
        int[] ints = hashMap.get(i);
        arr[ints[0]][ints[1]]=2;  //生成一個數為2
    } else {    //做了個簡單的提示
        //判斷是不是輸了 --- 可以自己做的更好點 --->可以快取上一步數,看是否可以移動
        Toast.makeText(getContext(),"你要輸了哦",Toast.LENGTH_SHORT).show();
    }

}
ArrayList<Integer> myData = new ArrayList<>(); //快取的集合
Integer filed;
private void down() {       //向下移動實現
    //返回一個裝滿不是0數字的集合
    for (int i = 0; i < 4; i++) {
        myData.clear(); //清除以前的資料
        for (int j = 0; j < 4; j++) { //遍歷豎的格子裡的數
            if (arr[j][i]!=0) { //如果不是0,在這豎的格子裡要進行一個重新賦值
                myData.add(arr[j][i]);
                arr[j][i]=0; //把以前記錄的數給清除,然後後面 進行一個重新賦值
            }
        }
        getFinalNumber2(myData); //對資料是否要相加要處理
        setNumberDown(i, myData); //資料處理之後進行一個重新賦值
    }
}
private void up() {     //向上移動實現
    for (int i = 0; i < 4; i++) {
        myData.clear();
        for (int j = 0; j < 4; j++) {
            if (arr[j][i]!=0) {
                myData.add(arr[j][i]);
                arr[j][i]=0;
            }
        }
        getFinalNumber(myData);
        setNumberUp(i, myData);
    }
}

private void right() {  //向右滑
    for (int i = 0; i < 4; i++) {
        myData.clear();
        for (int j = 0; j < 4; j++) {
            if (arr[i][j]!=0) {
                myData.add(arr[i][j]);
                arr[i][j]=0;
            }
        }
        getFinalNumber2(myData);//
        setNumberRight(i, myData);
    }
}

private void left() {  //向左滑
    for (int i = 0; i < 4; i++) {
        myData.clear();
        for (int j = 0; j < 4; j++) {
            if (arr[i][j]!=0) {
                myData.add(arr[i][j]);
                arr[i][j]=0;
            }
        }
        getFinalNumber(myData);
        setNumberLeft(i,myData);
    }
}
private void setNumberDown(int i, ArrayList<Integer> myData) {
    // 重新賦值
    int size = myData.size();
    for (int j = 0; j < size; j++) {
        arr[4-1-j][i] = myData.get(size-1-j);
    }
}
private void setNumberUp(int i, ArrayList<Integer> myData) {
    // 重新賦值
    int size = myData.size();
    for (int j = 0; j < size; j++) {
        arr[j][i]=myData.get(j);
    }
}
private void setNumberRight(int i, ArrayList<Integer> myData) {
    int size = myData.size(); //重新賦值
    for (int j = 0; j < size; j++) {
        arr[i][4-j-1] = myData.get(size-j-1);
    }
}
private void setNumberLeft(int i, ArrayList<Integer> myData) {
    // 重新賦值
    int size = myData.size();
    for (int j = 0; j < size; j++) {
        arr[i][j] = myData.get(j);
    }
}

private void getFinalNumber(ArrayList<Integer> myData) {
    for (int i = 0; i < myData.size() - 1; i++) {
        filed = myData.get(i);
        if (filed.equals(myData.get(i + 1))) {//是Integer物件不能用==相比較,當integer物件小於128可以用==號相比較,因為小於128是取常量池裡的
            myData.set(i, filed * 2);
            myData.remove(i + 1);
            getFinalNumber(myData);
        }
    }
}
private void getFinalNumber2(ArrayList<Integer> myData) {
    int mySize = myData.size() - 1;//求出集合的size
    for (int i = mySize; i > 0; --i) {
        filed = myData.get(i);
        if (filed.equals(myData.get(i - 1))) {//是Integer物件不能用==相比較,當integer物件小於128可以用==號相比較,因為小於128是取常量池裡的
            myData.set(i - 1, filed * 2);
            myData.remove(i);
            getFinalNumber2(myData);
            break;
        }
    }
}

}
//這是一個自定義的View,你直接在layout檔案中直接引用就可以了,也可修改這個view的程式碼實現自己的要求,這個只是簡單實現功能
啦啦圖

相關推薦

Android 遊戲2048 程式碼簡單實現

package com.my2048; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import andro

2048遊戲主要算法實現

mes 方向 時間限制 上下左右 print ron weight color ges http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=4681 4681: 2

用C++、Qt實現遊戲2048

圖片 explicit AC 向上 類的構造函數 += cli 而後 遊戲 窗口布局與遊戲截圖: 實現思路: 1.使用二維數組模擬整個遊戲網格,並將二維數組中每個數的大小用作遊戲中每個網格中的數據。 2.將對遊戲的數據及數據的操作(即玩家的操

python實現遊戲2048

一、原始碼 import curses from itertools import chain from random import choice class GameField(object): # 初始化資訊 def __init__(self, width=4, h

2048遊戲Python3.6.5實現

這個2048遊戲是我自學python以後寫的, 用了幾天時間。 其中的某些方法可能寫的很笨, 也可能還存在各種BUG, 歡迎各位評論指出。 下面貼出完整程式碼供大家學習交流。 import random #遊戲分數 gameScore = 0 #遊戲矩陣 matrix

android遊戲製作基礎,View實現遊戲佈局和方法

在使用android的朋友們,相信大家對android的遊戲不陌生吧,像憤怒的小鳥,植物大戰殭屍等等優秀的遊戲,給我們帶來了很好的使用者體驗 下面我來教大家一點android遊戲開發的一點基礎,大家可以參照這個方法框架來設計一些像貪吃蛇,俄羅斯方塊,雷電等小遊戲,從而激

遊戲2048最佳演算法怎麼實現?思路全解析!

## **1.簡介** 很多人都玩過2048,我就比較老套,因為我一向看不上這類單機遊戲。但是就在某一天泡腳的無聊時光,拿了媳婦兒的手機,左看看右點點,莫名打開了2048。嗯... 這真是一款打發無聊時光的 "good game"。通過滑動來使得每行或每列相鄰並且相同的數字相加而得到一個最大的數字,最後的數

三子棋遊戲(C語言實現

C語言打造簡單的三子棋小遊戲 簡單三子棋是指棋盤為3*3,玩家與電腦之間對決的遊戲。 話不多說,先上圖:其中‘0’代表電腦落子,‘X’:玩家落子 基本思路: 1.列印地圖(列印一個“#”字狀的棋盤) 2.電腦落子(隨機落子) 3.玩家落子(通過輸入座標的方式) 4判斷遊戲結果 程式碼及註釋

js程式碼 簡單實現數字滾動增加動效(原)

<html><body> <span>look this:</span><span id="nums">10000</span> </body> </heml> <script type="text/

手機遊戲輔助程式的實現

這兩天玩了一個微信的小遊戲,想到以前的跳一跳可以通過模擬按鍵和擷取螢幕的方式做輔助程式,所以想針對這個小遊戲也做個機器人自動玩,雖然結果是失敗的,但是也學到了點東西。 1.做這種小遊戲機器人的關鍵點有兩個,一個是模擬按鍵,一個是擷取螢幕。模擬按鍵很簡單,直接呼叫以下命令即可

c++遊戲——2048

#include <stdio.h> #include <time.h> #include <conio.h> #include <windows.h> void start_game(); void res

用Python編寫飛機遊戲演示程式碼

跟著視訊打的,沒有做完整 plane_main檔案 import pygame from plane_sprites import * class PlaneGame(object): def __init__(self): #遊戲視窗

對於spring中IOC和AOP的理解及程式碼簡單實現

IoC(Inversion of Control): 在傳統的java程式編寫中如果呼叫方法或類者,必須要對被呼叫者進行例項化,即必須要通過new 被呼叫者類,才能對被呼叫者類中的方法、成員進行操作。在開發某一個專案時必然會出現很多類來完善專案的需求,並且類與類

[原始碼和文件分享]基於C++的吃豆人遊戲的設計與實現

一 遊戲介紹 遊戲的目的就是控制遊戲的主角小精靈吃掉藏在迷宮內所有的豆子,並且不能被幽靈抓到,總共有三個關卡。 二 系統設計 2.1 系統總體架構 系統總體架構如下表所示: 玩家 地圖 敵軍 方向控

PHP 剪刀石頭布程式碼簡單實現

1.使用argv接收引數 2.使用剪刀石頭布的下標作為判斷單位 <?php header("Content-Type: text/html; charset=utf-8"); $value

MATLAB神經網路工具箱(程式碼簡單實現

根據網上搜素的關於MATLAB神經網路工具箱的GUI操作,結合書上的程式碼來跑了一遍,發現程式碼是引用了神經網路工具箱來做工作 %% 該程式碼為基於BP神經網路的預測算 %% 清空環境變數 clc clear %% 訓練資料預測資料提取及歸一化 %下載輸

android 圓形進度條的簡單實現

在網上看了些進度條效果,於是就想寫關於這方面部落格,先看下今天要實現一些進度條的效果圖: 當然要實現這些效果是基於你對canvas類繪製一些圖形是瞭解的,否則估計也不好看懂,我儘量講的詳細點, 先從簡單的畫圓開始一步步把這個效果實現出來,這樣幾乎每個人都能看的懂, 畫圓的

Android程式-簡易計算器的實現

目標效果:   通過編寫程式碼,可以實現整數和小數的加減乘除運算,以及刪除和清空的功能。 1.頁面中Button使用的是線性佈局,最外邊一個是父佈局,第一行C,DEL,/,*為第一個子佈局,第二行7,8,9,-為第二個子佈局,第三行4,5,6,+為第三個子佈局,第四五行

Android音樂播放器的簡單實現

1、MusicService 音樂播放器的Service,裡面獲取音樂檔案,封裝了MediaPlayer,實現播放上一首和下一首,播放,停止,封裝成方法供Activity呼叫,獲取音樂的當前進度,總長度、名字,通過傳送廣播的方式發給Activity pa

unity3d完成VR手柄第一人稱射擊遊戲(純程式碼)

using UnityEngine; using UnityEngine.AI; /// <summary> /// 敵人向玩家移動 並自動尋路 路途中播放自帶動畫 完成 攻擊兩次 敵人死亡 /// 以下程式碼負責動畫播放 /// </sum