iOS MFI controller connection issue - ios

i have this code that is a Plugin for Unreal Engine 4 is to allow MFI game controllers (Physical Bluetooth Gamepad, Joystick) to be used in my game on iOS devices
the plugin works fine if the game (App) is launched before connecting the controller
the problem is if the game controller is connected before launching the game the game crashes after the splash screen
also disconnecting the controller whilst the game is running closes/crashes the game
any advice is much appreciated
#include "IOSInputInterfacePrivatePCH.h"
#include "IInputInterface.h"
#include "IOSGamepad.h"
/** Beginning of FGCControllerNotificationHandler class */
#if PLATFORM_IOS
#interface FGCControllerNotificationHandler : NSObject
#property FIOSGamepad* device;
+ (id)sharedInstance;
#end
#implementation FGCControllerNotificationHandler
#synthesize device;
- (id)init
{
self = [super init];
return self;
}
+ (id)alloc
{
return [super allocWithZone:NULL];
}
+ (id)allocWithZone:(NSZone *)zone {
return [[self sharedInstance] retain];
}
- (id)copyWithZone:(NSZone *)zone {
return self;
}
- (id)retain {
return self;
}
- (NSUInteger)retainCount {
return NSUIntegerMax; /** denotes an object that cannot be released */
}
- (oneway void)release {
/** never release */
}
- (id)autorelease {
return self;
}
- (void)dealloc {
[super dealloc];
}
+ (FGCControllerNotificationHandler *)sharedInstance
{
static FGCControllerNotificationHandler* instance;
#synchronized(self)
{
if (instance == nil)
{
instance = [[self alloc] init];
}
}
return instance;
}
- (void)registerObservers:(FIOSGamepad *)inDevice
{
self.device = inDevice;
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
/** Assign controller when connected */
[center addObserver:self
selector:#selector(setupControllers)
name:GCControllerDidConnectNotification
object:nil];
/** Do something after controller disconnection */
[center addObserver:self
selector:#selector(cleanControllers)
name:GCControllerDidDisconnectNotification
object:nil];
/** Search for another controller */
[GCController startWirelessControllerDiscoveryWithCompletionHandler:nil];
/** Assign controller id for known controllers */
if ([[GCController controllers] count] > 0)
{
[self setupControllers];
}
}
- (void)setupControllers
{
if(device != nil)
{
self.device->OnControllerConnected();
}
}
- (void)cleanControllers
{
if(device != nil)
{
self.device->OnControllerDisconnected();
}
}
- (int32)getControllerCount
{
return (int32)[[GCController controllers] count];
}
- (TArray<GCController *>)getConnectedControllers
{
TArray<GCController *> availableControllers;
for (GCController* c in [GCController controllers])
{
availableControllers.Add(c);
}
return availableControllers;
}
#end
#endif
/** End of FGCControllerNotificationHandler class */
/** Beginning of FIOSGamepad class */
FIOSGamepad::FIOSGamepad(const TSharedRef<FGenericApplicationMessageHandler>& InMessageHandler) :
MessageHandler(InMessageHandler)
{
#if PLATFORM_IOS
/** In the engine, all controllers map to xbox controllers for consistency */
IOSToXboxControllerMapping[0] = 0; // FaceButtonBottom
IOSToXboxControllerMapping[1] = 1; // FaceButtonRight
IOSToXboxControllerMapping[2] = 2; // FaceButtonLeft
IOSToXboxControllerMapping[3] = 3; // FaceButtonTop
IOSToXboxControllerMapping[4] = 4; // L1
IOSToXboxControllerMapping[5] = 5; // R1
IOSToXboxControllerMapping[6] = 6; // None
IOSToXboxControllerMapping[7] = 7; // None
IOSToXboxControllerMapping[8] = 8; // None
IOSToXboxControllerMapping[9] = 9; // None
IOSToXboxControllerMapping[10] = 10; // L2
IOSToXboxControllerMapping[11] = 11; // R2
IOSToXboxControllerMapping[12] = 12; // Dpad up
IOSToXboxControllerMapping[13] = 13; // Dpad down
IOSToXboxControllerMapping[14] = 14; // Dpad left
IOSToXboxControllerMapping[15] = 15; // Dpad right
IOSToXboxControllerMapping[16] = 16; // Left stick up
IOSToXboxControllerMapping[17] = 17; // Left stick down
IOSToXboxControllerMapping[18] = 18; // Left stick left
IOSToXboxControllerMapping[19] = 19; // Left stick right
IOSToXboxControllerMapping[20] = 20; // Right stick up
IOSToXboxControllerMapping[21] = 21; // Right stick down
IOSToXboxControllerMapping[22] = 22; // Right stick left
IOSToXboxControllerMapping[23] = 23; // Right stick right
Buttons[0] = FGamepadKeyNames::FaceButtonBottom;
Buttons[1] = FGamepadKeyNames::FaceButtonRight;
Buttons[2] = FGamepadKeyNames::FaceButtonLeft;
Buttons[3] = FGamepadKeyNames::FaceButtonTop;
Buttons[4] = FGamepadKeyNames::LeftShoulder;
Buttons[5] = FGamepadKeyNames::RightShoulder;
Buttons[6] = FGamepadKeyNames::SpecialRight;
Buttons[7] = FGamepadKeyNames::SpecialLeft;
Buttons[8] = FGamepadKeyNames::LeftThumb;
Buttons[9] = FGamepadKeyNames::RightThumb;
Buttons[10] = FGamepadKeyNames::LeftTriggerThreshold;
Buttons[11] = FGamepadKeyNames::RightTriggerThreshold;
Buttons[12] = FGamepadKeyNames::DPadUp;
Buttons[13] = FGamepadKeyNames::DPadDown;
Buttons[14] = FGamepadKeyNames::DPadLeft;
Buttons[15] = FGamepadKeyNames::DPadRight;
Buttons[16] = FGamepadKeyNames::LeftStickUp;
Buttons[17] = FGamepadKeyNames::LeftStickDown;
Buttons[18] = FGamepadKeyNames::LeftStickLeft;
Buttons[19] = FGamepadKeyNames::LeftStickRight;
Buttons[20] = FGamepadKeyNames::RightStickUp;
Buttons[21] = FGamepadKeyNames::RightStickDown;
Buttons[22] = FGamepadKeyNames::RightStickLeft;
Buttons[23] = FGamepadKeyNames::RightStickRight;
bNeedsControllerStateUpdate = true;
InitialButtonRepeatDelay = 0.2f;
ButtonRepeatDelay = 0.1f;
/** Initialize ControllerStates */
for (int32 ControllerIndex=0; ControllerIndex < MAX_NUM_IOS_CONTROLLERS; ++ControllerIndex)
{
FControllerState& ControllerState = ControllerStates[ControllerIndex];
FMemory::Memzero(&ControllerState, sizeof(FControllerState));
ControllerState.ControllerId = ControllerIndex;
}
[[FGCControllerNotificationHandler sharedInstance] registerObservers:this];
#endif
}
FIOSGamepad::~FIOSGamepad()
{
}
void FIOSGamepad::Tick(float DeltaTime)
{
}
void FIOSGamepad::SendControllerEvents()
{
#if PLATFORM_IOS
for (int32 ControllerIndex=0; ControllerIndex < MAX_NUM_IOS_CONTROLLERS; ++ControllerIndex)
{
FControllerState& ControllerState = ControllerStates[ControllerIndex];
if (!ControllerState.bIsConnected && bNeedsControllerStateUpdate)
{
ControllerState.bIsConnected = (ControllerIndex < ((int32) [[GCController controllers] count]));
}
if (ControllerState.bIsConnected)
{
bool CurrentStates[MAX_NUM_IOS_CONTROLLER_BUTTONS] = {0};
GCController* Controller = [GCController controllers][ControllerIndex];
if (Controller.extendedGamepad != nil)
{
GCExtendedGamepad* ExGamepad = Controller.extendedGamepad;
/** Check Analog state */
if(ControllerState.LeftXAnalog != ExGamepad.leftThumbstick.xAxis.value)
{
MessageHandler->OnControllerAnalog(FGamepadKeyNames::LeftAnalogX, ControllerState.ControllerId, ExGamepad.leftThumbstick.xAxis.value);
ControllerState.LeftXAnalog = ExGamepad.leftThumbstick.xAxis.value;
}
if(ControllerState.LeftYAnalog != ExGamepad.leftThumbstick.yAxis.value)
{
MessageHandler->OnControllerAnalog(FGamepadKeyNames::LeftAnalogY, ControllerState.ControllerId, ExGamepad.leftThumbstick.yAxis.value);
ControllerState.LeftYAnalog = ExGamepad.leftThumbstick.yAxis.value;
}
if(ControllerState.RightXAnalog != ExGamepad.rightThumbstick.xAxis.value)
{
MessageHandler->OnControllerAnalog(FGamepadKeyNames::RightAnalogX, ControllerState.ControllerId, ExGamepad.rightThumbstick.xAxis.value);
ControllerState.RightXAnalog = ExGamepad.rightThumbstick.xAxis.value;
}
if(ControllerState.RightYAnalog != ExGamepad.rightThumbstick.yAxis.value)
{
MessageHandler->OnControllerAnalog(FGamepadKeyNames::RightAnalogY, ControllerState.ControllerId, ExGamepad.rightThumbstick.yAxis.value);
ControllerState.RightYAnalog = ExGamepad.rightThumbstick.yAxis.value;
}
if(ControllerState.LeftTriggerAnalog != ExGamepad.leftTrigger.value)
{
MessageHandler->OnControllerAnalog(FGamepadKeyNames::LeftTriggerAnalog, ControllerState.ControllerId, ExGamepad.leftTrigger.value);
ControllerState.LeftTriggerAnalog = ExGamepad.leftTrigger.value;
}
if(ControllerState.RightTriggerAnalog != ExGamepad.rightTrigger.value)
{
MessageHandler->OnControllerAnalog(FGamepadKeyNames::RightTriggerAnalog, ControllerState.ControllerId, ExGamepad.rightTrigger.value);
ControllerState.RightTriggerAnalog = ExGamepad.rightTrigger.value;
}
/** Get the current state of all buttons */
CurrentStates[IOSToXboxControllerMapping[0]] = ExGamepad.buttonA.pressed;
CurrentStates[IOSToXboxControllerMapping[1]] = ExGamepad.buttonB.pressed;
CurrentStates[IOSToXboxControllerMapping[2]] = ExGamepad.buttonX.pressed;
CurrentStates[IOSToXboxControllerMapping[3]] = ExGamepad.buttonY.pressed;
CurrentStates[IOSToXboxControllerMapping[4]] = ExGamepad.leftShoulder.pressed;
CurrentStates[IOSToXboxControllerMapping[5]] = ExGamepad.rightShoulder.pressed;
CurrentStates[IOSToXboxControllerMapping[6]] = false;
CurrentStates[IOSToXboxControllerMapping[7]] = false;
CurrentStates[IOSToXboxControllerMapping[8]] = false;
CurrentStates[IOSToXboxControllerMapping[9]] = false;
CurrentStates[IOSToXboxControllerMapping[10]] = ExGamepad.leftTrigger.value > IOS_TRIGGER_THRESHOLD;
CurrentStates[IOSToXboxControllerMapping[11]] = ExGamepad.rightTrigger.value > IOS_TRIGGER_THRESHOLD;
CurrentStates[IOSToXboxControllerMapping[12]] = ExGamepad.dpad.up.pressed;
CurrentStates[IOSToXboxControllerMapping[13]] = ExGamepad.dpad.down.pressed;
CurrentStates[IOSToXboxControllerMapping[14]] = ExGamepad.dpad.left.pressed;
CurrentStates[IOSToXboxControllerMapping[15]] = ExGamepad.dpad.right.pressed;
CurrentStates[IOSToXboxControllerMapping[16]] = ExGamepad.leftThumbstick.up;
CurrentStates[IOSToXboxControllerMapping[17]] = ExGamepad.leftThumbstick.down;
CurrentStates[IOSToXboxControllerMapping[18]] = ExGamepad.leftThumbstick.left;
CurrentStates[IOSToXboxControllerMapping[19]] = ExGamepad.leftThumbstick.right;
CurrentStates[IOSToXboxControllerMapping[20]] = ExGamepad.rightThumbstick.up;
CurrentStates[IOSToXboxControllerMapping[21]] = ExGamepad.rightThumbstick.down;
CurrentStates[IOSToXboxControllerMapping[22]] = ExGamepad.rightThumbstick.left;
CurrentStates[IOSToXboxControllerMapping[23]] = ExGamepad.rightThumbstick.right;
}
else if (Controller.gamepad != nil)
{
GCGamepad* Gamepad = Controller.gamepad;
/** Get the current state of all buttons */
CurrentStates[IOSToXboxControllerMapping[0]] = Gamepad.buttonA.pressed;
CurrentStates[IOSToXboxControllerMapping[1]] = Gamepad.buttonB.pressed;
CurrentStates[IOSToXboxControllerMapping[2]] = Gamepad.buttonX.pressed;
CurrentStates[IOSToXboxControllerMapping[3]] = Gamepad.buttonY.pressed;
CurrentStates[IOSToXboxControllerMapping[4]] = Gamepad.leftShoulder.pressed;
CurrentStates[IOSToXboxControllerMapping[5]] = Gamepad.rightShoulder.pressed;
CurrentStates[IOSToXboxControllerMapping[6]] = false;
CurrentStates[IOSToXboxControllerMapping[7]] = false;
CurrentStates[IOSToXboxControllerMapping[8]] = false;
CurrentStates[IOSToXboxControllerMapping[9]] = false;
CurrentStates[IOSToXboxControllerMapping[10]] = false;
CurrentStates[IOSToXboxControllerMapping[11]] = false;
CurrentStates[IOSToXboxControllerMapping[12]] = Gamepad.dpad.up.pressed;
CurrentStates[IOSToXboxControllerMapping[13]] = Gamepad.dpad.down.pressed;
CurrentStates[IOSToXboxControllerMapping[14]] = Gamepad.dpad.left.pressed;
CurrentStates[IOSToXboxControllerMapping[15]] = Gamepad.dpad.right.pressed;
CurrentStates[IOSToXboxControllerMapping[16]] = false;
CurrentStates[IOSToXboxControllerMapping[17]] = false;
CurrentStates[IOSToXboxControllerMapping[18]] = false;
CurrentStates[IOSToXboxControllerMapping[19]] = false;
CurrentStates[IOSToXboxControllerMapping[20]] = false;
CurrentStates[IOSToXboxControllerMapping[21]] = false;
CurrentStates[IOSToXboxControllerMapping[22]] = false;
CurrentStates[IOSToXboxControllerMapping[23]] = false;
}
const double CurrentTime = FPlatformTime::Seconds();
/** For each button check against the previous state and send the correct message if any */
for (int32 ButtonIndex = 0; ButtonIndex < MAX_NUM_IOS_CONTROLLER_BUTTONS; ++ButtonIndex)
{
if(CurrentStates[ButtonIndex] != ControllerState.ButtonStates[ButtonIndex])
{
if(CurrentStates[ButtonIndex])
{
MessageHandler->OnControllerButtonPressed(Buttons[ButtonIndex], ControllerState.ControllerId, false);
}
else
{
MessageHandler->OnControllerButtonReleased(Buttons[ButtonIndex], ControllerState.ControllerId, false);
}
if(CurrentStates[ButtonIndex] == true)
{
/** this button was pressed - set the button's NextRepeatTime to the InitialButtonRepeatDelay */
ControllerState.NextRepeatTime[ButtonIndex] = CurrentTime + InitialButtonRepeatDelay;
}
}
else if(CurrentStates[ButtonIndex] == true && ControllerState.NextRepeatTime[ButtonIndex] <= CurrentTime)
{
MessageHandler->OnControllerButtonPressed(Buttons[ButtonIndex], ControllerState.ControllerId, true);
/** set the button's NextRepeatTime to the ButtonRepeatDelay */
ControllerState.NextRepeatTime[ButtonIndex] = CurrentTime + ButtonRepeatDelay;
}
/** Update the state for next time */
ControllerState.ButtonStates[ButtonIndex] = CurrentStates[ButtonIndex];
}
}
}
bNeedsControllerStateUpdate = false;
#endif
}
void FIOSGamepad::SetMessageHandler(const TSharedRef<FGenericApplicationMessageHandler>&InMessageHandler)
{
MessageHandler = InMessageHandler;
}
bool FIOSGamepad::Exec(UWorld* InWorld, const TCHAR* Cmd, FOutputDevice& Ar)
{
return false;
}
void FIOSGamepad::SetChannelValue (int32 ControllerId, FForceFeedbackChannelType ChannelType, float Value)
{
}
void FIOSGamepad::SetChannelValues (int32 ControllerId, const FForceFeedbackValues &values)
{
}
void FIOSGamepad::OnControllerConnected ()
{
for(int32 ControllerIndex=0; ControllerIndex < FMath::Min<int32>(MAX_NUM_IOS_CONTROLLERS, [[GCController controllers] count]); ++ControllerIndex)
{
[GCController controllers][ControllerIndex].playerIndex = (GCControllerPlayerIndex)ControllerIndex;
}
this->bNeedsControllerStateUpdate = true;
}
void FIOSGamepad::OnControllerDisconnected ()
{
this->bNeedsControllerStateUpdate = true;
}
/** End of FIOSGamepad class */

