如何向进入移动区域的对象添加逻辑语句

时间:2017-04-30 20:25:22

标签: javascript if-statement html5-canvas

我正在尝试制作游戏。游戏的目的是在屏幕上移动方块,而不会撞到从屋顶掉下来的雨滴。如何制作它,以便如果其中一个雨滴进入正方形,则正方形返回到画布的开头或x = 0。这是代码:

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

var WIDTH = 1000;
var HEIGHT = 700;
var x = 0;
var y = HEIGHT-20;
var xPos = [0];
var yPos = [0];
var speed = [1];
var rainDrops = 50;
var rectWidth = 20;
var rectHeight = 20;






for (var i = 0; i < rainDrops; i++) {
    xPos.push(Math.random()* WIDTH);
    yPos.push(0);
    speed.push(Math.random() * 5);

    }



function rainFall () {

    window.requestAnimationFrame(rainFall);
    ctx.clearRect(0, 0, WIDTH, HEIGHT);



    for (var i = 0; i <rainDrops; i++) {
    //Rain
    ctx.beginPath();
    ctx.arc(xPos[i], yPos[i], 3, 0, 2 * Math.PI);
    ctx.fillStyle = 'blue';
    ctx.fill();

    //Rain movement
    yPos[i]+=speed[i];

    //Box

        ctx.fillStyle = 'red';
        ctx.fillRect(x, y, rectWidth, rectWidth);

    if (yPos[i] > HEIGHT) {
        yPos[i]= 0;
        yPos[i]+=speed[0];
        }
    //This is the part where I need the Help!!!!!!!!!
    if (){
        x = 0;
    }

    }


};



//Move Object

function move (e) {
    if (e.keyCode === 37) {
        ctx.clearRect (0, 0, WIDTH, HEIGHT);
        x -=10;
    }
    if (e.keyCode === 39) {
        ctx.clearRect (0, 0, WIDTH, HEIGHT);
        x+=10;
    }
    canvas.width=canvas.width

}




//Lockl Screen

window.addEventListener("keydown", function(e) {
    // Lock arrow keys
    if( [37,39,].indexOf(e.keyCode) > -1) {
        e.preventDefault();
    }
}, false);


rainFall(); 
document.onkeydown = move;
window.addEventListener("load", doFirst, false);

1 个答案:

答案 0 :(得分:0)

条件语句

我从不太确定如何回答这些类型的问题。由于你是初学者,我不想用代码和技术压倒你,但与此同时我也不想给出一个能够延续一些不良技术的答案。

简短回答

首先,您编写的代码中的简单答案

//This is the part where I need the Help!!!!!!!!!
// the test checks the center of the drop 
// if drop is greater than > top of player (y) and (&&) 
// drop x  greater than > left side of player x and (&&) drop is less than <
// right side of player (x + rectWidth) then drop has hit player   
if (yPos[i] > y && xPos[i] > x && xPos[i] < x + rectWidth ){
    x = 0; // move player back
}

顺便说一句,你正在为每次降雨画出玩家矩形。你应该把那个绘制函数移到循环之外。

答案很长

希望我没有让它太混乱,并且添加了很多关于我为什么这样做的评论。

为了帮助保持一切有条理,我将各种元素分成了自己的对象。有playerrain和键盘处理程序。这一切都是通过mainLoop进行协调的,每次调用一次(requestAnimationFrame)并调用各种函数来完成所需的一切。

player对象包含与播放器有关的所有数据,以及播放器drawupdate的功能(更新移动播放器)

rain对象保存名为rain.drops的数组中的所有降雨,它具有雨drawupdate的功能。它还有一些函数来随机化一个drop,并添加新的drop。

为了测试下雨是否已经击中了玩家我是在rain.update功能(我在哪里下雨)中进行测试的,当雨水冲击玩家时我不知道你想要发生什么,所以我只是重置雨水下降并在点击计数器上加1。

