LibGDX - Ending a Level and breaking out of Render() - libgdx

The basic idea of the game is to collect all the items in a room in order to proceed to the next. Not very original I know... When the items are all collected, a screen will be displayed stating "Level Complete" and then after a few seconds the next level will be reloaded. The problem I am having is that when I land on the last item, and the check "have all the items been collected?" rule is satisfied the game suddenly freezes, well starts to shake actually. The player sprite is frozen in place, as is the item, and the game can no longer be interacted with. I can only assume that the game is getting trapped inside the render() method and is not escaping, or is satisfying the same condition over again.
Does anyone have any ideas on how to break out of the main render() method correctly to traverse to a new screen?
In my main render() method I have a call to another method which checks the gamestate, ie, have all of the items been collected in the room...
render() {
... code ...
checkGameState()
}
And then checkGameState() looks as follows:
public void checkGameState()
{
//If the player has collected all of the items on a level then do something
//if(stats.getItemsCollected() == stats.getTotalItems()) {
//reset some stuff
stats.resetItems();
stats.incLevel();
//show the intermediate screen or menu screen
//load the next level
showLevelCompleteScreen();
//
}
}
The ShowLevelCompleteScreen() method simply attempts to switch screens as follows:
public void showLevelComplete()
{
game.setScreen(SuperBlockMan.LevelComplete);
}

First I'd advise you to not reset your Screen, but to dispose() it correctly and then create a completely new one after one level finished. That saves you from bugs due to incorrect resetting.
After you switched the Screen to LevelComplete, the rendering will not stop, but libGDX will start to call render of your LevelComplete Screen.
As for the freezing of your character, item and so on, I guess you do not call Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); in the render method of your LevelComplete Screen and that's why you can still see everything from your game, but cannot interact anymore.

Related

Libgdx and Box2d / Particles are not following bodies

i'll just cut to the chase.
So i'm making this game where you should kill other objects with your spells i've created bullets and their bodies we're all good it's working.
But i wanted to make it look special and "magiclike" so i decided to use particles. I've made the particles and put and made them follow the bullet bodies with this code:
for (Bullet bullet : bullets) {
bullet.update(dt);
if (!bullet.destroyed){
fireFx.start();
fireFx.setPosition(bullet.getPosition().x, bullet.getPosition().y);
fireFx.update(dt);
}
}
but there's a problem when i fire multiple bullets particles are just dissappearing from the all of the first bullets i fired and just appears on the last one. Can someone lead me on this one please ?
-----------------EDIT-----------------
Now i've got another problem that when bullet collides with something it gets destroyed and render method stops working but i want it to keep rendering till the animation is over. Like i don't want them to disappear suddenly here is my code for this:
for(int i = 0; i<bullets.size; i++){
if(!bullets.get(i).destroyed && !bullets.get(i).fireFx.isComplete())
bullets.get(i).fireFx.draw(game.batch);
}
fireFx.isComplete() is not working correctly what is the reason ?
The issue is that you're updating a single particle to have the coordinates of all the bullets in a list, and effectively keeping the coordinates of the last bullet in the list. You could maintain a Map that maps Bullets onto Particles, but I would instantiate a fireFx object when a Bullet is created and add it to the Bullet object. Then, in the Bullet#update method you can call the particle update method:
public void update(float dt) {
[...]
if ( !this.isDestroyed()) {
[...]
this.fireFx.start();
this.fireFx.setPosition(this.getPosition().x, this.getPosition().y);
this.fireFx.update(dt);
[...]
}
[...]
}

Cocos2d-x 3 - Disable collision between two bodies and detect when them separate each other

