【问题标题】:Position player hand定位玩家手
【发布时间】:2021-01-07 02:34:02
【问题描述】:

我正在制作一个 2d 游戏,并希望将玩家的手放在他们指向的位置。现在一个简单的方法是使用 ctx.move() 移动到玩家位置,使用 ctx.rotate() 和 Math.atan2() 相对于玩家位置旋转指向鼠标并绘制手。问题是,我想让手抵消。以下是我想要实现的目标。 Image

【问题讨论】:

    标签: javascript math html5-canvas trigonometry angle


    【解决方案1】:

    查看// magic except end load under here。图书馆就在上面。实际上在网上很难找到像这个例子这样的东西:

    //<![CDATA[
    /* js/external.js */
    let get, post, doc, htm, bod, nav, M, I, mobile, beacon, S, Q, hC, aC, rC, tC, shuffle, rand; // for use on other loads
    addEventListener('load', ()=>{
    get = (url, func, responseType = 'json', context = null)=>{
      const x = new XMLHttpRequest;
      const c = context || x;
      x.open('GET', url); x.responseType = responseType;
      x.onload = ()=>{
        if(func)func.call(c, x.response);
      }
      x.onerror = e=>{
        if(func)func.call(c, {xhrErrorEvent:e});
      }
      x.send();
      return x;
    }
    post = function(url, send, func, responseType ='json', context = null){
      const x = new XMLHttpRequest;
      if(typeof send === 'object' && send && !(send instanceof Array)){
        const c = context || x;
        x.open('POST', url); x.responseType = responseType;
        x.onload = ()=>{
          if(func)func.call(c, x.response);
        }
        x.onerror = e=>{
          if(func)func.call(c, {xhrErrorEvent:e});
        }
        let d;
        if(send instanceof FormData){
          d = send;
        }
        else{
          let s;
          d = new FormData;
          for(let k in send){
            s = send[k];
            if(typeof s === 'object' && s)s = JSON.stringify(s);
            d.append(k, s);
          }
        }
        x.send(d);
      }
      else{
        throw new Error('send argument must be an Object');
      }
      return x;
    }
    doc = document; htm = doc.documentElement; bod = doc.body; nav = navigator; M = tag=>doc.createElement(tag); I = id=>doc.getElementById(id);
    mobile = nav.userAgent.match(/Mobi/i) ? true : false;
    beacon = function(url, send){
      let r = false;
      if(typeof send === 'object' && send && !(send instanceof Array)){
        let d;
        if(send instanceof FormData){
          d = send;
        }
        else{
          let s;
          d = new FormData;
          for(let k in send){
            s = send[k];
            if(typeof s === 'object' && s)s = JSON.stringify(s);
            d.append(k, s);
          }
        }
        r = nav.sendBeacon(url, d);
      }
      else{
        throw new Error('send argument must be an Object');
      }
      return r;
    }
    S = (selector, within)=>{
      let w = within || doc;
      return w.querySelector(selector);
    }
    Q = (selector, within)=>{
      let w = within || doc;
      return w.querySelectorAll(selector);
    }
    hC = function(node, className){
      return node.classList.contains(className);
    }
    aC = function(){
      const a = [].slice.call(arguments), n = a.shift();
      n.classList.add(...a);
      return aC;
    }
    rC = function(){
      const a = [].slice.call(arguments), n = a.shift();
      n.classList.remove(...a);
      return rC;
    }
    tC = function(){
      const a = [].slice.call(arguments), n = a.shift();
      n.classList.toggle(...a);
      return tC;
    }
    shuffle = array=>{
      let a = array.slice(), i = a.length, n, h;
      while(i){
        n = Math.floor(Math.random()*i--); h = a[i]; a[i] = a[n]; a[n] = h;
      }
      return a;
    }
    rand = (min, max)=>{
      let mn = min, mx = max;
      if(mx === undefined){
        mx = mn; mn = 0;
      }
      return mn+Math.floor(Math.random()*(mx-mn+1));
    }
    // magic except end load under here 
    const canvas = I('canvas');
    let cb = canvas.getBoundingClientRect(), cX, cY, af = true, action = false;
    canvas.width = cb.width; canvas.height = cb.height;
    const ctx = canvas.getContext('2d');
    ctx.fillStyle = 'red';
    
    function createRect(){
      ctx.rect(cX-2, cY-37, 4, 37);
      ctx.stroke(); ctx.fill();
    }
    function noAct(){
      action = false;
    }
    function moveit(e, hit = false){
      af = true; cb = canvas.getBoundingClientRect();
      let w = cb.width, h = cb.height, p = 180/Math.PI, r;
      ctx.save(); ctx.clearRect(0, 0, w, h); ctx.beginPath(); ctx.translate(cX, cY);
      r = hit ? 0 : 90;
      ctx.rotate((p*Math.atan2(e.clientY-cb.top-cY, e.clientX-cb.left-cX)+r)/p);
      ctx.translate(-cX, -cY); createRect(e); ctx.restore();
    }
    function movement(e, hit = false){
      if(af && action){
        af = false; 
        requestAnimationFrame(()=>{ 
          moveit(e, hit);
        });
      }
    }
    function act(e){
      action = true; cX = e.clientX-cb.left; cY = e.clientY-cb.top; movement(e, true);
    }
    if(mobile){
      canvas.ontouchstart = e=>{
        act(e.touches[0]);
      }
      touchmove = e=>{
        movement(e.touches[0]);
      }
      ontouchend = noAct;
    }
    else{
      canvas.onmousedown = act; onmousemove = movement; onmouseup = noAct;
    }
    }); // end load
    /* css/external.css */
    *{
      box-sizing:border-box; font:22px Tahoma, Geneva, sans-serif; color:#000; padding:0; margin:0; overflow:hidden;
    }
    html,body,.main{
      width:100%; height:100%;
    }
    .main{
      background:#aaa; padding:10px; overflow-y:auto;
    }
    #canvas{
      width:100%; height:100%; background:#fff;
    }
    <!DOCTYPE html>
    <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
      <head>
        <meta charset='UTF-8' /><meta name='viewport' content='width=device-width, height=device-height, initial-scale:1, user-scalable=no' />
        <title>Title Here</title>
        <link type='text/css' rel='stylesheet' href='css/external.css' />
        <script src='js/external.js'></script>
      </head>
    <body>
      <div class='main'>
        <canvas id='canvas'></canvas>
      </div>
    </body>
    </html>

    【讨论】:

    • 我不知道代码中发生了什么!该示例显示了我已经能够做的事情:将播放器指向鼠标。我需要的是被抵消的手。在玩家面前,左侧。这意味着玩家的角度将不同于手的角度。
    • 如果你摆脱了mousedown,那么cXcY可以放置在任何坐标。
    • 我需要计算手相对于玩家位置和旋转的 x 和 y 位置。如果玩家面向右侧,则手将指向玩家圈子所在“正方形”的左上角。
    • 您是否单击鼠标并四处移动?红线指向鼠标所在的位置。您应该能够根据给出的内容弄清楚。
    猜你喜欢
    • 2020-12-16
    • 2016-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-17
    • 2021-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多