setInterval "MoveToPlayer" should start after meeting first condition from "checkPosition" method and it should run(this works). After meeting the same condition again it should stop and start again with different parameter. I through that simple placing clearInterval(MoveToPlayer) will do the job but it doesn't work.
Second issue is how to stop this interval for example from "checkPosition" method?
class player {
constructor(name, PosY) {
this.name = name;
this.PosX = 5;
this.PosY = PosY;
this.object = $('.' + name);
this.speed = 0;
this.direction = "";
this.lifes = 3;
}
playerMove(thisRaft) {
var MoveToPlayer = setInterval(() => {
clearInterval(MoveToPlayer)
$('.player1').css('left', thisRaft.PosX * 50);
$('.player1').css('bottom', thisRaft.PosY * 50);
}, 1);
}
checkPosition(x, y) {
for (var i = 0; i < raftsTab.length; i++) {
if (x == raftsTab[i].PosX && y == raftsTab[i].PosY) {
let thisRaft = raftsTab[i];
this.playerMove(thisRaft);
return;
}
}
for (var i = 0; i < raftsTab.length; i++) {
if (x !== raftsTab[i].PosX && y !== raftsTab[i].PosY && y !== 0 && y !== 5 && y !== 10) {
console.log("Dead");
player1.PosX = 5;
player1.PosY = 0;
changePosition();
return;
}
}
}
}
Regarding your first issue you are clearing the interval immediately after it starts, so it won't continue.
In order to make the interval more dynamic you should have a function that returns an interval within checkPosition.
Wasn't able to understand how your game should actually work, but I am posting an alteration to your script where I modified PlayerMove and checkPosition in away that gives you a better control of the interval in question.
Hope it is clear and helpful for you
class player {
constructor(name, PosY) {
this.name = name;
this.PosX = 5;
this.PosY = PosY;
this.object = $('.' + name);
this.speed = 0;
this.direction = "";
this.lifes = 3;
}
playerMove(thisRaft) {
return setInterval(() => {
$('.player1').css('left', thisRaft.PosX * 50);
$('.player1').css('bottom', thisRaft.PosY * 50);
}, 1);
}
checkPosition(x, y) {
if (someCondition && this.currentPlayerMove) {
clearInterval(this.currentPlayerMove)
}
for (var i = 0; i < raftsTab.length; i++) {
if (x == raftsTab[i].PosX && y == raftsTab[i].PosY) {
let thisRaft = raftsTab[i];
this.currentPlayerMove = this.playerMove(thisRaft);
return;
}
}
for (var i = 0; i < raftsTab.length; i++) {
if (x !== raftsTab[i].PosX && y !== raftsTab[i].PosY && y !== 0 && y !== 5 && y !== 10) {
console.log("Dead");
player1.PosX = 5;
player1.PosY = 0;
changePosition();
return;
}
}
}
Just assign your handler at such scope, that would make it accessible to all functions that could clear it.
var handler;
function movePlayer(text){
clearInterval(handler); // stop execution before assigning new handler
handler = setInterval(()=>{
/* do your stuff */
console.log(text);
}, 100)
}
movePlayer("I'm moving")
setTimeout(()=>{
clearInterval(handler)
}, 500)
setTimeout(()=>{
movePlayer("I'm moving again")
}, 1500)
setTimeout(()=>{
clearInterval(handler)
}, 2000)
Related
I have the mazeGen class that generates a maze using a version of prims algorithm using JS and P5.JS. Within the mazeGen class i have a display funtion that logs the maze to console. When i run this line it says it is not defined as a funtion. THe class will be used in another progect to generate multiple mazes to need it as a class
let maze1
function setup() {
maze1 = new MazeGen(11);
maze1.display()
}
function draw() {
background(220);
}
class MazeGen {
constructor(size) {
console.warn('in funt')
this.size = size
this.maze = new Array(this.size);
for (let i = 0; i < this.maze.length; i++) {
this.maze[i] = new Array(this.size);
for (let j = 0; j < this.maze.length; j++) {
this.maze[i][j] = 0
}
}
this.maze = this.PrimsAlgorithm()
this.maze[1][0] = 3;
this.maze[this.maze.length - 2][this.maze.length - 1] = 2;
console.table(this.maze);
return this.maze;
}
PrimsAlgorithm() {
this.frontAvailable = [0, 0, 0, 0];
this.currentCell = [1, 1];
while (this.Complete(this.maze, this.size) === false) {
//Console.WriteLine("Maze is not ready");
this.maze[this.currentCell[0]][this.currentCell[1]] = 1;
this.frontAvailable = this.Frontier(this.maze, this.currentCell);
//While the list of frontier cells is not empty
while (this.frontAvailable[0] !== 0 || this.frontAvailable[1] !== 0 || this.frontAvailable[2] !== 0 || this.frontAvailable[3] !== 0) {
//pick a random way
this.picked = false;
this.numSelected = 5;
while (this.picked === false) {
this.numSelected = Math.floor(Math.random() * 5);
if (this.frontAvailable[this.numSelected] === 1) {
this.picked = true;
}
}
//'Move to cell'
this.maze = this.MoveSquare();
this.frontAvailable = this.Frontier();
//Maze.PrintWhole(maze);
}
//List of frontier Cells is now empty
//Move to random cell and check if it is a path
this.currentCell = this.NewCurrent();
}
return this.maze;
}
Frontier() {
this.available = [0, 0, 0, 0];
//left check
if (((this.currentCell[1]) - 2) >= 0 && this.maze[this.currentCell[0]][(this.currentCell[1]) - 2] === 0) {
this.available[0] = 1;
} else {
this.available[0] = 0;
}
//up check
if (((this.currentCell[0]) - 2) >= 0 && this.maze[(this.currentCell[0]) - 2][(this.currentCell[1])] === 0) {
this.available[1] = 1;
} else {
this.available[1] = 0;
}
//right check
if (this.currentCell[1] + 2 < this.maze.length) {
if (this.maze[this.currentCell[0]][(this.currentCell[1]) + 2] === 0) {
this.available[2] = 1;
}
} else {
this.available[2] = 0;
}
//down check
if (this.currentCell[0] + 2 < this.maze.length) {
if (this.maze[this.currentCell[0] + 2][this.currentCell[1]] === 0) {
this.available[3] = 1;
}
} else {
this.available[3] = 0;
}
return this.available;
}
NewCurrent() {
this.found = false
this.currentCell = [];
while (this.found === false) {
this.cellX = Math.floor(Math.random() * (this.maze.length - 3) / 2)
this.cellX = this.cellX * 2 + 1
this.cellY = Math.floor(Math.random() * (this.maze.length - 3) / 2)
this.cellY = this.cellY * 2 + 1
if (this.maze[this.cellX][this.cellY] === 1) {
this.currentCell[0] = this.cellX;
this.currentCell[1] = this.cellY;
this.found = true
}
}
return this.currentCell;
}
MoveSquare() {
if (this.numSelected === 0) {
this.maze[this.currentCell[0]][(this.currentCell[1]) - 2] = 1;
this.maze[this.currentCell[0]][(this.currentCell[1]) - 1] = 1;
this.currentCell[1] = this.currentCell[1] - 2;
}
if (this.numSelected === 1) {
this.maze[(this.currentCell[0]) - 2][(this.currentCell[1])] = 1;
this.maze[(this.currentCell[0]) - 1][(this.currentCell[1])] = 1;
this.currentCell[0] = this.currentCell[0] - 2;
}
if (this.numSelected === 2) {
this.maze[this.currentCell[0]][(this.currentCell[1]) + 2] = 1;
this.maze[this.currentCell[0]][(this.currentCell[1]) + 1] = 1;
this.currentCell[1] = this.currentCell[1] + 2;
}
if (this.numSelected === 3) {
this.maze[(this.currentCell[0]) + 2][(this.currentCell[1])] = 1;
this.maze[(this.currentCell[0]) + 1][(this.currentCell[1])] = 1;
this.currentCell[0] = this.currentCell[0] + 2;
}
return this.maze;
}
Complete() {
let counter = 0;
//Console.WriteLine(counter);
for (let i = 0; i < (this.size - 1) / 2; i++) {
for (let j = 0; j < (this.size - 1) / 2; j++) {
let X = (2 * i) + 1;
let Y = (2 * j) + 1;
if (this.maze[X][Y] === 1) {
counter++;
}
}
}
return counter === (this.size - 1) / 2 * (this.size - 1) / 2;
}
display(){
console.table(this.maze);
}
}
If you return this.maze on constructor it will be an Array, Arrays don't have a display funcion
let maze1;
function setup() {
maze1 = new MazeGen(11);
maze1.display();
}
class MazeGen {
constructor(size) {
this.size = size;
this.maze = new Array(this.size).fill(1);
return this;//This is not really need it
}
display() {
console.log("In Display function");
console.log(this.maze);
}
}
setup();
The constructor property returns a reference to the Object constructor function that created the instance object. Note that the value of this property is a reference to the function itself, not a string containing the function's name.
More examples here : What does a JavaScript constructor return?
Are you trying to show the maze, or get what type of display it is on a webpage?
P5.js does not have such a method called .display(). However, there is a method called .show(), which makes the element visible. In normal web JavaScript, if you want to get or change the display type, you need to use the .style.display property.
//let screenWidth = window.screen.width;
//let screenHeight = window.screen.height;
let screenWidth = 800;
let screenHeight = 600;
let assets = {};
let frames = 60;
let score = 0;
let lives = 3;
let player;
// let enemie;
//let enemies;
let bullet;
//let bullets;
let powerup = 0;
let gameOver = true;
function drawScoreBoard() {
textSize(20);
fill('white');
text(`Score: ${score} / Lives: ${lives}`, 20, 40);
}
function preload() {
assets.player = loadImage('assets/Player.png');
assets.enemie = loadImage('assets/Enemie.png');
assets.bulletRight = loadImage('assets/Bullet_Right.png');
assets.bulletLeft = loadImage('assets/Bullet_Left.png');
assets.bulletUp = loadImage('assets/Bullet_Up.png');
assets.bulletDown = loadImage('assets/Bullet_Down.png');
}
function setup() {
bullets = createGroup();
enemies = createGroup();
assets.player.resize(30, 30);
assets.enemie.resize(30, 30);
assets.bulletRight.resize(30, 30);
assets.bulletLeft.resize(30, 30);
assets.bulletUp.resize(30, 30);
assets.bulletDown.resize(30, 30);
createCanvas(screenWidth, screenHeight);
}
function createBullet(){
let numList = [0, 90, 180, 270, 360];
let bulletDirection = [assets.bulletLeft, assets.bulletUp, assets.bulletRight, assets.bulletDown];
let randomdirection = numList[Math.floor(Math.random() * numList.length)];
let bullet = createSprite(bulletDirection[(Math.round(player.getDirection()/90))]);
enemie.centerX = random(0, screenWidth);
enemie.setSpeed(random(1,10));
enemie.setDirection(randomdirection);
enemie.setCollider("circle");
bullets.add(bullet);
}
function createPlayer(){
player = createSprite(assets.player);
player.bottom = screenHeight - 20;
player.centerX = screenWidth / 2;
}
function shoot(amountofbulletstobeshot) {
let bulletDirection = [assets.bulletLeft, assets.bulletUp, assets.bulletRight, assets.bulletDown];
let bullet = createSprite(bulletDirection[Math.abs(((Math.round(player.getDirection()/90))))]);
bullets.add(bullet);
// bullet.direction = player.direction;
bullet.centerX = player.centerX;
bullet.centerY = player.centerY;
bullet.setVelocity(11, player.getDirection());
// console.log('The players current direction right now is: ' + player.getDirection());
}
function shooting() {
if (keyIsDown(KEY.SPACE)) {
if (powerup === 1) {
shoot(3);
}
else {
shoot(1);
}
}
if (bullet) {
if (bullet.centerX[1] === screenWidth) {
bullets.remove(bullet);
}
}
}
function updateplayer() {
//movement
if (keyIsDown) {
if (keyIsDown(KEY.RIGHT_ARROW)) {
player.setVelocity(6, 0);
}
if (keyIsDown(KEY.LEFT_ARROW)) {
player.setVelocity(6, 180);
}
if (keyIsDown(KEY.UP_ARROW)) {
player.setVelocity(6, 270);
}
if (keyIsDown(KEY.DOWN_ARROW)) {
player.setVelocity(6, 90);
}
}
//dont go offscreen
if (player.left < 0) {
player.left = 0;
}
if (player.right > screenWidth) {
player.right = screenWidth;
}
if (player.top < 0) {
player.top = 0;
}
if (player.bottom > screenHeight) {
player.bottom = screenHeight;
}
enemies.overlap(player, HandlePlayerEnemieCollision);
//end up updateplayer
}
function updateEnemie() {
if (frameCount % 1 === 0) {
let directions = ["LEFT", "RIGHT", "UP", "DOWN"];
let direction = random(directions);
if (direction === "LEFT" && enemie.left > 0) {
enemie.centerX -= 5;
}
if (direction === "RIGHT" && enemie.right < screenWidth) {
enemie.centerX += 5;
}
if (direction === "UP" && enemie.top > 0) {
enemie.centerY -= 5;
}
if (direction === "DOWN" && enemie.bottom < screenHeight) {
enemie.centerY += 5;
}
}
}
function createEnemie() {
let directions = [270, 180, 0, 90];
direction = directions[(Math.floor(Math.random() * 5))];
enemies.overlap(bullets, HandleEnemieBulletCollision);
if (frameCount % 60 === 0) {
enemie = createSprite(assets.enemie);
enemie.centerX = Math.floor(Math.random() * 300) + 100;
enemie.centerY = Math.floor(Math.random() * 300) + 100;
enemie.setVelocity(Math.floor(Math.random() * 5) + 1, direction);
enemies.add(enemie);
}
}
function HandleEnemieEdgeCollision(enemie, edge) {
if (enemie.centerY === screenWidth) {
enemie.remove();
}
}
function HandleEnemieBulletCollision(enemie, bullet) {
enemie.remove();
bullet.remove();
score++;
}
function HandlePlayerEnemieCollision(player, enemie) {
enemie.remove();
player.remove();
lives--;
if (lives === 0) {
gameOver = true;
}
createPlayer();
}
/*
function updateEnemie() {
player.setVelocity(7, player.direction);
}
*/
function cheat() {
score = (score + 1000000);
lives = (lives + 1000000);
cheats = 'on';
if (cheats === 'on') {
textSize(50);
fill('yellow');
text('CHEATS ACTIVATED', 400, 300);
}
}
/*
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds) {
break;
}
}
}
*/
function drawGameOverScreen() {
background("black");
textAlign(CENTER);
fill("white");
textSize(40);
text("WELCOME", screenWidth/2, screenHeight/2);
textSize(20);
text("Press SPACE to play!", screenWidth/2, screenHeight/2 + 100);
if (keyWentDown(KEY.SPACE)){
resetGame();
gameOver = false;
}
}
function resetGame(){
score = 0;
lives = 3;
createPlayer();
}
function drawGame() {
background('lightgreen');
drawScoreBoard();
updateplayer();
drawSprites();
shooting();
// updateEnemie();
createEnemie();
}
function draw() {
if (gameOver === true) {
drawGameOverScreen();
} else {
drawGame();
}
}
There is my code, I want to add a time limit for how many seconds it takes until you can shoot again, right now you can just spam and make all of the bullets go in a straight line I need to wait before I let the player shoot again, Thanks! This will help out allot and i neede this in as few minutes as possible.
Use a flag to know when shooting is enabled and disabled. After each shot disable the ability to shoot. Then use a setTimeout to enable the shooting after a certain amount of time.
let shootingEnabled = true;
function tempDisableShooting(duration) {
shootingEnabled = false;
setTimeout(() => {
shootingEnabled = true;
}, duration);
}
function shooting() {
if (shootingEnabled && keyIsDown(KEY.SPACE)) {
if (powerup === 1) {
shoot(3);
} else {
shoot(1);
}
tempDisableShooting(1000); // Disable shooting for 1 second.
}
if (bullet) {
if (bullet.centerX[1] === screenWidth) {
bullets.remove(bullet);
}
}
}
Add property to track the disabled state of the shooting and a constant for the delay time in milliseconds.
let shootDisabled = false;
const shootDelayMS = 300;
Update your shoot function to only shoot if shootDisabled == false, update the shootDisabled to true after each shot, and to triggers a setTimeout which waits shootDelayMS milliseconds before setting shootDisabled to false again.
function shoot(amountofbulletstobeshot) {
if (shootDisabled == false) {
let bulletDirection = [assets.bulletLeft, assets.bulletUp, assets.bulletRight, assets.bulletDown];
let bullet = createSprite(bulletDirection[Math.abs(((Math.round(player.getDirection()/90))))]);
bullets.add(bullet);
bullet.centerX = player.centerX;
bullet.centerY = player.centerY;
bullet.setVelocity(11, player.getDirection());
shootDisabled = true;
setTimeout(() => shootDisabled = false, shootDelayMS );
}
}
one way is the hold the data in two variables: is_shooting, shot_reset.
if(is_shooting){
if(shot_reset>=x){ //x is frame count till able to shoot again)
shot_reset==0;
is_shooting=false;
}else{
shot_reset++
}
}
I'm using a number of boxes that are floating around the screen, I want for them to bounce away from each other when they collide and I am testing this by just changing their colours instead when they collide, for some reason their colour changes at the start(their starting colour is white and if they collide it should change to red but they start and stays red). Is there something I am doing wrong? I would also like for everything to be done within the constructor function. I am sorry for not commenting my code as yet.
function BoxSplash()
{
this.sample = [];
var test = false;
this.col = color(129)
this.changeColour = function()
{
this.col = color(random(0,255),random(0,128),random(0,255))
}
this.intersect = function(other)
{
for(var i = 0; i < numberss; i++)
{ var currentBox = this.sample[i]
var d = dist(currentBox.x,currentBox.y,other.x,other.y)
if(d < currentBox.width + other.width)
{
return true;
}
else
{
return false
}
}
noLoop()
}
this.draw = function()
{
stroke(255)
line(0,windowHeight/2,windowWidth,windowHeight/2)
stroke(0)
for(var i = 0; i < numberss; i++)
{
var box = {
x:random(0,windowWidth - 50),
y:random(windowHeight/2 ,windowHeight - 50),
width:50,
height:50,
speedX:random(1,5),
speedY:random(1,5)
}
this.sample.push(box)
}
//use numberss variable to work with gui
for(var i = 0; i < numberss; i++)
{
fill(this.col)
rect(this.sample[i].x,this.sample[i].y,50,50)
}
this.move()
}
this.move = function()
{
for(var i = 0; i < numberss; i++)
{
var shape = this.sample[i]
shape.x += shape.speedX
shape.y += shape.speedY
if(shape.x + shape.width >= windowWidth || shape.x <= 0 )
{
shape.speedX = -shape.speedX
}
if(shape.y + shape.height >= windowHeight || shape.y <= windowHeight/2)
{
shape.speedY = -shape.speedY;
}
for(var j = 0; j < numberss; j++)
{
var others = this.sample[j]
var d = dist(shape.x,shape.y,others.x,others.y)
if( i != j && d < shape.width + others.width)
{
test = true;
}
else
{
test = false
}
if(test)
{
this.col = color(255,0,0)
}
}
}
}
}
You should visit this link and transform their circles into your boxes.
1st: Calculate dist(object1.x, object.y, object2.x, object2.y) and save into a variable called d
2nd:
if (d < object1.h + object2.h) {
// Enter your code here
}
My code is as follows:
var map = [];
document.body.onkeydown = document.body.onkeyup = function(e){
e = e || event; // to deal with IE
map[e.key] = e.type == 'keydown';
console.log(map)
if (map["ArrowLeft"]) {move("left")}
if (map["ArrowRight"]) {move("right")}
if (map["Spacebar"] || map[" "]) {jump()};
However if i hold down the right arrow key and then press space the character jumps without changing the x pos.
My jumping code is:
async function jump() {
var jh = j;
var i;
for (i = jh * 2; i > -Math.abs(jh) * 2 - 0.5; i -= 0.5) {
rem_rect(70, py, 30, 30)
py -= i
rect(70, py, 30, 30)
await sleep(15)
}
}
My moving code is:
async function move(d) {
var i;
for (i = 0; i < p.length; i++) {
if (d === "right") {
var j;
for (j = 0; j <= 5; j++) {
rem_rect(p[i][0], p[i][1], p[i][2], p[i][3]);
p[i][0] -= ms / 5;
rect(p[i][0], p[i][1], p[i][2], p[i][3])
await sleep(0)
}
}
else if (d === "left") {
var j;
for (j = 0; j <= 5; j++) {
rem_rect(p[i][0], p[i][1], p[i][2], p[i][3]);
p[i][0] += ms / 5;
rect(p[i][0], p[i][1], p[i][2], p[i][3])
await sleep(0)
}
}
}
}
I am during writing game. When condition (playerlife < 1) is meet, game should stop. Whole game is in singlePlayer function. The problem is, I don't know how to end this function. Simple placing condition inside singlePlayer function doesn't work because it is checked only once during starting a game.
if (playerlife < 1) {
return;
}
I also tried to put this condition in interval and check if condition is meet continously but I doesn't work and anyway it doesn't looks like a good idea.
Below is part of code where after moving player there are checked some conditions. Game is similar to old school "Frogger". When player jump in to the water then he lost 1 life. After loosing 3 lives game should be over.
$(function() {
function singlePlayer() {
checkPosition(x, y) {
for (var i = 0; i < raftsTab.length; i++) {
if (x == raftsTab[i].PosX && y == raftsTab[i].PosY) {
let thisRaft = raftsTab[i];
console.log(x, y);
console.log(thisRaft);
clearInterval(MoveToPlayer);
movePlayer(thisRaft);
return;
}
}
for (var i = 0; i < raftsTab.length; i++) {
if (x !== raftsTab[i].PosX && y !== raftsTab[i].PosY && y !== 0 && y !== 5 && y !== 10) {
player1.lifes = player1.lifes - 1;
//player dead after loosing 3 lives - it would be perfect if game could be ended from here
$('.lifes').text("Player lifes: " + player1.lifes);
for (var i = 0; i < trophiesTab.length; i++) {
if (player1.trophie - 1 == i) {
trophiesTab[i].show();
player1.trophie = -1;
}
}
player1.PosX = 5;
player1.PosY = 10;
clearInterval(MoveToPlayer);
changePosition();
return;
}
}
for (var i = 0; i < trophiesTab.length; i++) {
if (x == trophiesTab[i].PosX && y == trophiesTab[i].PosY && player1.trophie == -1) {
trophiesTab[i].hide();
}
}
if (x == 5 && y == 0 && player1.trophie !== -1) {
tresure1 = tresure1 + player1.trophie;
player1.items = player1.items + 1;
$('.items').text("Gathered items: " + player1.items + "/3");
player1.trophie = -1;
console.log(tresure1);
}
clearInterval(MoveToPlayer);
}
}
});