Is get_rect a list, and how can I get it's components? - text

I'm rendering some text on a screen and I want to draw a box behind acting as background. Text is a surface if I know correctly, so you call get_rect() to get it's coordinates, width and height.
So when I print(my_text_surface.get_rect()) I get this:
rect(0, 0, 382, 66)>
By this information I assume I can write:
my_suface.get_rect(1)
and get it's x coordinate. But then it's says:
get_rect only accepts keyword arguments
So I'm asking you here if get_rect() can get me a list and, if yes how can I access it?
If you need my code:
font = self.pygame.font.Font("freesansbold.ttf", 64)
spadenpala_text = font.render("Spadenpala", True, (255, 255, 255))
spadenpala_text_position = spadenpala_text.get_rect(center=(self.width/2, 200))
print(spadenpala_text.get_rect([1]))
Thanks, Mirko Dolenc

pygame.Surface.get_rect() doesn't return a list, but a pygame.Rect object:
Returns a new rectangle covering the entire surface.
pygame.Surface.get_rect() returns a rectangle with the size of the Surface object, that always starts at (0, 0) since a Surface object has no position. A Surface is blit at a position on the screen. The position of the rectangle can be specified by a keyword argument. For example, the center of the rectangle can be specified with the keyword argument center. These keyword argument are applied to the attributes of the pygame.Rect before it is returned (see pygame.Rect for a full list of the keyword arguments).
A pygame.Rect object has a lot of virtual attributes like .x, .y, .width, .height etc. e.g.:
surf = pygame.Surface((100, 50))
rect = surf.get_rect(center = (200, 200))
print(rect)
print(rect.x)
print(rect.y)
print(rect.width)
print(rect.height)
output:
<rect(150, 175, 100, 50)>
150
175
100
50

Related

Python list not returning correct value of complex object

I am writing a platformer game using python 3.6.9 & the pygame library. I'm trying to create all of the game objects, then put them all in a list in order to blit them all to the screen in a for x in gameObjectList loop.
Each of the game objects in question has an attribute img, which I assign to pygame.image.load("slime-character.gif").
This stores the image as a pygame.Surface object.
The window (screen) has a function blit, that takes a Surface object (which is an image) and either an x and y coordinate pair or a pygame.Rect, which it takes the x and y from.
My code does:
for x in gameObjects:
screen.blit(x.img, x.rect)
but it throws an error, saying that x.img is an int. Printing this, it appears to be 200. Printing this without the iterator print(gameObjects[0].img) gives me the same thing.
BUT, if I print the object's value itself print(object1.img) I get out a pygame.Surface object, which is what I need to blit.
It's impractical for me to hardcode every possible object to appear, so I need to refer to their images from a list of the objects. But when I do, it gives me an incorrect datatype. Does anyone know why this is happening/a workaround so I can access the data I need?
Thanks in advance. Link to full code (89ish lines) on Google Drive.
EDIT: solved thanks to a comment by Chris Doyle: I'd forgotten to put screen as a parameter for movableObjs. I'm leaving this question up though, in case anyone can explain the program's behavior (working without list but failing when referred to from a list).
First of all Class names should normally use the CapWords convention. See Style Guide for Python Code - Class Names.
Use rename gameObjectRef by GameObjectRef, gameObj by GameObj and movableObj by MovableObj.
The issue is object2 respectively the class movableObj. The class movableObj is derived from the class gameObj. The first argument to the constructor of gameObj is screen. You have to pass screen to the constructor of gameObj in the super call o fht constructor:
Do
gameObj.__init__(self, img, xpos, ypos, w, h, visible, active)
gameObj.__init__(self, screen, img, xpos, ypos, w, h, visible, active)
in
class movableObj(gameObj):
def __init__(self, screen, img, xpos, ypos, w, h, gravity=1, xvel=0, yvel=0,
visible=False, leaveScreen=False, active=True):
gameObj.__init__(self, screen, img, xpos, ypos, w, h, visible, active)
self.gravity = gravity
self.xvel = xvel
self.yvel = yvel
self.leaveScreen = leaveScreen
Further more you have to pass screen to the constructor when you create an instance of movableObj:
object2 = movableObj(imgslime, 600, 200, 20, 20, 0, 2, 0)
object2 = movableObj(screen, imgslime, 600, 200, 20, 20, 0, 2, 0)

How to use a color buffer in OpenGL ES 2

