How to make a sprite blink X seconds? - libgdx

I'm using libGDX and I want to make my main character of my game to blinking x seconds on enemy touch (lose life)
Can someone tell me how can I make sprite to blinding?

Here is my solution, I use it exactly for the same purpose you described (blinking character when he injured).
public class Blinker {
private float BLINK_TIME = 1f;
private int BLINKING_FRAMES = 4;
private boolean isBlinking;
private int blinkFrameCounter;
private float blinkTimer;
public Blinker() {
this.blinkTimer = 0;
this.blinkFrameCounter = 0;
this.isBlinking = false;
}
public boolean shouldBlink(float delta) {
if (isBlinking) {
blinkTimer += delta;
blinkFrameCounter++;
if (blinkTimer < BLINK_TIME) {
if (blinkFrameCounter % BLINKING_FRAMES == 0) {
return true;
}
} else {
blinkTimer = 0;
isBlinking = false;
}
}
return false;
}
public boolean isBlinking() {
return isBlinking;
}
public void setBlinking(boolean isBlinking) {
this.isBlinking = isBlinking;
}
}
Usage:
first init the blinker object;
Blinker blinker= new Blinker();
blinker.setBlinking(true);
and then just add this to your draw() method (I suppose that you have separate method for drawing character, which you call in your screen draw method), before you draw the sprite you want to blink.
if (blinker.shouldBlink(delta))
return;

I recommend looking at something like this.
https://github.com/libgdx/libgdx/wiki/2D-Animation
You use this technique and adjust the frame duration.
walkAnimation = new Animation(0.025f, walkFrames); // #11
When you need to start making the animation blink faster. adjust the frame duration value.
public void setFrameDuration(float frameDuration)
I recommend doing it this way but if you HAVE to tint it w/e.... I guess this works.
private Texture texture;
private TextureRegion region;
private Sprite sprite;
...
texture = new Texture(Gdx.files.internal("image.png"));
region = new TextureRegion(texture, 20, 20, 50, 50);
sprite = new Sprite(texture, 20, 20, 50, 50);
sprite.setPosition(100, 10);
sprite.setColor(0, 0, 1, 1);
...
batch.begin();
batch.setColor(1, 0, 0, 1);
batch.draw(texture, 10, 10);
batch.setColor(0, 1, 0, 1);
batch.draw(region, 50, 10);
sprite.draw(batch);
batch.end();
key thing is Alpha is ignored if blending is disabled.

The previous answer from prgenhard will work, but I don't think that is sufficient enough, if you are using it without care.
You can use TweenEngine to interpolate alpha value with different functions.
It can be really cool.
Those values you can set on sprite's or actor's alpha and easily achieve flashing effect.
You can read more about it here:
http://www.aurelienribon.com/blog/projects/universal-tween-engine/
It should be enough.
And also it can be easily used within Libgdx engine.
Hope this helps.

Related

LWJGL/OpenGL -- Not drawing basic quad

I have looked everywhere, and I can't seem to get OpenGL to draw a simple quad.
The window shows up fine with the correct color background, but OpenGL just won't draw the box.
I am using OpenGL 4.4.0 - Build 20.19.15.4463
The window size is 1920x1080
This is the code I currently have:
in Main.java:
public void init(){
if(glfwInit() != true){
System.err.println("GLFW failed to initialize");
}
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
//TODO change name.
window = glfwCreateWindow(width, height, "GameName", NULL, NULL);
if(window == NULL){
System.err.println("Window failed to be created");
}
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(window, 100, 100);
glfwMakeContextCurrent(window);
glfwShowWindow(window);
GL.createCapabilities();
glClearColor(0.0f, 0.5f, 1.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
//set up projection matrix; allows us to draw.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, height, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
testBox = new EntityBox(3, Color.RED);//just to test right now
System.out.println("OpenGL: "+ glGetString(GL_VERSION));
}
public void update(){
glfwPollEvents();
}
public void render(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glfwSwapBuffers(window);
testBox.draw();
}
in EntityBox:
public void draw(){
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_QUADS);
glVertex2f(0,0);
glVertex2f(0,100);
glVertex2f(100,0);
glVertex2f(100,100);
glEnd();
}
I fixed it:
glClear needs to be
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
don't know why, because i was tole depth_buffer is used if you want 3d.
and
glfwSwapBuffers(window);
needs to be called after drawing.

