Parallax Background resizing - c#

I'm attempting my first 2D updown scroller really, and i can't seem to get the background size to fully work. for whatever reason it stays small and it is of no help.
I think in the beginning of the parallax scrolling class i was told to initialize variables and I know which one I have to change.
public Texture2D picture;
public Vector2 position = Vector2.Zero;
public Vector2 offset = Vector2.Zero;
public float depth = 0.0f;
public float moveRate = 0.0f;
public Vector2 pictureSize = Vector2.Zero;
public Color color = Color.White;
I believe i must change pictureSize in order to make it bigger as the current sizing i get this!
The final question i have is, How can I remove the whitespace from the ship image?
Thanks!
If any more code is needed please tell me, the reason I did not put it there, is due to the length.
EDIT*:
Here is the code for the rendering of the actual ship
public void Render(SpriteBatch batch)
{
batch.Begin();
batch.Draw(shipSprite, position, null, Color.White, 0.0f, spriteOrigin, 1.0f,
SpriteEffects.None, 0.0f);
batch.End();
}
The whitespace seems to be provided by XNA as I've cleared it several times using photoshop.
Because i can't directly upload to the site I have put it here: http://www.justbeamit.com/nk95n
And for the background rendering its
public void Draw()
{
layerList.Sort(CompareDepth);
batch.Begin();
for (int i = 0; i < layerList.Count; i++)
{
if (!moveLeftRight)
{
if (layerList[i].position.Y < windowSize.Y)
{
batch.Draw(layerList[i].picture, new Vector2(0.0f,
layerList[i].position.Y), layerList[i].color);
}
if (layerList[i].position.Y > 0.0f)
batch.Draw(layerList[i].picture, new Vector2(0.0f,
layerList[i].position.Y - layerList[i].pictureSize.Y),
layerList[i].color);
else
batch.Draw(layerList[i].picture, new Vector2(0.0f,
layerList[i].position.Y + layerList[i].pictureSize.Y),
layerList[i].color);
}
else
{
if (layerList[i].position.X < windowSize.X)
{
batch.Draw(layerList[i].picture, new Vector2(layerList[i].position.X,
0.0f), layerList[i].color);
}
if (layerList[i].position.X > 0.0f)
batch.Draw(layerList[i].picture, new Vector2(layerList[i].position.X -
layerList[i].pictureSize.X, 0.0f), layerList[i].color);
else
batch.Draw(layerList[i].picture, new Vector2(layerList[i].position.X +
layerList[i].pictureSize.X, 0.0f), layerList[i].color);
}
}
batch.End();
}
^
This is not my code but rather from a book I'm reading on how to do XNA(first attempt at C# to :/)

Without all the relevant code and details it is a bit hard to tell the problem, But I assume your scrolling code has a spriteBatch.Draw() call simlar to this:
spriteBatch.Draw(Texture, Destination, Source, Color.White);
TheDestination is probably equal too new Rectangle(0,0,pictureSize.X,pictureSize.Y), I'm assume with no code shown that the pictureSize is the size of the picture (No really!), with the spritebatch Destination parameter, you can "stretch" your image to your viewport.
With this your PictureSize should be the size of your viewport
pictureSize = new Vector2(graphics.PreferredBackBufferWidth,graphics.PreferredBackBufferHeight);
You can also use the Scale parameter of the SpiteBatch to enlarge it (However it will get blurred) or just create a bigger image for your needs.
Now for the spaceship having a white background, is XNA doing this or is the image white? I assume the latter, you will need a photo editing tool such as GIMP to remove the white background of the image.

How can I remove the whitespace from the ship image?
You could try making white transparent, using the Bitmap.MakeTransparent method. Something like this might work:
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
Bitmap test = new Bitmap("C:\Myimage.jpg");
test.MakeTransparent(Color.White);

Related

C# XNA - Start draw from bottom-center