Related

SpriteWidget: App doesn't response to handleEvent in NodeWithSize

I created a widget, added some Sprites and made some animation. I want to add some user interaction but handelEvent method is not working. I already set userInteractionEnabled to true.
I tried debugging and place a breakpoint inside the handleEvent method but it didn't stop when I touched the screen.
class MainSceneBackgroundNode extends NodeWithSize {
Sprite _logo;
RepeatedImage _background;
GuyImage _guy;
int _i = 0;
int _j = 0;
int _dir = -1;
MainSceneBackgroundNode() : super(new Size(2560.0, 1440.0)) {
userInteractionEnabled = true;
handleMultiplePointers = false;
// Add background
_background = new RepeatedImage(_imageMap["assets/background.png"]);
addChild(_background);
_guy = new GuyImage();
addChild(_guy);
_logo = new Sprite.fromImage(_imageMap["assets/logo.gif"]);
_logo.pivot = Offset.zero;
_logo.size = new Size(912, 486);
_logo.position = new Offset(824, 10);
addChild(_logo);
}
#override
bool handleEvent(SpriteBoxEvent event) {
if (event.type == PointerDownEvent) {
if (event.boxPosition.dx < 1280) {
_dir = -1;
} else {
_dir = 1;
}
}
return true;
}
...
}
Any suggestion will be appreciated. I don't know what else to do.
Thanks in Advance.

