スプライトを簡単に回転できますが、衝突のために長方形を回転させるにはどうすればよいですか (分離軸定理を使用することを考えていますが、それを適用する方法がわかりません) ヘルプまたは例をいただければ幸いです :)
ゲーム 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 CombatTank
{
public class Game1 : Microsoft.Xna.Framework.Game
{
//Declare Graphic Manager & Spritebatch
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
//Declare Player 1
theBody player1TankBody;
//Declare Player 2
theBody player2TankBody;
//Save Player 1 Position
Vector2 savedPlayer1TankBodyPosition;
//Save Player 2 Position
Vector2 savedPlayer2TankBodyPosition;
//Declare Keyboard States
KeyboardState currentkeyboardState;
KeyboardState previousKeyboardState;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
//TankBody Position Player 1
Vector2 player1TankBodyPosition = new Vector2(200, 200);
Vector2 player2TankBodyPosition = new Vector2(400, 200);
//TankBody Scale
float player1TankBodyScale = 1.0F;
float player2TankBodyScale = 1.0F;
//TankBody Rotation
float player1TankBodyRotation = 0.0F;
float player2TankBodyRotation = 0.0F;
//TankBody Color
Color player1TankBodyColor = Color.Red;
Color player2TankBodyColor = Color.Blue;
//Create Tank
player1TankBody = new theBody(player1TankBodyPosition,player1TankBodyScale, player1TankBodyRotation, player1TankBodyColor);
player2TankBody = new theBody(player2TankBodyPosition, player2TankBodyScale, player2TankBodyRotation, player2TankBodyColor);
base.Initialize();
}
protected override void LoadContent()
{
//Create New SpriteBatch
spriteBatch = new SpriteBatch(GraphicsDevice);
//Load The Player 1 TankBody Texture
Texture2D player1SpriteTankBody = Content.Load<Texture2D>("TankBody");
player1TankBody.LoadContent(Content,"TankBody");
//Extract Collision Data For Player 1
player1TankBody.TankBodyTextureData = new Color[player1TankBody.Texture.Width * player1TankBody.Texture.Height];
player1TankBody.Texture.GetData(player1TankBody.TankBodyTextureData);
//Load The Player 2 TankBody Texture
Texture2D player2SpriteTankBody = Content.Load<Texture2D>("TankBody");
player2TankBody.LoadContent(Content, "TankBody");
//Extract Collision Data For Player 2
player2TankBody.TankBodyTextureData = new Color[player2TankBody.Texture.Width * player2TankBody.Texture.Height];
player2TankBody.Texture.GetData(player2TankBody.TankBodyTextureData);
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
//Save Player 1 Postion
savedPlayer1TankBodyPosition.X = player1TankBody.Position.X;
savedPlayer1TankBodyPosition.Y = player1TankBody.Position.Y;
//Save Player 2 Position
savedPlayer2TankBodyPosition.X = player2TankBody.Position.X;
savedPlayer2TankBodyPosition.Y = player2TankBody.Position.Y;
//Updates Player 1
UpdatePlayer1(gameTime);
//Update Player 2
UpdatePlayer2(gameTime);
//Collision Player 1
CollisionPlayer1(gameTime);
//Collision Player 2
CollisionPlayer2(gameTime);
base.Update(gameTime);
}
private void UpdatePlayer1(GameTime gameTime)
{
//Save the previous state of the keyboard
previousKeyboardState = currentkeyboardState;
//Read the current state of the keyboard
currentkeyboardState = Keyboard.GetState();
//TankBody Movement
if (currentkeyboardState.IsKeyDown(Keys.W))
{
//Move Tank Forward
player1TankBody.Position.X -= 5 * (float)Math.Cos(player1TankBody.Rotation);
player1TankBody.Position.Y -= 5 * (float)Math.Sin(player1TankBody.Rotation);
}
if (currentkeyboardState.IsKeyDown(Keys.S))
{
//Move Tank Backwards
player1TankBody.Position.X += 5 * (float)Math.Cos(player1TankBody.Rotation);
player1TankBody.Position.Y += 5 * (float)Math.Sin(player1TankBody.Rotation);
}
if (currentkeyboardState.IsKeyDown(Keys.A))
{
player1TankBody.Rotation -= 0.03f;
}
if (currentkeyboardState.IsKeyDown(Keys.D))
{
player1TankBody.Rotation += 0.03f;
}
}
private void UpdatePlayer2(GameTime gameTime)
{
//Save the previous state of the keyboard
previousKeyboardState = currentkeyboardState;
//Read the current state of the keyboard
currentkeyboardState = Keyboard.GetState();
//TankBody Movement
if (currentkeyboardState.IsKeyDown(Keys.Up))
{
//Move Tank Forward
player2TankBody.Position.X -= 5 * (float)Math.Cos(player2TankBody.Rotation);
player2TankBody.Position.Y -= 5 * (float)Math.Sin(player2TankBody.Rotation);
}
if (currentkeyboardState.IsKeyDown(Keys.Down))
{
//Move Tank Backward
player2TankBody.Position.X += 5 * (float)Math.Cos(player2TankBody.Rotation);
player2TankBody.Position.Y += 5 * (float)Math.Sin(player2TankBody.Rotation);
}
if (currentkeyboardState.IsKeyDown(Keys.Left))
{
player2TankBody.Rotation -= 0.03f;
}
if (currentkeyboardState.IsKeyDown(Keys.Right))
{
player2TankBody.Rotation += 0.03f;
}
}
private void CollisionPlayer1(GameTime gameTime)
{
if (IntersectPixels(player1TankBody.BoundingBox, player1TankBody.TankBodyTextureData, player2TankBody.BoundingBox, player2TankBody.TankBodyTextureData))
{
player1TankBody.Position.X = savedPlayer1TankBodyPosition.X;
player1TankBody.Position.Y = savedPlayer1TankBodyPosition.Y;
}
}
private void CollisionPlayer2(GameTime gameTime)
{
if (IntersectPixels(player2TankBody.BoundingBox, player2TankBody.TankBodyTextureData, player1TankBody.BoundingBox, player1TankBody.TankBodyTextureData))
{
player2TankBody.Position.X = savedPlayer2TankBodyPosition.X;
player2TankBody.Position.Y = savedPlayer2TankBodyPosition.Y;
}
}
static bool IntersectPixels(Rectangle rectangleA, Color[] dataA, Rectangle rectangleB, Color[] dataB)
{
//Find top Bound of the Rectangle
int top = Math.Max(rectangleA.Top, rectangleB.Top);
int bottom = Math.Min(rectangleA.Bottom, rectangleB.Bottom);
int left = Math.Max(rectangleA.Left, rectangleB.Left);
int right = Math.Min(rectangleA.Right, rectangleB.Right);
for (int y = top; y < bottom; y++)
{
for (int x = left; x < right; x++)
{
//Get Color of both Pixels
Color colorA = dataA[(x - rectangleA.Left) + (y - rectangleA.Top) * rectangleA.Width];
Color colorB = dataB[(x - rectangleB.Left) + (y - rectangleB.Top) * rectangleB.Width];
//Both pixel are not completely Transparent
if (colorA.A != 0 && colorB.B != 0)
{
//Then an intersection is found
return true;
}
}
}
//No Intersection
return false;
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
player1TankBody.Draw(spriteBatch);
player2TankBody.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
theBody クラス:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;
namespace CombatTank
{
class theBody
{
//TankBody Texture
private Texture2D texture;
public Texture2D Texture
{
get
{
return texture;
}
}
//TankBody Height
private float height;
public float Height
{
get
{
return height;
}
}
//TankBody Width
private float width;
private float Width
{
get
{
return width;
}
}
//TankBody Position
public Vector2 Position;
//TankBody Origin
public Vector2 Origin;
//TankBody Rotation
public float Rotation = 0.0F;
//TankBody Color
public Color Color = Color.White;
//TankBody Scale
public float Scale = 1F;
//TankBody BoundingBox
public Rectangle BoundingBox
{
get
{
return new Rectangle((int)Position.X, (int)Position.Y, (int)texture.Width, (int)texture.Height);
}
}
//TankBody color Data(Used For Pixel Collision)
public Color[] TankBodyTextureData;
//TankBody Constructor
public theBody(Vector2 position,float scale,float rotation, Color color)
{
Position = position;
Scale = scale;
Rotation = rotation;
Color = color;
}
//LoadContent
public void LoadContent(ContentManager contentManager, string assetname)
{
texture = contentManager.Load<Texture2D>(assetname);
Origin = new Vector2(Texture.Width / 2, Texture.Height / 2);
}
//Draw
public virtual void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, Position, null, Color, Rotation, Origin, Scale, SpriteEffects.None, 0);
}
//Update
public void Update(GameTime gameTime)
{
}
}
}