Normally XNA start drawing sprite from top-left, but I would like to start draw object from bottom-center, how this could be done?
You want to specify a different origin in your SpriteBatch.Draw calls. The default is 0,0 (top-left). Note that the origin is relative to the sprite, not the screen.
So if your sprite is 64x64, you want to use an origin of 32x64 for bottom center.
e.g. using this override (MSDN)
spriteBatch.Draw (
texture,
position,
sourceRectangle,
color,
rotation,
new Vector2(32, 64), // origin
scale,
effects,
layerDepth
)
You can calculate these on the fly if you wish. e.g if you're using the full texture you could specify it as new Vector2(texture.Center.X, texture.Height). Or alternatively you could base it on the sourceRectangle if you're using a sprite sheet.
You need to specify a bunch of other arguments to use these Draw overrides but you can just pass in the defaults. The defaults are:
sourceRectangle: null = full texture
color: Color.White = default color (sprite colors will be used)
rotation: 0f = no rotation
scale: 1f = default scale
efects: SpriteEffects.None = no flipping
layerDepth: 0 = default layer
Lets say you are drawing an image WidthxHeight on position XxY.
spriteBatch.Draw(texture, position, Color.White);
First let's set the bottom of the image to those coordinates by subtracting images height from position's Y coordinate (subtracting because in XNA the Y-axis is inverted, not like in your math class)
spriteBatch.Draw(texture, position + new Vector2(0, -texture.Height), Color.White);
Second, let's set the image to the left by subtracting half of the image's width from position's X coordinate.
spriteBatch.Draw(texture, position + new Vector2(-texture.Width/2, -texture.Height), Color.White);
And there you have it.
Edit: Another thought: you can create new variable called DrawPosition and use that variable when needed, instead of always substracting. That would look something like this:
private Texture2D texture;
public Vector2 position;
public Vector2 DrawPosition
{ get { return position + new Vector2(-texture.Width/2, -texture.Height); } }
public void Draw(SpriteBatch spriteBatch)
{ spriteBatch.Draw(texture, DrawPosition, Color.White); }
Or, if this new variable doesn't make sense to you, create a function that will return the DrawPosition()
public Vector2 DrawPosition()
{ return position + new Vector2(-texture.Width/2, -texture.Height); }

C# Draw method does not draw to screen after adding transformation matrix to spritebatch

I have been trying my hand at making a simple 2D game in Monogame. I found a tutorial online for a Camera class to be used with scrolling the screen towards where my character is moving.
This is the camera class:
public class Camera
{
Vector2 position;
Matrix viewMatrix;
public Matrix ViewMatrix
{
get { return viewMatrix; }
}
public int ScreenWidth
{
get { return GraphicsDeviceManager.DefaultBackBufferWidth; }
}
public int ScreenHeight
{
get { return GraphicsDeviceManager.DefaultBackBufferHeight; }
}
public void Update(Vector2 playerPosition)
{
position.X = playerPosition.X - (ScreenWidth / 2);
position.Y = playerPosition.Y - (ScreenHeight / 2);
if(position.X <0)
{
position.X = 0;
}
if(position.Y <0)
{
position.Y = 0;
}
viewMatrix = Matrix.CreateTranslation(new Vector3(-position, 0));
}
And in the Game1.cs I use the following Draw method:
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend,
null, null, null, null, Camera.ViewMatrix);
ScreenManager.Instance.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
When I use spriteBatch.Begin() without any arguments, the Titlescreen and mainmenu load just fine followed by the tilemap and the player.
However when I add the Camera.Viewmatrix argument the screen stays Black. It does not seem to draw anything past the Graphicsdevice.Clear(Color.Black).
I would appreciate any and all input. And please let me know if you need to see more of my code.
UPDATE: The camera and matrix are fine I believe. The problem has to do with the fact that I have many classes, for example Screenmanager, Image, Tile, Layer, TitleScreen,... that are all using an Update and most of them a Draw method.
The actual drawing is being handled as shown above in the game1.cs by a singleton instance of the ScreenManager class using its draw method.
I suspect that it is trying to apply the matrix to the fadescreen/titlescreen in the start and that is causing errors such as not progressing past the black background. Perhaps because the camera position has no player position?
I have tried using a separate spritebatch.Begin() for the Camera and Player draw methods but this of course results in the error that I'm calling a new spriteBatch.Begin before the other one has ended.
I feel like this is solvable but I might have been staring at it too long to see the solution now.
I don't want to turn this into a 'look at my entire project and fix it for me' but if anyone recognizes this situation and has input, or even has run into the same thing and fixed it, I would very much appreciate your feedback.
Also, should anyone require more code to look at, again. feel free to let me know.
Try feeding it an Identity matrix. That should work and it would confirm that something must be wrong with your matrix. It's been a while since I did this, but it think this worked.
public void Update(Vector2 playerPosition)
{
if(position.X <0)
{
position.X = 0;
}
if(position.Y <0)
{
position.Y = 0;
}
viewMatrix = Matrix.CreateTranslation(new Vector3(-playerPosition.X, -playerPosition.Y, 0.0f));
}

Make a point follow a rotating sprite

