AS-3 - How to create different draw styles? - actionscript-3

I know the flash.display.Graphics class is final and can't be extended nor its objects in sprites replaced. But I need to change its behavior or fake changed behavior. Normally in OOP I would extend a class, override its methods and call super methods like I want. But since that is not possible with Graphics, what is the best technique to achieve that ?
Is prototyping a way to modify the Graphics class the way I want ?
Let's say I want to draw squares instead of circles:
public class Graphics2 extends Graphics
{
override public function drawCircle(x: NUmber, y: Number, radius: Number): void
{
super.drawRect(x - radius, y - radius, 2 * radius, 2 * radius);
}
}
This is what I wished I could do. How can I fake it ? In the end I want to have objects that represent different draw styles. When I replace my Graphics2 object I just change the complete style of drawing (circles turn to squares etc.)

Why not just map your own class to the methods you can't extend?
public class Graphics2 {
import flash.display.Graphics;
public static function drawCircle(obj:DisplayObject, x:Number, y:Number, r:Number):void {
obj.Graphics.drawRect(x - radius, y - radius, 2 * radius, 2 * radius);
}
}
A non-override-able Class will always remain that, and the classes that extend it will always use that final method, so any change would have to be mapped on to the actual functions (IMHO).

Related

libgdx - ClickListener not affected by actor scale?

Here's a constructor for a card class I was making. When I create one that is scaled and click on it, only clicks within the 1.0x scaled area are actually registered. i.e. if I pass in 1.5 for the scale, clicks on the borders don't work. Why not? I've scaled the actor itself.
public Card(float x, float y, float scale)
{
this.setPosition(x, y);
faceSprite = new Sprite(MyResources.getInstance().cardTextureRegion);
faceSprite.setPosition(x, y);
faceSprite.setScale(scale);
borderSprite = new Sprite(MyResources.getInstance().cardBorderTextureRegion);
borderSprite.setPosition(x, y);
borderSprite.setScale(scale);
// Set boundaries for ourselves (the actor). Note that we have to match the scale of the sprites.
setSize(borderSprite.getWidth(), borderSprite.getHeight());
setScale(scale);
// Add ClickListener
final Card thisCard = this;
addListener(new ClickListener() {
public void clicked(InputEvent event, float x, float y) {
((MyStage)(thisCard.getStage())).cardClicked(thisCard);
}
});
}
Basic Actor class might be missing some functionalities, including proper scale handling. If all you want is displaying some images (judging by the Sprite objects you use), I'd suggest using the existing classes rather than making custom actors - especially since you might have trouble rendering Sprites with exact Actor parameters if you use a lot of custom actions.
Image allows you to display "sprites" - although somewhat simplified, it should be enough. To store the images, you can use a Table (more flexible) or a Stack (will work with multiple images of the same size).
If you really want to stick with the custom actor approach, try this instead of changing the scale:
setSize(borderSprite.getWidth() * scale, borderSprite.getHeight() * scale);
If you don't change Card scale manually in runtime (only set it up during creation), it should just work.
You Can use image Class to display Images.
Texture texture=new Texture("test.jpg");
Image image=new Image(texture);
//you can use setsize() or setBounds() as per your requirement.
image.setScale(scale);
image.addListener(new ClickListener(){
#Override
public void clicked(InputEvent event, float x, float y) {
((MyStage)(thisCard.getStage())).cardClicked(event.getTarget());
}
});

Post overriding the paint method of the components in java

