javascript - Why isn't the else block firing? -
i'm making html canvas game (tron), , i'm want game detect when player hits border of canvas. have if
statement checks if player in contact either own trail or opponents, , works fine, parameter being outside of canvas (y >= 780
) doesn't seem doing anything. added snippet. there's library key event handling in there, that's not code (the library no longer necessary after made changes shouldn't have problem). time.
/*! keydrown - v1.2.2 - 2016-03-23 - http://jeremyckahn.github.com/keydrown */ !function(a){var b=function(){var b={};b.foreach=function(a,b){var c;for(c in a)a.hasownproperty(c)&&b(a[c],c)};var c=b.foreach;b.gettranspose=function(a){var b={};return c(a,function(a,c){b[a]=c}),b},b.indexof=function(a,b){if(a.indexof)return a.indexof(b);var c,d=a.length;for(c=0;d>c;c++)if(a[c]===b)return c;return-1};var d=b.indexof;return b.pushunique=function(a,b){return-1===d(a,b)?(a.push(b),!0):!1},b.removevalue=function(a,b){var c=d(a,b);return-1!==c?a.splice(c,1)[0]:void 0},b.documenton=function(b,c){a.addeventlistener?a.addeventlistener(b,c,!1):document.attachevent&&document.attachevent("on"+b,c)},b.requestanimationframe=function(){return a.requestanimationframe||a.webkitrequestanimationframe||a.mozrequestanimationframe||function(b){a.settimeout(b,1e3/60)}}(),b.noop=function(){},b}(),c={a:65,b:66,c:67,d:68,e:69,f:70,g:71,h:72,i:73,j:74,k:75,l:76,m:77,n:78,o:79,p:80,q:81,r:82,s:83,t:84,u:85,v:86,w:87,x:88,y:89,z:90,enter:13,shift:16,esc:27,space:32,left:37,up:38,right:39,down:40,backspace:8,delete:46},d=b.gettranspose(c),e=[],f=function(){"use strict";function a(a){this.keycode=a,this.cachedkeypressevent=null}function c(a,b,c,d){c?a[b]=c:a[b](d)}return a.prototype._downhandler=b.noop,a.prototype._uphandler=b.noop,a.prototype._presshandler=b.noop,a.prototype.isdown=function(){return-1!==b.indexof(e,this.keycode)},a.prototype.down=function(a){c(this,"_downhandler",a,this.cachedkeypressevent)},a.prototype.up=function(a,b){c(this,"_uphandler",a,b)},a.prototype.press=function(a,b){this.cachedkeypressevent=b,c(this,"_presshandler",a,b)},a.prototype.unbinddown=function(){this._downhandler=b.noop},a.prototype.unbindup=function(){this._uphandler=b.noop},a.prototype.unbindpress=function(){this._presshandler=b.noop},a}(),g=function(e){"use strict";var g={};g.key=f;var h=!1,i=date.now?date.now:function(){return+new date},j=i();return g.tick=function(){var a,b=e.length;for(a=0;b>a;a++){var c=e[a],f=d[c];f&&g[f].down()}},g.run=function(c){h=!0;var d=i(),e=d-j;b.requestanimationframe.call(a,function(){h&&(g.run(c),c(e,d))}),j=d},g.stop=function(){h=!1},b.foreach(c,function(a,b){g[b]=new f(a)}),b.documenton("keydown",function(a){var c=a.keycode,f=d[c],h=b.pushunique(e,c),i=g[f];if(i){var j=i.cachedkeypressevent||{};(j.ctrlkey||j.shiftkey||j.metakey)&&(h=!0),h&&i.press(null,a)}}),b.documenton("keyup",function(a){var c=b.removevalue(e,a.keycode),f=d[c];f&&g[f].up(null,a)}),b.documenton("blur",function(a){b.foreach(e,function(a){var b=d[a];b&&g[b].up()}),e.length=0}),g}(e);"object"==typeof module&&"object"==typeof module.exports?module.exports=g:"function"==typeof define&&define.amd?define(function(){return g}):a.kd=g}(window);
canvas { width: 1000px; height: 800px; margin-left: auto; margin-right: auto; display: block; border: 1px solid black; } h1,h2 { width: 100px; text-align: center; margin-left: auto; margin-right: auto; font-family: sans-serif; } h2 { border: 5px solid black; padding: 5px; } h2:hover { background-color: #7df9ff; cursor: pointer; }
<!doctype html> <html> <head> <meta charset="utf-8"> <title>tron</title> <script src="keydrown.min.js"></script> <link rel="stylesheet" type="text/css" href="tron.css"/> </head> <body> <h1>tron</h1> <h2>play</h2> <canvas height="800px" width="1000px"></canvas> <script> function game() { canvas = document.getelementsbytagname('canvas')[0]; ctx = canvas.getcontext('2d'); ctx.fillstyle = "blue"; ctx.fillrect(0,0,20,20); ctx.fillstyle = "red"; ctx.fillrect(980,780,20,20); x = 980; y = 780; = 0; b = 0; // p2 controls function moveright() { if(kd.up.isdown() === false && kd.down.isdown() === false && kd.left.isdown() === false && ctx.getimagedata(x+21, y, 1, 1).data[0] !== 255 && ctx.getimagedata(x+21, y, 1, 1).data[2] !== 255) { x+=10; ctx.fillstyle = "red"; ctx.fillrect(x,y,20,20); } else if(ctx.getimagedata(x+21, y, 1, 1).data[0] === 255 || ctx.getimagedata(x+21, y, 1, 1).data[2] === 255 || x >= 980) { alert("blue wins!"); } } kd.right.down(function() { clearinterval(dir2); dir2 = setinterval(moveright, 25); }); function moveleft() { if(kd.up.isdown() === false && kd.down.isdown() === false && kd.right.isdown() === false && ctx.getimagedata(x-1, y, 1, 1).data[0] !== 255 && ctx.getimagedata(x-1, y, 1, 1).data[2] !== 255) { x-=10; ctx.fillstyle = "red"; ctx.fillrect(x,y,20,20); } else if(ctx.getimagedata(x-1, y, 1, 1).data[0] === 255 || ctx.getimagedata(x-1, y, 1, 1).data[2] === 255 || x <= 0) { alert("blue wins!"); } } kd.left.down(function() { clearinterval(dir2); dir2 = setinterval(moveleft, 25); }); function moveup() { if(kd.left.isdown() === false && kd.down.isdown() === false && kd.right.isdown() === false && ctx.getimagedata(x, y-1, 1, 1).data[0] !== 255 && ctx.getimagedata(x, y-1, 1, 1).data[2] !== 255) { y-=10; ctx.fillstyle = "red"; ctx.fillrect(x,y,20,20); } else if(ctx.getimagedata(x, y-1, 1, 1).data[0] === 255 || ctx.getimagedata(x, y-1, 1, 1).data[2] === 255 || y <= 0) { alert("blue wins!"); } } kd.up.down(function() { clearinterval(dir2); dir2 = setinterval(moveup, 25); }); function movedown() { if(kd.left.isdown() === false && kd.up.isdown() === false && kd.right.isdown() === false && ctx.getimagedata(x, y+21, 1, 1).data[0] !== 255 && ctx.getimagedata(x, y+21, 1, 1).data[2] !== 255) { y+=10; ctx.fillstyle = "red"; ctx.fillrect(x,y,20,20); } else if(ctx.getimagedata(x, y+21, 1, 1).data[0] === 255 || ctx.getimagedata(x, y+21, 1, 1).data[2] === 255 || y >= 780) { alert("blue wins!"); } } kd.down.down(function() { clearinterval(dir2); dir2 = setinterval(movedown, 25); }); // controls function moved() { if(kd.w.isdown() === false && kd.s.isdown() === false && kd.a.isdown() === false && ctx.getimagedata(a+21, b, 1, 1).data[0] !== 255 && ctx.getimagedata(a+21, b, 1, 1).data[2] !== 255) { a+=10; ctx.fillstyle = "blue"; ctx.fillrect(a,b,20,20); } else if(ctx.getimagedata(a+21, b, 1, 1).data[0] === 255 || ctx.getimagedata(a+21, b, 1, 1).data[2] === 255 || >= 980) { alert("red wins!"); } } kd.d.down(function() { clearinterval(dir1); dir1 = setinterval(moved, 25); }); function movea() { if(kd.w.isdown() === false && kd.s.isdown() === false && kd.d.isdown() === false && ctx.getimagedata(a-1, b, 1, 1).data[0] !== 255 && ctx.getimagedata(a-1, b, 1, 1).data[2] !== 255) { a-=10; ctx.fillstyle = "blue"; ctx.fillrect(a,b,20,20); } else if(ctx.getimagedata(a-1, y, 1, 1).data[0] === 255 || ctx.getimagedata(a-1, b, 1, 1).data[2] === 255 || <= 0) { alert("red wins!"); } } kd.a.down(function() { clearinterval(dir1); dir1 = setinterval(movea, 25); }); function movew() { if(kd.a.isdown() === false && kd.s.isdown() === false && kd.d.isdown() === false && ctx.getimagedata(a, b-1, 1, 1).data[0] !== 255 && ctx.getimagedata(a, b-1, 1, 1).data[2] !== 255) { b-=10; ctx.fillstyle = "blue"; ctx.fillrect(a,b,20,20); } else if(ctx.getimagedata(a, b-1, 1, 1).data[0] === 255 || ctx.getimagedata(a, b-1, 1, 1).data[2] === 255 || b <= 0) { alert("red wins!"); } } kd.w.down(function() { clearinterval(dir1); dir1 = setinterval(movew, 25); }); function moves() { if(kd.a.isdown() === false && kd.w.isdown() === false && kd.d.isdown() === false && ctx.getimagedata(a, b+21, 1, 1).data[0] !== 255 && ctx.getimagedata(a, b+21, 1, 1).data[2] !== 255) { b+=10; ctx.fillstyle = "blue"; ctx.fillrect(a,b,20,20); } else if(ctx.getimagedata(a, b+21, 1, 1).data[0] === 255 || ctx.getimagedata(a, b+21, 1, 1).data[2] === 255 || b >= 780) { alert("red wins!"); } } kd.s.down(function() { clearinterval(dir1); dir1 = setinterval(moves, 25); }); kd.run(function () { kd.tick(); }); dir1 = setinterval(moved, 25); dir2 = setinterval(moveleft, 25); } document.getelementsbytagname('h2')[0].addeventlistener('click', function(){ game(); }); </script> </body> </html>
learning program not easy , little bugs can make more of chore joy.
i can not spot bug because not 100% sure want happen.
there many bad things waiting cause problems further on.
so rather find , fix problem rewrote code in manner easier manage, more friendly dom, , little less prone bugs.
the keyboard handle using way overkill need there simple keyboard handler @ top.
i hate use of alerts. can cause sorts of problems, changed code show results on canvas.
rather repeat code each player added function handle single play passed object. player1
, player2
objects contain makes player unique , updateplayer
function called each player.
there drawplayer
function draw.
rather use timers update game requestanimationframe
. should try avoid using setinterval , settimeout not make animation quality , can make timing messed up.
the player keyboard handling little complex @ first thought wanted play rule, "move when 1 move key down." eg when , left held down had no movement, , when release key player stops (but saw keyboard handler giving keydowns when no keys down". can add behaviour if wanted replacing &
(bitwise and) ===
eg if(keypadbits & up){
becomes if(keypadbits === up)
in updateplayer
function
i added "use strict" top of game function. makes code run faster forces more careful when coding rules strict. stop creating situations code runs , not report bug. may never have bug happen, or might , hard pressed find it. strict mode active error reported , can fix , there.
(function game() { "use strict"; // never code without line or live in hell of billion bugs var canvas = document.getelementsbytagname('canvas')[0]; //var canvas = document.getelementbyid('can'); var ctx = canvas.getcontext('2d'); //============================================================================================================== // constants , variables // bit positions keypad const = 0b1000; const right = 0b100; const down = 0b10; const left = 0b1; // speeds , sizes const move_speed = 10; const player_size = 20; const play_field_sizew = canvas.width - player_size; const play_field_sizeh = canvas.height - player_size; // flags game state var gameover = true; // must start game gameover= true or not start //============================================================================================================== // keyboard handler replace overkill keydrown lib var keys = {}; var filterkeys = "arrowup,arrowdown,arrowleft,arrowright,keya,keys,keyd,keyw".split(","); // array of keys listen function keyboard(event){ if(filterkeys.indexof(event.code) > -1){ // filter out unwanted key events keys[event.code] = event.type === "keydown"; // true if key down false if not event.preventdefault(); } } document.body.addeventlistener("keydown",keyboard); document.body.addeventlistener("keyup",keyboard); //============================================================================================================== // player restart function var restartplayer = function(){ this.x = this.start.x; this.y = this.start.y; this.dx = this.start.dx; this.dy = this.start.dy; this.crash = false; } // player details var player1 = { x : 980, // should set player start positions y : 0, dx : 0, // movement direction dy : 0, start : {x: canvas.width - player_size, y : canvas.height - player_size,dx :-1,dy :0}, crash : false, id : 0, col : "red", restart : restartplayer, } var player2 = { x : 0, // should set player start positions y : 0, dx : 0, // movement direction dy : 0, start : {x: 0, y : 0,dx : 1,dy : 0}, crash : false, id : 1, col : "blue", restart : restartplayer, } //============================================================================================================== // check player keys moves if needed , checks crashes function updateplayer(player){ debugger var keypadbits = 0; // set bits keys down if(player.id === 0){ // first player keypadbits |= keys.arrowup ? : 0; keypadbits |= keys.arrowright? right : 0; keypadbits |= keys.arrowdown ? down : 0; keypadbits |= keys.arrowleft ? left : 0; }else{ keypadbits |= keys.keyw ? : 0; keypadbits |= keys.keyd ? right : 0; keypadbits |= keys.keys ? down : 0; keypadbits |= keys.keya ? left : 0; } // movement direction in order of priority // can have diagonals eg if(keypadbits & (up+left)) if(keypadbits & up){ // yes single & bitwise , operator player.dy = -1; player.dx = 0; }else if(keypadbits & down){// yes single & bitwise , operator player.dy = 1; player.dx = 0; }else if(keypadbits & right){// yes single & bitwise , operator player.dx = 1; player.dy = 0; }else if(keypadbits & left){// yes single & bitwise , operator player.dx = -1; player.dy = 0; } // check pixel in direction of movement var x = player.x + player.dx + player_size * (player.dx > 0 ? 1 : 0); var y = player.y + player.dy + player_size * (player.dy > 0 ? 1 : 0); var data = ctx.getimagedata(x,y, 1, 1).data; if(data[0] !== 255 && data[2] !== 255){ player.x += move_speed * player.dx; player.y += move_speed * player.dy; // player has moved check edge crash if( player.x < 0 || player.y < 0 || player.x > play_field_sizew || player.y > play_field_sizeh){ player.crash = true; } } else { // player must have crashed if red , blue on player.crash = true; } } // draws player @ current position function drawplayer(player){ ctx.fillstyle = player.col; ctx.fillrect(player.x, player.y, player_size, player_size); } // updates both players function playerupdate(){ if(!gameover){ updateplayer(player1); updateplayer(player2); // draw both players after both have moved or give 1 player slight advantage of being // invisible @ current position drawplayer(player1); drawplayer(player2); if(player1.crash || player2.crash){ gameover = true; var text = ""; var col = "black"; if(player1.crash && player2.crash){ // may draw if both crash @ same time text = "it's draw!"; }else if(player1.crash){ text = "blue wins!"; col= "blue"; }else { text = "red wins!"; col = "red"; } ctx.font = "64px arial black"; ctx.textalign = "center"; ctx.fillstyle = col; ctx.strokestyle = "black"; ctx.linewidth = 4; if(col !== "black"){ ctx.stroketext(text,canvas.width * 0.5, canvas.height * 0.4); } ctx.filltext(text,canvas.width * 0.5, canvas.height * 0.4); ctx.fillstyle = "black"; ctx.font = "24px arial black"; ctx.filltext("click 'play' start again.",canvas.width * 0.5, canvas.height * 0.6 ); } } } // function restart game function restartgame(){ player1.restart(); player2.restart(); gameover = false; ctx.clearrect(0,0,canvas.width,canvas.height); } // main animation loop called 60 times second. function update(time){ playerupdate(); if(!gameover){ requestanimationframe(update); } } document.getelementsbytagname('h2')[0].addeventlistener('click', function(){ if(gameover){ restartgame(); requestanimationframe(update); } }); })(); // run function (function(){})() invoked function
canvas { width: 1000px; height: 800px; margin-left: auto; margin-right: auto; display: block; border: 1px solid black; } h1,h2 { width: 100px; text-align: center; margin-left: auto; margin-right: auto; font-family: sans-serif; } h2 { border: 5px solid black; padding: 5px; } h2:hover { background-color: #7df9ff; cursor: pointer; }
<h1>tron</h1> <h2>play</h2> <canvas height="800px" width="1000px"></canvas>
Comments
Post a Comment