我正在使用Monogame进行3D游戏,我现在还很早就开发了它,我正在为玩家制作一个健康系统,以便当玩家(目前是一个球)击中另一个球文时说“你已经死了!”弹出。
我认为一切正常,这不是问题,问题是什么时候,模型变得非常糟糕,这些图片是帮助显示我所说的内容的截图: 在http://i.imgur.com/vF2wCJv.png之前 在http://i.imgur.com/4VLdwqk.png之后
我的绘图代码和添加模型非常简单:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace Game7
{
/// <summary>
/// This is the main type for your game.
/// </summary>
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
SpriteFont font;
float player_health = 100;
Camera camera;
Floor floor;
BasicEffect effect;
Model ball;
static float player_x = 15;
static float player_y = 1;
static float player_z = 5;
private Matrix world_ball = Matrix.CreateTranslation(new Vector3(15, 1, 20));
private Matrix world_player = Matrix.CreateTranslation(new Vector3(player_x, player_y, player_z));
private Matrix view = Matrix.CreateLookAt(new Vector3(0, 0, 10), new Vector3(0, 0, 0), Vector3.UnitY);
private Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), 800f / 480f, 0.1f, 100f);
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
/// <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
camera = new Camera(this, new Vector3(10f, 1f, 5f), Vector3.Zero, 5f);
Components.Add(camera);
floor = new Floor(GraphicsDevice, 40, 40);
effect = new BasicEffect(GraphicsDevice);
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);
ball = Content.Load<Model>("Ball DAE");
font = Content.Load<SpriteFont>("basicFont");
// TODO: use this.Content to load your game content here
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// game-specific 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)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
// TODO: Add your update logic here
KeyboardState kb = Keyboard.GetState();
if (kb.IsKeyDown(Keys.Escape))
{
this.Exit();
}
if (kb.IsKeyDown(Keys.Left))
{
player_x = player_x + 0.05f;
world_player = Matrix.CreateTranslation(new Vector3(player_x, player_y, player_z));
if (IsCollision(ball, world_player, ball, world_ball))
{
player_x = player_x - 0.05f;
world_player = Matrix.CreateTranslation(new Vector3(player_x, player_y, player_z));
player_health = 0;
}
}
if (kb.IsKeyDown(Keys.Right))
{
player_x = player_x - 0.05f;
world_player = Matrix.CreateTranslation(new Vector3(player_x, player_y, player_z));
if (IsCollision(ball, world_player, ball, world_ball))
{
player_x = player_x + 0.05f;
world_player = Matrix.CreateTranslation(new Vector3(player_x, player_y, player_z));
player_health = 0;
}
}
if (kb.IsKeyDown(Keys.Up))
{
player_z = player_z + 0.05f;
world_player = Matrix.CreateTranslation(new Vector3(player_x, player_y, player_z));
if (IsCollision(ball, world_player, ball, world_ball))
{
player_z = player_z - 0.05f;
world_player = Matrix.CreateTranslation(new Vector3(player_x, player_y, player_z));
player_health = 0;
}
}
if (kb.IsKeyDown(Keys.Down))
{
player_z = player_z - 0.05f;
world_player = Matrix.CreateTranslation(new Vector3(player_x, player_y, player_z));
if (IsCollision(ball, world_player, ball, world_ball))
{
player_z = player_z + 0.05f;
world_player = Matrix.CreateTranslation(new Vector3(player_x, player_y, player_z));
player_health = 0;
}
}
base.Update(gameTime);
}
private bool IsCollision(Model model1, Matrix world1, Model model2, Matrix world2)
{
for (int meshIndex1 = 0; meshIndex1 < model1.Meshes.Count; meshIndex1++)
{
BoundingSphere sphere1 = model1.Meshes[meshIndex1].BoundingSphere;
sphere1 = sphere1.Transform(world1);
for (int meshIndex2 = 0; meshIndex2 < model2.Meshes.Count; meshIndex2++)
{
BoundingSphere sphere2 = model2.Meshes[meshIndex2].BoundingSphere;
sphere2 = sphere2.Transform(world2);
if (sphere1.Intersects(sphere2))
return true;
}
}
return false;
}
/// <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);
// TODO: Add your drawing code here
if (player_health == 0)
{
drawHealth();
}
floor.Draw(camera, effect);
DrawPlayer(ball, world_player, view, projection);
DrawModel(ball, world_ball, camera.View, camera.Projection);
base.Draw(gameTime);
}
private void DrawModel(Model model, Matrix world_ball, Matrix view, Matrix projection)
{
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.World = world_ball;
effect.View = camera.View;
effect.Projection = camera.Projection;
}
mesh.Draw();
}
}
private void DrawPlayer(Model model, Matrix world_player, Matrix view, Matrix projection)
{
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.World = world_player;
effect.View = camera.View;
effect.Projection = camera.Projection;
}
mesh.Draw();
}
}
private void drawHealth()
{
spriteBatch.Begin();
spriteBatch.DrawString(font, "You have died", new Vector2(100, 100), Color.Black);
spriteBatch.End();
}
}
}
所以是的,希望这更像是一种效果,我可以通过某种照明效果来修复,但我遇到的问题是灯光使我的模型只显示为黑色。
答案 0 :(得分:1)
当调用SpriteBatch.End()时,SpriteBatch会更改GraphicsDevice的属性(因此当它呈现给设备时)。 在绘制健康文本后,将它们重置为默认值(或您需要的默认值)。
GraphicsDevice.BlendState = BlendState.Opaque;
GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
GraphicsDevice.DepthStencilState = DepthStencilState.Default; // this should be the one you are looking for