精华 Phaser摇杆
发布于 2 年前 作者 xiaomingcscs 1000 次浏览 来自 分享

想要一个农药的摇杆很简单,主要就是计算一下摇杆的坐标和中心点的角度,然后再设置任务移动的方向。 摇杆素材请加群:519413640,在群文件搜索:摇杆素材 1.gif

新建主角和摇杆组,里面有摇杆背景和摇杆按钮

		//主角
		this.play = this.add.sprite(100,this.world.height - 110,"mario");
		//镜头跟随主角
		this.camera.follow(this.play);
		//设置主角动画
		this.play.animations.add('go',Phaser.Animation.generateFrameNames('mario', 1, 2, '.png', 0),10,true);
		this.play.animations.add('up',Phaser.Animation.generateFrameNames('mario', 3, 3, '.png', 0),10,true);
		//主角开启物理引擎
		this.physics.arcade.enable(this.play);
		//主角不能超出World范围
		this.play.body.collideWorldBounds = true;
		//摇杆组
		this.disBtn = this.add.group();
		//摇杆背景
		this.disBtn.bg = this.disBtn.create(0, 0,"button","1.png");
		//设置摇杆范围的半径
		this.disBtn.bg.radius = this.disBtn.bg.width / 2;
		//设置摇杆中心点坐标
		this.disBtn.bg.centerPoint = {
			x: this.disBtn.bg.x + this.disBtn.bg.radius,
			y: this.disBtn.bg.y + this.disBtn.bg.radius
		};
		//摇杆按钮
		this.disBtn.btn = this.disBtn.create(this.disBtn.bg.centerPoint.x, this.disBtn.bg.centerPoint.y,"button","2.png");
		this.disBtn.btn.anchor.set(0.5);
		//开启摇杆按钮点击事件
		this.disBtn.btn.inputEnabled = true;
		//开启摇杆按钮拖动功能
    	this.disBtn.btn.input.enableDrag();
		//开始拖动回调,本demo中用不到这个回调
    	this.disBtn.btn.events.onDragStart.add(this.dragStart,this);
		//拖动中的回调
    	this.disBtn.btn.events.onDragUpdate.add(this.dragUpdate,this);
		//结束拖动回调
    	this.disBtn.btn.events.onDragStop.add(this.dragStop,this);
		/**
		* 因为我本地这个Demo是有镜头移动的,随便放下摇杆定位的代码
		* fixedToCamera =>跟随镜头移动
		* cameraOffset.y => 设置摇杆组相对镜头Y坐标的偏移
		*/
		this.disBtn.fixedToCamera = true;
		this.disBtn.cameraOffset.y = this.world.height - this.disBtn.bg.height;

拖动中回调 => dragUpdate

function dragUpdate(e){
		/**
		* 获取触摸点与摇杆中心点的弧度
		* this.angleToXY(触摸点.x, 触摸点.y, 摇杆中心点.x, 摇杆中心点.y)
		*/
		var radian = this.angleToXY(this.game.input.x, this.game.input.y - this.disBtn.cameraOffset.y, this.disBtn.bg.centerPoint.x, this.disBtn.bg.centerPoint.y);
		/**
		* 设置摇杆最大移动范围
		* this.disToXY(摇杆中心点.x, 摇杆中心点.y, 摇杆.x, 摇杆.y)
		*/
		var dis = this.disToXY(this.disBtn.bg.centerPoint.x, this.disBtn.bg.centerPoint.y, this.disBtn.btn.x, this.disBtn.btn.y)
		if(dis > this.disBtn.bg.radius){
			//console.log("超出范围了!");
			/**
			* 设置摇杆新的坐标
			* 公式:
			* X = 中心点.x + 半径 * Math.cos(弧度)
			* Y = 中心点.y + 半径 * Math.sin(弧度)
			*/
			this.disBtn.btn.x = this.disBtn.bg.centerPoint.x + this.disBtn.bg.radius * Math.cos(radian);
			this.disBtn.btn.y = this.disBtn.bg.centerPoint.y + this.disBtn.bg.radius * Math.sin(radian);
		};
		//按照摇杆与中心点的角度,设置人物移动方向
		this.play.body.velocity.copyFrom(this.game.physics.arcade.velocityFromAngle(radian * 180 / Math.PI, 200));
}

结束拖动回调 => dragStop

function dragStop(e){
	//重置摇杆按钮坐标为摇杆中心点
	e.x = this.disBtn.bg.centerPoint.x;
	e.y = this.disBtn.bg.centerPoint.y;
	//停止主角运动
	this.play.body.velocity.x = 0;
	this.play.body.velocity.y = 0;
	//停止主角动画
	this.play.animations.stop();
	//重设主角的纹理
	this.play.frame = 0;
}

好啦,基础的代码就这么多了,是不是很简单?对~!!!简单到我都不知道有没有BUG~~ 如果大家发现BUG的话,就骂我,反正骂我还是有BUG~~

5 回复
  • 厉害

根据以sprite作为容器的相对坐标特点,以及充分利用事件的参数,其实可以再精简一下:

var GameState = function(game){
	var gamePad, btn, player;
	this.preload = function(){
		this.load.spritesheet("touch", "touch.png",64,64); // 把摇杆的素材做到一个spritesheet中
	};
	this.create = function(){
		player = this.game.add.sprite(300, 180, "touch",2); // 随便创建个精灵
		gamePad = this.game.add.sprite(100, 260, "touch",0); // 背景
		gamePad.anchor.set(0.5); // 中心点对齐
		btn = gamePad.addChild(this.game.make.sprite(0, 0, "touch",1));  // 摇杆
		btn.anchor.set(0.5); // 中心点对齐
		btn.inputEnabled = true;
		btn.input.enableDrag();
		btn.events.onDragUpdate.add(_dragUpdate,this);
		btn.events.onDragStop.add(_dragStop,this); 
	};
	this.update = function(){
		player.x += btn.x / 10;
		player.y += btn.y / 10;
	};
	var _dragUpdate = function(btn,p,xx,yy){
		var d = Math.sqrt(xx * xx + yy * yy); // 计算拖动距离(第3、4个参数很有用)
		if(d>30){d=30;} // 限制拖动距离
		var r = Math.atan2(yy, xx);
		btn.x = Math.cos(r)*d;
		btn.y = Math.sin(r)*d;
	};
	var _dragStop = function(btn){
	    // 松开返回原点
		btn.x = 0;
		btn.y = 0;
	};
};

Demo效果传送门:http://www.aleaf.com/h5/games/test/touch.html

@aleafworld老哥棒棒的。这就是分享自己代码的好处,有老哥门给你指正,优化~~

回到顶部