Spoj brackets segment tree

can anyone help me in my code. I am getting WA and m not able to rectify it plzzz
my code http://ideone.com/DkrwIg
problem link : http://www.spoj.com/problems/BRCKTS/
i am a bit doubtful in my modification function.
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
char str[40010];
struct node
{
int sum;
int minsum;
}tree[1000005];
void build(int id,int l,int r)
{
if(r-l<2)
{
if(str[l] == '(')
{
tree[id].sum = 1;
tree[id].minsum = 1;
}
else
{
tree[id].sum = -1;
tree[id].minsum = -1;
}
return;
}
int mid = (r+l)/2;
build(id*2,l,mid);
build(id*2+1,mid,r);
tree[id].sum = tree[id*2].sum + tree[id*2+1].sum;
tree[id].minsum = min(tree[id*2].minsum,tree[id*2].minsum+tree[id*2+1].minsum);
}
void modify(int index,int id,int l,int r)
{
if(r-l<2)
{
tree[id].sum = tree[id].minsum = -tree[id].sum;
return;
}
int mid = (r+l)/2;
if(index<mid)
modify(index,id*2,l,mid);
else
modify(index,id*2+1,mid,r);
tree[id].sum = tree[id*2].sum + tree[id*2+1].sum;
tree[id].minsum = min(tree[id*2].minsum,tree[id*2].minsum+tree[id*2+1].minsum);
}
int main()
{
int n,k;
int val;
int h = 1;
for(int h=1;h<=10;h++)
{
scanf("%d",&n);
scanf("%s",str);
build(1,0,n);
//cout<<"Test "<<h<<" :"<<endl;
printf("Test %d:\n",h);
//cin>>k;
scanf("%d",&k);
while(k--)
{
cin>>val;
if(!val)
{
if(tree[1].sum == 0 && tree[1].minsum == 0)
{
//cout<<"YES"<<endl;
printf("YES\n");
}
else
{
//cout<<"NO"<<endl;
printf("NO\n");
}
//cout<<tree[1].sum<<"------------"<<tree[1].minsum<<endl;
}
else
{
modify(val-1,1,0,n);
}
}
}
return 0;
}

