A* Start path finding in HTML5 Canvas - javascript

I'm trying implement A* Start path finding in my games(which are written with JavaScript, HTML5 Canvas). Library for A* Start found this - http://46dogs.blogspot.com/2009/10/star-pathroute-finding-javascript-code.html and now I'm using this library for path finding.
And with this library, I'm trying write a simple test, but stuck with one problem.
I'm now done when in HTML5 canvas screen click with mouse show path until my mouse.x and mouse.y. Here is a screenshot:
(Pink square: Player, Orange squares: path until my mouse.x/mouse.y)
Code how I'm drawing the orange squares until my mouse.x/mouse.y is:
for(var i = 0; i < path.length; i++) {
context.fillStyle = 'orange';
context.fillRect(path[i].x * 16, path[i].y * 16, 16, 16);
}
My problem is I do not understand how to move my player until path goal.
I've tried:
for(var i = 0; i < path.length; i++) {
player.x += path[i].x;
player.y += path[i].y;
}
But with this code my player is not beung drawn.(When I run the code, player.x and player.y are equals to 0 and when I click with the mouse I get the path player blink and disappear)
Maybe anyone know how to solve this problem?
And I'm very very very sorry for my bad English language. :)

My Working Fiddle
This is what I currently use which is based off of my a*. The concept should be the same though. The a* function should return the path as an array, then you just need to iterate through the path on each player update and move them.
// data holds the array of points returned by the a* alg, step is the current point you're on.
function movePlayer(data, step){
step++;
if(step >= data.length){
return false;
}
// set the player to the next point in the data array
playerObj.x = data[step].x;
playerObj.y = data[step].y;
// fill the rect that the player is on
ctx.fillStyle = "rgb(200,0,0)";
ctx.fillRect(playerObj.x*tileSize, playerObj.y*tileSize, tileSize, tileSize);
// do it again
setTimeout(function(){movePlayer(data,step)},10);
}​

Related

Colision detection p5.js

