Pygame how to change size of a surface? - pygame

How do you change the size of a surface in pygame that has an image (not scaling). When I load an image in pygame the surface becomes the size of the image. I need to change the size of the surface to be the size of a frame (sprite sheet).
Here is code I used to solve issue (thanks to Chris Dennett):
self.surface = pygame.Surface((20, 20))
self.surface.blit(pygame.image.load(imageName).convert_alpha(), (0,0), (0, 0, frameWidth, frameHeight))

For sprite sheets, you have 2 good options.
1) Load spritesheet as one Surface.
When blitting, use the source rect argument. This will blit just one frame, from the sheet.
2) Use subsurfaces.
Load spritesheet as one Surface.
Load a subsurface, of each frame you want : http://www.pygame.org/docs/ref/surface.html#Surface.subsurface
As far as you are concerned, the subsurface is a 'new' surface, with the width and height of the cell. But, it's not duplicate memory. It's linked.
From the docs:
Returns a new Surface that shares its pixels with its new parent. The
new Surface is considered a child of the original. Modifications to
either Surface pixels will effect each other. Surface information like
clipping area and color keys are unique to each Surface.

Create a new surface, passing in the desired width and height as arguments (i.e., how big the sprite is). Then use newsurf.blit(spritesheet, (0, 0), (posX, posY, newsurf.getWidth(), newsurf.getHeight())). Should work. Then you can use newsurf as your sprite. posX and posY should be the x and y you want to blit from in your sprite sheet respectively.

Related

How to draw line with texture instead of color?

I have lot of sprites on screen ( cars looking from top ) and I am drawing polylines ( like call ccDrawPoly(redBlue, 8, false) ). I need to replace line color with texture ( I have image of water and I want to draw line with water texture water.png ).
How to make this ?
PaolaJ, I could suggest a hack
Create Sprite Object
Give it some width like 2,4,8 or 16 (depending on your texture)
Sprite Height could be same as line length.
Use sprite->getTexture()->setTexParameters({GL_LINEAR, GL_LINEAR,GL_REPEAT,GL_REPEAT}) to repeat your texture.
use rotation to place the sprite properly.
make sure texture is power of 2.
On the other hand, proper way would be textured polygon as LearnCocos2d suggested.

Is there a way in pygame to detect if a rect is fully inside a mask?

Is there a way in pygame to detect if a rect is fully inside a mask?
I know that there is rect in rect collision and collidepoint (point in rect collision) but is there any way to detect if a rect is inside a mask?
Thanks
I don't believe there is any function supplied by pygame to do that. It would definitely be somewhat challenging, because of the "shapeless" possibilities of a mask. One possibility which might work for you would be to first get a list of the bounding rects of the mask (a list of rects which together "contain" all of the points of the mask) and check if your rect is inside any of these rects:
bounding_rects = mask.get_bounding_rects()
for b_rect in bounding_rects:
if b_rect.contains(test_rect):
print "Rect is inside mask"
Of course with this solution, if the rect is inside the mask, but not inside any one particular bounding rect, the test will fail. Here's an idea of how you might handle that, with the tradeoff of a little bit of lost precision:
bounding_rects = mask.get_bounding_rects()
mask_rect = bounding_rects[0].unionall(bounding_rects)
if mask_rect.contains(test_rect):
print "Rect is inside mask"
This solution unions all of the bounding rects of the mask into one rect, which has the possibility of covering area that none of the bounding rects covered (if two rects have a gap of 10 pixels between each other and are unioned together, the new rect will contain that gap)

As3 sprite rotationX and rotationY

I have a bit problem with rotationX and rotationY.
It's cool if i just do a roationX and rotaionY below
_eventParent.rotationY =_differentX;
_eventParent.rotationX =_differentY;
However once i have assign a mouse move to the _eventParent. The roationX and roationY change perspectively while the mouse is moving. so instead the item remain the same size. it increase and decrease size prospectively. any idea why is it doing this? is there a possibility to stop this behavior?
Thanks
Please find the image below.
Perspective allows part of your shape to look closer to you than other parts. The problem is that perspective has a center, or "vanishing point" and by default, it is fixed. As you move your shape farther away from the vanishing point, the perspective changes, causing your shape to widen or narrow.
You can fix this by updating the vanishing point so that it is always at the same coordinates as your shape. Since the shape will always be at the vanishing point, the perspective shouldn't change.
To do this, create a perspectiveProjection for your shape:
_eventParent.transform.perspectiveProjection = new PerspectiveProjection();
PerspectiveProjection is located in the flash.geom package, so don't forget to import it.
Then whenever you update your shape's position, update it's vanishing point:
_eventParent.transform.perspectiveProjection.projectionCenter =
new Point(_eventParent.x, _eventParent.y);
You might need to offset the vanishing point by a set number of pixels to get the perspective looking the way you want it to.
Correct me if I misunderstood your question. Your question is that if you apply rotation to the movieClip object, then why does the size appear to be changing?
For simplification, Let's not apply rotation on both X and Y axis. Let's take a rectangular movie clip and onMouseMove we do ++myMovieClip.rotationX;
Now, this statement is going to apply rotation on the object about the X-axis and one would get a perspective of the movie clip flipping across X -axis and this flipping will show as change in size of the object.
The same applies to rotating across y-axis.

adding transparent sprite over another sprite