I have a rectangle with a square at its bottom. I also have code that makes the rectangle rotate around its origin which is at the top of this rectangle. Im trying to make the square at the bottom to always stay at the end of this rectangle even when its rotated. Hers a picture to illustrate my problem:
I see now that it wasn't such a good idea to make the square at the bottom white. So when i rotate the rectangle upwards to the right or upwards to the left, I want the square to keep staying at the end of this rectangle. Maybe there is a simple solution, but my knowledge isn't as good as it should be on this subject. Hope someone could point me in the right direction.
Something like this aught to get you there.
float pendulumAngle;
Vector2 origin;
Vector2 squareTLcorner;//top left corner of square
Vector2 squareOffset;
void Reset()
{
pendulumAngle = 0;
origin = new Vector2(?.?f, ?.?f);// set to whatever you need
squareTLcorner = new Vector2(?.?f, ?.?f); // set to whatever you need
squareOffset = squareTLcorner - origin;
}
void UpdatePendulum(float angleMovedSinceLastFrame)
{
pendulumAngle += angleMovedSinceLastFrame;
}
void UpdateSquarePosition()
{
squareTLcorner = Vector2.Transform(squareOffset, Matrix.CreateRotationZ(pendulumAngle) + origin;
}
void DrawSquare()
{
spriteBatch.Draw(sqTex,squareTLcorner, , ,pendulumAngle, , , , );// overload 6 of 7
}
The easiest way is passing a transformation matrix to the sprite batch.
Rectangle Black = new Rectangle(0,0, 20, 100);
Rectangle White = new Rectangle( Black.Left, Black.Bottom, Black.Width, Black.width);
Vector2 Pivot= new Vector(100,100);
vector2 Origin = new Vector2( 10,10);
Matrix transform = Matrix.CreateTranslation(-Origin.X, -Origin.Y)
* Matrix.CreateRotationZ(angle)
* Matrix.CreateTranslation(Pivot);
SpriteBatch.begin(...., transform)
SpriteBatch.Draw( Texture, Black, Color);
SpriteBatch.Draw( Texture, White, Color);
SpriteBatch.end();
Basically you are working in a different space that is rotated ans translated as you need, realize that Black rectangle location is (0,0).
Code it's not tested but should work as expected. ;)

XNA 3.1 - Not sure how to add Rectangle in enemy Class

Trying to make a 2D side scroller here
I am quite new to programming. I've tried to follow guides and tutorials with not much luck. I am aware that this is quite simple but i just cannot figure it out.
I have multiple classes for all the different characters in the game.
I have a rectangle for the main sprite character which the player will control.
But the problem is that I want to add rectangles around enemy sprites so that i can add collision into the game.
public class enemyRocks
{
public Texture2D texture;
public Vector2 position;
public Vector2 velocity;
public Rectangle rockRectangle;
public bool isVisible = true;
Random random = new Random();
int randX;
public enemyRocks(Texture2D newTexture, Vector2 newPosition)
{
texture = newTexture;
position = newPosition;
randX = -5;
velocity = new Vector2(randX, 0);
}
public void Update(GraphicsDevice graphics)
{
position += velocity;
if (position.X < 0 - texture.Width)
isVisible = false;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, position, Color.White);
}
}
I have genuinely tried many methods but it just doesn't seem to work.
Everything i've done so far gave me a "nullreferenceexception was unhandled" error.
I will take any criticism needed to improve.
Thank you for your help.
you need boundingBox property on your sprites
new Rectangle((int)Position.X,(int)Position.Y,texture.Width, texture.Height);
then to check collision
if (Sprite1.BoundingBox.Intersects(Sprite2.BoundingBox))
but make sure that you load your texture before any function that uses texture. i guess your error happened on update function where you try to get width of texture that is not loaded.

Drawing lines in C# with XNA

There is a similar question System.Drawing in XNA, but this may be a clearer question and thus one easier to answer.
We're trying to draw lines on the screen in C#. We are using the XNA library. This code
void DrawLine2 (Vector2 point1, Vector2 point2)
{
System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.Green, 1);
Point p1 = new Point((int)point1.X, (int)point1.Y), p2 = new Point((int)point2.X, (int) point2.Y);
Graphics.DrawLine (pen, p1, p2);
}
gives the compile-time error that Graphics does not exist.
Perhaps I should be using something in XNA to draw the line rather than in System -- but if so I am not sure what. XNA has a Spritebatch drawing function, but AFAIK you give it a sprite and a center (and a rotation), rather than 2 points.
Try this handy extensions method,
public static void DrawLine(this SpriteBatch spriteBatch, Vector2 begin, Vector2 end, Color color, int width = 1)
{
Rectangle r = new Rectangle((int)begin.X, (int)begin.Y, (int)(end - begin).Length()+width, width);
Vector2 v = Vector2.Normalize(begin - end);
float angle = (float)Math.Acos(Vector2.Dot(v, -Vector2.UnitX));
if (begin.Y > end.Y) angle = MathHelper.TwoPi - angle;
spriteBatch.Draw(1X1 PIXEL TEXTURE, r, null, color, angle, Vector2.Zero, SpriteEffects.None, 0);
}
Spritebatch can be used to draw a line, as Beanish commented you can simply make a one pixel sprite and extend it between two points.
This is a great library for drawing 2D primitives in XNA that uses the technique for drawing lines, as well as other objects like arcs. I use it extensively:
http://sourceforge.net/projects/primitives2d/

Categories

Resources