How do I put a height limit within a canvas game? - javascript

Right so I'm a bit new to JS and I wanted to know how to put a roof or height limit within this small canvas game. It's practically W3's code but the teacher told us to just model after it. I wanted to fix the annoying issue of just jumping over the map to avoid obstacles.
I don't really know what to try since the height is set by canvas. I tried to make a new function based of hitBottom() which failed.
Just wanted to put the roof or height limit. Here's the original source: Here. Everything is literally the same except colors.

What you want to do is see if the current y-position is lower than 0, since that would be the 'roof' of the room. If the player y position is lower than 0, reset it back to 0, and stop the acceleration.
this.hitTop = function() {
if (this.y < 0) {
this.y = 0;
this.gravitySpeed = 0;
}
}
And to the newpos function, you want to call this function, so add this:
this.hitTop();

Check for y position in newPos method after increasing the y position. If it is less than 0 then make it 0. Code should look like below;
this.newPos = function() {
this.gravitySpeed += this.gravity;
this.x += this.speedX;
this.y += this.speedY + this.gravitySpeed;
/* Add below 4 lines */
if (this.y <= 0) {
this.y = 0;
this.gravitySpeed = 0;
}
/* Add above 4 lines */
this.hitBottom();
}
Happy coding ;)

Related

Give circle random direction after hitting another circle in p5.js

Im am creating a COVID-19 simulator where every circle in the simulation is a person. When two persons hit each other, i want the direction that they "bounce" off each other to be random. Currently i just mirror the current speed, which means the the persons follow a pre defined path, even when bouncing of each other.
This is my "move" function
move() {
if (this.willMove) {
this.xPos += this.xSpeed;
this.yPos += this.ySpeed;
}
}
This where i do my collision detection
collision(other) {
let distance = dist(this.xPos, this.yPos, other.xPos, other.yPos);
if (distance < this.personRadius + other.personRadius) {
this.changeDirection();
return true;
} else {
return false;
}
}
The things handeling the changing of direction:
changeDirection() {
this.mirrorXSpeed();
this.mirrorYSpeed();
}
mirrorXSpeed() {
this.xSpeed = this.xSpeed * -1;
}
mirrorYSpeed() {
this.ySpeed = this.ySpeed * -1;
}
I have tried multiplying the speed by -0.95, but this just decreases the speed.
The full project can be found here: https://github.com/perkynades/Simulation-of-COVID19/tree/part1
This might help, it will make all the people bounce in a random direction when called.
You will have to add this.speed to your person constructor, and make sure angle mode is set to radians.
changeDirection() {
//This next line will change the speed by a random amount,
//delete it if you don't like it,
//or change the range for a different behavior
this.speed += random(1,3) * random([-1,1])
let ang = random(PI * 2)
this.changeXSpeed(ang);
this.changeYSpeed(ang);
}
changeXSpeed(ang) {
this.xSpeed = this.speed * cos(ang);
}
changeYSpeed(ang) {
this.ySpeed = this.speed * sin(ang);
}
}
If you want a more realistic bounce, I would check out Chris courses video on Collision detection it gives a natural fell to circle on circle collisions, and even though it is not all P5.js, it is was very helpful to me and I hope that it will be for you too.

Simple AI method to make sprite follow player using car physics?