I need to place a transparent sprite over another sprite. The overlaying sprite will acept some mouse events. When a user move mouse over upper sprite a curve will be drawn. After it'll be processed it will be drawn on the base sprite (and erased on upper).
The idea I have now is to place the sprite, draw a rectange of size equal to sizes of sprite and set alpha to 0.
The question is a bit dump: maybe the proposed solution is not the best. Is there a better way to set width and height (as far a I understand Sprite.width = w; will not help)?
Thank you in advance!
You can't set dimensions directly, while you can draw over that Sprite. So you can do like this:
graphics.beginFill(0,0); // zero alpha fill
graphics.lineStyle(0,0,0); // invisible lines
graphics.drawRect(0,0,width,height);
graphics.endFill();
This way your Sprite can have its alpha remaining at 1, to not hide anything that's its child. Then, whatever curve you would decide to draw in that Sprite, you can draw within a child Shape object, via graphics.moveTo and graphics.lineTo.
UPDATE: According to comments below, setting alpha to 0 won't work with newer Flash player versions, so alpha should be set to a nonzero amount for the events to register on the overlapping sprite.
graphics.beginFill(0x808080,0.01); // almost zero alpha fill

understanding matrix.transition(); as3

I am trying to understand the method transition that falls in the Matrix Class. I am using it to copy pieces of a bitMapData. But I need to better understand what transitions do.
I have a tilesheet that has 3 images on it. all 30x30 pixels. the width of the total bitmap is 90pxs.
The first tile is green, the second is brown, and the third is yellow. If I move over 30pxs using the matrix that transitions, instead of getting brown, I get yellow, if I move over 60px, I get brown.
If I move -30 pixels, then the order is correct. I am confused on what is going on.
tileNum -= (tileNumber * tWidth);
theMatrix = new Matrix();
theMatrix.translate(tileNum,0);
this.graphics.beginBitmapFill(tileImage,theMatrix);
this.graphics.drawRect(0, 0,tWidth ,tHeight );
this.graphics.endFill();
Can someone tell me how transitions work, or some resources that show how they work. I ultimately want to know a good way to switch back and forth between each tile.
First of all, don't confuse translation with transition. The latter is a general English word for "change", whereas to translate in geometry and general math is to "move" or "offset" something.
A transformation matrix defines how to transform, i.e. scale, rotate and translate, an object, usually in a visual manner. By applying a transformation matrix to an object, all pixels of that object are rotated, moved and scaled/interpolated according to the values stored inside the matrix. If you'd rather not think about matrix math, just think of the matrix as a black box which contains a sequence of rotation, scaling, and translation commands.
The translate() method simply offsets the bitmap that you are about to draw a number of pixels in the X and Y dimensions. If you use the default ("identity") matrix, which contains no translation, the top left corner of your object/bitmap will be in the (0,0) position, known as the origin or registration point.
Consider the following matrix:
var mtx : Matrix = new Matrix; // No translation, no scale, no rotation
mtx.translate(100, 0); // translated 100px on X axis
If you use the above matrix with a BitmapData.draw() or Graphics.beginBitmapFill(), that means that the top left corner of the original bitmap should be at (x=100; y=0) in the target coordinate system. Sticking to your Graphics example, lets first consider drawing a rectangle without a matrix transformation.
var shape : Shape = new Shape;
shape.graphics.beginBitmapFill(myBitmap);
shape.graphics.drawRect(0, 0, 200, 200);
This will draw a 200x200 pixels rectangle. Since there is no transformation involved in the drawing method (we're not supplying a transformation matrix), the top left corner of the bitmap is in (x=0; y=0) of the shape coordinate system, i.e. aligned with the top left corner of the rectangle.
Lets look at a similar example using the matrix.
var shape : Shape = new Shape;
shape.graphics.beginBitmapFill(myBitmap, mtx);
shape.graphics.drawRect(0, 0, 200, 200);
This again draws a rectangle that is 200px wide and 200px high. But where inside this rectangle will the top left corner of myBitmap be? The answer is at (x=100, y=0) of the shape coordinate system. This is because the matrix defines such a translation.
But what then will be to the left of (x=100; y=0)? With the above code, the answer is that the bitmap repeats to fill the entire rectangle, and hence you will see the rightmost side of the bitmap, to the left of the leftmost side, as if there was another instance of the bitmap right next to it. If you want to disable the repeating image, set the third attribute of beginBitmapFill() to false:
shape.graphics.beginBitmpFill(myBitmap, mtx, false);
Lets take a look at one last example that might help your understanding. Remember that the translation matrix defines the position of the top left corner of an image, in the coordinate system of the shape. With this in mind, consider the following code, using the same matrix as before.
var shape : Shape = new Shape;
shape.graphics.beginBitmapFill(myBitmap, mtx);
shape.graphics.drawRect(100, 0, 100, 100);
Notice that this will draw the rectangle 100px in on the X axis. Not coincidentally, this is the same translation that we defined in our matrix, and hence the position of the top left corner of the bitmap. So even though repeating is enabled, we will not see a repeating image to the left of our rectangle, because we only start drawing at the point where the bitmap starts.
So the bottom line is, I guess, that you could think of the transform matrix as a series of transformation commands that you apply to your image as you draw it. This will offset, scale and rotate the image as it's drawn.
If you are curious about the inner workings of the matrix, Google transformation matrices, or read up on Linear Algebra!