This is my code that I tried. The ball is jumping when I pressing "up arrow key" or "space bar".The problem is that I am unable to move ball little bit forward when ball jumped.Can anybody help me please?
let jumper;
function setup() {
createCanvas(400, 400);
jumper = new Jumper();
}
function draw() {
clear();
jumper.run();
push();
fill(217);
textFont('Avenir');
textAlign(CENTER,CENTER);
textSize(33);
text('space bar to jump', width>>1, height*0.15);
pop();
}
function keyPressed() {
jumper.vel.y = -4;
jumper.vel.x=+5;
}
I set up a very basic example of what I think you might be working towards:
let jumper;
function setup() {
createCanvas(400, 400);
jumper = new Jumper();
}
function draw() {
clear();
jumper.run();
push();
fill(217);
textFont('Avenir');
textAlign(CENTER,CENTER);
textSize(33);
text('space bar to jump', width>>1, height*0.15);
pop();
}
function keyPressed() {
jumper.x+=5;
}
class Jumper {
constructor() {
this.x = 10;
this.y = height/2;
}
run() {
ellipse(this.x, this.y, 10, 10);
}
}
<script src="https://cdn.jsdelivr.net/npm/p5#0.10.2/lib/p5.js"></script>
#Dishant was correct in that your code had a typo in where you did jumper.vel.x =+ 5 which is basically just setting the position of the jumper to the x position of 5. When what you want is to actually make the jumper move 5 pixels forward - in my example this done using jumper.x += 5 but you'd of course use jumper.vel.x += 5 as that code wasn't shown in your question!
You need to remove the bug in the second last line.
jumper.vel.x += 5;
Related
I have a game made with the p5.js play library where a player sprite shoots out bullets and takes out with these bullets an oncoming stream of enemy sprites. I wanted to have the game set to game over after 3 enemy sprites have reached down the bottom of the screen past the player and wasn't sure how to approach doing that.
let y = 0;
let spr;
let enemies;
let player;
let bullets = [];
let bullet;
let bulletsprite;
let score = 0;
function setup() {
createCanvas(600, 600);
bulletsprites = new Group()
enemies = new Group()
for(i = 0; i < 60; i++){
spr = createSprite(
random(width), y, random(10, 40), random(10, 40));
spr.shapeColor = color(random(255), random(255), random(255), random(255));
spr.velocity.y = random(0.7, 2);
enemies.add(spr);
}
player = createSprite(50, 50, 40, 40);
player.shapeColor = color(255);
}
function draw() {
background(30);
player.velocity.x =
(mouseX-player.position.x)*0.1;
player.velocity.y =
(mouseY-player.position.y)*0.1;
textSize(72);
textAlign(CENTER, CENTER);
drawSprites();
if (enemies.length > 0) {
text(score, width/2, height/2);
}
else {
text("you win!", width/2, height/2);
}
bulletsprites.overlap(enemies, getScore)
}
function mousePressed() {
//bullets positions setting
let bullet = {
x: mouseX,
y: mouseY,
};
bullets.push(bullet);
bulletsprite = createSprite(bullet.x, bullet.y, 10);
bulletsprite.velocity.y = -4;
bulletsprites.add(bulletsprite)
}
function getScore(bullets, enemies) {
enemies.remove();
score += 1;
}
make a counter which adds up every time an enemy reaches the bottom.
make a pause variable
make a gameOver function which will pause your game if the counter reaches 3.
put all the functions like enemies moving and game motions within a if(pause==false){} statement on your main loop.
in the gameOver function make whatever you want to end the game, it can be an animation, a menu, a black screen with a text, buttons, etc...
call this function in your "main loop"
sorry for not using code, I don't use p5 but the logical part is the important part :) good luck.
I want to animate a growing line based on a dataset, I want the line to grow each time the program finds DAE in a Row of the third column.
Here is my p5js code here
let data;
let font;
let direction;
let montant;
let annee;
function preload() {
data=loadTable('data/subvention.csv','csv','header',chargementOK,chargementERROR);
font = loadFont("data/opensans.ttf");
}
function setup() {
createCanvas(700, 700);
}
function draw() {
background(1);
let nbDAE=0;
for (let i = 0; i < data.getRowCount(); i++) {
direction = data.getString(i, "direction");
if (direction == "DAE") {
nbDAE++;
fill(255);
rect(350, 700- nbDAE*12, 20, 700);
}
}
}
function chargementOK(mesData){
print("chargement OK");
print(mesData);
}
function chargementERROR(){
print("BUGG");
}
The problem is I think I did everything right but I'm not getting any animation from it, the line just appears and code keeps on going forever.
I need some help to figure out how to properly animate the growing line.
The draw() loop is executed 60 times per second, and in each loop, you have another loop wich totalizes all the values.
If you want to animate, you need to use a counter and increment it each draw() loop.
Initialization of counter and nbDAE should be at the exterior of the draw() loop.
function draw() {
background(0);
direction = data.getString(compteur, "direction");
if (direction == "DAE") {
nbDAE++;
}
fill(255);
rect(350, 700- nbDAE*12, 20, 700);
compteur += 1;
if (compteur >= data.getRowCount()) {
noLoop();
}
}
I had worked on your previous question : here on the p5js web editor
And on your previous question, the problem of csv file : In french, the separator is semicolon (;) and not comma (,). So, in the loadTable() function, the extension should be 'ssv' and not 'csv' (semicolon-separated values)
So I'm trying to make a shape move in the canvas with p5.js. However, all it does is redrawing the same shape in the newly assigned position without deleting the shape in the old position, leaving sort of a trail, and not completely moving it like I wanted. You can see the result here.
Below is the code for my "Player" class (the shape that I want to move):
function Player() {
this.hp = 10;
this.x = 230;
this.y = 240;
this.color = "red";
this.r = 10;
this.spawn = function(){
fill(this.color);
noStroke();
rect(this.x, this.y, this.r*2, this.r*2);
}
}
This is my code in the setup and draw functions in p5.js:
var p1;
function setup() {
createCanvas(500, 500);
background("green");
p1 = new Player();;
}
function draw() {
p1.spawn();
if (keyIsDown(LEFT_ARROW)) {
p1.x--;
}
if (keyIsDown(RIGHT_ARROW)) {
p1.x++;
}
if (keyIsDown(UP_ARROW)) {
p1.y--;
}
if (keyIsDown(DOWN_ARROW)) {
p1.y++;
}
}
Any help would be greatly appreciated. Thanks!
You need to clear out old frames using the background() function. You should generally call background() from the first line in the draw() function. Here's an example:
function setup() {
createCanvas(200, 200);
}
function draw() {
background(64);
ellipse(mouseX, mouseY, 25, 25);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.11/p5.min.js"></script>
Try moving the call to the background() function to the setup() function to see what I mean.
you just use
if (keyDown(the key you want to use)) {
}
or
if(keyDown("the key you want to use")){
}
So I am trying to make a simple space game. You will have a ship that moves left and right, and Asteroids will be generated above the top of the canvas at random X position and size and they will move down towards the ship.
How can I create Asteroid objects in seperate positions? Like having more than one existing in the canvas at once, without creating them as totally seperate objects with seperate variables?
This sets the variables I would like the asteroid to be created on.
var asteroids = {
size: Math.floor((Math.random() * 40) + 15),
startY: 100,
startX: Math.floor((Math.random() * canvas.width-200) + 200),
speed: 1
}
This is what I used to draw the asteroid. (It makes a hexagon shape with random size at a random x coordinate)
function drawasteroid() {
this.x = asteroids.startX;
this.y = 100;
this.size = asteroids.size;
ctx.fillStyle = "#FFFFFF";
ctx.beginPath();
ctx.moveTo(this.x,this.y-this.size*0.5);
ctx.lineTo(this.x+this.size*0.9,this.y);
ctx.lineTo(this.x+this.size*0.9,this.y+this.size*1);
ctx.lineTo(this.x,this.y+this.size*1.5);
ctx.lineTo(this.x-this.size*0.9,this.y+this.size*1);
ctx.lineTo(this.x-this.size*0.9,this.y);
ctx.fill();
}
I included ALL of my code in this snippet. Upon running it, you will see that I currently have a ship that moves and the asteroid is drawn at a random size and random x coordinate. I just need to know about how to go about making the asteroid move down while creating other new asteroids that will also move down.
Thank You for all your help! I am new to javascript.
// JavaScript Document
////// Variables //////
var canvas = {width:300, height:500, fps:30};
var score = 0;
var player = {
x:canvas.width/2,
y:canvas.height-100,
defaultSpeed: 5,
speed: 10
};
var asteroids = {
size: Math.floor((Math.random() * 40) + 15),
startY: 100,
startX: Math.floor((Math.random() * canvas.width-200) + 200),
speed: 1
}
var left = false;
var right = false;
////// Arrow keys //////
function onkeydown(e) {
if(e.keyCode === 37) {
left = true;
}
if(e.keyCode === 39) {
right = true;
}
}
function onkeyup(e) {
if (e.keyCode === 37) {
left = false;
}
if(e.keyCode === 39) {
right = false;
}
}
////// other functions //////
//function to clear canvas
function clearCanvas() {
ctx.clearRect(0,0,canvas.width,canvas.height);
}
// draw the score in the upper left corner
function drawscore(score) {
var score = 0;
ctx.fillStyle = "#FFFFFF";
ctx.fillText(score,50,50);
}
// Draw Player ship.
function ship(x,y) {
var x = player.x;
var y = player.y;
ctx.fillStyle = "#FFFFFF";
ctx.beginPath();
ctx.moveTo(x,y);
ctx.lineTo(x+15,y+50);
ctx.lineTo(x-15,y+50);
ctx.fill();
}
// move player ship.
function moveShip() {
document.onkeydown = onkeydown;
document.onkeyup = onkeyup;
if (left === true && player.x > 50) {
player.x -= player.speed;
}
if (right === true && player.x < canvas.width - 50) {
player.x += player.speed;
}
}
// Draw Asteroid
function drawasteroid() {
this.x = asteroids.startX;
this.y = 100;
this.size = asteroids.size;
ctx.fillStyle = "#FFFFFF";
ctx.beginPath();
ctx.moveTo(this.x,this.y-this.size*0.5);
ctx.lineTo(this.x+this.size*0.9,this.y);
ctx.lineTo(this.x+this.size*0.9,this.y+this.size*1);
ctx.lineTo(this.x,this.y+this.size*1.5);
ctx.lineTo(this.x-this.size*0.9,this.y+this.size*1);
ctx.lineTo(this.x-this.size*0.9,this.y);
ctx.fill();
}
// move Asteroid
function moveAsteroid() {
//don't know how I should go about this.
}
// update
setInterval (update, 1000/canvas.fps);
function update() {
// test collisions and key inputs
moveShip();
// redraw the next frame of the animation
clearCanvas();
drawasteroid();
drawscore();
ship();
}
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>My Game</title>
<script src="game-functions.js"></script>
<!--
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
-->
</head>
<body>
<canvas id="ctx" width="300" height="500" style="border: thin solid black; background-color: black;"></canvas>
<br>
<script>
////// Canvas setup //////
var ctx = document.getElementById("ctx").getContext("2d");
</script>
</body>
</html>
You want to make the creation of asteroids dynamic...so why not set up a setInterval that gets called at random intervals as below. You don't need a separate declaration for each Asteroids object you create. You can just declare a temporary one in a setInterval function. This will instantiate multiple different objects with the same declaration. Of course you need to store each object somewhere which is precisely what the array is for.
You also have to make sure that asteroids get removed from the array whenever the moveAsteroid function is called if they are off of the canvas. The setInterval function below should be called on window load and exists alongside your main rendering setInterval function.
You are also going to have to change your moveAsteroid function a bit to be able to point to a specific Asteroids object from the array. You can do this by adding the Asteroids object as a parameter of the function or by making the function a property of the Asteroids class and using this. I did the latter in the example below.
var astArray = [];
var manageAsteroidFrequency = 2000;
var Asteroids {
X: //something
Y://something
speed:1
move: function() {
this.X -= speed;
}
}
var mainRenderingFunction = setInterval( function() {
for (var i = astArray.length-1 ; i > -1; i --){
if(astArray[i].Y < 0){
astArray.splice(i, 1)
}else{
astArray[i].move;
}
}
}, 40);
var manageAsteroids = setInterval( function () {
if (astArray.length < 4){
var tmpAst = new Asteroids();
astArray.push(tmpAst);
}
manageAsteroidFrequency = Math.floor(Math.random()*10000);
}, manageAsteroidFrequency);
var context = document.getElementById("canvas").getContext("2d");
for(var i = 0; i< savedMove.length; i++){
doSetTimeout(i);
}
function doSetTimeout(i) {
setInterval(function() { animate(savedMove[i][0], savedMove[i][1]); }, 100);
}
function animate(xPos, yPos) {
context.fillStyle = "red";
context.fillRect(xPos, yPos, 5, 5);
}
I have every x and y position move inside of 2D array (savedMove) and I want to draw with array information with delay. But Canvas does not draw this. I keep debugging but I cannot figure out the problem.
You're setting savedMove.length timers to tick parallelly every 100 milliseconds. I'm pretty sure this is not what you want, though it's hard to guess what it is. First I would change setInterval to setTimeout and make them fire at different times, 100 ms away from each other:
function doSetTimeout(i) {
setTimeout(function() { animate(savedMove[i][0], savedMove[i][1]); }, 100 * i);
}
Note that this is not the best way to do it, but certainly better than the original code.
Then you can debug it, 'cause you might draw out of the visible canvas:
console.log("canvas size:", document.getElementById("canvas").width, document.getElementById("canvas").height);
function animate(xPos, yPos) {
context.fillStyle = "red";
context.fillRect(xPos, yPos, 5, 5);
console.log("animate:", xPos, yPos);
}