收藏
回答

Canvas的大小和真机实际的屏幕显示范围不一致。

问题模块 框架类型 问题类型 操作系统 工具版本
开发者工具 小游戏 Bug Windows 1.02.1808101

我创建了一个小游戏项目,在canvas.height、canvas.width得到的值和window.innerHeight、window.innerWidth、SystemInfo.windowHeight、SystemInfo.windowWidth是一样的,但是这些方法获得的屏幕尺寸和真机上的实际屏幕值不一致。,我用的是HuaWei M9 手机,真实屏幕尺寸是1920:1080,但是在小游戏环境下的到的永远是768:732,而且在Canvas上绘制东西显示的东西右侧和下侧面会被裁剪,这是为什么?但在模拟器中屏幕大小和选定的模拟器是一样的,也不会出现裁剪现象。

babylon.min.js可以在wx5952a4b12e404513这小程序的提交目录下得到。


import BABYLON from './libs/babylon.min'
// import Music from './runtime/music'
import GameInfo from './runtime/gameinfo'
var self;
/**
 * 游戏主函数
 */
export default class Main {
  ;
  scene;
  engine;
  camera;
  touchInput;
  gameinfo;
  dirCount;
  constructor() {
    self = this;
    var red, green, blue, yellow;
    var width = canvas.width;
    var height = canvas.height;
    console.log('canvas size:' + height + ' ' + width);
    console.log('window size:' + window.innerHeight + ' ' + window.innerWidth);
     
    var SystemInfo = wx.getSystemInfoSync();
    console.log('SystemInfo:' + SystemInfo);
    console.log(' .SDKVersion:' + SystemInfo.SDKVersion);
    console.log(' .batteryLevel:' + SystemInfo.batteryLevel);
    console.log(' .benchmarkLevel:' + SystemInfo.benchmarkLevel);
    console.log(' .brand:' + SystemInfo.brand);
    console.log(' .devicePixelRatio:' + SystemInfo.devicePixelRatio);
    console.log(' .fontSizeSetting:' + SystemInfo.fontSizeSetting);
    console.log(' .language:' + SystemInfo.language);
    console.log(' .model:' + SystemInfo.model);
    console.log(' .pixelRatio:' + SystemInfo.pixelRatio);
    console.log(' .platform:' + SystemInfo.platform);
    console.log(' .screenHeight:' + SystemInfo.screenHeight);
    console.log(' .screenWidth:' + SystemInfo.screenWidth);
    console.log(' .statusBarHeight:' + SystemInfo.statusBarHeight);
    console.log(' .system:' + SystemInfo.system);
    console.log(' .version:' + SystemInfo.version);
    console.log(' .windowHeight:' + SystemInfo.windowHeight);
    console.log(' .windowWidth:' + SystemInfo.windowWidth);
 
 
    //创建2DCanvas和2D上下文
    var canvas_2d = wx.createCanvas('canvas_2d');
    var ctx = canvas_2d.getContext('2d');
    //加载巴比伦3D引擎(使用默认的Canvas)
    var engine = self.engine = new BABYLON.Engine(canvas, true);
 
    canvas.width = width;
    canvas.height = height;
    canvas_2d.width = width;
    canvas_2d.height = height;
    console.log('canvas_2d size:' + canvas_2d.height + ' ' + canvas_2d.width);
    // 通过引擎创建基本场景
    var scene = self.scene = new BABYLON.Scene(engine);
    scene.clearColor = new BABYLON.Color3(0.5, 0.8, 0.9);
 
    //设置场景的动力(G重力, 基于Y轴)
    scene.gravity = new BABYLON.Vector3(0, -0.9, 0);
 
    //设置场景碰撞
    scene.collisionsEnabled = true;
    var gameinfo = self.gameinfo = new GameInfo();
    // var music = new Music();
 
    //创建天空盒(其实就是个box)
    var skybox = BABYLON.Mesh.CreateBox("skyBox", 100.0, scene);
    var skyboxMaterial = new BABYLON.StandardMaterial("skyBox", scene);
    skybox.material = skyboxMaterial;
    skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture("https://www.babylonjs.com/assets/skybox/nebula", scene);
    //设置图片的坐标类型(天空盒)
    skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
    //diffuseColor:漫反射颜色
    skyboxMaterial.diffuseColor = new BABYLON.Color3(0, 0, 0);
    //specularColor:镜面反射颜色
    skyboxMaterial.specularColor = new BABYLON.Color3(0, 0, 0);
    //不接受灯光渲染
    skyboxMaterial.disableLighting = true;
    //反而不剔除
    skyboxMaterial.backFaceCulling = false;
 
    // BABYLON.SceneLoader.Append("https://www.babylonjs.com/Assets/DamagedHelmet/glTF/", "DamagedHelmet.gltf", scene, function (meshes) {
    // });
 
    // 参数:名字,位置,所属场景
    var camera = self.camera = new BABYLON.FreeCamera("FreeCamera", new BABYLON.Vector3(0, 0, -10), scene);
    //给相机的目标设置特定的位置(相机总是朝向它的目标),在这个例子中设置为场景的原点
    camera.setTarget(BABYLON.Vector3.Zero());
    var touchInput = self.touchInput = new BABYLON.FreeCameraTouchInput();
    camera.inputs.add(touchInput);
    touchInput.attachControl(canvas, true);
    //将相机和画布关联
    // camera.attachControl(canvas, true);
 
    // 创建基本光源, 目标位于 x:0,y:1,z:0 -(由天空出现)
    var light = new BABYLON.DirectionalLight('light1', new BABYLON.Vector3(-5, -5, 5), scene);
 
 
    // // 创建一个内置的“球”的形状,它的构造函数包括5个参数:名称、宽度、深度、细分,场景(例子中仅4个参数)
    var sphere1 = BABYLON.Mesh.CreateSphere('sphere1', 16, 1, scene);
 
    red = new BABYLON.StandardMaterial("red", scene);
    red.diffuseColor = new BABYLON.Color3(1, 0, 0); //红
 
    sphere1.material = red;
 
 
    var points = [];
    for (var i = 0; i < 1000; i++) {
      var point = new BABYLON.Vector3();
      point.x = 5 * Math.cos(i * 0.01 * 2 * Math.PI);
      point.y = 1 * Math.cos(i * 0.05 * 2 * Math.PI);
      point.z = 3 * Math.cos(i * 0.1 * 2 * Math.PI);
      points.push(point);
    }
 
    var lines = BABYLON.Mesh.CreateLines("lines", points, scene);
    lines.color = new BABYLON.Color3(1, 0, 0); //红
 
 
    wx.onTouchStart(this.onTouchStart);
    wx.onTouchEnd(this.onTouchEnd);
 
    //一个特殊的顶点着色,没有任务矩阵变换
    BABYLON.Effect.ShadersStore["hudVertexShader"] = `
        #ifdef GL_ES
        precision highp float;
        #endif
        // Attributes
        attribute vec3 position;
        attribute vec2 uv;
        // Normal
        varying vec2 vUV;
        void main(void) {
        gl_Position = vec4(position, 1.0);
        vUV = uv;
        }          
    `;
    //最普通片元着色器,只有一个2D采样
    BABYLON.Effect.ShadersStore["hudFragmentShader"] = `
        #ifdef GL_ES
        precision highp float;
        #endif
        varying vec2 vUV;
        // Refs
        uniform sampler2D textureSampler;
        void main(void) {
        gl_FragColor = texture2D(textureSampler, vUV);
        }   
    `;
    var hudMaterial = new BABYLON.ShaderMaterial("hud", scene, {
      vertexElement: "hud",
      fragmentElement: "hud"
    },
      {
        needAlphaBlending: true,
        attributes: ["position", "uv"],
        samplers: ["textureSampler"]
      });
    var planeVertexData = BABYLON.VertexData.CreatePlane({ size: 2 });//从-1,-1 到 1,1的简单平面覆盖整个3D空间
    // delete planeVertexData.normals;
    var hud = new BABYLON.Mesh("Hud", scene);//HUD网格对象
    planeVertexData.applyToMesh(hud);
 
    //贴图大小和2D屏幕大小一致
    var hudTexture = new BABYLON.DynamicTexture("dynamic texture", { width: canvas_2d.width, height: canvas_2d.height }, scene, true);
    var textureContext = hudTexture.getContext();//贴图的绘制上下文
    hud.material = hudMaterial;
    hudMaterial.setTexture("textureSampler", hudTexture);
    hudMaterial.backFaceCulling = false; //关闭背面裁剪
    hudMaterial.disableDepthWrite = true;//关闭写深度缓存
    hudTexture.update();//贴图更新
 
    window.onresize = (window, event)=>{
      console.log('window:' + window );
      console.log('event:' + event );
    };
 
    // //在引擎中循环运行这个场景
    var isUp = true;
    // var count = 0;
    // var hitCount = 0;
    // self.dirCount = 0;
    engine.runRenderLoop(function () {
 
      // console.log('window size:' + window.innerHeight + ' ' + window.innerWidth);
      // //在2DCanvas上绘制两个矩形
      if (isUp){
        ctx.clearRect(0, 0, canvas_2d.width, canvas_2d.height);
        ctx.fillStyle = 'blue';
        ctx.fillRect(0, 0, 100, 100);
        ctx.fillStyle = 'red';
        ctx.fillRect(canvas_2d.width - 100, canvas_2d.height - 100, 100, 100);
        // //将2DCanvas绘制贴图的上下文
        textureContext.drawImage(canvas_2d, 0, 0);
        //贴图更新
        hudTexture.update();
        //保证每一帧HUD都在
        hud.position = new BABYLON.Vector3(camera._currentTarget.x, camera._currentTarget.y, camera._currentTarget.z);
      }
      isUp = !isUp;
      scene.render();
 
    });
  }
  offsetX;
  offsetY;
  onTouchStart(event) {
    console.log(event);
    let lastTouchPoint = event.changedTouches[0];
    self.offsetX = lastTouchPoint.screenX;
    self.offsetY = lastTouchPoint.screenY;
    let x = event.touches[0].clientX
    let y = event.touches[0].clientY
 
    // let area = self.gameinfo.btnArea
 
    // if (x >= area.startX
    //   && x <= area.endX
    //   && y >= area.startY
    //   && y <= area.endY)
    //   self.dirCount = 0;
  }
  onTouchEnd(event) {
    console.log(event);
    let lastTouchPoint = event.changedTouches[0];
    self.offsetX = lastTouchPoint.screenX - self.offsetX;
    self.offsetY = lastTouchPoint.screenY - self.offsetY;
    self.camera.inputs.attached.touch._offsetX = self.offsetX;
    self.camera.inputs.attached.touch._offsetY = self.offsetY;
 
    self.camera.inputs.attached.touch.touchAngularSensibility = 50000;
    self.camera.inputs.attached.touch.touchMoveSensibility = 250;
 
 
 
    // var target = camera.getTarget();
    // target.x += this.offsetX;
    // target.y += this.offsetY;
    // camera.setTarget(target);
  }
}




最后一次编辑于  2018-08-22  (未经腾讯允许,不得转载)
回答关注问题邀请回答
收藏

5 个回答

  • 是柿子啊
    是柿子啊
    2018-08-22

    你好,请提供一下出现问题的机型和微信版本,以及能复现问题的简单代码片段(https://developers.weixin.qq.com/miniprogram/dev/devtools/minicode.html)。

    2018-08-22
    赞同
    回复
  • tonny
    tonny
    09-14

    你好,请问你在微信中加载过场景吗?我加载时会报错。如您知道,求告知。谢谢。

    09-14
    赞同
    回复
  • _~胖小代
    _~胖小代
    03-13

    babylon.js 在微信小游戏里 锯齿现象严重吗, 最高drawcall是多少?

    03-13
    赞同
    回复
  • 挑战者
    挑战者
    2018-10-18

    问一下,您使用过three.js在小游戏里成功加载过gltf模型吗?


    2018-10-18
    赞同
    回复
  • 清峰
    清峰
    2018-08-22

    机型 HUAWEI Mate 9 微信版本 6.7.2


    wechatide://minicode/pDZXOQmx7t1Z


    babylon.min.js可以在wx5952a4b12e404513这小游戏的提交目录下得到。

    2018-08-22
    赞同
    回复