I wrote my code using the following javascript library, SimpleGame.js by A. Harris.
My code follows, the problem is that the character does not animate while the arrow keys are pressed, it does animate when same keys are released ... what am I missing? Furthermore, key 39, which should be the left arrow key, does not work at all. Any help appreciated, Thank you.
http://www.retroinvaders.net/multiAnimationTest.html
Multi Animation Test
<script type="text/javascript" src="simpleGame.js"></script>
<script type="text/javascript">
var game;
var background;
var character;
var critter;
window.addEventListener("keydown", keydownHandler, false);
function init() {
game = new Scene();
background = new Sprite(game, "media/rpgMap.png", 800, 600);
background.setSpeed(0, 0);
background.setPosition(400, 300);
character = new Character();
critter = new Critter();
game.start();
}
function update() {
game.clear();
checkCollisions();
background.update();
character.update();
critter.update();
}
function Character() {
tCharacter = new Sprite(game, "media/rpg_sprite_walk.png", 192, 128);
tCharacter.loadAnimation(192, 128, 24, 32);
tCharacter.generateAnimationCycles();
tCharacter.renameCycles(new Array("down", "up", "left", "right"));
tCharacter.setAnimationSpeed(1000);
tCharacter.setPosition(440, 380);
tCharacter.setSpeed(0);
tCharacter.pauseAnimation();
tCharacter.setCurrentCycle("down");
return tCharacter;
}
function keydownHandler(event) {
if (event.keyCode === 37) {
character.playAnimation();
character.setCurrentCycle("left");
character.setMoveAngle(270);
character.changeXBy(-5);
}
if (event.keyCode === 39) {
character.changeXby(5);
character.playAnimation()
character.setMoveAngle(90);
character.setCurrentCycle("right");
}
if (event.keyCode === 38) {
character.playAnimation()
character.changeYby(-5);
character.setMoveAngle(0);
character.setCurrentCycle("up");
}
if (event.keyCode === 40) {
character.changeYby(5);
character.playAnimation()
character.setMoveAngle(180);
character.setCurrentCycle("down");
}
}
function Critter() {
tCritter = new Sprite(game, "media/critter.gif", 30, 30);
tCritter.setSpeed(0);
tCritter.setPosition(200, 200);
return tCritter;
}
function checkCollisions() {
if (character.distanceTo(critter) <= 30) {
critter.hide();
}
}
</script>
You were assigning new animationCycle each time you pressed a key.
It seems that chrome had no time to set the new animation cycles.
Use a flag to change only when needed fix this :
function keydownHandler(event) {
event.preventDefault();
if (event.keyCode === 37) {
if (character.animation.currentCycleName !== "left") {
character.setCurrentCycle("left");
}
character.changeXby(-5);
character.playAnimation();
character.setMoveAngle(270);
}
if (event.keyCode === 39) {
if (character.animation.currentCycleName !== "right") {
character.setCurrentCycle("right");
}
character.changeXby(5);
character.playAnimation()
character.setMoveAngle(90);
}
if (event.keyCode === 38) {
if (character.animation.currentCycleName !== "up") {
character.setCurrentCycle("up");
}
character.changeYby(-5);
character.playAnimation();
character.setMoveAngle(0);
}
if (event.keyCode === 40) {
if (character.animation.currentCycleName !== "down") {
character.setCurrentCycle("down");
}
character.changeYby(5);
character.playAnimation();
character.setMoveAngle(180);
}
}
See fiddle
Related
I'm trying to create a class that supplies an event listener and handler for a html canvas object to respond to when left and right arrow keys are pressed. my project has 2 files a game's classes file and the game's main file
these are the functions that would normally go into the games main file. but I'm trying to make them into a class that can be exported.
// unmodified code
function keyDownHandler(e) {
if (e.keyCode == 39) {
rightPressed = true;
}
else if (e.keyCode == 37) {
leftPressed = true;
}
}
function keyUpHandler(e) {
if (e.keyCode == 39) {
rightPressed = false;
}
else if (e.keyCode == 37) {
leftPressed = false;
}
}
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
// actual answer is below
export class Paddle {
constructor (world) {
this.canvas = world.canvas,
this.ctx = world.ctx,
this.paddleHeight = 10;
this.paddleWidth = 75;
this.paddleX = (this.canvas.width - this.paddleWidth) / 2;
this.rightPressed = false;
this.leftPressed = false;
// do i have to make a attribute for the event handlers?
// or do i just add the listeners here?
}
draw() {
this.ctx.beginPath();
this.ctx.rect(this.paddleX, this.canvas.height - this.paddleHeight, this.paddleWidth, this.paddleHeight);
this.ctx.fillStyle = "#0095DD";
this.ctx.fill();
this.ctx.closePath();
}
keyDownHandler(e) {
if (e.keyCode == 39) {
rightPressed = true;
}
else if (e.keyCode == 37) {
leftPressed = true;
}
}
keyUpHandler(e) {
if (e.keyCode == 39) {
rightPressed = false;
}
else if (e.keyCode == 37) {
leftPressed = false;
}
}
listener() {
document.addEventListener("keydown", this.keyDownHandler, false);
document.addEventListener("keyup", this.keyUpHandler, false);
}
}
Create object that contains properties keyDownHandler and keyUpHandler as a functions and keyDown and KeyUp as a constants in the module
// Module my-module.js
var foo={
rightPressed:false;
leftPressed:false;
keyDownHandler:function(e) {
if (e.keyCode == 39) {
this.rightPressed = true;
}
else if (e.keyCode == 37) {
this.leftPressed = true;
}
}
keyUpHandler:function(e){
if (e.keyCode == 39) {
this.rightPressed = false;
}
else if (e.keyCode == 37) {
this.leftPressed = false;
}
const keyDown= document.addEventListener("keydown", this.keyDownHandler, false);
const keyUp= document.addEventListener("keyup", this.keyUpHandler, false);
}
export {foo};
Import the Module
import{foo} from 'my-module';
Use the constants
foo.keyUp;
foo.keyDown;
You're really quite close - but in your keyHandler functions, you have this:
if (e.keyCode == 39) {
rightPressed = true;
}
There is no global variable rightPressed - it exists only in the class Paddle. Change your key handlers to this:
keyDownHandler(e) {
if (e.keyCode == 39) {
this.rightPressed = true; //Changed here
}
else if (e.keyCode == 37) {
this.leftPressed = true; //Changed here
}
}
keyUpHandler(e) {
if (e.keyCode == 39) {
this.rightPressed = false; //Changed here
}
else if (e.keyCode == 37) {
this.leftPressed = false; //Changed here
}
}
Now all you need to do is change the listener() function in Paddle like this:
listener() {
document.body.addEventListener("keydown", this.keyDownHandler(e), false);
document.body.addEventListener("keyup", this.keyUpHandler(e), false);
And create the instance of your class like this:
var player = new Paddle(world);
And you need to put all the functions into the constructor for it to work.
what wrong with my code
function move(x,y)
{
setInterval(function()
{
gameArea.clear();
gamePiece.x += x;
gamePiece.y += y;
gamePiece.update();
}, 100);
}
document.getElementsByTagName('body')[0].onkeyup = function(e)
{
var myInterval;
if(e.keyCode == 37)
{
move(10,0);
}
else if(e.keyCode == 38)
{
move(0,-10);
}
else if(e.keyCode == 39)
{
move(-10,0);
}
else if(e.keyCode == 40)
{
move(0,10);
}
}
This produce output i'm not expected, and the object can't move correctly.
Please help me to fixed this.
This is an excerpt from a js file
$searchBox.keyup(function(event) {
if (event.keyCode === 13) { //enter
if(currentResult > -1) {
var result = $searchResults.find('tr.result a')[currentResult];
window.location = $(result).attr('href');
}
} else if(event.keyCode === 38) { //up
if(currentResult > 0) {
currentResult--;
renderCurrent();
}
} else if(event.keyCode === 40) { //down
if(lastResults.length > currentResult + 1){
currentResult++;
renderCurrent();
}
} else {
var query = $searchBox.val();
if (lastQuery !== query) {
currentResult = -1;
if (query.length > 2) {
self.search(query);
} else {
self.hideResults();
}
if(self.hasFilter(getCurrentApp())) {
self.getFilter(getCurrentApp())(query);
}
}
}
});
This means that it should only perform the action if the "Enter", "Up" or "Down" keys are pressed, right? Because the search start happening as soon as any key is pressed.
I also tried changing searchBox.keyup to searchBox.change but that messed up how something else was working.
I put in the entire thing just in case
I went into chrome and looked for errors, and it wasnt working either so I checked, apparently the first line has a problem. I kept the first 6 lines and deleted all else then it worked fine, so I went to SublimeText2 and searched for every ) and } in the code.
var canvasBg = document.getElementById('canvasBg');
var ctxBg = canvasBg.getContext('2d');
var canvasJet = document.getElementById('canvasJet');
var ctxJet = canvasJet.getContext('2d');
var jet1;
var fps = 17;
var drawInterval;
var imgSprite = new Image();
imgSprite.src = 'SpriteSheet.png'
imgSprite.addEventListener('load',init,false);
function init() {
drawBg();
startDrawing();
jet1 = new Jet();
document.addEventListener('keydown',checkKeyDown,false);
document.addEventListener('keyup',checKeyUp,false);
}
function draw() {
jet1.draw();
}
function startDrawing() {
stopDrawing();
drawInterval = setInterval(draw,fps);
}
function stopDrawing() {
clearInterval(setInterval);
}
Jet.prototype.draw = function() {
clearCtxJet();
ctxJet.drawImage(imgSprite,this.srcX,this.srcY,this.width,this.height,this.drawX,this.drawY,this.width,this.height);
};
function Jet() {
this.srcX = 0;
this.srcY = 0;
this.drawX = 200;
this.drawY = 200;
this.width = 96;
this.height = 30;
}
function drawJet() {
}
function drawBg() {
ctxBg.drawImage(imgSprite,96,0,800,500,0,0,800,500)
}
function clearCtxBg() {
ctxBg.clearRect(0,0,800,500);
}
function clearCtxJet() {
ctxJet.clearRect(0,0,800,500);
}
function checkKeyDown(e) {
var keyID = (e.keyCode) ? e.keyCode : e.which;
if (keyID === 38) { // 38 is up key
alert('up arrow was pressed');
e.preventDeafault();
}
if (keyID === 39) { // 39 is right key
e.preventDeafault();
}
if (keyID === 40) { // 40 is down key
e.preventDeafault();
}
if (keyID === 37) { // 37 is left key
e.preventDeafault();
}
function checkKeyup(e) {
var keyID = (e.keyCode) ? e.keyCode : e.which;
if (keyID === 38) { // 38 is up key
alert('up arrow was pressed');
e.preventDeafault();
}
if (keyID === 39) { // 39 is right key
e.preventDeafault();
}
if (keyID === 40) { // 40 is down key
e.preventDeafault();
}
if (keyID === 37) { // 37 is left key
e.preventDeafault();
}
}
I assume you're showing only parts of the code so there's no way of knowing whether this is the actual error, but both checkKeyup and checkKeydown are missing closing braces.
I recommend installing Package Control for Sublime Text 2 and then using it to install SublimeLinter which will be able to check your code for you and point out missing semicolons and braces.
It would be nice to see full code in http://jsfiddle.net
So here is my snake script -
http://jsfiddle.net/6bKHc/24/
I started to create a snake game, but basically move(top), move(bottom) e.c. is not working. Any ideas why? I understand that I can't pass the elements to variable like this, so maybe you could show me how to do that correctly?
Ok cleared syntax and took a look at errors this should get you started
$(document).keydown(function(event){
var move, inter;
inter = setInterval(move = function() {
var dir = $(".snake").data('dir');
var snake = $('.snake');
if(dir == 'top') {
snake.stop().animate({"top": "+=5px"});
}
if(dir == 'bottom') {
snake.stop().animate({"top": "-=5px"});
}
if(dir == 'left') {
snake.stop().animate({"left": "+=5px"});
}
if(dir == 'right') {
snake.stop().animate({"top": "-=5px"});
}
}, 500);
if(event.which == 40) {
$(".snake").data('dir','top');
} else if(event.which == 39) {
$(".snake").data('dir','left');
} else if(event.which == 37) {
$(".snake").data('dir','right');
} else if(event.which == 38) {
$(".snake").data('dir','bottom');
}; });
fiddle
Couple of obvious additions to make:
boundary checking
smoothness of animation.
To make it work you will have to moodify your code like follows :
$(document).keydown(function() {
var inter;
return function(event) {
var move, prevDirection;
clearInterval(inter);
inter = setInterval(move = function(direction) {
var value, prop;
switch (direction || prevDirection) {
case "top":
prop = "top";
value = -5;
break;
case "bottom":
prop = "top";
value = 5;
break;
case "left":
prop = "left";
value = -5;
break;
case "right":
prop = "left";
value = 5;
break;
}
if (direction) prevDirection = direction;
$(".snake").css(prop, $(".snake").position()[prop] + value);
}, 500);
if (event.which == 40) {
move('bottom');
} else if (event.which == 39) {
move('right');
} else if (event.which == 37) {
move('left');
} else if (event.which == 38) {
move('top')
};
}
}());
http://jsfiddle.net/6bKHc/42/