I am using VPython in my attempt to model a ball bouncing off a wall.
To make my code more elegant, I have decided to use class inheritance to set the dimensions and properties of my objects (at the moment, it's the ball and a wall). After I ran the code, the shell didn't produce any errors, however, it did not produce a window either.
I am fairly new to programming and I am using VPython 2.7 in Wine on Linux Mint 18. I have a feeling that I have missed something obvious but I don't know what it is.
My code so far is as follows:
from visual import *
class Obj(object):
def __init__(self, pos, color): #sets the position and color
self.pos = pos
self.color = color
class Sphere(Obj):
def __init__(self, pos, color, radius):
super(Sphere, self).__init__(pos, color)
self.radius = radius
class Box(Obj):
def __init__self, pos, color, radius):
super(Box, self).__init__(pos, color)
self.size = size
self.opacity = opacity
ball1 = Sphere((-5,0,0,), color.orange, 0.25)
wallR = Box((6,0,0), color.cyan, (0.,12,12), 0.3)
I take it you never dealt with graphic aspects before, as there is nothing about it in the code you posted. Then it is time to begin !
By default, python works in console mode. To show an actual window, with icons and stuff going across it, you'll need to write it explicitly in your code, using modules like TKinter or pygame.
I suggest you read the tutorial I found here : http://code.activestate.com/recipes/502241-bouncing-ball-simulation/ as it does what you want (with TKinter), including the window part. Take a look at it and let's see if you still need help !
Related
This is my first time posting to Stack Overflow, and I’m very new to the scene module for Pythonista, so please forgive any minor mistakes, and tell me if I have any mistakes regarding the formatting/question.
I’m currently trying to create a program that allows the user to hand draw a circle, and then take the circumference. However, the look of my line depends upon the send of which I draw. For example, if I draw fast, then the dots (the line segments) are few and far between, while slowly drawing makes it much more accurate. (I do not have the circumference yet, but I figure I can put a dot down every nth distance, then use the amount of dots and calculate it from there).
The question I’m posing is, how do I make it so that when I draw, speed does not (or at least insignificantly) impacts the line?
Notes- I’ve seen examples in the examples tab on Pythonista, and they all us the UI module, but since I already know a tiny bit of Scene, I want to stick with this. If it proves to be impossible, I’ll switch. (Also, if someone wishes to, could they create a tag that is “scene-module”? Thanks.)
from scene import *
import math
allPoints = []
line = []
def addPoint(x, y):
allPoints.append((x, y))
class MyScene(Scene):
def setup(self):
self.background_color = '#a9a9a9'
self.followPlayer = SpriteNode('shp:Circle', position = (-10,-10))
self.add_child(self.followPlayer)
def touch_began(self,touch):
self.followPlayer.position = touch.location
def touch_moved(self, touch):
x, y = touch.location
addPoint(x, y)
self.followPlayer.position = touch.location
self.drawNode = SpriteNode('iob:ios7_circle_filled_24', (x, y), parent = self)
run(MyScene())
Thank you
I am looking for a way in which wxPython GUI elements can be added into pygame. If there is an alternative to solve the purpose of adding GUI elements to a pygame please suggest so. I am having problem in installing PGU.Thanks for help.
Nope; you CAN add wxWidgets to PyGame. It's trivial to add open/save dialogs, buttons, etc. Sometimes it gets nasty when you try to share areas, (as above, there's conflicting window systems), but it is definitely doable.
I wrote the following years ago, so it's messy; but at least it's simple. It should help you get started:
class SDLThread:
def __init__(self,screen):
self.m_bKeepGoing = self.m_bRunning = False
self.screen = screen
self.color = (255,0,0)
self.rect = (10,10,100,100)
def Start(self):
self.m_bKeepGoing = self.m_bRunning = True
thread.start_new_thread(self.Run, ())
def Stop(self):
self.m_bKeepGoing = False
def IsRunning(self):
return self.m_bRunning
def Run(self):
while self.m_bKeepGoing:
pass
## GetInput()
## Draw()
self.m_bRunning = False;
class SDLPanel(wx.Panel):
def __init__(self,parent,ID,tplSize):
global pygame
wx.Panel.__init__(self, parent, ID, size=tplSize)
self.Fit()
os.environ['SDL_WINDOWID'] = str(self.GetHandle())
os.environ['SDL_VIDEODRIVER'] = 'windib'
import pygame
pygame.init()
icon = pygame.Surface((1,1));icon.set_alpha(0);pygame.display.set_icon(icon)
global Surface
Surface = pygame.display.set_mode(tplSize)
self.thread = SDLThread(Surface)
self.thread.Start()
def __del__(self):
self.thread.Stop()
I dont think its possible since wxPython (using wxWidgets c++) is a wrapper around the window management system, it rely on the OS functions to draw on screen (it convert to the right system calls depending on OS).
Pygame uses SDL and a simple code to window management system, it calls few OS functions just to create the window and give it to SDL to draw on it, like a canvas.
One way is:
using ctypes to make C calls into OS library files to draw system native widgets, this way you aren't using any pygame functions.
Other way(ugly and not sure if works):
I dont know how, but finding a way to convert widgets into image buffer objects and use it like surfaces(plain bitmaps).
What I think you should do:
Use pygame, build your own GUI using surfaces and mouse/keyboard events to control it or download some pre-made.
Stick with wx, you can build your GUI easily on system native theme, also you can use DC (draw contexts) to draw like pygame, and maybe (not sure) include pygame context into wx as one widget.
You can benefit from wx having its own event handler.
I hope it helps you in some way.
I am new to Python and have been working with the turtle module as a way of learning the language.
Thanks to stackoverflow, I researched and learned how to copy the image into an encapsulated postscript file and it works great. There is one problem, however. The turtle module allows background color which shows on the screen but does not show in the .eps file. All other colors, i.e. pen color and turtle color, make it through but not the background color.
As a matter of interest, I do not believe the import of Tkinter is necessary since I do not believe I am using any of the Tkinter module here. I included it as a part of trying to diagnose the problem. I had also used bgcolor=Orange rather than the s.bgcolor="orange".
No Joy.
I am including a simple code example:
# Python 2.7.3 on a Mac
import turtle
from Tkinter import *
s=turtle.Screen()
s.bgcolor("orange")
bob = turtle.Turtle()
bob.circle(250)
ts=bob.getscreen()
ts.getcanvas().postscript(file = "turtle.eps")
I tried to post the images of the screen and the .eps file but stackoverflow will not allow me to do so as a new user. Some sort of spam prevention. Simple enough to visualize though, screen has background color of orange and the eps file is white.
I would appreciate any ideas.
Postscript was designed for making marks on some medium like paper or film, not raster graphics. As such it doesn't have a background color per se that can be set to given color because that would normally be the color of the paper or unexposed film being used.
In order to simulate this you need to draw a rectangle the size of the canvas and fill it with the color you want as the background. I didn't see anything in the turtle module to query the canvas object returned by getcanvas() and the only alternative I can think of is to read the turtle.cfg file if there is one, or just hardcode the default 300x400 size. You might be able to look at the source and figure out where the dimensions of the current canvas are stored and access them directly.
Update:
I was just playing around in the Python console with the turtle module and discovered that what the canvas getcanvas() returns has a private attribute called _canvas which is a <Tkinter.Canvas instance>. This object has winfo_width() and winfo_height() methods which seem to contain the dimensions of the current turtle graphics window. So I would try drawing a filled rectangle of that size and see if that gives you what you want.
Update 2:
Here's code showing how to do what I suggested. Note: The background must be drawn before any other graphics are because otherwise the solid filled background rectangle created will cover up everything else on the screen.
Also, the added draw_background() function makes an effort to save and later restore the graphics state to what it was. This may not be necessary depending on your exact usage case.
import turtle
def draw_background(a_turtle):
""" Draw a background rectangle. """
ts = a_turtle.getscreen()
canvas = ts.getcanvas()
height = ts.getcanvas()._canvas.winfo_height()
width = ts.getcanvas()._canvas.winfo_width()
turtleheading = a_turtle.heading()
turtlespeed = a_turtle.speed()
penposn = a_turtle.position()
penstate = a_turtle.pen()
a_turtle.penup()
a_turtle.speed(0) # fastest
a_turtle.goto(-width/2-2, -height/2+3)
a_turtle.fillcolor(turtle.Screen().bgcolor())
a_turtle.begin_fill()
a_turtle.setheading(0)
a_turtle.forward(width)
a_turtle.setheading(90)
a_turtle.forward(height)
a_turtle.setheading(180)
a_turtle.forward(width)
a_turtle.setheading(270)
a_turtle.forward(height)
a_turtle.end_fill()
a_turtle.penup()
a_turtle.setposition(*penposn)
a_turtle.pen(penstate)
a_turtle.setheading(turtleheading)
a_turtle.speed(turtlespeed)
s = turtle.Screen()
s.bgcolor("orange")
bob = turtle.Turtle()
draw_background(bob)
ts = bob.getscreen()
canvas = ts.getcanvas()
bob.circle(250)
canvas.postscript(file="turtle.eps")
s.exitonclick() # optional
And here's the actual output produced (rendered onscreen via Photoshop):
I haven't found a way to get the canvas background colour on the generated (Encapsulated) PostScript file (I suspect it isn't possible). You can however fill your circle with a colour, and then use Canvas.postscript(colormode='color') as suggested by #mgilson:
import turtle
bob = turtle.Turtle()
bob.fillcolor('orange')
bob.begin_fill()
bob.circle(250)
bob.begin_fill()
ts = bob.getscreen()
ts.getcanvas().postscript(file='turtle.eps', colormode='color')
Improving #martineau's code after a decade
import turtle as t
Screen=t.Screen()
Canvas=Screen.getcanvas()
Width, Height = Canvas.winfo_width(), Canvas.winfo_height()
HalfWidth, HalfHeight = Width//2, Height//2
Background = t.Turtle()
Background.ht()
Background.speed(0)
def BackgroundColour(Colour:str="white"):
Background.clear() # Prevents accumulation of layers
Background.penup()
Background.goto(-HalfWidth,-HalfHeight)
Background.color(Colour)
Background.begin_fill()
Background.goto(HalfWidth,-HalfHeight)
Background.goto(HalfWidth,HalfHeight)
Background.goto(-HalfWidth,HalfHeight)
Background.goto(-HalfWidth,-HalfHeight)
Background.end_fill()
Background.penup()
Background.home()
BackgroundColour("orange")
Bob=t.Turtle()
Bob.circle(250)
Canvas.postscript(file="turtle.eps")
This depends on what a person is trying to accomplish but generally, having the option to select which turtle to use to draw your background to me is unnecessary and can overcomplicate things so what one can do instead is have one specific turtle (which I named Background) to just update the background when desired.
Plus, rather than directing the turtle object via magnitude and direction with setheading() and forward(), its cleaner (and maybe faster) to simply give the direct coordinates of where the turtle should go.
Also for any newcomers: Keeping all of the constants like Canvas, Width, and Height outside the BackgroundColour() function speeds up your code since your computer doesn't have to recalculate or refetch any values every time the function is called.
I've been using pyglet for a while now and I really like it. I've got one thing I'd like to do but have been unable to do so far, however.
I'm working on a 2D roleplaying game and I'd like the characters to be able to look different - that is to say, I wouldn't like use completely prebuilt sprites, but instead I'd like there to be a range of, say, hairstyles and equipment, visible on characters in the game.
So to get this thing working, I thought the most sensible way to go on about it would be to create a texture with pyglet.image.Texture.create() and blit the correct sprite source images on that texture using Texture.blit_into. For example, I could blit a naked human image on the texture, then blit a hair texture on that, etc.
human_base = pyglet.image.load('x/human_base.png').get_image_data()
hair_style = pyglet.image.load('x/human_hair1.png').get_image_data()
texture = pyglet.image.Texture.create(width=human_base.width,height=human_base.height)
texture.blit_into(human_base, x=0, y=0, z=0)
texture.blit_into(hair_style, x=0, y=0, z=1)
sprite = pyglet.sprite.Sprite(img=texture, x=0, y=0, batch=my_sprite_batch)
The problem is that blitting the second image into the texture "overwrites" the texture already blitted in. Even though both of the images have an alpha channel, the image below (human_base) is not visible after hair_style is blit on top of it.
One reading this may be wondering why do it this way instead of, say, creating two different pyglet.sprite.Sprite objects, one for human_base and one for hair_style and just move them together. One thing is the draw ordering: the game is tile-based and isometric, so sorting a visible object consisting of multiple sprites with differing layers (or ordered groups, as pyglet calls them) would be a major pain.
So my question is, is there a way to retain alpha when using blit_into with pyglet. If there is no way to do it, please, any suggestions for alternative ways to go on about this would be very much appreciated!
setting the blend function correctly should fix this:
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA,pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
I ran into the very same problem and couldn't find a proper solution. Apparently blitting two RGBA images/textures overlapping together will remove the image beneath. Another approache I came up with was using every 'clothing image' on every character as an independent sprite attached to batches and groups, but that was far from the optimal and reduced the FPS dramatically.
I got my own solution by using PIL
import pyglet
from PIL import Image
class main(pyglet.window.Window):
def __init__ (self):
TILESIZE = 32
super(main, self).__init__(800, 600, fullscreen = False)
img1 = Image.open('under.png')
img2 = Image.open('over.png')
img1.paste(img2,(0,0),img2.convert('RGBA'))
img = img1.transpose(Image.FLIP_TOP_BOTTOM)
raw_image=img.tostring()
self.image=pyglet.image.ImageData(TILESIZE,TILESIZE,'RGBA',raw_image)
def run(self):
while not self.has_exit:
self.dispatch_events()
self.clear()
self.image.blit(0,0)
self.flip()
x = main()
x.run()
This may well not be the optimal solution, but if you do the loading in scene loading, then it won't matter, and with the result you can do almost almost anything you want to (as long as you don't blit it on another texture, heh). If you want to get just 1 tile (or a column or a row or a rectangular box) out of a tileset with PIL, you can use the crop function.
I am making a battleship game for a project. While I have completed the logic and the game works with text input. I was hoping make a (very basic) GUI while still use the methods created for the text.
The two options I've been looking at are PyGame and Tkinter. PyGame does not seem to have a text output/label function. Tkinter does, but it doesn't seem as easy (i feel) as PyGame is.
Though I would love to give either of these frameworks the time they deserve, I have just over 60hrs before this is due.
I wanted to know if anyone one has any experience or insights and if it is a realistic option.
Thanks as always!
This is a fairly trivial thing to do in Tkinter. A battleship game shows an array of coordinates which you can display as a grid of checkbuttons.
You could check Kivy, it's working in top of OpenGL, provide severals basics widgets (label, button, slider, textinput, layouts, ...), and you can create your own / display graphics etc. Works as a python framework, almost all platforms.
You can also check the recent game contest to see what you can do with it :)
Why don't you try Cocos2D?
It's higher level, and it supports rich labeling (Class cocos.text.RichLabel)
http://cocos2d.org/
I suggest you use pyqt/pyside for this task. This lets you access the powerful Qt framework which has great documentation. If you design a game that does not need fast graphics you can simply use QGraphicsView/QGraphicsScene and related classes to display icons/numbers/whatever. Of course you can use OpenGL with Python and Qt as well.
You can render text on pygame, just use:
class pygame.font.Font
#create a new Font object from a file
pygame.font.Font(filename, size): return Font
pygame.font.Font(object, size): return Font
method Font.render
#method of Font() to draw text on a new Surface
Font.render(text, antialias, color, background=None): return Surface
Simple example how to use text on pygame:
from pygame import font as pgfont, sprite as pgspr
import pygame as pg
class FontSprite(pgspr.DirtySprite):
def __init__(self, text, x, y):
'''self.image = surface'''
pgspr.DirtySprite.__init__(self)
self.text = text
self.color = [0,0,0]
self.image = self.get_image()
self.rect = pg.Rect((x, y), self.image.get_size())
def get_image(self):
self.dirty = 1
return pgfont.Font('fonts\\BRLNSR.TTF', self.size).render(self.text,
True,
self.color)