I'm developing a cocos2d-x game (version 3.8). My game uses chipmunk physics and it has a static body that works like an interruptor. This interruptor is enabled when another body is over it. The interruptor is disabled when bodies separate each other.
I want to:
Moving body don't collision with interruptor. It has to cross interruptor with no bounce
I want to detect when moving body separates the interruptor
My first approach was implementing onContactBegin method. I return false when those two bodies get in touch. This way the body crosses the interruptor and does not bounce.
The problem is onContactSeparate method is not called, because contact did not happen.
If I return true in onContactBegin method, onContactSeparate is called and I can detect it. The problem is the body does not cross the interruptor, it bounces.
[EDIT] More info
This is the scenario where two sprites are separated. The ball can move and interruptor is a static body. Ball could be over the interruptor.
This is the scenario where two sprites are in contact and object1 (the ball) is over the interruptor. I want to detect where two sprites separate each other.
Any help would be appreciated!
It seems to me like you are using Box2D within cocos, so I'll answer with that as my base assumption.
This is what i would do.
My interrupter would be a b2Body* with no BodyDef dimensions defined or just a 0x0 dimension def.
I would set the user data for the bodyDef to a rectangle that describes my interruption area. This way you can always have your interruption area represented, but will not collide with anything.
(Optional) If you want the interruption area to move around based on the fake body you assigned to it, you can updated it just after the step function using something like below.
world->Step(delta, 10, 10);
for (auto physicsBody = _world->GetBodyList(); physicsBody; physicsBody = physicsBody->GetNext())
{
auto userData = static_cast<Node*>(physicsBody->GetUserData());
if(userData != NULL)
{
// Set interruptor area rectangle = physicsBody->GetPosition();
}
}
To let the rest of the system know when I have left the interrupter I would store a function pointer to the function I want to call when this happens, When a object enters the interruption area I would flag it saying "I'm in the area" after that, the first update step you get when it's not in the area anymore I would fire the callback and reset the flags I used to get to that point.
I hope this helps. You are not giving a lot of context for what you want to do, an image would be helpful. Especially when it comes to looking for help with code that has a visual representation as well.
[EDIT]
Based on the behaviour you want this is the way I did this. The first thing to know is that you don't need physics collisions for the behaviour you want. You can do this by using bounding box intersection tests and use flags and callbacks to figure out the rest.
I have an object that knows about both the ball and my interrupter nodes. In the update loop of this object I check if the two intersects. I set a flag indicating "I am in the interrupter", the next frame that I am not in the interrupter and my flag is still true I call the function that I assigned with my "leaving logic" in it, and set then flag back to false.

What is this, and why is it happening?

So I have been working on my final project for the semester for my Computer Systems class, and we have been tasked to make a game using Flash and ActionScript 3.0. I've pretty much completed everything but I have come across an extremely strange occurrence of Flash CS6 being silly. I am moving a MovieClip up and down depending on a selected index, however, the image leaves 'residue of it's footprints' behind and also moves. I have tried hard to look for an answer as to why this is happening, but I don't know what it's called, or how to appropriately explain it - I'm coming from an area where one must program graphics, not just simply, drag and drop.
Below are pictures as to what I've come across, but first the code I'm using:
function updateThemeScreen():void {
button_selection.y += (selectedPositions[selectedTheme] - button_selection.y) / 2;
}
function attemptThemeChange(mxP:Number, myP:Number):void {
if(objectContains(theme_darkness, mxP, myP)) {
selectedTheme = 0;
} else if(objectContains(theme_halloween, mxP, myP)) {
selectedTheme = 1;
}
}
As you can see in the final image, it has copied half of itself and left it at the last button, which is strange, and shouldn't happen...
Link to the SWF zipped up with the required AS3 classes: Dude, RUN
So it seems that I have magically fixed this problem by hiding the buttons and showing them all in one frame. I don't know what this problem is or why it does it, but to fix it, you just need to hide and show the affected components - yes, in one frame:
function hideShow(object:MovieClip):void {
object.visible = false;
object.visible = true;
}

Why do my buttons only work on the first frame of the main timeline in Flash AS3?

