我的球和我的矩形不会正确碰撞(Monogame)
Posted
技术标签:
【中文标题】我的球和我的矩形不会正确碰撞(Monogame)【英文标题】:My ball and my rectangle wont collide properly (Monogame) 【发布时间】:2021-12-23 21:16:13 【问题描述】:我目前正在为我的学校项目编写一个打砖块类型的游戏,并且刚刚开始使用 monogame。我在大红色矩形和球上遇到了碰撞问题。我只是无法弄清楚我的代码有什么问题我提前感谢您的所有帮助。
碰撞视频:https://youtu.be/HOuUS8bUKn4
Game1.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
namespace TSA3
public class Game1 : Game
private GraphicsDeviceManager graphics;
private SpriteBatch spriteBatch;
// Platform
Platform platform;
Texture2D platformTexture;
Rectangle platformRectangle;
Color platformColor;
// Ball
Ball ball;
Texture2D ballTexture;
Rectangle ballRectangle;
Color ballColor;
bool ballDirectionX = true, ballDirectionY = true;
// Enemy
Enemy enemy;
Texture2D enemyTexture;
Rectangle enemyRectangle;
Color enemyColor;
Random random = new Random();
public const int ScreenW = 1200, ScreenH = 720;
public Game1()
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
protected override void Initialize()
graphics.PreferredBackBufferWidth = ScreenW;
graphics.PreferredBackBufferHeight = ScreenH;
graphics.ApplyChanges();
Window.AllowUserResizing = false;
Window.AllowAltF4 = true;
Window.Title = "Arkanoid";
// Platform
platformTexture = Content.Load<Texture2D>("platform");
platformRectangle = new Rectangle(0, Window.ClientBounds.Height - 50, 100, 30);
platformColor = Color.White;
// Ball
ballTexture = Content.Load<Texture2D>("ball");
ballRectangle = new Rectangle(0, 0, 20, 20);
ballColor = Color.DarkBlue;
// Enemy
enemyTexture = Content.Load<Texture2D>("enemyPiece");
enemyRectangle = new Rectangle(Window.ClientBounds.Width / 2, Window.ClientBounds.Height / 2, 200, 200);
enemyColor = Color.White;
base.Initialize();
protected override void LoadContent()
// Player
platform = new Platform(platformTexture, platformRectangle, platformColor, Window.ClientBounds.Width - 100);
// Ball
ball = new Ball(ballTexture, ballRectangle, ballColor, Window.ClientBounds.Width - 20, Window.ClientBounds.Height - 20, ballDirectionX, ballDirectionY);
// Enemy
enemy = new Enemy(enemyTexture, enemyRectangle, enemyColor);
spriteBatch = new SpriteBatch(GraphicsDevice);
float spawn = 0;
protected override void Update(GameTime gameTime)
spawn += (float)gameTime.ElapsedGameTime.TotalSeconds;
ball.ballBounce(platform.PlatformRectangle);
Keys[] k = Keyboard.GetState().GetPressedKeys();
foreach (Keys key in k)
platform.platformMovement(key);
break;
if (Keyboard.GetState().IsKeyDown(Keys.Space) && !ball.StartGame)
ball.StartGame = true;
ball.ballCollision(platform.PlatformRectangle);
ball.enemyCollision(enemy.enemyRectangle);
base.Update(gameTime);
protected override void Draw(GameTime gameTime)
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(ball.BallTexture, ball.BallRectangle, ball.BallColor);
spriteBatch.Draw(platform.PlatformTexture, platform.PlatformRectangle, platform.PlatformColor);
spriteBatch.Draw(enemy.enemyTexture, enemy.enemyRectangle, enemy.enemyColor);
spriteBatch.End();
base.Draw(gameTime);
Ball.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Text;
namespace TSA3
public class Ball
Texture2D ballTexture;
Rectangle ballRectangle;
Color ballColor;
int boundaryX, boundaryY;
bool ballDirectionX, ballDirectionY;
bool startGame;
public const int BALL_SPEED = 7;
public Ball(Texture2D ballTexture, Rectangle ballRectangle, Color ballColor, int boundaryX, int boundaryY, bool ballDirectionX, bool ballDirectionY)
this.ballTexture = ballTexture;
this.ballRectangle = ballRectangle;
this.ballColor = ballColor;
this.boundaryX = boundaryX;
this.boundaryY = boundaryY;
this.ballDirectionX = ballDirectionX;
this.ballDirectionY = ballDirectionY;
startGame = false;
public Texture2D BallTexture get => ballTexture;
public Rectangle BallRectangle get => ballRectangle;
public Color BallColor get => ballColor;
public bool StartGame get => startGame; set => startGame = value;
public void ballBounce(Rectangle platformRectangle)
if (startGame)
if (ballRectangle.X <= 0)
ballDirectionX = true;
else if (ballRectangle.X >= boundaryX)
ballDirectionX = false;
if (ballRectangle.Y <= 0)
ballDirectionY = true;
else if (ballRectangle.Y >= boundaryY)
startGame = false;
if (ballDirectionX)
ballRectangle.X += BALL_SPEED;
else
ballRectangle.X -= BALL_SPEED;
if (ballDirectionY)
ballRectangle.Y += BALL_SPEED;
else
ballRectangle.Y -= BALL_SPEED;
else
ballRectangle.Location = new Point(platformRectangle.X + (platformRectangle.Width / 2) - 10, platformRectangle.Y - (ballRectangle.Height - 5));
public void ballCollision(Rectangle platform)
if (ballRectangle.Intersects(platform))
ballDirectionY = false;
public void enemyCollision(Rectangle enemyRectangle)
if (ballRectangle.Intersects(enemyRectangle))
ballDirectionY = false;
Enemy.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Text;
namespace TSA3
public class Enemy
public Texture2D enemyTexture;
public Rectangle enemyRectangle;
public Color enemyColor;
public bool isVisible = true;
Random random = new Random();
public Enemy(Texture2D enemyTexture, Rectangle enemyRectangle, Color enemyColor)
this.enemyTexture = enemyTexture;
this.enemyRectangle = enemyRectangle;
this.enemyColor = enemyColor;
public Texture2D EnemyTexture get => enemyTexture;
public Rectangle EnemyRectangle get => enemyRectangle;
public Color EnemyColor get => enemyColor;
Platform.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.Text;
namespace TSA3
public class Platform
Texture2D platformTexture;
Rectangle platformRectangle;
Color platformColor;
int boundaryX;
public const int PLATFORM_SPEED = 10;
public Platform(Texture2D platformTexture, Rectangle platformRectangle, Color platformColor, int boundaryX)
this.platformTexture = platformTexture;
this.platformRectangle = platformRectangle;
this.platformColor = platformColor;
this.boundaryX = boundaryX;
public Texture2D PlatformTexture get => platformTexture;
public Rectangle PlatformRectangle get => platformRectangle;
public Color PlatformColor get => platformColor;
public void platformMovement(Keys controls)
if (controls == Keys.A && platformRectangle.X > 0)
platformRectangle.X -= PLATFORM_SPEED;
if (controls == Keys.D && platformRectangle.X < boundaryX)
platformRectangle.X += PLATFORM_SPEED;
提前感谢任何愿意提供帮助的人!
【问题讨论】:
【参考方案1】:此方法缺少必要的代码来正常运行以从任何一侧接近块:
public void enemyCollision(Rectangle enemyRectangle)
if (ballRectangle.Intersects(enemyRectangle))
ballDirectionY = false;
目前它的工作原理与您的平台相同:在碰撞时将 Y 方向向上设置。 这对平台很有效,因为它很薄并且靠近屏幕边缘,因此不需要其他碰撞检查。
尝试改进此方法,类似于您对屏幕边缘的球碰撞所做的操作。
这里重要的是知道红色矩形角的位置,这样你就可以计算出球在哪个位置击中矩形。
据我所知,你不可能有确切的边界,但你可以通过计算角的位置来测量相同的边界。例如,您可以使用EnemyRectangle
并获取它们的 x/y 位置,即它的左上角,而不是您可以添加矩形的宽度,并且您将拥有右上角(同样适用于高度底角)。如果根据矩形角计算球的位置,您就会知道球在哪一侧与屏幕发生碰撞。
顶部碰撞示例:
public void enemyCollision(Rectangle enemyRectangle)
if (ballRectangle.Intersects(enemyRectangle))
if (ballRectangle.x > enemyRectangle.x &&
ballRectangle.x < enemyRectangle.x + enemyRectangle.Width &&
ballRectangle.y > enemyRectangle.y)
ballDirectionY = false;
【讨论】:
嗨。我尝试使用 ballRectangle.Right >enemyRectangle.Left 它确实发生了碰撞,但我的问题是它在我的屏幕的整个左侧而不是我的矩形上发生了碰撞。有什么办法可以得到我的矩形的确切边框? 这就是我所说的“知道红色矩形角的位置”。我已更新我的答案以添加有关矩形位置的更多信息。以上是关于我的球和我的矩形不会正确碰撞(Monogame)的主要内容,如果未能解决你的问题,请参考以下文章