-=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- (c) WidthPadding Industries 1987 0|511|0 -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=-
SoCoder -> Blogs Home -> Blogs


 
power mousey
Created : 24 June 2007
 

The entailing Python and Pygame



like the mythic and medical signs of the ancients
where two snakes are entwined on the staff of Mercury.
Where Mercury was not the only messenger of the gods and goddesses but also had the gift of healing and regeneration too.

I'm also entwined in the relearning the basics
and intricansies and dependecies of both Python
and Pygame.




um...one definite thing that I'm going to do:

relearn or bone up on functions and pass and return
a tuple with the data items of event,background,screen1,
and a color variable to a function to check and change..
if need be the color of the background.

but what I can gather from this simple snippet:

Pygame is a game library/package and a wrapper for
an interface of SDL and Python itself.
Within Pygame...the package or main module
contains classes,subclasses and submodules.
And also special functions(subsytems ) and other atribute
data types too. I got a headache!!
And these submodules contain classes,subclasses, special
functions too.

A few important ones are:

Display... a submodule and for the graphical display.

Surface... a class. The screen is considered a surface itself. The Surface is an rectangular area that contains some kind of image.

Rect.... a class to derive objects that represent a rectangle. You use rects to help determine the size and position of obects on the screen(the surface of the screen)
and to detect whether two objects collide.

Input modules...for event handling and user input.
There is an pygame object to represent the keyboard and keys, mouse and joystick.

Output modules...for output and to manage different image formats. It also has modules for audio output of music and sound effects too.

Utility modules...these include working with time, transformation functions, and even for managing fonts
and the cd-Rom drive.

I don't know about you.
But, I'm still hazy and fuzzy considering all these classes,objects, modules, submodules. But as I learn and code as I go...I will get a better understanding of the relationships involved.

cheers
power mousey

 

Comments


Monday, 25 June 2007, 11:41
power mousey
I learned and fiqured out how about all those keys.
Create a function to check the keys...umm hey! and why not
a function called CheckKeys.

Then for the parameter to pass and return...
create a tuple. Tuples are like arrays.
And contain mixed data items...which can be integers, floats, string, even other tuples, etc.
In the event handling section if an event.type equals
a KEYDOWN event...and hence a key...then call the
CheckKeys function to see if its a legal key and perform any particular action for that key...if any.
yet, I first create/re-create my tuple. And the tuple is an object and has a variable.
Then I call my tuple variable to equal to the CheckKeys function and the tuple variable itself as the parameter.
Then on return of the function and back to the main program and within the main loop...I extract the data items
from the tuple variable itself again.

Got a headache??
I certainly did...but after a few reads and a few times thru. I somewhat understand it better.

I think.

um...an example would be good.
I know. It will be forthcoming.
um..let me ponder n wonder and work on it....
Monday, 25 June 2007, 12:22
power mousey
all right!

here is some code.




indentation is very important in both
Python and Pygame.
Monday, 25 June 2007, 12:40
power mousey
okay....here is mouseys' fuzzy logic in play.
and also what is going on...per frame.
And thats 30 frames per second in the while game loop.

if the event.type equals a KEYDOWN
the user has pressed a key then

a tuple is assigned/re-assigned
with the event,background, KeepGoing objects.
the data items.

the CheckKeys function is called with the tuple
of mydata is passed as the parameter. And mydata
on the left will be re-assigned for any new return
value of the tuple of itself.

then, the item objects(values) are extracted from
the tuple of mydata itself.

same thing happens within the CheckKeys function.
the mydata tuple is extracted with the data items or
objects. They are are rolled out for use.

Then at the end of the function
the data items or objects are rolled backed
into the mydata tuple itself.
Monday, 25 June 2007, 14:24
f4ktor
Although I'm not really interested in Python I find that stuff quite interesting Keep on going!
Monday, 25 June 2007, 17:29
power mousey
you betcha I'm going to keep going.

I'm really liking coding in this Python and Pygame.

The mousey will have a go at the mouse, next. ^^
Monday, 25 June 2007, 17:53
Blitz3Dman
Neat stuff, mousey.
Wednesday, 27 June 2007, 15:07
power mousey
okay, a simple snippet of a basic mouse function.

First, here is some code




