Get the latest Education e-news
 

Go Back   Game Career Guide Forums > Programming
Forum Home Register Members List Mark Forums Read

Reply
 
Thread Tools Display Modes
Old 07-07-2008, 05:39 PM   #1
OSD
Member

Activity Longevity
0/20 17/20
Today Posts
0/11 sssssss55
Default XNA - Scrolling background + stop with final frame

Hi, I was wondering if anyone here knows how I can go about making a scrolling 2D background load a special background piece in XNA for say a boss and then resume after the boss die?

The layout I have right now is

Bg1 scrolls to Bg2 to Bg1 to Bg2 to etc...

After a certain point, I want to go from Bg2 to BossBg, pause on BossBg (and defeat the boss) then resume to Bg1.

I'm going nuts trying to figure this out as I'm REALLY new to XNA (I just got it yesterday). I managed to figure out how to make stuff collide, shoot bullets and make a player controlled object. But the other important stuff is hard for me to figure out. There is unfortunately no tutorial that has the stop option in it as all the ones I've found are non-stop version.

Thanks in advance.
OSD is offline   Reply With Quote
Old 07-07-2008, 11:39 PM   #2
Claxon
Senior Member

Activity Longevity
0/20 18/20
Today Posts
0/11 ssssss345
Location: London
Default

How is your scrolling background being handled? Unless it's some high level function call that you don't have control over (eg. if all you do is call LoadScrollingBackground("res/bg0.png")), I'm not sure how you would find it difficult as it should be fairly obvious where to make the change.

If you're doing it manually just edit the code where it changes the background, to check if your boss is active and if so, load the special boss background, else continue as normal.

Last edited by Claxon : 07-08-2008 at 10:31 AM.
Claxon is offline   Reply With Quote
Old 07-08-2008, 07:59 AM   #3
OSD
Member

Activity Longevity
0/20 17/20
Today Posts
0/11 sssssss55
Default

thanks for pointing the LoadScrollingBackground, I will cross that off my list to mess around with.
Here's the code I'm currently working on


public void Draw( SpriteBatch batch )
{
screenlock = 0;
// Draw the texture, if it is still onscreen.
if (screenpos.Y < screenheight || screenlock <=1 )
{
batch.Draw( mytexture, screenpos, null,
Color.White, 0, origin, 1, SpriteEffects.None, 0f );
screenlock += 1;
}
}
OSD is offline   Reply With Quote
Old 07-08-2008, 10:30 AM   #4
Claxon
Senior Member

Activity Longevity
0/20 18/20
Today Posts
0/11 ssssss345
Location: London
Default

Quote:
Originally Posted by OSD View Post
thanks for pointing the LoadScrollingBackground, I will cross that off my list to mess around with.
That was just an example saying that if XNA manages the scrolling for you, it could be more complicated to override. But anyway, let's look at your code:
Code:
        public void Draw( SpriteBatch batch )
        {
            screenlock = 0;
            // Draw the texture, if it is still onscreen.
            if (screenpos.Y < screenheight || screenlock <=1 )
            {
                batch.Draw( mytexture, screenpos, null,
                     Color.White, 0, origin, 1, SpriteEffects.None, 0f );
                screenlock += 1;
            }
        }
How is the screenlock value used elsewhere? Would I be right in guessing that when it reaches 1, the 'mytexture' image is replaced with another background? Either way the check is rather redundant here, since if you set it to 0 at the start of the method, it will always be less or equal to 1 when the actual drawing takes place. Thinking about it, that code isn't very useful to us, since all it is showing is that batch.Draw() will be called every frame. If you want help with the scrolling, you'd be best showing us that part of the code (where screenpos changes).

Edit:
I'll just add a little suggestion for how you could solve this, to stop constant back and forth requests for code. I suggest you have a boolean value named something like bActivateBoss. At some point in the game it is set to true, be that when you reach a certain score, or after a set period of time (at this point you can have your boss enter if you like or wait until it's background has fully appeared). Next what you should do is add a check where the code changes texture 1 for texture 2. Here's a little pseudo code to demonstrate:

