Jump to content

visible invisible x,y coordinate question about a sprite


thatguy

Recommended Posts

<!DOCTYPE html><title>Parallax scrolling</title><canvas width="1190" height="238" style="border: 1px dashed black"></canvas><script src="requestAnimationFramePolyfill.js"></script><script>// The sprite objectvar spriteObject =   {  	sourceX: 0, 	sourceY: 0,	sourceWidth: 64,	sourceHeight: 64,	x: 0,	y: 0,	width: 64,	  	height: 64,	  	vx: 0,	 	vy: 0, 	 	visible: false	};// Main program//The canvas drawing surface	var canvas = document.querySelector("canvas");	var drawingSurface = canvas.getContext("2d");//An array to store the sprites	var sprites = [];//the distantBackground sprite	var distantBackground = Object.create(spriteObject);	distantBackground.sourceY = 64;	distantBackground.sourceWidth = 1190;distantBackground.sourceHeight = 238;	distantBackground.width = 1190;	distantBackground.height = 238;	distantBackground.x = 0;	distantBackground.y = 0;	sprites.push(distantBackground);//the foreground spritevar foreground = Object.create(spriteObject);	foreground.sourceY = 302;foreground.sourceWidth = 1190;	foreground.sourceHeight = 238;	foreground.width = 1190;	foreground.height = 238;	foreground.x = 0;foreground.y = 0;	sprites.push(foreground);//GameWorld and camera objects	var gameWorld =	 {	 x: 0, 	 y: 0,  width: foreground.width,  height: foreground.height	};// -----> this is the code I'm trying to use for the visibility//Hidefunction hideHandler(event){ if(spriteObject.y < canvas.height / 2) 	{  		spriteObject.visible = false;   	}};//Showfunction showHandler(event){	if(spriteObject.y > canvas.height / 2)	{  spriteObject.visible = true; }};// --------^//The camera has 2 new properties: "vx" and "previousX"var camera =	{ 	 x: 0,	 	 y: 0,	  width: canvas.width,	  height: canvas.height,	  vx: 0,  previousX: 0,    //The camera's inner scroll boundaries 	 rightInnerBoundary: function()  {  	 return this.x + (this.width * 0.75);  },  leftInnerBoundary: function()  {    return this.x + (this.width * 0.25);  }};//Center the camera over the 	gameWorldcamera.x = (gameWorld.x + gameWorld.width / 2) - camera.width / 2;	camera.y = (gameWorld.y + gameWorld.height / 2) - camera.height / 2;//Create the cat sprite and center it	var cat = Object.create(spriteObject);cat.x = (gameWorld.x + gameWorld.width / 2) - cat.width / 2;cat.y = 174;sprites.push(cat);//Load the image	var image = new Image();	image.addEventListener("load", loadHandler, false);	image.src = "parallaxScrollingTileSheet.png";canvas.addEventListener("mousedown", mousedownHandler, false);window.addEventListener("mouseup", mouseupHandler, false);function mousedownHandler(event){	var mouseX = event.pageX - canvas.offsetLeft;	var mouseY = event.pageY - canvas.offsetTop;			var left = cat.x;	var right = cat.x + cat.width;	var top = cat.y;	var bottom = cat.y + cat.height;			if(mouseX < left)	{		cat.vx -= 5;	}		if(mouseX > right)	{		cat.vx += 5;	}		if(mouseY < top)	{		cat.vy -= 5;	}		if(mouseY > bottom)	{		cat.vy += 5;	}	}function mouseupHandler(event){	cat.vx = 0;	cat.vy = 0;}//Arrow key codesfunction loadHandler(){	update();}	//Add keyboard listenersfunction update(){  //The animation loop cat.x += cat.vx;	cat.y += cat.vy; requestAnimationFrame(update, canvas); if (cat.x < 0)  {    cat.x = 0;  }  if (cat.y < 0)  {    cat.y = 0;  }  if (cat.x + cat.width > canvas.width)  {    cat.x = canvas.width - cat.width;  }  if (cat.y + cat.height > canvas.height)  {    cat.y = canvas.height - cat.height;  }  //Up  //Move the cat and keep it inside the gameWorld boundaries        //Alternative way to set the cat's world boundaries using 2 if statements  /*  if(cat.x < gameWorld.x)  {    cat.x = gameWorld.x;  }   if(cat.x + cat.width > gameWorld.x + gameWorld.width)  {    cat.x = gameWorld.x + gameWorld.width - cat.width;  }  */    //Scroll the cameracat.x = Math.max(0, Math.min(cat.x + cat.vx, gameWorld.width - cat.width));  if(cat.x < camera.leftInnerBoundary())  {    camera.x = Math.floor(cat.x - (camera.width * 0.25));  }  if(cat.x + cat.width > camera.rightInnerBoundary())  {    camera.x = Math.floor(cat.x + cat.width - (camera.width * 0.75));  }    //The camera's world boundaries  if(camera.x < gameWorld.x)  {    camera.x = gameWorld.x;  }  if(camera.x + camera.width > gameWorld.x + gameWorld.width)  {    camera.x = gameWorld.x + gameWorld.width - camera.width;  }    //Figure out the camera's velocity by subtracting its position in the  //previous frame from its position in this frame  camera.vx = camera.x - camera.previousX;    //Move the distantBackground at half the speed of the camera  distantBackground.x += camera.vx / 2;    //Capture the camera's current x position so we can use it as the  //previousX value in the next frame  camera.previousX = camera.x;  render();}function render(event){   drawingSurface.clearRect(0, 0, canvas.width, canvas.height);    drawingSurface.save();    //Move the drawing surface so that it's positioned relative to the camera  drawingSurface.translate(-camera.x, -camera.y);    //Loop through all the sprites and use their properties to display them  if(sprites.length !== 0)  {    for(var i = 0; i < sprites.length; i++)    {      var sprite = sprites[i];      drawingSurface.drawImage      (image, sprite.sourceX, sprite.sourceY, sprite.sourceWidth, sprite.sourceHeight, Math.floor(sprite.x), Math.floor(sprite.y), sprite.width, sprite.height);     }  }    drawingSurface.restore();}</script>

