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 Software_Design_Major_Project
{

    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        Texture2D ship; // Declaring the sprite
        Vector2 shipposition = Vector2.Zero; 

        List<bullets> bullets = new List<bullets>();
        KeyboardState pastkey;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            graphics.PreferredBackBufferWidth = 600; 


        }



        protected override void Initialize()
        {

            base.Initialize();
        }


        protected override void LoadContent()
        {

            spriteBatch = new SpriteBatch(GraphicsDevice);

            ship = Content.Load<Texture2D>("ship"); // Loads the ship into the memory.
            shipposition = new Vector2((graphics.GraphicsDevice.Viewport.Width / 2) -
            (ship.Width / 2), 420);


        }


        protected override void UnloadContent()
        {

        }


        protected override void Update(GameTime gameTime)
        {

            if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Left) && shipposition.X
            >= 0) 
            {
                shipposition.X -= 6;
            }
            if(Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Right) && shipposition.X <
            ((graphics.GraphicsDevice.Viewport.Width) - (ship.Width))) 
            {
                shipposition.X += 6;
            }

            if (Keyboard.GetState().IsKeyDown(Keys.Space) && pastkey.IsKeyUp(Keys.Space)) 
            {
                shoot();                
            }
            pastkey = Keyboard.GetState();
            updatebullets();
            base.Update(gameTime);
        }

        public void updatebullets() 
        {
            foreach(bullets bullet in bullets)
            {

                if (Vector2.Distance(bullet.position, shipposition) < 0)
                    bullet.isvisible = false;
            }

            for (int i = 0; i < bullets.Count; i++) 
            {
                if (!bullets[i].isvisible)
                    bullets.RemoveAt(i);
                i--;
            }
        }

        public void shoot() 
        {
            bullets newbullet = new bullets(Content.Load<Texture2D>("bullet"));
            newbullet.position = shipposition;
            newbullet.isvisible = true;

            if (bullets.Count < 20)
                bullets.Add(newbullet);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend); 
            spriteBatch.Draw(ship, shipposition, Color.White);
            spriteBatch.End();

            foreach (bullets bullet in bullets)
                bullet.Draw(spriteBatch);

            base.Draw(gameTime);
        }



    }
}

子弹

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Software_Design_Major_Project
{

          class bullets // A new class needs to be created to allow for bullets.
        {
            public Texture2D texture;

            public Vector2 position;
            public Vector2 origin;

            public bool isvisible;

            public bullets(Texture2D newtexture) 
            {
                texture = newtexture;
                isvisible = false;
            }

            public void Draw(SpriteBatch spritebatch) 
            {
                spritebatch.Draw(texture, position, null, Color.White, 0f, origin, 1f, 
                SpriteEffects.None, 0);
            }
    }
}

PS对不起,很长的帖子。

4

3 回答 3

1

我没有看到任何改变你的子弹位置的代码,你需要一个速度变量,并根据每帧的速度更新位置。

你可以从 a = Math.Atan(Y,X) 得到角度

看起来您可能删除了计算位置的部分,因为您认为您不需要速度的东西。我建议您尝试将其重新添加以查看它是否有效,然后删除您不需要的部分。

于 2012-07-18T14:27:22.770 回答
1

让没有人更早发现这一点感到惊讶。在绘制子弹之前,您将结束 SpriteBatch。对 SpriteBatch.Draw 的调用必须发生在 Begin 和 End 方法之间,因为在幕后进行的所有工作都是为了使绘图尽可能快。您需要做的就是将 spriteBatch.End() 进一步向下移动,如下所示:

protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);

        spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);
        spriteBatch.Draw(ship, shipposition, Color.White);

        foreach (bullets bullet in bullets)
            bullet.Draw(spriteBatch);

        spriteBatch.End(); //Move to here instead

        base.Draw(gameTime);
    }

额外琐事:基本上幕后发生的事情是精灵批处理实际上使用 begin 描述的设置对纹理进行批处理(是的,这些可以更改)然后当 end 被调用时,它会计算出哪些位落在屏幕之外并注意不要绘制它们,如果被告知,它会对纹理进行深度排序,它会在将它们绘制到后台缓冲区之前进行各种其他优化,然后最后当所有绘图结束时,后台缓冲区会呈现到屏幕上,然后旧的被拿走并重新用于下一次绘制调用。听起来工作量很大,但随着现代计算机的工作方式,优化往往会带来很大的改进。

于 2013-06-14T05:47:46.177 回答
0

你可以在这里查看这个样本。我很久以前就写过这个东西了,我想在XNA的v2.0中,现在想不起来了。

http://gozoomin.com/media/p/69699.aspx

那里的逻辑很简单:)

开始制作“经典”总是一个好的开始。

编辑 - 你也可以在这里得到它:http ://www.sendspace.com/file/r4s4um Edit2 - 我现在刚刚检查了代码,它有一些注释记录了大部分内容,可能你会得到一些用葡萄牙语写的东西. PS - 不要复制过去的代码!尝试学习有关示例的基础知识。

于 2012-07-18T14:32:50.337 回答