javascript - 如何在街机游戏中实现环绕效果?

标签 javascript jquery animation graphics 2d-games

我正在开发游戏的克隆版太空 war !。在游戏中,船只可以行驶到 map 的边缘并绕到另一侧,有时会分成两半,屏幕的每一侧各有一半(当船只进入 Angular 落时,它们会分成四部分)。可以玩游戏here

现在我正在使用模数运算符将 div 包裹在屏幕周围,但它不会像我希望的那样将 block 分成两半。有什么方法可以在 JavaScript 或 jQuery 中实现这一点吗?

最佳答案

包裹 Sprite

您提供的有趣链接。他们实现了完整的 CPU 模拟并运行用汇编语言编写的游戏。

改进模数

无论如何,如果您使用 Canvas 来渲染 Sprite (图像),最简单的方法是使用简单的模数并进行修改以处理负值。

使用负值时,正常模数会崩溃。

x = 100 % 200; // 100
x = 300 % 200; // 100 
x = -100 % 200; // -100  the wrong sign should be 100
x = -50 % 200;  // -50 wrong sign wrong direction should be 150

您需要模数始终以正确的方向返回正值。要处理负数,请执行两次取模操作,第一次将在您想要的范围内但+/-范围内。然后通过添加范围将负值变成正值。然后再次进行模运算。

var range = 200;
var x = 150;
x = ((x % range) + range) % range; // result 150
x = -50;
x = ((x % range) + range) % range; // result 150 correct.

简单包装

使用上述模算法,检查边界并根据需要渲染 Sprite 就变得很简单。

// assuming ctx is canvas context 2D
// canvas is the canvas.
// img is a HTMLImageElement

var canW = canvas.width;                               // the canvas size
var canH = canvas.height;                              
// draw a sprite that is wrapped around the edges of the canvas
function drawWrappedSprite(img,x,y){
    x1 = ((x % canW) + canW) % canW;                   // wrap around correcting for negative values
    y1 = ((y % canH) + canH) % canH;
    x2 = x1 + img.width;                               // get right and bottom
    y2 = y1 + img.height;
    ctx.drawImage(img, x1, y1);                        // draw first copy
    if(x2 > canW){                                     // check if touching right side
        ctx.drawImage(img, x1 - canW, y1);             // draw left copy
        if(y2 > canH){                                 // check if touching bottom
            ctx.drawImage(img, x1 - canW, y1 - canH);  // draw top copy
        }
    }
    if(y2 > canH){
        ctx.drawImage(img, x1 , y1 - canH);            // draw top copy
    }
}

包裹旋转的 Sprite

由于游戏中有旋转的 Sprite ,因此上述功能将不起作用,因为旋转会改变 Sprite 的大小。要处理旋转的 Sprite ,您需要检查它的最大尺寸。这是穿过 Sprite 的对 Angular 线的长度,可以通过 sqrt(width * width + height * height)

找到

假设您希望 Sprite 绕其中心旋转,您可以通过减去并添加 x,y 中心位置的一半对 Angular 线来找到 Sprite 最大范围(顶部、底部、左侧和右侧)。就像第一个函数一样,根据需要进行取模并绘制 Sprite 。

在某些情况下,即使 Sprite 不可见,也会被绘制在相反的一侧。如果您要绘制大量 Sprite (100+),您可能想要获得准确的范围而不是最大范围,但随后您必须至少变换 Sprite 的一个 Angular 才能获得水平和垂直范围。然后只需使用这些值,而不是像函数中那样使用 diag

// assuming ctx is canvas context 2D
// canvas is the canvas.
// img is a HTMLImageElement

var canW = canvas.width;                               // the canvas size
var canH = canvas.height;  
// draws sprite rotated about its center by r
function drawWrappedRotatedSprite(img,x,y,r){  // x,y center pos, r rotation in radians
    var diag = Math.sqrt(img.width * img.width + img.height * img.height);  // get diagonal size
    diag /= 2;                                      // half the diagonal
    x1 = (((x - diag) % canW) + canW) % canW;       // get left extent position  and 
    y1 = (((y - diag) % canH) + canH) % canH;       // wrap around correcting for negative values
    var w = - img.width / 2;                        // get image width height
    var h = - img.height / 2                        // offset in rotated space
    x2 = x1 + diag * 2;                             // get right and bottom max extent
    y2 = y1 + diag * 2;
    ctx.setTransform(1,0,0,1,x1 + diag, y1 + diag); // set origin
    ctx.rotate(r);                                  // set rotation
    ctx.drawImage(img, w, h);                      // draw image rotated around its center    
    if(x2 > canW){                                  // check if touching right side
        ctx.setTransform(1,0,0,1,x1 + diag - canW, y1 + diag); // set origin
        ctx.rotate(r);                              // set rotation
        ctx.drawImage(img,w,h);                     // draw image rotated around its center    
        if(y2 > canH){                              // check if touching bottom
            ctx.setTransform(1,0,0,1,x1 + diag - canW, y1 + diag - canH); // set origin
            ctx.rotate(r);                          // set rotation
            ctx.drawImage(img,w,h);                 // draw image rotated around its center    
        }
    }
    if(y2 > canH){
        ctx.setTransform(1,0,0,1,x1 + diag, y1 + diag - canH); // set origin
        ctx.rotate(r);                              // set rotation
        ctx.drawImage(img,w,h);                     // draw top image rotated around its center    
    }

    ctx.setTransform(1,0,0,1,0,0); // reset the transform (should only do this after all sprites
                                   // using this function have been drawn 
}

关于javascript - 如何在街机游戏中实现环绕效果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39606123/

相关文章:

javascript - 如何为react-big-calendar(fullcalendar.js)设置momentLocalizer(moment.js)?

javascript - Div 的 Jquery 事件 onChange

jquery - 在 jQuery 中延迟按键输入的 ajax 调用

jquery - 上下滑动导航 JQuery 问题

ios - 在没有观察者的情况下检测 iOS 应用程序移至后台

javascript - jQuery val 函数不适用于隐藏字段?

php - jQuery 效率低下?

javascript - 在使用 jQuery 提交表单之前更改输入值

iOS SDK : How to cause view to flip when switching cameras

iphone - 优化 Core Graphics 动画绘图 (iPhone)