@JonB I believe you are correct that none of the video game emulators are pure python or quite finished. They all have several dependencies that are incompatible with Pythonista from what I saw. Emulation is a fascinating concept to me, but way over my head as I am just starting to dip my toes into programming.
I took a look at applepy and I am very impressed. I will try to learn more about emulation and hopefully be able to understand it a little better.
I’m also blown away that you were able to adapt a pygame project to Pythonista. It goes to show that the possibilities are endless!
@Ti Leyon I’ve been reading through that link you gave me, and it is an awesome reference. I will also have to give iDOS 2 a try, I wasn’t aware that a DOSbox emulator existed on iOS!
It was difficult for me to figure out because I'm a beginner, but I seem to have gotten the sprite movement halfway working with buttons. The rotation of the walking textures works with the gravity() module,
(see: https://github.com/bbroadhead/pythonista-rpg/blob/master/knight_test.py or part 3 of the pythonista game tutorial)
but it is a little wonky with using the buttons to move. I think it’s just because I haven’t figured out how to get update(self) to update only while the sprite is in motion. In the game tutorial, it uses a simple threshold for gravity() so it only updates when the accelerometer reads above a certain value, but I’m unsure what to reference in update(self) so it only updates when you’re pressing a button. I tried to reference touch_began but no matter how I tried it didn’t like that.
- What could I put in the spot that I commented out so update(self) recognizes touch_began?
My end goal is to make the sprite four directional like an RPG instead of side-scrolling. Reference this video for an example.
Which brings me to my second question:
- How would I make the sprite move a static distance while you’re holding down the button? (For example, move a certain number of pixels across the screen) rather than movement that references a fraction of the screen size as used below (I implemented the idea from this thread, but I want the sprite to move independently of screen size).
Thank you in advance for your help!
import ui from scene import * import sound standing_texture = Texture('Idle.png',) walk_textures = [Texture('Walk 1.png'), Texture('Walk 2.png'), Texture('Walk 3.png'), Texture('Walk 4.png'), Texture('Walk 5.png'), Texture('Walk 6.png'), Texture('Walk 7.png'), Texture('Walk 8.png'), Texture('Walk 9.png'), Texture('Walk 10.png')] player = sound.Player('battleThemeA.mp3') player.number_of_loops = -1 class MyScene(Scene): def setup(self): self.background_color = '#7bc7ff' ground = Node(parent=self) x = 0 while x <= self.size.w + 64: tile = SpriteNode('plf:Ground_Grass', position=(x, 0)) ground.add_child(tile) x += 64 self.player = SpriteNode(standing_texture) self.player.anchor_point = (0.5, 0) self.player.position = (self.size.w/2, 20) self.add_child(self.player) self.right_button = ShapeNode(ui.Path.rounded_rect(0, 0, 100, 50, 20), position=(250, 100), fill_color='black', parent=self) self.left_button = ShapeNode(ui.Path.rounded_rect(0, 0, 100, 50, 20), position=(100, 100), fill_color='black', parent=self) self.walk_step = -1 player.play() def touch_began(self, touch): right_move = Action.move_by(self.size/1, 0, 2, TIMING_SINODIAL) left_move = Action.move_by(self.size/-1, 0, 2, TIMING_SINODIAL) if touch.location in self.right_button.frame: self.player.run_action(right_move, 'move_action_key') Action.repeat(right_move, 0) self.player.x_scale = 1 moving += 1 elif touch.location in self.left_button.frame: self.player.run_action(left_move, 'move_action_key') Action.repeat(left_move, 0) self.player.x_scale = -1 def touch_ended(self, touch): if touch.location in self.right_button.frame: self.player.remove_action('move_action_key') elif touch.location in self.left_button.frame: self.player.remove_action('move_action_key') def stop(self): player.stop() def update(self): #if moving: -------------------------------what to do here? x = self.player.position.x x = max(0, min(self.size.w, x)) self.player.position = (x, 20) step = int(self.player.position.x / 20) % 10 if step != self.walk_step: self.player.texture = walk_textures[step] sound.play_effect('rpg:Footstep00', 0.05, 1.0 + 0.5 * step) self.walk_step = step else: self.player.texture = standing_texture self.walk_step = -1 run(MyScene())
While trying to figure this out for myself, I read a few threads in this forum that touched on this topic. I figured I would share this to help out other newbies like myself who are just starting to learn the basics of python. I made very slight adjustments to the code from the following link:
The aim for this person was to make the white background transparent and make the black lettering sharper.
My goal was to take any color background and make it transparent so it could be used for a spritesheet for games. This is what I ended up with:
from PIL import Image img = Image.open('image.png') img = img.convert("RGBA") # RGBA means Red, Green, Blue, Alpha. Alpha is the transparency of the image. datas = img.getdata() rgb = datas #get the color of the first pixel of the image, in RGB format newData =  for item in datas: if item == rgb and item == rgb and item == rgb: #check if the pixel matches the first pixel's color newData.append((0, 0, 0, 0)) #set the pixel to black and make it transparent. the first three numbers are the RGB levels and the fourth is the alpha else: newData.append(item) img.putdata(newData) img.save("image_transparent.png", "PNG")
Basically it sets the first pixel in the very top left as the background color and then goes through every pixel of the image and if the color of the pixel is the same as the first pixel, it makes it transparent. If the first pixel of the image is not the background color, you can set the number in datas to whichever pixel you want to establish as the background color.
I take no credit for writing any of this code since I just made very very minor adjustments to someone else's code, and just added a few comments. I am just sharing this because I appreciate it when I get help from others:)
This one is interesting:
It isn't an emulator per se, but it finds the images in the rom so you can create custom visuals.
What comes to mind right away is something like Game Maker Studio by YoYo Games. It would be a long (and not so cheap) process of writing something in Pythonista, converting your script for use in something else like Xcode for iOS, then using a cross platform program for exporting to different platforms. With my limited knowledge, it would definitely be easier to start on Windows or MacOS, then export your finished app to iOS and Android.
So I've been looking into how video game emulators work the past few days. Crazy stuff.
I learned that there have been several nintendo emulators written in python, and while most of them use pygame (which I know you can't use with Pythonista), I was wondering if making an NES emulator would be possible in Pythonista? I figured if it can be done with pygame then it isn't completely insane to think it could be done in Pythonista right? Since emulators are not available in the apple store, this would be an awesome way around that.
Of course, i'm just starting to develop my knowledge in python so writing an emulator would probably be a couple decades away for me. However, since emulators have already been written in python would someone be able to adapt it? I would love to hear if this is possible and if anyone else is interested in it.
I asked a similar question a few days ago. If you are using scene, I quote pulbrich in his response:
- pulbrich posted 4 days ago
In the Game class you can include a
method. It gets called automatically when a scene is stopped (by tapping the “x” button).
If this is a script that is running in the console, I imagine it would require a different approach. I'll leave that to the experienced guys:)