I am a bit confused on how to draw color using a color buffer. I found a similar question here and made my shader the same as shown in the post's accepted answer. I then used the code:
mColorHandle = GLES20.glGetAttribLocation(Shader, "vColor");
GLES20.glEnableVertexAttribArray(mColorHandle);
ByteBuffer cb = ByteBuffer.allocateDirect(color.length * BYTES_PER_FLOAT);
cb.order(ByteOrder.nativeOrder());
colorBuffer = cb.asFloatBuffer();
colorBuffer.put(color);
colorBuffer.position(0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, cbo);
GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, 0, colorBuffer.capacity(), colorBuffer);
GLES20.glVertexAttribPointer(mColorHandle, 4,
GLES20.GL_FLOAT, false,
0, 0);
in attempt to draw the color.
The shape displayed the color I was trying to draw but it faded out the color across the shape like this:
If someone could tell me what's going wrong and how I could get the shape to be all the same color, I would appreciate it.
Thanks to Rabbid76 for helping me find the mistake.
Instead of 4 elements total in the color array, there needs to be 16, an RGBA value for each vertex. (4 elements of the array are used to make one RGBA value.)

How to add centered text with gm for node (graphicsmagick/imagemagick)?

This relates to the "gm" extension for node, http://aheckmann.github.io/gm/docs.html
I need to add some text centered around a bounding box (horizontally is enough). The function drawText() requires x,y coordinates, but there is no way to draw centered text.
I would otherwise need a function which can return the width of a text string in the font/size given, so I can calculate my starting x position in javascript, before calling drawText().
You can use the region and gravity functions this way:
gm(filePath)
.region(WIDTH, HEIGHT, X, Y)
.gravity('Center')
.fill(color)
.fontSize(textFontSize)
.font(font)
.drawText(0, 0, 'This text will be centered inside the region')

How to isolate a Phaser shader to a specific object/shape?

I'm using the Phaser framework. Here is the jsfiddle:
http://jsfiddle.net/Dillybob/u3mGL/13/
Here is where the filter is getting populated:
background = game.add.sprite(0, 0);
background.width = 800;
background.height = 600;
filter = game.add.filter('Fire', 800, 600);
filter.alpha = 0.0;
background.filters = [filter];
My line object is assigned to the variable drawnObject
So I assign that object to receive the filter like so:
drawnObject.filters = [filter];
But my line is now a red fiery square instead of being a line with a fiery background, why?
Firstly, be aware that drawnObject is actually a bitmap, which is rectangular shaped. It consists of white pixels, which build your line, and transparent pixels, which are taking the rest of bitmap space.
The filter you use is a pixel shader. Pixel shader describes instructions that GPU invokes for each pixel of a provided bitmap. In case of this shader, it creates fire effect based on some noise functions, but it doesn't take original bitmap into account. The original color of pixels is not preserved, it doesn't add to final effect in any way.
To achieve your expected result, you have to amend fragmentSrc in Fire.js, so that shader uses and mixes/blends original color into final pixel color and/or doesn't change pixel transparency.

Why doesn't the alpha pixel in html canvas blend in with the background color?

http://jsfiddle.net/jBgqW/
I've painted the background with fillRect and fillStyle set to rgb(255,0,0) but when I iterate through the pixels and set some random color and value of the alpha pixel to 0 everything becomes white. I've assumed that when the pixel is transparent it should blend with the previously painted background color or does it always default to white.
I hope that it's just my wrong way of using the canvas.
Can anyone explain why the background isn't red in this case and how do i use the alpha pixel properly? I would like to know if this has something to do with the alpha premultiplication.
When using globalAlpha, the pixel colors are calculated with the current rgba values and the new values.
However, in this case you're setting the values manually and therefore doing no calculations. You're just setting the rgba values yourself, which means that the alpha channel is not used for calculating but is just altered without further use. The previous color (red) is basically overwritten in a 'brute force' way - instead of rgba(255, 0, 0, 255), it's now just rgba(128, 53, 82, 0). The original red color has simply been thrown away.
As a result, an alpha of 0 represents complete transparency, so you see the colors of the parent element.
This can be confirmed if you change the body background color: http://jsfiddle.net/jBgqW/2/.
This is somewhat thread necromancy, but I've just faced this problem and have a solution to it, if not for the original poster then for people like me coming from google.
As noted, putImageData directly replaces pixels rather than alpha blends, but that also means it preserves your alpha data. You can then redraw that image with alpha blending using drawImage.
To give an example, lets says we have a canvas that is 200 by 100 pixels and a 100 by 100 imageData object.
// our canvas
var canvas = document.getElementById("mycanvas");
var ctx = canvas.getContext("2d");
// our imageData, created in whatever fashion, with alpha as appropriate...
var data = /* ... */
// lets make the right half of our canvas blue
ctx.fillStyle="blue";
ctx.rect(100, 0, 100, 100);
ctx.fill();
// now draw our image data to the left (white) half, pixels are replaced
ctx.putImageData(data, 0, 0, 100, 100);
// now the magic, draw the canvas to itself with clipping
ctx.drawImage(canvas, 100, 0, 100, 100, 100, 0, 100, 100);
Voila. The right half of the image is now your image data blended with the blue background, rendered with hardware assistance.

Resources