XNA spritebatch.End(); with a class doesn't work and it is saying: 'XNA Framework Reach profile requires TextureAddressMode to be Clamp when using texture sizes that are not powers of two.' when started. And it doesn't show any error's either. How can I solve this? Please help!!
public override void Draw()
{
Statics.SPRITEBATCH.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearWrap, null,null);
Statics.SPRITEBATCH.Draw(this.background, Vector2.Zero, Color.White);
foreach (var item in Tuyaux)
{
item.Draw();
}
Statics.SPRITEBATCH.Draw(this.sand, new Vector2(0, 529), Color.White);
Scroll.Draw();
Bird.Draw();
Statics.SPRITEBATCH.DrawString(this.Font, "Score : " + this.score.ToString(), new Vector2(10, 10), Color.Red);
if (Bird.dead)
{
// rode gloed over het spel als het gameover is.
Statics.SPRITEBATCH.Draw(Statics.PIXEL, new Rectangle(0,0, Statics.GAME_WIDTH,Statics.GAME_HEIGHT), new Color(1f, 0f, 0f, 0.3f));
// gameover achtergrond laten zien.
Statics.SPRITEBATCH.Draw(this.gameover, new Vector2(0, 80), Color.White);
}
Statics.SPRITEBATCH.End();
base.Draw();
}
The problem is exactly what the exception tells you:
You are targetting the Reach profile, so either all your texture dimensions must be powers of two or you have to use clamp as adress mode. So:
If you don't need wrapping, try replacing SamplerState.LinearWrap with SamplerState.LinearClamp in your Statics.SPRITEBATCH.Begin call.
If you need wrapping textures, make sure all of them have dimensions that are powers of two
Last but not least, if it is an option for you, you may simply use the HiDef profile instead of Reach
Related
Currently in my game i want trying to move my object towards both x axis and y axis.As I also wanted to put it into center ,I have put a camera.Here is my Camera code-
public class Camera
{
public Matrix transform;
public Viewport view;
public Vector2 origin;
Vector2 baseScreenSize = new Vector2(1136, 720);
float horScaling ;
float verScaling ;
Vector3 screenScalingFactor ;
public Camera(Viewport newView)
{
view = newView;
horScaling = view.Width / baseScreenSize.X;
verScaling = view.Height / baseScreenSize.Y;
screenScalingFactor = new Vector3(horScaling, verScaling, 1);
}
public void update(GameTime gt, ball pl)
{
origin = new Vector2(pl.Position.X + (pl.ballRectangle.Width / 2) - 400, 0);
transform = Matrix.CreateScale(1,1,0) *
Matrix.CreateTranslation(new Vector3(-origin.X, -origin.Y, 0));
}
}
and in Game1.cs file as usual in begin statement i am putting this-
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null, null, cm.transform*globalTransformation);
ba.Draw(spriteBatch, Color.White);
spriteBatch.End();
Here ba is the object of ball,its just have moving x and y functionalities.
In a separate begin,end statement ,I am drawing rest all of the objects-
spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, null, null, globalTransformation);
spriteBatch.Draw(mainMenu, new Vector2(0, 0), Color.White);
spriteBatch.Draw(mainMenu1, new Vector2(450, 100), Color.White);
spriteBatch.End();
Here Have applied globaltransformation to acheive independent screen resolution(similar codes like in Camera.cs).
Rest of the objects are working as expected,But intersections of camera object and rest of the objects is not working as expected.
I guess this is due to resolution independency is not applied to Camera object(I am not sure).I have tried lot of codes after searching internet,but none of them is working as expected.
In a simple words-I want to clone this game-
https://play.google.com/store/apps/details?id=com.BitDimensions.BlockyJump
If you see main player is moving along x and y axis,but due to camera its in constant position,but the obstacles are not in camera,How to acheive the intersection between obejct which is in camera draw and objects which are not in camera in this case
Request all to help,I am stuck here from long time...
Never thought this will be this much of easy...Searched all over internet,in
most of the codes they were saying we need to inverse the camera transform.
But this is not the case.As from beginning I was saying my problem is intersection between camera object and non camera object,here is the answer-
First of all we need to find the positions of camera object to form a world space rectangle
Vector2 hj = Vector2.Transform(ba.Position, cm.transform);
Rectangle leftRectangleT1 =
new Rectangle((int)hj.X, (int)hj.Y, ba.tex.Width, ba.tex.Height);
Here ba is the camera object,we need to transform it to camera transform like above codes.
To get transform of ba in case pixel intersection,here is the codes-
Matrix ballTransform = Matrix.CreateTranslation(new Vector3(hj.X, hj.Y, 0.0f));
Thats it you have ball rectangle which is camera object to intersect with real world objects(non camera objects)
I don't understand your question per say, but from what I gathered, you want the camera to follow the target's position, and you also want independent screen resolutions?
Well, for the independent screen resolution, simply create a screen resolution handler that renders the scene to a RenderTarget2D as defined by your sizes. Then draw that to the screen.
For the camera movement. Try adjusting the camera's position to follow the target's position with an offset and slerp interpolation to prevent stuttering and smooth action.
void Update(float gameTime) {
Vector3 camTransform = Camera.Position + cameraTarget;
Vector3 newCameraPosition = Vector3.Slerp(cameraPosition, camTransform, 0.2f);
Camera.Position = newCameraPosition;
}
For your intersection problem try something along this
private bool intersects(rectangle1, rectangle2) {
return rectangle1.x >= rectangle2.x &&
rectangle1.y >= rectangle2.y &&
rectangle1.y <= rectangle2.y + rectangle2.h &&
rectangle1.x <= rectangle2.x + rectangle2.w;
}
private void checkIntersections(gameObjects[]) {
foreach (var obj in gameobjects) {
if (intersects(obj.rectangle, camera.rectangle){
handleIntersections(camera, obj);
}
}
}
This question already has answers here:
Xna draw order not working right
(2 answers)
Closed 9 years ago.
Problem: When an if clause is put around a spriteBatch.Draw statement, it seems to affect other spriteBatch.Draw that is outside the if clause .
This is (part of) the code in the Draw method:
if(OvertakeMouseHover == true)
{
spriteBatch.Draw(OvertakeButton, OvertakeButtonPosition, Color.White);
}
spriteBatch.Draw(Car1, Car1Position, Color.White);
spriteBatch.Draw(Car2, Car2Position, Color.White);
And this is the code setting OvertakeMouseHover:
if (mouse.X > OvertakeButtonPosition.X && mouse.X < OvertakeButtonPosition.X + OvertakeButton.Width &&
mouse.Y > OvertakeButtonPosition.Y && mouse.Y < OvertakeButtonPosition.Y + OvertakeButton.Height)
{
//Overtake button mouseover
OvertakeMouseHover = true;
}
else
{
OvertakeMouseHover = false;
}
When running the above code, OvertakeButton appears as expected (ie when the mouse is hovering over its location). Car2 appears as expected (all the time). However Car1, rather than appearing all the time, appears and disappears with the OvertakeButton, as though spriteBatch.Draw(Car1...) is within the if statement.
The following code makes all 3 sprites appear all the time:
//if(OvertakeMouseHover == true)
//{
spriteBatch.Draw(OvertakeButton, OvertakeButtonPosition, Color.White);
//}
spriteBatch.Draw(Car1, Car1Position, Color.White);
spriteBatch.Draw(Car2, Car2Position, Color.White);
I can't for the life of me work out why spriteBatch.Draw(Car1..) is affected by the if statement, but it definitely looks like it is to me. All ideas welcome!
EDIT - and this code makes all 3 sprite appear and disappear with the MouseHover. It's as though the bracket is one line lower than it should be:
if (OvertakeMouseHover == true)
{
spriteBatch.Draw(OvertakeButton, OvertakeButtonPosition, Color.White);
spriteBatch.Draw(Car1, Car1Position, Color.White);
}
spriteBatch.Draw(Car2, Car2Position, Color.White);
EDIT 2. Okay this is to do with the image appearing in front/behind of my background. In which case the issue is to do with sorting. How do I force the sorting order? I assumed it was just back to front in order of the code but that doesn't seem to be it.
EDIT 3. Entire draw method. Currently investigating what the various sort options do.
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(SpriteSortMode.Backtofront, BlendState.AlphaBlend);
spriteBatch.Draw(RaceBackground, BackgroundPosition, Color.White);
spriteBatch.Draw(Car1, Car1Position, Color.White);
spriteBatch.Draw(Car2, Car2Position, Color.White);
if (OvertakeMouseHover == true)
{
spriteBatch.Draw(OvertakeButton, OvertakeButtonPosition, Color.White);
}
string output = Car1Speed.ToString();
// Find the center of the string
Vector2 FontOrigin = Font1.MeasureString(output) / 2;
// Draw the string
spriteBatch.DrawString(Font1, output, FontPos, Color.LightGreen,
0, FontOrigin, 1.0f, SpriteEffects.None, 0.5f);
spriteBatch.End();
// TODO: Add your drawing code here
base.Draw(gameTime);
You should call SpriteBatch.Begin with SpriteSortMode.Deferred
Deferred guarantees that your sprites will be drawn in the order that you called the Draw method for them.
Deferred
Sprites are not drawn until End is called. End will apply graphics
device settings and draw all the sprites in one batch, in the same
order calls to Draw were received. This mode allows Draw calls to two
or more instances of SpriteBatch without introducing conflicting
graphics device settings. SpriteBatch defaults to Deferred mode.
http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.spritesortmode.aspx
according to the documentation, BackToFront says that it works the same as deferred, except that it takes depth into account, but you might be running into a bug with it. This is not the first time that I would have seen this bug.
If you use SpriteSortMode.BackToFront you need to specify the depth of each sprite, otherwise the game will draw them at the same time, making them to "flicker".
You may need to use a different SpriteBatch.Draw overload that has float layerDepth parameter, something like this one:
public void Draw (
Texture2D texture,
Vector2 position,
Nullable<Rectangle> sourceRectangle,
Color color,
float rotation,
Vector2 origin,
float scale,
SpriteEffects effects,
float layerDepth
)
Or better, as Sam I am previously wrote, use SpriteSortMode.Deferred which is easier to use and understand.
I have a 2D image of a tanks body (top down) that can be moved left-right across the screen.
On top, there's a second image of the tanks turret. This turret can be rotated across the screen edge following the users mouse movement along the Y axis.
When the user presses'Enter' a bullet appears and moves across the screen at the angle of the turret. However, whilst the angle is fine, the bullet's position seems to vary a lot. At times, it sites where it should (in the centre of the cannon) however, as you move the mouse it seems to get offsetted.
Edit: For some strange reason, my pictures don't seem to be showing up - so here is a direct link: http://img824.imageshack.us/img824/7093/khte.png
Edited Code:
Tank Fire
if (keyBoardState.IsKeyDown(Keys.Enter))
{
shell.Initialize(rotation, new Vector2(location.X + 25, location.Y - 15));
shell.makeAlive();
}
(It is initialized with the location of the tank (+25, -25) so it appears at the end of the turrent. having this set at the tanks location (shell.Initialize(rotation, location);) seems to make no difference to the offset.)
Bullet/Shell:
public void Update(GameTime gameTime)
{
if (alive)
{
movement.X -= speed * (float)Math.Cos(rotation);
movement.Y -= speed * (float)Math.Sin(rotation);
location.X += (int)movement.X;
location.Y += (int)movement.Y;
}
}
public void Draw(SpriteBatch spriteBatch)
{
if (alive)
{
spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
spriteBatch.Draw(texture, location, null, Color.White, rotation - MathHelper.PiOver2, new Vector2(texture.Width / 2, texture.Height / 2), 1.0f, SpriteEffects.None, 0f);
spriteBatch.End();
}
}
If you're trying to get your bullet to rotate about your tank, than I personally draw the bullet on top of the tank do the exact same thing that you do after you've fired your bullet(but with a greater magnitude) to displace it,
But if you want to use the origin parameter of SpriteBatch.Draw, than I'd imagine that it would look something like this:
given the following datapoints:
this.origin = new Vector2(texture.Width / 2, texture.Height / 2);
tank.origin = new Vector2(texture.Width / 2, texture.Height / 2);
// and this is what you'd pass into your sprite-batch.draw method
originToDraw = (tank.position + tank.origin)-(this.position + this.origin)
And you also have to initialize your bullet's position to the appropriate starting point Since I don't actually know where rotation comes from, I can't know for sure, but if it's the angle between your tank and the mouse, than I'd imagine it'd be the following
this.startingPosition = tank.position + tank.origin - this.origin
I asume that shell is a Bullet instance if yes your problem is the origin in Bullet class. It should have set this value in LoadTextures method
public void LoadTextures(Texture2D texture)
{
this.texture = texture;
this.origin = new Vector2(texture.Width, texture.Height);
}
And a little extra in Bullet.Draw method:
spriteBatch.Draw(texture, location, null, Color.White, rotation - 1.5f, origin, 1.0f, SpriteEffects.None, 0f);
change 1.5f to MathHelper.PiOver2 it is more accure when you want to rotate something 90 degrees
You have a nasty roundoff problem here.
You compute the velocity in floating point but switch to integers for the bullet's location. The problem is that while ON AVERAGE the errors even out any given bullet is going to either round up or round down every time.
Lets take an extreme case: The bullet is fired 25 degrees off the vertical axis and it's moving at two pixels per update cycle. Strangely enough the bullet flies directly down the axis.
Or an even more extreme case. The speed is 1/3 pixel per cycle. The bullet stands still.
I'm trying for hours now to solve this problem..
So.. I want to use different shaders on every Sprite I draw on the screen.
I tried to make different RenderTarget2Ds but no success.
No matter how hard I try to make the Graphicsdevice.Clear() Transparent, it just won't work.
(I use xna 3.1)
So all my sprites blocking the other sprites because I can't make the background transparent :\
Any idea ?
Code I use (it's a method):
graphicsDevice.SetRenderTarget(0, r2d);
graphicsDevice.Clear(ClearColor);
spriteBatch.Begin();
spriteBatch.Draw(
tex,
Dest,
Source,
moodcolor,
this.RotationAngle,
new Vector2(0, 0),
Zoom,
spriteEffect,
this.Z_Index);
spriteBatch.End();
graphicsDevice.SetRenderTarget(0, null);
graphicsDevice.Clear(ClearColor);
for (int i = 0; i < efs.Count; i++)
{
efs[i].effect.CurrentTechnique = efs[i].effect.Techniques["Deferred"];
foreach (EffectPass pass in efs[i].effect.CurrentTechnique.Passes)
{
spriteBatch.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.None);
efs[i].effect.Begin();
pass.Begin();
spriteBatch.Draw(r2d.GetTexture(), Vector2.Zero, Color.White);
spriteBatch.End();
pass.End();
efs[i].effect.End();
}
}
Update!
You don't have to use RenderTarget2D!
It's important to keep AlphaBlend!
This is solution for anybody who came across the same problem!
Solution snippet:
foreach (EffectPass pass in efs[ObjShaders[i].ShaderID].effect.CurrentTechnique.Passes)
{
spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None);
efs[ObjShaders[i].ShaderID].effect.Begin();
pass.Begin();
spriteBatch.Draw(
tex,
Dest,
Source,
moodcolor,
this.RotationAngle,
new Vector2(0, 0),
Zoom,
spriteEffect,
this.Z_Index);
spriteBatch.End();
pass.End();
efs[ObjShaders[i].ShaderID].effect.End();
}
Reading your question again, perhaps all you need to do is
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);
Now if your sprite textures have an alpha channel, they will be blended correctly.
As the title says, I have an XNA app that closes suddenly when it hits an app, but doesn't show any errors so I don't have a clue how to even begin to debug it. The code is very simple - I'm just playing with XNA and trying to render a simple triangle - so I can't imagine why it's stopping. The code that's running is
VertexPositionColor[] vertices;
public Terrain()
{
vertices = new VertexPositionColor[3];
vertices[0].Position = new Vector3(-0.5f, -0.5f, 0f);
vertices[0].Color = Color.Red;
vertices[1].Position = new Vector3(0, 0.5f, 0f);
vertices[1].Color = Color.Green;
vertices[2].Position = new Vector3(0.5f, -0.5f, 0f);
vertices[2].Color = Color.Yellow;
}
public void Draw(GameTime gameTime)
{
ScreenManager.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(
PrimitiveType.TriangleList,
vertices,
0,
1,
VertexPositionColor.VertexDeclaration);
}
and it's the Draw() function that screws it up. When I remove the DrawUserPrimitives line it runs fine (although show nothing...)
I'm going to assume that 'ScreenManager' is a class that inherits off 'DrawableGameComponent' and you are accessing the graphics device from there? Make sure somewhere in the constructor of your Game class you are initialising the GraphicsDeviceManager(this).
I think it's the 'GraphicsDevice' that your ScreenManager is grabbing statically that might not be initialised properly.