精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Android 原生控件打造經典貪吃蛇游戲實戰指南

移動開發 Android
貪吃蛇是一款經典的游戲,以其簡單易上手、策略性強、挑戰性高等特點深受玩家喜愛。下面我們使用Android原生控件來實現這個小游戲。

游戲說明

貪吃蛇是一款經典的游戲,以其簡單易上手、策略性強、挑戰性高等特點深受玩家喜愛。

游戲玩法:

  • 玩家使用方向鍵操控一條長長的蛇不斷吞下豆子,蛇身隨著吞下的豆子不斷變長
  • 游戲的目標是盡可能長時間地生存下去,同時避免蛇頭撞到自己的身體或屏幕邊緣

游戲特點:

  • 簡單易上手:游戲操作簡單,玩家只需要控制蛇的移動和轉向,吃掉食物即可
  • 策略性:雖然游戲看似簡單,但需要玩家靈活運用策略,在有限的空間內避免碰撞
  • 挑戰性:游戲難度逐漸增加,隨著蛇身的增長,玩家需要更加謹慎地操作

下面我們使用Android原生控件來實現這個小游戲(PS:不包含自定義View的方式)。

實現思路

1.游戲場景

使用GridLayout作為游戲板,大小為20x20,同時包含游戲分數和控制按鈕,下面是布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <TextView
        android:id="@+id/scoreTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="16dp"
        android:text="分數: 0"
        android:textSize="18sp" />

    <GridLayout
        android:id="@+id/gameBoard"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:columnCount="20"
        android:rowCount="20" />

    <RelativeLayout
        android:layout_width="160dp"
        android:layout_height="160dp"
        android:layout_gravity="center">

        <Button
            android:id="@+id/upButton"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_centerHorizontal="true"
            android:text="↑" />

        <Button
            android:id="@+id/leftButton"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_centerVertical="true"
            android:text="←" />

        <Button
            android:id="@+id/rightButton"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_alignParentEnd="true"
            android:layout_centerVertical="true"
            android:text="→" />

        <Button
            android:id="@+id/downButton"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:text="↓" />
    </RelativeLayout>
</LinearLayout>

預覽效果

private fun initializeGame() {
    // 初始化蛇
    snake.add(Pair(boardSize / 2, boardSize / 2))
    // 生成食物
    generateFood()
    // 初始化游戲板
    for (i in 0 until boardSize) {
        for (j in 0 until boardSize) {
            val cell = TextView(this)
            cell.width = 50
            cell.height = 50
            cell.setBackgroundColor(Color.WHITE)
            gameBoard.addView(cell)
        }
    }
    updateBoard()
}

private fun generateFood() {
    do {
        food = Pair(Random.nextInt(boardSize), Random.nextInt(boardSize))
    } while (snake.contains(food))
}
    
private fun updateBoard() {
    for (i in 0 until boardSize) {
        for (j in 0 until boardSize) {
            val cell = gameBoard.getChildAt(i * boardSize + j) as TextView
            when {
                Pair(i, j) == snake.first() -> cell.setBackgroundColor(Color.RED)
                snake.contains(Pair(i, j)) -> cell.setBackgroundColor(Color.GREEN)
                Pair(i, j) == food -> cell.setBackgroundColor(Color.BLUE)
                else -> cell.setBackgroundColor(Color.WHITE)
            }
        }
    }
}

初始化游戲板,大小為20*20,使用TextView作為每個單元格,用于表示可移動的范圍網格。初始化蛇的位置在游戲板中央,蛇被表示為MutableList<Pair<Int, Int>>,每個Pair代表蛇身體的一個部分的坐標。同時隨機在范圍中生成食物,最后更新游戲板給蛇和食物生成不同的顏色樣式。

2.游戲主循環

此時的游戲是不會動的,需要一個游戲主循環讓游戲不斷更新才能使游戲畫面動起來,使用Handler定期調用游戲更新邏輯,每200毫秒更新一次游戲狀態。

private val updateDelay = 200L // 游戲更新間隔,毫秒

