Im currently working on a small HTML5 game. Now I am busy with making the small car shrink in size when it reaches the horizon (on the road) and go back to original size when it drives back towards 'us'.
I am pretty new to javascript, that is why I started making this small game, I figured what better way to learn, right?
So this is what I have (within a canvas):
var render = function () {
if (bgReady) {
ctx.drawImage(bgImage, 0, 0);
}
if (carReady) {
//ctx.drawImage(carImage, car.x, car.y);
ctx.drawImage(carImage, car.x, car.y, (carImage.width /100 * 50),(carImage.height / 100 * 50));
}
};
What I want to say is, that the size only should be altered when car.y gets smaller. However I am not really sure about where to place it, in order to not get a chronological-error.
What I am trying to get is:
ctx.drawImage(carImage, car.x, car.y, (carImage.width /100 * 50),(carImage.height / 100 * 50));
if(car.y++){
car.Image.width /i * 50 && carImage.height /i * 50}
With the variable 'i' increasing as car.y increases.
I hope someone can point me into the right direction.
Mieer
EDIT:
// Handle keyboard controls
var keysDown = {};
addEventListener("keydown", function (e) {
keysDown[e.keyCode] = true;
}, false);
addEventListener("keyup", function (e) {
delete keysDown[e.keyCode];
}, false);
// Reset the game when the player catches a fuel
var reset = function () {
car.x = canvas.width / 3;
car.y = canvas.height / 1.2;
// Throw the fuel somewhere on the screen randomly [lengte(math random) keer breedte voor een random plaat in de oppervlakte)]
//fuel.x = 300 + (Math.random() * (canvas.width - 700)); -old
fuel.y = 500 + (Math.random() * (canvas.height - 550));
//The left-most x coordinate for each y coordinate,
//The road-width for each y coordinate.
var left_most_x = 10 + ((500-10)/1000) * fuel.y
var road_width = 500 - ((500-30)/1000) * fuel.y
fuel.x = left_most_x + (Math.random() * road_width)
};
// Update game objects
var update = function (modifier) {
if (38 in keysDown) { // Player holding up
car.y -= car.speed * modifier;
}
if (40 in keysDown) { // Player holding down
car.y += car.speed * modifier;
}
if (37 in keysDown) { // Player holding left
car.x -= car.speed * modifier;
}
if (39 in keysDown) { // Player holding right
car.x += car.speed * modifier;
}
// Are they touching?
if (
car.x <= (fuel.x + 32)
&& fuel.x <= (car.x + 32)
&& car.y <= (fuel.y + 32)
&& fuel.y <= (car.y + 32)
) {
++fuelsCaught;
reset();
}
};
Try keeping track of the last y value:
var lastY = 0;
var render = function () {
if (bgReady)
ctx.drawImage(bgImage, 0, 0);
if (carReady)
ctx.drawImage(carImage, car.x, car.y, (carImage.width / 100 * 50), (carImage.height / 100 * 50));
var deltaY = car.y - lastY;
carImage.width = carImage.width - deltaY;
carImage.height = carImage.height - deltaY;
lastY = car.y;
};
Related
I'm trying to create a 3D map in p5.js.
I took the code in mouseDragged() and mouseWheel() from prototype.orbitControl function in order to modify it based on the needs of the map.
For some reason, when I tilt the camera to the center and then try to mouse drag in order to move, it would get restricted left to right.
What I need help from is regardless of the tilt and rotation, I'd still be able to move the camera on top of the plane just like google earth.
let canvas, camera;
const sensitivityZ = 0.1;
const scaleFactor = 100;
const sensitivityX = 1;
const sensitivityY = 1;
function setup() {
canvas = createCanvas(windowWidth, 500, WEBGL);
camera = createCamera();
camera._orbit(0, 1, 0); // initial tilt
debugMode(); // show grid
// cursor: suppress right-click context menu
document.oncontextmenu = () => false;
}
function draw() {
background(170);
fill(50);
box(100);
}
function mouseDragged() {
// rotating
if (mouseButton === RIGHT) {
const deltaTheta = (-sensitivityX * (mouseX - pmouseX)) / scaleFactor;
const deltaPhi = (sensitivityY * (mouseY - pmouseY)) / scaleFactor;
camera._orbit(deltaTheta, deltaPhi, 0);
}
// moving
if (mouseButton === LEFT) {
const sensitivityTouch = 1;
const local = camera._getLocalAxes();
// normalize portions along X/Z axes
const xmag = Math.sqrt(local.x[0] * local.x[0] + local.x[2] * local.x[2]);
if (xmag !== 0) {
local.x[0] /= xmag;
local.x[2] /= xmag;
}
// normalize portions along X/Z axes
const ymag = Math.sqrt(local.y[0] * local.y[0] + local.y[2] * local.y[2]);
if (ymag !== 0) {
local.y[0] /= ymag;
local.y[2] /= ymag;
}
// move along those vectors by amount controlled by mouseX, pmouseY
const dx = -1 * sensitivityTouch * (mouseX - pmouseX);
const dz = -1 * sensitivityTouch * (mouseY - pmouseY);
// restrict movement to XZ plane in world space
camera.setPosition(
camera.eyeX + dx * local.x[0] + dz * local.z[0],
camera.eyeY,
camera.eyeZ + dx * local.x[2] + dz * local.z[2]
);
}
}
function mouseWheel(event) {
if (event.delta > 0) {
camera._orbit(0, 0, sensitivityZ * scaleFactor);
} else {
camera._orbit(0, 0, -sensitivityZ * scaleFactor);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.min.js" integrity="sha512-WJXVjqeINVpi5XXJ2jn0BSCfp0y80IKrYh731gLRnkAS9TKc5KNt/OfLtu+fCueqdWniouJ1ubM+VI/hbo7POQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
So I created this small "game" based off of a small intro youtube series about a year ago and I have recently found my old program and was wondering how I expand it. One of my ideas was that there is a variable called "badcube" and if the player was to touch it, it resets the game/score. I was wondering how I would set it up so that every 5 points or so it adds an Identical variable to bad cube making the game harder.
EDIT/UPDATE: so I added some lines based on the response from Jared Bledsoe,
I added the variable var cubebadary = []; and I added the if statement:if (score % 5 == 0){cubebadary.push(new cubebad());} I added this as you will se in the posted code under the function update. but when I try to run it through a simple html page I check the console and It comes with the error:
image of error
what does this mean and how do I chage/fix this?
The Program:
var canvas = document.getElementById("maincanvas");
var context = canvas.getContext("2d");
var keys = [];
var width = 1920,
height = 1080,
speed = 10;
var score = 0;
var player = {
x: 10,
y: 10,
width: 20,
height: 20
};
var cubegood = {
x: Math.random() * (width - 10),
y: Math.random() * (height - 10),
width: 10,
height: 10
};
var cubebad = {
x: Math.random() * (width - 20),
y: Math.random() * (height - 20),
width: 20,
height: 20
};
var cubebadary= [];
window.addEventListener("keydown", function(e) {
keys[e.keyCode] = true;
}, false);
window.addEventListener("keyup", function(e) {
delete keys[e.keyCode];
}, false);
/*
up - 38
down - 40
left - 37
right - 39
*/
function game() {
update();
render();
}
function update() {
if (keys[38]) player.y -= speed;
if (keys[40]) player.y += speed;
if (keys[37]) player.x -= speed;
if (keys[39]) player.x += speed;
if (player.x < 0) player.x = 0;
if (player.x >= width - player.width) player.x = width - player.width;
if (player.y < 0) player.y = 0;
if (player.y >= height - player.height) player.y = height - player.height;
if (collision(player, cubegood)) processgood();
if (collision(player, cubebad)) processbad();
if (score & 5 == 0)
{
cubebadary.push(new cubebad());
}
}
function render() {
context.clearRect(0, 0, width, height)
context.fillStyle = "blue";
context.fillRect(player.x, player.y, player.width, player.height);
context.fillStyle = "red";
context.fillRect(cubegood.x, cubegood.y, cubegood.width, cubegood.height);
context.fillStyle = "black"
context.fillRect(cubebad.x, cubebad.y, cubebad.width, cubebad.height);
context.font = "bold 30px helvetica";
context.fillText(score, 30, 30);
}
function processgood(){
score++;
cubegood.x = Math.random() * (width-10);
cubegood.y = Math.random() * (height-10);
}
function processbad(){
location.reload(true);
}
function collision(first, second) {
return !(first.x > second.x + second.width ||
first.x + first.width < second.x ||
first.y > second.y + second.height ||
first.y + first.height < second.y);
}
setInterval(function() {
game();
}, 1000 / 30);
First, you'll need an array to store all of the new enemies.
var enemies = [];
Then, when you want to create a new enemy:
enemies.push(new cubebad());
To view this in a working demo, feel free to visit a project I'm working on that happens to deal with lots of enemies (asteroids) here - http://asteroidio.bitballoon.com/
Starting at line 333 on that game, you can see the Asteroid object I have which acts as a template for creating all asteroids. Then, once the game initiates I use:
for (let i=0; i<foodValue; i++) {
asteroids[i] = new Asteroids;
}
Which creates a few hundred asteroids, and puts them into an array.
During my summer vacation boredom took over, so I decided to start learning html5-games. In the process of making this very easy game somewhat better in functionality (logical, if you will) I ran into an issue I can't figure out myself. I hope you can guide me accordingly.
So I have race.html (which only has the Canvas to show to game in my webbrowser)
and I have game.js
It's a simply 2D car game. The car goes down a road and in order to not run out of fuel, it has to catch as many fuel-tanks as possible in order to win.
My problem lies in the process of getting the "fuel-tank-image" to render and reset only between the x and y coordinates of the 'road'. Currently it resets and renders all over te place but not specifically on the 'road' where the car is driving.
Here is my game.js code:
// Create the canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = 1024;
canvas.height = 768;
document.body.appendChild(canvas);
// Background image
var bgReady = false;
var bgImage = new Image();
bgImage.onload = function () {
bgReady = true;
};
bgImage.src = "img/map.png";
// car image
var carReady = false;
var carImage = new Image();
carImage.onload = function () {
carReady = true;
};
carImage.src = "img/car.png";
// fuel image
var fuelReady = false;
var fuelImage = new Image();
fuelImage.onload = function () {
fuelReady = true;
};
fuelImage.src = "img/fuel.jpg";
// Game objects
var car = {
speed: 500 // movement in pixels per second
};
var fuel = {};
var fuelsCaught = 0;
// Handle keyboard controls
var keysDown = {};
addEventListener("keydown", function (e) {
keysDown[e.keyCode] = true;
}, false);
addEventListener("keyup", function (e) {
delete keysDown[e.keyCode];
}, false);
// Reset the game when the player catches a fuel
var reset = function () {
car.x = canvas.width / 3;
car.y = canvas.height / 1.3;
// Throw the fuel somewhere on the screen randomly [lengte(math random) keer breedte voor een random plaat in de oppervlakte)]
fuel.x = 300 + (Math.random() * (canvas.width - 700));
fuel.y = 400 + (Math.random() * (canvas.height - 550));
};
// Update game objects
var update = function (modifier) {
if (38 in keysDown) { // Player holding up
car.y -= car.speed * modifier;
}
if (40 in keysDown) { // Player holding down
car.y += car.speed * modifier;
}
if (37 in keysDown) { // Player holding left
car.x -= car.speed * modifier;
}
if (39 in keysDown) { // Player holding right
car.x += car.speed * modifier;
}
// Are they touching?
if (
car.x <= (fuel.x + 32)
&& fuel.x <= (car.x + 32)
&& car.y <= (fuel.y + 32)
&& fuel.y <= (car.y + 32)
) {
++fuelsCaught;
reset();
}
};
// Draw everything
var render = function () {
if (bgReady) {
ctx.drawImage(bgImage, 0, 0);
}
if (carReady) {
ctx.drawImage(carImage, car.x, car.y);
}
if (fuelReady) {
ctx.drawImage(fuelImage, fuel.x, fuel.y);
}
// Score
ctx.fillStyle = "rgb(250, 250, 250)";
ctx.font = "14px Helvetica";
ctx.textAlign = "left";
ctx.textBaseline = "top";
ctx.fillText("Fuel Tanks caught: " + fuelsCaught + "/100", 32, 32);
};
// The main game loop
var main = function () {
var now = Date.now();
var delta = now - then;
update(delta / 1000);
render();
then = now;
// Request to do this again ASAP
requestAnimationFrame(main);
};
// Cross-browser support for requestAnimationFrame
var w = window;
requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame;
// Let's play this game!
var then = Date.now();
reset();
main();
the emphasis is on this piece:
// Throw the fuel somewhere on the screen randomly [lengte(math random) keer breedte voor een random plaat in de oppervlakte)]
fuel.x = 300 + (Math.random() * (canvas.width - 700));
fuel.y = 400 + (Math.random() * (canvas.height - 550));
I have altered the 300 and the 700 often in order to get a clear perspective on the correlation. But to no avail, because the reset is not logical.
this is the image of the road (which has a res of: 1024x768):
this is the car:
And this is the fuel-tank:
and the race.html code is this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Race</title>
</head>
<body>
<script src="js/game.js"></script>
</body>
</html>
The idea is to render/reset the fuel-tank between the road sides and just above the car.
This is fun. So let's say we start by defining the Y coordinate. Y can be between the top of the road and the bottom or the canvas (or 400 as you've given). Your code does this:
fuel.y = 400 + (Math.random() * (canvas.height - 550));
The road gets thinner and starts more towards the right towards the top, we need to define how this happens. Let's say that at the bottom of the screen it starts 10px to the right, and at the maximum y, y=1000px it starts 600px to the right. (I've made these numbers up obviously, you'll have to refine them to suit your case).
Let's also say that at the bottom of the screen the width is 600px and at the top it is 30px. We need to define two formulae to describe:
The left-most x coordinate for each y coordinate,
The road-width for each y coordinate.
Here:
var left_most_x = 10 + ((600-10)/1000) * fuel.y
var road_width = 600 - ((600-30)/1000) * fuel.y
Then you can define the x position as:
fuel.x = left_most_x + (Math.random() * road_width)
Currently when my sprite is moving on the canvas, it will only bounce off after hitting the side of the canvas. Is there a way to let my sprite change to another direction at random position on the canvas?
Here is my code for the changing of direction and how it moves:
Fish.prototype.changeDirection = function () {
speedXSign = this.speedX > 0 ? 1 : -1;
speedYSign = this.speedY > 0 ? 1 : -1;
this.speedX = speedXSign * (1 + Math.random() * 2);
this.speedY = speedYSign * (1 + Math.random() * 2);
};
Fish.prototype.move = function () {
this.animIndex++;
if ( this.animIndex == animFrames.length) this.animIndex = 0;
this.xPos += this.speedX;
if ((this.xPos + this.frameWidth * this.frameScale / 2) >= canvas.width && this.speedX > 0 ||
(this.xPos - this.frameWidth * this.frameScale / 2) <= 0 && this.speedX <= 0) {
this.speedX = -this.speedX;
}
this.yPos += this.speedY;
if ((this.yPos + this.frameHeight * this.frameScale / 2) >= canvas.height && this.speedY > 0 ||
(this.yPos - this.frameHeight * this.frameScale / 2) <= 0 && this.speedY <= 0) {
this.speedY = -this.speedY;
}
};
One fairly simple option is to pick a random amount of time and have the fish change directions after that amount of time. My first thought would be to use setTimeout. I noticed the comparison in your changeDirection function was backward so I fixed that and set it to call itself after some random amount of time.
Fish.prototype.changeDirection = function () {
var me = this;
var speedXSign = this.speedX < 0 ? 1 : -1;
var speedYSign = this.speedY < 0 ? 1 : -1;
this.speedX = speedXSign * (1 + Math.random() * 2);
this.speedY = speedYSign * (1 + Math.random() * 2);
var time = 1000 + 2000*Math.random();
setTimeout(function() {me.changeDirection()}, time);
};
You can change how frequently they turn around by adjusting the time variable.
Then you'll need to initialize the changeDirection loop when you add a new fish so init might look like this:
function init() {
frameWidth = imgFish.width / frameCount ;
frameHeight = imgFish.height ;
document.getElementById("button").onclick = function() {
// create another fish using the Fish class
var anotherFish = new Fish(xPos, yPos, speedX, speedY, imgFish, frameWidth, frameHeight);
// put this new fish into the fishes[] array
fishes.push(anotherFish) ;
// make it start changing directions
anotherFish.changeDirection();
// draw this new fish
anotherFish.drawFish();
}
animate();
}
Also you don't want to change direction every frame so take the fish.changeDirection(); line out of your animate function.
As a side note, you might consider making them change x and y directions independently or randomly instead of every time. This makes it look a more natural.
var speedXSign = Math.random() < 0.5 ? 1 : -1;
var speedYSign = Math.random() < 0.5 ? 1 : -1;
Edit: JSFiddle
I need som help on moving the elements in the array I created call the "Predator" array. Now I have all the images appearing on the SVG box as well as stored in the array.
I have difficulties calling them in a "for" loop and to move them randomly. Further that, I would want to animate the images more closely to real life. Example pls take a look on this website.
<script>
var startPredator = 20; //number of fish to start with
var Predator = []; //array of fish
var predatorW = 307; //fish width
var predatorH = 313; //fish height
var velocity = 100; //base velocity
var imageStrip; //predator image strip
//var backgroundImage; //background image
//var backgroundImageW = 981; //background image width
//var backgroundImageH = 767; //background image height
//var WIDTH = document.body.offsetWidth;
//var HEIGHT = document.body.offsetHeight;
function animate(){
document.animation.src = arraylist[imgNum].src
imgNum++
for (var i=arraylist[].length; i--;){
arraylist[i].move();
}
setInterval(function () { draw(); }, 16.7);
}
function start() {
for (var i = 0; i < arraylist.length; i++) {
var image = document.createElement("img");
image.alt = images[i][0];
image.width = "150";
image.height = "150";
image.src = images[i][1];
var j = i;
if (j > 2) j = i - 3;
document.getElementsByTagName("div")[j].appendChild(image);
}
}
function Predator() {
var angle = Math.PI * 2 * Math.random(); //set the x,y direction this predator swims
var xAngle = Math.cos(angle); //set the x value of the angle
var yAngle = Math.sin(angle); //set the y value of the angle
var zAngle = 1+-2*Math.round(Math.random()); //set if the predator is swimming toward us or away. 1 = toward us; -1 = away from us
var x = Math.floor(Math.random() * (WIDTH - predatorW) + predatorW / 2); //set the starting x location
var y = Math.floor(Math.random() * (HEIGHT - predatorH) + predatorH / 2); //set the starting y location
var zFar = 100; //set how far away can a predator go
var zFarFactor = 1; //set the max size the predator can be. 1=100%
var zClose = 0; //set how near a predator can come
var z = Math.floor(Math.random() * ((zFar - zClose))); //set the starting z location
var scale = .1; //set the rate of scaling each frame
var flip = 1; //set the direction of the fish. 1=right; -1=left
var cellCount = 16; //set the number of cells (columns) in the image strip animation
var cell = Math.floor(Math.random() * (cellCount-1)); //set the first cell (columns) of the image strip animation
var cellReverse = -1; //set which direction we go through the image strip
var species = Math.floor(Math.random() * 3); //set which species of predator this predator is. each species is a row in the image strip
// stop predator from swimming straight up or down
if (angle > Math.PI * 4 / 3 && angle < Math.PI * 5 / 3 || angle > Math.PI * 1 / 3 && angle < Math.PI * 2 / 3) {
angle = Math.PI * 1 / 3 * Math.random();
xAngle = Math.cos(angle);
yAngle = Math.sin(angle);
}
// face the predator the right way if angle is between 6 o'clock and 12 o'clock
if (angle > Math.PI / 2 && angle < Math.PI / 2 * 3) {
flip = -1;
}
function swim() {
// Calculate next position of species
var nextX = x + xAngle * velocity * fpsMeter.timeDeltaS;
var nextY = y + yAngle * velocity * fpsMeter.timeDeltaS;
var nextZ = z + zAngle * .1 * velocity * fpsMeter.timeDeltaS;
var nextScale = Math.abs(nextZ) / (zFar - zClose);
// If species is going to move off right side of screen
if (nextX + fishW / 2 * scale > WIDTH) {
// If angle is between 3 o'clock and 6 o'clock
if ((angle >= 0 && angle < Math.PI / 2)) {
angle = Math.PI - angle;
xAngle = Math.cos(angle);
yAngle = Math.sin(angle) * Math.random();
flip = -flip;
}
// If angle is between 12 o'clock and 3 o'clock
else if (angle > Math.PI / 2 * 3) {
angle = angle - (angle - Math.PI / 2 * 3) * 2
xAngle = Math.cos(angle);
yAngle = Math.sin(angle) * Math.random();
flip = -flip;
}
}
// If fish is going to move off left side of screen
if (nextX - fishW / 2 * scale < 0) {
// If angle is between 6 o'clock and 9 o'clock
if ((angle > Math.PI / 2 && angle < Math.PI)) {
angle = Math.PI - angle;
xAngle = Math.cos(angle);
yAngle = Math.sin(angle) * Math.random();
flip = -flip;
}
// If angle is between 9 o'clock and 12 o'clock
else if (angle > Math.PI && angle < Math.PI / 2 * 3) {
angle = angle + (Math.PI / 2 * 3 - angle) * 2
xAngle = Math.cos(angle);
yAngle = Math.sin(angle) * Math.random();
flip = -flip;
}
}
// If fish is going to move off bottom side of screen
if (nextY + fishH / 2 * scale > HEIGHT) {
// If angle is between 3 o'clock and 9 o'clock
if ((angle > 0 && angle < Math.PI)) {
angle = Math.PI * 2 - angle;
xAngle = Math.cos(angle);
yAngle = Math.sin(angle) * Math.random();
}
}
// If fish is going to move off top side of screen
if (nextY - fishH / 2 * scale < 0) {
// If angle is between 9 o'clock and 3 o'clock
if ((angle > Math.PI && angle < Math.PI * 2)) {
angle = angle - (angle - Math.PI) * 2;
xAngle = Math.cos(angle);
yAngle = Math.sin(angle);
}
}
// If fish is going too far (getting too small)
if (nextZ <= zClose && zAngle < 0) {
zAngle = -zAngle;
}
// If fish is getting to close (getting too large)
if (((WIDTH / fishW) * 10) < ((fishW * fish.length) / WIDTH)) {
zFarFactor = .3
}
else if (((WIDTH / fishW) * 2) < ((fishW * fish.length) / WIDTH)) {
zFarFactor = .5
}
else { zFarFactor = 1 }
if (nextZ >= zFar * zFarFactor && zAngle > 0) {
zAngle = -zAngle;
}
if (scale < .1) { scale = .1 }; //don't let fish get too tiny
//draw the fish
//locate the fish
ctx.save();
ctx.translate(x, y);
ctx.scale(scale, scale); // make the fish bigger or smaller depending on how far away it is.
ctx.transform(flip, 0, 0, 1, 0, 0); //make the fish face the way he's swimming.
ctx.drawImage(imageStrip, fishW * cell, fishH * species, fishW, fishH, -fishW / 2, -fishH / 2, fishW, fishH); //draw the fish
ctx.save();
scale = nextScale // increment scale for next time
ctx.restore();
ctx.restore();
//increment to next state
x = nextX;
y = nextY;
z = nextZ;
if (cell >= cellCount-1 || cell <= 0) { cellReverse = cellReverse * -1; } //go through each cell in the animation
cell = cell + 1 * cellReverse; //go back down once we hit the end of the animation
}
return {
swim: swim
}
}
</script>
My concern is more on the animate and start function. Am I calling the images from the array to move?
Please offer a helping hand. Thanks