首先检查降雨量drop.y + drop.radius的底部是否大于播放器顶部if(drop.y + drop.radius >= player.y){

这使得我们不会浪费时间检查玩家上方的雨水。

我在x方向测试雨水。最简单的是测试负面(如果下雨没有击中玩家),因为逻辑稍微简单一些。

如果掉落的右侧位于播放器左侧的左侧,或者(使用||表示或),则放置的左侧位于播放器右侧的右侧而不是放置无法击中玩家。正如我们想要反向条件一样,我们将它包装在一个括号中,放在前面if(! ( ... ) )

测试时间有点长,所以为了便于阅读,我将其分为2行。

 // drop is a single rain drop player is the player
 if (drop.y + drop.radius >= player.y) {
     if ( ! (drop.x + drop.radius < player.x || 
     drop.x - drop.radius > player.x + player.width) ) { 
         // code for player hit by rain in here
     }
 }

rain.update函数还会检查雨水是否已经触及画布的底部并重置,如果是的话。

演示

我从问题中复制了您的代码并对其进行了修改。

&#13;
&#13;
addEventListener("load",function(){  // you had onload at the bottom after all the code that gets the canvas
                                     // etc. Which kind of makes the on load event pointless. Though not needed
                                     // in this example I have put it in how you can use it for a web page.
                                     // Using onload event lets you put the javascript anywhere in the HTML document
                                     // if you dont use onload you must then only put the javascript after
                                     // the page elements you need eg Canvas.
    var canvas = document.getElementById('gameCanvas');
    var ctx = canvas.getContext('2d');
    ctx.font = "20px arial";
    var frameCount = 0; // counts the frames

    var WIDTH = canvas.width;
    var HEIGHT = canvas.height;    
    var currentMaxDrops = 5; // rain will increase over time
    const numberFramesPerRainIncrease = 60 * 5; // long name says it all. 60 frames is one second.
    const maxRainDrops = 150;  // max number of rain drops
    
    // set up keyboard handler
    addEventListener("keydown", keyEvent);
    addEventListener("keyup", keyEvent);    
    requestAnimationFrame(mainLoop); // request the first frame of the animation (get it all going)

    //==========================================================================================
    // Setup the keyboard input stuff
    const keys = {  // list of keyboard keys to listen to by name. 
        ArrowLeft : false,
        ArrowRight : false,
    }
    function keyEvent(event){  // the key event argument event.code hold the named key.
        if(keys[event.code] !== undefined){   // is this a key we want
            event.preventDefault();  // prevent default browser action
            keys[event.code] = event.type === "keydown";  // true if keydown false if not
        }
    }


    //==========================================================================================
    const player = {  // object for everything to do with the player
        x : 0,           // position
        y : HEIGHT - 20,  
        width : 20,      // size
        height : 20,      
        speed : 4,       // speed per frame
        color : "red",
        showHit : 0,  // when this is > 0 then draw the player blue to indicate a hit. 
                      // This counter is counted down each frame  so setting its value 
                      // determins how long to flash the blue
        hitCount : 0,   // a count of the number of drops that hit the player.
        status(){  // uses hit count to get a status string 
            if(player.hitCount === 0){
                return "Dry as a bone.";
            }
            if(player.hitCount < 5){
                return "A little damp.";
            }
            if(player.hitCount < 15){
                return "Starting to get wet.";
            }
            return "Soaked to the core";
        },
        draw(){  // draw the player
           if(player.showHit > 0){
               player.showHit -= 1; // count down show hit
               ctx.fillStyle = "blue";
           }else{
               ctx.fillStyle = player.color;
           }
           ctx.fillRect(player.x,player.y,player.width,player.height);
        },
        update(){ // this updates anything to do with the player
           // Not sure how you wanted movement. You had it so that you move only when key down events
           // so I have done the same
           if(keys.ArrowLeft){
               player.x -= player.speed;  // move to the left
               keys.ArrowLeft = false; // turn off the key. If you remove this line then will move left while       
                                       // the key is down and stop when the key is up.
               if(player.x < 0){ // is the player on or past left side of canvas
                    player.x = 0; // move player back to zero.
               }
           }
           if(keys.ArrowRight){
               player.x += player.speed;  // move to the right
               keys.ArrowRight = false; // turn off the key. If you remove this line then will move right while       
                                       // the key is down and stop when the key is up.
               
               if(player.x + player.width >= WIDTH){ // is the player on or past right side of canvas
                    player.x = WIDTH - player.width; // move player back to inside the canvas.
               }
           }
        }
            
    }

    //==========================================================================================
    const rain = {  // object to hold everything about rain
        numberRainDrops : 50,
        drops : [],  // an array of rain drops.
        randomizeDrop(drop){ // sets a drop to random position etc.
            drop.x = Math.random() * WIDTH;  // random pos on canvas
            drop.y = -10;                      // move of screen a little so we dont see it just appear
            drop.radius = Math.random() *3 + 1; // give the drops a little random size
            drop.speed = Math.random() * 4 + 1; // and some speed Dont want 0 speed so add 1
            return drop;
        },
        createDrop(){  // function to create a rain drop and add it to the array of drops
            if(rain.drops.length < currentMaxDrops){ // only add if count is below max
                rain.drops.push(rain.randomizeDrop({})); // create and push a drop. {} creates an empty object that the function
                                                    // randomizeDrop will fill with the starting pos of the drop.
                rain.numberRainDrops = rain.drops.length;
            }
        },
        draw(){    // draw all the rain
            ctx.beginPath();  // start a new path
            ctx.fillStyle = 'blue';  // set the colour
            for(var i = 0; i < rain.drops.length; i ++){
                var drop = rain.drops[i]; // get the indexed drop
                ctx.arc(drop.x, drop.y, drop.radius, 0, 2 * Math.PI);
                ctx.closePath(); // stops the drops rendered as one shape
            }        
            ctx.fill();    // now draw all the drops.        
        },
        update(){
            for(var i = 0; i < rain.drops.length; i ++){
                var drop = rain.drops[i]; // get the indexed drop
                drop.y += drop.speed;     // move down a bit.
                if(drop.y + drop.radius >= player.y){ // is this drop at or below player height
                     // checks if the drop is to the left or right of the player
                     // as we want to know if the player is hit we use ! (not)
                     // Thus the next if statement is if rain is not to the left or to the right then 
                     // it must be on the player.
                     if(!(drop.x + drop.radius < player.x || // is the rigth side of the drop left of the players left side
                        drop.x - drop.radius > player.x + player.width)){ 
                        // rain has hit the player.
                        player.hitCount += 1;
                        player.showHit += 5;
                        rain.randomizeDrop(drop); // reset this drop.
                     }
                }
                if(drop.y > HEIGHT + drop.radius){ // is it off the screen ?
                      rain.randomizeDrop(drop); // restart the drop 
                }
            }        
        }
    }
            
    function mainLoop () {  // main animation loop
        requestAnimationFrame(mainLoop);  // request next frame (don`t need to specify window as it is the default object)
        ctx.clearRect(0, 0, WIDTH, HEIGHT);
        frameCount += 1; // count the frames
        // when the remainder of frame count and long name var is 0 increase rain drop count
        if(frameCount % numberFramesPerRainIncrease === 0){
            if(currentMaxDrops < maxRainDrops){
               currentMaxDrops += 1;
            }
        }
        
        rain.createDrop(); // a new drop (if possible) per frame
        rain.update();  // move the rain and checks if the player is hit
        player.update();   // moves the player if keys are down and check if play hits the side of the canvas
        player.draw();   // draw player
        rain.draw();  // draw rain after player so its on top.
        ctx.fillStyle = "black";
        ctx.fillText("Hit " + player.hitCount + " times.",5,20);
        ctx.setTransform(0.75,0,0,0.75,5,34); // makes status font 3/4 size and set position to 5 34 so I dont have to work out where to draw the smaller font
        ctx.fillText(player.status(),0,0); // the transform set the position so text is just drawn at 0,0
        ctx.setTransform(1,0,0,1,0,0); // reset the transform to the default so all other rendering is not effected
    };

});
&#13;
canvas {
   border : 2px black solid;
}
&#13;
<canvas id="gameCanvas" width=512 height=200></canvas>
&#13;
&#13;
&#13;

希望这有用。