private fun startGameLoop() {
    handler.postDelayed(object : Runnable {
        override fun run() {
            moveSnake()
            checkCollision()
            updateBoard()
            handler.postDelayed(this, updateDelay)
        }
    }, updateDelay)
}

每發送一次事件對蛇進行移動,檢查游戲是否結束(蛇是否咬到自己),更新GridLayout網格顯示,發送下一次更新事件

3.蛇的移動

蛇移動的核心邏輯,計算新的蛇頭位置,使用模運算確保蛇能夠穿過游戲邊界,檢查是否吃到食物,如果是,增加分數并生成新食物;否則,移除蛇尾。

private fun moveSnake() {
    val head = snake.first()
    val newHead = Pair(
        (head.first + direction.first + boardSize) % boardSize,
        (head.second + direction.second + boardSize) % boardSize
    )
    snake.add(0, newHead)

    if (newHead == food) {
        score++
        scoreTextView.text = "分數: $score"
        generateFood()
    } else {
        snake.removeAt(snake.size - 1)
    }
}

(1) 獲取蛇頭位置:

val head = snake.first()

蛇被表示為一個坐標對(Pair)的列表,第一個元素是蛇頭。

(2) 計算新的蛇頭位置:

val newHead = Pair(
    (head.first + direction.first + boardSize) % boardSize,
    (head.second + direction.second + boardSize) % boardSize
)

direction(控制的方向)來移動蛇頭,加上 boardSize 并對 boardSize 取模,確保新位置總是在游戲板內

direction = Pair(-1, 0) //上
direction = Pair(1, 0)  //下
direction = Pair(0, -1) //左
direction = Pair(0, 1)  //右

(3) 將新的蛇頭添加到蛇身列表的開頭:

snake.add(0, newHead)

蛇一直是在移動的,蛇頭坐標一直在變化。

(4) 檢查是否吃到食物:

if (newHead == food) {
    score++
    scoreTextView.text = "Score: $score"
    generateFood()
} else {
    snake.removeAt(snake.size - 1)
}

如果新的蛇頭位置與食物位置相同,增加分數,更新分數顯示,并生成新的食物。如果沒有吃到食物,則移除蛇尾,保持蛇的長度不變。

4.碰撞檢測

private fun checkCollision() {
    val head = snake.first()
    if (snake.subList(1, snake.size).contains(head)) {
        // 游戲結束
        handler.removeCallbacksAndMessages(null)
    }
}

檢查蛇頭是否與蛇身相撞,如果是,游戲結束。

5.生成食物

private fun generateFood() {
    do {
        food = Pair(Random.nextInt(boardSize), Random.nextInt(boardSize))
    } while (snake.contains(food))
}

隨機生成新的食物位置,確保不與蛇身重疊

6.顯示更新

private fun updateBoard() {
    for (i in 0 until boardSize) {
        for (j in 0 until boardSize) {
            val cell = gameBoard.getChildAt(i * boardSize + j) as TextView
            when {
                Pair(i, j) == snake.first() -> cell.setBackgroundColor(Color.RED)
                snake.contains(Pair(i, j)) -> cell.setBackgroundColor(Color.GREEN)
                Pair(i, j) == food -> cell.setBackgroundColor(Color.BLUE)
                else -> cell.setBackgroundColor(Color.WHITE)
            }
        }
    }
}

遍歷游戲板的每個單元格,根據其狀態(蛇頭、蛇身、食物或空白)設置不同的顏色。

游戲效果

7.游戲開始結束

此時的蛇可以掉頭和在游戲場景里穿越,下面我們改進一下,蛇撞到游戲邊界游戲結束

private fun moveSnake() {
    val head = snake.first()
    val newHead = Pair(
        head.first + direction.first,
        head.second + direction.second
    )

    // 檢查是否撞到邊界
    if (newHead.first < 0 || newHead.first >= boardSize || 
        newHead.second < 0 || newHead.second >= boardSize) {
        endGame()
        return
    }

    snake.add(0, newHead)

    if (newHead == food) {
        score++
        scoreTextView.text = "分數: $score"
        generateFood()
    } else {
        snake.removeAt(snake.size - 1)
    }
}