Code:
public void changeBackground(){

   if(BossEnabled){
      mytexture = background3; // Set to the 3rd (Boss) background
      CurrentBackground = 2;
   }else{
      if(CurrentBackground == 0){
         mytexture = background1; // Set to the 2nd background
         CurrentBackground = 1;
      }else{
         mytexture = background0; // Set to the 1st background
         CurrentBackground = 0;
      }
   }
}
You could also check the same boolean where the background scrolls. If it is true & the boss background is in the desired location on the screen, then don't scroll. Otherwise scroll as usual.

Last edited by Claxon : 07-08-2008 at 10:47 AM.
Claxon is offline   Reply With Quote
Old 07-08-2008, 10:53 AM   #5
OSD
Member

Activity Longevity
0/20 17/20
Today Posts
0/11 sssssss55
Default

Unnecessarily complicated = time better spent on more functional + practical stuff


After your post, I realized the rest of the code was really not flexible that even documentation still had my head spinning. So I went to another set of code and found another scrolling method that more newbie friendly. Here are the code.



public void Draw(SpriteBatch theSpriteBatch)
{
theSpriteBatch.Draw(mSpriteTexture, Position,
new Rectangle(0, 0, mSpriteTexture.Width, mSpriteTexture.Height),Color.White,
0.0f, Vector2.Zero, Scale, SpriteEffects.None, 0);
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);

// TODO: use this.Content to load your game content here


mBackgroundOne.LoadContent(this.Content, "Background01");
mBackgroundOne.Position = new Vector2(0, 0);

mBackgroundTwo.LoadContent(this.Content, "Background02");
mBackgroundTwo.Position = new Vector2(mBackgroundOne.Position.X + mBackgroundOne.Size.Width, 0);



}

protected override void Update(GameTime gameTime)


if (mBackgroundOne.Position.X < -mBackgroundOne.Size.Width)
{
mBackgroundOne.Position.X = mBackgroundTwo.Position.X + mBackgroundTwo.Size.Width;
screenlock += 5;
}

if (mBackgroundTwo.Position.X < -mBackgroundTwo.Size.Width)
{
mBackgroundTwo.Position.X = mBackgroundOne.Position.X + mBackgroundOne.Size.Width;
}
mBackgroundTwo.Size.Width;
}

Vector2 aDirection = new Vector2(-5, 0);
Vector2 aSpeed = new Vector2(160, 0);
if (screenlock < 10)
{
mBackgroundOne.Position += aDirection * aSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
mBackgroundTwo.Position += aDirection * aSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
}

protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue );

// TODO: Add your drawing code here
spriteBatch.Begin();

mBackgroundOne.Draw(this.spriteBatch);
mBackgroundTwo.Draw(this.spriteBatch);

spriteBatch.End();

base.Draw(gameTime);
}



I think I got all the relevant bits here...

I'm currently trying to add a mBackgroundThree to appear when the boss appears, pause the mbackgroundThree and then resume to mBackgroundOne => mBackgroundTwo sequence. I'll continue to mess around with the code and see if I can get it working the way I want. I managed to make a loop go from mBackgroundOne all the way to mBackgroundTen and back but I still can't figure out how to load a background not part of the loop and then resume the loop.
OSD is offline   Reply With Quote
Old 07-08-2008, 01:29 PM   #6
Claxon
Senior Member

Activity Longevity
0/20 18/20
Today Posts
0/11 ssssss345
Location: London
Default

Well I'm still not sure what the purpose of the screenlock variable is, but here's a little code you might want to try. It's possibly got some bugs in since I'm doing this in my head, but it's one method you could try:

Code:
// Define boss enabled somewhere
bool bBossEnabled = false;