okay.
After I load in and initialize the Pygame library
a screen object is created with the display module.
The screen is a Windowed screen set at 640 by 480
resolution. Also, a caption is placed at the top
as a title bar. In this case it reads as follows:
"Some Mouse functions"

then, a surface background entity is created onto the
screen and placed within the confines of the Windowed
screen.
also, a surface entity know as 'box' is created as well.
Its simply a red square with 25 by 25 pixels.
Also, its given a x,y postiton to be displayed
onto the surface background of the screen.
The variables of box_x,box_y contain and determine
the position of the red box entity onthe background of the screen.

again a clock object is created with the time module and its Clock method. While the main loop is run its set/reset for a frame rate of 30 frames per second.
the while loop variable KeepGoing is set to True
until the you or the user clicks the Quit button in
the Windows screen.

and within the event handling section, you will notice
pygame.MOUSEBUTTONDOWN and pygame.mouse.get_pos()
The MOUSEBUTTONDOWN is a definition for the mouse module.
If the event.type is a right or left mouse down click
within then... a tuple that contains the variables
of box_x, box_y are assigned/re-assigned the current x,y
positions of the mouse with the function of
pygame.mouse.get_pos().
This is a method of the mouse object within the imput modules of keyboard,mouse, and joystick. So, within the mouse object of the mouse module the function retrieves and returns the current mouse x,y postions and places them into the tuple which contains the variables box_x, box_y.

Later on in the refesh and display screen section
the square or red box is seemingly move and is display where the mouse is pointed to on the screen and clicked down...then released.
Friday, 29 June 2007, 01:59
power mousey
okay here is some more code.
I first just create the basic construct.
Which also includes the game loop.
I do this to make sure the construct is working fine.
Then I add other features and/or modify the code too.




as you can see..
if you read and follow the code...
I added a few new things to the code.

I created a screen1 object with a resolution
of 800 by 600. Also, I set a pygame flag to Full Screen.
I first tried the program in regular console Window
mode. SO I left the second command in...which is
pygame.display.set_caption("Display Heroes1 picture")

just in case...if I want to change the screen mode
back to a console Window. In Full Screen mode the caption
title is not displayed.

Also, in the event handling section I added some detection scheme to check whereby if the Escape key is pressed then
the while loop will exit and the program will end.
Cause again, the Full Screen mode does not have the Window box options such as minimize, hide, and quit. I left the
detection routine of pygame.QUIT if again I change the screen mode back to Window console mode.
But even in Window console mode both detection schemes will work too.

The biggest and newest addition is the magic1 object.
The magic1 object contains a bmp picture of "heroes1.bmp"
Also, it is converted into a format that both Python and Pygame can handle better and more efficiently.
Also in the screen refesh and display section...
a blit is done on this object of magic1.
Which contains the background picture of "heroes1.bmp"
Its blitted into a memory buffer and at the x,y coordinates
of 0,0. Which again is a tuple representing the x,y coordinates.
Then the display is flipped with the double buffers.
Also I have a wait of 3 milliseconds. This is for smoother
sequence and give a few tiny moments for Windows to breathe and do some of its other chores too.
Monday, 02 July 2007, 14:26
power mousey
time for another snakey snippet...
of the Python+Pygame persuasion.




this program is definitely the same as a basic
game loop or construct. Essentially, it will display
a blue background suface on a screen with a resolution
of 640 by 480 and within a Window screen.
You can also close it normally and usually with the
Quit box option on the upper right hand side of the
Window. And again, this is detected and utilized in the
event handling section.

The only 2 different and noteworthy things in this program
are the utilization of fonts and also more commands and definitons of the mouse object.

First and about fonts. In the Output module a font class
is set up to use both system and custom fonts. In the section of this particular program I elected to use a system font that is installed on Windows XP computer...and hopefully is backward compatible.
If the program lets say is run thru Linux or even a Mac
Python will look for this font but since it will not find this font cause its a Windows font it will replace and use a generic or default font.

Text is a special surface object. You set up and create
a font object derived from the font class.
You create and name a variable and assign to the pygame
font class and for a system font. The method contains 2 parameters: the name of the system font and the size in pixels.
Then, with your font object created.
You use it and its render method to create a text object. The render method contains 3 parameters:
the text itself, anti-aliasing off or on...0 or 1, and
the color of the text in rgb format.
This rgb format is contained within a tuple. A tuple of 3 elements.

