先看一下实际的成果:
PC玩法:点击打开链接
手机下方扫描二维码玩
开始讲解之前,打个广告,欢迎html5游戏开发爱好者扫描下方二维码或者搜群号223466431,加入开发者QQ群,我们免费提供最快速的开发工具,我们的所有html5游戏都开源。
整个游戏的开发,基于在线H5游戏开发工具TangIDE,相关开发文档点击这里,开发视频正在制作中…如果您致力于开发H5轻应用,请点这里
1. 准备工作
浏览器打开TangIDE链接,右上角有登陆按钮,选择QQ登陆。
浏览器推荐谷歌浏览器或者猎豹浏览器。
2. 创建第一个场景
这个场景比较简单没有什么好讲的。
3. 创建第二个场景
游戏场景布局比较中要:
人物我是选则四边形刚体:通过添加大小是人刚好角的中间这样比较合理,用其它刚体会引入形状带入的各种缺陷
还有一个就好调节楼梯对应的刚体的上下边距是使人可以在楼梯中间跑动和怪物可以在楼梯中间来回移动:
得分和结束加载我设置成了:不随场景滚动,这里因为有虚拟高度所以需要调节他们
y轴的坐标
。下图是得分的坐标,加载调到中间就可以了。
还有就是人物动画了,可以参考我以前讲的几个博客。
4. 创建第三个场景
5. 创建第四个场景
4,5场景都比较简单就不做讲解了。
6. 编写代码(游戏部分的主要逻辑)
窗口打开前事件:
var me = this;
var win = this.getWindow();
win.resetGame();
//显示对象
var person = win.find("人");
var monster = win.find("怪物");
var road = win.find("路");
var casement = win.find("窗户");
var SPACE_DEFINE = Math.floor(win.h/3);
var YOFFSET_DEFINE = 100000;
var GRAVITY= 25;
win.initVar = function(){
win.setOffset(0,YOFFSET_DEFINE);
win.arrayMonster = Array();
win.arrayRoadAndCasement = Array();
win.arraySensor = Array();
win.totalArrayLength = 1;
win.high = initData;
win.score = 0;
win.find("得分底").setVisible(true);
win.find("得分底/得分").setValue(win.score);
win.pointUpFalg = true;
win.pointDownFlag = false;
win.jump = true;
win.sensorContactFlag = true;
win.directionRoad = road;
};
//人与路碰撞路的动画
function onBeginContactRoad(body, contact){
var element = body.element;//比较控件的名字
var self = this;
if(element.name === "人"){
win.directionRoad = this;
if(person.x < this.x){
if(self.roadContactFalg && !win.sensorContactFlag){
self.roadContactFalg = false;
win.sensorContactFlag = true;
win.jump = true;
self.setBgImage(1);
setTimeout(function() {
self.setBgImage(0);
}, 100);
}
}
}
}
//路和窗户的复制
win.dupRoadAndCasement = function(){
var roadAndCasement ={
roadDup:win.dupChild("路"),
casementDup:[],
sensor:win.dupChild("感应器")
};
var roadDupY = win.totalArrayLength * SPACE_DEFINE + 50;
roadAndCasement.roadDup.setPosition( roadAndCasement.roadDup.x , YOFFSET_DEFINE - roadDupY);
//窗户设置在不同的地方
casementNumber = Math.floor(Math.random() * 2 )+2;
var casementSpace = (win.w - casementNumber * casement.w)/(casementNumber + 1);
for(var i = 0; i < casementNumber ; i++){
roadAndCasement.casementDup[i] = win.dupChild("窗户");
var casementDupX = casementSpace * ( i + 1 ) + i * casement.w;//设置窗户X方向的位置
roadAndCasement.casementDup[i].setPosition( casementDupX , YOFFSET_DEFINE - roadDupY - roadAndCasement.casementDup[i].h * 7 / 5 );
var casementPic = Math.floor(Math.random() * 2 );
roadAndCasement.casementDup[i].setImageSrc(casementPic);
}
win.totalArrayLength++;
win.arrayRoadAndCasement.push(roadAndCasement);
var arrayLength = win.arrayRoadAndCasement.length-1;
win.arrayRoadAndCasement[arrayLength].roadDup.roadContactFalg = true;
win.arrayRoadAndCasement[arrayLength].roadDup.onBeginContact = onBeginContactRoad;
return roadDupY;
};
//怪兽的移动
function MonsterOnMove(){
var v = this.getV();
//改变运动的方向
if( this.x <= 0 ){
this.setV( -v.x, v.y );
}
if( this.x+this.w >= win.w ){
this.setV( -v.x, v.y );
}
if(v.x > 0){
this.flipX = false;
}else{
this.flipX = true;
}
}
//怪兽复制 /*怪物的种类 最大速度 */
win.dupMonsterr = function(monsterrPic,monsterrMaxV){
if(monsterrPic < 0){
return;
}
var roadDupY = win.dupRoadAndCasement();//路和窗户的复制,返回路y轴坐标
if(monsterrMaxV < 0){
monsterrMaxV = -monsterrMaxV;
}
//复制怪兽,设置怪兽对应的图片,怪兽的x方向运动的速度
var monsterrDup = win.dupChild("怪物");
var number = Math.floor(Math.random() * monsterrPic);
var monsterrVX = Math.random() * monsterrMaxV;
//怪兽出现的不同位置,运动方向也不同
if(Math.random() >= 0.5){
monsterrDup.setPosition( win.w - monsterrDup.w , YOFFSET_DEFINE - (roadDupY + monsterrDup.h) );
monsterrDup.setV(-monsterrVX-0.9 , 0 );
}else{
monsterrDup.setPosition( 0 , YOFFSET_DEFINE - (roadDupY + monsterrDup.h));
monsterrDup.setV( monsterrVX+0.9 , 0);
}
//定义刚体的onMove事件
monsterrDup.handleOnMoved = MonsterOnMove;
win.arrayMonster.push(monsterrDup);
return roadDupY;
};
/***********************************感应器******************************************/
var end = win.find("结束感应器");
function onBeginContactSensor(body, contact){
var element = body.element;//比较控件的名字
var self = this;
if(element.name === "人"){
if(self.sensorContactFalg){
self.sensorContactFalg = false;
win.sensorContactFlag = self.sensorContactFalg;
win.score++;
win.find("得分底/得分").setValue(win.score);
end.setPosition(0,end.y - SPACE_DEFINE);
monster.setPosition(0,monster.y - SPACE_DEFINE);
win.jump = false;
win.dupSensor();
if(person.y < win.directionRoad.y){
if(win.directionRoad.roadContactFalg){
win.directionRoad.roadContactFalg = false;
win.directionRoad.setBgImage(1);
setTimeout(function() {
win.directionRoad.setBgImage(0);
}, 100);
}
}
me.playSoundEffect("上一个.mp3", function onDone() {console.log("play finished");});
}
}
}
win.dupSensor = function(){
var roadDupY = win.dupMonsterr(1,1);
var sensor = win.dupChild("感应器");
sensor.setPosition(0, YOFFSET_DEFINE - roadDupY - person.h/4);
win.arraySensor.push(sensor);
var length = win.arraySensor.length;
win.arraySensor[length - 1].sensorContactFalg = true;
win.arraySensor[length-1].onBeginContact = onBeginContactSensor;
//删除多余的数组
if(win.arraySensor.length > 5){
var removeMonster = win.arrayMonster.shift();
removeMonster.remove();
var removeRoadAndCasement = win.arrayRoadAndCasement.shift();
removeRoadAndCasement.roadDup.remove();
var lengthArray = removeRoadAndCasement.casementDup.length;
for(var i = lengthArray - 1; i >= 0 ;i--){
removeRoadAndCasement.casementDup[i].remove();
}
var removeSensor = win.arraySensor.shift();
removeSensor.remove();
}
};
/********************************************************************/
win.initVar();
win.dupSensor();
win.dupSensor();
win.dupSensor();
win.contact = false;
var ground = win.find("得分底");
var index = win.arrayMonster[win.arrayMonster.length - 1].getZIndex();
win.personY = 0;
ground.setZIndex(index);
/*********************************人************************************************/
var STATE_LEFT_RUN = 0;
var STATE_LEFT_JUMP = 1;
var STATE_RIGHT_RUN = 2;
var STATE_RIGHT_JUMP = 3;
win.gameState = STATE_RIGHT_RUN;
function stateToAction(state) {
switch (state) {
case STATE_LEFT_RUN:
return "zuo";
case STATE_RIGHT_RUN:
return "you";
case STATE_LEFT_JUMP:
return "zuotiao";
case STATE_RIGHT_JUMP:
return "youtiao";
}
}
function setAction() {
win.find("人/人动画").play(stateToAction(win.gameState),1, function(){
if(!win.children) {
return;
}
setAction();
});
}
setAction();
/*************************************************/
person.onBusyJumpFlag = false;
person.timeJump = 0;
person.setV(2.5,0);
function personOnMove(){
if(win.contact){//和怪物了发生碰撞
return;
}
var v = this.getV();
//改变运动的方向
var newState = STATE_RIGHT_RUN;
win.personJumpBusyVy = (Math.abs(win.personVy - v.y) > 0.01);
console.log("win.personJumpBusyVy" + win.personJumpBusyVy);
if(win.personJumpBusyVy){
newState = STATE_RIGHT_JUMP;
}else { //if(win.personJumpBusyVy){
newState = STATE_RIGHT_RUN;
}
if(win.pointDownFlag === true){
person.setSensor(true);
//newState = STATE_RIGHT_JUMP;
var index = win.arrayMonster[win.arrayMonster.length - 1].getZIndex();
person.setZIndex(index);
ground.setZIndex(index);
if(win.jump){
v.y = -6;
}
}
if(newState != win.gameState) {
win.gameState = newState;
setAction();
}
if(v.y >= 0){
person.setSensor(false);
}
if( this.x <= 0 ){
this.setV( -v.x, v.y );
win.find("人/人动画").flipX = false;
}
if( this.x + this.w >= win.w ){
this.setV( -v.x, v.y );
win.find("人/人动画").flipX = true;
}
if(this.y === win.personY){
win.jump = true;
}
win.personVy = v.y;
win.personY = this.y;
}
person.handleOnMoved = personOnMove;
指针按下事件:
var me = this;
var win = this.getWindow();
if(beforeChild){
return;
}
if(!win.personJumpBusyVy){
win.pointDownFlag = true;
if(!win.contact){
me.playSoundEffect("跳跃.mp3", function onDone() {console.log("play finished");});
}
}
指针松开事件:
var me = this;
var win = this.getWindow();
if(beforeChild){
return;
}
win.pointDownFlag = false;
如果有疑问或者指教,欢迎加群223466431讨论或者发邮件,有些地方可能学的不是很好望谅解,谢谢!