I've been building on top of an assignment we did in class and I'm stumped at the detection part.
我一直在建立在课堂上完成的任务之上,而且我对检测部分感到难过。
I want my Mew to be "caught" when he stands on top of the pokeball, the player moves the keyboard to control the Mew and the pokeball randomly repositions on a time delay.
我希望我的Mew能够被“抓住”,当他站在pokeball的顶部时,玩家移动键盘来控制Mew,并且pokeball随机地重新定位时间延迟。
How can I create a function that will detect when the mew.gif is in overlap with the pokeball?
如何创建一个能够检测mew.gif何时与pokeball重叠的函数?
var _stage = document.getElementById("stage");
var _Mew = document.querySelector("img");
var _PokeBall = document.getElementById("PokeBall");
_stage.style.width = "800px";
_stage.style.height = "600px";
_stage.style.backgroundColor = "black";
_stage.style.marginLeft = "auto";
_stage.style.marginRight = "auto";
_Mew.style.position = "relative"; // Uses top and left from parent
_PokeBall.style.position = "relative"; // Uses top and left from parent
var leftPressed = false;
var rightPressed = false;
var upPressed = false;
var downPressed = false;
var player = [ 400, 300 ]; // Left, Top
var PokeBall = [100, 100];// Top, Left
var uIval = setInterval(update, 22.22); // 30fps update loop
var map = []; // empty Map Array
window.addEventListener("keydown", onKeyDown);
window.addEventListener("keyup", onKeyUp);
var Pval= setInterval(MovePokeball, 2000);
function generateMap()
{
for (var row = 0; row < 2; row++)
{
for(var col = 0; col <8; col++)
{
console.log("In row "+row);
}
}
}
/*map[row] = []; // Creating new array in specified row
for (var col = 0; col <8; col++)
{
console.log("In row "+row+"doing col"+col);
}
*/
function onKeyDown(event)
{
switch(event.keyCode)
{
case 37: // Left.
if ( leftPressed == false )
leftPressed = true;
break;
case 39: // Right.
if ( rightPressed == false )
rightPressed = true;
break;
case 38: // Up.
if ( upPressed == false )
upPressed = true;
break;
case 40: // Down.
if ( downPressed == false )
downPressed = true;
break;
default:
console.log("Unhandled key.");
break;
}
}
function onKeyUp(event)
{
switch(event.keyCode)
{
case 37: // Left.
leftPressed = false;
break;
case 39: // Right.
rightPressed = false;
break;
case 38: // Up.
upPressed = false;
break;
case 40: // Down.
downPressed = false;
break;
default:
console.log("Unhandled key.");
break;
}
}
function update() // Going to run 30fps
{
movePlayer();
// move enemies
// collision check
// animate sprites
PlayerCaught();
render();
}
function movePlayer()
{
if ( leftPressed == true && player[0] >= _Mew.width/2)
player[0] -= 10;
if ( rightPressed == true && player[0] < 800 - _Mew.width/2)
player[0] += 10;
if ( upPressed == true && player[1] >= _Mew.height/2 )
player[1] -= 10;
if ( downPressed == true && player[1] < 600 - _Mew.width/2)
player[1] += 10;
}
function render()
{
_Mew.style.left = player[0]-_Mew.width/2+"px";
_Mew.style.top = player[1]-_Mew.width/2+"px";
}
function PlayerCaught()
{
if (_PokeBall [100,100] = player [100,100])
window.alert("Mew Has Been Captured!")
}
function MovePokeball()
{
_PokeBall.style.left= Math.floor(Math.random()*801)+"px";
_PokeBall.style.top= Math.floor(Math.random()*601)+"px";
}
1 个解决方案
#1
0
You're asking about collision detection. This is done by determining if two polygons intersect. Since your program is very simplified, I'm offering a very simplified solution. We're going to determine if the graphics intersect. This is not the ideal way to do it. Normally, graphics and physics are completely separated. But this will work (mostly), and hopefully it'll encourage you to continue to experiment.
你问的是碰撞检测。这是通过确定两个多边形是否相交来完成的。由于您的程序非常简单,我提供了一个非常简化的解决方案。我们将确定图形是否相交。这不是理想的做法。通常,图形和物理完全分开。但这会(大多数情况下)起作用,希望它会鼓励你继续尝试。
First, we need the height and width of both images so we can do our geometric magic. This can be easily set in JavaScript, just like you did for _stage
. However, you've already defined the src
of your images elsewhere (probably in HTML), so it would be best to define the height and width there.
首先,我们需要两个图像的高度和宽度,以便我们可以做几何魔术。这可以在JavaScript中轻松设置,就像您为_stage所做的那样。但是,您已经在其他地方(可能是HTML)中定义了图像的src,因此最好在那里定义高度和宽度。
HTML Example:
<img id="PokeBall" src="pokeball.png" style="width:50px; height:50px" />
Note: This uses "inline CSS" which is another bad practice. But this works, and I don't want to overcomplicate simple things right now.
注意:这使用“内联CSS”,这是另一种不好的做法。但这很有效,我现在不想让简单的事情过于复杂。
Now your PlayerCaught
method has all the information it needs to do it's job, so how do we detect collisions? If we're working with rectangles, it's very simple. We just determine if any of the corners of one object are inside the other object. So how do we do that? Basically, we see if they intersect on both the X and Y axes.
现在你的PlayerCaught方法拥有完成它所需的所有信息,那么我们如何检测碰撞呢?如果我们使用矩形,那很简单。我们只确定一个对象的任何角落是否在另一个对象内。那我们怎么做呢?基本上,我们看它们是否在X轴和Y轴上相交。
Take two rectangles: A
and B
. Both have four edges: top
, left
, right
, and bottom
. The edges top
and bottom
are Y values, and the edges left
and right
are X values. The two rectangles intersect if any of the following is true:
取两个矩形:A和B.两个都有四条边:顶部,左侧,右侧和底部。顶部和底部的边缘是Y值,左边和右边是X值。如果满足以下任何条件,则两个矩形相交:
(
A.left < B.left < A.right
OR A.left < B.right < A.right
) AND (
A.top < B.top < A.bottom
OR A.top < B.bottom < A.bottom
)
Translate that into JavaScript and you've got your collision detection function. To get the edges in your program, use the following:
将其转换为JavaScript,您就拥有了碰撞检测功能。要获得程序的优势,请使用以下命令:
function findEdges(img){
var result = [];
result["left"] = parseInt(img.style.left, 10);
result["top"] = parseInt(img.style.top, 10);
result["right"] = result["left"] + parseInt(img.style.width, 10);
result["bottom"] = result["top"] + parseInt(img.style.height, 10);
return result;
}
You can see that we are using the inline style that we set earlier for the width
and height
as well as the top
and left
you are already using for rendering.
您可以看到我们正在使用我们之前为宽度和高度设置的内联样式以及您已经用于渲染的顶部和左侧。
SPOILER...
Putting all the pieces together might look like:
将所有部分放在一起可能看起来像:
function PlayerCaught(){
if (detectImgCollision(_PokeBall, _Mew)){
window.alert("Mew Has Been Captured!")
}
}
function detectImgCollision(imgA, imgB){
var A = findEdges(imgA);
var B = findEdges(imgB);
return detectRectCollision(A, B);
}
function detectRectCollision(A, B){
return (
isBetween(A.left, B.left, A.right)
|| isBetween(A.left, B.right, A.right)
) && (
isBetween(A.top, B.top, A.bottom)
|| isBetween(A.top, B.bottom, A.bottom)
);
}
function isBetween(low, middle, high){
return (low <= middle && middle <= high);
}
#1
0
You're asking about collision detection. This is done by determining if two polygons intersect. Since your program is very simplified, I'm offering a very simplified solution. We're going to determine if the graphics intersect. This is not the ideal way to do it. Normally, graphics and physics are completely separated. But this will work (mostly), and hopefully it'll encourage you to continue to experiment.
你问的是碰撞检测。这是通过确定两个多边形是否相交来完成的。由于您的程序非常简单,我提供了一个非常简化的解决方案。我们将确定图形是否相交。这不是理想的做法。通常,图形和物理完全分开。但这会(大多数情况下)起作用,希望它会鼓励你继续尝试。
First, we need the height and width of both images so we can do our geometric magic. This can be easily set in JavaScript, just like you did for _stage
. However, you've already defined the src
of your images elsewhere (probably in HTML), so it would be best to define the height and width there.
首先,我们需要两个图像的高度和宽度,以便我们可以做几何魔术。这可以在JavaScript中轻松设置,就像您为_stage所做的那样。但是,您已经在其他地方(可能是HTML)中定义了图像的src,因此最好在那里定义高度和宽度。
HTML Example:
<img id="PokeBall" src="pokeball.png" style="width:50px; height:50px" />
Note: This uses "inline CSS" which is another bad practice. But this works, and I don't want to overcomplicate simple things right now.
注意:这使用“内联CSS”,这是另一种不好的做法。但这很有效,我现在不想让简单的事情过于复杂。
Now your PlayerCaught
method has all the information it needs to do it's job, so how do we detect collisions? If we're working with rectangles, it's very simple. We just determine if any of the corners of one object are inside the other object. So how do we do that? Basically, we see if they intersect on both the X and Y axes.
现在你的PlayerCaught方法拥有完成它所需的所有信息,那么我们如何检测碰撞呢?如果我们使用矩形,那很简单。我们只确定一个对象的任何角落是否在另一个对象内。那我们怎么做呢?基本上,我们看它们是否在X轴和Y轴上相交。
Take two rectangles: A
and B
. Both have four edges: top
, left
, right
, and bottom
. The edges top
and bottom
are Y values, and the edges left
and right
are X values. The two rectangles intersect if any of the following is true:
取两个矩形:A和B.两个都有四条边:顶部,左侧,右侧和底部。顶部和底部的边缘是Y值,左边和右边是X值。如果满足以下任何条件,则两个矩形相交:
(
A.left < B.left < A.right
OR A.left < B.right < A.right
) AND (
A.top < B.top < A.bottom
OR A.top < B.bottom < A.bottom
)
Translate that into JavaScript and you've got your collision detection function. To get the edges in your program, use the following:
将其转换为JavaScript,您就拥有了碰撞检测功能。要获得程序的优势,请使用以下命令:
function findEdges(img){
var result = [];
result["left"] = parseInt(img.style.left, 10);
result["top"] = parseInt(img.style.top, 10);
result["right"] = result["left"] + parseInt(img.style.width, 10);
result["bottom"] = result["top"] + parseInt(img.style.height, 10);
return result;
}
You can see that we are using the inline style that we set earlier for the width
and height
as well as the top
and left
you are already using for rendering.
您可以看到我们正在使用我们之前为宽度和高度设置的内联样式以及您已经用于渲染的顶部和左侧。
SPOILER...
Putting all the pieces together might look like:
将所有部分放在一起可能看起来像:
function PlayerCaught(){
if (detectImgCollision(_PokeBall, _Mew)){
window.alert("Mew Has Been Captured!")
}
}
function detectImgCollision(imgA, imgB){
var A = findEdges(imgA);
var B = findEdges(imgB);
return detectRectCollision(A, B);
}
function detectRectCollision(A, B){
return (
isBetween(A.left, B.left, A.right)
|| isBetween(A.left, B.right, A.right)
) && (
isBetween(A.top, B.top, A.bottom)
|| isBetween(A.top, B.bottom, A.bottom)
);
}
function isBetween(low, middle, high){
return (low <= middle && middle <= high);
}