【问题标题】:Canvas: Drag and Drop Images画布:拖放图像
【发布时间】:2020-11-01 04:04:32
【问题描述】:

所以我对 javascript 比较陌生。作为一个学校项目,我们必须使用 HTML、CSS 和 Javascript 编写游戏。

所以我想对新超级马里奥兄弟 Ds 中的 Sort 或“Splode”游戏进行廉价的重现。

我已经对炸弹的随机生成进行了编程,并对炸弹的运动进行了动画处理。如果它们在中间区域(它们产生的地方)太长,就会爆炸。

但我还没有对爆炸进行编程。我想先对拖放进行编程。我只想拖放炸弹。就这么简单,剩下的我想我可以自己做。

我搜索了一个教程,发现这个网页:https://html5.litten.com/how-to-drag-and-drop-on-an-html5-canvas/

我在我的游戏中重新创建了这个,但它不起作用......

抱歉我的代码不好。有人可以向我解释一下该怎么做吗?

最好, 塞巴斯蒂安

enter image description here

<!DOCTYPE html>
<html>
<head>
<title>BOMB-Sorter</title>

<style>
canvas {
    background-color:#fff;
    border:7px solid #000;
    border-radius: 5px;
    display: inline;
    background-image: url("img/background.jpg");
    background-size: cover;
}

body{
    display: flex;

    justify-content: center;
    align-items: center;

}


</style>
<script>

class GraphObj {

  constructor(x, y, w, h, c, x_vel, y_vel, t, d) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.c = c;
    this.x_vel = x_vel;
    this.y_vel = y_vel;
    this.t = t;
    this.d = d;
  }

  info() {
    return "\ngraphical object: x="+this.x + ", y="+this.y+", w="+this.w+", h="+this.h+", h="+this.c;
  }
}


// Declaration of Lists
var bList = null; // List of Bombs
var xlist = null;
var ylist = null;

var ref_time=0; // Reference Time
var lives = 10;
var score = 0;

var dragok = false;

var c = document.getElementById("myCanvas");



function drawGrid(ele,ctx){ // declaration of a new function
    
    ctx.globalAlpha = 0.5;
    ctx.fillStyle = "#ff9999";
    ctx.fillRect(0,0,ele.width/3,ele.height)

    ctx.fillStyle = "#60615a";
    ctx.fillRect(2* (ele.width/3),0,ele.width/3,ele.height)

    ctx.globalAlpha = 1;
    ctx.setLineDash([25, 15]);
    ctx.moveTo(ele.width/3 +1,0);
    ctx.lineTo(ele.width/3 +1, ele.height);

    ctx.moveTo(2*(ele.width/3 -1),0);
    ctx.lineTo(2*(ele.width/3 - 1), ele.height);
    ctx.lineWidth = 10;
    ctx.strokeStyle = "#f5f242";
    ctx.stroke();
}

function drawAll()
{
    var ele = document.getElementById("myCanvas");
    var ctx = ele.getContext("2d");
    
    ele.width = ele.width; // clear everything!

    drawGrid(ele,ctx); // call the function ...
    
    var bombb = document.getElementById("bombb");
    var bombr = document.getElementById("bombr");
    var bombr_step = document.getElementById("bombr_step");
    var bombb_step = document.getElementById("bombb_step");
    var bombw = document.getElementById("bombw");

    // draw bombs
    for (var i=0; i<bList.length; i++)
    {
        var o = bList[i];
        if(o.c == 0 && o.t != 8 && o.t != 10 ){
            ctx.drawImage(bombr, o.x,o.y,o.w,o.h);
            draggable: true;
        }

        if(o.c == 1 && o.t != 8 && o.t != 10 ){
            ctx.drawImage(bombb, o.x,o.y,o.w,o.h);
            draggable: true;
        }

        if(o.c == 2 && o.t != 8 && o.t != 10 ){
            ctx.drawImage(bombr_step, o.x,o.y,o.w,o.h);
            draggable: true;
        }

        if(o.c == 3 && o.t != 8 && o.t != 10 ){
            ctx.drawImage(bombb_step, o.x,o.y,o.w,o.h);
            draggable: true;
        }

        if(o.t == 10 || o.t == 8){
            ctx.drawImage(bombw, o.x,o.y,o.w,o.h);
            draggable: true;
        }


    }
    
    // draw lives
    ctx.font = "normal small-caps 70px Minecraft";
    ctx.fillStyle = "red";
    ctx.fillText(+lives, ele.width - 105, 70);

    // draw score
    ctx.font = "normal small-caps 70px Minecraft";
    ctx.fillStyle = "black";
    ctx.fillText(+score, 20, 70);

}