Now onto the mouse object and in the event handling section. pygame.MOUSEMOTION is a constant and definition
for the mouse object. This indicates and is used to check and detect if the mouse is in motion.
And the mouse is really sensitive and moves at the slightest motion.
The mouse command method of pygame.mouse.get_pressed()
checks for either a left button, middle button or right button presses.
The mosue mechanism to check for a specific or combination of button presses is again with a tuple. And in this case
with a 3 ordered element tuple. (1,0,0)-->
meaning or indicating left button pressed...ignore both the middle and right button press. Or another example such as
(1,0,1)-->is there a lefft or right button press?

So essentially in this snippet from above:

a text of "Might and Magic" is display onto a blue background screen and with a font of Comic Sans MS and a size of 30 pixels.
If the mouse is in motion and with a left button press
then the text of "Fallout 2" is displayed.
Elseif the mouse is in motion and with a right button
press, then the text "Might and Magic" is displayed.
Friday, 06 July 2007, 16:15
power mousey
okay, my first attempt with sprites and actual OOP
in action. Actually, all the data items in Python
are objects built from classes. This includes strings,
integers, floats, lists,tuples, dictionaries(dict), etc.

Yet, to actually create your own recipes from
a derived base class. Well, let me show you the code
for a simple and basic sprite. Then, I will dissect and
discuss it afterwards.





okay, now as you can see this program...named
square1.py is heavily commented and in certain sections.
Especially in the class recipe or definition of Square.
This program is used for and as a template and also
for a reference. The reason why for the large number
of comments. Who knows...maybe in a week, a month or two when I come back to it, I'll have trouble following it
or figuring it out. Thats the main reasons for a lot of comments.

Now to dissect this program.
The program square1.py.

(1)I load in and initialize the pygame library or package.
Always, the first thing you do. Even better, incorporate
and check to see if both pygame is loaded in properly and as well as initialized to. If not, set up and display
and return specific error message.
But for all practical purposes...I'm showing just a basic sprite and with class definition and OOP. I will incorporate
this error checking system later.
Right now, if pygame doesn't load properly and/or pygame isn't initialized then Python will raise and display an error exception for the specific error.

(2)as you can see I now create a screen object.
And also in the main() function I screen blit the background once.
What the fudge!?? why create a screen object now
rather than in the main function as in all the other programs that I have shown so far??
The reasons for both of these are:

I'm setting the screen object to global.
Also, I screen blit the background once because
it takes a lot of processing power and time to blit
the background onto the screen...and let alone every 30 frames per second. Plus, additional processing for other things too...such as logic,movement, event handling and the like.
Yet, the main reason why I set up the screen object as
global and blit the background on the screen once in the main function and out and away from the while loop(game loop) is because the Sprite Group manager or system utilizes "dirty rect drawing and animation".
In other words, it just clears and paints those portions of the background as it updates and re-draws the sprites.
But, not the whole background on the screen.

(3)I create a Square class. I'm making a new sprite
recipe. And its derived from the built in pygame Sprite object. All its own the built-in sprite object does nothing but is a template with useful attributes and methods inorder for you to design blueprints of your own sprites and build or make their assocative objects.
So, you define a class and with a name and refer to
the built-in pygame sprite class/object.



underneath and indented from the class definition is
an constructor type initializer for the class.



this is similar to a constructor method and initializes
the class to certain values and methods.
The first initialization underneath this is to initialize the built-in sprite class/object and to your class. So, and inorder for your class to use the features of pygame built-in sprite.
Within the built-in pygame sprite are 2 attributes. These
are image and rect. Image is for an graphical attachment...if any...to the sprite. You can even have text to represent graphical as a sprite as well. Also, you can can even have a blank or empty sprite too.
The second attribute sets up the rect object where both size,placement,position and movement can be set up and used too. In most cases...the size of the rect will be the size of your image. Although, you can make it bigger or smaller too.

I also set up the class where the center of the square
...when built...will be at x-10, y-200.

Also, I incorporated a speed and direction of the Square class and any built objects with a dx,dy attributes.
Where dx is 4 and dy is 1.

Another important feature and definiton of a class.
And I should have talked about it at the start or at least a passing refences is the "self" word.
self is a reference to the class itself.
And with a built object of that particular class refers to that specific object.


Another built-in feature of the pygame Sprite is the update method. You don't have to include one. Yet, in most cases you would if you want and like to perform movement,displacemen, color changes, collision and boundary checkings, and other things too.
In the update method of this program:

