Extending Group in LibGdx - libgdx

I created a group in my Project's play screen. The group contains a number of images and buttons as actors.
Group newGroup = new Group();
inside show()
newGroup.addActor(bg);
stage.addActor(newGroup);
This works well.But I want to add a lot more things in the group.Also I need to create few more groups also.So I think I can create new classes that extends the Group. Actually I want to use a modular way to create these groups.
public class newGroup extends Group {
//want to add actors here-buttons,images and other scene2d elements
}
public class actor extends Actor{
}
I have something like this in mind to do but I don't know how to do this effectively, so that I can move and scale the group items and access in play screen.
Please tell me how can I properly extend the Group in LibGdx and access it in play screen.

So, you need to do same things as in your example but do it your extended class. Maybe my short example will help you.
There are SKIN variable in the examples below. I haven't showed how to load the skin. Read about Scene2D.ui to understand the meaning of the SKIN.
First example (with no extending):
Group group = new Group();
TextButton b = new TextButton(SKIN, "Press Me");
Label l = new Label(SKIN, "Some text");
b.setPosition(0, 0); //in groups coordinates
l.setPosition(0, 100);
group.addActor(l);
group.addActor(b);
stage.addActor(group);
You can do the same with extending:
public class MyGroup extends Group {
private TextButton b;
private Label l;
public MyGroup() {
b = new TextButton(SKIN, "Press me");
l = new Label(SKIN, "Some text");
b.setPosition(0, 0); //in coordinates of group
l.setPosition(0, 100);
//now we will add button and label to the our extended group.
this.addActor(b);
this.addActor(l);
//"this" is unnecessary. I write this because it
//may be more clear for you to understand the code.
//"this" is our extended group and we add actors to it.
}
}
So, now you can create our new group and add it to the Stage:
MyGroup myGroup = new MyGroup();
myGroup.setPosition(200, 200); //also in `stage` coords.
stage.addActor(myGroup);

Related

Making a simple tamagoci game getting no compiler errors but receiving no output

