如何使球反弹离开桨在正确的方向不是一条直线 [英] How to have ball bounce off paddle in right directions not as a straight line

查看:141
本文介绍了如何使球反弹离开桨在正确的方向不是一条直线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

原谅我的完全noobness在这里是非常新的JS。
我创建了一个非常简单的画布,一个矩形由keydownevents控制,一个只是在rAF的画布上移动。

Forgive my complete noobness here as very new to JS. I've created a really simple canvas with one rectangle being controlled by keydownevents and one just moving around the canvas in rAF.

我想现在有if移动的球击中用户的矩形碰撞和反弹,但以正确的角度反弹,它撞击不只是反向像我尝试和失败。

I want to now have if the moving ball hits the users rectangle to collide and bounce back but to bounce at the right angle that it hits not just in reverse like i have tried and failed at.

我知道我需要计算它打在用户rect,但我不知道从哪里开始或如何
有人可能指向我正确的方向或给我一个小片段做什么?

I know i need to calculate where it hits on the users rect, but I have no idea where to start or how Can someone point me in the right direction or give me a small snippet of what to do?

我不会需要空格的Keycode函数。

I'll leave out the Keycode functions for space as they're not needed.

function init() {

    canvas = document.getElementById("canvasdemo");
    ctx = canvas.getContext("2d");

    canvasWidth = canvas.width;
    canvasHeight = canvas.height;

    drawSquare();
}

function drawSquare() {

  ctx.clearRect(0, 0, canvasWidth, canvasHeight);
  // user controlled square
  ctx.fillStyle = "blue";
  ctx.fillRect(rect.x, rect.y, rect.w, rect.h);
  requestAnimationFrame(drawSquare); 


  if (rect.x + rect.vx > canvasWidth - 20 || rect.x + rect.vx < 0)
    rect.vx = -rect.vx;
  if (rect.y + rect.vy > canvasHeight - 20 || rect.y + rect.vy < 0)
    rect.vy = -rect.vy;

  rect.x += rect.vx;  
  rect.y += rect.vy;   

  // Moving Square 1 (left-right):

  requestAnimationFrame(squareTwo);

   if (dir1 == "right") {
      if (xpos < canvasWidth - 35) {
        xpos += 2;
      }else{
        dir1 = "left";
      }
    }

    if (dir1 == "left") {
      if (xpos>0) {
        xpos -= 2;
      }else{
        dir1 = "right";
      }
   }
}
// Second square
 function squareTwo() {

    ctx.fillStyle = "black";
    ctx.fillRect(xpos, ypos, 35, 35);
    ctx.fill();    
}


推荐答案

可以做反射 -

首先,根据底座角度将法线定义为向量:

First, define the normal as a vector based on the pads angle:

function getNormal(a) {
    return {
        x: Math.sin(a),    // this will be 90° offset from the
        y: -Math.cos(a)    // incoming angle
    }
}

然后使用点积来计算入向向量的入射角:

Then use dot-product to calculate the incident angle with the incoming vector:

function reflect(n, v) {
    var d = 2 * dot(v, n);   // calc dot product x 2
    v.x -= d * n.x;          // update vectors reflected by
    v.y -= d * n.y;          // normal using product d
    return v
}

// helper, calc dot product for two vectors
function dot(v1, v2) {
    return v1.x * v2.x + v1.y * v2.y
}

然后你需要一个命中测试来触发反射。当点击时,将法线上的向量反射到与焊盘成90°相切的法线上。

Then you need a hit-test to trigger the reflection. When hit, reflect the incoming vector on the normal which is 90° tangent to the pad.

一个演示/ ) 此处

A demo/fiddle that shows this in use ("proof-of-concept") can be found here.

这篇关于如何使球反弹离开桨在正确的方向不是一条直线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