添加邊界檢測,檢測到坐標在游戲板邊界,游戲結束

findViewById<Button>(R.id.upButton).setOnClickListener { 
    if (isGameRunning) {
        direction = Pair(-1, 0)
    } else {
        restartGame()
    }
}
findViewById<Button>(R.id.downButton).setOnClickListener { 
    if (isGameRunning) {
        direction = Pair(1, 0)
    } else {
        restartGame()
    }
}
findViewById<Button>(R.id.leftButton).setOnClickListener { 
    if (isGameRunning) {
        direction = Pair(0, -1)
    } else {
        restartGame()
    }
}
findViewById<Button>(R.id.rightButton).setOnClickListener { 
    if (isGameRunning) {
        direction = Pair(0, 1)
    } else {
        restartGame()
    }
}

修改方向按鈕的點擊監聽器,使其能夠重新開始游戲

private fun endGame() {
    isGameRunning = false
    handler.removeCallbacksAndMessages(null)
    scoreTextView.text = "游戲結束!最終分數: $score\n點擊任意方向鍵重新開始"
}

private fun restartGame() {
    snake.clear()
    snake.add(Pair(boardSize / 2, boardSize / 2))
    direction = Pair(0, 1)
    score = 0
    generateFood()
    isGameRunning = true
    startGameLoop()
    updateBoard()
    scoreTextView.text = "分數: 0"
}

游戲結束和重新開始,通過isGameRunning變量控制游戲主循環

private fun startGameLoop() {
    handler.post(object : Runnable {
        override fun run() {
            if (isGameRunning) {
                moveSnake()
                if (isGameRunning) {  // 再次檢查,因為 moveSnake 可能會結束游戲
                    checkCollision()
                    updateBoard()
                    handler.postDelayed(this, updateDelay)
                }
            }
        }
    })
}

完整代碼

游戲效果

Github源碼https://github.com/Reathin/Sample-Android/tree/master/module_snake

責任編輯:趙寧寧 來源: 沐雨花飛蝶
相關推薦

2021-06-15 09:18:51

鴻蒙HarmonyOS應用

2012-06-05 14:42:57

Silverlight

2022-10-28 09:33:10

Linux貪吃蛇

2015-07-31 11:26:24

Swift貪吃蛇

2022-11-07 11:27:00

JS游戲開發

2020-08-20 20:30:49

C語言小游戲貪吃蛇

2021-09-02 15:25:53

鴻蒙HarmonyOS應用

2024-01-18 11:22:41

C++Windows開發

2022-07-25 14:17:04

JS應用開發

2023-10-17 10:20:53

VueReact

2021-04-20 11:40:12

Linux圖形庫curses

2024-12-06 09:20:22

Android游戲新數字

2024-12-09 09:18:21

Android原生控件

2025-02-27 09:31:05

2016-09-19 21:24:08

PythonAsyncio游戲

2016-09-22 21:12:14

2016-09-14 21:17:47

PythonAsyncio游戲

2010-02-05 15:00:44

Android 調用u

2018-08-31 15:48:33

2015-07-07 15:47:57

Razer雷蛇
點贊
收藏

51CTO技術棧公眾號

