亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > 綜合 > 正文

利用kotlin實現一個打方塊的小游戲實例教程

2024-07-21 23:03:43
字體:
來源:轉載
供稿:網友

前言

今天來做個打方塊的小游戲,繼續熟悉kotlin的語法,

看下要實現的效果圖:

打方塊小游戲,kotlin,實現,源代碼

看著效果圖好像挺難的樣子,但理清思緒后,你會發現特別的簡單,還是那句話,學習方法最重要

思路

1、構造界面 :

這個部分比較簡單,根據控件的比例來畫小球、擋板和擊打的方塊,所有擊打的方塊存儲在一個集合里面,方塊里面存儲的信息有left、top、right、bottom位置信息和是否被擊打過了的標志

2、擋板的滑動 :

下面的擋板需要根據手勢的左右移動來反彈小球,所以,我們可以重寫onTouch來實現

3、小球的運動 :

我們在線程里面開啟一個white循環,不停的改變小球的位置,然后重繪界面,小球的運動是有規則的,碰到四周的界面要回彈,碰到擊打的方塊要回彈,碰到擋板也要回彈,那么,如何回彈呢?我們給小球做一個累加值,讓小球不停的去加這個值,碰到碰撞物我們就給這個累加值取反,舉個例子,現在offsetX是一個正整數,那么ballX+=offsetX,現在小球是往右移動,當碰撞到最右邊的時候,我們給offsetX取反,也就是offsetX=offsetX*-1,這時候offsetX變成了一個負數,那么小球ballX+=offset就會越加越少,也就是往左移動,移動到最左邊的時候我們又給offsetX=offsetX*-1,這時候offsetX又變回了正數,這時候,來回的反彈就實現了,ballY的移動也是如此

4、小球擊打方塊 :

小球擊打到方塊有四個方向:左、上、右、下,我們就說說擊打下方的判斷吧,小球頂部碰撞到方塊的區域為方塊的left和right區域,并且當小球的頂部剛好突破方塊的bottom位置時,算是一次有效的碰撞,然后我們給這次碰撞做一個標記,然后反彈小球,下次做碰撞的時候我們忽略已經碰撞過的地方,并且不繪制碰撞過的區域

5、游戲結束 :

在每次循環結束時都去統計集合里碰撞標志數量是否等于集合的size,是的話就結束循環,游戲結束

思路整理清晰后,我們來一一實現

構造界面

