Я недавно начал заниматься разработкой XNA и, имея некоторый (очень ограниченный) опыт работы с ним в прошлом, я решил попробовать создать клон Pong, чтобы узнать, сколько я могу вспомнить. Большая часть того, что я знал, вернулась ко мне, но у меня возникли проблемы с обнаружением столкновений между битами и мячом. У меня есть 3 прямоугольника, чтобы обновить положение вместе со спрайтами, которые я использую, и когда прямоугольник шара пересекается с прямоугольником летучей мыши, я умножаю скорость шара X на -1. Однако это приводит к необычному эффекту, благодаря которому мяч подпрыгивает вокруг летучей мыши, как показано в этом видео . Что я здесь не так делаю?
Вот код для этого проекта (бедный, я знаю):
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 Pong
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
System.Random generator = new Random();
Texture2D ball;
Texture2D bat1;
Texture2D bat2;
Texture2D middle;
Vector2 midPos;
Vector2 bat1Pos;
Vector2 bat2Pos;
Vector2 ballPos;
Vector2 ballVelo;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
//Load sprites
ball = Content.Load<Texture2D>(@"sprites/pongball");
bat1 = Content.Load<Texture2D>(@"sprites/pongbat");
bat2 = Content.Load<Texture2D>(@"sprites/pongbat");
middle = Content.Load<Texture2D>(@"sprites/pongmiddle");
//Set default sprite positions
midPos.X = (Window.ClientBounds.Width / 2) - 5;
midPos.Y = 0;
bat1Pos.X = 10;
bat1Pos.Y = (Window.ClientBounds.Height/2) - 50;
bat2Pos.X = Window.ClientBounds.Width - 20;
bat2Pos.Y = (Window.ClientBounds.Height/2) - 50;
ballPos.X = (Window.ClientBounds.Width / 2) - 5;
ballPos.Y = (Window.ClientBounds.Height / 2) - 5;
//Generate random ball velocity
ballVelo.X = generator.Next(5,10);
ballVelo.Y = generator.Next(4, 7);
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
//Update rectangle values
Rectangle bat1Rect = new Rectangle((int)bat1Pos.X, (int)bat1Pos.Y, 10, 100);
Rectangle bat2Rect = new Rectangle((int)bat2Pos.X, (int)bat2Pos.Y, 10, 100);
Rectangle ballRect = new Rectangle((int)ballPos.X, (int)ballPos.Y, 10, 100);
//Move ball
ballPos += ballVelo;
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
if (Keyboard.GetState().IsKeyDown(Keys.Escape))
this.Exit();
//Bat 1 movement and restriction
if (Keyboard.GetState().IsKeyDown(Keys.Up))
bat1Pos.Y -= 4;
if (Keyboard.GetState().IsKeyDown(Keys.Down))
bat1Pos.Y += 4;
if (bat1Pos.Y <= 0)
bat1Pos.Y = 0;
if (bat1Pos.Y >= Window.ClientBounds.Height - 100)
bat1Pos.Y = Window.ClientBounds.Height - 100;
//Bat 2 movement and restriction
if (Keyboard.GetState().IsKeyDown(Keys.W))
bat2Pos.Y -= 4;
if (Keyboard.GetState().IsKeyDown(Keys.S))
bat2Pos.Y += 4;
if (bat2Pos.Y <= 0)
bat2Pos.Y = 0;
if (bat2Pos.Y >= Window.ClientBounds.Height - 100)
bat2Pos.Y = Window.ClientBounds.Height - 100;
//Ball movement restrictions
if (ballPos.X <= 0)
ballVelo.X *= -1;
if (ballPos.Y <= 0)
ballVelo.Y *= -1;
if (ballPos.X >= Window.ClientBounds.Width - 5)
ballVelo.X *= -1;
if (ballPos.Y >= Window.ClientBounds.Height - 5)
ballVelo.Y *= -1;
//Collision detection between bats and ball
if (ballRect.Intersects(bat1Rect))
{
ballVelo.X *= -1;
}
if (ballRect.Intersects(bat2Rect))
{
ballVelo.X *= -1;
}
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
spriteBatch.Begin();
spriteBatch.Draw(middle, midPos, Color.White);
spriteBatch.Draw(bat1, bat1Pos, Color.White);
spriteBatch.Draw(bat2, bat2Pos, Color.White);
spriteBatch.Draw(ball, ballPos, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
}