CollidedWith crashing application?

9 views
Skip to first unread message

bernhard

unread,
Feb 7, 2012, 12:16:25 PM2/7/12
to Android Programming at USF
hi,

i have a Ball component which should change the direction when it
collides
with an ImageSprite (see code below). The EdgeReached event works as
expected, causing the
ball to bounce from the edge. However if I want to to the same thing
when the Ball
Component hits the ImageSprite, the application just crashes.
From what I have seen in the log, the CollidedWith event seems to be
firing
endlessly after the ball hits the Sprite.

Any hints?
Thanks,
Bernhard

public class PongBall extends Ball{
public PongBall(ComponentContainer container) {
super(container);
// TODO Auto-generated constructor stub
}

@Override
public void EdgeReached(int edge){
int randHeading = 90 + randomGen.nextInt(10);
this.Heading(this.Heading() + randHeading);
}

@Override
public void CollidedWith(Sprite other){
//causes application to crash!
this.Heading(90);
}
}

Dave Wolber

unread,
Feb 7, 2012, 12:37:50 PM2/7/12
to Android Programming at USF
Hi Bernhard. Yes, I think the event triggers as long as objects are
still intersecting. I think you need to keep your own boolean variable
so that you only do whatever you want to do once. You can also deal
with the NoLongerCollidingWith event

Dave

Bernhard Schelling

unread,
Feb 7, 2012, 2:27:49 PM2/7/12
to android-progr...@googlegroups.com
Hi Dave,