I am making a top-down car battling game using JavaScript. I need a simple method to make the enemy car follow the player around the map based on the players coordinates. The hard part for me is that I need to make sure the enemy car uses the same turning physics as the player.
What I am looking for is help creating a simple movement formula that will decide when to move forward/backwards and/or when to rotate the enemy in order to bring it closer to the player.
I have tried many various "if enemy.x >player.x .." but I am thinking this is going to require a math function beyond simple logic, maybe something utilizing slope intercept or something but I don't have an idea how to implement
//this is the actual movement algorithm I am using
this.move=function(){
this.angle += this.rotation * Math.PI / 180;
this.nextX = this.x + this.speed * Math.sin(this.angle);
this.nextY = this.y - this.speed * Math.cos(this.angle
//This is how I am moving the player character atm
if(LEFT) {
this.rotation = -1;
}else if(RIGHT) {
this.rotation = 1;
}else {this.rotation = 0;}
if(UP && !BOOST) {
this.speed = 1;
}else if(DOWN) {
this.speed = -1;
}else if(UP && BOOST) {
this.speed = 4;
}else {this.speed = 0;}

Same jumpheight with changing gravity

I am trying to recreate the google-chrome offline Dino game.
In this game the Dino has a gravity-pull on himself and it has a jump velocity, an upwards speed applied when the user presses the space bar.
Over time the obstacles move faster and faster to the player.
When the obstacles move faster the Dino's jump should also be faster.
I tried to make a faster jump by increasing the gravity over time, so the Dino gets pulled down faster. But how do I get the Dino to jump the same height, let's say, 50 pixels upwards, no matter what the gravity is.
I tried working with the formula's:
y = 0.5*a*t^2 + v(0)*t
But I can't come to a correct answer.
The canvas this code is working as regards the top left corner as the origin(0,0). Therefore the jump velocity is negative and the gravity is positive.
This code is inside the Dino class, where this references to the Dino.
In the constructor of the Dino class I have the code
this.y = 0;
this.vy = 0;
this.gravity = 1;
this.speed = 0;
In the update function that is called each x amount of time:
this.speed += 0.001;
this.y += this.vy;
this.vy += this.gravity;
this.gravity += speed*0.001;
The jump function- executes when the spacebar is pressed:
this.vy = (-?);
The amount of pixels the dino jumps gets higher over time. How could I make the Dino jump the same amount of pixels every time no matter the gravity?
So I personally would do this a little differently. I would specify a maximum y; the highest point our object can jump. Then when the player hits the jump button, it will Linearly Interpolate to that position, this works perfectly for your problem as in p5 they've spoiled us with a lerp() function where you can specify the amount to lerp by, so the faster your game gets the quicker we want the player to jump so the higher we set the lerp.
To determine how fast we lerp I've used upSpeed which you will increment as the game progresses:
const MAX_Y = 150;
let y = 370;
let upSpeed = 0.1;
function setup() {
createCanvas(400, 400);
}
function draw() {
background(220);
fill(255, 100, 100);
y = lerp(y, MAX_Y, upSpeed);
ellipse(width / 2, y, 50, 50);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.js"></script>
And then add your gravity magic to the equation and you've got yourself a game!

Why is this basic Canvas animation not smooth?

The only thing that I do inside the animation loop is update the x and y coordinates but the circle is still not moving as smoothly as it should. This is the fiddle. I am using CraftyJS to animate the circle. Here is the code that does the animation:
.bind("EnterFrame", function (eventData) {
this.x += this.xDirection;
this.y += this.yDirection;
if (this.x < 0) this.xDirection *= -1;
if (this.y < 0) this.yDirection *= -1;
if (this.x > (0.96*gWidth)) this.xDirection *= -1;
if (this.y > (0.96*gHeight)) this.yDirection *= -1;
});
Rest of the calculations are done just once and I don't think just a bunch of multiplications should make the animation lag. Any help on how to make the animation smooth will be appreciated.
I failed to mention earlier that xDirection is equal to 0.005*gWidthand yDirection is equal to 0.005*gHeight. If gWidth is 600 the ball is still moving just 3px. Is it really that fast? I don't want to specify the width in pixels (gWidth is the screen size) because then the gameplay will be different on different devices. Is there some way to move the circle quickly while still keeping the animation smooth?
Changing from 'fixed' to 'variable' steptype smoothed things out for me.
After Crafty.init, call Crafty.timer.steptype():
const _step = 20;
Crafty.init(gWidth, gHeight, document.getElementById('game'));
Crafty.timer.steptype('variable', _step);
// ...
You may also want to update your EnterFrame to take in to account time elapsed since the last frame:
.bind("EnterFrame", function (eventData) {
let dt = eventData.dt;
this.x += this.xDirection * dt / _step;
this.y += this.yDirection * dt / _step;
// ...

JavaScript 2D collision anomaly

I'm experimenting with HTML5 canvas scripting in JavaScript and am having an issue with 2D collision detection. I'm basically checking the coordinates of the "player" against the coordinates of a box I've placed on screen but a strange result is occurring. I know why it's happening, but I don't know how to solve the problem.
Some of my code:
function Arc()
{
// Coordinates.
this.x = 540 / 2;
this.y = 0;
// Radius
this.r = 50;
// Gravity / velicoty.
this.g = 3;
this.vy = 15;
// Bounce.
this.b = -0;
this.speed = 20;
this.max_speed = 20;
this.friction = 0.03444;
}
Arc.prototype.collision = function()
{
for(var i = 0; i < game.sprites.length; i++)
{
if
(
// If the right side of the player is greater than the left side of the object.
this.x + this.r > game.sprites[i].x &&
// If the bottom of the player is greater than (meaning lower than) the top of the object.
this.y + this.r > game.sprites[i].y &&
// If the left side of the player is greater than the right side of the object.
this.x - this.r < game.sprites[i].x + game.sprites[i].w &&
// if the top of the player is greater than (meaning lower than) the bottom of the object.
this.y - this.r < game.sprites[i].y + game.sprites[i].h
)
{
this.y = game.sprites[i].y - this.r;
this.vy *= this.b;
}
}
}
The anomaly is that when I move the player sprite over the left or right of the box, it jumps upwards on the Y-axis because the logical check above is always true. Obviously this is unexpected because the sprite should only interact with the top of the box if a jump has occurred.
Note: I'm not looking for a solution that adds collision to the sides of the box only (that's very simple). Rather, I'm looking for the solution that allows for collision on all sides of the box (including the top) in the same way it currently works but without the anomaly where the sprite suddenly jumps on top of the box upon touching it.
I've reproduced my entire project on JSFiddle for the purposes of demonstration (keys a, d and space bar): http://jsfiddle.net/h5Fun/
Whether or not this is what you want, it solves the problem:
this.x = game.sprites[i].x + 150;
this.vx *= this.b;
The issue was you were setting the incorrect component upon collision. If you want the circle to stop when it hits the rectangle, not go on top of it, then use x, not y.
150 is the size of the rectangle. This means it will stop at the right side of the sprite. The bouncing is already there due to modifying the velocity (this.vx).

Categories