I am making a game where characters come from opposite sides of the screen and collide and attack each other then they are removed when they die. I have managed to enable the lists to stop moving and do damage when they collide but my problem is when 2 of them collide all of them stop moving.
My code for the shortswordsman collisions is:
private void shortMoveCollisions(GameTime gameTime)
{
Rectangle shortRect;
int shortSpeed = 2;
int shortDamage = 20;
bool collided = false;
for (int i = 0; i < shortList.Count; i++)
{
List<Goblin> tempGoblinList = new List<Goblin>(goblinList);
shortRect = new Rectangle((int)shortList[i].position.X, (int)shortList[i].position.Y, ShortSwordsman.texture.Width / 4 - 20, ShortSwordsman.texture.Height);
foreach (Goblin goblin in tempGoblinList)
{
Rectangle goblinRect = new Rectangle((int)goblin.position.X, (int)goblin.position.Y, Goblin.texture.Width / 4 - 20, Goblin.texture.Height);
if (shortRect.Intersects(goblinRect))
{
collided = true;
shortList[i].AnimateAttack(gameTime);
shortTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (shortTimer >= shortDelay)
{
shortTimer -= shortDelay;
goblin.health -= shortDamage;
if (goblin.health <= 0)
{
goblinList.Remove(goblin);
}
}
}
}
if (shortRect.Intersects(background.badCastleRect))
{
collided = true;
shortList[i].AnimateAttack(gameTime);
shortTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (shortTimer >= shortDelay)
{
shortTimer -= shortDelay;
badCastleHealth -= shortDamage;
}
}
if (collided == false)
{
shortList[i].AnimateWalk(gameTime);
shortList[i].position.X += shortSpeed;
}
}
}
And my code for the goblins collisions is:
private void GoblinMoveCollisions(GameTime gameTime)
{
Rectangle goblinRect;
int goblinSpeed = 2;
int goblinDamage = 20;
bool collided = false;
for (int i = 0; i < goblinList.Count; i++)
{
List<ShortSwordsman> tempShortList = new List<ShortSwordsman>(shortList);
goblinRect = new Rectangle((int)goblinList[i].position.X, (int)goblinList[i].position.Y, Goblin.texture.Width / 4 - 20, Goblin.texture.Height);
foreach (ShortSwordsman shortSwordsman in tempShortList)
{
Rectangle shortRect = new Rectangle((int)shortSwordsman.position.X, (int)shortSwordsman.position.Y, ShortSwordsman.texture.Width / 4 - 20, ShortSwordsman.texture.Height);
if (goblinRect.Intersects(shortRect))
{
collided = true;
goblinList[i].AnimateAttack(gameTime);
goblinAttackTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (goblinAttackTimer >= goblinAttackDelay)
{
goblinAttackTimer -= goblinAttackDelay;
shortSwordsman.health -= goblinDamage;
if (shortSwordsman.health <= 0)
{
shortList.Remove(shortSwordsman);
}
}
}
}
if (goblinRect.Intersects(background.goodCastleRect))
{
collided = true;
goblinList[i].AnimateAttack(gameTime);
goblinAttackTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (goblinAttackTimer >= goblinAttackDelay)
{
goblinAttackTimer -= goblinAttackDelay;
goodCastleHealth -= goblinDamage;
}
}
if (collided == false)
{
goblinList[i].AnimateWalk(gameTime);
goblinList[i].position.X -= goblinSpeed;
}
}
}
Your collided bool shouldn't be a variable of those classes, as those classes seem to operate on the entire lists of all the entities. Instead the collision detection should happen on an entity by entity basis, basically: make the collided bool a property of goblins and swordsmen. This would mean that you'll have to check for intersections with other creatures of the same type as well, probably without an attack command.
This is the code I am using at the moment - shortswordsman and goblin are the same so i will only show one:
In the goblin class:
public Goblin(Vector2 position, float health, bool Collided, Rectangle goblinRect)
{
this.position = position;
this.health = health;
this.Collided = Collided;
this.goblinRect = goblinRect;
}
In the game1 class:
void CreateGoblin()
{
goblinList.Add(new Goblin(new Vector2(1900, 270), 100, false, new Rectangle()));
}
And then for the collisions i tried this - this includes the bit to try and stop them overlapping each other:
private void GoblinMoveCollisions(GameTime gameTime)
{
int goblinSpeed = 2;
int goblinDamage = 20;
for (int i = 0; i < goblinList.Count; i++)
{
goblinList[i].Collided = false;
goblinList[i].goblinRect = new Rectangle((int)goblinList[i].position.X, (int)goblinList[i].position.Y, Goblin.texture.Width / 4 - 20, Goblin.texture.Height);
List<ShortSwordsman> tempShortList = new List<ShortSwordsman>(shortList);
foreach (ShortSwordsman shortSwordsman in tempShortList)
{
Rectangle shortRect = new Rectangle((int)shortSwordsman.position.X, (int)shortSwordsman.position.Y, ShortSwordsman.texture.Width / 4 - 20, ShortSwordsman.texture.Height);
if (goblinList[i].goblinRect.Intersects(shortRect))
{
goblinList[i].Collided = true;
goblinList[i].AnimateAttack(gameTime);
goblinAttackTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (goblinAttackTimer >= goblinAttackDelay)
{
goblinAttackTimer -= goblinAttackDelay;
shortSwordsman.health -= goblinDamage;
if (shortSwordsman.health <= 0)
{
shortList.Remove(shortSwordsman);
}
}
}
}
if (goblinList[i].goblinRect.Intersects(background.goodCastleRect))
{
goblinList[i].Collided = true;
goblinList[i].AnimateAttack(gameTime);
goblinAttackTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (goblinAttackTimer >= goblinAttackDelay)
{
goblinAttackTimer -= goblinAttackDelay;
goodCastleHealth -= goblinDamage;
}
}
if (goblinList[i].goblinRect.Intersects(goblinList[i].goblinRect))
{
goblinList[i].Collided = true;
goblinList[i].AnimateStill(gameTime);
}
if (goblinList[i].Collided == false)
{
goblinList[i].AnimateWalk(gameTime);
goblinList[i].position.X -= goblinSpeed;
}
}
}
Related
This program is about driving fast and dodging the obstacles. I followed a couple of tutorials and managed to create an explosion class. Whenever a collision occurs, the explosion is meant to appear, but it doesn't.
There is no error, but I think the problem is in the Game1.cs. I created the following functions in the Game1.cs:
//list
List <Explosion> explosionList = new List<Explosion>();
//This is in the update method
foreach (Explosion ex in explosionList)
{
ex.Update(gameTime);
}
//This is a method called manage explosions
public void ManageExplosions()
{
for (int i = 0; i < explosionList.Count; i++)
{
if (explosionList[i].isVisible)
{
explosionList.RemoveAt(i);
i--;
}
}
}
//This is placed in the CheckCollision method
explosionList.Add(new Explosion(Content.Load<Texture2D>("Images/explosion3"), new Vector2(theHazard.Position.X, theHazard.Position.Y)));
Game1.cs
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 DriveFast
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
private Texture2D mCar;
private Texture2D mBackground;
private Texture2D mRoad;
private Texture2D mHazard;
private Texture2D hazardCrash;
private KeyboardState mPreviousKeyboardState;
private Vector2 mCarPosition = new Vector2(280, 440);
private int mMoveCarX = 160;
private int mVelocityY;
private double mNextHazardAppearsIn;
private int mCarsRemaining;
private int mHazardsPassed;
private int mIncreaseVelocity;
private double mExitCountDown = 10;
private int[] mRoadY = new int[2];
private List<Hazard> mHazards = new List<Hazard>();
private Random mRandom = new Random();
private SpriteFont mFont;
//video
List <Explosion> explosionList = new List<Explosion>();
private enum State
{
TitleScreen,
Running,
Crash,
GameOver,
Success
}
private State mCurrentState = State.TitleScreen;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreferredBackBufferHeight = 600;
graphics.PreferredBackBufferWidth = 800;
}
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);
mCar = Content.Load<Texture2D>("Images/Car");
mBackground = Content.Load<Texture2D>("Images/Background");
mRoad = Content.Load<Texture2D>("Images/Road");
mHazard = Content.Load<Texture2D>("Images/Hazard");
hazardCrash = Content.Load<Texture2D>("Images/hazardCrash");
mFont = Content.Load<SpriteFont>("MyFont");
}
protected override void UnloadContent()
{
}
protected void StartGame()
{
mRoadY[0] = 0;
mRoadY[1] = -1 * mRoad.Height;
mHazardsPassed = 0;
mCarsRemaining = 3;
mVelocityY = 3;
mNextHazardAppearsIn = 1.5;
mIncreaseVelocity = 5;
mHazards.Clear();
mCurrentState = State.Running;
}
protected override void Update(GameTime gameTime)
{
KeyboardState aCurrentKeyboardState = Keyboard.GetState();
//Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed ||
aCurrentKeyboardState.IsKeyDown(Keys.Escape) == true)
{
this.Exit();
}
switch (mCurrentState)
{
case State.TitleScreen:
case State.Success:
case State.GameOver:
{
ExitCountdown(gameTime);
if (aCurrentKeyboardState.IsKeyDown(Keys.Space) == true && mPreviousKeyboardState.IsKeyDown(Keys.Space) == false)
{
StartGame();
}
break;
}
case State.Running:
{
//If the user has pressed the Spacebar, then make the car switch lanes
if (aCurrentKeyboardState.IsKeyDown(Keys.Space) == true && mPreviousKeyboardState.IsKeyDown(Keys.Space) == false)
{
mCarPosition.X += mMoveCarX;
mMoveCarX *= -1;
}
ScrollRoad();
foreach (Hazard aHazard in mHazards)
{
if (CheckCollision(aHazard) == true)
{
//video
explosionList.Add(new Explosion(Content.Load<Texture2D>("Images/explosion3"), new Vector2(aHazard.Position.X, aHazard.Position.Y)));
break;
}
MoveHazard(aHazard);
}
UpdateHazards(gameTime);
break;
}
case State.Crash:
{
//If the user has pressed the Space key, then resume driving
if (aCurrentKeyboardState.IsKeyDown(Keys.Space) == true && mPreviousKeyboardState.IsKeyDown(Keys.Space) == false)
{
mHazards.Clear();
mCurrentState = State.Running;
}
break;
}
}
mPreviousKeyboardState = aCurrentKeyboardState;
//video
ManageExplosions();
//
base.Update(gameTime);
//video
foreach (Explosion ex in explosionList)
{
ex.Update(gameTime);
}
}
private void ScrollRoad()
{
//Move the scrolling Road
for (int aIndex = 0; aIndex < mRoadY.Length; aIndex++)
{
if (mRoadY[aIndex] >= this.window.ClientBounds.Height)
{
int aLastRoadIndex = aIndex;
for (int aCounter = 0; aCounter < mRoadY.Length; aCounter++)
{
if (mRoadY[aCounter] < mRoadY[aLastRoadIndex])
{
aLastRoadIndex = aCounter;
}
}
mRoadY[aIndex] = mRoadY[aLastRoadIndex] - mRoad.Height;
}
}
for (int aIndex = 0; aIndex < mRoadY.Length; aIndex++)
{
mRoadY[aIndex] += mVelocityY;
}
}
private void MoveHazard(Hazard theHazard)
{
theHazard.Position.Y += mVelocityY;
if (theHazard.Position.Y > graphics.GraphicsDevice.Viewport.Height && theHazard.Visible == true)
{
theHazard.Visible = false;
mHazardsPassed += 1;
if (mHazardsPassed >= 100)
{
mCurrentState = State.Success;
mExitCountDown = 10;
}
mIncreaseVelocity -= 1;
if (mIncreaseVelocity < 0)
{
mIncreaseVelocity = 5;
mVelocityY += 1;
}
}
}
private void UpdateHazards(GameTime theGameTime)
{
mNextHazardAppearsIn -= theGameTime.ElapsedGameTime.TotalSeconds;
if (mNextHazardAppearsIn < 0)
{
int aLowerBound = 24 - (mVelocityY * 2);
int aUpperBound = 30 - (mVelocityY * 2);
if (mVelocityY > 10)
{
aLowerBound = 6;
aUpperBound = 8;
}
mNextHazardAppearsIn = (double)mRandom.Next(aLowerBound, aUpperBound) / 10;
AddHazard();
}
}
private void AddHazard()
{
int aRoadPosition = mRandom.Next(1, 3);
int aPosition = 275;
if (aRoadPosition == 2)
{
aPosition = 440;
}
bool aAddNewHazard = true;
foreach (Hazard aHazard in mHazards)
{
if (aHazard.Visible == false)
{
aAddNewHazard = false;
aHazard.Visible = true;
aHazard.Position = new Vector2(aPosition, -mHazard.Height);
break;
}
}
if (aAddNewHazard == true)
{
//Add a hazard to the left side of the Road
Hazard aHazard = new Hazard();
aHazard.Position = new Vector2(aPosition, -mHazard.Height);
mHazards.Add(aHazard);
}
}
private bool CheckCollision(Hazard theHazard)
{
BoundingBox aHazardBox = new BoundingBox(new Vector3(theHazard.Position.X, theHazard.Position.Y, 0), new Vector3(theHazard.Position.X + (mHazard.Width * .4f), theHazard.Position.Y + ((mHazard.Height - 50) * .4f), 0));
BoundingBox aCarBox = new BoundingBox(new Vector3(mCarPosition.X, mCarPosition.Y, 0), new Vector3(mCarPosition.X + (mCar.Width * .2f), mCarPosition.Y + (mCar.Height * .2f), 0));
if (aHazardBox.Intersects(aCarBox) == true)
{
//video
explosionList.Add(new Explosion(Content.Load<Texture2D>("Images/explosion3"), new Vector2(theHazard.Position.X, theHazard.Position.Y)));
mCurrentState = State.Crash;
mCarsRemaining -= 1;
if (mCarsRemaining < 0)
{
mCurrentState = State.GameOver;
mExitCountDown = 10;
}
return true;
}
return false;
}
private void ExitCountdown(GameTime theGameTime)
{
mExitCountDown -= theGameTime.ElapsedGameTime.TotalSeconds;
if (mExitCountDown < 0)
{
this.Exit();
}
}
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(mBackground, new Rectangle(graphics.GraphicsDevice.Viewport.X, graphics.GraphicsDevice.Viewport.Y, graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height), Color.White);
foreach (Explosion ex in explosionList)
{
ex.Draw(spriteBatch);
}
switch (mCurrentState)
{
case State.TitleScreen:
{
//Draw the display text for the Title screen
DrawTextCentered("Drive and avoid the hazards!", 200);
DrawTextCentered("Press 'Space' to start", 260);
DrawTextCentered("Exit in " + ((int)mExitCountDown).ToString(), 475);
break;
}
default:
{
DrawRoad();
DrawHazards();
spriteBatch.Draw(mCar, mCarPosition, new Rectangle(0, 0, mCar.Width, mCar.Height), Color.White, 0, new Vector2(0, 0), 0.2f, SpriteEffects.None, 0);
spriteBatch.DrawString(mFont, "Cars:", new Vector2(28, 520), Color.Brown, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 0);
for (int aCounter = 0; aCounter < mCarsRemaining; aCounter++)
{
spriteBatch.Draw(mCar, new Vector2(25 + (30 * aCounter), 550), new Rectangle(0, 0, mCar.Width, mCar.Height), Color.White, 0, new Vector2(0, 0), 0.05f, SpriteEffects.None, 0);
}
spriteBatch.DrawString(mFont, "Hazards: " + mHazardsPassed.ToString(), new Vector2(5, 25), Color.Brown, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 0);
if (mCurrentState == State.Crash)
{
DrawTextDisplayArea();
DrawTextCentered("Crash!", 200);
DrawTextCentered("Press 'Space' to continue driving.", 260);
}
else if (mCurrentState == State.GameOver)
{
DrawTextDisplayArea();
DrawTextCentered("Game Over.", 200);
DrawTextCentered("Press 'Space' to re-try.", 260);
DrawTextCentered("Exit in " + ((int)mExitCountDown).ToString(), 400);
}
else if (mCurrentState == State.Success)
{
DrawTextDisplayArea();
DrawTextCentered("Well Done!", 200);
DrawTextCentered("Press 'Space' to play again.", 260);
DrawTextCentered("Exit in " + ((int)mExitCountDown).ToString(), 400);
}
break;
}
}
spriteBatch.End();
base.Draw(gameTime);
}
private void DrawRoad()
{
for (int aIndex = 0; aIndex < mRoadY.Length; aIndex++)
{
if (mRoadY[aIndex] > mRoad.Height * -1 && mRoadY[aIndex] <= this.window.ClientBounds.Height)
{
spriteBatch.Draw(mRoad, new Rectangle((int)((this.window.ClientBounds.Width - mRoad.Width) / 2 - 18), mRoadY[aIndex], mRoad.Width, mRoad.Height + 5), Color.White);
}
}
}
private void DrawHazards()
{
foreach (Hazard aHazard in mHazards)
{
if (aHazard.Visible == true)
{
spriteBatch.Draw(mHazard, aHazard.Position, new Rectangle(0, 0, mHazard.Width, mHazard.Height), Color.White, 0, new Vector2(0, 0), 0.4f, SpriteEffects.None, 0);
}
}
}
private void DrawTextDisplayArea()
{
int aPositionX = (int)((graphics.GraphicsDevice.Viewport.Width / 2) - (450 / 2));
spriteBatch.Draw(mBackground, new Rectangle(aPositionX, 75, 450, 400), Color.White);
}
private void DrawTextCentered(string theDisplayText, int thePositionY)
{
Vector2 aSize = mFont.MeasureString(theDisplayText);
int aPositionX = (int)((graphics.GraphicsDevice.Viewport.Width / 2) - (aSize.X / 2));
spriteBatch.DrawString(mFont, theDisplayText, new Vector2(aPositionX, thePositionY), Color.Beige, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 0);
spriteBatch.DrawString(mFont, theDisplayText, new Vector2(aPositionX + 1, thePositionY + 1), Color.Brown, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 0);
}
//video
//manage explosions
public void ManageExplosions()
{
for (int i = 0; i < explosionList.Count; i++)
{
if (explosionList[i].isVisible)
{
explosionList.RemoveAt(i);
i--;
}
}
}
}
}
Explosion.cs
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 DriveFast
{
public class Explosion
{
public Texture2D texture;
public Vector2 position;
public float timer;
public float interval;
public Vector2 origin;
public int currentFrame, spriteWidth, spriteHeight;
public Rectangle sourceRect;
public bool isVisible;
//Constructor
public Explosion(Texture2D newTexture, Vector2 newPosition)
{
position = newPosition;
texture = newTexture;
timer = 0;
interval = 20f;
currentFrame = 1;
spriteWidth = 128;
spriteHeight = 128;
isVisible = true;
}
//load content
public void LoadContent(ContentManager Content)
{
}
//update
public void Update(GameTime gameTime)
{
//increase
timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
if (timer > interval)
{
currentFrame++;
timer = 0f;
}
if (currentFrame == 17)
{
isVisible = false;
currentFrame = 0;
}
sourceRect = new Rectangle(currentFrame * spriteWidth, 0, spriteWidth, spriteHeight);
origin = new Vector2(sourceRect.Width / 2, sourceRect.Height / 2);
}
//draw
public void Draw(SpriteBatch spriteBatch)
{
if (isVisible == true)
{
spriteBatch.Draw(texture, position, sourceRect, Color.White, 0f, origin, 1.0f, SpriteEffects.None, 0);
}
}
}
}
Hazard.cs
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace DriveFast
{
class Hazard
{
public Vector2 Position;
public bool Visible = true;
public Hazard()
{
}
}
}
First of all you need to draw your Explosions after road, car, hazards etc. Replace next code as shown below:
DrawRoad();
DrawHazards();
spriteBatch.Draw(mCar, mCarPosition, new Rectangle(0, 0, mCar.Width, mCar.Height), Color.White, 0, new Vector2(0, 0), 0.2f, SpriteEffects.None, 0);
// place code here
foreach (Explosion ex in explosionList)
{
ex.Draw(spriteBatch);
}
//
Into manage explosion method make !isVisible instead of isVisible:
public void ManageExplosions()
{
for (int i = 0; i < explosionList.Count; i++)
{
if (!explosionList[i].isVisible)
{
explosionList.RemoveAt(i);
i--;
}
}
}
Remove line:
foreach (Hazard aHazard in mHazards)
{
if (CheckCollision(aHazard) == true)
{
//remove next line because it is duplicate of adding Explosion which is already added inside CheckCollision(Hazard) method
//explosionList.Add(new Explosion(Content.Load<Texture2D>("Images/explosion3"), new Vector2(aHazard.Position.X, aHazard.Position.Y)));
break;
}
MoveHazard(aHazard);
}
Change next variables:
spriteWidth = 71;//128;
spriteHeight = 100;//128;
sourceRect = new Rectangle(currentFrame * spriteWidth, 0, spriteWidth, spriteHeight);
//origin = new Vector2(sourceRect.Width / 2, sourceRect.Height / 2);
origin = new Vector2(-(sourceRect.Width / 4), 0);
Comment next code for testing:
if (mCurrentState == State.Crash)
{
//DrawTextDisplayArea();
//DrawTextCentered("Crash!", 200);
//DrawTextCentered("Press 'Space' to continue driving.", 260);
}
Currently I'm working on a project recreating a mario level, my issue is that when I do not hard code the bottomLimit (the floor, currently set to 400) Mario will eventually just fall through.
Another thing I can't quite figure out is how I can move my invisible block that creates the floor boundary to accomodate the flooring. The level chosen is the Fortress level of Super Mario Brothers 3, if that helps picture what I'm trying to do with it.
There are a couple .as files to my code, I will put my troublesome file in along with my collision code.
package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.ui.Keyboard;
import flash.events.KeyboardEvent;
import flash.media.Sound;
public class FortressMap extends MovieClip
{
private var _mario:SmallMario;
private var vx:Number = 0;
private var vy:Number = 0;
private var _ceiling:Array = new Array();
private var _floor:Array = new Array();
public const accy:Number = 0.20;
public const termv:Number = 15;
public var onGround:Boolean;
public var bottomLimit:Number;
public function FortressMap()
{
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
_mario = new SmallMario();
addChild(_mario);
_mario.x = 50;
_mario.y = 400;
//Creating the blocks for the floor
createFloor(16, 416);
//Creating the blocks for the ceiling
createCeiling(16, 352);
}
private function createFloor(xPos:Number, yPos:Number):void
{
var floor:Floor = new Floor();
addChild(floor);
floor.x = xPos;
floor.y = yPos;
floor.height = 16;
_floor.push(floor);
floor.visible = false;
}
private function createCeiling(xPos:Number, yPos:Number):void
{
var ceiling:Ceiling = new Ceiling();
addChild(ceiling);
ceiling.x = xPos;
ceiling.y = yPos;
ceiling.height = 16;
_ceiling.push(ceiling);
ceiling.visible = false;
}
private function addedToStageHandler(event:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
addEventListener(Event.ENTER_FRAME, frameHandler);
addEventListener(Event.REMOVED_FROM_STAGE, removeStageHandler);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
}
private function frameHandler(event:Event):void
{
_mario.x += vx;
_mario.y += vy;
if (_mario.x < 16)
{
_mario.x = 16;
}
vy += accy;
for (var i:int = 0; i < _ceiling.length; ++i)
{
Collision.block(_mario, _ceiling[i]);
}
for (var j:int = 0; j < _floor.length; ++j)
{
Collision.block(_mario, _floor[j]);
}
bottomLimit = 400;
if(_mario.y >= bottomLimit)
{
_mario.y = bottomLimit;
vy = 0;
onGround = true;
}
else
{
onGround = false;
}
}
private function keyDownHandler(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.LEFT)
{
vx = -5;
return;
}
if (event.keyCode == Keyboard.RIGHT)
{
vx = 5;
return;
}
if (event.keyCode == Keyboard.UP)
{
if(onGround == true)
{
vy = -5;
trace("My people need me!");
}
return;
}
if (event.keyCode == Keyboard.DOWN)
{
//vy = 5;
return;
}
}
private function keyUpHandler(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.RIGHT)
{
vx = 0;
return;
}
if (event.keyCode == Keyboard.UP || event.keyCode == Keyboard.DOWN)
{
//vy = 0;
return;
}
}
private function removeStageHandler(event:Event):void
{
removeEventListener(Event.ENTER_FRAME, frameHandler);
removeEventListener(Event.REMOVED_FROM_STAGE, removeStageHandler);
stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
stage.removeEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
}
}
package
{
import flash.display.Sprite;
public class Collision
{
static public var collisionSide:String = "";
public function Collision()
{
}
static public function block(r1:Sprite, r2:Sprite):Boolean
{
var isBlocked:Boolean;
//Calculate the distance vector
var vx:Number
= (r1.x + (r1.width / 2))
- (r2.x + (r2.width / 2));
var vy:Number
= (r1.y + (r1.height / 2))
- (r2.y + (r2.height / 2));
//Check whether vx
//is less than the combined half widths
if(Math.abs(vx) < r1.width / 2 + r2.width / 2)
{
//A collision might be occurring! Check
//whether vy is less than the combined half heights
if(Math.abs(vy) < r1.height / 2 + r2.height / 2)
{
//A collision has ocurred! This is good!
//Find out the size of the overlap on both the X and Y axes
var overlap_X:Number
= r1.width / 2
+ r2.width / 2
- Math.abs(vx);
var overlap_Y:Number
= r1.height / 2
+ r2.height / 2
- Math.abs(vy);
//The collision has occurred on the axis with the
//*smallest* amount of overlap. Let's figure out which
//axis that is
if(overlap_X >= overlap_Y)
{
//The collision is happening on the X axis
//But on which side? _v0's vy can tell us
if(vy > 0)
{
collisionSide = "Top";
//Move the rectangle out of the collision
r1.y = r1.y + overlap_Y;
//r1 is being blocked
isBlocked = true;
}
else
{
collisionSide = "Bottom";
//Move the rectangle out of the collision
r1.y = r1.y - overlap_Y;
//r1 is being blocked
isBlocked = true;
}
}
else
{
//The collision is happening on the Y axis
//But on which side? _v0's vx can tell us
if(vx > 0)
{
collisionSide = "Left";
//Move the rectangle out of the collision
r1.x = r1.x + overlap_X;
//r1 is being blocked
isBlocked = true;
}
else
{
collisionSide = "Right";
//Move the rectangle out of the collision
r1.x = r1.x - overlap_X;
//r1 is being blocked
isBlocked = true;
}
}
}
else
{
//No collision
collisionSide = "No collision";
//r1 is not being blocked
isBlocked = false;
}
}
else
{
//No collision
collisionSide = "No collision";
//r1 is not being blocked
isBlocked = false;
}
return isBlocked;
}
}
}
I think what you want to do is to set the bottomlimit, but not hardcode the number 400, correct?
I would do change your createFloor method:
private function createFloor(xPos:Number, yPos:Number):void
{
var floor:Floor = new Floor();
addChild(floor);
floor.x = xPos;
floor.y = yPos;
floor.height = 16;
_floor.push(floor);
floor.visible = false;
// set bottom limit here
bottomLimit = yPos;
}
... then you wouldnt need to set it to 400.
However, another option is to change your if statement:
if(_mario.y >= Floor(_floor[0]).y)
{
_mario.y = Floor(_floor[0]).y;
vy = 0;
onGround = true;
}
else
{
onGround = false;
}
... and then you can get rid of the bottomLimit variable completely
(assuming I understood your code, and that the floor tiles are always going to be at the bottomLimit)
I'm trying to draw a line from the player to a targets asteroid as a "Grapple" hook, i've found some examples for doing this in 2D in xna but my "Position" and "origin" vector2 seems to change depending on who and when they are used. In the case of the lines they appear to draw up and right of the position (roughly 100 pixels) in the opposite direction of the target and rotate about an origin somewhere to the left of the target as the player moves.
here is the player code including the grapple code and target assignment
namespace Sparatius.Sprites
{
public class PlayerSprite : BaseSprite
{
ControlInput controlInput;
Texture2D Grapple;
SpriteFont font;
bool LeftGrapple = false, RightGrapple = false;
int GrappleRange = 300;
Sprites.AsteroidSprite LeftTarget, RightTarget;
public BoundingSphere grappleHitBox
{
get { return new BoundingSphere(new Vector3(Position.X + Origin.X, Position.Y + Origin.Y, 0), GrappleRange); }
}
public float speed
{
get { return Speed; }
}
public PlayerSprite(Vector2 spriteLocal)
:base(spriteLocal)
{
this.Rotation = 0;
this.Speed = 0;
this.FrameCount = new Point(4, 2);
this.ColorTint = Color.White;
this.controlInput = new ControlInput();
}
public void LoadContent(ContentManager content)
{
Texture = content.Load<Texture2D>("Sprites/PinballSpin");
font = content.Load<SpriteFont>("Fonts/Font1");
Grapple = content.Load<Texture2D>("Sprites/Grapple");
FrameSize = new Point((int)Texture.Width / FrameCount.X, (int)Texture.Height / FrameCount.Y);
Origin = new Vector2(FrameSize.X / 2, FrameSize.Y / 2);
Animation = new Animation(Texture, FrameSize);
}
public override void Update(GameTime gameTime)
{
base.Update(gameTime);
controlInput.GetControlStates();
if (controlInput.JustPressed(Keys.W))
Speed += 2;
else if (controlInput.JustPressed(Keys.S))
Speed -= 2;
if (controlInput.IsHeld(Keys.A))
Rotation -= 0.05f;
if (controlInput.IsHeld(Keys.D))
Rotation += 0.05f;
if (LeftTarget != null)
{
LeftTarget.Distance = Vector2.Distance(Position, LeftTarget.Position);
if (LeftTarget.Distance > GrappleRange)
{
LeftTarget.isTarget = false;
LeftTarget = null;
}
if (controlInput.IsHeld(Keys.Q))
{
LeftGrapple = true;
}
else
LeftGrapple = false;
}
if (RightTarget != null)
{
RightTarget.Distance = Vector2.Distance(Position, RightTarget.Position);
if (RightTarget.Distance > GrappleRange)
{
RightTarget.isTarget = false;
RightTarget = null;
}
if (controlInput.IsHeld(Keys.E))
{
RightGrapple = true;
}
else
RightGrapple = false;
}
}
public override void Draw(SpriteBatch spriteBatch)
{
base.Draw(spriteBatch);
if (LeftGrapple)
{
float leftRotation = (float)Math.Atan2(LeftTarget.Position.Y - Position.Y, LeftTarget.Position.X - Position.X);
//spriteBatch.Draw(Texture, Position, null, ColorTint, leftRotation, Position, 1f, SpriteEffects.None, 0f);
spriteBatch.Draw(Grapple,
new Rectangle((int)Position.X, (int)Position.Y, 2, (int)LeftTarget.Distance),
null, Color.Blue, leftRotation, Position, SpriteEffects.None, 0f);
}
if (RightGrapple)
{
float rightRotation = (float)Math.Atan2(RightTarget.Position.Y - Position.Y, RightTarget.Position.X - Position.X);
//spriteBatch.Draw(Texture, Position, null, ColorTint, rightRotation, Position, 1f, SpriteEffects.None, 0f);
spriteBatch.Draw(Grapple,
new Rectangle((int)Position.X, (int)Position.Y, 2, (int)RightTarget.Distance),
null, Color.Blue, rightRotation, Position, SpriteEffects.None, 0f);
}
spriteBatch.DrawString(font, "Player Rotation: " + Rotation, Position, Color.Red);
spriteBatch.DrawString(font, "Player RoationDegree: " + (int)MathHelper.ToDegrees(Rotation), origin, Color.Blue);
}
public void GrappleCheck(AsteroidSprite target)
{
float targetTragectory = (float)Math.Atan2(Position.Y - target.Position.Y, Position.X - target.Position.X);
if ((targetTragectory < (rotation - (float)MathHelper.PiOver4)) && ((targetTragectory > (rotation - (float)MathHelper.Pi + (float)MathHelper.PiOver4))))
{
target.Distance = Vector2.Distance(Position, target.Position);
if (LeftTarget != null)
{
if (LeftTarget.Distance > target.Distance)
{
LeftTarget.isTarget = false;
LeftTarget = target;
LeftTarget.isTarget = true;
}
}
else
{
LeftTarget = target;
LeftTarget.isTarget = true;
}
}
if ((targetTragectory > (rotation + (float)MathHelper.PiOver4)) && ((targetTragectory < (rotation + (float)MathHelper.Pi - (float)MathHelper.PiOver4))))
{
target.Distance = Vector2.Distance(Position, target.Position);
if (RightTarget != null)
{
if (RightTarget.Distance > target.Distance)
{
RightTarget.isTarget = false;
RightTarget = target;
RightTarget.isTarget = true;
}
}
else
{
RightTarget = target;
RightTarget.isTarget = true;
}
}
}
}
}
any idea whats going wrong? cheers
public static void DrawLine(SpriteBatch spriteBatch, Vector2 begin, Vector2 end, Color color, int width = 1)
{
Rectangle r = new Rectangle((int)begin.X, (int)begin.Y, (int)(end - begin).Length()+width, width);
Vector2 v = Vector2.Normalize(begin - end);
float angle = (float)Math.Acos(Vector2.Dot(v, -Vector2.UnitX));
if (begin.Y > end.Y) angle = MathHelper.TwoPi - angle;
spriteBatch.Draw(Pixel, r, null, color, angle, Vector2.Zero, SpriteEffects.None, 0);
}
Pixel is just a 1x1 sprite
You can also use the this keyword to make a handy extension method.
Making a touch based platform game based in actionscript 3 using Gary Rosenzweig's game as a basis, all was going well until today, I've been trying to swap out floor objects etc without changing much of the actionscript at all and I have the following error.
ArgumentError: Error #2109: Frame label jump not found in scene jump.
at flash.display::MovieClip/gotoAndStop()
at PlatformGame/moveCharacter()[C:\Users\Michael\Desktop\platformGame\PlatformGame.as:418]
at PlatformGame/moveEnemies()[C:\Users\Michael\Desktop\platformGame\PlatformGame.as:314]
at PlatformGame/gameLoop()[C:\Users\Michael\Desktop\platformGame\PlatformGame.as:303]
This also seems to cause problems with collision detection.
The code is as follows. (not i have not changed the scene or label names from the originals but it still shows the error).
package {
import flash.display.*;
import flash.events.*;
import flash.text.*;
import flash.utils.getTimer;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
public class PlatformGame extends MovieClip {
// movement constants
static const gravity:Number = .004;
// screen constants
static const edgeDistance:Number = 100;
public var rightButton:SimpleButton;
// object arrays
private var fixedObjects:Array;
private var otherObjects:Array;
// hero and enemies
private var hero:Object;
private var enemies:Array;
// game state
private var playerObjects:Array;
private var gameScore:int;
private var gameMode:String = "start";
private var playerLives:int;
private var lastTime:Number = 0;
// start game
public function startPlatformGame() {
playerObjects = new Array();
gameScore = 0;
gameMode = "play";
playerLives = 3;
}
// start level
public function startGameLevel() {
// create characters
createHero();
addEnemies();
// examine level and note all objects
examineLevel();
// add listeners
this.addEventListener(Event.ENTER_FRAME,gameLoop);
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
gamelevel["rButton"].addEventListener(TouchEvent.TOUCH_BEGIN,touchRight);
gamelevel["rButton"].addEventListener(TouchEvent.TOUCH_END,touchRightReleased);
gamelevel["lButton"].addEventListener(TouchEvent.TOUCH_BEGIN,touchLeft);
gamelevel["lButton"].addEventListener(TouchEvent.TOUCH_END,touchLeftReleased);
gamelevel["jButton"].addEventListener(TouchEvent.TOUCH_BEGIN,jump);
gamelevel["jButton"].addEventListener(TouchEvent.TOUCH_END,jumpReleased);
trace("hi"+gamelevel["rButton"]);
// set game state
gameMode = "play";
addScore(0);
showLives();
}
// start level
public function startGameLevelHarder() {
// create characters
createHero();
addHardEnemies();
// examine level and note all objects
examineLevel();
// set game state
gameMode = "play";
addScore(0);
showLives();
}
// start level
public function startGameLevelHardest() {
// create characters
createHero();
addHardestEnemies();
// examine level and note all objects
examineLevel();
// set game state
gameMode = "play";
addScore(0);
showLives();
}
// creates the hero object and sets all properties
public function createHero() {
hero = new Object();
hero.mc = gamelevel.hero;
hero.dx = 0.0;
hero.dy = 0.0;
hero.inAir = false;
hero.direction = 0;
hero.animstate = "stand";
hero.walkAnimation = new Array(2,3,4,5,6,7,8);
hero.animstep = 0;
hero.jump = false;
hero.moveLeft = false;
hero.moveRight = false;
hero.jumpSpeed = .8;
hero.walkSpeed = .15;
hero.width = 15.0;
hero.height = 35.0;
hero.startx = hero.mc.x;
hero.starty = hero.mc.y;
}
// finds all enemies in the level and creates an object for each
public function addEnemies() {
enemies = new Array();
var i:int = 1;
while (true) {
if (gamelevel["enemy"+i] == null) break;
var enemy = new Object();
enemy.mc = gamelevel["enemy"+i];
enemy.dx = 0.0;
enemy.dy = 0.0;
enemy.inAir = false;
enemy.direction = 1;
enemy.animstate = "stand"
enemy.walkAnimation = new Array(2,3,4,5);
enemy.animstep = 0;
enemy.jump = false;
enemy.moveRight = true;
enemy.moveLeft = false;
enemy.jumpSpeed = 1.0;
enemy.walkSpeed = .08;
enemy.width = 30.0;
enemy.height = 30.0;
enemies.push(enemy);
i++;
}
}
// finds all enemies in the level and creates an object for each
public function addHardEnemies() {
enemies = new Array();
var i:int = 1;
while (true) {
if (gamelevel["enemy"+i] == null) break;
var enemy = new Object();
enemy.mc = gamelevel["enemy"+i];
enemy.dx = 0.0;
enemy.dy = 0.0;
enemy.inAir = false;
enemy.direction = 1;
enemy.animstate = "stand"
enemy.walkAnimation = new Array(2,3,4,5);
enemy.animstep = 0;
enemy.jump = false;
enemy.moveRight = true;
enemy.moveLeft = false;
enemy.jumpSpeed = 1.0;
enemy.walkSpeed = .15;
enemy.width = 56.0;
enemy.height = 80.0;
enemies.push(enemy);
i++;
}
}
// finds all enemies in the level and creates an object for each
public function addHardestEnemies() {
enemies = new Array();
var i:int = 1;
while (true) {
if (gamelevel["enemy"+i] == null) break;
var enemy = new Object();
enemy.mc = gamelevel["enemy"+i];
enemy.dx = 0.0;
enemy.dy = 0.0;
enemy.inAir = false;
enemy.direction = 1;
enemy.animstate = "stand"
enemy.walkAnimation = new Array(2,3,4,5);
enemy.animstep = 0;
enemy.jump = false;
enemy.moveRight = true;
enemy.moveLeft = false;
enemy.jumpSpeed = 1.0;
enemy.walkSpeed = .25;
enemy.width = 40.0;
enemy.height = 40.0;
enemies.push(enemy);
i++;
}
}
// look at all level children and note walls, floors and items
public function examineLevel() {
fixedObjects = new Array();
otherObjects = new Array();
for(var i:int=0;i<this.gamelevel.numChildren;i++) {
var mc = this.gamelevel.getChildAt(i);
// add floors and walls to fixedObjects
if ((mc is Floor) || (mc is Wall) || (mc is ground1) || (mc is wall1) || (mc is ledge1) || (mc is ledge2) || (mc is rock) ||(mc is rocktip)) {
var floorObject:Object = new Object();
floorObject.mc = mc;
floorObject.leftside = mc.x;
floorObject.rightside = mc.x+mc.width;
floorObject.topside = mc.y;
floorObject.bottomside = mc.y+mc.height;
fixedObjects.push(floorObject);
// add treasure, key and door to otherOjects
} else if ((mc is Treasure) || (mc is Key) || (mc is Door) || (mc is Chest)) {
otherObjects.push(mc);
}
}
}
// note key presses, set hero properties
public function touchRight(event:TouchEvent) {
trace("touchRight");
hero.moveRight = true;
}
public function touchRightReleased(event:TouchEvent) {
hero.moveRight = false;
}
public function touchLeft(event:TouchEvent) {
hero.moveLeft = true;
}
public function touchLeftReleased(event:TouchEvent) {
hero.moveLeft = false;
}
public function jump(event:TouchEvent) {
if (!hero.inAir) {
hero.jump = true;
}
}
public function jumpReleased(event:TouchEvent) {
if (!hero.inAir) {
hero.jump = false;
}
}
// note key presses, set hero properties
//public function keyDownFunction(event:KeyboardEvent) {
//if (gameMode != "play") return; // don't move until in play mode
//if (event.keyCode == 37) {
//hero.moveLeft = true;
//} else if (event.keyCode == 39) {
//hero.moveRight = true;
//} else if (event.keyCode == 32) {
//if (!hero.inAir) {
//hero.jump = true;
//}
//}
//}
//public function keyUpFunction(event:KeyboardEvent) {
//if (event.keyCode == 37) {
//hero.moveLeft = false;
//} else if (event.keyCode == 39) {
//hero.moveRight = false;
//}
//}
// perform all game tasks
public function gameLoop(event:Event) {
// get time differentce
if (lastTime == 0) lastTime = getTimer();
var timeDiff:int = getTimer()-lastTime;
lastTime += timeDiff;
// only perform tasks if in play mode
if (gameMode == "play") {
moveCharacter(hero,timeDiff);
moveEnemies(timeDiff);
checkCollisions();
scrollWithHero();
}
}
// loop through all enemies and move them
public function moveEnemies(timeDiff:int) {
for(var i:int=0;i<enemies.length;i++) {
// move
moveCharacter(enemies[i],timeDiff);
// if hit a wall, turn around
if (enemies[i].hitWallRight) {
enemies[i].moveLeft = true;
enemies[i].moveRight = false;
} else if (enemies[i].hitWallLeft) {
enemies[i].moveLeft = false;
enemies[i].moveRight = true;
}
}
}
// primary function for character movement
public function moveCharacter(char:Object,timeDiff:Number) {
if (timeDiff < 1) return;
// assume character pulled down by gravity
var verticalChange:Number = char.dy*timeDiff + timeDiff*gravity;
if (verticalChange > 15.0) verticalChange = 15.0;
char.dy += timeDiff*gravity;
// react to changes from key presses
var horizontalChange = 0;
var newAnimState:String = "stand";
var newDirection:int = char.direction;
if (char.moveLeft) {
// walk left
horizontalChange = -char.walkSpeed*timeDiff;
newAnimState = "walk";
newDirection = -1;
} else if (char.moveRight) {
// walk right
horizontalChange = char.walkSpeed*timeDiff;
newAnimState = "walk";
newDirection = 1;
}
if (char.jump) {
// start jump
char.jump = false;
char.dy = -char.jumpSpeed;
verticalChange = -char.jumpSpeed;
newAnimState = "jump";
}
// assume no wall hit, and hanging in air
char.hitWallRight = false;
char.hitWallLeft = false;
char.inAir = true;
// find new vertical position
var newY:Number = char.mc.y + verticalChange;
// loop through all fixed objects to see if character has landed
for(var i:int=0;i<fixedObjects.length;i++) {
if ((char.mc.x+char.width/2 > fixedObjects[i].leftside) && (char.mc.x-char.width/2 < fixedObjects[i].rightside)) {
if ((char.mc.y <= fixedObjects[i].topside) && (newY > fixedObjects[i].topside)) {
newY = fixedObjects[i].topside;
char.dy = 0;
char.inAir = false;
break;
}
}
}
// find new horizontal position
var newX:Number = char.mc.x + horizontalChange;
// loop through all objects to see if character has bumped into a wall
for(i=0;i<fixedObjects.length;i++) {
if ((newY > fixedObjects[i].topside) && (newY-char.height < fixedObjects[i].bottomside)) {
if ((char.mc.x-char.width/2 >= fixedObjects[i].rightside) && (newX-char.width/2 <= fixedObjects[i].rightside)) {
newX = fixedObjects[i].rightside+char.width/2;
char.hitWallLeft = true;
break;
}
if ((char.mc.x+char.width/2 <= fixedObjects[i].leftside) && (newX+char.width/2 >= fixedObjects[i].leftside)) {
newX = fixedObjects[i].leftside-char.width/2;
char.hitWallRight = true;
break;
}
}
}
// set position of character
char.mc.x = newX;
char.mc.y = newY;
// set animation state
if (char.inAir) {
newAnimState = "";
}
char.animstate = newAnimState;
// move along walk cycle
if (char.animstate == "walk") {
char.animstep += timeDiff/60;
if (char.animstep > char.walkAnimation.length) {
char.animstep = 0;
}
char.mc.gotoAndStop(char.walkAnimation[Math.floor(char.animstep)]);
// not walking, show stand or jump state
} else {
char.mc.gotoAndStop(char.animstate);
}
// changed directions
if (newDirection != char.direction) {
char.direction = newDirection;
char.mc.scaleX = char.direction*1.35;
}
}
// scroll to the right or left if needed
public function scrollWithHero() {
var stagePosition:Number = gamelevel.x+hero.mc.x;
var rightEdge:Number = stage.stageWidth-edgeDistance;
var leftEdge:Number = edgeDistance;
if (stagePosition > rightEdge) {
gamelevel.x -= (stagePosition-rightEdge);
gamelevel["rButton"].x += (stagePosition-rightEdge);
gamelevel["lButton"].x += (stagePosition-rightEdge);
gamelevel["jButton"].x += (stagePosition-rightEdge);
if (gamelevel.x < -(gamelevel.width-stage.stageWidth)) gamelevel.x = -(gamelevel.width-stage.stageWidth);
}
if (stagePosition < leftEdge) {
gamelevel.x += (leftEdge-stagePosition);
gamelevel["rButton"].x -= (leftEdge-stagePosition);
gamelevel["lButton"].x -= (leftEdge-stagePosition);
gamelevel["jButton"].x -= (leftEdge-stagePosition);
if (gamelevel.x > 0) gamelevel.x = 0;
}
}
// check collisions with enemies, items
public function checkCollisions() {
// enemies
for(var i:int=enemies.length-1;i>=0;i--) {
if (hero.mc.hitTestObject(enemies[i].mc)) {
// is the hero jumping down onto the enemy?
if (hero.inAir && (hero.dy > 0)) {
enemyDie(i);
} else {
heroDie();
}
}
}
// items
for(i=otherObjects.length-1;i>=0;i--) {
if (hero.mc.hitTestObject(otherObjects[i])) {
getObject(i);
}
}
}
// remove enemy
public function enemyDie(enemyNum:int) {
var pb:PointBurst = new PointBurst(gamelevel,"Got Em!",enemies[enemyNum].mc.x,enemies[enemyNum].mc.y-20);
gamelevel.removeChild(enemies[enemyNum].mc);
enemies.splice(enemyNum,1);
}
// enemy got player
public function heroDie() {
// show dialog box
var dialog:Dialog = new Dialog();
dialog.x = 175;
dialog.y = 100;
addChild(dialog);
if (playerLives == 0) {
gameMode = "gameover";
dialog.message.text = "Game Over!";
} else {
gameMode = "dead";
dialog.message.text = "He Got You!";
playerLives--;
}
hero.mc.gotoAndPlay("die");
}
// player collides with objects
public function getObject(objectNum:int) {
// award points for treasure
if (otherObjects[objectNum] is Treasure) {
var pb:PointBurst = new PointBurst(gamelevel,100,otherObjects[objectNum].x,otherObjects[objectNum].y);
gamelevel.removeChild(otherObjects[objectNum]);
otherObjects.splice(objectNum,1);
addScore(100);
// got the key, add to inventory
} else if (otherObjects[objectNum] is Key) {
pb = new PointBurst(gamelevel,"Got Key!" ,otherObjects[objectNum].x,otherObjects[objectNum].y);
playerObjects.push("Key");
gamelevel.removeChild(otherObjects[objectNum]);
otherObjects.splice(objectNum,1);
// hit the door, end level if hero has the key
} else if (otherObjects[objectNum] is Door) {
if (playerObjects.indexOf("Key") == -1) return;
if (otherObjects[objectNum].currentFrame == 1) {
otherObjects[objectNum].gotoAndPlay("open");
levelComplete();
}
// got the chest, game won
} else if (otherObjects[objectNum] is Chest) {
otherObjects[objectNum].gotoAndStop("open");
gameComplete();
}
}
// add points to score
public function addScore(numPoints:int) {
gameScore += numPoints;
scoreDisplay.text = String(gameScore);
}
// update player lives
public function showLives() {
livesDisplay.text = String(playerLives);
}
// level over, bring up dialog
public function levelComplete() {
gameMode = "done";
var dialog:Dialog = new Dialog();
dialog.x = 175;
dialog.y = 100;
addChild(dialog);
dialog.message.text = "Level Complete!";
}
// game over, bring up dialog
public function gameComplete() {
gameMode = "gameover";
var dialog:Dialog = new Dialog();
dialog.x = 175;
dialog.y = 100;
addChild(dialog);
dialog.message.text = "You Got the Treasure!";
}
// dialog button clicked
public function clickDialogButton(event:MouseEvent) {
removeChild(MovieClip(event.currentTarget.parent));
// new life, restart, or go to next level
if (gameMode == "dead") {
// reset hero
showLives();
hero.mc.x = hero.startx;
hero.mc.y = hero.starty;
gameMode = "play";
} else if (gameMode == "gameover") {
cleanUp();
gotoAndStop("start");
} else if (gameMode == "done") {
cleanUp();
nextFrame();
}
// give stage back the keyboard focus
stage.focus = stage;
}
// clean up game
public function cleanUp() {
removeChild(gamelevel);
this.removeEventListener(Event.ENTER_FRAME,gameLoop);
}
}
}
The error is with the following line and is occurring because the referenced MovieClip does not have a frame labelled "jump":
char.mc.gotoAndStop(char.animstate);
My guess is that you made a change to the MovieClip which contains your character and, in doing so, removed the label which the code above references.
Here is my navigationMovement():
protected boolean navigationMovement(int dx, int dy, int status, int time) {
int focusIndex = getFieldWithFocusIndex();
while (dy > 0) {
if (focusIndex >= getFieldCount()) {
return false;
} else {
Field f = getField(focusIndex);
if (f.isFocusable()) {
f.setFocus();
dy--;
}
}
}
while (dy < 0) {
if (focusIndex < 0) {
return false;
} else {
Field f = getField(focusIndex);
if (f.isFocusable()) {
f.setFocus();
dy++;
}
}
}
while (dx > 0) {
focusIndex++;
if (focusIndex >= getFieldCount()) {
return false;
} else {
Field f = getField(focusIndex);
if (f.isFocusable()) {
f.setFocus();
dx--;
}
}
}
while (dx < 0) {
focusIndex--;
if (focusIndex < 0) {
return false;
} else {
Field f = getField(focusIndex);
if (f.isFocusable()) {
f.setFocus();
dx++;
}
}
}
return true;
}
This only allows the track wheel to scroll left and right, but I want up, down, left and right.
my layout is this.
It is a 3 rows x 4 columns.
This code is checking getField(0->10), that's why it cannot from 0 to 4.
I want it to be movable in all directions. How to implement that?
Updated
protected void sublayout(int width, int height) {
int y = 0;
Field[] fields = new Field[columnWidths.length];
int currentColumn = 0;
int rowHeight = 0;
for (int i = 0; i < getFieldCount(); i++) {
fields[currentColumn] = getField(i);
fields[currentColumn]
.setChangeListener(new FieldChangeListener() {
public void fieldChanged(Field field, int context) {
final int focusIndex = getFieldWithFocusIndex();
if (focusIndex == position) {
Main.getUiApplication().popScreen(
mainscreen);
} else {
Main.getUiApplication().popScreen(
mainscreen);
Main.getUiApplication().pushScreen(
new Custom_LoadingScreen(1));
Main.getUiApplication().invokeLater(
new Runnable() {
public void run() {
if (focusIndex == 0)
Main.getUiApplication()
.pushScreen(
new Main_AllLatestNews());
else
Main.getUiApplication()
.pushScreen(
new Main_ParticularCategoryAllNews(
catnewsid[focusIndex],
focusIndex,
cattitle[focusIndex]));
}
}, 1 * 1000, false);
}
}
});
layoutChild(fields[currentColumn], columnWidths[currentColumn],
height - y);
if (fields[currentColumn].getHeight() > rowHeight) {
rowHeight = fields[currentColumn].getHeight() + 10;
}
currentColumn++;
if ((currentColumn == columnWidths.length)
|| (i == (getFieldCount() - 1))) {
int x = 0;
if (this.allRowHeight >= 0) {
rowHeight = this.allRowHeight;
}
for (int c = 0; c < currentColumn; c++) {
long fieldStyle = fields[c].getStyle();
int fieldXOffset = 0;
long fieldHalign = fieldStyle & Field.FIELD_HALIGN_MASK;
if (fieldHalign == Field.FIELD_RIGHT) {
fieldXOffset = columnWidths[c]
- fields[c].getWidth();
} else if (fieldHalign == Field.FIELD_HCENTER) {
fieldXOffset = (columnWidths[c] - fields[c]
.getWidth()) / 2;
}
int fieldYOffset = 0;
long fieldValign = fieldStyle & Field.FIELD_VALIGN_MASK;
if (fieldValign == Field.FIELD_BOTTOM) {
fieldYOffset = rowHeight - fields[c].getHeight();
} else if (fieldValign == Field.FIELD_VCENTER) {
fieldYOffset = (rowHeight - fields[c].getHeight()) / 2;
}
setPositionChild(fields[c], x + fieldXOffset, y
+ fieldYOffset);
x += columnWidths[c];
}
currentColumn = 0;
y += rowHeight;
}
if (y >= height) {
break;
}
}
int totalWidth = 0;
for (int i = 0; i < columnWidths.length; i++) {
totalWidth += columnWidths[i];
}
if (position > -1) {
Field f = getField(position);
f.setFocus();
}
setExtent(totalWidth, Math.min(y, height));
}
}
The issue with your code that you treat dx and dy in the same way. You need to calculate next previous index differently depends on if it's horizontal scroll or vertical.
Btw, what manager do you use? FlowFieldManager? Because I think it's should work as expected in default navigationMovement implementation.
navigationMovement default will provide focus on all focusable components.
It only matters what layout you have used & how did you arrange these managers. You have row, column wise structure, so if you used horizonal manager for a row, it's elements will get focus & after completing all elements, focus will be down to the second horizontal manager.
I just find the solution which is each move +/- column size
while (dy > 0) {
if (focusIndex + columnwidth.length >= getFieldCount()) {
return false;
} else {
Field f = getField(focusIndex + columnwidth.length);
if (f.isFocusable()) {
f.setFocus();
dy--;
}
}
}
while (dy < 0) {
if (focusIndex - columnwidth.length < 0) {
return false;
} else {
Field f = getField(focusIndex - columnwidth.length);
if (f.isFocusable()) {
f.setFocus();
dy++;
}
}
}