I am creating a game in python using Tkinter canvases, and I need to rotate a sprite in the game, I have attempted using PIL's
'image'.rotate()
however the loss of quality is far too high and it wont perform more than about 20 transforms before it starts to lag badly. Can this be fixed or are there any other options aside from making 100s of images by hand?
Here is my code:
shipPIL = shipPIL.rotate(math.degrees(increment), expand=True)
shipTex = ImageTk.PhotoImage(shipPIL)
canvas.itemconfig(self.object, image=shipTex)
increment = pi/20
You really should be saving the original image as a clean copy, and rotating it starting from the original each time. Depending on what you're doing, it may also be a good idea to cache the various rotations somewhere instead of calculating it each time.
EDIT: and TKinter is for GUI applications, not games. I recommend Pygame instead.
Related
is there any way to create a game were there are two background colors where one square is smaller than the other. In the background, I am thinking of being able to place buttons and so on. I have a game that works fine but I would like to develop it. As I have no knowledge about how to do, I have not tried it.
Pygame won't allow you to have more than one screen per application, if that is what you are asking. You can check the pyglet library for that: http://pyglet.org/ -
I can't figure out if you have any further doubts from your text, however - you will have to be more specific.
If it is about having a sub-section of the window as the action area of the game, and an outer margin where to to place controls, yes, that is just straightforward drawing with the provided calls.
This question already has answers here:
simple animation using tkinter
(2 answers)
Closed 6 years ago.
In Python 2.7, I want to display some simple graphics, such as a red square moving around on a blue window. On every frame, I want to update the position of the square, and render the new window. I am looking for something simple and lightweight.
I have seen people use matplotlib for drawing shapes, but I don't want to have to deal with axes and data points. I have also seen pygame suggested, but this seems to heavyweight for what I want, as I do not want to create a game, just a simple animation.
So what I really want is something where on every frame, I just indicate the colour of every pixel on an image, and then display that image. What are some good suggestions?
Tkinter is not good for setting individual pixels. If you want to move rectangles or ovals though (a small oval will look like a pixel, but it doesn't scale for updating a whole image).
def update(x,y):
canvas.delete('all')
canvas.create_rectangle(x-1,y-1,x+1,y+1)
You can, of course, be more judicious, saving the return value of the rectangle and then only clear the appropriate elements. Or you can move existing elements directly as Bryan points out. As he explains elsewhere Tkinter of course, supports drawing images, ovals, and a slew of other things. Here's a canonical source edit: that is old and not canoncial This one's slightly better For a general source on animating with a timer loop, here's Bryan agian
Bryan also noted that you can work with pixels directly You can do that with PhotoImage.
Array-Like Pixel Access Without Graphical Extensions
A robust module like pygame will be the most scalable option. However, I've had success (in educational settings only) writing graphics engines by modifying the elements of a numpy array and then displaying it as an image (you also need this link to display the images).
This lets you do pixel level modifications; since it's relatively trivial to write C-extensions that modify numpy arrays, you can prototype fast image processing doing custom manipulations. While I've written whole graphics engines using just tkinter this way, again I can only reccomend it for educational purposes.
Otherwise, just bite the bullet and pull in openGl or pygame. You'll save yourself a ton of time in the long run.
Summary
Very simple animations can be done right in tkinter
For educational purposes, you can do arbitrary graphics with numpy and tkinter
For rhobust animations, check out a full library (openGl, matplotlib, pygame) that suits your needs (graphical rendering, statistical graphing, game development, etc.)
Is it possible to scale all the items of a pygame program?
I am running the AdvancedDemo from with pygame project:
http://www.pygame.org/project-PaintBrush-1280-.html
But it is too large for my resolution. Is it possible to scale everything that is displayed to fit on the screen, without having to transform all the objects individually?
Thanks
Tom
Not sure how your advance demo works, but you can use
pygame.transform.scale
to scale down the resulting screen. This might be a bit slow though.
First question ever on stackoverflow. Been reading for some time now, while trying to learn Python and wxPython.
I'm writing a small app for presenting a large amount of data on the screen in a custom way. The data is stock information stored in objects in Python. Its about 100 stocks that should be presented at the same time on the screen. Every stockobject has 35 attributes, so it makes 3 500 attributes showing at the same time. And I want different fonts, size and colour depending on attribute. The background of each stockobject is changing depending on user (me) input.
So I tried making a interface with wxPython and a lot of StaticText controls. It took 5 seconds to load, timing it with timeit module.
Googling the net gave me an idea to draw the data on a device context instead. That took only 0.1 second. To make the app clickable I draw a second picture into memory with specific colours for each attribute. When clicking on the panel showing the picture I compare the coordinates with the DC in memory to calculating what was clicked. And now I am about to write a sizer routine so the user can change fontsize.
Well my question is quit simple: Do you think I chose the right approach?
Or is there a simpler more pythonic way to do this, without using StaticText that took forever to load?
Grids is not a solution for me, because I want the data to be presented in a very specific layout. To be able to do that with a grid, I would have to set the grid to 2px with and hight, and then merge cells all over the place...
edit:
link for downloading picture of the controll as it looked yesterday:
http://dl.dropbox.com/u/10606669/super.png
Ugly and not the exact way I want it to lok. This because of trying to write my own sizer routine.
You can try freezing the whole frame during the loading process, like this:
frame.Freeze()
try:
# load all data
finally:
frame.Thaw()
In general, though, having that many Window controls will hurt performance, so custom drawing is the only solution. You could simplify things a little by creating your own custom control for one stock (with its own EVT_PAINT handler, etc.) and then creating 100 of them. It should make your DC calculations easier. See Creating Custom Controls for more information.
I am trying to decide if it is better to use a pre-rendered large image for a scrolling map game or to render the tiles individual on screen each frame. I have tried to program the game both ways and don't see any obvious difference in speed, but that might be due to my lack of experiences.
Besides for memory, is there a speed reasons to not use a pre-rendered map?
The only reason I can think of for picking one over the other on modern hardware (anything as fast and with as much ram as, say, an iPhone), would be technical ones that make the game code itself easier to follow. There's not much performance wise to distinguish them.
One exception I can think of, is if you are using a truly massive background, and doing tile rendering in a GPU, tiles can be textures and you'll get a modest speed bump since you don't need to push much data between cpu and gpu per frame, and it'll use very little video ram.
Memory and speed are closely related. If your tile set fits in video memory, but the pre-rendered map doesn't, speed will suffer.
Maybe it really depends of the map's size but this shouldn't be a problem even with a low-level-computer.
The problem with big images is that it takes a lot of time to redraw all the stuff on it so you will get an unflexible "map".
But a real advantage with an optimized image(use convert()-function and 16 bit) is are the fast blittings.
I work with big images as well on a maybe middle-good-computer and I have around 150 FPS by blitting huge images which require just ~ 100? MB RAM
image = image.convert()#video system has to be initialed
The following code creates an image(5000*5000), draws something on it, (blit this to the screen, fill the screen)*50 times and at the end it tells how long it took to do one blit and one flip.
def draw(dr,image,count,radius,r):
for i in range(0,5000,5000//count):
for j in range(0,5000,5000//count):
dr.circle(image,(r.randint(0,255),r.randint(0,255),r.randint(0,255)),[i,j],radius,0)
def geschw_test(screen,image,p):
t1 = p.time.get_ticks()
screen.blit(image,(-100,-100))
p.display.flip()
return p.time.get_ticks() - t1
import pygame as p
import random as r
p.init()
image = p.Surface([5000,5000])
image.fill((255,255,255))
image.set_colorkey((255,255,255))
screen = p.display.set_mode([1440,900],p.SWSURFACE,16)
image = image.convert()#extremely efficient
screen.fill((70,200,70))
draw(p.draw,image,65,50,r)#draw on surface
zahler = 0
anz = 20
speed_arr = []
while zahler < anz:
zahler += 1
screen.fill((0,0,0))
speed_arr.append(geschw_test(screen,image,p))
p.quit()
speed = 0
for i in speed_arr:
speed += i
print(round(speed/anz,1),"miliseconds per blit with flip")
Depends on the size of the map you want to make, however, with the actual technologies it's very hard to see a tile-map "rendered" to take longer than expected, tiled based games are almost extinguished, however is always a good practice and a starting point to the world of game programming