激情久久一区二区| 国产一区在线免费| www国产亚洲精品久久网站| 中文字幕一区二区三区乱码| 国产麻豆xxxvideo实拍| 免费a级在线播放| 日韩高清成人在线| 一区二区三区精品| 国产美女精品视频| 日韩乱码人妻无码中文字幕久久| 婷婷在线播放| 久久99精品久久久久久久久久久久 | 午夜成人免费电影| 国产精品久久久av| 日本少妇高潮喷水xxxxxxx| 欧美男男tv网站在线播放| 国产激情一区二区三区| 久久精品国产亚洲7777| www.超碰97.com| 二区三区在线| 免费人成黄页网站在线一区二区| 国产一区二区三区毛片| 免费观看成人网| 韩国中文免费在线视频| 亚洲一区二区三区免费在线观看| 亚洲精品美女久久久| 一本久道高清无码视频| 亚洲精品国产精品国| 国产精品videosex极品| 亚洲激情第一页| 国产肥臀一区二区福利视频| 日韩av高清在线| 亚久久调教视频| 亚洲视频在线视频| 亚洲精品久久久中文字幕| 精品麻豆一区二区三区| 国产福利91精品一区二区| 久久在线观看免费| 国产精品欧美久久久| 欧美成人短视频| 国产亚洲高清一区| 亚洲国产欧美在线人成| 精品福利影视| 男人天堂视频在线| 色乱码一区二区三区网站| 91精品国产综合久久久蜜臀粉嫩 | 国产视频第一区| 天堂a中文在线| 亚洲超碰在线观看| 亚洲一区在线观看网站| 国产精品国产三级国产专区53| 日本中文字幕在线免费观看| 国产精品亚洲人成在99www| 欧美日韩一区二区三区视频| 好吊色这里只有精品| 欧美 日韩 综合| 久久久久在线| 欧美极品少妇xxxxⅹ裸体艺术| www.88av| 欧美男男freegayvideosroom| 欧美综合视频在线观看| 五月天激情图片| 欧洲一区av| 久久久久综合网| 91亚洲精品久久久| 91在线视频在线观看| 国产精品久久久久久久久妇女| 精品国产亚洲在线| 9久久婷婷国产综合精品性色| 中日韩高清电影网| 欧美97人人模人人爽人人喊视频| 欧美色图免费看| av免费一区二区| 日本在线一区二区三区| 亚洲精品福利免费在线观看| 久久只有这里有精品| 色喇叭免费久久综合网| 欧美日本高清视频| 国产视频三区四区| 久久影院资源站| 欧美精品在线一区二区三区| 国产精品第12页| av福利导福航大全在线| 综合电影一区二区三区 | 五月激激激综合网色播| 国产亚洲精品成人av久久ww| 国产黄色小视频网站| 亚洲图片久久| 欧美精品一区二区在线播放| 黄色片视频免费观看| 精品视频网站| 日韩理论片久久| 久久精品综合视频| 99精品国产高清一区二区麻豆| 欧美理论片在线| 黄色国产在线视频| 黄色成人免费网| 亚洲va天堂va国产va久| 亚洲欧美另类动漫| 99热这里只有精品首页| 国产一区二区激情| 国产一级片网址| 欧美日韩岛国| 九九久久综合网站| 极品国产91在线网站| 夜久久久久久| 91国产一区在线| 国产五月天婷婷| 美腿丝袜一区二区三区| 国产嫩草一区二区三区在线观看| 成人精品一区二区三区免费| 国产日韩欧美精品一区| 欧美午夜精品久久久久久蜜| 亚洲欧美日本在线观看| 91免费版在线看| 欧美日韩在线观看一区| 在线视频中文字幕第一页| 色综合视频在线观看| www在线观看免费| xxxx另类黑人| 天天色综合天天| 精品国产一二三四区| 这里有精品可以观看| 色婷婷激情久久| 精品久久久久久无码人妻| 视频一区中文字幕精品| 色播久久人人爽人人爽人人片视av| 黑人と日本人の交わりビデオ| 亚洲国产1区| 久久精品国产免费观看| 天码人妻一区二区三区在线看| 午夜在线播放视频欧美| 国内精品**久久毛片app| jizzjizz亚洲| 精品欧美aⅴ在线网站| 国产综合免费视频| 国产在视频一区二区三区吞精| 亚洲精品福利在线观看| 国产小视频在线看| 久久国产一二区| 精选一区二区三区四区五区| 久久一卡二卡| 色婷婷av一区二区| 第四色婷婷基地| 精品视频亚洲| 国产精品久久久久久久久久新婚 | 国产成人精品视频免费看| 91精品啪在线观看国产爱臀| 亚洲国产又黄又爽女人高潮的| 欧美黄色免费看| 久久国产精品毛片| 欧美国产一区二区在线| 免费看av不卡| 欧美日韩国产小视频| 欧美激情第四页| 亚洲电影男人天堂| 国产成人精品免费久久久久 | 国精产品一区一区三区mba桃花| 电影午夜精品一区二区三区| 男人天堂亚洲二区| 亚洲日本护士毛茸茸| 免费成人午夜视频| 香蕉久久夜色精品国产更新时间| 欧美一级大片在线观看| 国产精品日韩无码| 97se亚洲国产综合自在线观| 亚洲永久激情精品| 人人草在线视频| 亚洲美女视频网站| 中文字幕亚洲欧美日韩| 石原莉奈一区二区三区在线观看| 91传媒免费看| av大片在线观看| 欧美日韩视频免费播放| theav精尽人亡av| 日韩av网站在线观看| 国产精品一区而去| 成人性生交大片免费观看网站| 一本色道久久综合狠狠躁篇怎么玩 | 一级国产黄色片| 石原莉奈一区二区三区在线观看| 视频在线观看成人| а√天堂8资源在线| 欧美精品色一区二区三区| 欧美三级日本三级| 韩国成人在线视频| 日韩精品一区二区在线视频 | 国产日本精品| 亚洲午夜久久久影院伊人| a级日韩大片| 国产精品视频午夜| 96av在线| 久久五月天色综合| 一本一道精品欧美中文字幕| 久久久久成人黄色影片| theporn国产精品| 日韩欧美视频在线播放| 国产精品国模大尺度私拍| 日本一区二区三区视频在线| 亚洲天堂免费观看| www.国产麻豆| 亚洲黄一区二区三区| 亚洲精品中文字幕乱码无线| 无码一区二区三区视频| 久久精品日韩精品| 色一区二区三区| 久久久精品一区二区| 久久久久国产精品嫩草影院| 日韩欧美久久一区| 国产九九九视频| 天堂在线视频免费| 成人aa视频在线观看| 欧美日韩一级在线| 成人日韩视频| 欧美亚洲另类视频| 欧美极品少妇videossex| 中文日韩在线视频| 一本一道精品欧美中文字幕| 午夜电影久久久| 强行糟蹋人妻hd中文| 国产精品福利在线播放| 中文字幕在线视频精品| 久久精品一区二区国产| 国产一区二区四区| 亚洲一区色图| 官网99热精品| 激情久久免费视频| 久久久精品999| 高清av在线| 国产一区二区动漫| 国产一级免费在线观看| 亚洲免费电影在线观看| 亚洲欧洲国产综合| 亚洲国产成人久久综合| 天天干天天干天天| 亚洲国产日韩精品| 国产一级大片在线观看| 亚洲精品乱码久久久久久黑人| 精品伦精品一区二区三区视频密桃| 久久久久久**毛片大全| 黄瓜视频污在线观看| 捆绑调教美女网站视频一区| 正在播放久久| 久久国产精品亚洲人一区二区三区| 奇米精品在线| 久久av偷拍| 成人精品一区二区三区电影免费| 国产在线高清理伦片a| 最新的欧美黄色| 在线国产91| 日韩中文字幕网址| 老司机在线永久免费观看| 日韩一区二区三区xxxx| 成人午夜在线影视| 欧美二区乱c黑人| 天堂a中文在线| 亚洲欧美激情精品一区二区| 日本人妖在线| 一区二区欧美亚洲| 免费在线你懂的| 欧美日韩aaaa| 国产夫妻在线| 国产成人精品免费视频| 色综合视频一区二区三区日韩| 欧美激情网友自拍| 欧美aa免费在线| 日本欧美在线视频| 国产精品偷拍| 2020国产精品视频| 色综合天天色| 99国产在线视频| 日韩成人精品一区二区三区| 成人精品福利视频| 高清日韩欧美| 亚洲aⅴ男人的天堂在线观看| 欧美一区久久久| 国产欧美一区二区三区久久人妖| 亚洲精品日产| 国产精品自产拍在线观| 伊人精品综合| 四虎影视永久免费在线观看一区二区三区| 欧美好骚综合网| 午夜精品美女久久久久av福利| 99精品在线观看| 久草热视频在线观看| 另类的小说在线视频另类成人小视频在线| 特级黄色片视频| 久久伊人中文字幕| 曰本女人与公拘交酡| 色一区在线观看| xxxwww在线观看| 中文字幕在线视频日韩| a在线视频v视频| 成人在线中文字幕| 你懂的视频欧美| 欧美高清性xxxxhd| 欧美精品黄色| 爱情岛论坛亚洲首页入口章节| 六月婷婷一区| wwwxxx色| 粉嫩欧美一区二区三区高清影视| 日本中文字幕在线不卡| 久久久国产午夜精品| 久久久国产精品人人片| 在线视频国内自拍亚洲视频| 韩国av在线免费观看| 亚洲精品在线电影| 亚洲成a人v欧美综合天堂麻豆| 中文字幕欧美日韩在线| 国产一二三在线| 91嫩草在线| 97视频热人人精品免费| 人妻无码视频一区二区三区| 成人高清视频免费观看| 中文字幕电影av| 欧美色精品在线视频| 撸视在线观看免费视频| 国产91精品久久久久久| 亚洲视频一起| 99re99热| 黄一区二区三区| 国产在线免费av| 国产人妻精品午夜福利免费| 亚洲91在线| 欧美午夜精品久久久久久蜜| 亚洲精品九九| 最新中文字幕日本| 亚洲欧美乱综合| 精品欧美一区二区久久久久| 国产欧美一区二区三区精品观看| 国产在线拍揄自揄拍无码| 琪琪一区二区三区| 欧美三级视频网站| 91久久精品午夜一区二区| 深夜福利在线看| 55夜色66夜色国产精品视频| 精品国产导航| 日韩精品xxxx| 久久婷婷成人综合色| 亚洲国产精品无码久久久| 亚洲社区在线观看| 精品123区| 在线成人av电影| 久久99国产精品麻豆| 中文字幕求饶的少妇| 一区二区三区不卡视频在线观看| 国产乱人乱偷精品视频a人人澡| 中文字幕精品网| 成人乱码手机视频| 日本天堂免费a| 日韩电影在线一区二区三区| 韩国三级丰满少妇高潮| 亚洲精品成人精品456| 国产丝袜在线视频| 亚洲视频国产视频| 成人免费av电影| 国产精品二区在线| 亚洲黄色大片| 国产全是老熟女太爽了| 欧美羞羞免费网站| 欧美在线 | 亚洲| 4p变态网欧美系列| 精品国产中文字幕第一页| 天天插天天操天天射| 亚洲美女淫视频| 成人无码一区二区三区| 奇米4444一区二区三区| 亚洲精品v亚洲精品v日韩精品| 久久99久久久久久| 久久久久久久久久久电影| 亚洲网站在线免费观看| 欧美日韩成人黄色| 天天躁日日躁成人字幕aⅴ| 成年网站在线播放| 亚洲精品v日韩精品| 五月婷婷六月色| 91精品国产综合久久香蕉| 亚洲视频观看| 国产综合精品在线| 日韩视频在线你懂得| 午夜国产福利在线| 超碰97在线资源| 天堂久久久久va久久久久| 黄色录像免费观看| 欧美色区777第一页| 国产黄a三级三级三级av在线看| 国产一区二区三区av在线| 日本一不卡视频| 国产第一页第二页| 中文字幕亚洲欧美一区二区三区| 亚洲一区二区三区中文字幕在线观看 | 九九热爱视频精品视频| 九色91porny| 欧洲视频一区二区| 538视频在线| 警花观音坐莲激情销魂小说 | avtt天堂在线| 亚洲网站在线看| 欧美国产极品| 能看毛片的网站|