首先來繪制一下小球和擋板

 var width: Float = 0f var height: Float = 0f /** * 移動滑塊的寬度 */ var boardWdith: Float = 0f /** * 擋板的高度 */ var boardHeight: Float = 0f /** * 擋板距離頂部的距離 */ var board2Top: Float = 0f /** * 擋板距離左邊的距離 */ var board2Left: Float = 0f /** * 小球的半徑 */ var ballRadius: Float = 0f override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { super.onSizeChanged(w, h, oldw, oldh) width = w.toFloat() height = h.toFloat() //擋板的寬度 boardWdith = width / 8 //擋板距離頂部的距離 board2Top = height / 8 * 7 //擋板的left距離左邊的距離,目的使擋板居中 board2Left = width / 2 - boardWdith / 2 //設置小球的半徑為擋板的1/4 ballRadius = boardWdith / 4 //設置小球的x和y坐標 ballX = width / 2 ballY = board2Top - ballRadius - dip(10).toFloat() / 2  ballPaint.style = Paint.Style.FILL ballPaint.isAntiAlias = true ballPaint.color = resources.getColor(R.color.colorAccent) boardPaint.style = Paint.Style.STROKE boardPaint.isAntiAlias = true boardPaint.strokeWidth = dip(10).toFloat() boardPaint.color = resources.getColor(R.color.colorPrimary) }  override fun onDraw(canvas: Canvas) { super.onDraw(canvas) setBackgroundColor(resources.getColor(R.color.black)) canvas.drawLine(board2Left, board2Top, board2Left + boardWdith, board2Top, boardPaint) canvas.drawCircle(ballX, ballY, ballRadius, ballPaint) } 

ok,擋板和小球已經畫好了

打方塊小游戲,kotlin,實現,源代碼

然后,我們來畫一下被擊打的方塊,首先定義一個存儲方塊信息的Bean類

/** * @author wangqi * @since 2017/12/10 17:26 */public class Brick { /** * 存儲方塊的顏色 */ private String color; /** * 存儲方塊的坐標 */ private RectF rectF; /** * 判斷是否碰撞到了,默認為false未碰撞 */ private boolean isImpact; public String getColor() { return color; } public void setColor(String color) { this.color = color; } public RectF getRectF() { return rectF; } public void setRectF(RectF rectF) { this.rectF = rectF; } public boolean isImpact() { return isImpact; } public void setImpact(boolean impact) { isImpact = impact; }}

然后我們來看看怎么繪制

 /** * 定義一個存儲方塊的集合 */ var brickList: MutableList<Brick> = mutableListOf() /** * 方塊的寬度 */ var brickWidth = 0f /** * 方塊的高度 */ var brickHeight = 0f  override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { super.onSizeChanged(w, h, oldw, oldh) ...   //方塊的寬度是view的1/5  brickWidth = width / 5  //方塊的高度是寬度的一半  brickHeight = brickWidth / 2   /*初始化方塊 設置一個三行四列的方塊*/ for (row in 0..3) {  for (col in 0..4) {  createBricks(row, col)  } }  paintLine.strokeWidth = dip(1.0f).toFloat() paintLine.isAntiAlias = true paintLine.textSize = dip(width / 50).toFloat() paintLine.style = Paint.Style.FILL  }  /** * 創建方塊 */ fun createBricks(row: Int, col: Int) { var brick = Brick() var rectF = RectF() rectF.left = brickWidth * col rectF.top = brickHeight * row rectF.right = brickWidth * (col + 1) rectF.bottom = brickHeight * (row + 1) brick.rectF = rectF val hex = "#" + Integer.toHexString((-16777216 * Math.random()).toInt()) brick.color = hex brickList.add(brick) }

ok,方塊完美的繪制

打方塊小游戲,kotlin,實現,源代碼

擋板的滑動

擋板的滑動部分,我們只需要重寫onTouch方法,然后再每次move的過程中去改變擋板距離View左邊界的距離

 override fun onTouchEvent(event: MotionEvent): Boolean { when (event.action) {  MotionEvent.ACTION_DOWN -> {  }  MotionEvent.ACTION_MOVE -> {  board2Left = event.x - boardWdith / 2  invalidate()  }  MotionEvent.ACTION_UP -> {  } } return true }

打方塊小游戲,kotlin,實現,源代碼

小球的運動

小球的運動是這里面最核心的部分了,我們得細細的講講
首先,我們需要定義一個線程,在線程里面定義一個while循環,sleep50毫秒去重回界面,所以,我們要在這50毫秒的時間里,去改變小球的運動軌跡、邊界值情況、是否碰撞到方塊、是否碰撞到擋板和游戲是否結束,我們先把小球給運動起來再說

 /** * 結束循環的標志位 */ var isOver: Boolean = false /** * 小球x方向每次移動的偏移量 */ var vx: Float = 8f /** * 小球y方向每次移動的偏移量 * 默認為負數,因為小球是向上運動  */ var vy: Float = -8f  override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { super.onSizeChanged(w, h, oldw, oldh) ...  //開啟線程 thread {  while (!isOver) {  ballX += vx  ballY += vy  /*   邊界值判定   如果小球小于左邊界或大于右邊界則x方向取反   */  if (ballX + ballRadius > width || ballX - ballRadius < 0) {   vx *= -1  }  /*   邊界值判定   如果小球大于底部邊界或小于頂部邊界則Y方向取反   */  if (ballY - ballRadius < 0 || ballY + ballRadius > height) {   vy *= -1  }  Thread.sleep(50)  postInvalidate()  } }.start() }

小球開始運動了,咦,小球怎么突然不見了,哈哈,因為被方塊遮擋住了

打方塊小游戲,kotlin,實現,源代碼

小球移動解決了,接下來我們來處理下小球彈到擋板反彈

  //開啟線程  thread {   while (!isOver) {   //邊界值判斷   ...    /*    判斷小球是否落在滑塊上    小球x軸的中心大于擋板的left并且小球x軸中心小于擋板的右邊并且小球的y軸中心加上半徑加上擋板高度的一半     */    if (ballX >= board2Left && ballX <= board2Left + boardWdith      && ballY >= board2Top - ballRadius - dip(10).toFloat() / 2      ) {     //改變Y軸的運動方向      vy *= -1    }   ...      }    }

擋板的判斷知道了,那么小球和方塊的碰撞也就自然清晰了

  //開啟線程  thread {   while (!isOver) {   //判斷小球是否落在滑塊上   ...    /*     * 循環集合的每一個方塊,判斷小球當前的位置是否碰撞到方塊     */    for (i in brickList.indices) {     //拿到方塊     val brick = brickList[i]     //忽略撞擊過的方塊     if (brick.isImpact) {      continue     }     //獲取方塊的坐標     val rectF = brick.rectF     /*      判斷小球是否撞擊到方塊的底部      小球x軸的中心大于方塊的left      小球x軸的中心小于方塊的right      小球y軸中心減去半徑,也就是小球的頂部,是否小于等于方塊的底部,也就是穿過方塊底部的一瞬間      */     if (ballX >= rectF.left && ballX <= rectF.right && ballY - ballRadius <= rectF.bottom) {      //設置該方塊已被撞擊      brick.isImpact = true      //方向取反      vy *= -1     }    }    /*     * 統計被撞擊方塊的數量是否等于集合,是的話表明游戲結束,設置結束標志位,停止while循環     */    if (brickList.count { it.isImpact } == brickList.size) {     isOver = true    }       ...      }    } override fun onDraw(canvas: Canvas) {  super.onDraw(canvas)  ...    if (isOver) {   val text = "通關成功"   //獲取文字的寬度,目的是為了文字居中   val textWidth = paintLine.measureText(text)   canvas.drawText(text, width / 2 - textWidth / 2, 100, paintLine)  }   }

最終效果圖

打方塊小游戲,kotlin,實現,源代碼

通關成功

打方塊小游戲,kotlin,實現,源代碼

總結

小球碰撞到底部邊界的判斷我沒有去做,原因是為了能擊打到方塊,增加趣味性,還有碰撞方塊的四個方向,我只做了碰撞到底部的方向,有興趣的同學可以自己試著補上,查看完整源碼

理論和實踐相輔相成,理論是規劃實踐的實施性,實踐是為了證明理論

好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VeVb武林網的支持。


注:相關教程知識閱讀請移步到kotlin教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲欧美日韩第一区| 亚洲第一综合天堂另类专| 久热精品视频在线| 欧美日韩人人澡狠狠躁视频| 精品国内亚洲在观看18黄| 精品国产自在精品国产浪潮| 欧美在线观看一区二区三区| 欧美激情在线一区| 国产亚洲精品美女| 亚洲欧洲自拍偷拍| 久久精品99久久久香蕉| 在线观看国产精品91| 亚洲综合在线小说| 一区二区三区视频免费在线观看| 91在线无精精品一区二区| 成人免费视频97| 另类少妇人与禽zozz0性伦| 精品高清一区二区三区| 日韩电影中文字幕av| 国产日韩av在线| 亚洲免费伊人电影在线观看av| 中文字幕一区二区精品| 国产精品十八以下禁看| 亚洲国产成人精品女人久久久| 精品调教chinesegay| 国产精品成人aaaaa网站| 日本91av在线播放| 欧美一级视频免费在线观看| 亚洲嫩模很污视频| 成人网址在线观看| 国产精品免费一区| 在线看欧美日韩| 欧美精品在线免费| 欧美日韩亚洲一区二区三区| 久久久久久噜噜噜久久久精品| 黑人极品videos精品欧美裸| 国产精品男女猛烈高潮激情| 国产精品久久久久久久久久| 亚洲国产精品大全| 日韩成人黄色av| 青草青草久热精品视频在线观看| 91免费看片网站| 亚洲电影第1页| 欧美另类极品videosbestfree| 国产一区二区三区在线播放免费观看| 亚洲国模精品私拍| 国产一区二区色| 国产精品91免费在线| 日韩国产激情在线| 国产视频精品va久久久久久| 久久夜色精品国产欧美乱| 亚洲精品电影久久久| 欧美成人h版在线观看| 亚洲一区二区三区久久| 欧美一区二区三区免费视| 国产成人高潮免费观看精品| 九九精品在线视频| 在线成人免费网站| 亚洲国语精品自产拍在线观看| 欧美精品久久久久| 精品国产一区二区三区在线观看| 日韩精品一区二区三区第95| 精品少妇一区二区30p| 精品国产鲁一鲁一区二区张丽| 欧美裸体男粗大视频在线观看| 亚洲伦理中文字幕| 亚洲国产天堂久久国产91| 成人免费在线视频网址| 亚洲欧美日韩中文在线制服| 久久亚洲一区二区三区四区五区高| 隔壁老王国产在线精品| 日韩免费不卡av| 成人国内精品久久久久一区| 久久99国产综合精品女同| 欧美大片网站在线观看| 色综合色综合网色综合| 国产一区二区三区高清在线观看| 欧美中文在线字幕| 欧美一级大片在线观看| 91亚洲精品久久久| 欧美性高潮在线| 欧美性猛交视频| 国产精品视频yy9099| 欧美老女人性视频| 欧美精品999| 欧美高清理论片| 国产欧美精品在线| 国产一区二区香蕉| 国产精品久久久久久久久免费| 性夜试看影院91社区| 亚洲男女自偷自拍图片另类| 日韩视频免费在线| 欧美日本在线视频中文字字幕| 91视频国产高清| 国产精品久久久久久搜索| 中文字幕亚洲欧美日韩2019| 8x拔播拔播x8国产精品| 日韩中文有码在线视频| 精品国产乱码久久久久久婷婷| 亚洲色图15p| 亚洲国产精品福利| 亚洲理论电影网| 久久久av电影| 久久九九免费视频| 亚洲福利小视频| 亚洲国产成人爱av在线播放| 宅男66日本亚洲欧美视频| 亚洲欧美国产一本综合首页| 亚洲成人久久久| 欧美午夜视频在线观看| 欧美久久精品午夜青青大伊人| 国产亚洲精品va在线观看| 亚洲综合社区网| 国产成人鲁鲁免费视频a| 日韩在线视频观看| 亚洲字幕一区二区| 国产成人av在线| 国产精品夫妻激情| 国产精品久久久av| 欧美一乱一性一交一视频| 精品偷拍各种wc美女嘘嘘| 亚洲视频第一页| 成人综合网网址| 69久久夜色精品国产69乱青草| 韩曰欧美视频免费观看| 欧美亚洲午夜视频在线观看| 国产日本欧美一区二区三区在线| 日韩欧美999| 亚洲欧美三级在线| 国产丝袜高跟一区| 精品久久久视频| 国产日韩专区在线| 国产伊人精品在线| 国产成人久久久精品一区| 亚洲人成电影在线播放| 国产视频久久久久久久| 在线观看日韩专区| 欧美在线视频a| 成人有码视频在线播放| 久久福利视频导航| 欧美孕妇毛茸茸xxxx| 青青精品视频播放| 亚洲精品视频在线观看视频| 亚洲free性xxxx护士白浆| 国产九九精品视频| 亚洲一区二区中文字幕| 亚洲男人天堂手机在线| 国产精品福利小视频| 午夜精品视频在线| 久久精品视频导航| 免费不卡欧美自拍视频| 国产精品高潮呻吟久久av黑人| 欧美成人亚洲成人| 91国内免费在线视频| 91精品中国老女人| 欧美精品电影免费在线观看| 国产精品啪视频| 国产亚洲激情在线| 日韩av在线免费| 日韩精品中文字幕在线| 成人国产精品av| 欧洲亚洲在线视频| 国产精品久久久久7777婷婷| 国产精品普通话|