private void enableBoss(){
	bBossEnabled = true;
	
	// set initial position
	if(mBackgroundOne.Position.X < mBackgroundTwo.Position.X)
		mBackgroundBoss.Position.X = mBackgroundTwo.Position.X +  mBackgroundTwo.Size.Width;
	else
		mBackgroundBoss.Position.X = mBackgroundOne.Position.X +  mBackgroundOne.Size.Width;
}
 
 //------------------------------------------

public void Draw(SpriteBatch theSpriteBatch)
{

	theSpriteBatch.Draw(mSpriteTexture, Position, 
		new Rectangle(0, 0, mSpriteTexture.Width, mSpriteTexture.Height),Color.White, 
		0.0f, Vector2.Zero, Scale, SpriteEffects.None, 0);
}
protected override void LoadContent()
{

	// Create a new SpriteBatch, which can be used to draw textures.
	spriteBatch = new SpriteBatch(GraphicsDevice);

	// TODO: use this.Content to load your game content here
	mBackgroundOne.LoadContent(this.Content, "Background01");
	mBackgroundOne.Position = new Vector2(0, 0);

	mBackgroundTwo.LoadContent(this.Content, "Background02");
	mBackgroundTwo.Position = new Vector2(mBackgroundOne.Position.X + mBackgroundOne.Size.Width, 0);
	
	// Create a boss background
	mBackgroundBoss.LoadContent(this.Content, "BackgroundBoss");
	mBackgroundBoss.Position = new Vector2(mBackgroundOne.Position.X + mBackgroundOne.Size.Width, 0);

}


protected override void Update(GameTime gameTime)
{
		if (mBackgroundOne.Position.X < -mBackgroundOne.Size.Width)
		{
			mBackgroundOne.Position.X = mBackgroundTwo.Position.X + mBackgroundTwo.Size.Width;
			screenlock += 5;
		}

		if (mBackgroundTwo.Position.X < -mBackgroundTwo.Size.Width)
		{
			mBackgroundTwo.Position.X = mBackgroundOne.Position.X + mBackgroundOne.Size.Width;
		}

		Vector2 aDirection = new Vector2(-5, 0);
		Vector2 aSpeed = new Vector2(160, 0);
		if (screenlock < 10)
		{

				
			if((bBossEnabled && mBackgroundBoss.Position.X > 0) 
				|| (!bBossEnabled && mBackgroundBoss.Position.X < screenWidth) ){
				// Boss background is being displayed so scroll to it's next position
				mBackgroundBoss.Position += aDirection * aSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
			}
			
			if(bBossEnabled && mBackgroundBoss.Position.X <=0){
				if(mBackgroundBoss.Position.X < screenWidth)
			}
			mBackgroundOne.Position += aDirection * aSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
			mBackgroundTwo.Position += aDirection * aSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
		}
	
}
protected override void Draw(GameTime gameTime)
{
	graphics.GraphicsDevice.Clear(Color.CornflowerBlue  );

	// TODO: Add your drawing code here
	spriteBatch.Begin();

	if(mBackgroundBoss.Position.X  == mBackgroundOne.Position.X)
		mBackgroundOne.Draw(this.spriteBatch);// BackgroundBoss drawn over background 1
	
	if(mBackgroundBoss.Position.X  == mBackgroundTwo.Position.X)
		mBackgroundTwo.Draw(this.spriteBatch);
	
	if(mBackgroundBoss.Position.X < screenWidth)
		mBackgroundBoss.Draw(this.spriteBatch); 

	spriteBatch.End();

	base.Draw(gameTime);
}
Claxon is offline   Reply With Quote
Old 07-08-2008, 02:17 PM   #7
OSD
Member

Activity Longevity
0/20 17/20
Today Posts
0/11 sssssss55
Default

Thanks for the detailed reply! I can actually understand what you are trying to do! xD I will dissect and play around with the code, it will probably take a day or two (hopefully) to get it working, will let you know what happens
OSD is offline   Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Powered by vBulletin® Version 3.6.9
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
All times are GMT -8. The time now is 02:35 AM.






UBM Tech