Why is my sprite speeding up without changing variables? - javascript
I have a bug in this code somewhere that cause the ship to fly faster and faster in space after returning from the planet. I cant figure this one out.
I set the speed to 0.1 so that its super slow in space. When you click on the planet, i run a function that will move canvas's off screen and use zindex to brong a div tag to the top of the stack. When you land and return to orbit, the ship will move slightly faster. After doing it about 10-15 times the ship moves far greater than the 0.1 speed that is set. I will include the html, js and css so you can run it to test.
Here is the whole code.
// Canvas Context's
var canvasMS = document.getElementById('MainScreen_cvs');
var ctxMain = canvasMS.getContext('2d');
var canvasShip = document.getElementById('Ship_cvs');
var ctxShip = canvasShip.getContext('2d');
var PlanetDiv = document.getElementById('PlanetDiv');
var OrbitReturn = document.getElementById('OrbitReturn');
var canvasPlanets = document.getElementById('Planets_cvs');
var ctxPlanets = canvasPlanets.getContext('2d');
var canvasHUD = document.getElementById('HUD_cvs');
var ctxHUD = canvasHUD.getContext('2d');
var canvasSurface = document.getElementById('Surface_cvs');
var ctxSurface = canvasSurface.getContext('2d');
// ----------------------------------End Canvas Context
var Player1;
var Planet1;
var planetClicked;
var gameWidth = canvasMS.width;
var gameHeight = canvasMS.height;
var mouseX = 10000;
var mouseY = 10000;
var SpaceMapX = 10;
var SpaceMapY = 10;
var SurfaceMap = 0;
var SurfaceMap2 = -1600;
var inSpace = true;
var onSurface = false;
var requestAnimFrame = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame;
// Load Images
var imgMap = new Image();
imgMap.src = 'images/bg1.png';
var imgButtons = new Image();
imgButtons.src = 'images/button_sprite.png';
var imgBlueWindow = new Image();
imgBlueWindow.src = 'images/blue_window.png';
var imgSprite = new Image();
imgSprite.src = 'images/sprite.png';
var imgPlanets = new Image();
imgPlanets.src = 'images/earthlike_p1.png';
var imgBluesky1 = new Image();
imgBluesky1.src = 'images/bluesky1.png';
var imgBluesky2 = new Image();
imgBluesky2.src = 'images/bluesky2.png';
imgMap.addEventListener('load',init,false);
// ------------- End Loading Images
//-------------------- Create Game Objects ----------------
function CreateGameObjects(){
Player1 = new Ship();
Planet1 = new Planet();
};
//---------------END CREATING GAME OBJECTS------------------
function init(){ //----------------------------------------------- GAME INITIALIZATION
document.addEventListener('keydown',checkKeyDown,false);
document.addEventListener('keyup',checkKeyUp,false);
document.addEventListener("mousedown", checkMouseDown, false);
document.addEventListener("mouseup", checkMouseUp, false);
CreateGameObjects();
Loop();
};
function Loop() { // ---------------- Main Game Loop
clearCtx();
DrawGameObjects();
requestAnimFrame(Loop);
};
function planetSurface(){
if(onSurface){
clearCtx();
HUD();
Player1.draw();
if(mouseY < 21 && mouseX > 693){
ReturntoOrbit();
}
planetClicked.drawSurfaceImg();
var CloseButton = '<button style="float:right;" type="button">Return to Orbit</button>' ;
OrbitReturn.innerHTML = CloseButton;
requestAnimFrame(planetSurface);
}
};
function DrawGameObjects(){
Player1.draw();
Planet1.draw();
HUD();
};
function HUD(){
canvasHUD.style.zIndex = "100";
if (onSurface){
ctxHUD.fillStyle = "#000";
ctxHUD.fillText("locSurface: " + planetClicked.locSurface, 20,30);
}
if (inSpace)
ctxHUD.fillStyle = "#fff";
ctxHUD.fillText("Speed: " + Player1.speed, 60,60);
ctxHUD.fillText("drawX: " + Player1.drawX, 600,40);
ctxHUD.fillText("drawY: " + Player1.drawY, 600,30);
// ctxHUD.fillText("Planet Clicked: " + Planet1.isClicked, 600,50);
}
//----------------------------------------------------------- Objects
/************************************************************************************/
//--------------------------------- SPACE SHIP --------------------------------------
function Ship(){
this.srcX = 0;
this.srcY = 0;
this.srcW = 60;
this.srcH = 60;
this.drawX = 20 ;
this.drawY = 50 ;
this.speed = 0;
this.surfaceSpeed = 10;
this.drift = 0.45;
this.w = 16;
this.h = 16;
this.isUpKey = false;
this.isDownKey = false;
this.isLeftKey = false;
this.isRightKey = false;
this.isSpacebar = false;
this.direction = "n/a";
this.isMoving = false;
this.isClicked = false;
this.surfX = 350;
this.surfY = 200;
};
Ship.prototype.draw = function() {
if(inSpace)
ctxShip.drawImage(imgSprite,this.srcX,this.srcY,this.srcW,this.srcH,this.drawX,this.drawY,this.w,this.h);
if(onSurface)
ctxShip.drawImage(imgSprite,this.srcX,this.srcY,this.srcW,this.srcH,this.surfX,this.surfY,this.w,this.h);
this.checkPos(planetClicked);
};
Ship.prototype.checkPos = function (PlanetX){
if(inSpace){
this.srcY = 0;
this.srcW = 60;
this.w = 16;
this.h = 16;
this.speed = 0.1;
//----------------------------- Move Ship and Map based on the speed of the ship.
if(this.isLeftKey){
this.drawX -= this.speed;
if(SpaceMapX >= 1){
SpaceMapX -= this.speed;
}
}
if(this.isRightKey){
this.drawX += this.speed;
if(SpaceMapX <= 2190)SpaceMapX += this.speed;
}
if(this.isDownKey){
this.drawY += this.speed;
if(SpaceMapY <= 2490)SpaceMapY += this.speed;
}
if (this.isUpKey) {
this.drawY -= this.speed;
if(SpaceMapY >= 1){
SpaceMapY -= this.speed;
}
}
if (SpaceMapY < 0) {SpaceMapY = 0;}
if (SpaceMapX < 0 ) {SpaceMapX = 0}
//--------------------------------------------------------------------END
//-----------------------------------Change Ship Graphic based on direction and map boundaries.
if(this.isUpKey) this.srcX = 360;
if(this.isDownKey) this.srcX = 120;
if(this.isLeftKey) this.srcX = 240;
if(this.isRightKey) this.srcX = 0;
if(this.isUpKey && this.isLeftKey) this.srcX = 300;
if(this.isUpKey && this.isRightKey) this.srcX = 420;
if(this.isDownKey && this.isLeftKey) this.srcX = 180;
if(this.isDownKey && this.isRightKey) this.srcX = 60;
if (this.drawX <= 5) this.drawX = 5;
if (this.drawY <= 5) {this.drawY = 5};
if (this.drawY >= 480) {this.drawY = 480};
if (this.drawX >= 780) {this.drawX = 780};
//----------------------------------------------------------------END
ctxMain.drawImage(imgMap,SpaceMapX,SpaceMapY,gameWidth,gameHeight,0,0,gameWidth,gameHeight);
}
if (onSurface) {
this.srcY = 240;
this.srcW = 92;
this.w = 93;
this.h = 60;
if(this.isLeftKey){
PlanetX.locSurface -= this.surfaceSpeed;
SurfaceMap += this.surfaceSpeed;
SurfaceMap2 += this.surfaceSpeed;
PlanetX.MapDirection = -1;
this.srcX = 93;
}
if(this.isRightKey){
PlanetX.locSurface += this.surfaceSpeed;
SurfaceMap -= this.surfaceSpeed;
SurfaceMap2 -= this.surfaceSpeed;
PlanetX.MapDirection = 1;
this.srcX = 0;
}
}
};
//------------------------------END OF SPACE SHIP ------------------------------------
//----------------------------- PLANET OBJECT INFO ------------------------------------
function Planet(){
this.srcX = 0;
this.srcY = 0;
this.srcW = 100;
this.srcH = 100;
this.w = 50;
this.h = 50;
this.coordX = 100;
this.coordY = 100;
this.planetType = "Small Earthlike Planet."
this.drawX = this.coordX - SpaceMapX;
this.drawY = this.coordY - SpaceMapY;
this.surfaceIMG = imgBluesky1;
this.isClicked = false;
this.locSurface = 0;
};
Planet.prototype.draw = function(){
this.drawX = this.coordX - SpaceMapX;
this.drawY = this.coordY - SpaceMapY;
ifClicked(this);
if(this.isClicked){
PlanetDiv.style.display = "block";
var LandPlanetDivButton = '<button id="LandPlanetDivButton" type="button" onclick="landOnSurface();">Land On Surface</button>';
var ClosePlanetDivButton = '<button id="ClosePlanetDivButton" type="button" onclick="ClosePlanetDiv();">Close (x)</button><br/><p id="PlanetDivText">' ;
PlanetDiv.style.zIndex = "2";
HideCanvas();
planetClicked = this;
PlanetDiv.innerHTML = LandPlanetDivButton + ClosePlanetDivButton + this.planetType; + '</p>';
}
ctxPlanets.drawImage(imgPlanets,this.srcX,this.srcY,this.srcW,this.srcH,this.drawX,this.drawY,this.w,this.h);
};
Planet.prototype.drawSurfaceImg = function(){
if(SurfaceMap2 >= 0) SurfaceMap2 = -1600;
if(SurfaceMap2 < -1600) SurfaceMap2 = -1;
if(SurfaceMap >= 1600) SurfaceMap = 0;
if(SurfaceMap < 0) SurfaceMap = 1599;
ctxSurface.drawImage(this.surfaceIMG, 0, 0, 1600, gameHeight, SurfaceMap, 0, 1600, gameHeight);
ctxSurface.drawImage(this.surfaceIMG, 0, 0, 1600, gameHeight, SurfaceMap2, 0, 1600, gameHeight);
};
//----------------------------- END OF PLANET OBJECT -----------------------------------
//-----end Objects
function randomFromTo(from,to){
return Math.floor(Math.random()*(to-from+1)+from);
};
function closestNum(Num, a){
var num = Num + (gameWidth/2);
var closest = a[0];
var difference = Math.abs (num - closest);
for (var i = 0; i < a.length; i++) {
var difference2 = Math.abs (num - a[i]);
if (difference2 < difference) {
difference = difference2;
closest = a[i];
}
}
return closest;
};
function sortNum(a)
{
var swapped;
do{
swapped = false;
for (var i=0; i < a.length-1; i++) {
if (a[i] > a[i+1]) {
var temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
swapped = true;
}
}
}while (swapped);
};
function ifClicked(obj){
if(mouseX >= obj.drawX && mouseX <= obj.drawX + obj.w){
if(mouseY >= obj.drawY && mouseY <= obj.drawY + obj.h){
obj.isClicked = true;
}
}
else{
obj.isClicked = false;
}
};
function clearCtx() {
ctxMain.clearRect(0,0,gameWidth,gameHeight);
ctxShip.clearRect(0,0,gameWidth,gameHeight);
ctxPlanets.clearRect(0,0,gameWidth,gameHeight);
ctxHUD.clearRect(0,0,gameWidth,gameHeight);
ctxSurface.clearRect(0,0,gameWidth,gameHeight);
};
function checkKeyDown(e){
var keyID = e.keyCode || e.which;
if(keyID === 38 || keyID === 87){ // up arrow or W key
Player1.isUpKey = true;
Player1.direction = "North";
Player1.isMoving = true;
e.preventDefault();
}
if(keyID === 39|| keyID === 68){ // right arrow or D key
Player1.isRightKey = true;
Player1.direction = "East"
Player1.isMoving = true;
e.preventDefault();
}
if(keyID === 40 || keyID === 83){ // down arrow or S key
Player1.isDownKey = true;
Player1.direction = "South";
Player1.isMoving = true;
e.preventDefault();
}
if(keyID === 37 || keyID === 65){ // left arrow or A key
Player1.isLeftKey = true;
Player1.direction = "West";
Player1.isMoving = true;
e.preventDefault();
}
};
function checkKeyUp(e){
var keyID = e.keyCode || e.which;
if(keyID === 38 || keyID === 87){ // up arrow or W key
Player1.isUpKey = false;
Player1.isMoving = false;
e.preventDefault();
}
if(keyID === 39|| keyID === 68){ // right arrow or D key
Player1.isRightKey = false;
Player1.isMoving = false;
e.preventDefault();
}
if(keyID === 40 || keyID === 83){ // down arrow or S key
Player1.isDownKey = false;
Player1.isMoving = false;
e.preventDefault();
}
if(keyID === 37 || keyID === 65){ // left arrow or A key
Player1.isLeftKey = false;
Player1.isMoving = false;
e.preventDefault();
}
};
function clearMouse(){
mouseX = 10000;
mouseY = 10000;
};
function checkMouseDown(e) {
var mX = (e.clientX - (canvasMS.offsetLeft - canvasMS.scrollLeft));
var mY = (e.clientY - (canvasMS.offsetTop - canvasMS.scrollTop));
if(mX <= gameWidth && mX >= 0) mouseX = mX;
if(mY <= gameHeight && mY >= 0) mouseY = mY;
//mouseIsDown = true;
};
function checkMouseUp(e){
//mouseIsDown = false;
clearMouse();
};
function ClosePlanetDiv (){
PlanetDiv.style.zIndex = "-2";
PlanetDiv.innerHTML = "";
PlanetDiv.style.display = "none";
ShowCanvas();
};
function HideCanvas(){
canvasShip.style.marginTop = "-10000px";
canvasPlanets.style.marginTop = "-10000px";
};
function ShowCanvas(){
canvasShip.style.marginTop = "-500px";
canvasPlanets.style.marginTop = "-500px";
};
function landOnSurface(){
ClosePlanetDiv();
inSpace = false;
onSurface = true;
Player1.srcX = 0;
planetSurface();
canvasSurface.style.display = "block";
OrbitReturn.style.display = "block";
};
function ReturntoOrbit(){
OrbitReturn.style.display = "none";
canvasSurface.style.display = "none";
inSpace = true;
onSurface = false;
Loop();
};
<!doctype html>
<html lang='en'>
<head>
<meta charset="utf-8">
<title>Space Explorer</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="Functions.js"></script>
</head>
<body>
<canvas id="MainScreen_cvs" width="800" height="500"></canvas>
<div id="PlanetDiv"></div>
<canvas id="Surface_cvs" width="800" height="500"></canvas>
<canvas id="Ship_cvs" width="800" height="500"></canvas>
<canvas id="Planets_cvs" width="800" height="500"></canvas>
<canvas id="HUD_cvs" width="800" height="500"></canvas>
<div id="OrbitReturn"></div>
<div id="log">
<h1 style="color:blue;">Recent updates will be logged here when made live.</h1>
<hr />
<h3> Wednesday August 3, 2016 </h3>
<ul>
<li> HTML file completed. Working on getting JS files started.</li>
<li> JS files created. </li>
<li>Basic ship & flight functions in place. Basic star map initialized.</li>
</ul>
<hr />
</div>
<script type="text/javascript" src="game.js"></script>
</body>
</html>
body {
background: #303030;
}
#MainScreen_cvs {
position: relative;
display: block;
background: #777777 ;
margin: 30px auto 0px;
z-index: 1;
}
#Surface_cvs{
position: relative;
display: none;
z-index: 1;
margin: -500px auto 0px;
}
#Ship_cvs, #Planets_cvs, #HUD_cvs {
display: block;
position: relative;
margin: -500px auto 0px;
z-index: 1;
}
#log {
display: block;
position: absolute;
top: 560px;
left: 233px;
background: #ffffff;
overflow: scroll;
width: 800px;
height: 300px;
z-index: 3;
}
#OrbitReturn{
display: block;
position: relative;
width: 800px;
height: 500px;
z-index: 3;
margin: -500px auto 0px;
}
#PlanetDiv {
display: block;
position: relative;
width: 800px;
height: 500px;
background-image: url("images/Sky.jpg");
z-index: -2;
margin: -500px auto 0px;
}
#ClosePlanetDivButton{
float: right;
}
#LandPlanetDivButton{
position: absolute;
top: 400px;
left: 325px;
font-size: 20px;
}
#PlanetDivText{
text-indent: 50px;
font-size: 20px;
}
Something is happening with Ship.prototype.checkPos. Each time you land on the planet, it looks like the checking pauses, then starts up when you enter orbit. But this time he checkPos is getting called faster.
I could keep staring at it but you might be able to figure it out from there. I put a console.log('checkPos') at the top of that function and watched it pause and restart.
Ship.prototype.checkPos = function(PlanetX) {
console.log('checkPos');
if (inSpace) {
...
I think it might be here
function ReturntoOrbit() {
OrbitReturn.style.display = "none";
canvasSurface.style.display = "none";
inSpace = true;
onSurface = false;
//Loop(); <--- this little guy. Get rid of him.
};
Related
Prevent block from touching the containers borders
I have this little block that I move around using javascript code. It works all good except if I keep moving it, it can easily get out of the box where it is supposed to be. Can I prevent this somehow? So no matter how far I want to move it, it will stay stuck inside of the container/box ? Here's my snippet code: /// store key codes and currently pressed ones var keys = {}; keys.UP = 38; keys.LEFT = 37; keys.RIGHT = 39; keys.DOWN = 40; /// store reference to character's position and element var character = { x: 100, y: 100, speedMultiplier: 2, element: document.getElementById("character") }; var is_colliding = function(div1, div2) { var d1_height = div1.offsetHeight; var d1_width = div1.offsetWidth; var d1_distance_from_top = div1.offsetTop + d1_height; var d1_distance_from_left = div1.offsetLeft + d1_width; var d2_height = div2.offsetHeight; var d2_width = div2.offsetWidth; var d2_distance_from_top = div2.offsetTop + d2_height; var d2_distance_from_left = div2.offsetLeft + d2_width; var not_colliding = d1_distance_from_top <= div2.offsetTop || div1.offsetTop >= d2_distance_from_top || d1_distance_from_left <= div2.offsetTop || div1.offsetLeft >= d2_distance_from_left; return !not_colliding; }; /// key detection (better to use addEventListener, but this will do) document.body.onkeyup = document.body.onkeydown = function(e){ if (e.preventDefault) { e.preventDefault(); } else { e.returnValue = false; } var kc = e.keyCode || e.which; keys[kc] = e.type == 'keydown'; }; /// character movement update var moveCharacter = function(dx, dy){ character.x += (dx||0) * character.speedMultiplier; character.y += (dy||0) * character.speedMultiplier; character.element.style.left = character.x + 'px'; character.element.style.top = character.y + 'px'; }; /// character control var detectCharacterMovement = function(){ if ( keys[keys.LEFT] ) { moveCharacter(-5, 0); } if ( keys[keys.RIGHT] ) { moveCharacter(5, 0); } if ( keys[keys.UP] ) { moveCharacter(0, -5); } if ( keys[keys.DOWN] ) { moveCharacter(0, 5); } }; /// update current position on screen moveCharacter(); /// game loop setInterval(function(){ detectCharacterMovement(); }, 1000/24); body{ display: flex; justify-content: center; align-items: center; } #character { position: absolute; width: 42px; height: 42px; background: red; z-index:99; } #container{ width: 400px; height: 400px; background: transparent; border:5px solid rgb(0, 0, 0); position: relative; overflow: hidden; } <div id="container"> <div id="character"></div> </div> PS: You can move the box using keyboard arrows.
Get the container width and height into variable and set a condition on your move var moveCharacter = function(dx, dy){ let div_width = document.getElementById('container').clientWidth; let div_height = document.getElementById('container').clientHeight; if((div_width - character.x) < 50 ){ // 50 = width of character and padding character.x = div_width - 50; } if(character.x < 10){ // Padding character.x = 11; } if((div_height - character.y) < 50 ){ character.y = div_height - 50; } if(character.y < 10){ character.y = 11; }
Collision detection between bricks and ball (working with an array of numbers)
I want to detect a collision between my ball and my bricks with an array made of numbers. It works but not completely. If you look at my code, you see an array made of numbers from 0 to 5. 0 means that there is no brick detected and the rest is made of a color. The problem is that my function only detects a collision with the color 1 (black) but not the rest. What is the problem? var canvas = document.getElementById("mijnCanvas"); var mijnObject = canvas.getContext("2d"); var afbeelding = new Image(); var balkX = (canvas.width/2)-50; var balkY = canvas.height-40; var balX = canvas.width/2; var balY = canvas.height-50; var radius = 8; var balNaarX = 5; var balNaarY = 5; function makenBalkKort() { mijnObject.drawImage(afbeelding, balkX, balkY, afbeelding.width, afbeelding.height); } afbeelding.src = "Afbeeldingen/BrickSmasher_Balk_Kort.png"; function makenBal() { mijnObject.beginPath(); var mijnBalGradient = mijnObject.createRadialGradient(balX, balY, 0, balX, balY, 6); mijnBalGradient.addColorStop(0, "#000000"); mijnBalGradient.addColorStop(1, "#FFFFFF"); mijnObject.fillStyle = mijnBalGradient; mijnObject.strokeStyle = "#000000"; mijnObject.arc(balX, balY, radius, 0, 2*Math.PI, false); mijnObject.fill(); mijnObject.stroke(); mijnObject.closePath(); } function tekenenObjecten() { mijnObject.clearRect(0, 0, canvas.width, canvas.height); makenBalkKort(); makenBal(); makenMuur(); collisieMetStenenX(); setTimeout(function() { if(balX+balNaarX < radius || balX+balNaarX > canvas.width-radius) { balNaarX = -balNaarX; } if(balY+balNaarY < radius) { balNaarY = -balNaarY; } if(balY+balNaarY > balkY-radius) { if(balX+balNaarX >= balkX && balX+balNaarX <= balkX+afbeelding.width) { balNaarY = -balNaarY; } else { alert("Game over"); document.location.reload(); } } balX += balNaarX; balY += balNaarY; }, 1000); } setInterval(tekenenObjecten, 20); window.addEventListener("keydown", function LinksOfRechts() { mijnObject.clearRect(balkX, balkY, canvas.width, canvas.height); var balkNaarX = 10; var code = event.which || event.keyCode; if(code == 37) { if(balkX > 0) { balkX -= balkNaarX; } } else if(code == 39) { if(balkX < canvas.width-afbeelding.width) { balkX += balkNaarX; } } mijnObject.drawImage(afbeelding, balkX, balkY, afbeelding.width, afbeelding.height); }); canvas.addEventListener("click", function balkLangMaken() { mijnObject.clearRect(balkX, balkY, canvas.width, canvas.height); afbeelding.src = "Afbeeldingen/BrickSmasher_Balk_Lang.png"; setTimeout(function() { mijnObject.clearRect(balkX, balkY, canvas.width, canvas.height); afbeelding.src = "Afbeeldingen/BrickSmasher_Balk_Kort.png"; }, 3000); }); var stenenPerRij = 27; var steenHoogte = 20; var steenBreedte = canvas.width/stenenPerRij; var stenen = [ [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0], [0,1,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,1,0], [0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,1,1,0,0,2,2,2,2,0,0,0,0,0,0,1,0,1,4,4,4,0,1,0,0,0,1], [1,0,0,1,0,2,0,0,0,2,0,0,0,0,0,1,0,1,0,0,0,0,1,1,0,0,1], [1,1,1,1,0,2,2,2,2,0,0,0,0,0,0,1,0,1,4,4,0,0,1,0,1,0,1], [1,0,0,1,0,2,0,2,0,0,0,1,0,0,0,1,0,1,0,0,0,0,1,0,0,1,1], [1,0,0,1,0,2,0,0,2,2,0,0,1,1,1,0,0,1,4,4,4,0,1,0,0,0,1], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], ]; function makenMuur() { for(var i = 0; i < stenen.length; i = i+1) { for(var j = 0; j < stenen[i].length; j = j+1) { tekenenStenen(j,i,stenen[i][j]); } } } function tekenenStenen(x,y,stenen) { switch(stenen) { case 1: mijnObject.fillStyle = "#0d0d0d"; break; case 2: mijnObject.fillStyle = "#333333"; break; case 3: mijnObject.fillStyle = "#595959"; break; case 4: mijnObject.fillStyle = "#808080"; break; case 5: mijnObject.fillStyle = "#a6a6a6"; break; default: mijnObject.clearRect(0, 0, steenBreedte, steenHoogte); break; } if(stenen) { mijnObject.beginPath(); mijnObject.strokeStyle = "#000000"; mijnObject.rect(x*steenBreedte, y*steenHoogte, steenBreedte, steenHoogte); mijnObject.fill(); mijnObject.stroke(); mijnObject.closePath(); } } function collisieMetStenenX() { for(var i = 0; i < stenen.length; i = i+1) { for(var j = 0; j < stenen[i].length; j = j+1) { if(stenen[i][j] == true) { var steenX = j*steenBreedte; var steenY = i*steenHoogte; if((balX+balNaarX > steenX && balX+balNaarX < steenX+steenBreedte) && (balY+balNaarY > steenY && balY+balNaarY < steenY+steenHoogte)) { balNaarY = -balNaarY; } } } } } Here is my HTML-code: <!doctype html> <html> <head> <meta charset="utf-8"> <title>BrickSmasher</title> <style> canvas { position: relative; margin-left: auto; margin-right: auto; display: block; } </style> </head> <body> <canvas id="mijnCanvas" width="1200" height="600" style="border: 1px solid black"></canvas> <script src="BrickSmasher.js"></script> </body> </html>
Replace this line: if(stenen[i][j] == true) { with: if(stenen[i][j] > 0) { or simply: if(stenen[i][j]) { The reason is that when you compare with true, JavaScript needs to do a conversion. As one side of the equation is numeric, the boolean expression on the other side is converted to the numeric equivalent of true, which is 1. That means there is no equality when stenen[i][j] is 2, 3, ... The last alternative works, because there the conversion is in the opposite sense: an if condition needs to resolve to a boolean value. So the numerical value is converted to boolean. And there any non-zero value will convert to true.
JavaScript: change object path if collision detected
I have to create some falling snowflakes in javascript, but they have change current path if they get collision with other flake. Something like on this image: Here is my current code: http://codepen.io/wojtek1150/pen/QyaYdY var flakePositions = [[]]; var temp = 0; // snowflake proto function Snowflake() { this.pos = new Physics(); // snowflake guid this.id = ''; // inits this.MAX_X_START_POS = 100; this.X_START_OFFSET = 0; this.MAX_Y_START_POS = 50; this.Y_START_OFFSET = -50; this.MAX_X_SPEED = 4; this.MAX_Y_SPEED = 1.2; // use to get sin && cos this.animationStepsCounter = 0 this.fallFactor = 100; // snowflake html this.getId = function () { if (this.id == '') { this.id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { var r = crypto.getRandomValues(new Uint8Array(1))[0] % 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } return this.id; } this.initalize = function () { temp++; //var size = 5 + Math.random() * 20; var size = 20; this.flakeDOM.style.width = size + "px"; this.flakeDOM.style.height = size + "px"; this.flakeDOM.style.opacity = Math.random(); this.pos.x = (Math.random() * this.MAX_X_START_POS); this.pos.y = this.Y_START_OFFSET+(Math.random() * this.MAX_Y_START_POS); this.pos.xSpeed = Math.random() * this.MAX_X_SPEED* Math.sign(-0.5 + Math.random()); this.pos.ySpeed = Math.random() * this.MAX_Y_SPEED; //create array flakePositions[temp] = []; flakePositions[temp]['id'] = this.id; flakePositions[temp]['x'] = this.flakeDOM.style.top; flakePositions[temp]['y'] = this.flakeDOM.style.left; flakePositions[temp]['width'] = this.flakeDOM.style.width; flakePositions[temp]['height'] = this.flakeDOM.style.height; flakePositions[temp]['xspeed'] = this.pos.xSpeed; flakePositions[temp]['yspeed'] = this.pos.ySpeed } this.move = function () { this.flakeDOM.style.top = (this.pos.y+=this.pos.ySpeed) + "px"; this.flakeDOM.style.left = (this.pos.x += Math.sin(this.animationStepsCounter/this.fallFactor) * this.pos.xSpeed) + "px"; this.animationStepsCounter += this.pos.ySpeed; //update array flakePositions[temp]['x'] = this.flakeDOM.style.top; flakePositions[temp]['y'] = this.flakeDOM.style.left; //check position with rest for (var i = 1, len = flakePositions.length; i < len-1; i++) { var rect1 = flakePositions[i]; var rect1d = rect1['id']; var rect1sx = rect1['xspeed']; var rect1sy = rect1['yspeed']; var rect1x = parseInt(rect1['x']); var rect1y = parseInt(rect1['y']); for (var j = 2, len = flakePositions.length; j < len; j++) { var rect2 = flakePositions[j]; var rect2d = rect2['id']; var rect2x = parseInt(rect2['x']); var rect2y = parseInt(rect2['y']); //if(rect1x == rect2x && rect1y == rect2y) if(rect1x < rect2x + 10 && rect1x + 10 > rect2x && rect1y < rect2y + 10 && 10 + rect1y > rect2y ) { console.log('collision detected'); var t = document.getElementById(rect1d); t.style.top = t.style.top+rect1sx+10; t.style.left = t.style.left+rect1sy-10; } } } } } function Physics() { // pos this.x = 0; this.y = 0; this.z = 0; // speed this.xSpeed = 0; this.ySpeed = 0; this.zSpeed = 0; // acceleration this.xAccel = 1; this.yAccel = 1; this.zAccel = 1; } snowflakes = new Array(); var interval = 0; function makeThisBoom() { // snowflakes container snowfield = document.getElementById('snow'); // snowflakes count snoflakesCount = 20; for (var i = 0; i < snoflakesCount; i++) { snowflakes[i] = new Snowflake(); var flake = document.createElement('div'); snowflakes[i].flakeDOM = flake; flake.id = snowflakes[i].getId(); flake.classList.add('sf'); snow.appendChild(flake); snowflakes[i].initalize(); snowflakes[i].move(); } interval = setInterval(anime,50); } function anime() { for (var flake of snowflakes) { flake.move(); } } function setInterface() { document.getElementById('startstop').onclick = function () { if (interval != 0) { clearInterval(interval); interval = 0; } else interval = setInterval(anime, 50); } } document.addEventListener("DOMContentLoaded", makeThisBoom); document.addEventListener("DOMContentLoaded", setInterface); .sf{ position:absolute; z-index:9999999; /*background: -moz-radial-gradient(center, ellipse cover, rgba(255,255,255,1) 0%, rgba(255,255,255,0) 100%); background: -webkit-radial-gradient(center, ellipse cover, rgba(255,255,255,1) 0%,rgba(255,255,255,0) 100%); background: radial-gradient(ellipse at center, rgba(255,255,255,1) 0%,rgba(255,255,255,0) 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#00ffffff',GradientType=1 ); */ border-radius:50%; display:block; width:20px; height:20px; /* FOR DEV ONLY */ background:#FFF; opacity:1!important; } body{ background:#222; overflow:hidden; } #snow { position: absolute; width: 100%; height: 100%; overflow: hidden; } #startstop{ width:100px; height:30px; border:0; background:rgb(61, 95, 123); color:#FFF; outline:none; } <button id="startstop">Start/stop</button> <div id="snow"> </div> I already know how to get positions and I got if statement to check if there is any collision. But I don't know how to change path in proper way, even just bounce it :( Any suggestions?
One of the key things for you to think about when doing this, are the cost/reward of implementing this kind of feature. I don't think these collisions will help you create the illusion of snowfalling. When the snowflakes in your current iteration miss each other it gives the illusion of 3d. If they were to hit each other and bounce it might give the incorrect illusion of balls falling in a 2d plane. That being said, to implement what you are asking without using a library would be a huge time sync. I would recommend taking a look at PhysicsJS or matter-js. Below you can see the function I personally use in a library I was working on. You can adapt most of it for your use. The truth is this a complicated ask. define( 'detect/detectCircleCircleCollision' , [ 'lib/underscore' ] , function ( _ ) { return function detectCircleCircleCollision ( circlePositionA, circleRadiusA, circleDisplacementA, circlePositionB, circleRadiusB, circleDisplacementB, boolean, normalBody ) { boolean = _.isUndefined( boolean ) || boolean ? true : false; normalBody = _.isUndefined( normalBody ) || normalBody ? true : false; var relativePosition = circlePositionA.subtract.new( circlePositionB ), combineRadius = circleRadiusA + circleRadiusB, relativePositionDotProduct = relativePosition.lengthSqr(), relativeDisplacement = circleDisplacementA.subtract.new( circleDisplacementB ), a,b,c,r,t,newCircleOnePosition,newCircleTwoPosition,newCirclePositionDifference,collisionPoint; if ( relativePositionDotProduct < combineRadius * combineRadius ) { if ( boolean ) return true; return collision( 0,//Time circlePositionB.add.new( vector( relativePosition ).magnitude.set( circleRadiusA ) ),//point relativePosition.normalize(),//Normal normalBody,//normalbody vector( relativePosition ).magnitude.set( circleRadiusA + circleRadiusB - relativePosition.magnitude() ) );//intersection } a = relativeDisplacement.dotProduct( relativeDisplacement ); b = relativePosition.dotProduct( relativePosition ); c = relativePositionDotProduct - combineRadius * combineRadius; r = b * b - a * c; if ( r < 0 ) return false; t = -b - r * r / a; if ( t > 1 || t < 0 ) return false; else if ( boolean ) return true; newCircleOnePosition = circleDisplacementA.scale.new( t ).add( circlePositionA ); newCircleTwoPosition = circleDisplacementB.scale.new( t ).add( circlePositionB ); newCirclePositionDifference = newCircleTwoPosition.subtract.new( newCircleOnePosition ).normalize(); collisionPoint = newCirclePositionDifference.scale.new( circleRadiusA ); return collision( t, collisionPoint.add( newCircleOnePosition ), newCirclePositionDifference, normalBody, false ); }; } );
How do I get my arrow widget to rotate back to start on second click
After following two YouTube lessons, I now have a nice arrow widget that fades in, rotates to 180 degrees and fades out controlled from one button. I do not know how to make the arrow rotate back to 0 on the second click of this button. Probably not the most elegant of code, but here we are: <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Fade In and Out</title> <style type="text/css"> div.contentbox { width: 50px; height: 50px; padding: 20px; opacity: 0; } </style> <script type="text/javascript"> var fade_in_from = 0; var fade_out_from = 10; function fadeIn(element) { var target = document.getElementById(element) target.style.display = "block"; var newSetting = fade_in_from / 10; target.style.opacity = newSetting; fade_in_from++; if(fade_in_from == 10) { target.style.opacity = 1; clearTimeout(loopTimer); fade_in_from = 0; return false; } var loopTimer = setTimeout('fadeIn(\''+element+'\')', 50); } function fadeOut(element) { var target = document.getElementById(element) var newSetting = fade_out_from / 10; target.style.opacity = newSetting; fade_out_from--; if(fade_out_from == 0) { target.style.opacity = 0; clearTimeout(loopTimer); fade_out_from = 10; return false; } var loopTimer = setTimeout('fadeOut(\''+element+'\')', 50); } var looper; var degrees = 0; function rotateAnimation(el,speed) { var elem = document.getElementById(el); if(navigator.userAgent.match("Chrome")){ elem.style.WebkitTransform = "rotate("+degrees+"deg)"; } else if(navigator.userAgent.match("Firefox")){ elem.style.MozTransform = "rotate("+degrees+"deg)"; } else if(navigator.userAgent.match("MSIE")){ elem.style.msTransform = "rotate("+degrees+"deg)"; } else if(navigator.userAgent.match("Opera")){ elem.style.OTransform = "rotate("+degrees+"deg)"; } else { elem.style.transform = "rotate("+degrees+"deg)"; } looper = setTimeout ('rotateAnimation(\''+el+'\','+speed+')',speed); degrees++; if(degrees > 179){ clearTimeout(looper) } } </script> </head> <body> <button onmouseover="fadeIn('arrow_box')": onmouseout="fadeOut('arrow_box')": onclick="rotateAnimation('arrow',5)">fade in/out</button> <div id="arrow_box" class="contentbox"><img id="arrow" img src="images/Arrow.png" width="50" height="50" alt="Arrow" /></div> </body> </html> Please help.
Create a new variable to remember the direction and then increment or decrement the degrees depending on which direction you want to go. Here is a JSfiddle link of a working solution. var looper; var degrees = 0; var direction = 0; function rotateAnimation(el,speed){ var elem = document.getElementById(el); if(navigator.userAgent.match("Chrome")){ elem.style.WebkitTransform = "rotate("+degrees+"deg)"; }else if(navigator.userAgent.match("Firefox")){ elem.style.MozTransform = "rotate("+degrees+"deg)"; }else if(navigator.userAgent.match("MSIE")){ elem.style.msTransform = "rotate("+degrees+"deg)"; }else if(navigator.userAgent.match("Opera")){ elem.style.OTransform = "rotate("+degrees+"deg)"; }else { elem.style.transform = "rotate("+degrees+"deg)"; } looper = setTimeout ('rotateAnimation(\''+el+'\','+speed+')',speed); if(direction === 0){ degrees++; if(degrees > 179){ direction = 1; clearTimeout(looper); } }else { degrees--; if(degrees < 1){ direction = 0; clearTimeout(looper); } } }
Javascript Custom Scrollbar Bug
var start_mouse_y = 0; var scroll_offset = 0; function SET_SCROLL(e){ document.getElementById("online_list_scroll").draggable = true; start_mouse_y = e.clientY; } function ADJUST_SCROLL(e){ dont_pass = (412 - set_scroll_height); mouse_y = e.clientY; scroll_top = parseInt(document.getElementById("online_list_scroll").style.top); scroll_offset = (mouse_y - scroll_top) + 46; new_top = scroll_top + (mouse_y - start_mouse_y); document.getElementById("DEBUG").innerHTML = "my: "+mouse_y+"<br>new_top: "+new_top+"<br>scroll_offset: "+scroll_offset+"<br>scroll_top: "+scroll_top; if(new_top <= 0){ document.getElementById("online_list_scroll").style.top = 0+"px"; }else if(new_top >= dont_pass){ document.getElementById("online_list_scroll").style.top = dont_pass+"px"; }else{ document.getElementById("online_list_scroll").style.top = new_top+"px"; } scroll_bottom = set_scroll_height + new_top; scroll_percent = scroll_bottom / 412; online_show = (document.getElementById("online_list").scrollHeight - 412) * scroll_percent; online_show = Math.round(online_show); document.getElementById("online_list").scrollTop = online_show; } var SCROLL_ON = 0; document.onmouseup = function(){ SCROLL_ON = 0; }; document.onmousemove = function(event){ if(SCROLL_ON == 1){ADJUST_SCROLL(event);} }; javascript ^^ <div style="float: left; width: 13px; position: relative; height: 412px;"> <div id="online_list_scroll" style="width: 5px; position: absolute; top: 0px; left: 4px; border-radius: 4px; background-color: #3f3f3f; height: 15px;" onmousedown="if(SCROLL_ON == 0){ SET_SCROLL(event); SCROLL_ON = 1; }"></div> </div> html^^ i dont know why but the scroll bar scrolls at a very fast and unsteady flow rate. it works, but just jerks when scrolls up and down, jerk as in as u move one way it shoots that way quicker and quicker. Thanks for any help, worked figuring out how to do this all night.
You have a problem with local var the following code works. Not made as a general thing, just repaired the code. Here you have the code with the comments where is the common mistake. //first make sure you have defined with var the variables you need. var start_mouse_y = 0; var mouse_y = 0; var scroll_offset = 0; function SET_SCROLL(e) { document.getElementById("online_list_scroll").draggable = true; start_mouse_y = e.clientY; // you need mouse_y to be initialized with start_mouse_y mouse_y = start_mouse_y; } function ADJUST_SCROLL(e) { var set_scroll_height = 0; var dont_pass = (412 - set_scroll_height); // here you set the last mouse_y to be start_mouse_y or else it would be // a the first position of the mouse ( eg. 8 ) subtracted from the current ( eg. 50 ) // now remembering the last already added position (eg. 49) which is subtracted from // the current (eg. 50 ) it works just fine start_mouse_y = mouse_y; mouse_y = e.clientY; var scroll_top = parseInt(document.getElementById("online_list_scroll").style.top); scroll_offset = (scroll_top- mouse_y ) + 46; var new_top = scroll_top + (mouse_y- start_mouse_y); console.log("my: " + mouse_y + "<br>new_top: " + new_top + "<br>scroll_offset: " + scroll_offset + "<br>scroll_top: " + scroll_top); if(new_top <= 0) { document.getElementById("online_list_scroll").style.top = 0 + "px"; } else if(new_top >= dont_pass) { document.getElementById("online_list_scroll").style.top = dont_pass + "px"; } else { document.getElementById("online_list_scroll").style.top = new_top + "px"; } var scroll_bottom = set_scroll_height + new_top; var scroll_percent = scroll_bottom / 412; var online_show = (document.getElementById("online_list").scrollHeight - 412) * scroll_percent; online_show = Math.round(online_show); document.getElementById("online_list").scrollTop = online_show; } var SCROLL_ON = 0; document.onmouseup = function() { SCROLL_ON = 0; }; document.onmousemove = function(event) { if(SCROLL_ON == 1) {ADJUST_SCROLL(event); } }; Best regards,