I'm trying to code the navigation of a Flash AS3 project in an actionscript file. In the project there are several frames with buttons to navigate through the project. The ones I have coded for the first frame work, but on any other frame they don't.
here is the code:
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class Main extends MovieClip
{
public function Main()
{
trace("it's working");
btn_one.addEventListener(MouseEvent.MOUSE_UP,eventResponse1);
btn_two.addEventListener(MouseEvent.MOUSE_UP,eventResponse2);
btn_three.addEventListener(MouseEvent.MOUSE_UP,eventResponse3);
btn_four.addEventListener(MouseEvent.MOUSE_UP,eventResponse4);
btn_five.addEventListener(MouseEvent.MOUSE_UP,eventResponse5);
btn_six.addEventListener(MouseEvent.MOUSE_UP,eventResponse6);
}
function eventResponse1(evt:MouseEvent):void
{
gotoAndStop("game");
}
function eventResponse2(evt:MouseEvent):void
{
gotoAndStop("specimenroom");
}
function eventResponse3(evt:MouseEvent):void
{
gotoAndStop("how");
}
function eventResponse4(evt:MouseEvent):void
{
gotoAndStop("game");
}
function eventResponse5(evt:MouseEvent):void
{
gotoAndStop("feedback");
}
function eventResponse6(evt:MouseEvent):void
{
gotoAndStop("home");
}
}
}
In the code the first five buttons work, but the sixth doesn't. This button is not located on the first frame of the main timeline, it's on the second and third frame. It doesn't work at all. What code is needed to get them to work? Any help is much appreciated, thank you.
The button must be present on the frame that the AS3 code gets executed on.
For example, if your button is on frame 2 and your code that tries to add the listener is on frame 1, that will not work.
I assume you are using a Document class, so the same applies. Only what is present on the stage at the time that constructor code runs, is available for you to work with.
What you could do is have a method that adds listeners to the appropriate buttons when you go to that frame.
There are other solutions that would require a more radical change to your current design of using the timeline to change screens, so I suggested the one that would require minimum change.
Because you asked in comments another possible solution is to not navigate through your different screens via timeline frames, but instead do it via code and MovieClip symbols that contain your UI screens. You would just create the instances of the screens in code as needed and handle their handlers appropriately when doing so.
other solution is that make button accessible on first frame and change its alpha to zero so that its not visible. This why u will not have to change the code and just change the time line.

Movieclip stacking in Actionscript

I'm building a game of which the interface is one of the first items to load on screen. Sound button, pause and all the bits -
During the game - all manor of things are dynamically added and removed to the stage. Therefore my interface goes behind my game scene.
How do I ensure the movieclip always stays on top?
Can I override the addChild of my Document Class and every time a new child is added, I restack the interface to the top?
You can use setChildIndex to rearrange objects that are already contained within a MovieClip or Sprite. For example, if you have an object called container, which contains a redBall, blueBall and many other ball objects, you can use the following to make sure redBall is behind everything else:
container.setChildIndex(redBall, 0);
Equally you can make sure that blueBall will be displayed infront of everything else using:
container.setChildIndex(blueBall, container.numChildren-1);
addChildAt will sort you out for adding children straight into their correct position, and setChildIndex will allow you to re-position objects already placed. Hope that helps.
debu
Look into addChildAt, it allows you to specify the index that the new object should be added too.
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/DisplayObjectContainer.html#addChildAt%28%29
A good strategy is to keep all interface elements in one parent Sprite/MovieClip, and all game assets in another. (With the interface one on top)
With your guys suggestion I made this, apparently, if you addChild an object already on the screen, it's simply reindex'd to the top. Does this look ok?
private var topLevelChildrenArray:Array = [];
public function addTopLevelChild(child:DisplayObject):DisplayObject
{
topLevelChildrenArray.push(child)
return this.addChildAt( child, this.numChildren - 1 );
}
override public function addChild(child:DisplayObject):DisplayObject
{
this.addChildAt(child, this.numChildren);
for each(var topChild:DisplayObject in topLevelChildrenArray)
{
super.addChild(topChild);
}
return child
}