I move the red square...actually its center by an additional 4 pixels per each update. The right of the square is checked to see if it is greater than the screen width. If it is, then the dx of class...of the object built... is assigned a minus 4 and moves back and left.
If the center of the square is almost at the near left edge(by 2 pixels or less) then the dx of this class...and of any object built..is assigned back the negative(in this case back to a positive 4) and the square bounces and moves to the right again.
A similar situation occurs with the vertical movement of the red square as well. The red square moves down and by 1 pixel per update. When the bottom of the rect of the red square reaches or is greater than the height of the screen
the dy changes to a negative assignment and starts to move up by 1 pixel per update.
Howevwer, if the top of the rect of the red square is 2 pixels or less then the assignment of another negative makes the current dy positive again.
So, that the vertical movement portion starts to move downward again. And in an ascending numerical order of 1 pixel per update.


I will continue onward and with the main function
in another section and at another time.
Stay tuned and check back for more mousey class.

cheers
power mousey
Friday, 06 July 2007, 23:39
power mousey
okay, now onward into the main function
and designated with




first thing, first.
a caption title is created and displayed
on the Windowed 640 by 480 screen.
It will, of course, read "Basic Sprite and Basic OOP".

then, a background object entity is created,
converted to a format that both Python and Pygame can
handle more effficiently, and is filled with a color blue
and with small tints of red and green too.
Just a stylish blue flavor for the eyes.

then, the whole background is blitted on the screen.
And only once and outside the main loop.
Remember blitting the whole screen is a complex process
and takes up valuable computational power and resources.
Besides, the "dirt rect drawing.animation" utilized by the Sprite Group manager will take care of any necessary portions of both sprite and background clears,updates and re-draws as well.
Finally, an object named 'box' is created from the Square class. And the object is placed into the Sprite Group
system. Additional sprite objects of the same and/or different sprite classes can be grouped together.
A variable object is assigned to this particular Sprite Group manager. Although, there can be other different Sprite Group mangagers too. In general at least one will
do a lot of times.
allSprites is the object name of this particular
Sprite Group manager.

Next, both a clock object and a while loop object
are created for the game loop.
Within the while 'game loop':

clock frame rate is set to 30 frames per second
event handling section checks to see if a mouse
has clicked the quit button option on the upper right
side of the Window screen. If it has, it exits on next
entry of while loop.

after this cntrol is handled by the Sprite Group mangager.
And assigned and designated by the object name of 'allSprites'.
allSprites will clear all the sprites onto the screen
and replace with portions of background...which in this case is blue. Net, the Manager will call or page
all of the sprite objects update methods...if any...and the methods will perform any movements, logics,actions and functions.
Then, the Mangager will redraw the sprites based upon each of the sprite object(s) update methods and draw only the
sprites involved and sections of the background screen.

then, the pygame.display.flip() method will be called
to display the whole buffer ono the screen.


again, at the end of this program the main() function is called.
Tuesday, 10 July 2007, 12:20
power mousey
here is a snippet done in Python
and Pygame that defines a class
of a Circle sprite. With this class you can build
and use a particular circle as a sprite.
Try to follow along to see whats going on.
The comments should help a little and make some
things clear.
I will explain in the next section of what
this program corecircle1.py does.


Tuesday, 10 July 2007, 13:10
power mousey
okay...here is whats going on.

I first load in and initialize pygame.
I'm also importing the random module.
I will utilize this later.

again, I create and make a screen resolution object
and also make it global. So that both the main() function
will use it and also class definitions too. Besides,
remember the 'dirty' rect drawing/animation that
pygames' Sprite Group manager uses.

now, Im defining a class called Circle
and is derived from Pygames' basic built-in Sprite
class/object.
The image attribute is just a rectangular surface.
And is a default square like surface of 20 by 20
pixels. The color of the square is that of the blue
background...which is a rgb tuple of (10,10,250).
Then, a circle is drawn on this surface object.
The pygame circle command is as follows and in this line
of the program: draw a red circle on the surface of the object. And with the center of x,y at 10,10 of the surface,
and with a radius of 10.
Also, the last argument specifies the line width. If its 0 then draw it as filled.

