利用kotlin实现一个打方块的小游戏实例教程

利用kotlin实现一个打方块的小游戏实例教程,第1张

概述前言今天来做个打方块小游戏,继续熟悉kotlin的语法,更多关于kotlin的语法大家可以参考这篇文章:https://www.oudahe.com/p/25381/

前言

今天来做个打方块的小游戏,继续熟悉kotlin的语法,更多关于kotlin的语法大家可以参考这篇文章:https://www.oudahe.com/p/25381/

看下要实现的效果图:

看着效果图好像挺难的样子,但理清思绪后,你会发现特别的简单,还是那句话,学习方法最重要

思路

1、构造界面 :

这个部分比较简单,根据控件的比例来画小球、挡板和击打的方块,所有击打的方块存储在一个集合里面,方块里面存储的信息有left、top、right、bottom位置信息和是否被击打过了的标志

2、挡板的滑动 :

下面的挡板需要根据手势的左右移动来反d小球,所以,我们可以重写ontouch来实现

3、小球的运动 :

我们在线程里面开启一个white循环,不停的改变小球的位置,然后重绘界面,小球的运动是有规则的,碰到四周的界面要回d,碰到击打的方块要回d,碰到挡板也要回d,那么,如何回d呢?我们给小球做一个累加值,让小球不停的去加这个值,碰到碰撞物我们就给这个累加值取反,举个例子,现在offsetX是一个正整数,那么ballX+=offsetX,现在小球是往右移动,当碰撞到最右边的时候,我们给offsetX取反,也就是offsetX=offsetX*-1,这时候offsetX变成了一个负数,那么小球ballX+=offset就会越加越少,也就是往左移动,移动到最左边的时候我们又给offsetX=offsetX*-1,这时候offsetX又变回了正数,这时候,来回的反d就实现了,ballY的移动也是如此

4、小球击打方块 :

小球击打到方块有四个方向:左、上、右、下,我们就说说击打下方的判断吧,小球顶部碰撞到方块的区域为方块的left和right区域,并且当小球的顶部刚好突破方块的bottom位置时,算是一次有效的碰撞,然后我们给这次碰撞做一个标记,然后反d小球,下次做碰撞的时候我们忽略已经碰撞过的地方,并且不绘制碰撞过的区域

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,boardPaint) canvas.drawCircle(ballX,ballY,ballRadius,ballPaint) } 

ok,挡板和小球已经画好了

然后,我们来画一下被击打的方块,首先定义一个存储方块信息的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,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,方块完美的绘制


挡板的滑动

挡板的滑动部分,我们只需要重写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 }

小球的运动

小球的运动是这里面最核心的部分了,我们得细细的讲讲
首先,我们需要定义一个线程,在线程里面定义一个while循环,sleep50毫秒去重回界面,所以,我们要在这50毫秒的时间里,去改变小球的运动轨迹、边界值情况、是否碰撞到方块、是否碰撞到挡板和游戏是否结束,我们先把小球给运动起来再说

 /** * 结束循环的标志位 */ var isOver: Boolean = false /** * 小球x方向每次移动的偏移量 */ var vx: float = 8f /** * 小球y方向每次移动的偏移量 * 默认为负数,因为小球是向上运动  */ var vy: float = -8f  overrIDe fun onSizeChanged(w: Int,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() }

小球开始运动了,咦,小球怎么突然不见了,哈哈,因为被方块遮挡住了

小球移动解决了,接下来我们来处理下小球d到挡板反d

  //开启线程  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实现一个打方块的小游戏实例教程所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1143245.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存