just trying to make a simple pong game in p5.js. I have very recently gotten into JavaScript and can't manage to figure out collision detection between the ball and the bat. I have tried a few ways of doing it but it mostly just stopped my code from running.. etc.. would love any help!
Here is my source code:
function setup() {
createCanvas(750, 750);
}
var x = 50;
var y = 50;
var direction = 5;
var arrow = 0;
var ball;
var bat;
function draw() {
background(220);
fill ('white');
ball = ellipse (x, y, 50, 50);
x = x + direction;
if (x > width - 25){
direction = -5;
}
if (x < 25) {
direction = 5;
}
x++;
y++;
if (keyIsDown(RIGHT_ARROW)){
arrow += 7;
}
if (keyIsDown(LEFT_ARROW)){
arrow += -7;
}
fill ('black');
bat = rect(arrow, 600, 150, 15);
}
Your question is pretty broad, but basically what you want to do is imagine a "bounding rectangle" around the ball, and then use rectangle-rectangle collision to check whether the ball is colliding with a paddle. If it is, "bounce" the ball by multiplying its horizontal speed by -1.
I wrote a tutorial on collision detection available here, but the basic if statement looks like this:
if(rectOneRight > rectTwoLeft && rectOneLeft < rectTwoRight && rectOneBottom > rectTwoTop && rectOneTop < rectTwoBottom){
You also might want to read the Collision Detection with Moving Objects section of that tutorial. It's written for Processing, but everything applies to P5.js as well.
If you're having trouble getting it working, then please start over with a more basic sketch that just shows two hard-coded rectangles. Make them turn red when they're not colliding. Then work your way up from there. It's hard to answer general "how do I do this" type questions, so you'll have much better luck if you post a specific "I tried X, expected Y, but got Z instead" type question. Good luck.

How to Implement Back-Face Culling in a 3D Javascript Engine

Recently I've been working on creating a 3D graphics engine in Javascript. Currently, the camera can move in the x, y, and z axis (working on learning how to rotate the camera) and shapes can be rotated. Shapes are generated based on groups of vertices that make up a face.
An example of the drawing code for the shapes is as below:
function renderShapes() {
for (i = 0; i < objects.length; i++) { // For each object
for (j = 0; j < objects[i].faces.length; j++) { // For each face
var face = objects[i].faces[j];
var P = project(face[0],objects[i].type);
if (P == false) { // project the coordinates based on camera.
continue;
}
ctx.beginPath();
ctx.moveTo(P.x + cx, - P.y + cy); // Start line at first vertex
// Draw the other vertices that make up the face
for (l = 0; l < face.length; l++) {
P = project(face[l],objects[i].type);
if (P == false) {
continue;
}
ctx.lineTo(P.x + cx, -P.y + cy); // Draw line to the next vertex
}
// Close the path and draw the face
ctx.closePath();
ctx.stroke();
if (objects[i].color != undefined) { // Fill in a color if the object has color property
ctx.fillStyle = objects[i].color;
ctx.fill();
}
}
}
}
This above code, generates something roughly like this depending on how I rotate it:
Everything works perfectly, except that all faces are drawn, and based on their order in the object array, may overlap one or the other. The red cube is an example of my problem. The blue diamond is an example of what I want to achieve, clean faces that are only rendered based on what the camera can see. Instead of rendering all 8 faces of the diamond, it should only render the 4 visible ones. Instead of rendering all 6 faces of the cube, it should only render the 2 visible ones.
I have researched into it to find back-face culling, although the examples were either non-existent, in the wrong language, or simply hard to understand or fit into my case.
Can anyone explain to me, in layman's terms how back-face culling works? And if possible, a Javascript example of it that could be implemented into my code?
Alternatively, is there a different word or phrase for what I'm trying to achieve or a different process or algorithm that would be better suited?
Thanks

Making a rectangle bounce off a canvas wall

All I need is to have this object travel left and right across the top of the canvas. Currently it spawns and travels right absolutely fine, then stops once it reaches the right edge of the canvas.
//mainEnemy Variables
var mainEnemy_x = 10;
var mainEnemy_y = 10;
var mainEnemyHeight = 50;
var mainEnemyWidth = 25;
var mainEnemyRight = true;
var mainEnemyLeft = false;
var mainEnemy_dx = 2;
//Drawing the Main Enemy
function drawMainEnemy()
{
ctx.beginPath();
ctx.rect(mainEnemy_x, mainEnemy_y, mainEnemyHeight, mainEnemyWidth);
ctx.fillStyle = "green";
ctx.fill();
ctx.closePath();
}
//Movement speed of mainEnemy
if(mainEnemyRight && mainEnemy_x < canvas.width-mainEnemyWidth)
{
mainEnemy_x += 5;
}
else if(mainEnemyLeft && mainEnemy_x > 0)
{
mainEnemy_x -= 5;
}
//mainEnemy moves across the top of the canvas
if(mainEnemy_x + mainEnemy_dx - mainEnemyWidth > canvas.width)
{
mainEnemy_dx = -mainEnemy_dx;
}
ball_x += dx;
ball_y += dy;
mainEnemy_x += mainEnemy_dx;
}
This is all the code relevant to the object I need help with. I've tried just reversing it's x movement, with the mainEnemy_dx = -mainEnemy_dx; line, but this isn't working. I can see this code is an absolute mess at the moment, I just need to get it working then time for some serious cleanup.
Any and all help would be greatly appreciated!
First of all, you have two movement systems. One with the left and right flags and constants added or subtracted from x and the other with dx. You should just use one or the other, the latter being simpler.
For the jitter, you have to either also check that the current dx is positive when going over the right by border (and negative on left) and then switch the sign, or move the object left when a collision with right border is found.
At the moment you are moving the object 7 units right every time, then when border is found only dx is used (2 or -2) but since your object can be over the border it might vibrate between 2 and -2 always. But at least the right branch will always try to move 5 units right even when dx is negative.
Using a debugger to step through the code and inspecting the variables and branches taken while vibrating on the right edge will show exactly how it behaves.