next, create and assign a rect object for this image of the class...and for any object built from this class.
I then, assign the rect attributes of placing the whole rectangle which contains the circle of x-10, y-100.
In other words the upper left,top portion of the rectangLe...which contains the red circle...is placed at
the starting x,y coordinates 10,100

2 custon attributes are created. color1 and lock.
color1 will contain the default color of red or rgb
tuple of (250,0,0). lock represent a flag variable
where you can change the color of the circle object.
And if you change the color of the particular circle object
then that changed color will be locked up. Where you can't change the color anymore.
You can change only the color of the circle once.
And if you do..then the lock variable will be turned on as a 1. Indicating lock up.

in the update method of the class blueprint
and in any associative object built....
a check will first be made if the color has been changed thru the objects color1 atrribute. If it has then the circle will be redrawn on its surface image and with the specified color. And again, will be locked up....where you can't change the circles' color anymore. Its just a one shot deal.

|edit| I forgot to add... that the class and the
newly built object...in this case core1. That its rect
attribute of center is assigned an x,y coordinate of
where the mouse is moved and place within the screen
of the Window. The format is a 2 element tuple consiting of both x,y coordinates of the mouse.
The prebuilt mouse object and its method of
pygame.mouse.get_pos() retrieves the current mouse x,y coordinates and the rect(rectangle) center is assigned
the mouse x,y coordinates
There is also an indivual attrribute of the rect object
of both the center x and center y of the rectangle of the sprite. In this case and repsectively its:

self.rect.centerx
self.rect.centery

yet, self.rect.center includes both the x,y coordinates
and of the center of the rectangle. And in and within tuple format of a variable and/or a bracket format representing a two element tuple.

|edit|



then checks and adjustments will be made to see if the circle has moved off the screen boundaries of both the
screen width and height.


in the main function:

a caption is displayed on the pygame Windowed screen
set at 640 by 480. The caption title is "Circle..basic Sprite class/object"

a background entity object is created,converted and filled with a blue color of rgb tuple (10,10,250).
then the whole screen is blitted and onto the background and starting at x,y coordinate positions. Specified by the tuple of (0,0).

now and finally!.... a circle object is built.
The circle sprite object is called core1.
And as you can see.. the core1 color1 attribute
is assigned a green color of (0,250,0). A one shot color change occurs and the sprite object color is changed to green and only once. its attribute of lock is loced up
and as a 1.
Then, the core1 sprite circle is assigned to the pygame Sprite Group manager. And represented as a variable named allSprites.

next..., a clock object is created and along with a while loop varible called KeepGoing. KeepGoing is set to True.
also, pygames' mouse object is set to invisible. So,
when the program is run the mouse and its cursor is hidden and disappears. This is because the intent of this program is to move the circle using the mouse.
The mouse will reappear but outside the pygame Window screen. If its inside the screen, it will remain hidden or invisible.

within the game loop:

the frame is set/reset to 30 frames per loop.
the event section checks to see if the exit option
box of the Window screen has been activated..or simply clicked. Indicating that the loop and program will exit within the next loop entry.
Then control is passed to the allSprites Group manager.
all portions of the screen and background of all or any sprites are cleared including the sprites themselves.
Then each sprites' update method is called.
Then the allSprites will redraw all the sprites themselves
onto the screen and any background portions of each sprites background as well. hence...dirty rect drawing and animation.

then the whole scene is flipped and displayed.
Also there is a breather or refresher refresh rest of
3 milliseconds too.
When the program is quit or exited...the mouse is turned back on to display again and with the pygame.mouse.set_visible(True) command.
Wednesday, 11 July 2007, 08:32
power mousey
Next, I will design a class
inorder to create a object to display text.
I will include some custom attributes and methods
for font size, color for text, and perhaps to move
text.
hmmm...maybe add some constant definitions
for BOUNCE, WRAP, MOUSEMOVEMENT, SCROLL, and a
few other options.
Thursday, 12 July 2007, 22:48
power mousey
well here is some code
for a basic sprite text class
to build a text object.

if you have been reading my logs
of a blog, lets see if you can follow along
and see what the program does.
A re-edit of some of the details
of this program will be forthcoming.
But I'm in no hurry either.







some details and explanations will be placed
here and in about 10 minutes of post:

okay...here we go:

