Cocos3D integration in UIViewController crashing - ios6

Hi I am trying to integrate Cocos3D into my current project.
I can successfully run it when i set UIViewControllerCOCOS containing Cocos3D code (Listed below) in App Delegate as root of UINavigationController.
But if i use some other viewController say OtherVC and push UIViewControllerCOCOS on navigationController then it crashes on
_viewController.supportedInterfaceOrientations = UIInterfaceOrientationMaskAll; //APPLICATION CRASH HERE SAYING -[CCDirectorDisplayLink setSupportedInterfaceOrientations:]: unrecognized selector sent to instance 0x146ab0b0. Where
_viewController is CC3DeviceCameraOverlayUIViewController* _viewController;
I have used Cocos3D hello world code.
//UIViewControllerCOCOS.m
-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self setupCocos3D];
}
-(void)setupCocos3D{
CCTexture2D.defaultAlphaPixelFormat = kCCTexture2DPixelFormat_RGBA8888;
// Establish the view controller and CCDirector (in cocos2d 2.x, these are one and the same)
[self establishDirectorController];
[self.view addSubview:_viewController.view];
// ******** START OF COCOS3D SETUP CODE... ********
// Create the customized CC3Layer that supports 3D rendering.
cc3Layer = [Nabru_cocos3dLayer layerWithController: _viewController];
// Create the customized 3D scene and attach it to the layer.
// Could also just create this inside the customer layer.
cc3Layer.cc3Scene = [Nabru_cocos3dScene scene];
// Assign to a generic variable so we can uncomment options below to play with the capabilities
CC3ControllableLayer* mainLayer = cc3Layer;
_viewController.controlledNode = mainLayer;
// Run the layer in the director
CCScene *scene = [CCScene node];
[scene addChild: mainLayer];
[CCDirector.sharedDirector runWithScene: scene];
}
-(void) establishDirectorController {
_viewController = CC3DeviceCameraOverlayUIViewController.sharedDirector;
_viewController.supportedInterfaceOrientations = UIInterfaceOrientationMaskAll; //APPLICATION CRASH HERE SAYING -[CCDirectorDisplayLink setSupportedInterfaceOrientations:]: unrecognized selector sent to instance 0x146ab0b0. If i comment out this line then it crash second line below it.
_viewController.viewShouldUseStencilBuffer = NO; // Set to YES if using shadow volumes
_viewController.viewPixelSamples = 1; // Set to 4 for antialiasing multisampling
_viewController.animationInterval = (1.0f / kAnimationFrameRate);
_viewController.displayStats = YES;
[_viewController enableRetinaDisplay: YES];
}
Any suggestion please?

Related

How can I prevent my app from restarting when I switch apps?