I'm trying to set my sprite so that when it reaches the halfway point in the top portion of the canvas it is set to invisible and visible in the lower half, but I'm not sure what to do to make this work.

Edited by thatguy
Link to comment
Share on other sites

I am surprised that it is allowing you to go without a body tag. I think this is a bad idea and suggest you go ahead and add the basic html, head, and body tags.

 

You could then explain which Polyfill file you are using and what this program is supposed to do. All I see is an empty dashed rectangle.

 

hideHandler() and showHandler() are never called.

 

Is this code directly out of "Foundation Game Design with HTML5 and JavaScript" by Rex van der Spuy?

 

https://books.google.com/books?id=QiHJr-TWmfMC&pg=PA432&lpg=PA432&dq=parallaxScrollingTileSheet.png&source=bl&ots=wmuxU3rPwW&sig=38PMUvKXZhgUJo_Y-PmnQEkRCI0&hl=en&sa=X&ei=I067VNHlIYe0ggSvzICgDQ&ved=0CCAQ6AEwAA#v=onepage&q=parallaxScrollingTileSheet.png&f=false

Link to comment
Share on other sites

I am using a requestAnimationFramePolyfill.js, file however the site will not allow me to upload it. It's basically a parallax scroller that I'm creating, for a game. (the tilesheet is just a filler.) I'm trying to write in a handler for the code that once the sprite reaches the upper half of the screen it disappears, and then reappears in the lower half, but I'm not sure how to set it up. I was hoping I could get a bit of guidance on how I should handle it. I couldn't find a tutorial regarding the material. So I came to the experts. :) haha