Canvas water/blob physics on a circular path with texture?

this is my first question after having relied on this site for years!
Anyway, I'd like to accomplish something similar to this effect:
http://www.flashmonkey.co.uk/html5/wave-physics/
But on a circular path, instead of a horizon. Essentially, a floating circle/blob in the center of the screen that would react to mouse interaction. What I'm not looking for is gravity, or for the circle to bounce around the screen - only surface ripples.
If at all possible I'd like to apply a static texture to the shape, is this a possibility? I'm completely new to Canvas!
I've already tried replacing some code from the above example with circular code from the following link, to very limited success:
http://www.html5canvastutorials.com/tutorials/html5-canvas-circles/
If only it were that easy :)
Any ideas?
Thanks in advance!
I tried to figure out how wave simulation works using View Source and JavaScript console. It's working fine but threw some JS errors. Also, it seems physics update is entangled with rendering in the render() method.
Here is what I found about the code:
The mouseMove() method creates disturbances on the wave based on mouse position, creating a peak around the mouse. The target variable is the index of the particle that needs to be updated, it's calculated from mouse pos.
if (particle && mouseY > particle.y) {
var speed = mouseY - storeY;
particles[target - 2].vy = speed / 6;
particles[target - 1].vy = speed / 5;
particles[target].vy = speed / 3;
particles[target + 1].vy = speed / 5;
particles[target + 2].vy = speed / 6;
storeY = mouseY;
}
Then, the particles around target are updated. The problem I found is that it does no bounds checking, i.e. it can potentially particles[-1] when target == 0. If that happens, an exception is thrown, the method call ends, but the code does not stop.
The render() method first updates the particle positions, then renders the wave.
Here is its physics code:
for (var u = particles.length - 1; u >= 0; --u) {
var fExtensionY = 0;
var fForceY = 0;
if (u > 0) {
fExtensionY = particles[u - 1].y - particles[u].y - springs[u - 1].iLengthY;
fForceY += -fK * fExtensionY;
}
if (u < particles.length - 1) {
fExtensionY = particles[u].y - particles[u + 1].y - springs[u].iLengthY;
fForceY += fK * fExtensionY;
}
fExtensionY = particles[u].y - particles[u].origY;
fForceY += fK / 15 * fExtensionY;
particles[u].ay = -fForceY / particles[u].mass;
particles[u].vy += particles[u].ay;
particles[u].ypos += particles[u].vy;
particles[u].vy /= 1.04;
}
Basically, it's Hooke's Law for a chain of particles linked by springs between them. For each particle u, it adds the attraction to the previous and next particles (the if statements check if they are available), to the variable fForceY. I don't fully understand the purpose of the springs array.
In the last four lines, it calculates the acceleration (force / mass), updates the velocity (add acceleration), then position (add velocity), and finally, reduce velocity by 1.04 (friction).
After the physics update, the code renders the wave:
context.clearRect(0, 0, stageWidth, stageHeight);
context.fillStyle = color;
context.beginPath();
for (u = 0; u < particles.length; u++) {
...
}
...
context.closePath();
context.fill();
I'm not explaining that, you need to read a canvas tutorial to understand it.
Here are some ideas to get started, note that I didn't test these code.
To modify the code to draw a circular wave, we need introduce a polar coordinate system, where the particle's x-position is the angle in the circle and y-position the distance from center. We should use theta and r here but it requires a large amount of refactoring. We will talk about transforming later.
mouseMove(): Compute particle index from mouse position on screen to polar coordinates, and make sure the disturbance wrap around:
Define the function (outside mouseMove(), we need this again later)
function wrapAround(i, a) { return (i + a.length) % a.length; }
Then change
particles[target - 2] --> particles[wrapAround(target - 2, particles)]
particles[target - 1] --> particles[wrapAround(target - 1, particles)]
...
The modulo operator does the job but I added particles.length so I don't modulo a negative number.
render(): Make sure the force calculation wrap around, so we need to wrapAround function again. We can strip away the two if statements:
fExtensionY = particles[wrapAround(u - 1, particles)].y - particles[u].y - springs[wrapAround(u - 1, springs)].iLengthY;
fForceY += -fK * fExtensionY;
fExtensionY = particles[u].y - particles[wrapAround(u + 1, particles)].y - springs[warpAround(u, springs)].iLengthY;
fForceY += fK * fExtensionY;
Here is the result so far in jsfiddle: Notice the wave propagate from the other side. http://jsfiddle.net/DM68M/
After that's done, the hardest part is rendering them on a circle. To do that, we need coordinate transform functions that treat particle's (x, y) as (angle in the circle, distance from center), and we also need inverse transforms for mouse interaction in mouseMove().
function particleCoordsToScreenCoords(particleX, particleY) {
return [ radiusFactor * particleY * Math.cos(particleX / angleFactor),
radiusFactor * particleY * Math.sin(particleX / angleFactor) ];
}
function screenCoordsToParticleCoords(screenX, screenY) {
// something involving Math.atan2 and Math.sqrt
}
Where the ...Factor variables needed to be determined separately. The angleFactor is two pi over the highest x-position found among particles array
Then, in the coordinates supplied to the context.lineTo, context.arc, use the particleCoordsToScreenCoords to transform the coordinates.