Kind of new Actionscript and I'm just trying to make a simple tamagoci game. I've wrote all the code out but and receiving no compiler errors but for some reason I'm also not receiving any output messages for my mouse event listeners. Here is all my code, I really can't find the problem and any help would be greatly appreciated. Thanks.
package{
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class Main extends MovieClip{
public var feedButton:MovieClip;
public var tamagoci:MovieClip;
public var disButton:MovieClip;
public var dietButton:MovieClip;
public function Main() {
this.init();
}
private function init():void {
this.feedButton.addEventListener(MouseEvent.MOUSE_DOWN, onfeedMouseDownHandler);
this.disButton.addEventListener(MouseEvent.MOUSE_DOWN, ondisMouseDownHandler);
this.dietButton.addEventListener(MouseEvent.MOUSE_DOWN, ondietMouseDownHandler);
}
private function onfeedMouseDownHandler(event:MouseEvent)void{
this.tamagoci.scaleX += 0.1;
this.tamagoci.scaleY += 0.1;
}
private function ondisMouseDownHandler(event:MouseEvent)void{
this.tamagoci.gotoAndPlay(5);
}
private function ondietMouseDownHandler(event:MouseEvent)void{
this.tamagoci.scaleX -= 0.1;
this.tamagoci.scaleY -= 0.1;
}
Are you using Flash Professional?
You're declaring your variable types in your class here;
public var feedButton:MovieClip;
public var tamagoci:MovieClip;
public var disButton:MovieClip;
public var dietButton:MovieClip;
But then in your constructor, all you are doing is running init();
public function Main() {
this.init();
}
So, this could one of a few things. The most likely is that you have declared your variables, but you haven't initialised them. You've created the variables to hold your objects, but according to your code, they're empty. More specifically, a variable or class property that doesn't assign an object to a variable of an object type will contain a default value of null.
You could prove this in your code by simply putting a condition inside your init(); method;
if(tamagoci == null){
trace("I haven't been assigned an object of type class yet!")
}
So it could be 1 of these 3 things:
1: If you have written your own classes for these class properties/variables, then you need to instantiate them with the new keyword. The general syntax is;
variable_name = new ClassName(parameter_1, parameter_2);
If you are using classes you have written yourself, you have to create an instance of the object, assign it to a variable, and then add it to the stage using addChild();. For example, lets say you've written your own Tamagoci class;
tamagoci = new Tamagoci();
tamagoci.x = 100; // set the x location
tamagoci.y = 200; // set the y location
addChild(tamagoci);
Notice the use of Tamagoci. This is just an example, but this is the class name, which shouldn't be confused with variable/property name. It could just have easily been;
tamagoci = new MovieClip();
But then, this is just an empty MovieClip. It needs a property to display on the screen. A Shape, A Bitmap, or another container class object like MovieClip or Sprite (container classes allow you to nest display objects inside them). But on a basic level, it must contain a visual component to appear on the stage.
2:
Have you made Main your document class? This is the class which will get automatically called when your Flash movie plays. To set this, click on your stage, and in the properties dialogue box on the right, under PUBLISH, type in the name of your class, which is "Main".
3:
If you have created MovieClips in your library in Flash Professional, then you need to go to your library, right click the MovieClips, and select properties. From there, you need to make sure Export for Actionscript is ticked.
Now, if you click on your MovieClips on the stage, then open the Properties tab in the top right of Flash Professional's default layout, then right at the top should be a text field, and if you hover over it, Instance name will pop up as a tool tip. This is where you name your stage objects. Once that is done, you have access to them in your timeline.
If this is how you've done this, then you don't need to declare the variables in your main class, as they are already declared on your stage by Flash Professional and instantiated automatically.

Multiple levels

I was reading a tutorial about creating multiple levels, and the below really interested me on how i should go about this.
It may seem natural to make one class per level, with each class
extending AvoiderGame, and use events to switch between them. So, we
might have classes named AvoiderGameLevelOne, AvoiderGameLevelTwo,
etc., and let each one fire off a “NavigationEvent.NEXT_LEVEL” when
appropriate. Presumably then the document class would listen for this
event, and when it heard it, it would run “playScreen = new
AvoiderGameLevelTwo()” (or whichever level was appropriate), and pass
through all the information such as score and time to this new
playScreen instance.
I'm not entirely sure on how to go about this. I put my stage, which is an array of tiles in a class called level1, level2, etc and had it extend my main class. Just to check if everything works, I added a public static var called levelArray in my main, which is a blank array. Then in level1, I pushed my array into levelArray.
So for my level1 class
package {
public class Level1 extends Main {
public var floor1:Array = new Array();
floor1[0] = [2,1,1,1,1,1,2];
floor1[1] = [1,1,1,1,1,1,1];
floor1[2] = [1,1,1,2,1,1,1];
floor1[3] = [1,1,1,1,1,1,1];
floor1[4] = [1,1,1,2,1,1,1];
floor1[5] = [1,1,1,1,1,1,1];
floor1[6] = [2,1,1,1,1,1,2];
public function Level1() {
Main.levelArray.push(floor1);
}
}
}
Doesn't seem to be working. levelArray comes up as blank. Might be because the two classes aren't communicating with each other correctly? Any ideas if I am approaching this the correct way?
I dont know if the rest of your concept is sound, but I think the syntax is off for the part you have shown. try:
package {
public class Level1 extends Main {
public var floor1:Array = new Array( [2,1,1,1,1,1,2],
[1,1,1,1,1,1,1],
[1,1,1,2,1,1,1],
[1,1,1,1,1,1,1],
[1,1,1,2,1,1,1],
[1,1,1,1,1,1,1],
[2,1,1,1,1,1,2]
);
public function Level1() {
Main.levelArray = floor1;
}
}
}
EDIT: if the only thing distinct about each level is the array that forms the floor, you may consider the fact that you do not need a new class for each level, just a new array. you can define the arrays for each level in the class that is super to this one and then just replace them with each progression.

as3 animation with multiple images

I have only 3 images that I'm working with for animating a running animal:
1: animal standing
2: animal in stride/jumping
3: animal on its back dead
Currently, I'm embedding them into the main class as sprites and changing their .alpha properties whenever I want one and not the other 2. Is there a better way to do what I'm doing? One of the annoying things is updating the properties for each sprite individually. It would be ideal to have one object and being able to change the image on the object so I would only have to change one object's properties.
For this it would be best to handle your animation in its own Class!
Something like this, let's say your animal is a horse so that's what I'll call the class
package {
import flash.display.Sprite;
public class Horse extends Sprite{
private var holder:Sprite = new Sprite();
public function Horse() {
var img1:Image1 = new Image1();// ur images from library
var img2:Image2 = new Image2();
var img3:Image2 = new Image3();
holder.addChild(img1);
holder.addChild(img2);
holder.addChild(img3);
addChild(holder);
setImage(0);// set 1st image visible
}
public function setImage(nr:uint):void
{
for(var i:int = 0; i < holder.length;i++;)
holder[i].visible = false;
holder[nr].visible = true;
}
}
}
then you would use it like this for example!
var horse:Horse = new Horse();
addChild(horse);
horse.x = 25;
horse.y = 25; // move the whole object(all 3 images)
horse.setImage(2);// or to whatever frame you need
Use the visible attribute instead of the alpha value. If u just set alpha to 0 it will still be rendered and cost cpu. if you set visible to false it will not be rendered!
EDIT: As Amy pointed out, blitting is a possibilty here to, although the fastest aproach would be BitmapData Frame Assignment!
Here you keep all your Frames as BitmapData in a Vector, which you load from a SpriteSheet and just assign the new BitmapData to your Bitmap instead of using copyPixels. It's faster then blitting and you still have all your builtin methods availible!!

AS3 - Trying to declare the value of a Movie Clip

Okay, I have the following code in my Bullet.as file:
public var impact:MovieClip;
public function Bullet():void
{
addEventListener(Event.ADDED_TO_STAGE, whenAdded);
}
function whenAdded(e:Event)
{
if(this is zArrow){
power = -1;
speed = 15;
impact = arrowImpact;
trace(impact);
}
if(this is Dice){
power = -Math.round(Math.random()*5 + 1);
speed = 10;
impact = diceImpact
}
}
See, I am trying to set the value of "public var impact:MovieClip" as the movie clip "arrowImpact" or "diceImpact". What I want is whenever a bullet collides with an enemy, it leaves an impact image behind and I'm trying to change what impact is shown depending on what bullet is colliding.
I am able to change all of the other variables like power and speed using this setup, but I can't declare which impact movie clip the "impact" movie clip variable is.
From the way I understand your question now, you want to pull these specific movie clips from the Library. If I am not mistaken. To do this, you need to pair each of the movie clips in the library to an AS class that extends MovieClip.
Make sure you check "Export for Actionscript" and create the class you want for each. Then, in your code for the Bullet, you can create a new instance of them. So have it say:
impact = new ArrowImpact)();
or DiceImpact depending on your classes.
Hope this is along the lines of what you wanted.
In order to use these, I would recommend creating a getImpact method along the lines of:
public function getImpactMC():MovieClip
{
return impact;
}
Then all you need to do in your main Document is addChild the proper impact from this method. However, be aware that you need to adjust the x and y values of the impactMC before adding it as a child on the stage to make sure that it displays in the proper position.
Glad this helps!

Drag and clone MovieClip in AS3

I have a toolbar with some cars on the left of the window, and I want to click on one element and drag it to the board creating a clone of it, but I can't do it.
My app looks like this:
Cars on the left are my desired dragged.
My source code is:
public class Car extends MovieClip
{
// imports...
var newcar:Car;
public function Car(){
addListeners();
}
private function addListeners():void{
this.addEventListener(MouseEvent.MOUSE_DOWN,clone);
}
private function clone(e:MouseEvent):void{
// Clone the object
newcar = new dibujo();
newcar.graphics.copyFrom(this.graphics);
newcar.x = this.x;
this.parent.addChild(newcar);
// Asign new events to recently created mc
newcar.addEventListener(MouseEvent.MOUSE_OVER,dragCar);
newcar.addEventListener(MouseEvent.MOUSE_UP,dropCar);
}
private function dragCar(e:MouseEvent):void{
this.startDrag();
}
private function dropCar(e:MouseEvent):void{
this.stopDrag();
}
}
The red car and the truck use my own basic class called 'Car'.
Thanks in advance! I hope someone can help me.
And what is not working?
Main problem I see is, that you create new car, but you don't add it to the display list. In your clone function, you need something like
this.parent.addChild(newcar);
edit:
So as I said in comments, problem is, tah property graphics is read only, so you can't change it.
If your cars are instaces of classes that extend your Car (if they are not, you can easily make them), you can use this:
replace
newcar = new dibujo(); //I think you menat new Car() here
with
newcar = new e.target.constructor;
this should finally make it work.
You will then encounter problem with dragging - it never stops. But solution is simple, add this line to your stopDrag function:
e.target.removeEventListener(MouseEvent.MOUSE_MOVE, dragCar);