In java awt or swing when you want to change painting of some component you usually have to override the method paint(Graphics g) (in awt) or paintComponent(Graphics g) (in swing).
This is usually (maybe allways - I'm not sure) done when you are creating the component for example:
JPanel jPanel = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
//... my implementation of paint, some transfromations, rotation, etc
}
};
Imagine that you have container of components which could for example consists of some JLabels, some JTextFields, some image. Which will be all put on one component.
By container I mean you have some list or map with ids or some similar structure in which are all components you will put on one JFrame.
The question is if I can change the painting method after creating with all of the components which are in this list in the moment when all of them are already created. For example I want do the rotation action (rotate), which is defined in Graphisc2D, with all of them.
So basicaly what I want is that I throught the list of componets I have and say:
"All of you (components) which are in the list will be rotated by some angle". Is that possible? If yes how?
Edit:
This is my not correctly working solution:
graphicalDisplayPanel = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g2d = (Graphics2D) g;
g2d.rotate(Math.PI, anchorx, anchory);
}
#Override
public void paintChildren(Graphics g) {
super.paintChildren(g);
Graphics2D g2d2 = (Graphics2D) g;
g2d2.rotate(Math.PI, anchorx, anchory);
}
};
JFrame jFrame = JFrame();
// ... setting dimension, position, visible etc for JFrame, it works correctly nonrotated
jFrame.setContentPane(graphicalDisplayPanel);
I have not tested this, but it seems like it would work. A JComponent's paint() method calls:
paintComponent(co);
paintBorder(co);
paintChildren(co);
where co is a Graphics object. In theory you create an image, retrieve the graphics object and then pass that into paintChildren(). you will have to call paintComponent() and paintBorder() yourself, if you do this. Then, just rotate the image and draw it into your component. You may have to crop the image or resize your component accordingly for this to work. It might look something like this:
BufferedImage myImage;
#Override
public void paint(Graphics g){
myImage = new BufferedImage(getWidth(), getHeight(), BufferedImage.TRANSLUCENT);
//using a transparent BufferedImage might not be efficient in your case
Graphics myGraphics = myImage.getGraphics();
super.paintComponent(g);
super.paintBorder(g);
super.paintChildren(myGraphics);
//rotation code here
// ...
//draw children onto your component
g.drawImage(myImage, 0, 0,getWidth(), getHeight(), null);
}
I hope I didn't make any mistakes, please let me know if this works.
So basicaly what I want is that I throught the list of componets I have and say: "All of you (components) which are in the list will be rotated by some angle".
If you want to rotate panel and therefore all the components on the panel as a single using then you need to do the custom painting in the paintComponent() method.
If you want to rotate, for example, individual images that each have a different angle of rotation then you can again do this in the paintComponent(...) method and change the angle for each component.
Or, in this second case you can use the Rotated Icon class. In this case the Icon is just added to a JLabel. Then you can change the degrees of rotation and repaint the label, so there is no custom painting (except in the Icon itself).

Adding shape to stage as3

I'm not sure if I'm over or under thinking this however I've got this scenario. I wish to be able to add (for now) a triangle to the page using multiple classes. The first one being adding actionscript to a frame in flash the second an actual class. Now, can I do this? Or am I silly thinking I can? I wish to do this so I can create my background as a dynamically created area where thinks I can interact with are placed on as instances of a class.
On frame
import flash.display.Stage;
var sides:Sides=new Sides();
stage.addChild(sides);
this.addChild(sides);
On class
package {
import flash.display.Shape;
public class Sides extends Shape {
public function Sides() {
var triangleHeight:uint = 100;
var triangle:Shape = new Shape();
// red triangle, starting at point 0, 0
triangle.graphics.beginFill(0xFF0000);
triangle.graphics.moveTo(triangleHeight / 2, 0);
triangle.graphics.lineTo(triangleHeight, triangleHeight);
triangle.graphics.lineTo(0, triangleHeight);
triangle.graphics.lineTo(triangleHeight / 2, 0);
triangle.graphics.endFill();
trace("Into construct");
}
}
}
The issue I have is that the actual triangle does not appear on the screen it's blank. I know the constructor is ran, however I get no actual output as such.
I hope I made myself clear. If anyone can suggest a better solution I would love to hear it. My scenario is this.
I wish to create a world that other movie-clips can interact with. I will be creating lines to represent them. Now is it better to do it dynamically generated or is there a way to have some sort of base class that all of the other ones run off where that allows me to have random width. Hope this is clear.
you create an instance of a Shape within your Sides constructor to which you draw the triangle however this shape is never added to a display list, instead you add your instance of Sides (which itself has nothing drawn) to a display list.
Because your Sides class is extending Shape you don't need another instance of a Shape, your instance of Sides itself is a Shape and you can draw directly to it like so:
package {
import flash.display.Shape;
public class Sides extends Shape {
public function Sides() {
var triangleHeight:uint = 100;
// red triangle, starting at point 0, 0
this.graphics.beginFill(0xFF0000);
this.graphics.moveTo(triangleHeight / 2, 0);
this.graphics.lineTo(triangleHeight, triangleHeight);
this.graphics.lineTo(0, triangleHeight);
this.graphics.lineTo(triangleHeight / 2, 0);
this.graphics.endFill();
trace("Into construct");
}
}
}

