Collision detection (Cocos-2d) won't work - xcode

I recently bought the book Learn Cocos 2d 2, and have been following the tutorial on how to make my first game(chapter 4). Basically, what is supposed to happen in the game where I am in the book, you are the alien, and you have to tilt to avoid falling spiders. If you hit one, the game resets.
The probelem I'm having is that the collision detecting doesn't work. The spiders fall and pass through me, the game doesn't reset. As far as I can tell (I just started), it should work, and I couldn't find any differences between the book and this.
This is the code(It's actually an exaple of the game without collisions, and I added the code the book told me to)
http://pastebin.com/0Jt9PdMy
As far as I know(not much), it should work.
Any help?

I guess you would need to stop the spiders actions in that reset loop:
for (int i = 0; i < numSpiders; i++)
{
CCSprite* spider = [spiders objectAtIndex:i];
[spider stopAllActions]; // add this
spider.position = CGPointMake(imageSize.width * i + imageSize.width * 0.5f, screenSize.height + imageSize.height);
}

Related

AS3 Particle Explosion Crash

Hellooooo, hope y'all are doing great.
A while ago, I asked a question about how to do particle explosions in AS3 when I was coming from AS2. Luckily, I got help from Organis (thank you so much btw), but every time I try export the animation in SWF, it keeps crashing my file and I'm not sure why?
I should probably preface that what I'm doing is specifically for animation. I'm not trying to make a game, just a simple script where the movieclip I created can explode into different objects in its timeline...if that made any sense.
In case anyone needs the actual file itself, you can download it right here: https://sta.sh/018lqswjfmp2
Here is the AS2 version in case anyone needs it: https://sta.sh/02fzsqon3ohw
Here is the code given to me by Organis:
// Allows the script to interact with the Particle class.
import Particle;
// Number of particles.
var maxparticles:int = 200;
// I imagine you will need to access the particles somehow
// in order to manipulate them, you'd better put them into
// an Array to do so rather then address them by their names.
var Plist:Array = new Array;
// Counter, for "while" loop.
var i:int = 0;
// The loop.
while (i < maxparticles)
{
// Let's create a new particle.
// That's how it is done in AS3.
var P:Particle = new Particle;
// The unique name for the new particle. Whatever you want it for.
P.name = "particle" + i;
// Enlist the newly created particle.
Plist.push(P);
// At the moment, the P exists but is not yet attached to the display list
// (or to anything). It's a new concept, there wasn't such thing in AS2.
// Let's make it a part of the display list so that we can see it.
addChild(P);
i++;
}
And in case anyone needs it, here is the code I used for AS2:
maxparticles = 200; //number of particles
i = 0; //counter, for "while" loop
while(i < maxparticles){
newparticlename = "particle" + i; //creates a new name for a new particle instance
particle.duplicateMovieClip(newparticlename, i); //duplicates our particle mc
i++;
}

Collision not detecting at high speed

I decided I wanted to learn how to work with the unity2D engine, and started with trying to make pong. This was going pretty good, until I found a problem I couldn't find/didn't understand an answer for on google .
Every time the player/AI hits the ball, I make the ball go a little bit faster. This works fine until the ball goes pretty fast (still playable though) and just passes through the player/AI. I solved this by making the box collider of the player/AI really long, but at really high (and unplayable) speeds it still goes through.
My solution works, but isn't that pretty, and I wonder if there is a better solution for this (make the engine check more often for collisions?).
Here's the script for the ball movement (Javascript):
#pragma strict
var StartSpeed : int;
var speedFactor : float;
function Start () {
yield WaitForSeconds(2);
StartBall();
}
function ResetBall () {
GetComponent.<Rigidbody2D>().velocity.x = 0;
GetComponent.<Rigidbody2D>().velocity.y = 0;
transform.position.x = 0;
transform.position.y = 0;
yield WaitForSeconds(0.5);
StartBall();
}
function StartBall () {
var randomDirection = Random.Range(0f,1f);
var randomAngle = Random.Range(-Mathf.PI/4, Mathf.PI/4);
if(randomDirection < 0.5f){
GetComponent.<Rigidbody2D>().velocity.x = Mathf.Cos(randomAngle) * StartSpeed;
GetComponent.<Rigidbody2D>().velocity.y = Mathf.Sin(randomAngle) * StartSpeed;
}else{
GetComponent.<Rigidbody2D>().velocity.x = - Mathf.Cos(randomAngle) * StartSpeed;
GetComponent.<Rigidbody2D>().velocity.y = Mathf.Sin(randomAngle) * StartSpeed;
}
}
function OnCollisionEnter2D (colInfo : Collision2D) {
if(colInfo.collider.tag == "Player"){
GetComponent.<Rigidbody2D>().velocity.x = speedFactor * GetComponent.<Rigidbody2D>().velocity.x;
if(colInfo.collider.GetComponent.<Rigidbody2D>().velocity.y == 0){
GetComponent.<Rigidbody2D>().velocity.y = speedFactor * GetComponent.<Rigidbody2D>().velocity.y;
}
var vel = GetComponent.<Rigidbody2D>().velocity;
Debug.Log("Speed: " + vel);
}
}
Any other comments on the script that may improve it are welcome!
EDIT: I tried the following (as Andrew suggested):
function OnCollisionEnter2D (colInfo : Collision2D) {
if(colInfo.collider.tag == "Player"){
GetComponent.<Rigidbody2D>().AddForce( Vector2 (speedFactor * GetComponent.<Rigidbody2D>().velocity.x, speedFactor * GetComponent.<Rigidbody2D>().velocity.y));
var vel = GetComponent.<Rigidbody2D>().velocity;
Debug.Log("Speed: " + vel);
}
}
This still causes the problem I had before.
Update your RigidBody settings and set Collision Detection to Continuous (it will probably be set to discrete) and your high speed collision will work fine.
You shouldn't be messing with the velocity directly, try just using AddForce() instead.
Whole physics including collision detection runs on FixedUpdate, so to actually detect any collision colliders must collide when FixedUpdate is called. Let's say one collider isn't moving (wall for example) and another is going right at it, on current call of FixedUpdate collider that is moving is just before the wall, while on the next call of FixedUpdate collider that is moving has passed the wall, because that is it's position step per frame. Visually we see that colliders did collide, but they didn't collide on any call to FixedUpdate. Now, there are two solutions to this, lower the speed or lower the timestep of FixedUpdate ( http://docs.unity3d.com/Manual/class-TimeManager.html ), but this can be bad for framerate, it all depends what machines are you targeting and how hardware hungry your game is.
There is also this open source script which you should look at :
http://wiki.unity3d.com/index.php?title=DontGoThroughThings#C.23_-_DontGoThroughThings.js

OpenCV - Earth Mover's Distance issue, icvInitEMD()

I am having trouble calling EMD() in OpenCV 2.4.2 under Mac OS ML.
I have a class with an attribute Mat _signature defined like that :
Mat _signature(size,dim+1,CV_32F);
for (int i = 0; i<size; ++i){
_signature.at<float>(i,0) = weight;
for (int j = 1; j < dim+1; ++j){
_signature.at<float>(i,j) = vec[i].at<float>(0,j-1); // vec[i] is a line vector containing the position in R^dim
}
}
I then have u and v 2 instances of that class, and when I call EMD(u._signature, v._signature, CV_DIST_L2);
It fails with OpenCV Error: One of arguments' values is out of range () in icvInitEMD, file /*SOME PATH*/OpenCV-2.4.2/modules/imgproc/src/emd.cpp, line 408
I looked at the sourcecode but could not figure out what this fails. My arguments appear in correspondence to what the documentation wants. Any help will be appreciated.
Ok, it took me quite some time to figure it out, but among my data there was a component of one of my vector which was miscalculated, and ended up being NaN.
Of course this was buried deep into my data so that it would be completely lost in any amount of data reasonably observable via a debugger (or even cout)
The cryptic error from OpenCV did the rest in confusing me.
For people stumbling upon the same issue as me :
Make sure your weight vectors are not zero
Make sure none of your data is NaN

WP7 zxing scan not reliable

I've printed a few short qr-codes (like "HAEB16653") on a page using this algorythm:
private void CreateQRCodeFile(int size, string filename, string codecontent)
{
QRCodeWriter writer = new QRCodeWriter();
com.google.zxing.common.ByteMatrix matrix;
matrix = writer.encode(codecontent, BarcodeFormat.QR_CODE, size, size, null);
Bitmap img = new Bitmap(size, size);
Color Color = Color.FromArgb(0, 0, 0);
for (int y = 0; y < matrix.Height; ++y)
{
for (int x = 0; x < matrix.Width; ++x)
{
Color pixelColor = img.GetPixel(x, y);
//Find the colour of the dot
if (matrix.get_Renamed(x, y) == -1)
{
img.SetPixel(x, y, Color.White);
}
else
{
img.SetPixel(x, y, Color.Black);
}
}
}
img.Save(filename, ImageFormat.Png);
}
The printed barcodes work very well and fast with the integrated WP7 bing scan&search.
When I try to scan the very same printed qrcodes with Stéphanie Hertrichs sample app, scanning is very slow, most do not scan at all, or will only be recognized when I slowly rotate the camera around.
How do I get my scanning to be as reliable as the integrated barcode recognition? I only need to scan QrCodes, so I disabled all the others, still it does not work most of the time.
Is there maybe some other barcode scanning library which is working better?
The silverlight port in Stéphanie Hertrichs sample app is very old. It seems to me that the project at codeplex isn't maintained anymore since more then 1 year. You should try one of the newer and maintained ports like ZXing.Net
zxing works very well -- just try it on Android. I would not be surprised if it is what powers the Bing search.
The problems are likely in the port. Any non-Java port is at best old and incomplete. I also can't speak to the efficiency of the approach used in the sample you are looking at. For example, is it really binarizing the image from the APIs correctly? Also make sure it is not using TRY_HARDER mode.
There is no objective answer to this question...
My personal opinion is that the ZXing lib that you tried (Stéphanie Hertrichs sample app) is the best you can get. As far as I know it is used on the other plattforms, too (e.g. Android).
As I tested the lib a few months ago, I had the impression it worked very reliable and quick, but it may be that you had other circumstances (lighting, camera, angle, etc...)

Actionscript 2: Event Cue Points: findNearestCuePoint

Hello everyone and anyone!
Ok... I have been banging my head against the wall with this issue for literally weeks, but I still cannot find an answer that has successfully resolved the issue.
I created an FLA and placed a FLV component with the instance name of videoPlay on the stage.
videoPlay is pathed to a streaming FLV with embedded event cue points. The cue points are numbered sequentially from narration1 to narration16.
I established a listener object:
var videoPlayCuePointListener:Object = new Object();
The event listener for the cue points:
videoPlayCuePointListener.cuePoint = function(eventObject:Object):Void{
if(eventObject.info.name == "narration1"){_root.cc_box.cc_txt.htmlText = cueTxt1);}
else if(eventObject.info.name == "narration2"){_root.cc_box.cc_txt.htmlText = cueTxt2);}
etc, through narration16 }
and so on through narration16.
Then I attached the event listener to the FLV component on stage:
videoPlay.addEventListener("cuePoint", videoPlayCuePointListener);
All of this works very well. As the FLV plays, each event cue point fires off the correct text to the cc_txt dynamic text box.
The issue I am having is that I cannot find the nearest cue point to the FLV playhead so that I can fire events when the user scrubs the timeline.
I have researched this as thoroughly as I possibly could before finally deciding to post the issue, but although the documentation and various postings regarding findNearestCuePoint discovered throughout the web have provided numerous examples, not a single one has been successful.
I have attempted to add a listener to videoPlay that creates an object (nearestCue) and gives nearestCue the value of videoPlay.findNearestCuePoint(videoPlay.playheadTime), then read out nearestCue's name, label, etc. No dice.
Nothing suggested in any posts I have reviewed (many, many posts) has provided an answer.
This seems like it would be the easiest thing to accomplish but I have not been successful a single time.
Any suggestions or assistance would be much appreciated.
Thank you for your time!
Haven't touched AS2 in a long time. I've done a basic test and findNearestCuePoint worked. You're using the FLVPlayback component, right ?
Here's what I've tried:
videoPlayer.autoPlay = false;
onEnterFrame = function():Void{
videoPlayer.seekPercent(_xmouse/Stage.width * 100);
videoPlayer.play();
trace(videoPlayer.findNearestCuePoint(videoPlayer.playheadTime).name);
}
The recommended way would be to find the nearest cue point in an playheadUpdate handler which is triggered after the playhead changes it's value. (e.g. 1. tell the playhead to move, 2. the playhead actually changes the value, 3. the playheadUpdate gets called)
Here's a more basic approach:
onEnterFrame = function():Void{
if(videoPlayer.metadata) trace(videoPlayer.findNearestCuePoint(_xmouse/Stage.width * videoPlayer.metadata.duration).name);
}
In my test I've added 4 cue points. Tried them all: actionscript/event/navigation.
The strange thing was when I tried to access the cuePoints property through videoPlayer
or through videoPlayer.metadata I got an array of 8 undefined objects, and the length of the array was 4 when I traced it. Don't know what the issue is, maybe encoding/codec and as2 compatibility, not sure.
Anyway...as long as you've got your cuePoints array, you can manually find the closest one by looping though all of them and getting the smallest absolute difference between each cue point time and the current time:
function getClosestCuePoint(cuePoints:Array,time:Number):Object{
var numCuePoints:Number = cuePoints.length;
var minDist:Number = 100000000,result:Object;
for(var i:Number = 0 ; i < numCuePoints ; i++){
if(Math.abs(cuePoints[i].time - time) < minDist){
minDist = Math.abs(cuePoints[i].time - time);
result = cuePoints[i];
}
}
return result;
}
Here's a mockup example: let's pretend some boxes on the screen are the cue points and the _xmouse position would be the playhead time. Try this in a new document:
//fake cue points
var numCuePoints:Number = 5;
var cuePoints = [];
for(var i:Number = 0 ; i < numCuePoints ; i++) cuePoints[i] = {name:'narration ' + (i+1),time: 10 + (80 + Math.random() * 20) * i}
//visual hint - separated from the cue points
for(var i:Number = 0 ; i < numCuePoints ; i++) drawBox(this,0x009900,10,15,cuePoints[i].time,Stage.width * .5);
var playhead:TextField = drawText(this,'playhead');
//playhead update
onEnterFrame = function():Void{
playhead._x = _xmouse;
playhead.setTextFormat(new TextFormat('Verdana',11));
playhead.text = 'time: ' + _xmouse+' / cue ' + getClosestCuePoint(cuePoints,_xmouse).name;
}
//find the shortest marker within the shortest distance from the current value
function getClosestCuePoint(cuePoints:Array,time:Number):Object{
var numCuePoints:Number = cuePoints.length;
var minDist:Number = 100000000,result:Object;
for(var i:Number = 0 ; i < numCuePoints ; i++){
if(Math.abs(cuePoints[i].time - time) < minDist){
minDist = Math.abs(cuePoints[i].time - time);
result = cuePoints[i];
}
}
return result;
}
//utils
function drawBox(target:MovieClip,color:Number,width:Number,height:Number,x:Number,y:Number):Void{
target.lineStyle(3,color);
target.moveTo(x,y);
target.lineTo(x+width,y);
target.lineTo(x+width,y+height);
target.lineTo(x,y+height);
target.lineTo(x,y);
}
function drawText(target:MovieClip,name:String):TextField{
var result:TextField = target.createTextField(name,target.getNextHighestDepth(),0,Stage.width * .5-20,100,20);
result.autoSize = 'left';
result.border = true;
result.selectable = false;
return result;
}
HTH
George,
I believe I discovered the issue, and I think it was something that you covered in your previous post, but I glossed over it by accident.
The F4V I was working with had the cue points embedded using Adobe Media Encoder... and that was the entire issue.
I went back and exported the cue points out to XML, then stripped them out of the F4V and re-encoded it without them. Then I edited the XML to change all of the event cue point to actionscript and imported them into the FLA file using the FLV component properties dialogue.
Presto, amazingly enough, I had no issues finding the cue points, tracing them, and using them for any purpose.
So in the future, I just need to remember to set up the cue points in the Properties dialogue and set them to actionscript and I should be golden. So far, it has worked flawlessly with all of the F4V files since making the change.
Thank you very much for your detailed response and your follow up!

Resources