I am currently watching a bunch of introductory videos about using the canvas tag in HTML5 to create simple 2d games.
As I was following the video code - precisely - there was an error somewhere along the way. I tried to draw a rectangle in the canvas that would respond to the navigation buttons and move accordingly.
Here is the main game code:
function game() {
update();
render();
}
function update() {
//This is the code that I think is causing an error
if(keys[38]) player.y--;
if(keys[40]) player.y++;
if(keys[37]) player.x--;
if(keys[39]) player.x++;
}
function render() {
context.fillRect(player.x, player.y, player.width, player.height);
}
setInterval(function(){
game();
}, 1000/30);
The site runs perfectly fine when I load it, but it doesn't respond to the user clicks. Thanks for any help in advance.
Below is the keys array that adds an indexed value every-time a the navigation keys are pressed:
var keys = [];
window.addEventListener('keydown', function(e){
keys[e.keycode] = true;
}, false);
window.addEventListener('keyup', function(e){
delete keys[e.keycode]
}, false);
It seems like you're using the .keycode property, all lower case, in your event handlers. That property doesn't exist. Instead, try using the .keyCode property, with a capital C.
Using a nonexistent property returns undefined, so that would always execute keys[undefined] = true and keys[undefined] = false.
It doesnt respond to mouse interactions because you just assigned key codes. i assume you can control the rectangle with the arrow keys?
which framework are you using?
Related
everytime I resume some scene, the main character keeps walking along, because I think it's remember the movement from before the scene was paused. I set the velocity.x and velocity.y to 0 before pause the scene. But doesn't works. Any idea? Thanks!
Here is my code:
function workPopUp (){
this.scene.pause();
this.scene.launch('popup');
this.work.destroy();
}
This is the normal behaivor of velocity:
if (this.cursorKeys.left.isDown)
{
this.kid.setVelocityX(-200);
this.kid.anims.play('left', true);
}
else if (this.cursorKeys.right.isDown)
{
this.kid.setVelocityX(200);
this.kid.anims.play('run', true);
}
else
{
this.kid.setVelocityX(0);
this.kid.anims.play('idle', true);
};
if (this.cursorKeys.up.isDown && this.kid.body.touching.down)
{
this.kid.setVelocityY(-480);
this.kid.anims.play('jump', true);
}
if(this.cursorKeys.up.isDown && this.cursorKeys.right.isDown){
this.kid.anims.play('jump', true);
}else if(this.cursorKeys.up.isDown && this.cursorKeys.left.isDown){
this.kid.anims.play('jump', true);
}
UPDATE
I still don't know why it was happening, so I'd love if someone else could find a better way, but I did find a way to stop it.
In the tutorial I reference below, they had you add a wake function to reset the cursor keys by putting this line into your create:
this.sys.events.on('wake', this.wake, this);
And then this function:
wake: function() {
this.cursors.left.reset();
this.cursors.right.reset();
this.cursors.up.reset();
this.cursors.down.reset();
},
As I said, that didn't work for me. So instead, I set a boolean in my wake function:
wake: function() {
this.sleeping = true;
},
and then in my Update function, I check for the bool and reset the keys there:
update: function (time, delta)
{
if (this.sleeping)
{
this.sleeping = false;
this.cursors.left.reset();
this.cursors.right.reset();
this.cursors.up.reset();
this.cursors.down.reset();
}
Like I said, this works when putting the reset in my wake function didn't. Somewhere between my wake function running and the first update, the cursor was being updated to down, but I can't figure out where.
Hope this helps.
Original Post
I'm having the same problem and I think it's some change in the a recent version of Phaser 3.
I followed this tutorial:
https://gamedevacademy.org/how-to-create-a-turn-based-rpg-in-phaser-3-part-3/
The tutorial mentions having this problem where the sprite is moving after the scene resumes and adding an on wake function to reset the cursor keys. That wasn't working for me.
I downloaded the source code from the tutorial and found it didn't have this issue, but I noticed that the source code comes with a phaser.min.js whereas I was referencing the latest version online in my html file. When I updated the tutorial source code to use the latest version, the issue occurred.
Hope this context helps, I'll continue to troubleshoot and update if I find the issue.
I had similar problem with in my game when pausing and resuming the scene, so if I was pressing a key and paused the game, after resuming the player would continue the movement event if I was not pressing the key anymore.
So this is what I did
in my playScene add an event on pause
this.sys.events.on("pause, () => { this.player.sleep() })
in my player class created a function to reset all the key values that is called whenever the scene is paused
sleep() {
this.keys.left.reset();
this.keys.right.reset();
this.keys.up.reset();
this.keys.down.reset();
this.keys.jump.reset();
this.keys.fire.reset();
}
Probably there is a better way of handling this, but for what I want at the moment it works
In OpenLayer 3 I create a Draw interaction using the 'draw-feature' sample code they have on their website.
The only difference is that I supply my own condition function to the Draw constructor.
I would like to know if there is a way to determine within the condition function if the interaction/drawing has started?
Basically my goal is to change the behavior slightly so drawing a box is initiated with a CTRL-click rather than a click. But ending the drawing can be done with a simple click. So my approach would be something like this (in TypeScript)
var condition = (e: ol.MapBrowserEvent): boolean => {
return (myDraw.isStarted() ? true : e.originalEvent['ctrlKey']);
}
As far as I can see there's nothing like an isStarted() method in OL Draw class. If I had access to internal members I would resolve it by checking the length of myDraw.sketchCoords_ (haven't checked this but if 0 the drawing is not started yet). But I don't want to rely on private members, furthermore I'm using the minified version of OL where members names are transformed.
Try something like this:
var start_drawing = false;
function drawCondition(evt){
var ctrl = ol.events.condition.platformModifierKeyOnly(evt);
// this should be ol.events.condition.click
// but for some reason always returns false
var click = evt.type == 'pointerdown';
// to finish draw with click
if(start_drawing) return click;
// start drawing only with Ctrl + click
return ctrl && click;
}
// draw is a reference to ol.interaction.Draw
draw.on('drawstart', function(evt){
start_drawing = true;
});
draw.on('drawend', function(evt){
start_drawing = false;
});
I am trying to call a function when a constantly changing element becomes a certain value.
When player.getCurrentTime() >= 0.95 * player.getDuration() I want to call handleEvent(). What would the best way to do this be?
This is what the latest iteration of my try:
window.onLoad=function() {
var player = document.getElementById("movie_player");
player.addEventListener("customEvent", handleEvent(), false);
function handleEvent() {
// do something here
}
var myEvent = new CustomEvent("customEvent", {
detail: {
time: 0.95 * getDuration()
}
});
document.body.dispatchEvent(myEvent);
}
How would I accomplish this?
I am guessing you are using YouTube player. As per its API, there is an YT.PlayerState.PLAYING event that you can use to keep track of your getCurrentTime(). Take a look at the below code:
player.addEventListener(YT.PlayerState.PLAYING, onVideoPlaying, false);
function onVideoPlaying(){
console.log('video is playing');
if (player.getCurrentTime() >= 0.95 * player.getDuration()){
console.log('Here I am!');
// do Something
}
}
Also, I do not think you need to dispatchEvent yourself because as mentioned above, player is already dispatching a continuously changing event which you can utilize.
Let me know if anything is unclear or if I have missed out on any detail.
You are already using Custom Events and that code seems nearly correct, just remove the parentheses or i doubt it will work:
player.addEventListener("customEvent", handleEvent, false);
I am making a javascript canvas drawing program and I want the user to be able to choose between the pencil tool, circle tool and clearing screen on keypress.
In the following code the variable key_press holds the users selection. The whole program does not work when I don't assign anything to the variable, so I made the default value = pencil(). But now I cant use anything but pencil.
I post only relevant code here, but it is full in this jsfiddle
var canvas, context, tool, key_press;
// check for key press
window.addEventListener('keydown',function(event){
key_press= String.fromCharCode(event.keyCode);
},false);
function init () {
canvas = document.getElementById('canvas');
context = canvas.getContext('2d');
//check user selection
if (key_press === "1") {
tool = new Pencil();
} else if (key_press === "2") {
tool = new Circle();
} else if (key_press === "3") {
canvas.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
tool = new Pencil();
} else tool = new Pencil(); //this part is probably causing the problem, but clear screen (selection 3) does not work either so it could be something different.
//onmouse calls and end of init()
}
//basically just two functions after init for the tools
function Pencil () {
//...
}
function Circle() {
//...
}
//calling main function init()
init();
Obviously the way I handle user input is bad. Could you point me in the right direction as to what I am doing wrong?
Your distance calculation wasn't working because you left off a , 2 in the second Math.pow call.
Your jsfiddle wasn't working because the default on a new fiddle is to run in window.load, but you then added another load event listener that never fired.
I've changed the code to reflect these changes (and make the context.arc call use the distance rather than z) and it appears to work:
http://jsfiddle.net/rWV5h/1/
I'm attempting to create a simple program that sequentially displays a number of letters where each letter is presented alone (see the figure below). I'm also attempting to make the program work in such a way that the user needs to press a key on the keyboard before the next letter is presented.
I'm trying to do this by encapsulating each letter presentation within a single, almost self-contained function (singleTrial). My problem is is that I can't figure-out how to stop the singleTrial function from returning unless a key press is made (see the waitForResponse function). In this case, when the function returns, the next function call to SingleTrial is executed, making it so that only the second letter is displayed (because the first letter gets presented and then cleared in almost an instant). What am I doing wrong here? How can I make it so that the singleTrial function does not return unless a key press is made?
My ultimate goal is to make it so that I can iterate though a letter list, presenting each letter sequentially:
letterList.forEach(function(stim) {
singleTrial(stim);
});
Thanks in advance!
Here is my code:
var responseMade;
function onResponse() {
responseMade = true;
}
function singleTrial(stim, context, canvas) {
responseMade = false;
context.clearRect(0, 0, canvas.width, canvas.height);
window.removeEventListener('keydown', onResponse, false);
context.clearRect(0, 0, canvas.width, canvas.height);
context.fillText(stim, 100, 10);
window.addEventListener('keydown', onResponse, false);
function waitForResponse() {
if (responseMade == false) {
setInterval(waitForResponse, 1000);
}
}
waitForResponse();
}
function main() {
var canvas = document.getElementById('canvas'),
context = canvas.getContext('2d');
singleTrial("A", context, canvas);
singleTrial("B", context, canvas);
}
main()
</script>
I can't figure-out how to stop the singleTrial function from returning unless a key press is made
You can't (currently; ES6's "generators" will offer a way to do it, but it still wouldn't be the best way here). Instead, what you do is hook up an event handler for when a key is pressed, and generate the next letter when that event occurs. This is a key concept in web (and other) programming: Rather than your program working in some set loop, you wait for and respond to events that occur.
For instance, remove waitForResponse from singleTrial, and change main:
function main() {
var canvas = document.getElementById('canvas'),
context = canvas.getContext('2d'),
nextLetter = "A".charCodeAt(0);
document.addEventListener("keydown", function() {
singleTrial(String.fromCharCode(nextLetter), context, canvas);
++nextLetter;
}, false);
}
(You'll need to handle the addEventListener / attachEvent thing if you need to support old IE. From the canvas, I'm thinking you don't.)