судя по тому, что на скриншоте - у тебя spriteTexture равен null Судя по тому, что я увидел, ты создаешь объект car = new Sprite(spritePosition, spriteTexture); однако я не вижу присвоения spriteTexture какого-либо значения, хотя может невнимательно смотрю
protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); spriteTexture = Content.Load<Texture2D>("car1"); //car.LoadContent(content, "Content\\car1"); sprite[0].LoadContent(content, "Content\\car2"); sprite[1].LoadContent(content, "Content\\car3"); sprite[2].LoadContent(content, "Content\\car4"); sprite[3].LoadContent(content, "Content\\car5");
fon = Content.Load<Texture2D>("fon"); fon2 = Content.Load<Texture2D>("fon2");
menu.LoadContent(Content);
// TODO: use this.Content to load your game content here }
просто с хна не работал, незнаю как устроено там все изнутри :-) Тогда начинай методично отлавливать, в какой момент времени spriteTexture становится null, и вообще получает ли она свое значение в LoadContent
В классе Sprites если два конструктора. Один для анимированных спрайтов, другой для неанимированных. И соответственно две отрисовки - для анимированных и нет. Так вот, объект car нужно сделать через неанимированные, а он выпендривается.
Добавлено (19.02.2013, 13:13) --------------------------------------------- IIyxMASTER, она все время становится. Но если делать кар через анимированный отрисовщик, то тогда просто не грузится его спрайт. А ограничивающий прямоугольник работает.
Добавлено (19.02.2013, 13:21) --------------------------------------------- может создать carTexture, но оно тож не фурычит
Добавлено (19.02.2013, 14:46) --------------------------------------------- Еще есть какие-либо предложения???
Тут все понятно. Типичная ошибка. Ты сначала извлекаешь значение, а только потом его присваиваешь. Klkz начала в классе Sprites перенеси
Код
center = new Vector2(spriteTexture.Height / 2, spriteTexture.Width / 2);
В конец метода LoadContent
После чего в классе Game1 удали строчки
Код
car = new Sprite(spritePosition, spriteTexture);
и
Код
car.spritePosition = new Vector2(300, 300);
А после
Код
spriteTexture = Content.Load<Texture2D>("car1");
напиши
Код
spritePosition = new Vector2(300, 300); car = new Sprite(spritePosition, spriteTexture);
Добавлено (21.02.2013, 09:53) --------------------------------------------- А вообще, если честно в твоем классе я не вижу смысла. Я не знаю, будет ли выше представленый код корректно работать, т.к. загрузка спрайта у тебя происходит два раза, чего быть категорически не должно" Это пагубно влияет на производительность, да и вообще, лишняя, совершенно ненужная работ. Не нужно загружать текстуру в Game1, там просто создается объект Sprites, а в него просто просто передается Content и путь. Загружает все Sprites. Вот, так же передавать текстуру в конструктор не нужно, т.к. сама текстура в Game1 тебе не нужна. Просто создай текстуру в Sprites, загрузи ее в Sprites и отрисуй ее в Sprites/ Game1 тут вообще не при делах. Корочего говоря, я бы на твоем месте полностью переписал бы оба класса =)
*Не убегай от снайпера, умрешь уставшим. *Мои статьи...
using System; using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.GamerServices; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Media;
namespace Racing { class Sprite { public Texture2D spriteTexture; public Vector2 spritePosition;
//для анимации (хотя тут все спрайты не анимированы) private int frameCount; private double timeFrame; private int frame; private double totalElapsed;
//для движения public Vector2 speedSprite = new Vector2(0, -1);
KeyboardState oldState; float dx = 0; int speed = 1; public float rotation; public Vector2 center; public Vector2 velocity; KeyboardState keys; bool isRun; public Rectangle rect;
public void LoadContent(ContentManager content, String stringTexture) { spriteTexture = content.Load<Texture2D>(stringTexture);
center = new Vector2(spriteTexture.Height / 2, spriteTexture.Width / 2); }
public void Update(GameTime gameTime) { keys = Keyboard.GetState(); if (keys.IsKeyDown(Keys.Up)) isRun = true; else { isRun = false; speed = 1; dx = 0; } if (keys.IsKeyDown(Keys.A) && oldState.IsKeyUp(Keys.A)) { if (speed < 6) speed++; else speed = 2; } if (keys.IsKeyDown(Keys.Left) && isRun) { rotation -= 0.05f; } else if (keys.IsKeyDown(Keys.Right ) && isRun) { rotation += 0.05f; } if (isRun) { velocity = new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation)); if (speed == 1) { if (dx <= 2) dx += 0.1f; } else if (speed == 2) { if (dx <= 5) dx += 0.1f; } else if (speed == 3) { if (dx <= 8) dx += 0.1f; } else if (speed == 4) { if (dx >= 5) dx -= 0.1f; }
else if (speed == 3) { if (dx >= 8) dx -= 0.1f; } else if (speed == 2) { if (dx >= 5) dx -= 0.1f; } spritePosition += velocity * dx; } oldState = Keyboard.GetState(); }
public void DrawAnimationSprite(SpriteBatch spriteBatch) { int frameWidth = spriteTexture.Width; //frameCount; Rectangle rectangle = new Rectangle(frameWidth * frame, 0, frameWidth, spriteTexture.Height); spriteBatch.Draw(spriteTexture, spritePosition, rectangle, Color.White, 0f, center, 1,SpriteEffects.None, 0);
}
} }
Код
using System; using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.GamerServices; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Media;
namespace Racing { /// <summary> /// This is the main type for your game /// </summary> public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics;
ContentManager content;
SpriteBatch spriteBatch;
KeyboardState keyboardState;
public Texture2D spriteTexture; public Vector2 spritePosition;
private Texture2D fon; private Texture2D fon2;
//для движения Random rand = new Random();
//другие машинки Sprite[] sprite = new Sprite[4]; int j;
//столкновения public BoundingBox bbcar; public BoundingBox[] bb = new BoundingBox[4];
//меню Menu menu; private bool menuState; private int cursorState;
public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; content = new ContentManager(Services); graphics.PreferredBackBufferWidth = 800; graphics.PreferredBackBufferHeight = 600;
for (int i = 0; sprite.Length > i; i++) { sprite[i] = new Sprite(1, 1); }
car = new Sprite(spritePosition,spriteTexture); menu = new Menu(); menuState = true; cursorState = 1;
}
/// <summary> /// Allows the game to perform any initialization it needs to before starting to run. /// This is where it can query for any required services and load any non-graphic /// related content. Calling base.Initialize will enumerate through any components /// and initialize them as well. /// </summary> protected override void Initialize() { // TODO: Add your initialization logic here j = 0; for (int i =0; sprite.Length > i; i++) { sprite[i].spritePosition = new Vector2(rand.Next(10, Window.ClientBounds.Height), j = j + 200); } car.spritePosition = new Vector2(300, 300);
base.Initialize(); }
/// <summary> /// LoadContent will be called once per game and is the place to load /// all of your content. /// </summary> protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice);
fon = Content.Load<Texture2D>("fon"); fon2 = Content.Load<Texture2D>("fon2");
menu.LoadContent(Content);
// TODO: use this.Content to load your game content here }
/// <summary> /// UnloadContent will be called once per game and is the place to unload /// all content. /// </summary> protected override void UnloadContent() { // TODO: Unload any non ContentManager content here }
/// <summary> /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Update(GameTime gameTime) { // Allows the game to exit keyboardState = Keyboard.GetState();
if (keyboardState.IsKeyDown(Keys.Escape)) { menuState = true; } if (menuState == true) { if (keyboardState.IsKeyDown(Keys.Up)) { menu.cursorPositionGame = new Vector2(550, 30); menu.cursorPositionExit = new Vector2(520, 120); cursorState = 1; } else if (keyboardState.IsKeyDown(Keys.Down)) { menu.cursorPositionGame = new Vector2(550, 30); menu.cursorPositionExit = new Vector2(520, 120); cursorState = 2; } if (keyboardState.IsKeyDown(Keys.Enter) && cursorState == 1) { menuState = false; } else if (keyboardState.IsKeyDown(Keys.Enter) && cursorState == 2) { this.Exit(); } } else { Pause(); if (paused == false) {
double elapsed = gameTime.ElapsedGameTime.TotalSeconds; for (int i = 0; sprite.Length > i; i++) { sprite[i].UpdateFrame(elapsed); }
public void Collisions() { bbcar.Min = new Vector3(car.spritePosition.X, car.spritePosition.Y, 0); bbcar.Max = new Vector3(car.spritePosition.X + car.spriteTexture.Width, car.spritePosition.Y + car.spriteTexture.Height, 0);
for (int i = 0; bb.Length > i; i++) { bb[i].Min = new Vector3(sprite[i].spritePosition.X, sprite[i].spritePosition.Y, 0); bb[i].Max = new Vector3(sprite[i].spritePosition.X + sprite[i].spriteTexture.Width, sprite[i].spritePosition.Y + sprite[i].spriteTexture.Height, 0); } if (bbcar.Intersects(bb[0])) { sprite[0].spritePosition = new Vector2(rand.Next(10, Window.ClientBounds.Width - 0 - sprite[0].spriteTexture.Width), 50); } if (bbcar.Intersects(bb[1])) { sprite[1].spritePosition = new Vector2(rand.Next(10, Window.ClientBounds.Width - 0 - sprite[1].spriteTexture.Width), 50); } if (bbcar.Intersects(bb[2])) { sprite[2].spritePosition = new Vector2(rand.Next(10, Window.ClientBounds.Width - 0 - sprite[2].spriteTexture.Width), 50); } if (bbcar.Intersects(bb[3])) { sprite[3].spritePosition = new Vector2(rand.Next(10, Window.ClientBounds.Width - 0 - sprite[3].spriteTexture.Width), 50); } }
/// <summary> /// This is called when the game should draw itself. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); if (menuState == true) { spriteBatch.Begin(); menu.DrawMenu(spriteBatch, cursorState); spriteBatch.End(); } else {
spriteBatch.Begin(); spriteBatch.Draw(fon, new Vector2(0, 0), Color.AliceBlue); //car.DrawCar(spriteBatch); for (int i = 0; sprite.Length > i; i++) { sprite[i].DrawAnimationSprite(spriteBatch); }
car.DrawAnimationSprite(spriteBatch); spriteBatch.Draw(fon2, new Vector2(0, 0), Color.AliceBlue); spriteBatch.End(); }
// TODO: Add your drawing code here
base.Draw(gameTime); } } }
Маленько переделал, но теперь этот долбаный кар1 не едет в ту сторону, которую надо - нажимаешь Up, а он вправо. И поворачивается не так , как надо, а вокруг непонятного центра, на вроде спутника.
Добавлено (22.02.2013, 19:57) --------------------------------------------- Ну я и идиот , понял, в чем косяк с поворотом. Надо было в этой строчке
Цитата (Amri)
spriteBatch.Draw(spriteTexture, spritePosition, rectangle, Color.White, 0f, center, 1,SpriteEffects.None, 0);
заменить 0f на rotation. Получило, что я поворот заблокировал. А теперь все норм
Добавлено (01.03.2013, 01:01) --------------------------------------------- Думаю, что нет смысла создавать новую тему, поэтому спрошу здесь.
Есть такая проблема. Имеется вот такой код
Код
st = false; //это изначальное значение if (/*тут какое-то событие*/) { st = true; // переменная принимает это значение } switch (st) { case false: //тут какие-то действия, не суть break;
case true: //тут тоже некие действия break; }
Так вот, как сделать так, что бы переменная st не меняла своего значения после выхода из цикла? То есть, что бы после события она осталась true, а не перекидывалась обратно в false. Но что бы до события она осталась false.
Сообщение отредактировал Amri - Четверг, 21 Февраля 2013, 17:14
Сначала я if и юзал. В принципе, результат такой же. Необходимо, чтобы переменная st приняла значение true до следующего события, в данном случае - что бы она после принятия значения true не менялась обратно на false.
Amri, если ты не меняешь, то она и должна остаться true. Хотя я может чего-то не понимаю, я не знаком с xna. Тогда попробуй сохранять значение переменной с помощью другой переменной и когда тебе надо, переменной st присваивай значение переменной, в которую ты ранее сохранил значение переменной st. Сталина в каждый дом!
Это уже не хна, это просто шарп . Тогда может попробовать int вместо bool. Сейчас мне не возможно проверить, ибо я на работе, а компа под рукой нет. Попробую и твой вариант. Но, думаю, есть способ проще.
Добавлено (01.03.2013, 11:48) --------------------------------------------- Это уже не хна, это просто шарп . Тогда может попробовать int вместо bool. Сейчас мне не возможно проверить, ибо я на работе, а компа под рукой нет. Попробую и твой вариант. Но, думаю, есть способ проще.
Все равно что использовать switch или if, хотя switch обычно используют, если проверяемое условие может иметь больше двух вариантов. Чтобы переменная st не меняла свое значение нужно просто использовать дополнительную переменную, которой будет присваиваться значение переменной st:
Код
st = false;
bool stLoc = st;
if(/* какое-то условие*/) { stLoc = true; }
if(stLoc) { // Первый вариант развития событий } else { // Второй вариант развития событий }
TreinDSM, значит switch тут и должно быть планируется вариантов больше, чем два. Но тогда получается, что bool в этом случае не катит. Необходимо использовать int.
TreinDSM, этот вариант тоже не помогает. Оно перекидывается обратно. Хм.. Надо думать дальше.
Amri, Ага. Я то понял, что нужно, чтобы st не меняла своего изначального значения. Вот этот код выполняется внутри цикла?
Код
st = false; //это изначальное значение if (/*тут какое-то событие*/) { st = true; // переменная принимает это значение } switch (st) { case false: //тут какие-то действия, не суть break;
TreinDSM, нет. Изначальное значение переменной st - false. Значение true приобретается в результате выполнения условия. Необходимо, что бы значение true осталось до следующего условия, где явно прописано, что st = false. Но конкретно сейчас такого нет, поэтому требуется, что бы st = true и после того, как условие выполнено. А приведенный код - это не цикл, это метод целиком. Вот полный код, возможно это поможет лучше разобраться
Код
public void AIBot() { st = false;
if (bbkr.Intersects(bbcar2)) { st = true; }
switch (st) { case false: car2.spritePosition += car2.speedSprite; car2.speedSprite = new Vector2(1, 0); car2.rotation = 0.0f; car2.velocity = new Vector2(); break;
case true: car2.rotation = 3.1f; car2.velocity = new Vector2(); car2.speedSprite = new Vector2(-1, 0); car2.spritePosition += car2.speedSprite; break; }
Тогда не переопределяй st в начале метода AIBot, а вынеси ее определение в тело класса. Если я правильно понял, то нужно, чтобы переменная st была изначально инициализирована значение false, после чего ее изменение происходит только при определенных условиях, таких как bbkr.Intersects(bbcar2) == true. Тогда как то так:
Код
private bool st = false; public void AIBot() {
if (bbkr.Intersects(bbcar2)) { st = true; }
switch (st) { case false: car2.spritePosition += car2.speedSprite; car2.speedSprite = new Vector2(1, 0); car2.rotation = 0.0f; car2.velocity = new Vector2(); break;
case true: car2.rotation = 3.1f; car2.velocity = new Vector2(); car2.speedSprite = new Vector2(-1, 0); car2.spritePosition += car2.speedSprite; break; }
Так тоже не получается. St принимает почему-то значение true, еще задолго до события, в данном случае - столкновения. И в итоге машинка едет в другую сторону, но она должна развернуться только тогда, когда пересечет линию, а этого не происходит. она сразу едет обратно.