What I want is that when I lose focus and return to my app, it continues where it left off.
To show the problem I have created a 45 second video at this link enter link description here
The same thing happens when running simulator. In the main class I make use of Lifecycle (generated from CN1).
I am copying the main class to it for validation.
MainClass
public class TarifaTaxiPredictivo extends Lifecycle {
private Usuario iU;
#Override
public void runApp() {
String sIdioma = L10NManager.getInstance().getLanguage().toLowerCase();// Salva el tipo de idioma
if (!sIdioma.equals(IDIOMA_INGLES) && !sIdioma.equals(IDIOMA_ESPANOL)) {
sIdioma = IDIOMA_ESPANOL;
}
iU = Usuario.getInstancia();
iU.setIdioma(sIdioma);
iU.setAumento(calculatePorcentajeAumento());
showSplashAnimation();
}
public void showSplashAnimation() {
Form splash = new Form(new LayeredLayout());
splash.setUIID("Splash");
ScaleImageLabel iconBackground = new ScaleImageLabel(getGlobalResources().getImage("attt.png"));
iconBackground.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL);
Container centerBackground = BorderLayout.center(iconBackground);
splash.add(centerBackground);
Label iconForeground = new Label(getGlobalResources().getImage("attt.png"));
Container centerIcon = BorderLayout.centerAbsolute(iconForeground);
splash.add(centerIcon);
splash.show();
Display.getInstance().callSerially(() -> {
((BorderLayout) centerBackground.getLayout()).setCenterBehavior(BorderLayout.CENTER_BEHAVIOR_CENTER_ABSOLUTE);
centerBackground.setShouldCalcPreferredSize(true);
centerBackground.animateLayoutAndWait(2000);
iconForeground.remove();
iconBackground.remove();
centerIcon.remove();
Container cnFondo = LayeredLayout.encloseIn(
new Label(iconBackground.getIcon(), "CenterIcon"));
Container boxy = BoxLayout.encloseY(cnFondo);
Label placeholder = new Label();
placeholder.setShowEvenIfBlank(true);
Label lbTit = new Label("Tarifa de Taxi", "SplashSubTitulo");
Component.setSameHeight(placeholder, lbTit);
Component.setSameWidth(placeholder, lbTit, boxy);
centerBackground.add(BorderLayout.CENTER, boxy);
splash.revalidate();
Display.getInstance().callSerially(() -> {
placeholder.setText(" ");
boxy.add(placeholder);
boxy.setShouldCalcPreferredSize(true);
boxy.getParent().animateLayoutAndWait(1500);
boxy.replaceAndWait(placeholder, lbTit, CommonTransitions.createFade(1500));
Label lbNuevoTitulo = new Label(" ");
Label lbTitulo = new Label("ATTT", "SplashTitulo");
Component.setSameHeight(lbNuevoTitulo, lbTitulo);
Component.setSameWidth(lbNuevoTitulo, lbTitulo);
boxy.add(lbNuevoTitulo);
boxy.getParent().animateLayoutAndWait(250);
boxy.replaceAndWait(lbNuevoTitulo, lbTitulo, CommonTransitions.createFade(3000));
new Tarifa().show();
});
});
}
}
This is OS behavior. When an app is sent to the background the stop() method is invoked. It's important that we stop all connections etc. otherwise the phone will kill the app to preserve battery life.
When the app is restored start() will be invoked again. If your app always restarts when start() is invoked then you will get the effect of a clean restart.
You can test this in the simulator via the pause/resume functionality. You will be able to see how your app is supposed to act when the phone pauses it and restores it.
Assuming this works correctly in the simulator but fails in the device this would be because you're using resources in the background which you can only do through a background service facility.

ActionScript 3 : character hit test object with all objects in array

First of all thank you for the attention of anybody reading this question
I'm Indonesian, so apologize if my english was bad.
I'm currently in a school project creating touchscreen Android game using Flash ActionScript 3 or Unity, my current project is made using Flash with ActionScript 3. My current work is a Feeding Frenzy-like game which involves a female scuba diver which will annihilate a fish bomb falling underwater.
I'm trying to make the diver warned for all bombs in the screen. I have a BombsLayer class which will call a RegularBomb Class to fall in random x position. All RegularBomb instance are placed into an Array, then i use for each looping with hitTestObject so if the diver hit the transparent circle inside the movieclip, an exclamation sign will appear and sets the readyToDefuse boolean in diver class to true, and when the diver is away from bomb, the boolean will set to false, and the exclamation sign will dissapear.
My problem is the diver can only interact with the last bomb movieclip instace in the array. when the first bomb child added into the array and the diver reachs it, the exclamation sign would appear, but every time a new bomb instantiated the exclamation sign would disappear and i have to make the diver move to the new bomb instantiated to make the sign appear.
i have read the suggestion on this question : AS3 - array hit test in 'for each' loop only works properly with last object in array to remove the else statement in the for each loop, but by removing it will make the readyToDefuse remains True and the exclamation sign remains appearing.
i have done a google searching and nothing seems to answer my problem, i have to finish this game for one week until presentation and this had driving me confused for these past days..
here is my complete code for the Bombslayer Class :
package {
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
public class BombsLayer extends MovieClip{
public var area:Sprite;
public var bombs:Array;
public var bomb:RegularBomb;
public var bombground:BombGround;
public var diver:Diver;
public var warner:BombWarn;
public function BombsLayer(character:Diver, warn:BombWarn){
// constructor code
area = new Sprite();
area.graphics.beginFill(000000, 0);
area.graphics.drawRect(0,0,2200,720);
area.graphics.endFill();
addChild(area);
diver = character;
warner = warn;
bombs = new Array();
var newBomb = new RegularBomb(Math.random()*area.width, diver, warner);
bombs.push(newBomb)
addChild(newBomb);
bombground = new BombGround(0, 670, this);
addChild(bombground);
this.addEventListener(Event.ENTER_FRAME, moveBomb);
}
function moveBomb(event:Event){
if(Math.random() <= 0.0005){
var newBomb = new RegularBomb(Math.random()*area.width, diver, warner);
bombs.push(newBomb)
addChild(newBomb);
}
for each(var bomb:RegularBomb in bombs){
bomb.moveDown();
if(diver.hitTestObject(bomb)){
warner.visible = true;
diver.readyToDefuse = true;
}
else{
warner.visible = false;
diver.readyToDefuse = false;
}
}
}
}
}
if needed i can upload the complete project too..
All helps would be appreciated.
Thank you!
The logic is wrong. You need to browse through the bombs and find one in contact with diver if any, and work with the only bomb. Otherwise the diver is ready to defuse bomb A but not ready to defuse B, C and D and thus is not ready at all.
function moveBomb(event:Event)
{
var aBomb:RegularBomb;
if (Math.random() <= 0.0005)
{
aBomb = new RegularBomb(Math.random() * area.width, diver, warner);
bombs.push(aBomb)
addChild(aBomb);
}
for each(aBomb in bombs) aBomb.moveDown();
// Find bomb in diver's vicinity.
aBomb = findBomb();
// The same as "if (aBomb != null)"
if (aBomb)
{
warner.visible = true;
diver.readyToDefuse = true;
}
else
{
warner.visible = false;
diver.readyToDefuse = false;
}
}
function findBomb():RegularBomb
{
for each(var aBomb:RegularBomb in bombs)
if (diver.hitTestObject(aBomb))
return aBomb;
return null;
}