HTML 5 canvas animation - objects blinking

I am learning ways of manipulating HTML 5 Canvas, and decided to write a simple game, scroller arcade, for better comprehension. It is still at very beginning of development, and rendering a background (a moving star field), I encountered little, yet annoying issue - some of the stars are blinking, while moving. Here's the code I used:
var c = document.getElementById('canv');
var width = c.width;
var height = c.height;
var ctx = c.getContext('2d');//context
var bgObjx = new Array;
var bgObjy = new Array;
var bgspeed = new Array;
function init(){
for (var i = 1; i < 50; i++){
bgObjx.push(Math.floor(Math.random()*height));
bgObjy.push(Math.floor(Math.random()*width));
bgspeed.push(Math.floor(Math.random()*4)+1);
}
setInterval('draw_bg();',50);
}
function draw_bg(){
var distance; //distace to star is displayed by color
ctx.fillStyle = "rgb(0,0,0)";
ctx.fillRect(0,0,width,height);
for (var i = 0; i < bgObjx.length; i++){
distance = Math.random() * 240;
if (distance < 100) distance = 100;//Don't let it be too dark
ctx.fillStyle = "rgb("+distance+","+distance+","+distance+")";
ctx.fillRect(bgObjx[i], bgObjy[i],1,1);
bgObjx[i] -=bgspeed[i];
if (bgObjx[i] < 0){//if star has passed the border of screen, redraw it as new
bgObjx[i] += width;
bgObjy[i] = Math.floor(Math.random() * height);
bgspeed[i] = Math.floor (Math.random() * 4) + 1;
}
}
}
As you can see, there are 3 arrays, one for stars (objects) x coordinate, one for y, and one for speed variable. Color of a star changes every frame, to make it flicker. I suspected that color change is the issue, and binded object's color to speed:
for (var i = 0; i < bgObjx.length; i++){
distance = bgspeed[i]*30;
Actually, that solved the issue, but I still don't get how. Would any graphics rendering guru bother to explain this, please?
Thank you in advance.
P.S. Just in case: yes, I've drawn some solutions from existing Canvas game, including the color bind to speed. I just want to figure out the reason behind it.
In this case, the 'Blinking' of the stars is caused by a logic error in determining the stars' distance (color) value.
distance = Math.random() * 240; // This is not guaranteed to return an integer
distance = (Math.random() * 240)>>0; // This rounds down the result to nearest integer
Double buffering is usually unnecessary for canvas, as browsers will not display the drawn canvas until the drawing functions have all been completed.
Used to see a similar effect when programming direct2d games. Found a double-buffer would fix the flickering.
Not sure how you would accomplish a double(or triple?)-buffer with the canvas tag, but thats the first thing I would look into.

Categories