To avoid memory leak in corona sdk - memory-management

I used spritext() method for the animation, and I tried to release the memory of spritesheets by using the dispose() method, but it is showing error.
How to release the memory of spritesheets?
local spritext = require("spritext")
local arr = {"images/rainbow2.png","images/rainbow1.png"}
local myAnim = spritext.newAnim(arr[1], 600,350, 1, 15);
myAnim.x = display.contentWidth/2;
myAnim.y = display.contentHeight/2 -70;
r:insert(myAnim);
myAnim:play{ startFrame=1, endFrame=15, loop=1 }
local function cleanUp()
myAnim:dispose();
end

Are you using the API for SpriteSheet? I believe that object:dispose is deprecated.
The new way of using it is via SpriteObject, and it inherits from the DisplayObject API.
http://docs.coronalabs.com/api/type/SpriteObject/index.html - SpriteObject
You should able to call object:removeSelf from the DisplayObject API. http://docs.coronalabs.com/api/type/DisplayObject/removeSelf.html
Here is a snippet of how I handle my spritesheets.
-- Import sprite sheet
local someSheet = graphics.newImageSheet( "someimages.png", someInfo:getSheet() ) -- ImageSheet.png is the image Texture packer published
-- Set sprite sequence data.
local someSequenceData = {
{ name="dance", frames={8,1,2,3,4,5,4,3,2,1,8}, time=2000, loopCount=1},
{ name="sad", frames={8,9,8}, time=3000, loopCount=1},
{ name="happy", frames={8,5,8}, time=3000, loopCount=1},
{ name="smile", frames={8,10,8}, time=3000, loopCount=1},
{ name="hit", frames={7,8}, time=2000, loopCount=1}
}
-- load sprite object
spriteObject = display.newSprite( someSheet, someSequenceData )
spriteObject.x = display.contentWidth/2
spriteObject.y = display.contentHeight/2
-- play one of the animations
spriteObject:play("dance")
-- to remove the entire sprite object
spriteObject:removeSelf()
A quick note:
For my spritesheets I use a application called "TexturePacker", I just drop some images in, set some settings, and then it builds a packed sprite sheet, along with a data sheet to go along with it.
EDIT:
I didn't realize this question is rather old.. Oh well. I hope this helps someone out anyway. :P

Related

FlxSpriteGroup is not visible (haxeflixel)

