HTML5游戏 - 行走边界问题

时间:2013-01-22 23:10:59

标签: javascript html5 position collision boundary

我正在做一个自上而下的射手,基本上这个角色从屏幕中间开始,在一个矩形(安全区)内。角色不是静态的,场景是。他可以在安全区内走来走去。一旦角色走出这个区域,静态切换......角色是静止的,场景在他周围移动。

唯一的问题是我不能走回安全区,让我的静力学再次切换。

所以我永远被困在了区域之外。我正在做的就是检查我的角色位置是否在某个值内(即矩形),如果他已经出局 - 那么我的KeyControls会影响Map,而不是角色。

所以这是我的边界(安全区)检查器:

//Walking Window Boundaries
    var boundarySizeX = 400;
    var boundarySizeY = 200;

    ctxWalkBoundary.fillStyle = "grey";
    ctxWalkBoundary.fillRect(gameWidth/2 - boundarySizeX/2, gameHeight/2 - boundarySizeY/2, boundarySizeX, boundarySizeY);
    ctxWalkBoundary.clearRect((gameWidth/2 - boundarySizeX/2) + 2, (gameHeight/2 - boundarySizeY/2) + 2, (boundarySizeX) - 4, (boundarySizeY) -4 );

    var paddingLeft = (gameWidth - boundarySizeX) / 2;
    var paddingRight = gameWidth - ((gameWidth - boundarySizeX) / 2) - this.charWidth;
    var paddingTop = (gameHeight - boundarySizeY) / 2;
    var paddingBottom = gameHeight - ((gameHeight - boundarySizeY) / 2) - this.charHeight;

    var paddingY = (gameHeight - boundarySizeY) / 2;

    if(this.drawX > paddingLeft && this.drawX < paddingRight && this.drawY > paddingTop && this.drawY < paddingBottom){
        inBoundary = true;
    }
    else{
        inBoundary = false;
        console.debug("Out Of Boundary!");
    }

这是我的KeyChecker:

//UP
    if(this.isUpKey){

        //Character movement
        if(inBoundary){
            this.drawX = this.drawX + this.speed * Math.cos((this.characterRotation));
            this.drawY = this.drawY + this.speed * Math.sin((this.characterRotation));
        }
        else{
            mapPositionX = mapPositionX - this.speed * Math.cos((this.characterRotation));
            mapPositionY = mapPositionY - this.speed * Math.sin((this.characterRotation));
        }

我的角色总是面向我的鼠标(旋转)。因此,每次用户按下W或Up时,角色将始终朝着鼠标位置移动。

我有什么想法可以回到这个区域吗?

-----更新-----

我想我需要以某种方式检查我是否仍然面对安全区以外 - 如果没有,那么反过来静态。

2 个答案:

答案 0 :(得分:0)

这里的问题是你等待角色走出界限,然后移动地图。但是国旗已经被绊倒了,现在无论你走向何方,角色运动都是静止的,因为你已经超出界限。

您可以改为检测角色何时越过边界并通过移动地图来阻止它:

//UP
if(this.isUpKey){

// save the x and y offset to prevent needless recalculation
var xOffset = this.speed * Math.cos(this.characterRotation),
    yOffset = this.speed * Math.sin(this.characterRotation);

    //Character movement
    if( boundaryCheck(xOffset, yOffset) ){
        this.drawX = this.drawX + xOffset;
        this.drawY = this.drawY + yOffset;
    }
    else{
        mapPositionX = mapPositionX - xOffset
        mapPositionY = mapPositionY - yOffset;
    }

然后boundaryCheck获取x和y delta,并确定它们是否仍处于边界内。如果角色仍然在界限中,return true并且角色将移动,否则地图将移动。

function boundaryCheck(xOffset, yOffset){
// variables set and other stuff done...
    if(this.drawX + xOffset > paddingLeft && this.drawX + xOffset < paddingRight && this.drawY + yOffset > paddingTop && this.drawY + yOffset < paddingBottom){
       return true;
    }
    else{
        console.debug("Out Of Boundary!");
        return false;
    }

};

这样你就不必弄清楚越界角色是否正在向边界移动。相反,你预先确定角色的去向,并相应地调整,始终保持他的边界。

如果没有完整的代码,这当然是不可测试的,但我认为它应该适用于您所提供的内容。

答案 1 :(得分:0)

只需分开两件事:地图和视图。

地图是你的等级,你用坐标保存物体。 视图是您在屏幕上看到的地图的一部分。 View有4个属性:x,y,widht和height,其中widht和height最有可能是你的画布大小。

如果您的游戏以屏幕中间的地图点(0,0)的视图开始,则您的视图(x,y)坐标应为(-view.width / 2,-view.height / 2)。

如何在视图中绘制角色和对象?

首先,只绘制视图矩形中的内容。 因此,遍历所有对象并检查是否

object.x >= view.x && object.x <= view.x + view.width && object.y >= view.y && object.y <= view.y + view.height

(您可能也应考虑对象边界)。

如果对象在视图区域中,则在位置(object.x - view.x, object.y - view.y)处绘制它。 而这一切都与绘画有关。

与他一起移动角色和视图区域。

现在,当你的角色与边界碰撞时,例如(与右边界碰撞)

character.x >= view.x + view.width

然后通过使用某个值(可能是character.width / 2)递增view.x来向右移动视图。

- 更新 -

我看到你在游戏中没有使用OOP(实际上你是因为JS中的所有内容都是一个对象,但你没有故意使用它)。

JS中的OOP有很多解释,所以我会尽量缩短它。

您可以使用JSON格式制作角色,地图和视图等对象。

character = {
    x: 0,
    y: 0,
    xspeed: 0,
    yspeed: 0,
    speed: 0,
    radius: 20,
}

map = {
    objects: [
        {sprite: 'tree.jpg', x: 100, y: 50},
        {sprite: 'stone.jpg', x: 20, y: 30},
    ],
}

view = {
    width: canvas.width,
    height: canvas.height,
    x: -this.width/2,
    y: -this.height/2,
}

这些是你可以在你的函数中使用的对象:

for (var i=0; i++, i<map.objects.length) {
    if (map_obj.x >= view.x && map_obj.x <= view.x + view.width && map_obj.y >= view.y && map_obj.y <= view.y + view.height) {
        var map_obj = map.objects[i];
        draw_sprite(map_obj.sprite, map_obj.x - view.x, map_obj.y - view.y);
    }
}

这不是最好的方式,但它现在仍然比你的好多了。当你了解OOP是什么时,你会更好地为自己做好准备。