I will create a Sprite text class
inorder to build text messages.
There are defaults of font type,font size,
color, and even x,y position placements
of the text. And, even a text message too.
Defined within the class of SpriteText
a font of the class itself is assigned
a system font of 'None' or generic.
And with a font size of 25.
A text message will be initialized with the
message of "This is text"
Also, a default x,y position is assigned
with self.left of 100 and self.top of 50
The color of the text is black and a three rgb element of
a tuple--> (1,1,1)
the change in the width and speed is
represented by self.dx, which is self.dx=2
The text message object will move 2 pixels either
left to right or right to left by 2 pixels per loop.

Normally and usually in the update method()
logic and math is applied, keys,mouse and screen boundaries checked, collisions determined, and movemnet...if any.. occurs with the sprite object.
Yet, in this case...the image object is created/recreated
and reassigned as well as the rect object due to potential changing of the text message itself.
Also, in the update method() I move the text message object by 2. And where screen boundaries are checked for the maximum screen width and the mimimal screen width.
I use the self.rect.left for moving along the width of the screen and bounce the message seemingly from left to right and right to left. And back n forth again.
Notice that I reassign the self.left variable to the
new calculated addition of self.rect.left and self.dx
The change in dx or the width movement of the object.
This is again due to updating the text message
in the class update method() because of the potential to change the message itself. And hence its image and rect attributes.
I have also noted and worked with that both self.dx and self.dy are part of the self.rect object and will only work
with the pygame self.rect object rect built into the class itself. Its part of the class. I thinks its either a bug or a quirk of Python and pygame.
I will investigate this more further and later.

Now....down into the main function and where the Spritetext object is built as message1. I changed the defaults of the color of the text, and its starting x,y
positions itself. I could've changed the message of the text
to something else...even made it empty such as ""

Later on, I'm going to add some more options to
this text object and the defining SpriteText class by adding some more features....static or no movement,
scroll
one way and wrap around...either left or right scroll, bounce horizontal and/or vertical. Even, have the text follow the mouse.
Saturday, 14 July 2007, 09:22
power mousey
haha!!
you should hear my kitty Lisssie...Lissie Kissie
and the way she meows as she bumps n bounce across
horizontally the walls of the screen.

yeah, its so cutesy.
But after awhile, it can get annoying.
So, I could enter a counter..or even better a flag
option so you can turn off the meowing moans
of Lissie. Or, after so many times she meows
as she bounces against the walls.
My poor ole Lissie kitty.

here is the program she is contained within
or an exact representation of her:




you have enough information to figure or follow the program along. Except...for the mixer.
And I don't mean mixing martinis either.
There is a sound module in Pygame called mixer.
At the start of the program I initialize the mixer module for use.
Now within the Lissie cat sprite class...inorder to build instances or objects with, I create an attribute sound called meow....actually its self.meow.
This self.meow is an object attribute of the Lissie class
and is assigned and loaded with a wav sound of catmeow.wav
There are other sound formats supported such as mp3 and Ogg Vorbis. In Pygame...Ogg Vorbis works really well and the best of the sound formats.
I use the objects play sound method... self.meow.play()
when the rectangular lissie pic object collides/touches the screen boundaries of maximum and minimum widths.

And thats all there is to the program.
I could've assigned different default x,y positions
and as well as a different image.
And even a different dx change of speed and direction.
And utilizing the object or instance built and its own attribute, and outside of the class.
But I kept it simple and with the defaults and inside the class definitions itself.
Tuesday, 17 July 2007, 15:21
power mousey
I asked some people at work
including Philthy Drone, Danny
and a few others what would be more natural
and user friendly in building a Lissie sprite object
from the class

either



or.....



in other words, when I build a cat object...the instance
of the Lissie class will be passed starting x,y parameter
locations or it will have default starting x,y positions and then can be changed once using custom attributes of self.top and self.left-->which will object is built and
to change once and only once the starting x,y positions with
and in this case: cat.top=50 and cat.left=20 for example.

They pick the second option or choice where you specify and pass the parmaeters which represent the starting x,y positions of the Lissie cat object is built.
I added some extra code where you can change and only change once the starting x,y positions with the custom attributes of self.left(cat.left) and self.top(cat.top).
I commented the changes out with #.

here is the code:




now is the time...
to move on and with both a studious scholary treatise
and also with an artistic appreciation:
design a class module of classes and sub classes
of Sprites for use. And also to extend them as well.
Then, import the module ready for use for some
more snippets,demos, games and other applications too.