libGDX 1.4.1 can't slow down animations

This is what I have:
...
private Array<Sprite> fireballFadeOutAnim;
private Array<Sprite> bucketFadeOutAnim;
private TextureAtlas fballAnimSheet;
private TextureAtlas bucketAnimSheet;
private Animation catch_animation;
private Animation visual_feedback;
private float elapsedTime = 0f;
...
#Override
public void create () {
...
fballAnimSheet = new TextureAtlas("animations/fireball_fadeout.txt");
bucketAnimSheet = new TextureAtlas("animations/bucket_fadeout.txt");
fireballFadeOutAnim = fballAnimSheet.createSprites("fireball_fadeout");
bucketFadeOutAnim = bucketAnimSheet.createSprites("bucket_fadeout");
catch_animation = new Animation(1/15f, fballAnimSheet.getRegions(), Animation.PlayMode.NORMAL);
visual_feedback = new Animation(1/15f, bucketAnimSheet.getRegions(), Animation.PlayMode.LOOP);
...
}
#Override
public void render () {
...
// Set the anim_elipsed_time
elapsedTime += Gdx.graphics.getDeltaTime();
...
// I try to draw them later on (under the render method) like this:
// Start and draw animation of fireball catch
batch.begin();
batch.draw(catch_animation.getKeyFrame(elapsedTime, true), fireBallRect.getX(), fireBallRect.getY());
batch.end();
}
I can see both animations happening extremely fast (they look like a white-flash), they do not loop even if the animation mode is set to "LOOP".
What am I doing wrong ? I can't seem to be able to slow them down or to have them LOOP. Thanks much.
Edited:
As requested, I upload all the code
public class MainActivity extends ApplicationAdapter {
public enum State {
PAUSE,
RUN,
RESUME,
STOPPED
}
public static State state = State.RUN;
private SpriteBatch batch;
private OrthographicCamera camera;
private Stage stage;
private Texture backgroundImage;
private Texture bucketImage;
private Texture fireballImage;
private Texture heart;
private TextureRegion criticalTexture;
private Sprite backgroundSprit;
private Sprite bucketSprite;
private Sprite fireballSprite;
private Sprite heartSprite;
private Rectangle bucketRect;
private Rectangle fireBallRect;
private Rectangle bucketSpriteRect;
private ShapeRenderer bucketRenderer;
private ShapeRenderer fireballRenderer;
private Button pauseButton;
private Array<Rectangle> fireballArray;
private Skin progressBarSkin;
private long lastFireballTime;
public static Sound bucket_tap;
public static Sound bucket_drag;
private Sound fireball_missed_sound;
private Sound catchFireball;
private Sound pauseBtnSound;
private Music bgMusic;
private float volume = 0.30f; // music and sfx volume control
public static int w;
public static int h;
private int barLength = 325;
private int numberOfFails = 10; // change numberOfFails to increase or decrese
// the total num. of missed fireballs the player
private int deductedBarSegment = barLength / numberOfFails;
private int numOfBallsLeft = numberOfFails; // use this var to check how many fballs left
private long fireballFrequency = 1000000000L; // change fireballFrequency to increase or decrease
// the number of fireballs on the screen
private int fireballSpeed = 400; // change the fireballSpeed to increase or decrease
// the speed at which the fireballs fall
private InputProcessor gameInputProcessor; // this sets the game input controller for the bucket
private InputMultiplexer multiplexer; // this sets the input processors from the game and UI
/************************************ Animation Properties ************************************/
private TextureAtlas fballAtlas;
private TextureAtlas bucketAtlas;
private Animation catch_animation;
private Animation visual_feedback;
private float elapsedTime = 0f;
private Actor feedbackPanel;
/**********************************************************************************************/
#Override
public void create () {
// Parse Test
//ParseObject testObject = new ParseObject("TestObject");
//testObject.put("foo", "bar");
//testObject.saveInBackground();
// Catch the dynamic size of the screen based on the device that's ran on
w = Gdx.graphics.getWidth();
h = Gdx.graphics.getHeight();
// Set up the camera
camera = new OrthographicCamera();
camera.setToOrtho(false, (float)w, (float)h);
// Instantiate the batch
batch = new SpriteBatch();
/***************************** These renders are for debugging only *****************************/
bucketRenderer = new ShapeRenderer();
fireballRenderer = new ShapeRenderer();
/**************************************************************************************************/
/******************************************** Stage and HUD ***************************************/
stage = new Stage();
pauseButton = new Button(new TextureRegionDrawable(
new TextureRegion(new Texture(Gdx.files.internal("images/pase_button_red.png")))),
new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("images/pase_button_white.png")))));
pauseButton.setX(flipCoordinates(w, 150));
pauseButton.setY(flipCoordinates(h, 170));
pauseButton.act(Gdx.graphics.getDeltaTime());
stage.addActor(pauseButton);
pauseButton.addListener(new ChangeListener() {
#Override
public void changed (ChangeEvent event, Actor actor) {
// Do something when the pauseButton is pressed
// Control multiple touches on the pauseButton
if(state == State.RUN) {
state = State.PAUSE;
pauseBtnSound.play();
// Set the pauseButton icon to the white version
//pauseButton.setColor(Color.WHITE);
}
else {
state = State.RUN;
pauseBtnSound.play();
}
}
});
// Add the critical_life indicator to the stage as an actor
criticalTexture = new TextureRegion(new Texture(Gdx.files.internal("images/critical_life.png")));
feedbackPanel = new Actor() {
public void draw(Batch batch, float alpha) {
batch.draw(criticalTexture, getX(), getY(), getOriginX(), getOriginY(), getWidth(), getHeight(),
getScaleX(), getScaleY(), getRotation());
}
};
feedbackPanel.setBounds(w / 2, h / 2,
criticalTexture.getRegionWidth(), criticalTexture.getRegionHeight());
// Set up an Action for the critical life actor
feedbackPanel.addAction(forever(sequence(scaleTo(2, 2, 0.5f), scaleTo(1, 1, 0.5f), delay(0.5f))));
feedbackPanel.act(Gdx.graphics.getDeltaTime());
stage.addActor(feedbackPanel);
/**************************************************************************************************/
/*********************************** Set up the Input Controllers *********************************/
// The multiplexer helps target several input processes (in this case, the stage and the
// InputProcessor.class)
multiplexer = new InputMultiplexer();
multiplexer.addProcessor(stage);
multiplexer.addProcessor(new GameInputProcessor());
// InputAdaptor
Gdx.input.setInputProcessor(multiplexer);
/**************************************************************************************************/
backgroundImage = new Texture("images/bg.jpg");
bucketImage = new Texture("images/bucket_small.png");
fireballImage = new Texture("images/fireball_small.png");
heart = new Texture("images/heart.png");
/*************************************** Animations Setup *****************************************/
fballAtlas = new TextureAtlas("animations/fireball_fadeout.txt");
bucketAtlas = new TextureAtlas("animations/bucket_fadeout.txt");
catch_animation = new Animation(0.50f, fballAtlas.getRegions());
visual_feedback = new Animation(0.15f, bucketAtlas.getRegions());
/**************************************************************************************************/
// Instantiate all sounds
bucket_tap = Gdx.audio.newSound(Gdx.files.internal("sounds/bucket_tap.ogg"));
bucket_drag = Gdx.audio.newSound(Gdx.files.internal("sounds/bucket_drag.ogg"));
fireball_missed_sound = Gdx.audio.newSound(Gdx.files.internal("sounds/fireball_missed.ogg"));
catchFireball = Gdx.audio.newSound(Gdx.files.internal("sounds/fastSteam.ogg"));
pauseBtnSound = Gdx.audio.newSound(Gdx.files.internal("sounds/pauseBtn_sound.ogg"));
bgMusic = Gdx.audio.newMusic(Gdx.files.internal("sounds/music_bg.mp3"));
bgMusic.setLooping(true);
bgMusic.play(); // <----------- turn bg music on/off
// Instantiate the progressBarSkin
progressBarSkin = new Skin();
progressBarSkin.add("progressBarBg", new Texture("images/progress-bar_bg.png"));
progressBarSkin.add("progressBar", new Texture("images/progress-bar_dynamic_red.png"));
// Create bg sprite
backgroundSprit = new Sprite(backgroundImage);
//backgroundSprit.setPosition((float)w / 2, (float)h / 2);
//backgroundSprit.setSize((float)w, (float)h);
// Bucket sprite
bucketSprite = new Sprite(bucketImage);
// Fireball sprite
fireballSprite = new Sprite(fireballImage);
// Heart sprite
heartSprite = new Sprite(heart);
// Set the bucketRect into the rect from the bucketSprite (THE GREEN ONE)
bucketSpriteRect = bucketSprite.getBoundingRectangle();
bucketSpriteRect.x = w / 2 - 100 / 2;
bucketSpriteRect.y = 20;
bucketSpriteRect.setSize(200, 200);
// Set the collision rectangle (THE RED ONE)
bucketRect = new Rectangle();
bucketRect.x = bucketSpriteRect.getX() + 70; // <---- adjust position left/right
bucketRect.y = bucketSpriteRect.getY() + 150; // <---- adjust position up/down
bucketRect.setSize(100, 10);
// Set a rectangle for each fireball sprite (THE WHITE ONE)
fireBallRect = new Rectangle();
fireBallRect.x = fireballSprite.getX();
fireBallRect.y = fireballSprite.getY();
fireBallRect.width = 55;
fireBallRect.height = 55;
fireballArray = new Array<Rectangle>();
}
#Override
public void render () {
// Devide the Render method into a few switch cases based on the game's state
switch (state) {
case RUN:
// Do all the batch drawing here
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
elipsedTime += Gdx.graphics.getDeltaTime();
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(backgroundSprit, 0, 0, w, h);
batch.draw(bucketSprite, bucketSpriteRect.x, bucketSpriteRect.y,
bucketSprite.getWidth() - 160, bucketSprite.getHeight() - 140);
for(Rectangle fireball: fireballArray) {
batch.draw(fireballSprite, fireball.x, fireball.y,
fireballSprite.getWidth() - 20, fireballSprite.getHeight() - 20);
}
batch.draw(progressBarSkin.getSprite("progressBarBg"), 200, flipCoordinates(h, 170));
batch.draw(progressBarSkin.getSprite("progressBar"),
210, flipCoordinates(h, 162), barLength, 6); // <---- modify x, x, <x>, x to adjust the length of the life-bar
batch.draw(heartSprite, 95, flipCoordinates(h, 200), 90, 76);
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
batch.end();
/***************************************Debugging Rectangles************************************/
// Draw rects around sprites
// bucketRenderer.begin(ShapeRenderer.ShapeType.Line);
// bucketRenderer.setColor(Color.GREEN);
// bucketRenderer.rect(bucketSpriteRect.getX(), bucketSpriteRect.getY(),
// bucketSprite.getWidth() - 160, bucketSprite.getHeight() -140);
// bucketRenderer.end();
//
// bucketRenderer.begin(ShapeRenderer.ShapeType.Line);
// bucketRenderer.setColor(Color.RED);
// bucketRenderer.rect(bucketRect.getX(), bucketRect.getY(), 100, 10);
// //bucketRenderer.point(bucketRect.getX(), bucketRect.getY(), 0f);
// bucketRenderer.end();
//
// fireballRenderer.begin(ShapeRenderer.ShapeType.Line);
// fireballRenderer.setColor(Color.WHITE);
// fireballRenderer.rect(fireBallRect.x, fireBallRect.y,
// fireballSprite.getWidth() - 20, fireballSprite.getHeight() - 20);
// fireballRenderer.end();
// To avoid sprite flickering, surround batch.draw with a game state check
if (state != State.PAUSE) {
Iterator<Rectangle> iter = fireballArray.iterator();
while(iter.hasNext()) {
fireBallRect = iter.next();
fireBallRect.y -= fireballSpeed * Gdx.graphics.getDeltaTime();
// Remove the fireBallRect from the array as soon as it leaves the screen
if(fireBallRect.y + 106 < 0) {
iter.remove();
// The player missed the fireball, play a the fireball_missed_sound
fireball_missed_sound.play();
// Subtract a ball from the total number allowed to be missed
numOfBallsLeft --;
// Call life deduction
deductLifePoints();
// Check to see if this is the last fball left to fail
if (numOfBallsLeft == 1) {
}
// Check to see if life points are 0 or < 0
if (numOfBallsLeft <= 0) {
// Game over logic
barLength = 0;
// Set the game state to PAUSED
//state = State.PAUSE;
//bucketSprite.setColor(Color.RED);
batch.begin();
batch.draw(bucketSprite, bucketSpriteRect.x, bucketSpriteRect.y,
bucketSprite.getWidth() - 160, bucketSprite.getHeight() - 140);
batch.end();
}
}
// Collision detector
if(bucketRect.overlaps(fireBallRect)) {
catchFireball.play(volume);
// Start and draw animagion of fireball catch
batch.begin();
batch.draw(catch_animation.getKeyFrame(elapsedTime, true), fireBallRect.getX(), fireBallRect.getY());
batch.end();
// Remove the fireball that collides with the bucket
iter.remove();
}
}
}
// Touch input controller
if(Gdx.input.isTouched()) {
Vector3 touchPos = new Vector3();
touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touchPos);
if(touchPos.y <= 250) {
bucketSpriteRect.setX(touchPos.x - 115);
bucketRect.setX(touchPos.x - 50); // <---- adjust position left/right on touch
}
}
if(TimeUtils.nanoTime() - lastFireballTime > fireballFrequency) {
fireBallRect = new Rectangle();
fireBallRect.x = MathUtils.random(50, w - 270);
fireBallRect.y = h;
fireBallRect.width = 75;
fireBallRect.height = 75;
fireballArray.add(fireBallRect);
lastFireballTime = TimeUtils.nanoTime();
}
/**************************************************************************************************/
break;
case PAUSE:
// Pause the game here
/******************************** Redraw the sprites to avoid flickering **************************/
batch.begin();
batch.draw(backgroundSprit, 0, 0, w, h);
batch.draw(bucketSprite, bucketSpriteRect.x, bucketSpriteRect.y,
bucketSprite.getWidth() - 160, bucketSprite.getHeight() - 140);
for(Rectangle fireball: fireballArray) {
batch.draw(fireballSprite, fireball.x, fireball.y,
fireballSprite.getWidth() - 20, fireballSprite.getHeight() - 20);
}
batch.draw(progressBarSkin.getSprite("progressBarBg"), 200, flipCoordinates(h, 170));
batch.draw(progressBarSkin.getSprite("progressBar"),
210, flipCoordinates(h, 162), barLength, 6); // <---- modify x, x, <x>, x to adjust the length of the life-bar
batch.draw(heartSprite, 95, flipCoordinates(h, 200), 90, 76);
//pauseButton.draw(batch, 1);
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
batch.end();
/**************************************************************************************************/
break;
case RESUME:
break;
default:
break;
}
}
/************************************* Implement Dispose **************************************/
#Override
public void dispose() {
batch.dispose();
bucketRenderer.dispose();
fireballRenderer.dispose();
backgroundImage.dispose();
bucketImage.dispose();
fireballImage.dispose();
bucket_tap.dispose();
bucket_drag.dispose();
catchFireball.dispose();
bgMusic.dispose();
fireball_missed_sound.dispose();
progressBarSkin.dispose();
fballAtlas.dispose();
stage.dispose();
}
/************************************* Flip Coordinates Method ********************************/
public static float flipCoordinates(float height, float xORy) {
float newPosition = height - xORy;
return newPosition;
}
/************************************** Deduces Life Points ***********************************/
private void deductLifePoints() {
barLength -= deductedBarSegment;
}
/************************************** Set the Game's state **********************************/
public void setGameState(State s) {
this.state = s;
}
/******************************** Android's Lyfe-Cycle Overrides ******************************/
#Override
public void pause() {
super.pause();
this.state = State.PAUSE;
}
#Override
public void resume() {
super.resume();
this.state = State.PAUSE;
}
}
The first parameter of the Animation constructor is the frameDuration in seconds. You are passing it 1/15f, which is really fast. Try something greater, like 0.15f.