SharpDX.WPF Increasing memory usage during rendering

I have started working with DirectX in WPF app. My first step was to use simple library:
SharpdDX.WPF. Based on samples I've implemented WPF control drawing simple line. SharpDX.WPF uses D3DImage to render images in WPF.
Unfortunately application's memory increasing all time.
I implemented class TestControlRenderer : D3D10.
Vertex shader is initialized like:
var sizeInBytes = dataLength * sizeof(int) * 3;
var bufferDescription = new BufferDescription(
sizeInBytes,
ResourceUsage.Dynamic,
BindFlags.VertexBuffer,
CpuAccessFlags.Write,
ResourceOptionFlags.None);
using (var stream = new DataStream(sizeInBytes, true, true))
{
stream.Position = 0;
_graphDataVertexBuffer = new SharpDX.Direct3D10.Buffer(Device, stream, bufferDescription);
}
Device.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(_graphDataVertexBuffer, sizeof(int) * 3, 0));
Device.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineStrip;
Then constant buffer with parameters used in shader:
_controlInfoConstantBuffer = new ConstantBuffer<ControlParamsShaderData>(Device);
Device.VertexShader.SetConstantBuffer(0, _controlInfoConstantBuffer.Buffer);
To init animation Reset method was overriden like that:
base.Reset(args);
if (args.RenderSize.Width == 0) return;
_drawArgs = args;
InitVertexBuffer(dataLength);
_controlInfoConstantBuffer.Value = new ControlParamsShaderData
{
SamplesInControl = dataLength,
MinSignalDataY = -1500,
MaxSignalDataY = 1500
};
Device.VertexShader.SetConstantBuffer(0, _controlInfoConstantBuffer.Buffer);
The last step is RenderScene method:
public override void RenderScene(DrawEventArgs args)
{
if (args.RenderSize.Width == 0) return;
Device.ClearRenderTargetView(RenderTargetView, Color.Transparent);
using (var stream = _graphDataVertexBuffer.Map(MapMode.WriteDiscard, SharpDX.Direct3D10.MapFlags.None))
{
for (int i = 0; i < Data.Length; i++)
{
stream.Write(new Vector3(i, Data[i], 0));
}
}
_graphDataVertexBuffer.Unmap();
Device.Draw(Data.Length, 0);
}
Rendering is controlled by DispatcherTimer where OnTickMethod updates array with points coordinates and then invoke Render() method.
My question is simply, is that memory leak or something is created on each render iteration?
I don't change backbuffer or create another objects. Only change Data array, update it to GPU and Shaders process it to display.
My case is to display about 30 wpf controls width DirectX on one screen. Controls are with simple but realtime animation. Is that possible in that way?
Most likely you are leaking resources. You can see this by setting the static configuration property
SharpDX.Configuration.EnableObjectTracking = true;
then calling
SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects()
at various points in your application lifetime to see if anything is leaking (at least on the SharpDX side). You can edit your code to make sure to dispose these objects. Only enable object tracking while debugging - it hurts performance.
SharpDX used to release COM objects when the finalizer ran if the object had not already been Diposed (at least as in version 2.4.2), but later disabled that (they detail why in one of their changelogs, I forget which one).
Additionally, DirectX requires that you release objects in the reverse order they were created - this can create hard-to-debug memory leaks. So when your code is
var device = new Devie(...);
var effect = new Effec(Device, byteCode);
technique = effect.GetTechniqueByName(techniqueName);
inputLayout = new InputLayout(Device, _technique.GetPassByIndex(0).Description.Signature, ...);
then your dispose code has to be
_inputLayout.Dispose();
_technique.Dispose();
_effect.Dispose();
_device.Dispose();