Any direction would be appreciated. Yes this is code from that book. I'm using Firefox to test my code, which automatically inserts the tags into the program when I run it, however I did make the changes you mentioned.

post-179970-0-57994800-1421562093_thumb.png

Edited by thatguy
Link to comment
Share on other sites

HTML 5 allows the omission of the <html>, <head> and <body> tags, but I don't recommend it. http://www.w3schools.com/html/html5_syntax.asp

 

The problem with your parallax program is not making a distinction between real coordinates and screen coordinates.

 

Each sprite should have the following properties:

image: The image you show on the screen to represent the sprite

x, y: Its world coordinates

vx, vy: Its velocity

depth: Important for parallax, a coefficient to determine how fast or slow to make it move. Depth is 1 for elements in the foreground, you can use 0.5 for the background, but any value between0 and 1 works.

width, height: For this purpose, it's the same as what you called sourceWidth and sourceHeight earlier but also represents the sprite's size in the actual world

sourceX, sourceY: This is where to start slicing on the sprite's source image

 

Here's how your logic should go in each animation frame:

1. Update velocities of all objects

2. Update positions of everything on the world based on their own velocity

3. Update the position of the camera

3.5 (optional) Get screen coordinates and use them to update object's position

4. Get screen coordinates of the objects to draw them.

 

So here's the main idea. First you get the real world coordinates

// Calculate velocities// for each sprite:sprite.vx = 5; // Arbitrary value 5 for this examplesprite.vy = 5; // Arbitrary value 5 for this example// Update positions// For each sprite:sprite.x += sprite.vx;sprite.y += sprite.vy;// Update the camera// This example has the camera always pointing at the catcamera.x = cat.x;camery.y = cat.y;

Now you can find out the screen coordinates using the following formula:

function getScreenCoordinates(sprite) {    /* We can determine the X and Y position on the screen without having to modify the sprite's actual X and Y positions */    var screenX;    var screenY;    // The following formula is used to find the screen position of the object    // 1. Get the position on the screen by subtracting the camera's position from it    screenX = sprite.x - camera.x;    screenY = sprite.y - camera.y;    // 2. Multiply by the depth coefficient for parallax    screenX *= depth;    screenY *= depth;    // 3. Make sure the camera is pointing at the center of the canvas instead of the top    // left corner by adding half the canvas width and height    screenX += canvas.width * 0.5;    screenY += canvas.height * 0.5;    // 4. The sprite is currently positioned by its top left corner, let's make it based    // on the center of the sprite:    screenX -= sprite.width * 0.5;    screenY -= sprite.height * 0.5;    return {        x : screenX,        y : screenY    }}

Now you can find out when the sprite is in the upper half of the screen and move it to the bottom again like this:

var screen = getScreenCoordinates(sprite);if(screen.y < canvas.height * 0.5) {    // This formula moves the sprite to the bottom of the screen regardless of depth    sprite.y = camera.y + canvas.height * 0.5 / sprite.depth}

Your render() function no longer needs to call the .translate() method, it just needs to call drawImage for each sprite

var screen = getScreenCoordinates(sprite);drawingSurface.drawImage(    sprite.image,    sprite.sourceX, sprite.sourceY,    sprite.width, sprite.height,    screen.x, screen.y,    sprite.width, sprite.height);
  • Like 1
Link to comment
Share on other sites

Wow! thanks a lot for all the help. You are awesome people. However I'm trying to make it so that the sprite isn't visible while in the top half of the screen. I should be able to make it do that however with the help you provided me. So thanks again! :)

Link to comment
Share on other sites

Once you already have the screen coordinate, in the part of the program that draws the sprite, just check the Y coordinate on the screen to determine whether you should draw something or not.

if(screen.y > canvas.height*0.5) { // If the position on the screen is further down than half of the canvas height    // Draw the sprite    // ...
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...