How can masking not work in ActionScript 3?

I wanted to mask some nodes of my DisplayObject tree. I couldn't make masking work in my big project. So I build a simple example for me and I saw it works actually pretty good. But I can't figure out why it doesn't work in my big project. All my visible objects are Sprites or from classes that extend Sprite.
masking in big project doesn't work
I can see the normal state of my nodeToBeMasked
when I add the mask to this node I can see the mask
but when I set the mask to be the mask, I continue to see everything (pure nodeToBeMasked is masked but not the children - which would be much more important)
masking in simple example works fine
How can masking stop working ?
Code: (that doesn't work, big project)
// custom class extends Sprite
override protected function onAddToStage(event:Event):void
{
trace(stage); // stage exists
var maskSprite:Sprite = new Sprite();
maskSprite.graphics.beginFill(0xffff00, 1);
maskSprite.graphics.drawCircle(0, 0, 64);
maskSprite.graphics.endFill();
maskSprite.x = 64;
maskSprite.y = 64;
if (true)
{
this.addChild(maskSprite); // doesn't help
this.mask = maskSprite; // I can see EVERYTHING here, inside and outside the cirle
}
else
addChild(maskSprite); // I can see the mask here
}
Code: (that works)
[SWF(frameRate="60",backgroundColor="0xffffff",width="128",height="128")]
public class MaskTest extends Sprite
{
public function MaskTest()
{
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
private function onAddedToStage(event: Event): void
{
trace(stage);
// this
graphics.beginFill(0x00ff00, 1);
graphics.drawRect(8, 8, 112, 112);
graphics.endFill();
// extra childs <- ^^
for (var i: int = 0; i < 100; i++)
{
var child: Sprite = new Sprite();
child.graphics.beginFill(uint(Math.random() * 0x1000000), 1);
child.graphics.drawRect(Math.random() * 64, Math.random() * 64, 64, 64);
child.graphics.endFill();
addChild(child);
}
// mask
var maskSprite: Sprite = new Sprite();
maskSprite.graphics.beginFill(0xffff00, 1);
maskSprite.graphics.drawCircle(0, 0, 64);
maskSprite.graphics.endFill();
maskSprite.x = 64;
maskSprite.y = 64;
// switch to check the mask
if (true)
this.mask = maskSprite;
else
addChild(maskSprite);
}
}
Update:
I found out that my custom class (that is the root and is only responsible for Event.ENTER_FRAME updates) was causing the problem. I don't know why but by disabling the z update in all my project solved the children of my maskedNode not being masked.
The mask MUST be added to the parent to work, not only used as
obj.mask = myMask; //This will not work alone
To make it work, it must be added to the parent object display list
obj.addChild(myMask);
obj.mask = myMask;
//this wasthe problem in my big project
maskSprite.z = 0; // avoid this with masks
Just a wild guess from me:if you use the properties z, rotationX, rotationY, rotationZ (maybe some more) the sprite is shifted to the 3D space and the masking is only working in 2D.
I have experimented with Flash 3D a bit. The transition from 2D to 3D seemed very smooth. You can't see when they "turn".

AS3 - How to copy sprites / graphics of sprites?

Let's say I have a 2D level that is build out of 2D blocks. Some of them are boxes.
The boxes look just the same. No difference! How can I "copy" or clone the graphics of one box to another ? The only difference the boxes will have is that sprite.x and sprite.y have different values. I would probably go that way:
public static function drawBox(graphics:Graphics):void
{
graphics.clear();
// draw box
}
drawBox(box1.graphics);
drawBox(box2.graphics);
drawBox(box3.graphics);
No textures will be used, only vector drawing!
Is this a good practice ? Is there another way to achieve the same ?
Update: Sometimes I draw sprites randomly (very hard to redraw them if I need many instances of one sprite and all its attributes).
You can use the function copyFrom.
Something like this:
var s:Sprite = new Sprite();
s.graphics.beginFill(0);
s.graphics.drawRect(0, 0, 100, 100);
s.graphics.endFill();
addChild(s);
var s2:Sprite = new Sprite();
// Copyfrom accepts a `Graphics` object.
s2.graphics.copyFrom(s.graphics);
s2.x = 100;
s2.y = 100;
addChild(s2);
Have a look at the documentation about copyFrom().
If you treat it like an object in your game you should probably rather consider the OOP-approach #Pier suggested.
This comes in a lot of flavors:
You could extend a class from Sprite and draw the box as soon as the box is ADDED_TO_STAGE by its parent.
public class box extends Sprite
{
protected var _color:uint;
protected var _size:int;
public function box(size:int=100, color:uint=0x000000)
{
super();
_size = size;
_color = color;
this.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
protected function onAddedToStage(event:Event):void
{
this.removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
draw();
}
protected function draw():void
{
this.graphics.beginFill(_color);
this.graphics.drawRect(0,0,_size,_size);
this.graphics.endFill();
}
}
This box can be constructed/created by calling:
var b:box = new box();
this.addChild(b);
Or you could let the box contain itself - which could be more feasible if you deal with a lot of Objects. The box would just need a reference to its parent then - and of course it should provide a dispose()-function
public class box
{
private var _parent:Sprite;
protected var s:Sprite;
public function box(parent:Sprite)
{
_parent = parent;
s = new Sprite();
s.graphics.beginFill(0x00000);
s.graphics.drawRect(0,0,100,100);
s.graphics.endFill();
_parent.addChild(s);
}
public function dispose():void
{
_parent.removeChild(s);
}
}
}
In this case you would construct the box as follows - it requires a reference to a Sprite (or any extension of) that has already been added to the stage:
var b:box = new box(this);
In both cases you could dynamically change attributes and make the object more versatile:
public function set size(val:int):void
{
_size = val;
draw();
}
public function set color(val:uint):void
{
_color = val;
draw();
}

AS3 draws bigger Sprite than i have set (padding/margin ?)

i created my own Button which simply extends from Sprite.
Its able to show 3 different text fading in and out using a timer.
In my draw function i first draw a rectangle with the Sprites graphics object representing the background of the button.
I added a function to set the button width. This property is used to draw the rectangle. I know that the sprites's size is updated after the rectangle drawing. But for some reason the sprite's width is always more than what i have set via my "setButtonWidth" function.
Now i have a simple sprite acting as a button having a graphics.drawRectangle part drawing a simple rect. with lets say 500px width. But when i trace the width of that button it is always about 10% more. Where are these 10% coming from?
I read about calling validateNow(). But this is only for Labels, or Checkboxes. For some reason i cannot access the library for Label. This must work somehow with TextFields. But how?
// this function is part of MyButtonClass.as file
function drawButton()
{
this.graphics.clear();
this.graphics.beginFill( currentBackColor);
this.graphics.drawRoundRect(0, 0, int(this.buttonWidth)+20, 30, 10, 10);
this.graphics.endFill();
}
// this code is in main action code frame
// the buttonWidth is set this way
stage.addEventListener( Event.RESIZE, updateBtn);
function updateBtn( event:Event)
{
// access the container in which the buttons are in like ...
for( var i = 0; i < buttonContainer.numChildren; i++) {
var btn = buttonContainer.getChildAt( i) as MyButtonClass;
// MyButtonClass is the class which extends from Sprite drawing my button
// and using buttonWidth to draw the backgrounds width.
btn.setButtonWidth( (stage.stageWidth / 2) - 20);
// i set half of stageWidth because i have two columns with a list of buttons
// after setButtonWidth is called in MyButtonClass, the draw function is called
// which does the graphics stuff above.
}
}
this.buttonWidth is set to 500. There is nothing special done on that sprite. No children to be added, only this drawing stuff. But this sets the sprite's width to 550 or something.
Define Button like this
package {
import flash.display.Sprite;
public class Button extends Sprite {
private var _buttonWith: int = 0;
private var _buttonHeight: int = 0;
public function Button() {
// constructor code
}
public function set buttonWidth(w: int): void {
_buttonWith = w;
updateButton();
}
public function get buttonWidth(): int {
return _buttonWith;
}
public function set buttonHeight(h: int): void {
_buttonHeight = h;
updateButton();
}
public function get buttonHeight(): int {
return _buttonHeight;
}
protected function updateButton() {
graphics.clear();
graphics.beginFill(0xff00ff);
graphics.drawRoundRect(0, 0, buttonWidth, buttonHeight, 10, 10);
graphics.endFill();
}
}
}
And create instance like this
var button:Button = new Button();
addChild(button);
button.buttonWidth = 100;
button.buttonHeight = 30;