我正在尝试重新制作游戏http://www.sinuousgame.com/并开始学习 html5画布和 kineticJS 。
最近我遇到了getIntersection函数,并且找到了很多关于它的细节。但是我用它做了一个代码,使用 getIntersection()函数完成碰撞检测。 但它似乎没有起作用。
如您所见,我的小提琴:http://jsfiddle.net/p9fnq/8/
//The working player code
var LimitedArray = function(upperLimit) {
var storage = [];
// default limit on length if none/invalid supplied;
upperLimit = +upperLimit > 0 ? upperLimit : 100;
this.push = function(item) {
storage.push(item);
if (storage.length > upperLimit) {
storage.shift();
}
return storage.length;
};
this.get = function(flag) {
return storage[flag];
};
this.iterateItems = function(iterator) {
var flag, l = storage.length;
if (typeof iterator !== 'function') {
return;
}
for (flag = 0; flag < l; flag++) {
iterator(storage[flag]);
}
};
};
var tail = new LimitedArray(50);
var flag = 0, jincr = 0;
var stage = new Kinetic.Stage({
container: 'container',
width: window.innerWidth,
height: window.innerHeight,
listening: true
});
var layer = new Kinetic.Layer({
listening: true
});
stage.add(layer);
var player = new Kinetic.Circle({
x: 20,
y: 20,
radius: 6,
fill: 'cyan',
stroke: 'black',
draggable: true
});
var line = new Kinetic.Line({
points: [],
stroke: 'cyan',
strokeWidth: 2,
lineCap: 'round',
lineJoin: 'round'
});
layer.add(line);
layer.add(player);
// move the circle with the mouse
stage.getContent().addEventListener('mousemove', function() {
player.position(stage.getPointerPosition());
var obj = {
x: stage.getPointerPosition().x,
y: stage.getPointerPosition().y
};
tail.push(obj);
var arr = [];
tail.iterateItems(function(p) {
arr.push(p.x, p.y);
});
line.points(arr);
});
var x = 0;
var y = 0;
var noOfEnemies = 200;
var enemyArmada = new Array();
createEnemy();
function createEnemy() {
for (var i = 0; i < noOfEnemies; i++) {
var enemy = new Kinetic.Circle({
x: Math.random() * window.innerWidth,
y: Math.random() * window.innerHeight,
radius: 4.5 + 1.5 * Math.random(),
fill: 'red',
stroke: 'black'
});
enemy.speedX = enemy.speedY = (0.5 + Math.random() * 50);
enemyArmada.push(enemy);
layer.add(enemy);
}
}
var checkCollide = function() {
var position = stage.getPointerPosition();
if(position == null)
position = player.position();
if(position == null)
position = {x:0,y:0};
var collided = stage.getIntersection(position);
console.log(position);
if (typeof collided !== 'Kinetic.Shape') {
console.log("not shape");
}
else {
console.log("BOOOM!!!");
}
};
var anim = new Kinetic.Animation(function(frame) {
checkCollide();
for (var i = 0; i < noOfEnemies; i++) {
var e = enemyArmada[i];
e.position({
x: e.position().x - e.speedX * (frame.timeDiff / 400),
y: e.position().y + e.speedY * (frame.timeDiff / 400)
});
if (e.position().y < 0 || e.position().x < 0) {
e.position({
x: (Math.random() * (window.innerWidth + 600)),
y: -(Math.random() * window.innerHeight)
});
}
}
}, layer);
anim.start();
我需要检测到碰撞。我在这里写的函数是 checkCollide ,并在 kinetic.Animation 函数中调用它。
任何人都可以帮我解决这个问题吗? (如果你不知道解决方案,请像帖子一样,我需要解决方案很糟糕)
答案 0 :(得分:2)
问题的根源
getIntersection(point)
表示“此时任何对象”。
由于您使用的是玩家的位置,getIntersection
将始终返回true,因为玩家总是处于自己的位置!
一个解决方案
将你的玩家放在一层,将所有敌人放在一个单独的层上。
这样你就可以在没有玩家对象干扰的情况下对敌人进行测试。
代码和演示:http://jsfiddle.net/m1erickson/JCfW8/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.0.1.min.js"></script>
<style>
body{padding:20px;}
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:350px;
height:350px;
}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 350,
height: 350
});
var enemyLayer = new Kinetic.Layer();
stage.add(enemyLayer);
var playerLayer = new Kinetic.Layer();
stage.add(playerLayer);
var player = new Kinetic.Circle({
x:100,
y:100,
radius: 10,
fill: 'green',
draggable: true
});
player.on("dragmove",function(){
if(enemyLayer.getIntersection(player.position())){
this.fill("red");
playerLayer.draw();
}
});
playerLayer.add(player);
playerLayer.draw();
var enemy = new Kinetic.Circle({
x:200,
y:100,
radius: 20,
fill: 'blue',
draggable: true
});
enemyLayer.add(enemy);
enemyLayer.draw();
}); // end $(function(){});
</script>
</head>
<body>
<h4>Drag the green player<br>Player will turn red if it collides<br>with the blue enemy</h4>
<div id="container"></div>
</body>
</html>
另一种解决方案
以数学方式测试玩家对抗每一个敌人:
警告:未经测试的代码 - 可能需要进行一些调整
function playerEnemyCollide(){
var playerX=player.x();
var playerY=player.y();
var playerRadius=player.radius();
for(var i=0;i<enemyArmada.length;i++){
var e=enemyArmada[i];
if(circlesColliding(playerX,playerY,playerRadius,e.x,e.y,e.radius)){
return(true);
}
}
return(false);
}
function circlesColliding(cx1,cy1,radius1,cx2,cy2,radius2){
var dx=cx2-cx1;
var dy=cy2-cy1;
return(dx*dx+dy*dy<(radius1*2+radius2*2);
}