Help with blit and screen

Discuss using and improving Lua and the Lua Player specific to the PSP.

Moderators: Shine, Insert_witty_name

Post Reply
Ferrero
Posts: 15
Joined: Mon Dec 19, 2005 7:26 pm
Contact:

Help with blit and screen

Post by Ferrero »

Hello everybody,

I'm trying to make a class that manage sprites.
All is going well, but I've a little problem :

I'm trying to save the content of a screen portion before drawing a sprite to avoid re-drawing all the background at every frames.

But when I use screen_save.blit (...., screen, ....) LUAPlayer says that it want an image and not a table for the argument.

Has the screen have an image property, or is there a special instruction to blit the screen to an image ?

Thanks
Shine
Posts: 728
Joined: Fri Dec 03, 2004 12:10 pm
Location: Germany

Re: Help with blit and screen

Post by Shine »

The screen object should work like an image object. If not, please add a note to the bugs page, with an example how I can reproduce the bug, maybe I or someone else can fix it. But first try screen_save:blit instead of screen_save.blit please :-)
Ferrero
Posts: 15
Joined: Mon Dec 19, 2005 7:26 pm
Contact:

Post by Ferrero »

OK I'll post a reply with a sample and and this to the bug list.
I must say, that issue is under LuaPlayer for windows. I can't test on a psp because I haven't got one for the moment.
Ferrero
Posts: 15
Joined: Mon Dec 19, 2005 7:26 pm
Contact:

Post by Ferrero »

Here's the SpriteManagerClass :

Code: Select all

clsSpriteManager = {
	tileWidth	= 0,
	tileHeight	= 0,
	nbTilesOnRow	= 0,
	nbTilesOnCol	= 0,
	image		= nil,
	background	= nil,
	timer		= Timer.new()
}

function clsSpriteManager:new()
   
	mtbSpriteManager = {}
	setmetatable(mtbSpriteManager, self)
	self.background = Image.createEmpty(480, 272)
	self.__index = self
	return mtbSpriteManager

end

function clsSpriteManager:load(filename, width, height)

	self.image=Image.load(filename)
	self.tileWidth  = width   
   	self.tileHeight = height
   	self.nbTilesOnRow = self.image:width() / width
   	self.nbTilesOnCol = self.image:height() / height
   	self.timer:start()
   		
end

function clsSpriteManager:getTile(tile)

	local x = math.mod(tile, self.nbTilesOnRow) * self.tileWidth
	local y = math.floor(tile / self.nbTilesOnCol) * self.tileHeight
	
	return x,y

end
Here's the sprite class :

Code: Select all

-------------------------------------
-- SPRITE OBJECT
-------------------------------------

clsSprite = {
	x		= 0,
	y		= 0,
	index		= 0,
	oldx		= 0,
	oldy		= 0,
	savx		= 0,
	savy		= 0,
	trgx		= 0,
	trgy		= 0,
	isMoving	= false,
	movingStartTime	= 0,
	movingTime	= 0,
	manager		= nil
}

function clsSprite:new(SpriteManager)
   mtbSprite = {}
   setmetatable(mtbSprite, self)
   self.manager = SpriteManager
   self.__index = self
   return mtbSprite
end

function clsSprite:moveTo(newX, newY, time)
   
   local startTime = self.manager.timer:time()   
   
   self.trgx	 	= newX
   self.trgy	 	= newY
   self.oldx		= self.x
   self.oldy		= self.y
   self.isMoving 	= true
   self.movingStartTime	= startTime
   self.movingTime	= time
   
end

function clsSprite:saveBackground()
	
	screen:blit(self.savx,self.savy,self.manager.background,0,0,480,272,false)
	
	self.savx = self.x
   	self.savy = self.y
	
	self.manager.background:blit(self.x,self.y,screen,self.x,self.y,self.manager.tileWidth,self.manager.tileHeight,true)  -- HERE IS THE PROBLEM --

end

function clsSprite:Draw()
   
   local currentTime = self.manager.timer:time()   
   
   self:saveBackground()
   
   if currentTime >= self.movingStartTime + self.movingTime then
   	
   	self.x = self.trgx
   	self.y = self.trgy
   	self.isMoving = false
   	
   end
   
   if self.isMoving then
   
   	self.x = self.oldx + (self.trgx - self.oldx) * ((currentTime - self.movingStartTime) / self.movingTime) 
   	self.y = self.oldy + (self.trgy - self.oldy) * ((currentTime - self.movingStartTime) / self.movingTime) 
   	
   end
   
   local sourcex, sourcey = self.manager:getTile(self.index) 
   print(currentTime, self.x, self.y)  
   screen:blit(self.x, self.y, self.manager.image, sourcex, sourcey, self.manager.tileWidth, self.manager.tileHeight, true)
   	
end
Here's the Main Code :

Code: Select all

require("SpriteManager.lua")
require("Sprite.lua")

sprManager = clsSpriteManager:new()
sprManager:load("Tiles.png",20,20)

spr = clsSprite:new(sprManager)

-- wait forevever
spr:moveTo(200,200,1000)

while spr.isMoving do
	
	spr:Draw()
	screen.waitVblankStart()
	screen.flip()
	
end
The problem is in the method saveBackground(), the instruction self.manager.background:blit(self.x,self.y,screen,self.x,self.y,self.manager.tileWidth,self.manager.tileHeight,true) cause the problem
error: Sprite.lua:51: bad argument #2 to `blit' (Image expected, got table)
Screen doesn't seems to be an image.

Is is possible to acces to the screen Image or the Backbuffer Image ?

PS : I must say that I use LuaPlayer for Windows.
romero126
Posts: 200
Joined: Sat Dec 24, 2005 2:42 pm

Post by romero126 »

I would personally use a custom image and redisplay that every time you want to refresh the table.. It can be done by defining it.

Code: Select all

preimage = Image.createEmpty(screen:width(), screen:height())
That way you use a preimage and draw that every time instead of screen..
Unfortunatly that would be the only way of preventing drawing everything all over again.
Plus if you blit it to the "screen" then you can check the screen instead of preimage.

I just thought id throw that out there.
youresam
Posts: 87
Joined: Sun Nov 06, 2005 1:43 am

I think I know your problem....

Post by youresam »

You are telling it a table, but not which part of it.
for example,

to blit self.x, lets say:
self.x = {0}
Now, to blit it, you need to tell it what number out of self.x.
screen_save:blit(self.x[1],self.y[1],...)
That tells it the first digit in self.x and self.y instead of just telling it to use the table.
romero126
Posts: 200
Joined: Sat Dec 24, 2005 2:42 pm

Post by romero126 »

youresam wrote:You are telling it a table, but not which part of it.
for example,

to blit self.x, lets say:
self.x = {0}
Now, to blit it, you need to tell it what number out of self.x.
screen_save:blit(self.x[1],self.y[1],...)
That tells it the first digit in self.x and self.y instead of just telling it to use the table.
Self.x is a variable not a table.

screen is a table. Unfortunatly there is no way arround defining that as anything more than a table with a write function.
So what I would suggest is looking at writing a prebuffer code to allow you to make your drawing of sprites faster. Unfortunatly there is no current work arround other than that.

PS I ran into a similar problem with code I created as well. So I know first hand.
Post Reply