将玩家对象移向画布中的光标方向(slither.io样式)

时间:2018-12-13 23:42:41

标签: javascript canvas

我发现了类似的问题,但并不确切。我可以使用鼠标onclick来做到这一点,但是我不确定如何仅通过'mousemove'事件来处理它。

我目前的状况JSFiddle for example

我正在尝试使其移动播放器时,不仅将鼠标移动,还可以将屏幕向鼠标平移。但是我不知道该怎么办。

我有一个播放器对象,当鼠标移动时会更新。

function Player (x,y) {
    this.x = x;
    this.y = y;

    this.draw = function () {
        ctx.beginPath();
        ctx.arc(this.x,this.y,30,0,Math.PI * 2, false);
        ctx.fillStyle = 'black';
        ctx.fill();
    }

    this.update = function () {
        this.x = playerX;
        this.y = playerY;
        this.draw();
    }
}

此更新功能不允许恒定移动,但是当我尝试实现某些功能时,它最终会导致大量的滞后-显然,我采用了错误的方法。

此刻,我只是检测鼠标在屏幕中央的位置。

document.addEventListener('mousemove', (event) => {
    moveWorld(event);
});    

function moveWorld(e){
    var x = e.clientX;
    var y = e.clientY;
    // playerSpeed is 3
    var centerX = window.innerWidth / 2
    var centerY = window.innerHeight / 2
    // move south
    if (y < centerY) {
        ctx.translate (0,playerSpeed);
        playerY -= playerSpeed;        
    }
    // move e
    if (x < centerX) {
        ctx.translate (playerSpeed,0);
        playerX -=playerSpeed;
    } 
    // move north
    if (y > centerY) {
        ctx.translate (0,-playerSpeed);
        playerY += playerSpeed;
    }
    // move west
    if (x > centerX) {
        ctx.translate (-playerSpeed,0);
        playerX +=playerSpeed;
    }
    drawWorld();
}

最后渲染所有内容。

function drawWorld(){
    requestAnimationFrame(drawWorld); // refresh world

    //  CLEAR
    ctx.clearRect(0,0,innerHeight,innerHeight);

    // world
    ctx.fillStyle = 'red';
    ctx.fillRect(10, 10, 50, 50);
    ctx.fillRect(110, 30, 50, 50);

    // player
    player.update();

}
document.addEventListener('mousemove', (event) => {
    moveWorld(event);
});    

drawWorld();

3 个答案:

答案 0 :(得分:1)

  1. 假设鼠标位于屏幕中心
  2. 在mousemove上,更新鼠标坐标
  3. 使用最后一个已知的鼠标坐标作为方向,循环运行moveWorld

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

var playerX = canvas.width / 2;
var playerY = canvas.height / 2;

$(window).on("resize", function () {
    $("#login,#game,#canvas").width( $(this).width());
    $("#login,#game,#canvas").height( $(this).height());
    playerX = canvas.width / 2;
    playerY = canvas.height / 2;
}).resize();

var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var playerSpeed = 3;

var mouseX = centerX;
var mouseY = centerY;

function mouseUpdate(e) {
    mouseX = e.clientX;
    mouseY = e.clientY;
}

function moveWorld(){
    var x = mouseX;
    var y = mouseY;
    var centerX = window.innerWidth / 2
    var centerY = window.innerHeight / 2
    // move south
    if (y < centerY) {
        ctx.translate (0,playerSpeed);
        playerY -= playerSpeed;        
    }
    // move e
    if (x < centerX) {
        ctx.translate (playerSpeed,0);
        playerX -=playerSpeed;
    } 
    // move north
    if (y > centerY) {
        ctx.translate (0,-playerSpeed);
        playerY += playerSpeed;
    }
    // move west
    if (x > centerX) {
        ctx.translate (-playerSpeed,0);
        playerX +=playerSpeed;
    }
    drawWorld();
    requestAnimationFrame(moveWorld);
}

var player = new Player (playerX, playerY);
var counter = 0;


function drawWorld() {
    //  CLEAR
    ctx.clearRect(0,0,innerHeight,innerHeight);
    
    // world
    ctx.fillStyle = 'red';
    ctx.fillRect(10, 10, 50, 50);
    ctx.fillRect(110, 30, 50, 50);

    // player
    player.update();

}
document.addEventListener('mousemove', (event) => {
    mouseUpdate(event);
});    

requestAnimationFrame(moveWorld);

function Player (x,y) {
    this.x = x;
    this.y = y;
    
    this.draw = function () {
        ctx.beginPath();
        ctx.arc(this.x,this.y,30,0,Math.PI * 2, false);
        ctx.fillStyle = 'black';
        ctx.fill();
    }

    this.update = function () {
        this.x = playerX;
        this.y = playerY;
        this.draw();
    }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="canvas"></canvas>

答案 1 :(得分:0)

已更新

在您尝试开发Slither.io系统时,我假设您正在寻找Slither.io Clone制造的Loonride available on Github


您是否要实现以下目标? Phaser 3 : pointer - move event

var config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    scene: {
        preload: preload,
        create: create
    }
};

var game = new Phaser.Game(config);
var player = null;

function preload ()
{
    this.load.spritesheet('balls', 'https://labs.phaser.io/assets/sprites/balls.png', { frameWidth: 17, frameHeight: 17 });
}

function create ()
{
 player = this.add.image(0,0, 'balls', Phaser.Math.Between(0, 5));

    this.input.on('pointermove', function (pointer) {

        player.x = pointer.x;
        player.y = pointer.y;

    }, this);
}
<script src="//cdn.jsdelivr.net/npm/phaser@3.15.1/dist/phaser.min.js"></script>
<div id="phaser-example" style="overflow: hidden;"></div>

答案 2 :(得分:0)

做这种事情的正确方法是让浏览器使用window.requestAnimationFrame处理“帧滴答”。

这是我的小提琴:

https://jsfiddle.net/r5e2ht1v/4/

var mouseX, mouseY; 

document.addEventListener('mousemove', (event) => {
    mouseX = event.clientX; 
  mouseY = event.clientY; 
});    

function drawWorld(){

    //  CLEAR
    ctx.clearRect(0,0,innerHeight,innerHeight);

    // world
    ctx.fillStyle = 'red';
    ctx.fillRect(10, 10, 50, 50);
    ctx.fillRect(110, 30, 50, 50);

    // player
    player.update();
    moveWorld(); 

    window.requestAnimationFrame(drawWorld);

}

window.requestAnimationFrame(drawWorld); 

您可以在此处使用更多性能优化方法:

https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas