初识html5小游戏

本次Html5小游戏使用createjs来开发。基本涵盖这个游戏的全部核心代码。
如下是主要用到的元素:

  • createjs.SpriteSheet
    创建雪碧图,将生成好的雪碧图读取出来
  • createjs.Container
    创建容器,容器可以叠加,将多个容器加到一个容器,则操作一个容器就行,类似分组处理。
  • createjs.Shape
    创建矢量图形,创建的容器对象,可以设置hitArea=new createjs.Shape(),然后再在容器上设置点击或者移动事件。
  • createjs.Bitmap
    创建图形对象容器,new createjs.Bitmap()[x|y],x和y设置图片位置
  • createjs.Sound
    播放声音,播放前需要加载,new createjs.LoadQueue().installPlugin(createjs.Sound)注册声音插件.
    也可以单独注册资源:createjs.Sound.registerSound(d.src, d.id);
    然后播放对应注册资源的音频文件id即可:createjs.Sound.play(id);

创建舞台(stage),然后将创建的各种雪碧图,背景图,容器,全部加入到舞台,设置在舞台的位置(都是绝对位置,左上角为 0,0),this.stage.update(e);刷新舞台。

一、初始化

首先要初始化页面场景,和一些默认页面元素。

  • 获取屏幕宽度,设置canvas
	this.windowWidth = document.documentElement.clientWidth;
	this.windowHeight = document.documentElement.clientHeight;
	const canvas = document.getElementById('a_game');
  	canvas.setAttribute('width', 750);
 	canvas.setAttribute('height', (this.windowHeight * 750) / this.windowWidth);
  • 设置场景
	this.stage = new createjs.Stage(canvas);
 	this.stageWidth = canvas.width;
  	this.stageHeight = canvas.height;
  	createjs.Touch.enable(this.stage);
  	this.complete = complete || function () {};
  	this.musicChange = musicChange || function () {};
  	createjs.Ticker.paused = 0;
  	createjs.Ticker.addEventListener('tick', this.tick.bind(this));
  	createjs.Ticker.framerate = 60;
  • 检测横屏竖屏
this.detectOrient();//首次先执行一次
window.onresize = this.debounce(this.detectOrient.bind(this), 300);// 检测窗口改变
Avoiding.prototype.detectOrient = function () {
  const orient = document.getElementById('a_orient');
  const cw = this.windowWidth;
  const sw = window.screen.width;
  if (cw == sw) {
    // 竖屏
    orient.className = 'orient_tips hide';
    this.orient = 1;
    return true;
  }
  // 横屏
  orient.classList.remove('hide');
  this.orient = 0;
  return false;
};

如果设置了orient_tips,则提示用户改成竖屏
在这里插入图片描述

  • 设置页面元素的缩放