function positionCheck(i, ele){
        if(bList[i].x < ele.width/3){
            bList[i].x_vel = bList[i].x_vel * (-1);
        }
        else if(bList[i].x > 2*(ele.width/3) -64){
            bList[i].x_vel = bList[i].x_vel * (-1);
        }
        else if(bList[i].y < 0){
            bList[i].y_vel = bList[i].y_vel * (-1);
        }
        else if(bList[i].y > ele.height -64){
            bList[i].y_vel = bList[i].y_vel * (-1);
        }
}

function animateStep(){
    
    for(var i = 0;i < bList.length; i++){

            if(bList[i].c == 0){
                bList[i].c = 2;
                bList[i].t++;
            }
            else if(bList[i].c == 1){
                bList[i].c = 3;
                bList[i].t++;
            }
            else if(bList[i].c == 2){
                bList[i].c = 0;
            }
            else if(bList[i].c == 3){
                bList[i].c = 1;
            }   

            else if(bList[i].t == 8){
            bList[i].c = 4;
            }

            else if(bList[i].t == 10){
            bList[i].c = 4;
            }

    }
}

function functimer(){

    var ele = document.getElementById("myCanvas");
    
    // create new bomb every s
    if (Date.now() - ref_time >= 1000)
    {
        // random number between 0 and ele.width
        var pos_x = Math.floor(Math.random() * (ele.width/3 - 64)) + (ele.width/3 +1); 

        //random height
        var pos_y = Math.floor(Math.random() * (ele.height - 70) -1);

        //random color
        var color = Math.round(Math.random());
        
        //random x velocity
        var x_vel = Math.ceil(Math.random() * 2) * (Math.round(Math.random()) ? 1 : -1);

        //random y velocity
        var y_vel = Math.ceil(Math.random() * 2) * (Math.round(Math.random()) ? 1 : -1);

        var t = 0;

        var o = new GraphObj(pos_x,pos_y,64,64, color, x_vel, y_vel, t); // create new bomb
        bList.push(o);

        animateStep();

        ref_time = Date.now();
    }
    
    var xlist = null;
    xlist = new Array();

    var ylist = null;
    ylist = new Array();


    // move bombs
    for (var i=0; i<bList.length; i++)
    {
        bList[i].y += bList[i].y_vel;
        bList[i].x += bList[i].x_vel;
        positionCheck(i, ele);
    }

    drawAll();
    requestAnimationFrame(functimer); // draw everything BEFORE screen update
    
}

function myMove(i,e){
    if(dragok == true){
        bList[i].x = e.pageX - c.offsetLeft;
        bList[i].y = e.pageY - c.offsetTop;
    }
}


function myDown(e){
    for(var i = 0; i < bList.lenght; i++){
        if(e.pageX < bList[i].x + 64 + c.offsetLeft && e.pageX > bList[i].x + c.offsetLeft && e.pageY < bList[i].y + 64 + c.offsetTop && e.pageY > bList[i].y + c.offsetTop){

            bList[i].x = e.pageX - c.offsetLeft;
            bList[i].y = e.pageY - c.offsetTop;
            bList[i].x_vele = 0;
            bList[i].y_vel = 0;
            dragok = true;
            c.onmousemove = myMove(i,e);
        }
    }
}

function myUp(){
    dragok = false; 
}

function start() {
    // create lists
    
    bList = new Array();
    
    var c = document.getElementById("myCanvas");
    c.setAttribute('tabindex','0');
    c.focus();
    c.onmousedown = myDown;
    c.onmouseup = myUp;

    var xlist = null;
    xlist = new Array();

    var ylist = null;
    ylist = new Array();

    drawAll();
    requestAnimationFrame(functimer); // draw everything BEFORE screen update

    
}

