• 【整理】HTML5游戏开发学习笔记(2)- 弹跳球


    1.预备知识
    (1)在画布上绘制外部图片资源
    (2)梯度(gradient):HTML5中的对象类型,包括线性梯度和径向梯度。如createLinearGradient,绘制梯度需要颜色组
    http://www.w3school.com.cn/tags/canvas_createlineargradient.asp

    function test1(){
    				//在画布上绘制外部图片资源
    				var ctx = document.getElementById('ballCanvas').getContext('2d')
    				var image =new Image()
    				image.src = 'football.jpg'
    
    				ctx.drawImage(image,0,0,360,300)
    			}
    			//test1()
    
    			function test2(){
    				/*
    				梯度(gradient):HTML5中的对象类型,包括线性梯度和径向梯度。如createLinearGradient,
    				绘制梯度需要颜色组
    				http://www.w3school.com.cn/tags/canvas_createlineargradient.asp
    				*/
    				var ctx = document.getElementById('ballCanvas').getContext('2d')
    				var gradient = ctx.createLinearGradient(10,10,200,10)
    				var hue = ['#FFF','#F00','#000']
    
    				gradient.addColorStop(0,hue[0])
    				gradient.addColorStop(0.5,hue[1])
    				gradient.addColorStop(1,hue[2])
    
    				ctx.fillStyle = gradient
    				ctx.fillRect(10,10,200,100)
    			}
    			//test2()
    


    2.实现思路
    整个游戏中涉及的对象,包括运动的球(Ball),墙壁(Box),速度(Speed)。
    同时,球必须在墙壁内部进行运动,碰到墙壁则会反弹。

    当到球和墙壁碰撞的时候,运行方向会发生改变,这个改变对速度的绝对值没有变化,而是改变速度的正负。在实现过程中,我把方向的概念合并到

    了速度对象中,主要是代码实现上的方便。

    3.代码(片段)

    			// Ball
    			function Ball(){
    				var opts,
    						ctx,
    						ballX,
    						ballY
    
    				function drawBall(){
    					var ballOpts = opts.ballOpts
    					ballX = ballOpts.x
    					ballY = ballOpts.y
    
    					ctx.lineWidth = ballOpts.lineWidth
    					ctx.strokeStyle = ballOpts.strokeStyle
    					
    					ctx.beginPath()
    					ctx.arc(ballX,ballY,ballOpts.radius,0,2*Math.PI,false)
    					ctx.closePath()
    					ctx.stroke()
    				}
    
    				return {
    
    					init : function(options){
    						opts = $.extend(options,{
    							canvas : null,
    							ballOpts : {
    								x : 100,
    								y : 100,
    								radius : 50,
    								lineWidth : 1,
    								strokeStyle : '#000'
    							}
    						})
    
    						var canvas =	opts.canvas
    
    						if(canvas==null){
    							alert('canvas is null.')
    							return
    						}
    
    
    						ctx = canvas.getContext('2d')
    						drawBall()
    
    						return this
    					},			
    
    					/*
    						beginMove
    							@return:void
    							@speed:{offsetX:0,offsetY:0}
    							@box:Box instance
    					*/
    					beginMove : function(speed,box){
    						box.refresh()
    
    						var boxSize = box.getSize(),
    								ballOpts = opts.ballOpts,
    								offsetX = speed.offsetX,
    								offsetY = speed.offsetY,
    								directionChanged = false
    								
    						// 判断球ball是在盒子box内边框(上,右,下,左)内
    						var boxInnerBoundry = {	top:boxSize.y+boxSize.lineWidth,
    																		right:boxSize.x+boxSize.lineWidth+boxSize.width,
    																		bottom:boxSize.y+boxSize.lineWidth+boxSize.height,
    																		left:boxSize.x+boxSize.lineWidth }
    
    						var top = (ballY-ballOpts.radius-ballOpts.lineWidth)+offsetY,
    								right = (ballX+ballOpts.radius+ballOpts.lineWidth)+offsetX,
    								bottom = (ballY+ballOpts.radius+ballOpts.lineWidth)+offsetY,
    								left = (ballX-ballOpts.radius-ballOpts.lineWidth)+offsetX
    
    						if(top<boxInnerBoundry.top){
    							ballY += top-boxInnerBoundry.top
    							offsetY = -offsetY
    
    							directionChanged = true
    						}
    
    						if(right>boxInnerBoundry.right){
    							ballX += right-boxInnerBoundry.right
    							offsetX = -offsetX
    
    							directionChanged = true
    						}
    
    						if(bottom>boxInnerBoundry.bottom){
    							ballY += offsetY - (bottom-boxInnerBoundry.bottom)
    							offsetY = -offsetY
    
    							directionChanged = true
    						}						
    
    						if(left<boxInnerBoundry.left){
    							ballX	+= left-boxInnerBoundry.left
    							offsetX = -offsetX
    
    							directionChanged = true
    						}
    
    						ballX += offsetX
    						ballY += offsetY
    
    						/*
    						必须变更当前速度speed,因为在定时器中传入的速度speed是个常量,
    						而实际运动中速度(用加号和减号来表示的方向是会改变的)
    						*/
    						if(directionChanged){
    							speed.changeSpeed(offsetX,offsetY)
    						}
    
    						//alert(ballOpts.x+offsetX+'-'+ballOpts.y+offsetY)
    
    						ctx.beginPath()
    						ctx.arc(ballX,ballY,ballOpts.radius,0,2*Math.PI,false)
    						ctx.closePath()
    						ctx.stroke()
    					}
    
    				}				
    			}
    



    4.优化和完善
    (1)主要还是在球和墙壁的判断上,通过大量的IF判断,实现得比较恶心
    (2)速度实现为了类似的单例方式,不符合重用
    (3)风格可以美化,加入外部图片资源等,比如美化成足球和球场
    (4)引入加速度

  • 相关阅读:
    html+vue.js 实现分页可兼容IE
    Display、Visibility 和 Opacity 的区别
    Vue项目刷新页面 IE/360 浏览器 input输入框不清空问题处理
    Webpack入门
    linux下Tomcat日志文件catalina.out的切割
    无监控,不运维
    windows与linux下jdk+tomcat安裝
    java面向对象(提高篇)
    java面向对象(汇总)
    JAVA工程师简历模板
  • 原文地址:https://www.cnblogs.com/Benoly/p/4028448.html
Copyright © 2020-2023  润新知