MFMessageComposeViewController not full screen on 4" screen

I'm make an iPhone app, in this app the user can send a SMS.
On my iPhone 4 is my screen perfect, but on my iPhone 5 i get a blank box.
iPhone only. iOS 6x
Screenhot (iphone5): http://i.stack.imgur.com/ZOqu1.png
#import "smsview.h"
#interface smsview ()
#end
#implementation smsview
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result
{
[self dismissModalViewControllerAnimated:YES];
if (result == MessageComposeResultCancelled)
NSLog(#"Message cancelled");
else if (result == MessageComposeResultSent)
NSLog(#"Message sent");
else
NSLog(#"Message failed");
}
- (void)sendSMS:(NSString *)bodyOfMessage recipientList:(NSArray *)recipients
{
MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];
if([MFMessageComposeViewController canSendText])
{
controller.body = bodyOfMessage;
controller.recipients = recipients;
controller.messageComposeDelegate = self;
[self presentModalViewController:controller animated:YES];
}
}
-(IBAction)Text:(id)sender
{
{
[self sendSMS:#"" recipientList:[NSArray arrayWithObjects:#"+1-234-567-8910", nil]];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#end
Follow these steps if u failed to.
Are you using the latest version of Xcode if not download from here.
You can use the Auto layout feature and create the design the using iPhone 5 screen resolution and it will work for the both 4" and 3.5" devices, but in this case you should have a enough knowledge of layout manager.
Set a 4-inch launch image for your app. This is how you get 1136 px screen height (without it, you will get 960 px with black margins on top and bottom), To adapt your app to the new taller screen, the first thing you do is to change the launch image to: Default-568h#2x.png. Its size should be 1136x640 (HxW). Yep, having the default image in the new screen size is the key to let your app take the whole of new iPhone 5's screen..
Hopefully everything should work if you had set auto resizing masks properly.
If you didn't, adjust your view layouts with proper auto resizing masks or look into Auto Layout if you only want to support iOS 6 going forward.
If there is something you have to do for the larger screen specifically, then it looks like you have to check height of [[UIScreen mainScreen] bounds] (or applicationFrame, but then you need to consider status bar height if it's present) as there seems to be no specific API for that.
for instance:
CGRect screenBounds = [[UIScreen mainScreen] bounds];
if (screenBounds.size.height == 568) {
//iPhone 4 specific
} else {
//iPhone 5 specific
}
Hope this solves your problem.

Problems with iOS 6 and UIActivityIndicator in a UINavigationBar titleView

been having problems with this since iOS 6. I can't really figure out whats changed that would cause this behavior. This used to work perfectly in 5. Now the activity indicator doesn't come up timely or at all. Any help would be much appreciated.
-(void)myMethod
{
UIView *currentTitleView = [[self navigationItem] titleView];
// Create an activity indicator and start it spinning in the nav bar
UIActivityIndicatorView *aiview = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
[[self navigationItem] setTitleView:aiview];
[aiview startAnimating];
// Start of Block code
void (^block)(arg1, arg2) =
^(arg1, arg2)
{
block code;
[aiview stopAnimating];
[[self navigationItem] setTitleView:currentTitleView];
};
// End of Block code
}
It sounds like myMethod is being called from a background thread. As a general rule, all interactions with UIKit elements (which includes UIActivityIndicatorView) should always be done on the main thread. Try using GCD to move the UI code to the main queue (a.k.a. main thread).
-(void)myMethod {
dispatch_async(dispatch_get_main_queue(), ^{
UIView *currentTitleView = [[self navigationItem] titleView];
// Create an activity indicator and start it spinning in the nav bar
UIActivityIndicatorView *aiview = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
[[self navigationItem] setTitleView:aiview];
[aiview startAnimating];
});
// Start of Block code
void (^block)(arg1, arg2) =
^(arg1, arg2)
{
block code;
dispatch_async(dispatch_get_main_queue(), ^{
[aiview stopAnimating];
[[self navigationItem] setTitleView:currentTitleView];
});
};
// End of Block code
}

Resources