AS3: How do i draw shapes in my own class

I'm very new on AS3. I would like to create a shape as i defined in my own constructor class.
It should create a shape when class was created. (Constructor)
I commented my want in following code :
ballShape class
public class ballShape {
public function ballShape() {
// define shape properties.
// create shape and put that in x = 0, y = 0
}
}
Any helps would be awesome.
You can easily do this while extending your class to Shape or Sprite
Here's your code
public class ballShape extends Sprite {
public function ballShape() {
// define shape properties. The graphics object is already added to your Sprite, no need to manually addChild() this object.
graphics.beginFill(color, alpha); // you can begin a fill with this method, there are also methods to start a bitmap fill, gradient fill.
graphics.drawRect( x, y, width, height ); // draw a shape
graphics.endFill();
}
}
While Shape can have the same functionality to draw shapes and lines, I chose Sprite, because:
You will have interactivity and be able to dispatch events from that class
You will have a set of useful properties that Sprite has.
For more info on the Graphics class, please refer to http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Graphics.html

Flash ActionScript 3 - Draw static 3D cube

I'm trying to draw a 10x10 grid with Actionscript 3 with a vanishing point behind - so each square looks like it's coming towards the screen (each from its own relative perspective).
I've found many tutorials for 3D perspective cubes, but they all revolve around movement. Surely static shapes must be easier, but I'm yet to find any help regarding them.
Is there some way I can use PerspectiveProjection() in my case where it doesn't involve movement? It looks to be exactly what I want, yet seems reliant on movement.
Or are there any other methods for 3D perspective object creation?
I'd prefer to use internal AS3 functions if possible.
The closest I've got was this tutorial , which I could likely apply to my situation, but I want to make sure there's not an easier/cleaner way before attempting it.
Thanks.
Here's the fastest and probably most recommended way to achieve what you're after:
Download the Papervision3D library for AS3.
Once you've done this, create a document class and paste inside it this code that I've created for you to get you started:
package
{
import org.papervision3d.view.BasicView;
import org.papervision3d.objects.primitives.Cube;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.materials.ColorMaterial;
/**
* Document class.
* #author Marty Wallace.
*/
public class Base extends BasicView
{
/**
* Constructor.
*/
public function Base()
{
// Create an array of faces for your cube.
var faces:Array = [
"front",
"back",
"left",
"right",
"top",
"bottom"
];
// Create a list of materials, which contains a material for each face of the cube.
var list:MaterialsList = new MaterialsList();
// Create a new material for each face.
for each(var i:String in faces)
{
// Define the material.
var material:ColorMaterial = new ColorMaterial(Math.random()*0xFFFFFF);
// Add your material to the face represented by i.
list.addMaterial(material, i);
}
// Create the Cube.
var cube:Cube = new Cube(list, 250, 250, 250);
// Rotate the cube to however required.
cube.rotationX = Math.random()*360;
cube.rotationY = Math.random()*360;
cube.rotationZ = Math.random()*360;
// Add the cube to the scene.
scene.addChild(cube);
// Render the cube.
startRendering();
}
}
}
The majority of the code is pretty self explanatory and there are uint.MAX_VALUE tutorials around for this particular framework.
Enjoy!