thanks for the hints. I set a "colliding" flag to ensure the call to
Heading() occurs
only once and verified it with a debug message which only shows up
once (see below).
Still - any call (Heading() or PaintColor() - doesn't matter - crashes
the app...
Hm...

Bernhard


public void CollidedWith(Sprite other) {
if(!this.colliding){
this.Heading(90);
this.colliding = true;
dbg("this.colliding="+this.colliding); //+" "+other.equals(racketSprite));

Lazeeb Choudhury

unread,
Feb 8, 2012, 3:16:37 AM2/8/12
to android-progr...@googlegroups.com
Hi:
I cannot detect a Collision with a ImageSprite object and a Ball object in Java Bridge. I'm trying to use "CollidingWith" but cannot get it to work. Its crashing my app too. Its also the most important element for me to convert my appinventor app to JavaBridge. Is there any solution?

Thanks,
Lazeeb

David W Wolber

unread,
Feb 8, 2012, 10:36:52 AM2/8/12
to android-progr...@googlegroups.com
Bernhard had issues and ended up using a Clock.Timer event and checking explicitly for collisions (with explicit checks on the x and y coordinates)

I'll work on an example for you and see if I get the same bug,

Dave

Chris B.

unread,
Feb 8, 2012, 12:05:11 PM2/8/12
to Android Programming at USF
I did something similar to this. In the Timer() method of my Clock
class, I check collisions with the following:

ImageSprite.colliding(sprite1,sprite2)

That is, I have to call the static 'colliding' method in the
ImageSprite class, and pass it the two sprites to check. This works
for me, though in general collision detection is very hit and miss
(har har).

M. Hossein Amerkashi

unread,
Feb 8, 2012, 12:22:25 PM2/8/12
to android-progr...@googlegroups.com
Please see wiki (BallSpriteActivity ) below for an example of using ImageSprite and Ball collide. Please note the section that is marked as NOTE.

http://code.google.com/p/apptomarket/w/list

-Hossein

Dave Wolber

unread,
Feb 8, 2012, 5:05:51 PM2/8/12
to Android Programming at USF
Hi Hossein. Thanks for your help on all of this. Two things:

1. I notice in your example that you a) create objects in $define, and
b) catch the initialize event of the form and initialize data for
imagesprites there. Can you explain how this works and why one needs
both a $define and an Initialize-- I don't get much different behavior
(I don't think) if I do the init stuff in $define.

2. So my examples have subclassed the components, e.g., I've created
subclasses of ImageSprites. I can then handle events by overriding the
high-level event-handling functions (similar to dragging an event-
handling block in from App Inventor).

This works fine for most samples, but I believe this is causing the
crashes with CollidedWith. Specifically, when I moved the CollidedWith
response code in your sample from the dispatchEvent method into an
overridden CollidedWith method in my subclass GameImageSprite (and
GameBall), I get the stack overflow like Bernhard got. Do you have any
ideas why this would happen (I'm assuming that the event is being
triggered thousands of times, but I can't quite figure why the
subclassing method of handling the event would cause the problem).

Thanks,

Dave

On Feb 8, 9:22 am, "M. Hossein Amerkashi" <kkash...@gmail.com> wrote:
> Please see wiki (BallSpriteActivity<http://code.google.com/p/apptomarket/wiki/BallSpriteActivity>) below for an example of using ImageSprite and Ball collide. Please note

Lazeeb Choudhury

unread,
Feb 8, 2012, 6:20:07 PM2/8/12
to android-progr...@googlegroups.com
thanks a lot. :)

M. Hossein Amerkashi

unread,
Feb 8, 2012, 8:11:33 PM2/8/12
to android-progr...@googlegroups.com
Hi,

on item 1:
The Initialize event is equivalent to AI Screen1.Initialize block.
Initialize is the event that gets triggered ONLY AFTER screen is initialized and its width and height are no longer zero.
So, if you try to for example get screen height and width in $define, it will return 0. That's why in dispatch event, I check for "this" (AI Screen1) and "Initialize" event and the invoke some method; e.g. initData(). Then in initData I do more logic.

on item 2:
Can you post code?

Thanks,
Hossein.

Bernhard Schelling

unread,
Feb 8, 2012, 8:17:19 PM2/8/12
to android-progr...@googlegroups.com
Hi,
on item2 :

public class PongBall extends Ball{
public PongBall(ComponentContainer container) {
super(container);
// TODO Auto-generated constructor stub
}

@Override
public void EdgeReached(int edge){
int randHeading = 90 + randomGen.nextInt(10);
this.Heading(this.Heading() + randHeading);
}

@Override
public void CollidedWith(Sprite other){
//causes application to crash!
this.Heading(90);
}
}

David W Wolber

unread,
Feb 8, 2012, 8:39:08 PM2/8/12
to android-progr...@googlegroups.com
Hi Hossein. My sample is similar and the error, same as Bernhard's I think, is a stack overflow. Here's the sample (the one I changed from yours). It breaks on first collision:

package com.javabridge.samples;
 

import com.google.devtools.simple.runtime.components.Component;
 import com.google.devtools.simple.runtime.components.HandlesEventDispatching;
 import com.google.devtools.simple.runtime.components.android.*;
import com.google.devtools.simple.runtime.events.EventDispatcher;
 

public class BallAndImageSpriteActivity extends Form  {
 

     Canvas canvas;
     GameBall ball;
     GameImageSprite imageSprite;
 

   void $define() {
         canvas = new Canvas(this);
         imageSprite = new GameImageSprite(canvas);
         ball = new GameBall(canvas);
         EventDispatcher.registerEventForDelegation(this, "test", "Initialize");

      
     }
 

   @Override
     public boolean dispatchEvent(Component component, String id, String eventName, Object[] args) {
         if (component.equals(this) && eventName.equals("Initialize")) {
             initData();
             return true;
         }   
         return false;
     }
 

   /**      * Method called on startup to do caching, initialization. We need to do this so that
      * AI initializes all sounds, otherwise, it will run into issue switching between sounds.
      */
     private void initData() {
         canvas.Height(this.Height());
         canvas.Width(this.Width());
         canvas.BackgroundImage("bg.jpg");
 

       canvas.PaintColor(COLOR_BLUE);
         canvas.FontSize(10f);
 

       imageSprite.Picture("bird.png");
         imageSprite.X(this.Width() / 2);
         imageSprite.Y((this.Height() / 2) - (imageSprite.Height() / 2));
         imageSprite.Speed(12);
         imageSprite.Initialize();
         imageSprite.Interval(32);
         imageSprite.Enabled(true);
 

       ball.Radius(22);
         ball.PaintColor(COLOR_BLUE);
         ball.Speed(12);
         ball.Initialize();
         ball.Interval(32);
         ball.Enabled(true);
 

   }
     
     class GameImageSprite extends ImageSprite
     {

  @Override
  public void EdgeReached(int edge) {
  // TODO Auto-generated method stub
  this.Bounce((Integer) edge);
        this.Heading(this.Heading() - 22);
  }

  public GameImageSprite(ComponentContainer container) {
  super(container);
  // TODO Auto-generated constructor stub
  }

  @Override
  public void CollidedWith(Sprite other) {
  // TODO Auto-generated method stub
  this.Heading(this.Heading() - 55);
  }  
  }    
   class GameBall extends Ball
   {

@Override
public void EdgeReached(int edge) {
// TODO Auto-generated method stub
this.Bounce((Integer) edge);
        this.Heading(this.Heading() - 22);
}

public GameBall(ComponentContainer container) {
super(container);
// TODO Auto-generated constructor stub
}

@Override
public void CollidedWith(Sprite other) {
// TODO Auto-generated method stub
this.Heading(this.Heading() - 22);

M. Hossein Amerkashi

unread,
Feb 8, 2012, 10:00:54 PM2/8/12
to android-progr...@googlegroups.com
Please see code below:

package com.javabridge.samples;

import com.google.devtools.simple.runtime.components.Component;
            this.Bounce(edge);

            this.Heading(this.Heading() - 22);
        }

        public GameImageSprite(ComponentContainer container) {
            super(container);
            // TODO Auto-generated constructor stub
        }

        @Override
        public void CollidedWith(Sprite other) {
            super.CollidedWith(other);

            // TODO Auto-generated method stub
            this.Heading(this.Heading() - 55);
        }
    }

    class GameBall extends Ball {

        @Override
        public void EdgeReached(int edge) {
            // TODO Auto-generated method stub
            this.Bounce( edge);

            this.Heading(this.Heading() - 22);
        }

        public GameBall(ComponentContainer container) {
            super(container);
            // TODO Auto-generated constructor stub
        }

        @Override
        public void CollidedWith(Sprite other) {
            super.CollidedWith(other);

Dave Wolber

unread,
Feb 8, 2012, 11:58:53 PM2/8/12
to Android Programming at USF
Hi Hossein and thanks the code works. I see now from the API the
clever way collisions are handled and that the system registers the
collision on the first collidedwith, then doesn't fire that event
again while the two objects are still colliding (and until
NotCollidingWith is called to unregister).

Because we were overriding CollidedWith, and not calling super, the
event was firing a zillion times and causing the stack overflow. Very
interesting.

Thanks again,

Dave
> *            super.CollidedWith(other);*
>             // TODO Auto-generated method stub
>             this.Heading(this.Heading() - 55);
>         }
>     }
>
>     class GameBall extends Ball {
>
>         @Override
>         public void EdgeReached(int edge) {
>             // TODO Auto-generated method stub
>             this.Bounce( edge);
>             this.Heading(this.Heading() - 22);
>         }
>
>         public GameBall(ComponentContainer container) {
>             super(container);
>             // TODO Auto-generated constructor stub
>         }
>
>         @Override
>         public void CollidedWith(Sprite other) {
> *            super.CollidedWith(other);*
Reply all
Reply to author
Forward
0 new messages