I'm working on my First 2D Game with XNA and I have a little problem.
To give a running effect to my Sprite, I scroll through a SpriteSheet with this code(running right):
if (AnimationDelay == 6)
{
if (CurrentFrameR.X < SheetSizeR.X)
{
++CurrentFrameR.X;
}
else
{
CurrentFrameR.Y++;
CurrentFrameR.X = 1;
}
if (CurrentFrameR.Y >= SheetSizeR.Y)
{
CurrentFrameR.X = 0;
CurrentFrameR.Y = 0;
}
AnimationDelay = 0;
}
else
{
AnimationDelay += 1;
}
xPosition += xDeplacement;
}
And these are the objects used :
Point FrameSizeR = new Point(29, 33);
Point SheetSizeR = new Point(5, 1);
Point CurrentFrameR = new Point(0, 0);
int AnimationDelay = 0;
I have the same Code with different SpriteSheet when the sprite is running Left.
Everything is working fine I'd say 90% of the time but the other 10% the sprite animation stays on one Frame of the SpriteSheet, on both directions(left and right) and it stays stuck until I close the program.
The thing is I can't quite figure out why since it never happens at the same moment..Sometimes after 10,15,30 seconds and sometimes even on boot!
Any idea why?
Thanks in advance and let me know if you need any other parts of the code
Your code can be rewrited this way:
ElapsedTimeFrame += (float) GameTime.ElapsedTime.TotalSeconds;
if (ElapsedTimeFrame >= TimePerFrame)
{
CurrentFrameR.X = (CurrentFrameR.X + 1) % SheetSizeR.X;
if (CurrentFrameR.X == 0)
{
CurrentFrameR.Y = (CurrentFrameR.Y + 1) % SheetSizeR.Y;
}
ElapsedTimeFrame-= TimePerFrame;
}
But you have to show more code to guess what happens...
Related
I'm working on a digital book for an Android tablet on Unity 5. I'm using this Page Curl plugin from the Asset Store.
I have 3 main planes: LeftPage, RightPage and TurningPage, and I keep an index of which page I'm looking for each one of this pages so I can manage the corresponding textures. When I click on one of the Left or Right pages, the turning page animation starts playing and when it ends, I update the index values and the corresponding textures.
It works perfect in Unity Editor and perfect with Unity Remote in the tablet, but when I run the installed apk, the turning page is always showing the textures assigned at the begining. The Left and Right pages work fine.
Printing the assigned texture name (pageFront.mainTexture.name) I get the correct texture which is equivalent to the page index value, but the turningPage keeps showing the initial (indPage = 0) texture.
All the textures are asigned on the editor on a Texture2D array.
void Update()
{
...
// If click is in one of four defined areas.
if (mouseX > 970 && mouseX < 1024 && canFlipFwd)
{
if (mouseY > 250 && mouseY < 710)
{
clickCase = 1; // Play animation 1.
changePageFwd();
}
else if (mouseY > 50 && mouseY <= 250)
{
clickCase = 2; // Play animation 2.
changePageFwd();
}
}
else
{
...
}
}
void PageFlipOver(bool pageTurned)
{
if (pageTurned)
{
// Update page index.
indRight += 2;
indPage += 2;
if (indLeft + 2 < pages.Length)
{
indLeft += 2;
leftBackground.mainTexture = pages[indLeft];
if (indLeft + 2 < pages.Length)
pageBack.mainTexture = pages[indLeft + 2];
else
pageBack.mainTexture = pages[indLeft];
}
if (!canFlipBkw)
canFlipBkw = true;
}
canFlip = true;
}
void changePageFwd()
{
if (indRight < pages.Length)
{
rightBackground.mainTexture = pages[indRight];
}
else
{
rightBackground.mainTexture = alpha;
canFlipFwd = false;
}
if (indPage < pages.Length)
pageFront.mainTexture = pages[indPage];
}
Any help is welcome, I've been stuck with this for two weaks and I can't find whats wrong.
I am working on a space shooter game using XNA and have followed multiple tutorials to create a parallax background. So far I can get it to go along one axis, either X or Y, but not both at the same time. I have a camera class that follows the player, which the player moves (instead of the 'world'), since I figured it would be easier to just move the player versus moving everything else around the player.
So far, the background doesn't keep up with the player, and it also can't comprehend both axis at the same time. I thought about a tile engine, but that wouldn't let me parallax different layers would it?
Could anyone help me understand what I need to do, or recommend a tutorial that can do both axis at the same time? I can't seem to find the answer on my own this time.
Here is the code for my background class:
class Background
{
// Textures to hold the two background images
Texture2D spaceBackground, starsParallax;
int backgroundWidth = 2048;
int backgroundHeight = 2048;
int parallaxWidth = 2048;
int parallaxHeight = 2048;
int backgroundWidthOffset;
int backgroundHeightOffset;
int parallaxWidthOffset;
int parallaxHeightOffset;
public int BackgroundWidthOffset
{
get { return backgroundWidthOffset; }
set
{
backgroundWidthOffset = value;
if (backgroundWidthOffset < 0)
{
backgroundWidthOffset += backgroundWidth;
}
if (backgroundWidthOffset > backgroundWidth)
{
backgroundWidthOffset -= backgroundWidth;
}
}
}
public int BackgroundHeightOffset
{
get { return backgroundHeightOffset; }
set
{
backgroundHeightOffset = value;
if (backgroundHeightOffset < 0)
{
backgroundHeightOffset += backgroundHeight;
}
if (backgroundHeightOffset > backgroundHeight)
{
backgroundHeightOffset -= backgroundHeight;
}
}
}
public int ParallaxWidthOffset
{
get { return parallaxWidthOffset; }
set
{
parallaxWidthOffset = value;
if (parallaxWidthOffset < 0)
{
parallaxWidthOffset += parallaxWidth;
}
if (parallaxWidthOffset > parallaxWidth)
{
parallaxWidthOffset -= parallaxWidth;
}
}
}
public int ParallaxHeightOffset
{
get { return parallaxHeightOffset; }
set
{
parallaxHeightOffset = value;
if (parallaxHeightOffset < 0)
{
parallaxHeightOffset += parallaxHeight;
}
if (parallaxHeightOffset > parallaxHeight)
{
parallaxHeightOffset -= parallaxHeight;
}
}
}
// Constructor when passed a Content Manager and two strings
public Background(ContentManager content,
string sBackground, string sParallax)
{
spaceBackground = content.Load<Texture2D>(sBackground);
backgroundWidth = spaceBackground.Width;
backgroundHeight = spaceBackground.Height;
starsParallax = content.Load<Texture2D>(sParallax);
parallaxWidth = starsParallax.Width;
parallaxHeight = starsParallax.Height;
}
public void Draw(SpriteBatch spriteBatch)
{
// Draw the background panel, offset by the player's location
spriteBatch.Draw(
spaceBackground,
new Rectangle(-1 * backgroundWidthOffset,
-1 * backgroundHeightOffset,
backgroundWidth,
backgroundHeight),
Color.White);
// If the right edge of the background panel will end
// within the bounds of the display, draw a second copy
// of the background at that location.
if (backgroundWidthOffset > backgroundWidth)
{
spriteBatch.Draw(
spaceBackground,
new Rectangle(
(-1 * backgroundWidthOffset) + backgroundWidth, 0,
backgroundWidth, backgroundHeight),
Color.White);
}
else //(backgroundHeightOffset > backgroundHeight - viewportHeight)
{
spriteBatch.Draw(
spaceBackground,
new Rectangle(
0, (-1 * backgroundHeightOffset) + backgroundHeight,
backgroundHeight, backgroundHeight),
Color.White);
}
// Draw the parallax star field
spriteBatch.Draw(
starsParallax,
new Rectangle(-1 * parallaxWidthOffset,
0, parallaxWidth,
parallaxHeight),
Color.SlateGray);
// if the player is past the point where the star
// field will end on the active screen we need
// to draw a second copy of it to cover the
// remaining screen area.
if (parallaxWidthOffset > parallaxWidth)
{
spriteBatch.Draw(
starsParallax,
new Rectangle(
(-1 * parallaxWidthOffset) + parallaxWidth,
0,
parallaxWidth,
parallaxHeight),
Color.White);
}
}
}
The main game then has ties to move the backgrounds, along with the player.
background.BackgroundWidthOffset -= 2;
background.ParallaxWidthOffset -= 1;
Visually, the background is sort of jumpy, and seems to randomly skip or overlap background tiles.
I've used this method in the past with great results:
http://www.david-gouveia.com/scrolling-textures-with-zoom-and-rotation/
It uses a shader to accomplish the effect, resulting in a fast implementation.
There is a complete example here.
Alright, so I am pretty new to XNA programming and I am trying to code a platformer. I have implemented pixel-perfect collision but it seems to fail for no apparent reason sometimes (I couldn't figure out a pattern) and the hero sprite goes through platforms.
static bool IntersectsPixel(Rectangle rect1, Color[] data1, Rectangle rect2, Color[] data2)
{
int top = Math.Max (rect1.Top, rect2.Top);
int bottom = Math.Min(rect1.Bottom, rect2.Bottom);
int left = Math.Max (rect1.Left,rect2.Left);
int right = Math.Min(rect1.Right,rect2.Right);
//Top
for(int y = top; y<bottom;y++)
for (int x = left; x < right; x++)
{
Color color1 = data1[x-rect1.Left + (y-rect1.Top) * rect1.Width];
Color color2 = data2[x - rect2.Left + (y - rect2.Top) * rect2.Width];
if (color1.A != 0 && color2.A != 0)
return true;
}
return false;
}
And here's the Update Method
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
foreach(Platform platform in platformList)
{
Rectangle check = new Rectangle(hero.GetRectangle().X - 300, hero.GetRectangle().Y - 300, 600, 600);
if(check.Intersects(platform.rectangle))
if (IntersectsPixel(hero.GetRectangle(), hero.textureData, platform.rectangle, platform.platformTextureData))
{
int direction = CheckDirection(platform,hero);
if (hero.hasJumped == true && direction == 3 && hero.velocity.Y <= 0 )
{
hero.velocity.Y = 0f;
hero.SetPosition(new Vector2((float)hero.GetPosition().X, (float)platform.rectangle.Bottom));
break;
}
else
if (direction == 4 && hero.velocity.X >= 0)
{
hero.velocity.X = 1;
hero.SetPosition(new Vector2((float)platform.rectangle.Left - (float)hero.GetRectangle().Width, (float)hero.GetPosition().Y));
break;
}
else
if (direction == 2 && hero.velocity.X <= 0)
{
hero.velocity.X = -1;
hero.SetPosition(new Vector2((float)platform.rectangle.Right - 1, (float)hero.GetPosition().Y));
break;
}
else
if (direction == 1 && hero.velocity.Y >= 0)
{
hero.velocity.Y = 0;
hero.hasJumped = false;
hero.SetPosition(new Vector2((float)hero.GetRectangle().X, (float)platform.rectangle.Y - (float)hero.GetRectangle().Height + 1));
hero.SetRectangle(new Rectangle((int)hero.GetPosition().X, (int)hero.GetPosition().Y, (int)hero.GetSize().X, (int)hero.GetSize().Y));
break;
}
}
}
hero.Update(gameTime);
camera.Update(gameTime, hero, screenBounds);
base.Update(gameTime);
}
And here's the direction check:
private int CheckDirection(Platform platform,Hero hero)
{
int distance = Math.Abs(platform.rectangle.Top - hero.GetRectangle().Bottom);
int direction = 1; //Top
if (distance > Math.Abs(platform.rectangle.Right - hero.GetRectangle().Left))
{
distance = Math.Abs(platform.rectangle.Right - hero.GetRectangle().Left);
direction = 2;
}
if (distance > Math.Abs(platform.rectangle.Bottom - hero.GetRectangle().Top))
{
distance = Math.Abs(platform.rectangle.Bottom - hero.GetRectangle().Top);
direction = 3;
}
if (distance > Math.Abs(platform.rectangle.Left - hero.GetRectangle().Right))
{
direction = 4;
distance = Math.Abs(platform.rectangle.Left - hero.GetRectangle().Right);
}
return direction;
}
Those are all my functions related to collision detection. If you happen to have any ideea of what might cause this, please let me know.
Thank you very much !
One thing I see that might be a possible reason is that right in the beginning where you build a box around both objects:
int top = Math.Max (rect1.Top, rect2.Top);
int bottom = Math.Min(rect1.Bottom, rect2.Bottom);
int left = Math.Max (rect1.Left,rect2.Left);
int right = Math.Min(rect1.Right,rect2.Right);
Unless you flipped it, typically XNA's Y grows positive as you go down (not up). This means you would actually want to take the Max of Bottom, and the Min of Top, since Top will always be less than Bottom. It looks like you already knew that though by the look of this line:
for(int y = top; y<bottom;y++)
I'll keep looking (it's difficult to test without the actual project). Another recommendation I'd give you is to do some debug drawing. Draw where the intersection functions thinks that pixels are touching or not touching.
Because of lag, Your character could be moving more than the blocks height per frame, so the collision may think it is in between blocks, and cause it to fly through.
https://gamedev.stackexchange.com/questions/30458/platformer-starter-kit-collision-issues
Check that out, It solved the problem for me.
Either slowing down movement, or clamping the change in position to the size of a block should solve this.
i'm making my first game on XNA for my class. I'm trying to make the monsters move left and right automatically. I have total 4 monsters for now. I'm trying to get them move left then right within the screen.
//Monster movements
for (int i = 0; i < numOfMonster; i++)
{
if (destinationMonster[i].X >= screenWidth - 60)
{
while(destinationMonster[i].X != -10)
moveLeft = true;
}
else
{
moveRight = true;
}
if (moveLeft)
{
int temp = destinationMonster[i].X;
temp = destinationMonster[i].X - monsterSpeed;
//This prevents the object passing the screen boundary
if (!(temp < -10))
{
destinationMonster[i].X = temp;
}
moveLeft = false;
}
if (moveRight)
{
int temp = destinationMonster[i].X;
temp = destinationMonster[i].X + monsterSpeed;
//This prevents the object passing the screen boundary
if (!(temp > screenWidth - 50))
{
destinationMonster[i].X = temp;
}
moveRight = false;
}
}
Your first problem is your while statement, once you enter it you are not going to exit because you are not changing your X value. If it were me I would have a bool array variable corresponding to each of your monsters. I would also change your conditional to trigger the change of the boolean value once the monster has reached the extents at either end. Something like this.
if (destinationMonster[i].X >= screenWidth - 60)
{
moveRight[i] = false ;
}
else if (destinationMonster[i].X <= -10)
{
moveRight[i] = true ;
}
I am brand new to XNA and C# (I started 2 days ago, so please forgive the sloppy programming), and I have run into a problem with a simple game I am making. I can't seem to find the solution in any of the online tutorials. I am trying to utilize rectangle collision detection but I cannot get it to work properly. The character falls completely through the floor and it seems there is no collision ever registering in any place. I cannot find my logic error here. Below I posted a bit of my code that pertains to the collision detection. I can post more if necessary. Thank you for the help in advance!
Level.cs
//The method below is called in the initial LoadContent method in Game1.cs. 'LoadBlocks()' is supposed to read in a text file and setup the level's "blocks" (the floor or platforms in the game).
public void LoadBlocks(int level){
if (level == 0)
{
fileName = "filepath";
}
System.IO.StreamReader file = new System.IO.StreamReader(fileName);
while ((line = file.ReadLine()) != null)
{
for (int i = 0; i < 35; i++)
{
rectBlock = new Rectangle((int)positionBlock.X, (int)positionBlock.Y, width / 30, height / 30);
if (line.Substring(i, 1).Equals(","))
{
positionBlock.X += (width / 100) * 24;
}
if (line.Substring(i, 1).Equals("#"))
{ //block -> (bool isPassable, Texture2D texture, Rectangle rectangle, Vector2 position)
block = new Block(false, textureBlock, rectBlock, positionBlock);
blocks.Add(block);
positionBlock.X += (width / 100) * 24;
}
}
positionBlock.Y += (height / 100) * 8;
positionBlock.X = 0;
}
}
//This method below updates the character 'bob' position and velocity.
public void UpdatePlayer()
{
bob.position += bob.velocity;
bob.rectangle = new Rectangle((int)bob.position.X, (int)bob.position.Y, width / 30, height / 30);
float i = 1;
bob.velocity.Y += 0.15f * i;
foreach (Block block in blocks)
{
if (bob.isOnTopOf(bob.rectangle, block.rectangle))
{
bob.velocity.Y = 0f;
bob.hasJumped = false;
}
}
}
Character.cs
//Here is my whole Character class for 'bob'
public class Character
{
int height = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
int width = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
int health;
String name;
bool gender;
Texture2D texture;
public Vector2 position;
public Vector2 velocity;
public bool hasJumped;
public Rectangle rectangle;
public Character(int newHealth, String newName, bool newGender, Texture2D newTexture, Vector2 newPosition)
{
health = newHealth;
gender = newGender;
name = newName;
texture = newTexture;
position = newPosition;
hasJumped = true;
rectangle = new Rectangle(0,0, width/30,height/30);
velocity = Vector2.Zero;
}
public bool isOnTopOf(Rectangle r1, Rectangle r2)
{
const int penetrationMargin = 5;
return (r1.Bottom >= r2.Top - penetrationMargin &&
r1.Bottom <= r2.Top &&
r1.Right >= r2.Left + 5 &&
r1.Left <= r2.Right - 5);
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, rectangle,null, Color.White,0,position,SpriteEffects.None,0);
}
}
Sorry if this is too much posted code or is confusing, but any help is greatly appreciated! Thanks!
Your test condition for intersection appears to be incorrect, at least. There might be other problems with the code (there are several just giving a quick look at it), but let's focus on this:
r1.Bottom >= r2.Top - penetrationMargin &&
r1.Bottom <= r2.Top &&
r1.Right >= r2.Left + 5 &&
r1.Left <= r2.Right - 5;
First, don't code what exists in the library for you. Xna Rectangles have an Intersects method, so scrap that code and use it instead.
We'll look at the condition anyway:
r1's Bottom is below r2's Top minus a margin AND
r1's Bottom is above r2's Top AND (...)
This is already impossible. r1.Bottom cannot be both below and above r2.Top.
Further, even if all the comparisons were correct, you are using AND everywhere (&&), which means that the condition is only true if all 4 of them are true. Basically, you are not testing for intersection, you are testing for containement, i.e. you are testing that r1 is entirely within r2. An intersection test would join the conditions using OR (||) not AND (&&).
But again, although you might want to code it yourself for educative purposes, the best solution from an engineering perspective is to use what the library provides, here Rectangle.Intersects.
I figured it out, but I'm not sure why this actually works. Something was wrong with my draw method. I originally had:
spriteBatch.Draw(texture, rectangle, null, Color.White, 0, position, SpriteEffects.None, 0);
as my method but then I changed this to
spriteBatch.Draw(texture, rectangle, Color.White);
and now everything works fine.