警报前填写 canvas

Fill canvas before alert

对于 canvas 游戏,如何在 window 警报之前加载 canvas 填充和文本?哪怕只有几毫秒。

两名玩家发生碰撞。 紧接着,canvas 应填充为颜色并应显示文本。

问题是在发生这种情况之前出现警报。

警报,当按下确定时,应该重新加载页面 - 我发现 setTimeout 不起作用,因为它里面有 location.reload

当前工作原理的快速(讨厌)示例:JSFiddle

//collision
if (x < object.x - 50 + 60 &&
    x + width > object.x - 50 && 
    y < object.y - 60 + 60 && 
    height + y > object.y - 60) {

  
//fill before alert
ctx.fillRect(0,0,2000,2000);
ctx.strokeText("You only reached a score of " + score + ", you lose!\nPress 'OK' to try again?", 250, 290);
ctx.fillText("You only reached a score of " + score + ", you lose!\nPress 'OK' to try again?",250,290);

  
//end game alert
if(!alert("You reached a score of ...")){
location.reload();
}}

这应该有效。

var x = 1 //collision or any true statement
if (x == 1) {
  ctx.fillRect(0, 0, 2000, 2000);
  ctx.strokeText("You only reached a score of ...", 250, 290);
  ctx.fillText("You only reached a score of ...", 250, 290);
  setTimeout(function(){
      alert("You only reached a score of ...");
      location.reload();
  }, 10);
}

https://jsfiddle.net/ajrwpmb3/10/

警报没有 return 任何价值。他们阻止完整的代码执行。这里的问题是浏览器倾向于对 DOM 进行批量更新以获取在函数内完成的更改。由于在您的代码中更改为 canvas 已完成并且浏览器线程立即被警报阻止,因此不会应用更改。在我的示例中,我添加了 10 毫秒来中断 canvas 更新事件,并将警报分为浏览器事件队列中的 2 个块,这允许浏览器完成事件 1,即先 canvas 更新,然后执行第二个事件,即显示阻止代码的警报。 您可以使用超时值 0ms 来验证这个概念。

setTimeout perfectly works, check this code out

HTML

<canvas id="canvas"></canvas>
<button id="buttonID">click here</button>

Javascript

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

ctx.fillStyle=gradient;
var my_gradient=ctx.createLinearGradient(0,0,0,170);
my_gradient.addColorStop(0,"#7E6189");
my_gradient.addColorStop(1,"#FFFFFF");
ctx.fillStyle=my_gradient;

ctx.lineWidth = 5;
ctx.font="30px Verdana";
var gradient=ctx.createLinearGradient(0,0,canvas.width,0);
gradient.addColorStop("0","magenta");
gradient.addColorStop("0.5","blue");
gradient.addColorStop("1.0","red");
ctx.strokeStyle = 'black';
//irrelevant above



var x = 1 //collision or any true statement


// when the event occures
// create the gredient
document.querySelector('#buttonID').onclick = function() {
  ctx.fillRect(0,0,2000,2000);
  ctx.strokeText("You only reached a score of ...", 250, 290);
  ctx.fillText("You only reached a score of ...",250,290);
  setTimeout(function() {
    if(!alert("You only reached a score of ...")){
        location.reload();
    }
  }, 300); // chenge the millis to whatever you want
}

i am using an event to execute the code because the permanent alets are annoying

window.alert,确认,提示应该死了..

回答这么多,我再补充一个。

不要使用警报...永远...拜托!!!,为了您网站的所有用户,因为如果他们像我一样第一次在网站上看到警报时,我会关闭它们。事实上,用户可以 block/stop 这些警报应该足以成为不使用它们的理由,因为依赖警报会破坏像我这样迂腐的人的游戏。

更好的警报

您最好的选择是创建您自己的非阻塞、自定义警报。创建一个 div 并将其样式设置为 position: absolute,将其置于页面中心,然后添加一个 ok 按钮并隐藏整个按钮。

将警报 div 设为 id="myAlert",当您需要它时,只需取消隐藏它并等待按钮被点击,当按钮被点击时隐藏警报。

对于您的游戏,您应该添加一些暂停逻辑,当需要显示警报时,只需暂停游戏并显示警报即可。单击警报后,取消暂停游戏并执行所需的操作。

演示仅展示了如何实现简单的自定义提醒和暂停游戏。

// alert function handles the display of a custom alert
var alert = (function(){
    var firstRun = true;
    var callback;
    function alertCallback(){  // handle the click event
        if(typeof callback === "function"){
            callback();
        }
        myAlert.className = "alert hideAlert";
    }
    function alert(message,callbackO){
        myAletMessage.textContent = message;
        myAlert.className = "alert showAlert";
        if(firstRun){
            firstRun = false;
            myAlertButton.addEventListener("click",alertCallback)
        }
        callback = callbackO;  // set the callback
        
    }
    return alert;
})()

var canvas,ctx;
function addCanvas(){
    canvas = document.createElement("canvas");
    canvas.style.top = "0px";
    canvas.style.left = "0px";
    canvas.style.position = "absolute";
    document.body.appendChild(canvas);
    ctx = canvas.getContext("2d");
}
function resizeCanvas(){
    if(canvas === undefined){
        addCanvas();
    }
    canvas.width = innerWidth;
    canvas.height = innerHeight;
    ctx.font = "32px arial black";
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.fillStyle = "red";
}

resizeCanvas();
window.addEventListener("resize",resizeCanvas);



// The following code just shows a pretend game with a paused function 
// The paused is used when the alert is called.

var paused = false;
var x,y,t;



function update2(timer){

    globalTime = timer;
    ctx.setTransform(1,0,0,1,0,0); // reset transform
    ctx.clearRect(0,0,canvas.width,canvas.height);
    ctx.globalAlpha = 1;           // reset alpha
    if(paused){
        if(t > 0){
            var sc = t / 10 + 0.1;
            ctx.setTransform(sc,0,0,sc,x,y);
            ctx.fillText("BANG!",0,0);
        }
        var sc = Math.sin(timer /100) * 0.1 + 1.0;
        ctx.fillStyle = "Green";
        ctx.setTransform(sc,0,0,sc,canvas.width/2,canvas.height/2);
        ctx.fillText("Paused!",0,0);
        ctx.fillStyle = "Red";
    }else{
        if(t > 0){
            var sc = t / 10 + 0.1;
            ctx.setTransform(sc,0,0,sc,x,y);
            ctx.fillText("BANG!",0,0);
            t -= 1;
        }else{
            if(Math.random() < 0.1){
                x = (Math.random() * (canvas.width -200))+100;
                y = (Math.random() * (canvas.height -200))+100;
                t= 10;
            }
        }
        if(Math.random() < 0.01){
            alert("A 1 in 100 random event paused the game!",function(){paused = false;});
            paused = true;
        }
    }
    requestAnimationFrame(update2);
}
requestAnimationFrame(update2);
    
.alert {  
    position : absolute;
    z-index : 100;
    left : 35%;
    width : 30%;
    top : 10%;
    background: #fff;
    border: 1px #000 solid;
    text-align: center;
    padding: 6px;    
}
.hideAlert {
    display : none;
}
.showAlert {
    display : block;
}
<div class="alert hideAlert" id="myAlert">
    <div id="myAletMessage"></div><br>
    <input id="myAlertButton" type="button" value="OK got it."></input>
</div>