Hello everyone,
I'm currently having issues making the arrow keys working correctly while pressing [space] key. Everything is working whle holding [space] key and one of the arrow keys. But if I try to press [space] and hold [up] and [left] at the same time , it will go straigh to the top of the screen as if the [left] key wasn't even pressed (it should move diagonally to the top left corner). This is only happening while pressing [space].
I'd like to use this key for shooting bullets later on.
Is there something wrong in my code? Or is it some kind of bug?
Apologies for my bad english :/ ..
<!DOCTYPE html>
<body>
<canvas id="myCanvas" width="568" height="262">
</canvas>
<script type="text/javascript">
var canvas;
var ctx;
var dx = 0.5;
var dy = 0.5;
var x = 284;
var y = 130;
var WIDTH = 568;
var HEIGHT = 262;
var keys = new Array();
function circle(x,y,r) {
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI*2, true);
ctx.fill();
}
function rect(x,y,w,h) {
ctx.beginPath();
ctx.rect(x,y,w,h);
ctx.closePath();
ctx.fill();
ctx.stroke();
}
function clear() {
ctx.clearRect(0, 0, WIDTH, HEIGHT);
}
function init() {
canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
window.addEventListener('keydown',doKeyDown,true);
window.addEventListener('keyup',doKeyUp,true);
return setInterval(draw, 1);
}
function draw() {
move();
clear();
ctx.fillStyle = "white";
ctx.strokeStyle = "black";
rect(0,0,WIDTH,HEIGHT);
// player ///
ctx.fillStyle = "purple";
circle(x, y, 20);
}
function doKeyDown(evt)
{
keys[evt.keyCode] = true;
evt.preventDefault(); // Prevents the page to scroll up/down while pressing arrow keys
}
function doKeyUp(evt){
keys[evt.keyCode] = false;
}
function move() {
if (32 in keys && keys[32]){
; // fire bullets
}
if (38 in keys && keys[38]){ //up
y -= dy;
}
if (40 in keys && keys[40]){ //down
y += dy;
}
if (37 in keys && keys[37]){ //left
x -= dx;
}
if (39 in keys && keys[39]){ //right
x += dx;
}
}
init();
</script>
</body>
</html>
Odds are this is nothing to do with your code. Many keyboards, to save cost, are not capable of supporting every combination of 3 or more keys at once, and are specifically wired to support combinations that are in common use (such as Ctrl+Alt+Del). The phenomenon is known as "ghosting".
See this page from Microsoft for an expanded explanation.
I had the same issue (I found the issue but not the solution) the key codes for up and left follow each other. so do down and right. The fact that the key codes follow each other seems to be the issue. if you set A to move player UP and B to move player DOWN, then press A+B+spaceBar the same issue occurs. but when the key codes are different (e.g. wasd) the three button press works. using WASD might seem like a good idea but wait until someone using a French keyboard plays your game.
Any way I wrote this hoping that someone would find a work around.
Related
This question already has answers here:
how to skew image like this
(5 answers)
Closed 10 months ago.
i am trying to make a simple canvas game in jquery,
basically, i have an infinite loop that constantly draws the player and background:
loop = () => {
$('#player').css("transform", "rotateX("+xr+"deg) rotateY("+yr+"deg)");
ctx.fillStyle = 'gray';
ctx.fillRect(0,0,400,400);
ctx.drawImage(player, x, y, 50, 50);
window.setTimeout(loop, 1);
}
And then i have a switch statement that alters the player's XR and YR when they push the A and D buttons:
$(document).ready(()=>{
loop();
$(document).bind('keydown',(e)=>{
switch(e.keyCode){
case 65:
//moving left (altering the xr and yr values)
break;
case 87:
//moving up (altering the y and x values based on SIN and COS and player's XR and YR)
break;
etc...
}
});
});
i can tell it's detecting the key pushes, because when i run CONSOLE.LOG() in the switch statement, it prints something to the console,
so clearly this is a problem with images drawn to a canvas not keeping their css styling.
if anybody can figure out how to keep an image's css when drawing it to a canvas, or alter an image draw in a canvas's css, that would be great.
and no, i didn't find any answers anywhere else. this question doesn't seem to have been asked yet.
EDIT: xr and yr are XROTATION and YROTATION variables.
apparently, images don't keep their css in canvases, and there is no way to add this. never mind, guess i'll try something else.
You don't need CSS, you can do everything with the Canvas, you have translate and rotate methods. Here a very basic example:
const ctx = canvas.getContext("2d");
const { width: w, height: h } = canvas;
let x = (w - 50) >> 1, y = (h - 50) >> 1;
let angle = 0;
const Keys = {
pressed: {},
handleEvent({type, code}) {
this.pressed[code] = type === "keydown"
}
}
document.addEventListener("keydown", Keys);
document.addEventListener("keyup", Keys);
function update() {
if (Keys.pressed["ArrowLeft"]) {
--angle;
}
if (Keys.pressed["ArrowRight"]) {
++angle;
}
}
function draw() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, w, h);
ctx.translate(x + 25, y + 25);
ctx.rotate(angle * Math.PI / 180 );
ctx.drawImage(player, -25, -25, 50, 50);
ctx.setTransform(1, 0, 0, 1, 0, 0);
}
let player = new Image();
player.src = "https://1.bp.blogspot.com/-ddkcnhuU07g/Vllq4DNohkI/AAAAAAAACHo/p8d9SZxOy-w/s1600/mship1.png";
requestAnimationFrame(function render() {
update();
draw();
requestAnimationFrame(render);
})
<canvas id="canvas" width="320" height="240"></canvas>
I'm trying to make a basic 2d game with p5js and p5.play. An issue that seems to cause issues every time I try to do anything is the keyIsDown function. Is there a way to determine if a key is down before pressing it? If I used
upKey = keyIsDown(UP_ARROW);
upKey will show as undefined until I press the up arrow. Is there any way to assign the respective boolean values to these types of things prior to pressing them?
As of now, my game will not properly work until I have pressed every involed key one time.
The keyIsDown() function checks if the key is currently down, i.e. pressed. It can be used if you have an object that moves, and you want several keys to be able to affect its behaviour simultaneously, such as moving a sprite diagonally.
Note that the arrow keys will also cause pages to scroll so you may want to use other keys for your game.. but if you want to use arrow keys this is the code snippet from the reference page
let x = 100;
let y = 100;
function setup() {
createCanvas(512, 512);
}
function draw() {
if (keyIsDown(LEFT_ARROW)) {
x -= 5;
}
if (keyIsDown(RIGHT_ARROW)) {
x += 5;
}
if (keyIsDown(UP_ARROW)) {
y -= 5;
}
if (keyIsDown(DOWN_ARROW)) {
y += 5;
}
clear();
fill(255, 0, 0);
ellipse(x, y, 50, 50);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.min.js"></script>
To implement similar logic without the use of arrow keys you will need to determine the key code of the keys you want to use.
Here is an example that uses awsd keys and also logs out the key code of the currently pressed key.
let x = 50;
let y = 50;
function setup() {
createCanvas(512, 512);
}
function keyPressed(){
console.log(keyCode);
}
function draw() {
if (keyIsDown(65)) {
x -= 5;
if (x < 0) x = 0;
}
if (keyIsDown(68)) {
x += 5;
if (x > width) x = width;
}
if (keyIsDown(87)) {
y -= 5;
if (y < 0) y = 0;
}
if (keyIsDown(83)) {
y += 5;
if ( y > height) y = height;
}
clear();
fill(255, 0, 0);
ellipse(x, y, 50, 50);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.min.js"></script>
I am writing a game in progress and I ran into a little problem. I am using the keyPressed function and when I am moving the the left, then I suddenly and quickly start moving to the right, my rectangle just stops (vice versa). There will be dodging in my game, so it is important to be able to switch direction as fast as possible. What should I do?
//main file, sketch.js:
var person;
function setup() {
createCanvas(380, 720);
person = new Person();
}
function draw() {
background(64, 64, 64);
person.show();
person.move();
}
function keyReleased() {
if (keyCode === LEFT_ARROW || keyCode === RIGHT_ARROW) {
person.setDirX(0);
}
}
function keyPressed() {
if (keyCode === RIGHT_ARROW) {
person.setDirX(1)
}
else if (keyCode === LEFT_ARROW) {
person.setDirX(-1);
}
}
//person(rectangle) file, person.js:
function Person() {
this.x = width/2;
this.y = height - 20;
this.xdir = 0;
this.ydir = -0.25;
this.show = function() {
noStroke();
fill(250);
rectMode(CENTER);
rect(this.x, this.y, 25, 25);
}
this.setDirX = function(dir) {
this.xdir = dir;
}
this.move = function(dir) {
this.x += this.xdir * 5;
this.y += this.ydir;
}
}
Try to think about what keys you're pressing and releasing when you quickly go from holding in left to holding in right. This is what you're doing:
First you hold down left.
Then you hold down right. So for a split second you're holding down both keys.
Then you let go of left, but continue holding down right.
Your code detects that you released the left key and sets the movement speed to 0, which is why you stop moving.
To fix this, you're going to want to keep track of which keys are currently pressed. You do this by keeping track of a boolean variable for each key you care about, setting those booleans in your keyPressed() and keyReleased() function, and checking those booleans in the draw() function.
Shameless self-promotion: I wrote a tutorial on using this approach here. See the section titled "Handling Multiple Keys". This tutorial is for Processing, but the same idea applies to P5.js.
Hey I have a simple triangle in canvas, and I would like to add listener to each triangle's point, so that if user click each point an action will happen.
I would like to know if such procedure is possible in canvas, if not what my alternatives? so my main question is as follows:
Can I add a listener on canvas single points? if not what are my alternatives?
Update:
I have tried my luck and succeed in adding click event on the all canvas and then get current points of mouse click,but my solution isn't final and very not precious.
Can I create an area around each point which is clicked so the user will not have to be precious in his clicks?
http://codepen.io/Barak/pen/VadQYm
$(function(){
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var triangle = [{ x: 58, y: 845 }, { x: 984, y: 845 }, { x: 521, y: 41 }];
drawTriangle(triangle);
function drawTriangle(t) {
ctx.beginPath();
ctx.moveTo(t[0].x, t[0].y);
ctx.lineTo(t[1].x, t[1].y);
ctx.lineTo(t[2].x, t[2].y);
ctx.closePath();
ctx.strokeStyle = 'black';
ctx.lineWidth = 2;
ctx.stroke();
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="canvas-wrapper">
<canvas id="canvas" width=1024 height=980></canvas>
</div>
There is no single point you could attach an event to in your canvas - it is just a drawing Api - a container for your Image (See W3School for further reference).
But if you have the coordinates, of course you can always detect the clicked position in your Canvas.
I made you a fiddle, to show the possible solution.
canvas.addEventListener("mousedown", doMouseDown, false);
function doMouseDown(e) {
for (i = 0; i < triangle.length; ++i) {
if ((e.x triangle[i].x) && (e.y === triangle[i].y)) {
console.log('you hit an edge!');
}
}
}
Update:
If you want to create a tolerance, you have to define the plus and the minus of the actual position you want to accept. A simple and not elegant way could be the following:
function tolerance(number){
//define the tolerance here
var tolerance = 15;
//all the accepted numbers within the tolerance will be in this array
var numberArray=[];
for(i=0;i<(tolerance)*2;++i){
if(i >= tolerance){
if(i!=tolerance){
numberArray[i] = numberArray[i-1]-1;
}else{
numberArray[i] = number -1;
}
}else{
if(i!=0){
numberArray[i] = numberArray[i-1]+1;
}else{
numberArray[i] = number +1;
}
}
}
//don't forget to put the actual number in the array
numberArray.push(number);
return numberArray;
}
You can now change the doMouseDown function to look something like this:
function doMouseDown(e) {
for (k = 0; k < triangle.length; ++k) {
if ((tolerance(triangle[k].x).indexOf(e.x)!=-1) && (tolerance(triangle[k].y).indexOf(e.y)!=-1)) {
console.log('you hit an edge!');
}
}
}
I want to create a Canvas in which there will be two areas (Left and right), Left panel will contain some shapes which will be draggable(static as well) and on the right side I would be able to drop them, but I am facing following problem,
I am not able to make the shapes which i draw on the left side, draggable, because there is no id associated with them.
I do not know how to make some particular area droppable.
Here is code to visualize what I am trying to achieve-
<body>
<canvas id="myCanvas" width="800" height="600" style="border:1px solid #000000;">
</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.moveTo(250,0);
ctx.lineTo(250,600);
ctx.stroke();
ctx.fillStyle = "#FF0000";
ctx.fillRect(50,50,160,25);
ctx.fillStyle = "#0000FF";
ctx.font = "15px";
ctx.strokeText("Draggable Elements here",57,67);
ctx.fillStyle = "#FF0000";
ctx.fillRect(500,50,130,25);
ctx.font = "15px";
ctx.strokeText("Droppable area Here",510,67);
</script>
</body>
Here is the JS fiddle for the same -
http://jsfiddle.net/akki166786/4tfyy4o5/
so if anybody can shed some light on how can I achieve this, it will be a great help.
Thanks in Advance
Drag and drop in specifik area
UPDATE: Copy of box remains at original position while it's being moved.
First you need to be able to detect your rectangles. You do this by making then into objects in your code:
function box(x,y,w,h,rgb) {
this.x = x,
this.y = y;
this.xS = x; //saving x
this.yS = y; //saving y
this.w = w;
this.h = h;
this.rgb = rgb;
//to determine if the box is being draged
this.draging = false;
}
No you need to add an event listener to determine if someone is clicking, you also need to determine if the person clicked in one of your boxes.
c.addEventListener("mousedown",down);
c.addEventListener("mousemove",move);
c.addEventListener("mouseup",up);
So events have been made to detect when the mouse button is pressed down, released back up and if the mouse moves within the canvas. To these events we have functions, down(), move() and up(), ready to be executed.
All functions will be visible in the example below.
When we're happily draging our boxes and releasing our mouse button, we need to check if the box was dropped in the dropable area. We do this in the up()-function. If the drop was OK, the box can stay, otherwise we send it back to where it came from.
Working example
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
c.width = 600;
c.height = 300;
//My mouse coordinates
var x,y;
c.addEventListener("mousedown",down);
c.addEventListener("mousemove",move);
c.addEventListener("mouseup",up);
//I'll save my boxes in this array
var myBoxes = new Array();
//This function describes what a box is.
//Each created box gets its own values
function box(x,y,w,h,rgb) {
this.x = x,
this.y = y;
this.xS = x; //saving x
this.yS = y; //saving y
this.w = w;
this.h = h;
this.rgb = rgb;
//to determine if the box is being draged
this.draging = false;
}
//Let's make some boxes!!
myBoxes[0] = new box(10,10,50,100,"green");
myBoxes[1] = new box(80,50,100,75,"blue");
myBoxes[2] = new box(40,150,20,70,"yellow");
//here we draw everything
function draw() {
ctx.clearRect(0,0,c.width,c.height);
//Dropable area
ctx.fillStyle="red";
ctx.fillRect(c.width/2,0,c.width,c.height);
//Boxes!
for (var i = 0; i<myBoxes.length; i++) {
var b = myBoxes[i];
//NEW CODE FOR UPDATE
if (b.draging) { //box on the move
//Also draw it on the original spot
ctx.fillStyle="grey"; //I chose a different color to make it appear more as a shadow of the box that's being moved.
ctx.fillRect(b.xS,b.yS,b.w,b.h);
ctx.strokeRect(b.xS,b.yS,b.w,b.h);
}
//End of new code for update
ctx.fillStyle=b.rgb;
ctx.fillRect(b.x,b.y,b.w,b.h);
ctx.strokeRect(b.x,b.y,b.w,b.h);
}
//Let's keep re-drawing this
requestAnimationFrame(draw);
}
function down(event) {
event = event || window.event;
x = event.pageX - c.offsetLeft,
y = event.pageY - c.offsetTop;
for (var i = 0; i<myBoxes.length; i++) {
var b = myBoxes[i];
if (x>b.x && x<b.x+b.w && y>b.y && y<b.y+b.h) {
b.draging = true;
}
}
}
function move(event) {
event = event || window.event;
x = event.pageX - c.offsetLeft,
y = event.pageY - c.offsetTop;
for (var i = 0; i<myBoxes.length; i++) {
var b = myBoxes[i];
if (b.draging) {
b.x = x;
b.y = y;
}
}
}
function up(event) {
event = event || window.event;
x = event.pageX - c.offsetLeft,
y = event.pageY - c.offsetTop;
for (var i = 0; i<myBoxes.length; i++) {
var b = myBoxes[i];
if (b.draging) {
//Let's see if the rectangle is inside the dropable area
if (b.x>c.width/2) {
//Yes is it!
b.x = x;
b.y = y;
b.draging = false;
}
else {
//No it's not, sending it back to its ordiginal spot
b.x = b.xS;
b.y = b.yS;
b.draging = false;
}
}
}
}
draw();
canvas {
border: 1px solid black;
}
<canvas id="canvas"></canvas>
You're using just one canvas, maybe it would be better if you use two separate canvas, one for each element you want to handle on page. so you'll have one element ID for each one.
plus. if your drawing is simple, consider using a div for it instead a canvas
Once drawn to the canvas, shapes(or lines, images, everything) are no longer accessible.
What you will need to do is store each shape in an object in your code. For example:
var rectangle = {
width: 100,
height: 100,
x: 50,
y: 50
}
Then when you drag rectangle, you will need to update it's x and y properties on mouseup (or while it's being dragged if you want a drag preview).