几周前我开始学习c#monogame,我想开始一个项目。 我选择的项目是破砖者克隆,一切顺利。但我偶然发现了一些我花了几个小时在google上寻找没有答案的东西。 我遇到的问题是球和砖之间的碰撞检测。 在球拍和球的工作之间,我有一个有效的解决方案。 这是:
// Collision between the ball and player
public void Collision(Player player, Ball ball)
{
MinX = (int)player.PlayerPosition.X - ball.Width;
MaxX = (int)player.PlayerPosition.X + player.Width + ball.Width;
MinY = 0;
MaxY = (int)player.PlayerPosition.Y - ball.Height;
Rectangle BallRectangle = new Rectangle((int)ball.BallPosition.X, (int)ball.BallPosition.Y, ball.Width, ball.Height);
Rectangle PlayerRectangle = new Rectangle((int)player.PlayerPosition.X, (int)player.PlayerPosition.Y, player.Width, player.Height);
if (BallRectangle.Intersects(PlayerRectangle))
{
ball.BallPosition.Y = MathHelper.Clamp(ball.BallPosition.Y, MinY, MaxY);
ball.BallPosition.X = MathHelper.Clamp(ball.BallPosition.X, MinX, MaxX);
ball.BallSpeed.Y *= -1;
float BallMiddlePoint = ball.BallPosition.X + (ball.Width / 2);
float PlayerMiddlePoint = player.PlayerPosition.X + (player.Width / 2);
ball.BallSpeed.X = (BallMiddlePoint - PlayerMiddlePoint) / 10 + ball.ExtraSpeedOverTime;
}
}
现在回到我的问题,我使用Rectangle.Intersect(Rectangle)来检查碰撞。 主要问题是:如何让球在砖块上正确弹跳?
我希望我能提供足够的信息。
我的球类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace BrickBreakerV2
{
class Ball
{
// The texture of the ball
Texture2D BallTexture;
// The position of the ball
public Vector2 BallPosition;
// The speed of the ball
public Vector2 BallSpeed;
// The speed that gets added over time
public float ExtraSpeedOverTime;
// Time values used in incrementing the speed over time
TimeSpan IncreaseSpeed;
TimeSpan PreviousSpeedIncrease;
// The "active" state of the ball
public bool Active;
// The state of movement of the ball
public bool Moveball;
// The Width of the ball
public int Width
{
get { return BallTexture.Width; }
}
// The Height of the ball
public int Height
{
get { return BallTexture.Height; }
}
// Construct a class for Boundaries
CollisionHandler Collision = new CollisionHandler();
public void Initialize(ContentManager Content, GraphicsDevice graphicsDevice, Player player)
{
BallTexture = Content.Load<Texture2D>("Graphics\\ball.png");
BallPosition = new Vector2(player.PlayerPosition.X + (player.Width / 2) - (Width / 2),
player.PlayerPosition.Y - Height - 5);
BallSpeed = new Vector2(5.0f, -5.0f);
ExtraSpeedOverTime = 1.0f;
IncreaseSpeed = TimeSpan.FromSeconds(12f);
PreviousSpeedIncrease = TimeSpan.Zero;
Active = true;
Moveball = false;
}
public void Update(GraphicsDevice graphicsDevice, GameTime gameTime, Player player)
{
if (Moveball)
{
BallPosition += BallSpeed;
}
else
{
BallPosition = new Vector2(player.PlayerPosition.X + (player.Width / 2) - (Width / 2),
player.PlayerPosition.Y - Height - 5);
}
if (gameTime.TotalGameTime - PreviousSpeedIncrease > IncreaseSpeed)
{
ExtraSpeedOverTime += 0.01f;
BallSpeed.X *= ExtraSpeedOverTime;
BallSpeed.Y *= ExtraSpeedOverTime;
PreviousSpeedIncrease = gameTime.TotalGameTime;
}
// Makes sure that the ball doesn't go to fast
if (BallSpeed.X > 10.50f)
BallSpeed.X = 10.50f;
if (BallSpeed.Y > 10.50f)
BallSpeed.Y = 10.50f;
if (BallSpeed.X < -10.50f)
BallSpeed.X = -10.50f;
if (BallSpeed.Y < -10.50f)
BallSpeed.Y = -10.50f;
// Keep the ball in the boundaries
Collision.GetBoundaries(graphicsDevice, this);
// Detect collision between ball and player
Collision.Collision(player, this);
}
public void Update(Brick brick)
{
// Detect collision between ball and brick
Collision.Collision(this, brick);
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(BallTexture, BallPosition, null, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, 1f);
}
}
}
我的砖类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace BrickBreakerV2
{
class Brick
{
// The texture of the brick
public Texture2D BrickTexture;
// The position of the bricks
public Vector2 BrickPosition;
// The color tint of the brick
public Color ColorTint;
// The "active" state of the brick
public bool Active;
// The width of the brick
public int Width
{
get { return BrickTexture.Width; }
}
// The height of the brick
public int Height
{
get { return BrickTexture.Height; }
}
// Construct a class for collisionhandler
CollisionHandler Collision;
public void Initialize(ContentManager Content)
{
BrickTexture = Content.Load<Texture2D>("Graphics\\brick.png");
BrickPosition = new Vector2(600, 500);
Active = true;
ColorTint = Color.White;
Collision = new CollisionHandler();
}
public void Update(Ball ball)
{
Collision.Collision(ball, this);
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(BrickTexture, BrickPosition, null, ColorTint, 0f, Vector2.Zero, 1f, SpriteEffects.None, 1f);
}
}
}
我的代码块用于处理CollisionHandler.cs中球和砖之间的碰撞:
// Collision between ball and brick
public void Collision(Ball ball, Brick brick)
{
Rectangle BallRectangle = new Rectangle((int)ball.BallPosition.X, (int)ball.BallPosition.Y, ball.Width, ball.Height);
Rectangle BrickRectangle = new Rectangle((int)brick.BrickPosition.X, (int)brick.BrickPosition.Y, brick.Width, brick.Height);
if (BallRectangle.Intersects(BrickRectangle))
{
int XOverlap;
int YOverlap;
if (BallRectangle.Center.X < BrickRectangle.Center.X)
{
XOverlap = (BallRectangle.X + ball.Width) - BrickRectangle.X;
}
else
{
XOverlap = (BrickRectangle.X + brick.Width) - BallRectangle.X;
}
if (BallRectangle.Center.Y < BrickRectangle.Center.Y)
{
YOverlap = (BallRectangle.Y + ball.Height) - BrickRectangle.Y;
}
else
{
YOverlap = (BrickRectangle.Y + brick.Height) - BallRectangle.Y;
}
if (XOverlap == YOverlap)
{
ball.BallSpeed.X *= -1;
ball.BallSpeed.Y *= -1;
}
else if (XOverlap < YOverlap)
{
ball.BallSpeed.X *= -1;
}
else
{
ball.BallSpeed.Y *= -1;
}
brick.Active = false;
}
}
答案 0 :(得分:1)
我想帮助你,但我不打算调试你的代码。幸运的是,基本的二维碰撞检测和破碎机克隆已经做过很多次了。
快速谷歌搜索出现了以下教程。我自己没有这样做,但如果我在哪里,我会从这里开始:
祝你好运。