</script>

</head>

<body onload="start()">

<img id="bombb" src="img/bombb.png" alt="x" style="display: none;">
<img id="bombr" src="img/bombr.png" alt="y" style="display: none;">
<img id="bombr_step" src="img/bombr_step1.png" alt="y" style="display: none;">
<img id="bombb_step" src="img/bombb_step.png" alt="y" style="display: none;">
<img id="bombw" src="img/bombw.png" alt="y" style="display: none;">

<div>
<canvas id="myCanvas" width="1000" height="600"></canvas>
</div>

</body>

</html>

【问题讨论】:

  • 嗨,你的炸弹不是矩形的,它们有很多而且它们重叠。您知道如何判断一枚炸弹是否(部分)在另一枚炸弹之上吗?是否有某种堆叠顺序?
  • @AHaworth 我不知道,这是个问题。我认为,因为也有一个被绘制在另一个上,所以它会自动选择在另一个上绘制的炸弹。
  • 嗨,我认为代码所做的是查看鼠标是否在炸弹的矩形内,如果是,则选择它,所以如果点击它,部分后面的炸弹将不会被选中该矩形内的部分。这对您的游戏可能无关紧要,我不知道规则是什么,但我希望在几个小时内仔细研究一下,以便更好地了解需要什么。
  • 另一件需要仔细观察的事情是声明的地方——它们的范围是什么。例如,您在 start 函数中声明了一个变量“c”,但由于作用域不同,它与某些函数中使用的 c 不同。
  • 如果你从函数 start() 中的 var c = .... 之前删除 'var',你将始终使用全局 c,这至少意味着我们开始看到一些动作我们试图拖动炸弹。你能描述一下当炸弹被拖走时你想要发生的事情吗?它应该去哪里?

标签: javascript html css canvas


【解决方案1】:

这不是一个完整的答案,因为我不确切知道拖动炸弹时需要什么,但这里有几个地方可以进行更改以帮助进一步调试:

canvas 元素 'c' 在两个地方声明,因此当它用于 mousedown 等时,它是未定义的,一个具有更多本地范围的元素已在 start 函数中设置。我建议在 start 函数中使用 c 之前删除“var”,以便选择具有全局范围的变量。

一般来说,通过代码查看事物的定义位置以及是否处于最佳位置 - 查看所有变量的范围。这方面的代码几乎是可以的,例如你知道你不能在画布上绘制一个 img 直到它被下载,但一些事情可以做整理。

'length' (lenght) 有一个拼写错误,这意味着函数无法工作。

通常使用浏览器的开发工具控制台来确保您没有任何未声明或看起来像 null 等的内容。此类 Javascript 错误将显示在那里。还要在战略点使用 console.log 以确保您了解逻辑流程。在 main 函数的开头以 console.log('at function xxx') 开始可能会有用。然后,您可以查看例如在炸弹上鼠标按下/向上的顺序。

如果您可以进一步描述拖动炸弹时会发生什么,那将很有用。在这里为了完整起见,我重申我在评论中所说的,炸弹将被视为矩形 - 从拖动的角度来看,它们后面的炸弹会变得模糊 - 这对您的应用程序可能很重要,也可能无关紧要。如果它很重要,有办法绕过它,但最好先理清基础知识。

【讨论】:

  • 感谢您的 cmets 和回答。首先,很抱歉我迟到的回复。我正在解决另一个问题。基本上我对游戏“Sort a Splode”youtube.com/watch?v=A6c9iqOvDWU 进行编程,只是没有花哨的动画和 co。
  • 所以我在画布上绘制了 3 个扇区。目标是在爆炸之前将红色炸弹拖到红色站点,将黑色炸弹拖到黑色站点。当它们停留在中间部分(它们产生并四处移动的地方)时,它们会在一段时间后爆炸——我创建了爆炸动画,现在我做了一些改变。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-07
  • 1970-01-01
  • 2014-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多