【问题标题】:How would I create a "Choose your Own Adventure game" on Canvas?如何在 Canvas 上创建“选择你自己的冒险游戏”?
【发布时间】:2015-11-23 19:40:44
【问题描述】:

刚接触编码,我决定使用从网上提取的 6 张图片创建一个交互式的点击冒险游戏。

我将第一张图片添加到画布上,并在画布上的图片前面放了一个很酷的小动画,但现在我遇到了一个大问题。

整个游戏是在一个画布上完成的,有多个,以及点击事件的分支。

示例:在标题屏幕上,用户可以选择“开始游戏”或“积分”(作为可点击文本完成)。

如果用户选择“开始游戏”,画面切换到2号图,再次点击后,2号图模糊,旁白文字出现在用户面前。然而,如果他们选择“学分”,则屏幕转而切换到不同的图片,即图片编号 3。在图片编号 3 上,学分以缓慢的自动向上滚动方式显示。

我在网上查到了这个,但我通常会在我正在寻找的大致范围内得到答案,我发现的一些结果是开关案例(对它们没有太多经验,更不用说进行 BRANCHING 开关了案例),用于交互式故事讲述、事件处理程序等的 Undum 框架。

我没有太多使用 Javascript 或画布,在我处理这个项目之前,我认为最好直接提出我的项目问题并获得经验丰富的意见,以及将项目逐个分解并形成某种攻击方法。

知道这个项目将如何运作,你们会推荐我使用哪些资源或编码方法?这个“分支”动画树会是什么样子?

这是我目前的代码:

-- HTML--

<html>
<head>
    <title>Detective</title>
  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
  <%= javascript_include_tag  'application', 'data-turbolinks-track' => true %>
  <%= csrf_meta_tags %>
  <!--   load in the jquery -->
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.js">
    </script>
</head>
<body>

</body>
</html>

-- CSS --

body{
  background:#000;
  width: 100%;
  height: 100%;
  overflow:hidden;
}

canvas{
/*the code below this activates the canvas border, turn it on to visibly see how big the canvas is */

/*  border: 1px solid red;*/  

    position: absolute;
    top:0;
    bottom: 0;
    left: 0;
    right: 0;
    margin:auto;
    display: none;
}

@font-face{
  font-family: 'Betty Noir Regular';
  src: url('/assets/bettynoir.ttf');
}

-- JS--

var canvas = document.createElement('canvas'); 
var w = canvas.width = 800,
    h = canvas.height = 400;
var c = canvas.getContext('2d');

var img = new Image();
img.src = 'http://oi41.tinypic.com/4i2aso.jpg';

var background = new Image();
background.src = "https://i2.wp.com/i2.listal.com/image/2669447/500full.jpg";



var position = {x : 410, y : 238};

document.body.appendChild(canvas);

var particles = [];
var random = function(min, max){
  return Math.random()*(max-min)*min;
};

function Particle(x, y){
  this.x = x;
  this.y = y;
  this.velY = -2;
  this.velX = (random(1, 10)-5)/10;
  this.size = random(3, 5)/10;
  this.alpha = 1;
  this.update = function(){
    this.y += this.velY;
    this.x += this.velX;
    this.velY *= 0.99;
    if(this.alpha < 0){this.alpha = 0;}
    c.globalAlpha = this.alpha;
    c.save();
    c.translate(this.x, this.y);
    c.scale(this.size, this.size);
    c.drawImage(img, -img.width/2, -img.height/2);
    c.restore();
    this.alpha *= 0.96;
    this.size += 0.02;//  
  };
}

var draw = function(){
  var p = new Particle(position.x, position.y);
  particles.push(p);

  // draw the background image before you draw the particles
  c.drawImage(background,160,0);
  c.font="20px Betty Noir Regular";
  c.fillStyle = "white";
  c.fillText("Start",500,200);

  c.font="20px Betty Noir Regular";
  c.fillStyle = "white";
  c.fillText("Credits",500,250);

  while(particles.length > 500) particles.shift();

  for(var i = 0; i < particles.length; i++)
  {
    particles[i].update();
  }
};



setInterval(draw, 3500/60);


$(document).ready(function() {
 $("canvas").fadeIn(7000);
});

$(document).ready(function() {
    $("#noir-song").get(0).play();
});

【问题讨论】:

    标签: javascript html canvas branch


    【解决方案1】:

    看起来不错。

    我会说摆脱setInterval,因为从长远来看它只会给你带来问题。由于您有粒子系统,因此某些设备可能无法很好地处理负载,并且 setInterval 在调用调用堆栈之前不会检查最后一个渲染作业是否完成,您最终可能会溢出调用堆栈并使应用程序崩溃。

    使用window.requestAnimationFrame(functionName)

    如下

    // your main render function
    function draw(){
        // do your stuff
        requestAnimationFrame(draw); // needs to be call for every new frame
    }
    draw(); // start it all happening.
    

    requestAnimationFrame 对渲染负载很敏感,会尽力保持均匀的帧速率 1/60 或 60fps。如果可能的话,与显示器刷新率同步,这样您就不会受到剪切。它是为动画设计的(因此得名),所以试试吧。

    我会问“为什么要使用 jquery?”您将使用支持画布和 jquery 的浏览器,除了支持旧版浏览器之外没有提供真正的好处,并且只会增加页面的复杂性并增加加载时间。你只用它来准备页面,所以看起来有点浪费。移除 jQuery 并使用 onload 替换就绪调用

    window.addEventListener("load",function(){
       // your startup up code
    });
    

    创建粒子的更好方法。使用 new 很慢,尤其是当您创建同一事物的许多实例时。

    试试

    // define the function to update once. In the new Particle() version
    // javascript actually has to create this function every time you create a particle.
    // This makes it quicker.
    var particleUpdate = function(){
        this.y += this.velY;
        this.x += this.velX;
        this.velY *= 0.99;
        // a quicker way to clamp a value
        // if(this.alpha < 0){this.alpha = 0;} // done in the following line
        c.globalAlpha = Math.max(0,this.alpha); // returns the max value so while 
                                                // alpha > 0 it returns alpha
                                                // when alpha < 0 returns max 
                                                // which is 0;
        //c.save();  // dont need this here do it outside the loop that renders
                     // the particles. Save and restore are expensive in  terms
                     // of GPU performance and should be avoided if possible. 
        // the translate and scale can be done in one call halving the time
        // to do the same thing
        //c.translate(this.x, this.y);
        //c.scale(this.size, this.size);
        // use setTransform does the same as translate and scale but in one step
        c.setTransform(this.size,0,0,this.size,this.x,this.y)
        c.drawImage(img, -img.width/2, -img.height/2);
        // c.restore(); see above
        this.alpha *= 0.96;
        this.size += 0.02;//  
    };
    var createParticle = function(x,y){
        return {
            x:x,
            y:y,
            velY:-2,
            velX:(random(1, 10)-5)/10,
            size:random(3, 5)/10,
            alpha = 1,
            update:particleUpdate,
        }
    }
    

    然后创建

    particles.push(createParticle(position.x, position.y));

    更新和剔除你已经在做的只是在循环之外添加保存和恢复。获得“particles.length”也比直接变量慢。所以重写循环如下

      var len = particles.length
      c.save()
      for(var i = 0; i < len; i++){
           particles[i].update();
      }
      c.restore();
    

    在这种情况下不会有太大的不同,因为没有那么多事情发生。但是随着你推动越来越多的效果,每帧性能的更多爆炸将成为一个主要问题。尽早学习有效的方法会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-25
      • 2015-04-27
      • 1970-01-01
      相关资源
      最近更新 更多