卓球ゲームのパワーアップを続けていると、ほとんどの部分で正しく動作するようになりました (主に Jim Perry のおかげです)。 .
バットのサイズの呼び方と関係があると思います。私の Bat クラスには、バットのサイズを返すGetSize()という関数があります。
public Rectangle GetSize()
{
return size;
}
私は基本的に、ある関数でバットのサイズを 2 倍にし、別の関数で元のバットの半分のサイズにしようとしています。
public void GrowBat()
{
}
public void ShrinkBat()
{
}
以下のようなものを関数に挿入すると、コウモリの変化に気づきません。
public void GrowBat()
{
size = new Rectangle(0, 0, leftBat.Width * 2, leftBat.Height *2);
}
public void ShrinkBat()
{
size = new Rectangle(0, 0, leftBat.Width / 2, leftBat.Height / 2);
}
コウモリのサイズを返さないことに関係があると思います。皆さんはこれをどのように解決しますか?
わかりやすくするために、 BatクラスとGame1クラスを以下に含めました。特に、パワーアップ用の Game1 クラスの switch ステートメントの約半分を下に示します。
namespace Pong
{
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System;
public class Bat
{
public Vector2 position;
public float moveSpeed;
public Rectangle size;
private int points;
private int yHeight;
private Texture2D leftBat;
public float turbo;
public float recharge;
public float interval;
public bool isTurbo;
public Bat(ContentManager content, Vector2 screenSize, bool side)
{
moveSpeed = 7f;
turbo = 15f;
recharge = 100f;
points = 0;
interval = 5f;
leftBat = content.Load<Texture2D>(@"gfx/batGrey");
size = new Rectangle(0, 0, leftBat.Width, leftBat.Height);
if (side) position = new Vector2(30, screenSize.Y / 2 - size.Height / 2);
else position = new Vector2(screenSize.X - 30, screenSize.Y / 2 - size.Height / 2);
yHeight = (int)screenSize.Y;
}
public void IncreaseSpeed()
{
moveSpeed += .5f;
}
public void Turbo()
{
moveSpeed += 7.0f;
}
public void DisableTurbo()
{
moveSpeed = 7.0f;
isTurbo = false;
}
public Rectangle GetSize()
{
return size;
}
public void IncrementPoints()
{
points++;
}
public int GetPoints()
{
return points;
}
public void SetPosition(Vector2 position)
{
if (position.Y < 0)
{
position.Y = 0;
}
if (position.Y > yHeight - size.Height)
{
position.Y = yHeight - size.Height;
}
this.position = position;
}
public Vector2 GetPosition()
{
return position;
}
public void MoveUp()
{
SetPosition(position + new Vector2(0, -moveSpeed));
}
public void MoveDown()
{
SetPosition(position + new Vector2(0, moveSpeed));
}
public virtual void UpdatePosition(Ball ball)
{
size.X = (int)position.X;
size.Y = (int)position.Y;
}
public void ResetPosition()
{
SetPosition(new Vector2(GetPosition().X, yHeight / 2 - size.Height));
}
public void GrowBat()
{
}
public void ShrinkBat()
{
size = new Rectangle(0, 0, leftBat.Width / 2, leftBat.Height / 2);
}
public virtual void Draw(SpriteBatch batch)
{
batch.Draw(leftBat, position, Color.White);
}
}
}
namespace Pong
{
using System;
using System.Diagnostics; // There for debugging purposes right now
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Media;
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
public static GameStates gamestate;
private GraphicsDeviceManager graphics;
public int screenWidth;
public int screenHeight;
private Texture2D backgroundTexture;
private SpriteBatch spriteBatch;
private Menu menu;
private SpriteFont arial;
private HUD hud;
Animation player;
// Bats & Ball
public Bat rightBat;
public Bat leftBat;
public Ball ball;
// Scoring
private int resetTimer;
private bool resetTimerInUse;
public bool lastScored;
// All things having to do with the powerup
Powerup powerup;
SpriteFont font;
Vector2 vec;
Vector2 vec2;
Vector2 tickVec;
Vector2 activatedVec;
Vector2 deactivatedVec;
Vector2 promptVec;
Random random;
GamePadState lastState;
int tickCount;
bool powerupInitialized;
// Menus
private SoundEffect menuButton;
private SoundEffect menuClose;
public Song MainMenuSong { get; private set; }
public Song PlayingSong { get; private set; }
private Input input;
// For resetting the speed burst of the paddle
int coolDown = 0;
int disableCooldown = 0;
int powerEnableCooldown = 5000;
int powerDisableCooldown = 2000;
// Creates a new intance, which is used in the HUD class
public static Game1 Instance;
public enum GameStates
{
Menu,
Running,
Paused,
End
}
// Constructor (I'm a n00b, remember?)
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
// Creates an instance of the class, which is used in the HUD class
Instance = this;
}
protected override void Initialize()
{
screenWidth = 1280;
screenHeight = 720;
menu = new Menu();
gamestate = GameStates.Menu;
resetTimer = 0;
resetTimerInUse = true;
lastScored = false;
graphics.PreferredBackBufferWidth = screenWidth;
graphics.PreferredBackBufferHeight = screenHeight;
graphics.IsFullScreen = true;
graphics.ApplyChanges();
ball = new Ball(Content, new Vector2(screenWidth, screenHeight));
SetUpMulti();
input = new Input();
hud = new HUD();
// Places the powerup animation inside of the surrounding box
player = new Animation(Content.Load<Texture2D>(@"gfx/powerupSpriteSheet"), new Vector2(103, 44), 64, 64, 4, 5);
// Used by for the Powerups
random = new Random();
vec = new Vector2(100, 50);
vec2 = new Vector2(100, 100);
promptVec = new Vector2(50, 25);
powerupInitialized = false;
base.Initialize();
}
protected override void LoadContent()
{
arial = Content.Load<SpriteFont>("Arial"); // for game scores
spriteBatch = new SpriteBatch(GraphicsDevice);
backgroundTexture = Content.Load<Texture2D>(@"gfx/background");
hud.LoadContent(Content);
menuButton = Content.Load<SoundEffect>(@"sfx/menuButton");
menuClose = Content.Load<SoundEffect>(@"sfx/menuClose");
MainMenuSong = Content.Load<Song>(@"sfx/getWeapon");
PlayingSong = Content.Load<Song>(@"sfx/boomer");
MediaPlayer.IsRepeating = true;
// MediaPlayer.Play(MainMenuSong); // getWeapon music
font = Content.Load<SpriteFont>("Arial"); // Used by the Powerup
}
private void PowerupActivated(object sender, PowerupEventArgs e)
{
activatedVec = new Vector2(100, 125);
}
private void PowerupDeactivated(object sender, PowerupEventArgs e)
{
deactivatedVec = new Vector2(100, 150);
//do whatever - shrink ball, paddle, slow down ball
}
private void PowerupTick(object sender, PowerupEventArgs e)
{
tickVec = new Vector2(100, 175);
tickCount++;
//for powerup like Regen, add hp
}
// Sets up single player game
private void SetUpSingle()
{
rightBat = new AIBat(Content, new Vector2(screenWidth, screenHeight), false);
leftBat = new Bat(Content, new Vector2(screenWidth, screenHeight), true);
}
// Sets up 2 player game
private void SetUpMulti()
{
rightBat = new Bat(Content, new Vector2(screenWidth, screenHeight), false);
leftBat = new Bat(Content, new Vector2(screenWidth, screenHeight), true);
}
// Increases the speed of the bats slightly after each round
private void IncreaseSpeed()
{
ball.IncreaseSpeed();
leftBat.IncreaseSpeed();
rightBat.IncreaseSpeed();
}
protected override void Update(GameTime gameTime)
{
input.Update();
player.Update(gameTime);
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed ||
Keyboard.GetState().IsKeyDown(Keys.Escape))
this.Exit();
GamePadState state = GamePad.GetState(PlayerIndex.One);
if (state.Buttons.RightShoulder == ButtonState.Pressed && lastState.Buttons.RightShoulder == ButtonState.Released
|| Keyboard.GetState().IsKeyDown(Keys.LeftAlt))
{
//generate a random powerup
PowerupType type = (PowerupType)random.Next(Enum.GetNames(typeof(PowerupType)).Length);
switch (type)
{
case PowerupType.BigBalls:
{
powerup = new Powerup(type, 10.0f, 1.0f);
ball.ShrinkBall();
break;
}
case PowerupType.BigPaddle:
{
powerup = new Powerup(type, 10.0f, 10.0f);
leftBat.GrowBat();
break;
}
case PowerupType.ShrinkEnemy:
{
powerup = new Powerup(type, 10.0f, 10.0f);
rightBat.ShrinkBat();
break;
}
case PowerupType.SpeedBall:
{
powerup = new Powerup(type, 10.0f, 20.0f);
ball.IncreaseSpeed();
break;
}
case PowerupType.SplitWall:
case PowerupType.ThreeBurst:
case PowerupType.Heal:
{
powerup = new Powerup(type, 1.0f, 1.0f);
hud.AddHealthP1();
break;
}
case PowerupType.Regen:
{
powerup = new Powerup(type, 20.0f, 1.0f);
break;
}
}
powerupInitialized = false;
}
else if (state.Buttons.LeftShoulder == ButtonState.Pressed &&
lastState.Buttons.LeftShoulder == ButtonState.Released ||
Keyboard.GetState().IsKeyDown(Keys.LeftControl) && Keyboard.GetState().IsKeyUp(Keys.LeftControl))
{
powerup.Activate();
}
if (powerup != null && IsActive)
{
if (!powerupInitialized)
{
powerup.Activated += PowerupActivated;
powerup.Deactivated += PowerupDeactivated;
if (powerup.Type == PowerupType.Regen)
powerup.Tick += PowerupTick;
powerupInitialized = true;
}
powerup.Update((float)gameTime.ElapsedGameTime.TotalMilliseconds);
}
lastState = state;
// What to do when the game is over
if (gamestate == GameStates.Running)
{
if (hud.currentHealthP2 < 1)
{
menu.InfoText = "Game, blouses.";
gamestate = GameStates.End;
}
else if (hud.currentHealthP1 < 1)
{
menu.InfoText = "You just let the AI beat you.";
gamestate = GameStates.End;
}
if (resetTimerInUse)
{
resetTimer++;
ball.Stop();
}
if (resetTimer == 120)
{
resetTimerInUse = false;
ball.Reset(lastScored);
resetTimer = 0;
}
// Controls movement of the bats
if (rightBat.GetType() != typeof(Pong.AIBat))
{
if (input.LeftDown) leftBat.MoveDown();
else if ((input.LeftUp)) leftBat.MoveUp();
if (input.RightDown) rightBat.MoveDown();
else if (input.RightUp) rightBat.MoveUp();
}
else if (rightBat.GetType() == typeof(Pong.AIBat))
{
if (input.LeftDown) leftBat.MoveDown();
else if ((input.LeftUp)) leftBat.MoveUp();
if (input.RightDown) leftBat.MoveDown();
else if (input.RightUp) leftBat.MoveUp();
}
// Updating ball and bat position
leftBat.UpdatePosition(ball);
rightBat.UpdatePosition(ball);
ball.UpdatePosition();
// Checking for collision of the bats
if (ball.GetDirection() > 1.5f * Math.PI || ball.GetDirection() < 0.5f * Math.PI)
{
if (rightBat.GetSize().Intersects(ball.GetSize()))
{
ball.BatHit(CheckHitLocation(rightBat));
}
}
else if (leftBat.GetSize().Intersects(ball.GetSize()))
{
ball.BatHit(CheckHitLocation(leftBat));
}
// Triggers the turbo button and cooldown
if (input.SpaceDown)
{
if (disableCooldown > 0)
{
leftBat.isTurbo = true;
coolDown = powerEnableCooldown;
leftBat.moveSpeed = 40.0f;
disableCooldown -= gameTime.ElapsedGameTime.Milliseconds;
}
else
{
leftBat.DisableTurbo();
}
}
// If spacebar is not down, begin to refill the turbo bar
else if (!input.SpaceDown)
{
leftBat.DisableTurbo();
coolDown -= gameTime.ElapsedGameTime.Milliseconds;
if (coolDown < 0)
{
disableCooldown = powerDisableCooldown;
}
}
// Makes sure that if Turbo is on, it automatically turns of. Kills it after () seconds
if(leftBat.isTurbo)
disableCooldown -= gameTime.ElapsedGameTime.Milliseconds;
if(disableCooldown < 0)
{
leftBat.isTurbo = false;
}
if (!resetTimerInUse)
{ // checks out of bounds for right side
if (ball.GetPosition().X > screenWidth)
{
resetTimerInUse = true;
lastScored = true;
hud.SubtractHealthP2();
// Checks to see if ball went out of bounds, and triggers warp sfx
ball.OutOfBounds();
leftBat.IncrementPoints();
IncreaseSpeed();
} // Checks out of bounds for left side
else if (ball.GetPosition().X < 0)
{
resetTimerInUse = true;
lastScored = false;
hud.SubtractHealthP1();
// Checks to see if ball went out of bounds, and triggers warp sfx
ball.OutOfBounds();
rightBat.IncrementPoints();
IncreaseSpeed();
}
}
}
// Navigating through the menus
else if (gamestate == GameStates.Menu)
{
if (input.RightDown || input.LeftDown)
{
menu.Iterator++;
menuButton.Play();
}
else if (input.RightUp || input.LeftUp)
{
menu.Iterator--;
menuButton.Play();
}
if (input.MenuSelect)
{
if (menu.Iterator == 0)
{
gamestate = GameStates.Running;
SetUpSingle();
menuClose.Play();
}
else if (menu.Iterator == 1)
{
gamestate = GameStates.Running;
SetUpMulti();
menuClose.Play();
}
else if (menu.Iterator == 2)
{
this.Exit();
menuClose.Play();
}
menu.Iterator = 0;
}
}
else if (gamestate == GameStates.End)
{
if (input.MenuSelect)
{
gamestate = GameStates.Menu;
hud.ResetHealth();
}
}
// Updates the HUD
hud.Update(gameTime);
base.Update(gameTime);
}
// Checking for bat collision & instructs the ball where to deflect to
private int CheckHitLocation(Bat bat)
{
int block = 0;
if (ball.GetPosition().Y < bat.GetPosition().Y + bat.GetSize().Height / 20) block = 1;
else if (ball.GetPosition().Y < bat.GetPosition().Y + bat.GetSize().Height / 10 * 2) block = 2;
else if (ball.GetPosition().Y < bat.GetPosition().Y + bat.GetSize().Height / 10 * 3) block = 3;
else if (ball.GetPosition().Y < bat.GetPosition().Y + bat.GetSize().Height / 10 * 4) block = 4;
else if (ball.GetPosition().Y < bat.GetPosition().Y + bat.GetSize().Height / 10 * 5) block = 5;
else if (ball.GetPosition().Y < bat.GetPosition().Y + bat.GetSize().Height / 10 * 6) block = 6;
else if (ball.GetPosition().Y < bat.GetPosition().Y + bat.GetSize().Height / 10 * 7) block = 7;
else if (ball.GetPosition().Y < bat.GetPosition().Y + bat.GetSize().Height / 10 * 8) block = 8;
else if (ball.GetPosition().Y < bat.GetPosition().Y + bat.GetSize().Height / 20 * 19) block = 9;
else block = 10;
return block;
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
// TODO: Add your drawing code here
spriteBatch.Begin();
if (gamestate == GameStates.Running)
{
// Draws background
spriteBatch.Draw(backgroundTexture, new Rectangle(0, 0, screenWidth, screenHeight), Color.White);
player.Draw(spriteBatch);
// Draws the bats and ball
leftBat.Draw(spriteBatch);
rightBat.Draw(spriteBatch);
ball.Draw(spriteBatch);
// Draws the score on screen
spriteBatch.DrawString(arial, leftBat.GetPoints().ToString(), new Vector2(screenWidth / 4 - arial.MeasureString
(rightBat.GetPoints().ToString()).X, 20), Color.White);
spriteBatch.DrawString(arial, rightBat.GetPoints().ToString(), new Vector2(screenWidth / 4 * 3 - arial.MeasureString
(rightBat.GetPoints().ToString()).X, 20), Color.White);
}
// Only draws the menu
else if (gamestate == GameStates.Menu)
{
spriteBatch.Draw(backgroundTexture, new Rectangle(0, 0, screenWidth, screenHeight), Color.White);
menu.DrawMenu(spriteBatch, screenWidth, arial);
}
else if (gamestate == GameStates.End)
{
spriteBatch.Draw(backgroundTexture, new Rectangle(0, 0, screenWidth, screenHeight), Color.White);
menu.DrawEndScreen(spriteBatch, screenWidth, arial);
}
spriteBatch.End();
// Draws the HUD
if (gamestate == GameStates.Running)
{
hud.Draw(gameTime);
}
spriteBatch.Begin();
// Powerup text
if (gamestate == GameStates.Running)
{
spriteBatch.DrawString(font, "Press A or Left Alt button to generate powerup", promptVec, Color.White);
if (powerup != null)
{
spriteBatch.DrawString(font, "Powerup Type: " + powerup.Type, vec, Color.White);
spriteBatch.DrawString(font, "Press Left Bumper or Left Ctrl to activate powerup", vec2, Color.White);
}
if (deactivatedVec != Vector2.Zero)
spriteBatch.DrawString(font, "Powerup deactivated", deactivatedVec, Color.White);
if (activatedVec != Vector2.Zero)
spriteBatch.DrawString(font, "Powerup activated", activatedVec, Color.White);
if (tickVec != Vector2.Zero)
spriteBatch.DrawString(font, "Tick count: " + tickCount.ToString(), tickVec, Color.White);
}
spriteBatch.End();
base.Draw(gameTime);
}
}
}