let scale;
  if (this.windowWidth <= 320) {
    scale = 0.8;
  } else if (this.windowWidth <= 360) {
    scale = 1;
  } else if (this.windowWidth <= 420) {
    scale = 1.1;
  } else if (this.windowWidth <= 736) {
    scale = 1.15;
  } else {
    scale = 1.2;
  • 创建背景图片
// 创建背景
Avoiding.fn.createBackground = function () {
  this.bgContainer1 = new createjs.Bitmap(this.resource.bg);
  this.bgContainer2 = this.bgContainer1.clone();
  this.bgHeight = (2668 * this.stageWidth) / 750;
  this.bgContainer1.y = -(this.bgHeight - this.stageHeight);
  this.bgContainer2.y = this.bgContainer1.y - this.bgHeight;
  this.stage.addChild(this.bgContainer1);
  this.stage.addChild(this.bgContainer2);
};
  • 处理雪碧图
Avoiding.fn.createSprite = function () {
  this.spriteImages = new createjs.SpriteSheet({
    images: [this.resource.sprite],
    frames: [
      [0, 0, 218, 176],
      [218, 0, 218, 176],
      [436, 0, 218, 176],
      [0, 176, 148, 148],
      [148, 176, 148, 148],
      [296, 176, 148, 148],
      [444, 176, 148, 148],
      [0, 324, 148, 148],
      [148, 324, 148, 148],
      [296, 324, 148, 148],
      [444, 324, 148, 148],
      [0, 472, 121, 82],
      [121, 472, 121, 81]
    ],
    animations: {
      normal: {
        frames: [0]
      },
      giddy: {
        frames: [1]
      },
      eat: {
        frames: [2]
      },
      one: {
        frames: [3]
      },
      two: {
        frames: [4]
      },
      three: {
        frames: [5]
      },
      four: {
        frames: [6]
      },
      five: {
        frames: [7]
      },
      six: {
        frames: [8]
      },
      seven: {
        frames: [9]
      },
      eight: {
        frames: [10]
      },
      rock1: {
        frames: [11]
      },
      rock2: {
        frames: [12]
      }
    }
  });
  const self = this;
  function create(obj, key) {
    obj[key] = new createjs.Sprite(self.spriteImages, key);
  }

  this.brands.map((d) => {
    create(self.brandObj, d);
  });
  this.rocks.map((d) => {
    create(self.rockObj, d);
  });
  const brandGif = new createjs.SpriteSheet({
    images: [this.resource.brandGif],
    frames: {
      width: 168,
      height: 168
    },
    animations: {
      gif: {
        frames: [1, 2, 3, 4, 5],
        speed: 0.2
      }
    }
  });
  this.brandGif = new createjs.Sprite(brandGif, 'gif');
};
  • 创建操作的任务图像
/**
   * 创建圈妹
   */
Avoiding.fn.createQuanmei = function () {
  // 普通小圈妹妹
  this.quanNormal = new createjs.Sprite(this.spriteImages, 'normal');
  this.quanNormal.scaleX = this.quanScale;
  this.quanNormal.scaleY = this.quanScale;
  this.quanNormal.alpha = 1;

  // 晕了的小圈妹妹
  this.quanGiddy = new createjs.Sprite(this.spriteImages, 'giddy');
  this.quanGiddy.scaleX = this.quanScale;
  this.quanGiddy.scaleY = this.quanScale;

  const giddyQuan = new createjs.SpriteSheet({
    images: [this.resource.quanGif],
    frames: {
      width: 218,
      height: 176
    },
    animations: {
      giddy: {
        frames: [1, 2, 3, 4, 5],
        speed: 0.2
      }
    }
  });
  this.quanGiddyGif = new createjs.Sprite(giddyQuan, 'giddy');
  this.quanGiddyGif.scaleX = this.quanScale;
  this.quanGiddyGif.scaleY = this.quanScale;

  const quanGiddC = new createjs.Container();
  quanGiddC.addChild(this.quanGiddy);
  quanGiddC.addChild(this.quanGiddyGif);
  this.quanGiddC = quanGiddC;
  this.quanGiddC.alpha = 0;

  // 吃到东西的小圈妹妹
  this.quanEat = new createjs.Sprite(this.spriteImages, 'eat');
  this.quanEat.scaleX = this.quanScale;
  this.quanEat.scaleY = this.quanScale;
  this.quanEat.alpha = 0;

  const quanC = new createjs.Container();
// 创建一个container,里面附加人物的不停变换效果
  quanC.addChild(this.quanNormal);
  quanC.addChild(this.quanGiddC);
  quanC.addChild(this.quanEat);

  quanC.width = 218 * this.quanScale;
  quanC.height = 176 * this.quanScale;
  quanC.x = (this.stageWidth - quanC.width) / 2;
  quanC.y = this.stageHeight - quanC.height;

  this.quanC = quanC;
  //如果需要捕捉用户的事件点击,需要创建一个shape,由于产品需要触摸点是整个屏幕,所以把宽度调大了
  const hitArea = new createjs.Shape();
  hitArea.graphics.beginFill('#fff').drawRect(0, 0, this.stageWidth*2, this.stageHeight*2); // 这里是图片大小
  this.quanNormal.hitArea = hitArea;

  this.quanNormal.addEventListener('mousedown', this.touchStart.bind(this));
  this.quanNormal.addEventListener('pressmove', this.touchMove.bind(this));
  this.stage.addChild(quanC);
};

二、开始游戏

  • 手势事件
Avoiding.fn.touchStart = function (e) {
  this.startX = e.stageX;
  this.startY = e.stageY;
  this.startGame = 1;
};
Avoiding.fn.touchMove = function (e) {
  if (this.quanGiddC.alpha) return;//如果是撞击了石头等,则不移动,晕1s
  const { stageX, stageY } = e;
  this.distanceX += stageX - this.startX;
  this.distanceY += stageY - this.startY;
  this.startX = stageX;
  this.startY = stageY;
};
  • 处理场景更新
Avoiding.fn.tick = function (e) {
  if (e.paused === 0) {
    if (this.startGame) {
      this.movePeople();
      this.moveObstacles();
      this.createObstacles();
      this.hitCheck();
      this.updateScore();
    }
    // 刷新舞台
    this.stage.update(e);
  }
};
  • 处理人物更新
    移动人物,设置边界
Avoiding.fn.movePeople = function (e) {
  if (!this.startX || !this.startY || !this.distanceX || !this.distanceY) { return; }
  const x = this.detectX(this.quanC.x + this.distanceX, 176 * this.quanScale);
  const y = this.detectY(this.quanC.y + this.distanceY, 218 * this.quanScale);
  this.distanceY = 0;
  this.distanceX = 0;
  this.quanC.x = x;
  this.quanC.y = y;
};
  • 下滑障碍物和背景图片,给用户是人向前的感觉
    背景图设置两个,同一个图片,做无限循环
/**
   * 下滑障碍物
   */
Avoiding.fn.moveObstacles = function () {
  const now = Date.now();
  if (!this.moveLastTime) return (this.moveLastTime = now);
  let diff = now - this.moveLastTime;
  if (diff > 20) diff = 20;
  const distance = diff * 0.1 * this.speed;
  let y1 = this.bgContainer1.y;
  let y2 = this.bgContainer2.y;
  if (y1 >= this.stageHeight) {
    y1 = y2 - this.bgHeight;
  }
  if (y2 >= this.stageHeight) {
    y2 = y1 - this.bgHeight;
  }
  y1 += distance;
  y2 += distance;

  this.bgContainer1.y = y1;
  this.bgContainer2.y = y2;
  this.obstaclesList = this.obstaclesList.filter((d) => {
    d.y += distance;
    if (d.y > this.stageHeight || d.isHited) {
      //   d.x = -500;
      this.obstaclesC.removeChild(d);
      return false;
    }
    return true;
  });
  this.moveLastTime = Date.now();
};
  • 障碍物和背景向下掉落,那么需要创建新的障碍物
    这里设定了没滑动0.2个屏幕高度,则创建一个障碍物,且是出现五个积分物件再出现一个石头
Avoiding.fn.createObstacles = function () {
  if (!this.moveDistance) return (this.moveDistance = this.bgContainer1.y);
  const diff = this.bgContainer1.y - this.moveDistance;
  if (Math.abs(diff) >= 0.2 * this.stageHeight) {
    if (this.brandCount < 5) {
      const d = this.getRandomBrand();
      this.obstaclesList.push(d);
      this.obstaclesC.addChild(d);
      this.brandCount++;
      if (this.brandCount == 5) {
        const r = this.getRandomRock();
        this.obstaclesList.push(r);
        this.obstaclesC.addChild(r);
        this.brandCount = 0;
      }
    }
    this.moveDistance = this.bgContainer1.y;
  }
};
  • 检测撞击
    撞击很容易理解,任务四周和掉落的东西的四周碰撞即表明是撞击了,此时将该物体表面是已撞击,在移动物体的时候,直接干掉这个remove物体。撞击了石头要眩晕,撞击物品要加积分
/**
   * 检测撞击
   */
Avoiding.fn.hitCheck = function () {
  const quanC = this.quanC;
  const qx = quanC.x + 15;
  const qy = quanC.y + 15;
  const qw = quanC.width - 30;
  const qh = quanC.height - 30;
  const hitBrand = []; // 创建的泡泡列表
  this.obstaclesList.map((d) => {
    const {
      x, y, width, height, isHited
    } = d;
    if (isHited) return;
    if (x + width > qx && x < qx + qw && y + height > qy && y < qy + qh) {
      if (d.type == 'brand') {
        hitBrand.push(this.hitBrand(x, y));
      } else {
        this.hitRock();
      }
      d.isHited = true;
    }
  });
  if (hitBrand.length == 0) return;
  hitBrand.map((hb) => {
    this.obstaclesC.addChild(hb);
  });
};

总结:还没做的时候,觉得复杂,毕竟从来没搞过,其实还是很简单的。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值