Comparing two version numbers

How can I compare two Version number strings?
For example: 3.1.1 and 3.1.2.5.4
Now I need to find out if 3.1.2.5.4 is higher than 3.1.1 but I don't know how to do this.
Can anybody help me?
Thanks in advance!
Sample Code :
NSString* v1 = #"3.1.1";
NSString* v2 = #"3.1.2.5.4";
if ([v1 compare:v2 options:NSNumericSearch] == NSOrderedDescending) {
NSLog(#"%# is greater than %#",v1,v2);
}
From the Apple Documentation for Comparing and sorting strings.
Yes, you can compare the versions, please refer the code below:
public class Comparision {
string ver1, ver2;
public static void main(String args[]){
string ver1Split[] = ver1.split('.');
string ver2Split[] = ver2.split('.');
for (int i = 0; i < ver1Split.length; ++i) {
if (ver2Split == i) {
return ver1 + " is larger";
}
if (ver1Split[i] == ver2Split[i]) {
continue;
}
else if (ver1Split[i] > ver1Split[i]) {
return ver1 + " is larger";
}
else {
return ver2 + " is larger";
}
if (ver1Split.length != ver2Split.length) {
return ver2 + " is larger";
}
return "versions are equal";
}
}
Objective-C:
- (BOOL)isVersion:(NSString *)arg1 higherThan:(NSString *)arg2 {
NSMutableString * v1 = arg1.mutableCopy;
NSMutableString * v2 = arg2.mutableCopy;
NSMutableArray * parts1 = [v1 componentsSeparatedByString:#"."].mutableCopy;
NSMutableArray * parts2 = [v2 componentsSeparatedByString:#"."].mutableCopy;
if (parts1.count > parts2.count) {
NSInteger diff = parts1.count - parts2.count;
for (NSInteger i = diff; i<parts1.count; i++) {
[v2 appendString:#".0"];
}
} else if (parts1.count < parts2.count){
NSInteger diff = parts2.count - parts1.count;
for (NSInteger i = diff; i<parts2.count; i++) {
[v1 appendString:#".0"];
}
}
parts1 = [v1 componentsSeparatedByString:#"."].mutableCopy;
parts2 = [v2 componentsSeparatedByString:#"."].mutableCopy;
NSInteger j = 0;
for (NSString * num1 in parts1) {
NSString * num2 = parts2[j];
if(num1.integerValue > num2.integerValue){
//break;
return YES;
} else if (num1.integerValue < num2.integerValue) {
//break;
return NO;
} else {
// ==
}
j++;
}
return NO;
}
Unit test:
- (void)test_isHigherFunc {
XCTAssert([self isVersion:#"4.1.2.1" higherThan:#"4.1.2.0"]);
XCTAssertFalse([self isVersion:#"4.1.2.0" higherThan:#"4.1.2.0"]);
XCTAssert([self isVersion:#"4.1.2.0" higherThan:#"4.1.1.0"]);
XCTAssertFalse([self isVersion:#"3.1.2.0" higherThan:#"4.1.1.0"]);
XCTAssertFalse([self isVersion:#"4.2.2.0" higherThan:#"4.3.1.0"]);
XCTAssert([self isVersion:#"5.2" higherThan:#"4.3.1.0"]);
XCTAssertFalse([self isVersion:#"6.2" higherThan:#"7.3.1.0"]);
XCTAssert([self isVersion:#"6.2" higherThan:#"5"]);
XCTAssert([self isVersion:#"6.2.0" higherThan:#"5.9"]);
XCTAssert([self isVersion:#"1.1.1.1.1.1.1.1" higherThan:#"1.1.1.1.1.1.1.0"]);
XCTAssert([self isVersion:#"2.0" higherThan:#"1"]);
}

Actionscript3 ArgumentError: Error #2109:

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.

Collision stops all characters moving in the list

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;
}
}
}

Resources