I'm trying to create some sort of "item displayer" in a game to showcase items or act as an icon in the inventory (it will include informations like item tier, item name, exc).
To achieve this, i wanted to create a ItemDisplay class extending FlxSpriteGroup, and put inside it the frame, background and info for the item as Sprites, so that i would be able to work with all as if they were a single Sprite.
So i did just that, but the group isn't showing up when the ItemDisplay object is created and supposedly added to the FlxState.
After some troubleshooting, i discovered that the object exists, but isOnScreen() returns false, and i don't know why.
Here's the code i'm using to create the ItemDisplay object:
var itd:ItemDisplay = new ItemDisplay(FlxG.width / 2, FlxG.height / 2, test_sword);
add(itd);
...and here's the ItemDisplay class in all it's glory:
class ItemDisplay extends FlxSpriteGroup
{
override public function new(posX:Float, posY:Float, itemToShow:Item)
{
super();
x = posX;
y = posY;
// create sprites
var bckgr:FlxSprite = new FlxSprite(x, y);
var itPng:FlxSprite = new FlxSprite(x, y);
var itFrm:FlxSprite = new FlxSprite(x, y);
// load sprites graphics (problem's not here, i checked)
bckgr.loadGraphic("assets/images/ui/item_framing/ifbg_" + itemToShow.tier + "Tier.png");
itPng.loadGraphic(itemToShow.pngPath);
itFrm.loadGraphic("assets/images/ui/item_framing/item_frame.png");
// add all sprites to group
this.add(bckgr);
this.add(itPng);
this.add(itFrm);
}
}
(i'm running the code on macos, not HTML5)
If you have any idea why the ItemDisplay is not showing up, please explain it to me, as i'm not that good of a programmer, and i might have missed something.
Thank you ^-^
Nvm, as i thought, it was my stupid error: when creating the sprites in lines 10-12, i set their positions to X and Y, to make them the same as the group positions.
I just found out that the sprites consider the group's x and y as (0, 0), and start calculating their position from there.
So, by setting the sprites' x/y the same as the group's, i was essentially doubling the values, and putting the sprites outside of the screen
lmao sorry for bad english

createGraphics in Instance Mode in p5js

I'm new to p5.
My aim is to display ASCII value of the key I type and also leave a trail of vertical lines whose distance from left is 200+the ASCII value of the key,
which can be done using createGraphics() (adding an additional canvas layer on top with same dimensions as original and drawing on that additional canvas layer)
But the code doesn't seem to work and also it is not displaying any errors in the console.
const c5=function(p){
let pg;
p.setup=function(){
p.createCanvas(600,400);
pg=p.createGraphics(600,400);
};
p.draw=function(){
p.background(200);
p.textAlign(p.CENTER,p.TOP);
p.textSize(20);
p.text('ASCII Value : '+p.keyCode,300,100);
pg.line(200+p.keyCode,200,200+p.keyCode,300);//shift right by 200
};
};
The first issue is that you have to tell the engine that the thing you name p is actually a p5 instance. You can construct a p5 object using new p5(...) as follows:
const c5 = new p5(function(p) {
p.setup = function(){
...
};
p.draw = function(){
...
};
});
You then correctly fill up your pg graphic object with vertical lines. However, you do not "draw" it on your original canvas. You can do so using the p5.js image() function (see also the example shown in the createGraphics() documentation).
I've made a working example in the p5.js editor here.
Your code is very close. You are creating the graphic object and drawing to it but you also need to display it as an image to your canvas. In your code snippet you are also missing the call to create the new p5js object but that may be just a copy paste error.
Here is a working snippet of your code with the call to draw the image. I also moved the key detection logic to keyPressed so the logic only runs when a key is pressed.
Also notice that running the logic inside of keyPressed allows the sketch to handle keys such as f5 by returning false and preventing default behavior. In a real application we would need to be very careful about overriding default behavior. Here we assume that the user wants to know the key code of the f5 key and will be ok with the page not reloading. In a real application that might not be the case.
const c5=function(p){
let pg;
p.setup=function(){
p.createCanvas(600,400);
pg=p.createGraphics(600,400);
};
p.draw=function(){
};
p.keyPressed = function() {
p.background(200);
p.textAlign(p.CENTER,p.TOP);
p.textSize(20);
p.text('ASCII Value : '+p.key + " " +p.keyCode,300,100);
pg.line(200+p.keyCode,200,200+p.keyCode,300);//shift right by 200
p.image(pg, 0, 0);
return false; // prevent default
}
};
var myp5 = new p5(c5)
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.min.js"></script>

Save multiple images with one function - AS3 ADOBE AIR

I've got an Array with 17 web links of images
var products:Array;
trace(products)
// Ouput :
"http://www.myWebsite.com/zootopia.jpg"
"http://www.myWebsite.com/james.jpg"
"http://www.myWebsite.com/tom.jpg"
..etc
If I do products[10].movieimage; the output will be the 9th link (something like : "http://www.myWebsite.com/lalaland.jpg")
I'm looking for downloading every images without a dialog box.
I manage to do so for 1 image with the specific link, like that :
function saveImage (event:Event):void {
var stream:URLStream = new URLStream();
var image1:File = File.documentsDirectory.resolvePath("test.jpg");
var fileStream:FileStream = new FileStream();
stream.load(new URLRequest("http://www.myWebsite.com/lalaland.jpg"));
stream.addEventListener(Event.COMPLETE, writeComplete);
        
function writeComplete(evt:Event):void  {
                var fileData:ByteArray = new ByteArray();
                stream.readBytes(fileData,0,stream.bytesAvailable);
                fileStream.openAsync(image1, FileMode.UPDATE);
                fileStream.writeBytes(fileData,0,fileData.length);
                fileStream.close();
trace("writeComplete");
trace(image1.url);
        }
}
Question : Is there a way to download all the images with the web links of my products array ? (and if images already exist, replace them. I could use if (image1.exists){ if (image2.exists){ ..etc for each image. But maybe there is a simplier solution)
If you could show me how, with a bit of code, I could that.
Also, note that I'd like to load the images then in Uiloader, like that :
function loadImages():void {
uiloader1.source = image1.url;
uiloader2.source = image2.url;
etc...
}
Don't over think it. You have your array of images. You have your tested routine for saving one image. Now put it together:
Some function initializes things and kicks it off.
Either splice out (or pop out) an item on the array – OR use a index var to access an item in the array
Pass that to your download function.
When the download completes either pop another item off the array OR increment your index. But first you would test if array.length== 0 OR `index > array.length. If either is true (depending on which method you use), then you are done.
If you want to get fancy you can show a progress bar and update it each time your download completes.

How to move an image in Lua?

I am new to Lua programming and I am having problems while trying to move an image from a set of coordinates to another.
What I am trying to create is to be used with the X-Plane flight simulator. There is a library called SASL (www.1-sim.com), that was created to make plugins (for X-Plane) creation easir, since the default language is C++ and many people find it difficult.
In general, SASL works as a bridge between Lua and X-Plane, in general lines, the scripts you write reads some data straight from X-Plane (DataRefs) while it is running and depending on the code you wrote its execute commands or many other things that it is possible.
So, when using SASL to create cockpit/panel gauges it uses a base file, named 'avionics.lua' that works as a class and loads all gauges you create for the specific aircraft you are working on. For example my avionics.lua file looks like this:
size = { 2048, 2048 }
components = {
flaps {};
};
where, 'size' is the size that will be used for things to be drawn and components is an array of gauges, in this case the flaps gauge.
The rest of the work is to create the gauge functionality and this is done in a separate file, in my case, called 'flaps.lua'.
Within flaps.lua, is where I need to code the flaps indicator functionality which is to load 2 images: one for the back ground and the second one for the flaps indicator.
The first image is a fixed image. The second one will move throught the 'y' axis based on the flaps indicator DataRef (flapsDegree property below).
The code below when X-Plane is running displays the background image and the flaps indicator on its first stage which is 0 as you can see on the image.
size = {78,100}
local flapsDegree = globalPropertyf("sim/cockpit2/controls/flap_ratio")
local background = loadImage("gfx/Flaps.png")
local indicator = loadImage("gfx/Flaps_Indicator.png")
local flaps = get(flapsPosition)
components = {
texture { position = {945, 1011, 60, 100}, image = background},
texture { position = {959, 1097, 30, 9}, image = indicator},
}
Image
Now, the problem comes when I need to implement the logic for moving the 'indicator' image through the 'y' axis.
I have tried this code without success:
if flaps == 0.333 then
indicator.position = {959, 1075, 30, 9}
end
So how could I accomplish that?
I am not familiar with the SALS library. I just had a quick look into it.
Everything you need to know is in the manuals on the website you linked.
In particular http://www.1-sim.com/files/SASL300.pdf
Everytime your screen is updated each components draw() function will be called.
So if you want to change something dynamically you have to put that into the component's draw function.
If you open the SALS sources you'll find basic components which show you how to use that stuff. One of them is needle.lua:
-- default angle
defineProperty("angle", 0)
-- no image
defineProperty("image")
function draw(self)
local w, h = getTextureSize(get(image))
local max = w
if h > max then
max = h
end
local rw = (w / max) * 100
local rh = (h / max) * 100
drawRotatedTexture(get(image), get(angle),
(100 - rw) / 2, (100 - rh) / 2, rw, rh)
end
If you check the manual you'll find that there is not only a drawRotatedTexture function but many other functions for drawing stuff. Just play around. Try drawTexture for your purpose.
If you don't know what you have to program, open every single lua file in the library and read it together with the Lua reference manual and the SALS documentation until you understand what is going on. Once you understand the existing code you can extend it with ease.

Flixel Game Over Screen

I am new to game development but familiar with programming languages. I have started using Flixel and have a working Breakout game with score and lives.
I am just stuck on how I can create a new screen/game over screen if a player runs out of lives. I would like the process to be like following:
Check IF lives are equal to 0
Pause the game and display a new screen (probably transparent) that says 'Game Over'
When a user clicks or hits ENTER restart the level
Here is the function I currently have to update the lives:
private function loseLive(_ball:FlxObject, _bottomWall:FlxObject):void
{
// check for game over
if (lives_count == 0)
{
}
else
{
FlxG:lives_count -= 1;
lives.text = 'Lives: ' + lives_count.toString()
}
}
Here is my main game.as:
package
{
import org.flixel.*;
public class Game extends FlxGame
{
private const resolution:FlxPoint = new FlxPoint(640, 480);
private const zoom:uint = 2;
private const fps:uint = 60;
public function Game()
{
super(resolution.x / zoom, resolution.y / zoom, PlayState, zoom);
FlxG.flashFramerate = fps;
}
}
}
There are multiple ways to go about doing this...
You could use different FlxStates, like I described in the answer to your other post: Creating user UI using Flixel, although you'll have to get smart with passing the score or whatever around, or use a Registry-type setup
If you want it to actually work like you described above, with a transparent-overlay screen, you can try something like this (keep in mind, the exact details may differ for your project, I'm just trying to give you an idea):
First, make sure you have good logic for starting a level, lets say it's a function called StartLevel.
You'll want to define a flag - just a Boolean - that tracks whether or not the game is still going on or not: private var _isGameOver:Boolean; At the very end of StartLevel(), set this to false.
In your create() function for your PlayState, build a new FlxGroup which has all the things you want on your Game Over screen - some text, an image, and something that says "Press ENTER to Restart" (or whatever). Then set it to visible = false. The code for that might look something like:
grpGameOver = new FlxGroup();
grpGameOver.add(new FlxSprite(10,10).makeGraphic(FlxG.Width-20,FlxG.Height-20,0x66000000)); // just a semi-transparent black box to cover your game screen.
grpGameOver.add(new FlxText(...)); // whatever you want to add to the group...
grpGameOver.visible = false;
add(grpGameOver); // add the group to your State.
Depending on how your game is setup, you may also want to set the objects in your group's scrollFactor to 0 - if your game screen scrolls at all:
grpGameOver.setAll("scrollFactor", new FlxPoint(0,0));
In your update() function, you'll need to split it into 2 parts: one for when the game is over, and one for if the game is still going on:
if (_isGameOver)
{
if (FlxG.keys.justReleased("ENTER"))
{
grpGameOver.visible = false;
StartLevel();
}
}
else
{
... the rest of your game logic that you already have ...
}
super.update();
Keep in mind, if you have things that respond to user input anywhere else - like a player object or something, you might need to change their update() functions to check for that flag as well.
Then, the last thing you need to do is in your loseLive() logic:
if (lives_count == 0)
{
_isGameOver = true;
grpGameOver.visible = true;
}
else
...
That should do it!
I would highly recommend spending some time with different tutorials and sample projects to kind of get a better feel for Flixel in general. Photon Storm has some great material to play with (even though he's jumped over to HTML5 games)
I also want to note that if you get comfortable with the way Flixel handles updates, you can get really smart with your state's update() function and have it only call update on the grpGameOver objects, instead of having to change all your other objects updates individually. Pretty advanced stuff, but can be worth it to learn it.

Resources