I've been doing quite a bit lately with games an pygame. I thought I'd take a break and do something useful. Actually, I found some online drawing that I wanted to win, and they allowed you to submit an entry every day over the course of a month. Obviously I didn't want to log in every day, and even if I did have that level of enthusiasm, my memory would fail at some point and I'd miss a few days here or there.
So the only real solution was to script something and set up a cron job to do it for me every morning. Now, I've never done a script to crawl web pages or anything, so I did a bit of digging and found there are actually quite a few options open for python. Since I was more concerned with just getting something together quickly, I went for what looked to be the easiest option: Mechanize.
Mechanize is a library that can search a URL for existing forms and then allows you to edit form contents and follow links or submit forms. Perfect for what I wanted.
Here's an example script:
#! /usr/bin/env python
import os
from mechanize import Browser
fname="submitResults.txt"
f = open(fname, 'w')
br = Browser()
br.set_proxies({"http":"5.5.5.5:3128"})
br.open("http://www.site.com/giveaway/")
br.select_form(nr=1)
br['fvFirst']='firstName'
br['fvLast']='lastName'
f.write('submitted to site\n')
br.submit()
br.close()
f.close()
Nothing special here. I found out the form and field names ahead of time, by loading up the python interpreter and creating the browser object. Then I used Browser.forms to list the available forms. Then I hard coded the form names into the script. If you really wanted to automate it better, you could set up a function or two to handle that step for you. Have it parse for the fields and look for keywords to make sure you fill in the right values.
If you noticed, I have it write a little message to a text file. That was more for me to validate that cron was running every day. If I checked the text file modification date, it would reflect the last time the script ran successfully. If I had thought about it, I would've added some exceptions that would write errors to the log as well.
In any case, this worked out great. I set up the script with it's own directory and set up a cron job to run every morning around 1am. Still waiting on the results for the giveaway, but at least I know I've entered every day possible. And I learned how to use the mechanize library for web scraping and automated form submissions.
-Newt
Showing posts with label Python. Show all posts
Showing posts with label Python. Show all posts
Tuesday, June 11, 2013
Monday, June 10, 2013
Map Generation - Ready, Fight!
Okay, I've started work on the map generation code. I had some time to think it over and talk through the logic a bit more, and I made some changes to the way it's going to work. Here's the code I have so far:
import random, pygame
class RoomObj:
def update(self,anchorpoint):
self.rect.left = self.xoffset + anchorpoint[0]
self.rect.top = self.yoffset + anchorpoint[1]
class Room(RoomObj):
def __init__(self, x,y, imageset):
#RoomObj.__init__(self)
self.direction = random.randint(1,4) #up, down, left, right
self.size = (random.randint(400,600),random.randint(500,700))
self.image = pygame.Surface(self.size)
pygame.transform.scale(random.choice(imageset), self.size, self.image)
self.rect = self.image.get_rect()
self.rect.topleft = [x,y]
self.xoffset = x
self.yoffset = y
class Hall(RoomObj):
def __init__(self, direction, room_rect):
#RoomObj.__init__(self)
if direction==1:
self.size = (80,random.randint(100,300))
self.rect.bottom = room_rect.top
self.rect.left = random.randint(room_rect.left, room_rect.right-80)
def genMap(size,roomimages,hallimages):
if size=='small':
numofrooms = random.randint(3,5)
if size=='medium':
numofrooms = random.randint(5,8)
rooms = []
map = []
startpoint = [0,0]
for i in range(numofrooms):
if i < len(numberofrooms)-1:
tmproom = Room(startpoint, roomimages)
#up
if tmproom.direction == 1:
map.append(tmproom)
map.append(Hall(tmproom.direction, tmproom.rect))
return map
Basically I have a parent class called RoomObj that has the update functions. You may be wondering why a stationary object needs an update function, but for this large of a map, i'm going to have it scroll as the player moves. If you're interested in how I've done the scrolling, check out this article. I'm applying forces to the player object, which move the player sprite around. When the player moves to the edges of an invisible radius around the center of the screen, these forces are transferred to other objects making them scroll. I do this by giving each object an anchor point as an argument. This anchor point is simply a coordinate that I transfer the forces to when the player is moving outside of their center radius. I'm sure I could explain that better, but like I said, if you really care, just check out the blog post. I have the source code up that should explain it better than I could.
Then I have two other classes that inherit from the RoomObj. I created a Room object and a Hall object. I still need to flesh them out a bit more in order to accurately place everything and check for collisions and some other general stuff. I guess I could've created a single class with overloaded init functions, but I've never really been a fan of overloaded classes. They just get kind of confusing after a while. Using inheritance, I can expand the base class or add other children classes fairly easily.
The genMap function is where I made the real changes to how everything is created. If you check out my last blog post, I was going to have it create all the rooms, then loop through the objects to place connecting hall objects. After a great deal of thought, I changed it to create a room, then create a hall, then create a room, and so on. I believe this will allow for much more complex maps. In the future I'd like to add a bit to allow for multiple Hallways to branch off, but for now, I just want to get this working.
Like I said, it's still a work in progress. I know I need to rework the room and hall objects a bit, and I still need to figure out how I want to handle the placement for them. As of right now, I'm thinking I'll use the room object to choose a random direction and then have the hallway get it's x/y coordinates from that. I'm thinking that I'll also need to add wall rectangles to each room object for player collisions later on.
I'm also thinking that the images for the floors will have to be different from those used for the walls. If I'm creating wall objects for each room, those will be scaled to fit the pseudo-random size. I'd like to get some sort of tile for the floors though. I think it'll just look nicer if the floors are all uniform for each map. In any case, I think this should do the trick if I ever finish up the Room and Hall classes. I just don't have time lately to really work on anything. I can dream though...
-Newt
import random, pygame
class RoomObj:
def update(self,anchorpoint):
self.rect.left = self.xoffset + anchorpoint[0]
self.rect.top = self.yoffset + anchorpoint[1]
class Room(RoomObj):
def __init__(self, x,y, imageset):
#RoomObj.__init__(self)
self.direction = random.randint(1,4) #up, down, left, right
self.size = (random.randint(400,600),random.randint(500,700))
self.image = pygame.Surface(self.size)
pygame.transform.scale(random.choice(imageset), self.size, self.image)
self.rect = self.image.get_rect()
self.rect.topleft = [x,y]
self.xoffset = x
self.yoffset = y
class Hall(RoomObj):
def __init__(self, direction, room_rect):
#RoomObj.__init__(self)
if direction==1:
self.size = (80,random.randint(100,300))
self.rect.bottom = room_rect.top
self.rect.left = random.randint(room_rect.left, room_rect.right-80)
def genMap(size,roomimages,hallimages):
if size=='small':
numofrooms = random.randint(3,5)
if size=='medium':
numofrooms = random.randint(5,8)
rooms = []
map = []
startpoint = [0,0]
for i in range(numofrooms):
if i < len(numberofrooms)-1:
tmproom = Room(startpoint, roomimages)
#up
if tmproom.direction == 1:
map.append(tmproom)
map.append(Hall(tmproom.direction, tmproom.rect))
return map
Basically I have a parent class called RoomObj that has the update functions. You may be wondering why a stationary object needs an update function, but for this large of a map, i'm going to have it scroll as the player moves. If you're interested in how I've done the scrolling, check out this article. I'm applying forces to the player object, which move the player sprite around. When the player moves to the edges of an invisible radius around the center of the screen, these forces are transferred to other objects making them scroll. I do this by giving each object an anchor point as an argument. This anchor point is simply a coordinate that I transfer the forces to when the player is moving outside of their center radius. I'm sure I could explain that better, but like I said, if you really care, just check out the blog post. I have the source code up that should explain it better than I could.
Then I have two other classes that inherit from the RoomObj. I created a Room object and a Hall object. I still need to flesh them out a bit more in order to accurately place everything and check for collisions and some other general stuff. I guess I could've created a single class with overloaded init functions, but I've never really been a fan of overloaded classes. They just get kind of confusing after a while. Using inheritance, I can expand the base class or add other children classes fairly easily.
The genMap function is where I made the real changes to how everything is created. If you check out my last blog post, I was going to have it create all the rooms, then loop through the objects to place connecting hall objects. After a great deal of thought, I changed it to create a room, then create a hall, then create a room, and so on. I believe this will allow for much more complex maps. In the future I'd like to add a bit to allow for multiple Hallways to branch off, but for now, I just want to get this working.
Like I said, it's still a work in progress. I know I need to rework the room and hall objects a bit, and I still need to figure out how I want to handle the placement for them. As of right now, I'm thinking I'll use the room object to choose a random direction and then have the hallway get it's x/y coordinates from that. I'm thinking that I'll also need to add wall rectangles to each room object for player collisions later on.
I'm also thinking that the images for the floors will have to be different from those used for the walls. If I'm creating wall objects for each room, those will be scaled to fit the pseudo-random size. I'd like to get some sort of tile for the floors though. I think it'll just look nicer if the floors are all uniform for each map. In any case, I think this should do the trick if I ever finish up the Room and Hall classes. I just don't have time lately to really work on anything. I can dream though...
-Newt
Wednesday, June 5, 2013
Map Gen Pseudo Code
I know there are a ton of map generators out there already, but I was considering trying my hand at it as well. More as a learning experience though, and not as an attempt to improve on them in any way. Lord knows I'm not that good.
But I was thinking about it and I think I may be able to pull it off. I threw together some pseudo code to help me out with the logistics, and I wanted to see if anyone had any improvements or maybe some comments.
Here's what I've got so far:
class RoomObj:
init(type): #types can be hallways or rooms
attributes, size, type, image etc.
randomize image based on type given
update:
pass
class Room(RoomObj):
create room type=Room
class Hall(RoomObj):
create hall type=Hall
def genMap():
numofrooms = random number of rooms from range
listofrooms = []
listofmapobj = []
for i in range(numofrooms):
listofrooms.append(Room())
for i in range(len(listofrooms)):
create room objects with a "hallway" type
if i is not the last iterate:
listofmapobj.append(Hall(listofrooms[i], listofrooms[i+1]))
listofmapobj.append(listofrooms[i])
return listofmapobj
I still need to figure out exactly what parameters the room and hallway classes need to be given, but the rooms will initially just create random sized rectangular rooms, then choose a random image from a pre-loaded set. The room placement would have to check to ensure there are no collisions with other room rectangles. And finally the hallway objects would base their size and shape on the locations of the two rooms given as a parameter.
There are a lot of other particulars I still need to figure out, but I think it is doable. and it should be an interesting project to work on.
I'll have to post whatever I end up with at the end of this little adventure.
-newt
But I was thinking about it and I think I may be able to pull it off. I threw together some pseudo code to help me out with the logistics, and I wanted to see if anyone had any improvements or maybe some comments.
Here's what I've got so far:
class RoomObj:
init(type): #types can be hallways or rooms
attributes, size, type, image etc.
randomize image based on type given
update:
pass
class Room(RoomObj):
create room type=Room
class Hall(RoomObj):
create hall type=Hall
def genMap():
numofrooms = random number of rooms from range
listofrooms = []
listofmapobj = []
for i in range(numofrooms):
listofrooms.append(Room())
for i in range(len(listofrooms)):
create room objects with a "hallway" type
if i is not the last iterate:
listofmapobj.append(Hall(listofrooms[i], listofrooms[i+1]))
listofmapobj.append(listofrooms[i])
return listofmapobj
I still need to figure out exactly what parameters the room and hallway classes need to be given, but the rooms will initially just create random sized rectangular rooms, then choose a random image from a pre-loaded set. The room placement would have to check to ensure there are no collisions with other room rectangles. And finally the hallway objects would base their size and shape on the locations of the two rooms given as a parameter.
There are a lot of other particulars I still need to figure out, but I think it is doable. and it should be an interesting project to work on.
I'll have to post whatever I end up with at the end of this little adventure.
-newt
Labels:
Code,
Map Gen,
Pseudo,
Pseudo Code,
Python,
Random,
rectangles,
Script
Thursday, May 16, 2013
Pygame Subset for Android - Soft Keyboard
The guys over at pygame.renpy.org have out-done themsleves with their work on the pygame subset for android development. It can be a bit tricky at first if you're not familiar with ant builds or android development, but for the most part they've made it pretty simple to pick up. If I can figure it out, anyone can do it. So first let me just say thanks to all who have worked on the project.
That being said, there are a number of things I wish worked better. Since the pygame mixer wasn't included, the subset allows you to take advantage of the android mixer. Unfortunately the android mixer isn't quite as full-featured in it's implementation here. The soft-touch keyboard is in the same boat. You can import the android subset, and even have the app call the keyboard, but to my knowledge (and this may be completely wrong) you can't actually watch for these key events. I've tried a multitude of methods and searched for hours on how to correctly do this with the pygame subset for android. I've found absolutely nothing that can show me how to correctly implement this.
So what I ended up doing was writing my own soft-keyboard function. I've tested it and it works great with android apps & games.
Here's basically how it works:
Then you can do something like this to implement it:
So right before the game loop, you create the keyboard. The makeKeyBoard function just needs a starting position and it will create each key and give it it's own rectangle, image and coordinate.
Inside the main loop, under the event listener, you have it watch for mousebuttondown events. When the app is run on android, this equates to a screen press. It uses the event position to determine if there was a collision with a keyboard rectangle. You can map these collisions to any functions you want. You'll notice my keyboard only has letters and the enter key, but you could set up a full keyboard in much the same way.
This likely isn't the best way to implement a soft-keyboard, but it works which is more than I can say for the android soft-touch keyboard using the pygame subset. If anyone else has a better way to do this, or they managed to figure out how to implement the android soft-touch keyboard, I'd love to hear from you. Especially if you figured out the android soft-touch. I'd love to see how you get the events into python.
-Newt
That being said, there are a number of things I wish worked better. Since the pygame mixer wasn't included, the subset allows you to take advantage of the android mixer. Unfortunately the android mixer isn't quite as full-featured in it's implementation here. The soft-touch keyboard is in the same boat. You can import the android subset, and even have the app call the keyboard, but to my knowledge (and this may be completely wrong) you can't actually watch for these key events. I've tried a multitude of methods and searched for hours on how to correctly do this with the pygame subset for android. I've found absolutely nothing that can show me how to correctly implement this.
So what I ended up doing was writing my own soft-keyboard function. I've tested it and it works great with android apps & games.
Here's basically how it works:
def makeKey(x, y, letter):
global keyArray
temp = pygame.image.load('key.png')
if letter == 'enter':
temp = pygame.image.load('longkey.png')
limage = pygame.transform.scale2x(temp)
lrect = limage.get_rect()
lrect.topleft = [x,y]
keyArray.append((limage,lrect,letter))
#map out whole keyboard using makeKey()
def makeKeyboard(x,y):
letters = ['q','w','e','r','t','y','u','i','o','p','a','s','d','f','g','h','j','k','l','z','x','c','v','b','n','m','enter']
x_move = 0
y_move = 0
for i in letters:
if i == 'a':
y_move = 40
x_move = 0
if i == 'z':
y_move = 80
x_move = 0
makeKey(x+x_move, y+y_move, i)
x_move+=40
#draw keyboard and write in letters
def drawKeyboard(color,font,surface):
global keyArray
for i in keyArray:
surface.blit(i[0],i[1])
drawText(i[2],color,font,surface,i[1].center[0],i[1].center[1],True)
#used for drawing text onto the key surface
def drawText(text, color, font, surface, x, y, center):
textobj = font.render(text, 1, color)
textrect = textobj.get_rect()
textrect.topleft = (x, y)
if center:
textrect.center = (x, y)
surface.blit(textobj, textrect)Then you can do something like this to implement it:
def main():
#keyboard start coord
startKey_x = screen.get_size()[0]/2
startKey_y = screen.get_size()[1]/2
#create images and rects for keyboard
makeKeyboard(startKey_x,startKey_y)
#temp string for testing
clickedLetters = ""
clock = pygame.time.Clock()
while 1:
clock.tick(60)
global MOUSEDOWN
global keyArray
for event in pygame.event.get():
if android:
if android.check_pause():
android.wait_for_resume()
if event.type == pygame.QUIT:
terminate()
if event.type==pygame.MOUSEBUTTONDOWN:
MOUSEDOWN=True
for i in keyArray:
if i[1].collidepoint(event.pos):
if i[2] == 'enter':
pass
else:
clickedLetters+=i[2]
if event.type==pygame.MOUSEBUTTONUP:
MOUSEDOWN=False
drawKeyboard(black,font,screen)
drawText(clickedLetters, black, font, screen, (800/2), (480/4), True)
pygame.display.flip()![]() |
| here's an example implementation |
So right before the game loop, you create the keyboard. The makeKeyBoard function just needs a starting position and it will create each key and give it it's own rectangle, image and coordinate.
Inside the main loop, under the event listener, you have it watch for mousebuttondown events. When the app is run on android, this equates to a screen press. It uses the event position to determine if there was a collision with a keyboard rectangle. You can map these collisions to any functions you want. You'll notice my keyboard only has letters and the enter key, but you could set up a full keyboard in much the same way.
This likely isn't the best way to implement a soft-keyboard, but it works which is more than I can say for the android soft-touch keyboard using the pygame subset. If anyone else has a better way to do this, or they managed to figure out how to implement the android soft-touch keyboard, I'd love to hear from you. Especially if you figured out the android soft-touch. I'd love to see how you get the events into python.
-Newt
Labels:
Android,
Code,
Pygame,
Pygame Subset,
Python,
Python to Android,
rectangles
Tuesday, May 14, 2013
Moar Pygame Sprite Movement
There are a number of ways to have python move game objects around the screen. Up until recently I hadn't really tried much other than tying keys to a function that would move a rectangle object by an offset.
Something like this:
*** in the sprite class***
def change_pos(self, x, y):
self.change_x += x
self.change_y += y
*** in the main loop ***
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_UP:
player.change_pos(0, -PS)
I'd set up a global for player speed (PS) that I could hand to the change_pos function as a positive or negative value based on the direction the player wanted to go.
This way works fine, but it's not really all that flexible. What if you wanted to have the player sprite keep moving a bit after the player releases the movement keys? For that you'd need to use a bit of physics. There are a ton of different ways to do something like this, and I've read through some tutorials on it. Since I'm not very good with math though, most of it was way over my head. I came up with a very simplistic approach to the whole thing.
I created a sprite object with an attribute to store a list of forces that will act as inertia to be applied to the object. Then I took out the change_pos() function and replaced it with this:
def apply_force():
for i in self.forces:
i -= friction
if self.up:
self.forces[0] += speed
if self.down:
self.forces[1] +=speed
if self.left:
self.forces[2] +=speed
if self.right:
self.forces[3] +=speed
In the player sprite's update function, I can say:
def update():
self.apply_force()
self.rect.top += (self.forces[1] - self.forces[0])
self.rect.left += (self.forces[3] - self.forces[2])
You can play around with the values that you use for speed, and friction. Speed is how fast your player object gains speed and friction is how fast the object is slowed. You may want to add something to the end of your apply_force() function to cap the forces. I used something like this:
for i in self.forces:
if i > 200:
i=200
if i < 0:
i=0
Also, if you want, you can have your main loop use actual time to update instead of FPS which can be affected by the power of the system you're running on. Up until recently I had been using the following in my main loop:
clock = pygame.time.Clock()
while 1:
clock.tick(60)
It actually makes more sense to use the following:
FPS = 60
clock = pygame.time.Clock()
while 1:
milliseconds = clock.tick(FPS)
seconds = milliseconds / 1000.0
Then change the player class update function to take seconds as an argument. This will give you a much more consistent movement:
self.rect.top += (self.forces[1] - self.forces[0]) * seconds
self.rect.left += (self.forces[3] - self.forces[2]) * seconds
There are of course, more accurate ways to produce the same effect, but I found this pretty simple to understand and easy to implement.
-Newt
Something like this:
*** in the sprite class***
def change_pos(self, x, y):
self.change_x += x
self.change_y += y
*** in the main loop ***
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_UP:
player.change_pos(0, -PS)
I'd set up a global for player speed (PS) that I could hand to the change_pos function as a positive or negative value based on the direction the player wanted to go.
This way works fine, but it's not really all that flexible. What if you wanted to have the player sprite keep moving a bit after the player releases the movement keys? For that you'd need to use a bit of physics. There are a ton of different ways to do something like this, and I've read through some tutorials on it. Since I'm not very good with math though, most of it was way over my head. I came up with a very simplistic approach to the whole thing.
I created a sprite object with an attribute to store a list of forces that will act as inertia to be applied to the object. Then I took out the change_pos() function and replaced it with this:
def apply_force():
for i in self.forces:
i -= friction
if self.up:
self.forces[0] += speed
if self.down:
self.forces[1] +=speed
if self.left:
self.forces[2] +=speed
if self.right:
self.forces[3] +=speed
In the player sprite's update function, I can say:
def update():
self.apply_force()
self.rect.top += (self.forces[1] - self.forces[0])
self.rect.left += (self.forces[3] - self.forces[2])
You can play around with the values that you use for speed, and friction. Speed is how fast your player object gains speed and friction is how fast the object is slowed. You may want to add something to the end of your apply_force() function to cap the forces. I used something like this:
for i in self.forces:
if i > 200:
i=200
if i < 0:
i=0
Also, if you want, you can have your main loop use actual time to update instead of FPS which can be affected by the power of the system you're running on. Up until recently I had been using the following in my main loop:
clock = pygame.time.Clock()
while 1:
clock.tick(60)
It actually makes more sense to use the following:
FPS = 60
clock = pygame.time.Clock()
while 1:
milliseconds = clock.tick(FPS)
seconds = milliseconds / 1000.0
Then change the player class update function to take seconds as an argument. This will give you a much more consistent movement:
self.rect.top += (self.forces[1] - self.forces[0]) * seconds
self.rect.left += (self.forces[3] - self.forces[2]) * seconds
There are of course, more accurate ways to produce the same effect, but I found this pretty simple to understand and easy to implement.
-Newt
Tuesday, May 7, 2013
ArcSight Export Parser Script
For those of you not familiar with it, ArcSight is a pretty robust correlation engine. I've been working with it for quite a while now, and I've never really been happy with the case management system they have. When an alert is triggered, it pulls in some information and saves it to a Case. Unfortunately the management of these cases are kind of messy and can easily become unwieldy for large environments. If you have HP Openview, you can have ArcSight export the cases directly to your ticketing system. But what if you use another ticketing system or a custom built ticketing system? Well, then you can export the files to the system and write your own API to parse the export files and send to the ticketing system of your choice.
That's what I've been working on the last few weeks. With an ArcSight ESM appliance, I'm limited to using bash, perl (limited libraries), or python 2.4. Since I'm more familiar with python, I went that route. Although, you could easily write a parser in perl. In fact, ArcSight has an approved perl script that parses these exports and formats them to a customized email, so you can route events that way. Still python was what I went with.
It's still a work in progress, but here's the basic functions:
Essentially I will parse the xml file for a correlation event, then parse the event for specific fields that I will store in the arcsight object. I'm thinking I'll use these fields later to fill in json files that I can post to the webserver. But for now I just store them and then grab the base event ID's associated with each event.
You may have noticed the deviceCustomString6 message I apply to the default alertName variable. That is something I have ArcSight set before it exports the rule-fire. I use that field to store the rulename + time + attacker address and a number of other useful things. The reason was that our ticketing system only lets us query on that alertName field. This way we can search for any of those fields (i.e. all rules triggered by a particular host).
Then I take those ID's, create a list of base events, using my grabBaseEvents function. Then I run that through my createHtml function which will create a table with the base events. This HTML file will probably be zipped up and posted to the web server as well.
Here's what the main loop looks like so far. The addNSend function will be what ultimately adds the fields to the json file and POSTs it to the server.
All in all, it works pretty well. I still need to make some formatting changes and add some logic to parse deeper into the xml for some relevant fields, but that's not difficult. Just time consuming. For now it's fine with the handful of fields that it parses for. I guess I could also have it pretty up the html file a bit. As it is, the headers are still smashed together field names like sourceAddress, and what-not.
Maybe when I have it complete, I can post it to ArcSight 724. No telling how many other people are in need of an API for a non-supported ticketing system. With a little modification, I bet this script would work for quite a few other systems.
-Newt
That's what I've been working on the last few weeks. With an ArcSight ESM appliance, I'm limited to using bash, perl (limited libraries), or python 2.4. Since I'm more familiar with python, I went that route. Although, you could easily write a parser in perl. In fact, ArcSight has an approved perl script that parses these exports and formats them to a customized email, so you can route events that way. Still python was what I went with.
It's still a work in progress, but here's the basic functions:
# simple function to consolidate headers from base events
def getHeaders(allevents):
x = []
for i in range(len(allevents)):
for thing in allevents[i]:
if x.count(thing[0]) == 0:
x.insert(i,thing[0])
x.reverse()
return x
# creates an HTML table for use in our web-based ticketing system
def createHtml(baseEventList):
if os.path.exists('tmp_alert/'):
removeDir('tmp_alert/')
fname="tmp_alert/tmp.html"
d = os.path.dirname(fname)
if not os.path.exists(d):
os.makedirs(d)
f = open(fname, 'w')
f.write('<!DOCTYPE html>\n')
f.write('<html>\n')
f.write('<body>\n')
f.write('<p>Base Security Events</p>\n')
#grab the list of headers
x = getHeaders(baseEventList)
f.write('<br>\n') #the baseTable class is a css file on the server #change if you have your own custom style sheet
f.write('<table class=baseTable>\n')
f.write('<tr>\n')
#grab and write headers
for i in x:
f.write('<th> %s </th>\n' % i)
f.write('</tr>\n')
#loop over all events
for event in baseEventList:
f.write('<tr>\n')
offset = 0
#loop again to create matching value fields in our table
for item in range(len(event)):
itemwritten = False
for header in x:
if itemwritten:
pass
else:
if header == event[item][0]:
f.write('<td> %s</td>\n' % event[item][1])
itemwritten = True
f.write('</tr>\n')
f.write('</table>')
f.close()# function to grab all base events using a list of ID numbers
def grabBaseEvents(xmlcontents, baseEventIDList, arcObj):
#takes the dom document object for a single xml and baseEvent ID list
baseEvent = []
allEvents = []
#for each sec event
for node in xmlcontents.getElementsByTagName('SecurityEvent'):
attr_list = node.attributes
#iterate over sec event attributs
for attr in range(attr_list.length):
if attr_list.item(attr).name == 'id':
#look at all the event IDs
for baseevent in baseEventIDList:
#when we have a match, iterate over the current
#sec event child nodes and append them to a base event list
baseEvent = []
if baseevent == attr_list.item(attr).value:
for x in node.childNodes:
if x.hasChildNodes():
if x.nodeName == 'destinationProcessName':
arcObj.setAttr('TPN',x.firstChild.nodeValue)
baseEvent.append((x.nodeName,x.firstChild.nodeValue))
#when we're done with the base event, append that to an
#element in the allEvents list
if len(baseEvent) != 0:
allEvents.append(baseEvent)
return allEvents# Object to store and retrieve RuleFire Event values
class arcObject:
def __init__(self):
self.AlertName = "deviceCustomString6 not filled in"
self.AA = "None"
self.AH = "None"
self.AU = "None"
self.TA = "None"
self.TH = "None"
self.TU = "None"
self.rulename = "None"
self.time = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
self.filename = "None"
self.targetproc = "None"
def getAttr(self, attr):
if attr == 'AA':
return self.AA
elif attr == 'AN':
return self.AlertName
elif attr == 'AH':
return self.AH
elif attr == 'AU':
return self.AU
elif attr == 'TA':
return self.TA
elif attr == 'TH':
return self.TH
elif attr == 'TU':
return self.TU
elif attr == 'rulename':
return self.rulename
elif attr == 'time':
return self.time
elif attr == 'FN':
return self.filename
elif attr == 'TPN':
return self.targetproc
else:
pass
def setAttr(self, attr, value):
if attr == 'AA':
self.AA = value
elif attr == 'AN':
self.AlertName = value
elif attr == 'AH':
self.AH = value
elif attr == 'AU':
self.AU = value
elif attr == 'TA':
self.TA = value
elif attr == 'TH':
self.TH = value
elif attr == 'TU':
self.TU = value
elif attr == 'rulename':
self.rulename = value
elif attr == 'time':
self.time = value
elif attr == 'FN':
self.filename = value
elif attr == 'TPN':
self.targetproc = value
else:
pass
Essentially I will parse the xml file for a correlation event, then parse the event for specific fields that I will store in the arcsight object. I'm thinking I'll use these fields later to fill in json files that I can post to the webserver. But for now I just store them and then grab the base event ID's associated with each event.
You may have noticed the deviceCustomString6 message I apply to the default alertName variable. That is something I have ArcSight set before it exports the rule-fire. I use that field to store the rulename + time + attacker address and a number of other useful things. The reason was that our ticketing system only lets us query on that alertName field. This way we can search for any of those fields (i.e. all rules triggered by a particular host).
Then I take those ID's, create a list of base events, using my grabBaseEvents function. Then I run that through my createHtml function which will create a table with the base events. This HTML file will probably be zipped up and posted to the web server as well.
Here's what the main loop looks like so far. The addNSend function will be what ultimately adds the fields to the json file and POSTs it to the server.
dir = glob.glob('*.xml')
for xmlfile in dir:
contents = parse(xmlfile)
#print "parsing " +xmlfile
#for each Security Event
for i in contents.getElementsByTagName('SecurityEvent'):
x = i.attributes
#if external ID attribute exists, it's a rule fire
if x.item(1).name != 'externalID':
arcObj = arcObject()
arcObj.setAttr('rulename', x.item(2).value)
baseEventIDs = []
#map rule fire values to alert web fields
for node in i.childNodes:
if node.hasChildNodes():
if node.nodeName == 'fileName':
if node.firstChild.nodeValue != x.item(1).value:
arcObj.setAttr('FN', node.firstChild.nodeValue)
elif node.nodeName == 'deviceCustomString6':
arcObj.setAttr('AN',node.firstChild.nodeValue)
elif node.nodeName == 'sourceAddress':
arcObj.setAttr('AA', node.firstChild.nodeValue)
elif node.nodeName == 'sourceHostName':
arcObj.setAttr('AH', node.firstChild.nodeValue)
elif node.nodeName == 'sourceUserName':
arcObj.setAttr('AU', node.firstChild.nodeValue)
elif node.nodeName == 'destinationAddress':
arcObj.setAttr('TA', node.firstChild.nodeValue)
elif node.nodeName == 'destinationHostName':
arcObj.setAttr('TH', node.firstChild.nodeValue)
elif node.nodeName == 'destinationUserName':
arcObj.setAttr('TU', node.firstChild.nodeValue)
elif node.nodeName == 'destinationProcessName':
arcObj.setAttr('TPN', node.firstChild.nodeValue)
elif node.nodeName == 'managerReceiptTime':
arcObj.setAttr('time', node.firstChild.nodeValue.rstrip('.0'))
#check for baseEventIDs
elif node.nodeName == 'baseEventIds':
for ref in node.getElementsByTagName('ref'):
attr_list_obj = ref.attributes
for attr in range(attr_list_obj.length):
if attr_list_obj.item(attr).name == 'id':
baseEventIDs.append(attr_list_obj.item(attr).value)
#find base events and create html to store
#grabBaseEvents should return a list of key/value pairs for #each event
listOfBaseEvents = grabBaseEvents(contents, baseEventIDs, arcObj)
#createHtml creates the tmp_alert directory and the html
createHtml(listOfBaseEvents)
else:
pass
#addNsend(arcObj)
addFileToFolder(xmlfile,'/var/tmp/processed')
os.remove(xmlfile)All in all, it works pretty well. I still need to make some formatting changes and add some logic to parse deeper into the xml for some relevant fields, but that's not difficult. Just time consuming. For now it's fine with the handful of fields that it parses for. I guess I could also have it pretty up the html file a bit. As it is, the headers are still smashed together field names like sourceAddress, and what-not.
Maybe when I have it complete, I can post it to ArcSight 724. No telling how many other people are in need of an API for a non-supported ticketing system. With a little modification, I bet this script would work for quite a few other systems.
-Newt
Monday, April 29, 2013
Ludum Dare - Post-mortum
Well, that was quite an experience. Ludum Dare 26 has come and gone and I have very little to show for it. Due to a lack of planning on my part and some issues with conflicting responsibilities eating up my time, I didn't end up with anything to submit at the end of this game jam. Not to say I didn't get anything from the competition though. I did get my feet wet, so to speak, and in doing so I think I came away with a number of ways I can improve upon my time management next round.
For instance, I discovered that I was spending a good amount of time coding things I could have easily gotten from existing libraries. The problem was, that I wasn't familiar with these libraries ahead of time, so I instead spent too much time coding it from scratch. Something as simple as a particle effect library or physics library could have helped me out immensely. I intend to spend the next few months getting myself acquainted with these libraries and finding out what I can do to avoid spending precious time trying to rewrite these things.
Another lesson learned was that next time I shouldn't try to do this from home. Family life, and other responsibilities can easily demand attention that will prevent a game from being finished. I ended up doing the majority of my coding in the morning (when the family was still sleeping) and in the evening (after everyone had retired). The whole 10-12 hours in between were just a cluster f*ck where I rarely accomplished anything of value.
I did manage to get a few interesting classes and functions out of this whole experience as well. The theme for the game was that it should be minimalistic in some way. I wanted to apply this to the artistic direction, so many of the objects drawn to the screen were basic shapes. I made them hallow, so that I could easily fill in the objects with whatever color I wanted. It was my intention to create several arrays with different color schemes that could be interchanged for each level. I had that working the first morning.
Next thing I wanted was some sort of map generation. I had a friend willing to work on this for me. He had already worked on something similar for one of his previous classes, and he figured he could easily rewrite it for me.
Another thing I was working on, (didnt get finished with it, but I have some promising code so far) was player movement that moved the screen around with it. I'd never done anything like that with a previous game so it was something new. I really should have attempted something like it prior to this game jam, since I spent a lot of time on this. I was also trying to incorporate a parallex effect using layered images moving at different speeds to give the game some depth. This was also somewhat new to me as I had read about it but not actually attempted it myself. Like I said, I have some promising code, but nothing completely working.
I also managed to get a pretty neat looking background for the game. I created a class that you can pass a surface (to draw to), a color scheme object, and the number of objects to be created: and the class would create a background object with small moving particles. It was a pretty neat effect, and as soon as I have some time, I'll post the code along with a little video clip or gif.
So I ended up with some pretty neat stuff and a neat idea for a game, but unfortunately it just didn't get to the "playable" phase. I might continue working on it, but I'm not sure when I'll have the time. At least I came away with a few lessons and even some neat code that I can implement elsewhere. All in all, it was a good time and I can't wait for the next Ludum Dare to come around.
Cheers,
-Newt
For instance, I discovered that I was spending a good amount of time coding things I could have easily gotten from existing libraries. The problem was, that I wasn't familiar with these libraries ahead of time, so I instead spent too much time coding it from scratch. Something as simple as a particle effect library or physics library could have helped me out immensely. I intend to spend the next few months getting myself acquainted with these libraries and finding out what I can do to avoid spending precious time trying to rewrite these things.
Another lesson learned was that next time I shouldn't try to do this from home. Family life, and other responsibilities can easily demand attention that will prevent a game from being finished. I ended up doing the majority of my coding in the morning (when the family was still sleeping) and in the evening (after everyone had retired). The whole 10-12 hours in between were just a cluster f*ck where I rarely accomplished anything of value.
I did manage to get a few interesting classes and functions out of this whole experience as well. The theme for the game was that it should be minimalistic in some way. I wanted to apply this to the artistic direction, so many of the objects drawn to the screen were basic shapes. I made them hallow, so that I could easily fill in the objects with whatever color I wanted. It was my intention to create several arrays with different color schemes that could be interchanged for each level. I had that working the first morning.
Next thing I wanted was some sort of map generation. I had a friend willing to work on this for me. He had already worked on something similar for one of his previous classes, and he figured he could easily rewrite it for me.
Another thing I was working on, (didnt get finished with it, but I have some promising code so far) was player movement that moved the screen around with it. I'd never done anything like that with a previous game so it was something new. I really should have attempted something like it prior to this game jam, since I spent a lot of time on this. I was also trying to incorporate a parallex effect using layered images moving at different speeds to give the game some depth. This was also somewhat new to me as I had read about it but not actually attempted it myself. Like I said, I have some promising code, but nothing completely working.
I also managed to get a pretty neat looking background for the game. I created a class that you can pass a surface (to draw to), a color scheme object, and the number of objects to be created: and the class would create a background object with small moving particles. It was a pretty neat effect, and as soon as I have some time, I'll post the code along with a little video clip or gif.
So I ended up with some pretty neat stuff and a neat idea for a game, but unfortunately it just didn't get to the "playable" phase. I might continue working on it, but I'm not sure when I'll have the time. At least I came away with a few lessons and even some neat code that I can implement elsewhere. All in all, it was a good time and I can't wait for the next Ludum Dare to come around.
Cheers,
-Newt
Friday, April 26, 2013
Ludum Dare - First Attempt
Okay, so I decided to take a stab at Ludum Dare 26. For those of you not familiar, it's a game jam. You are given a theme, and tasked with creating a game in a single weekend. Since this is my first go at the game jam, I'm going the more relaxed, less competetive route.
I'm still new at game development in general and I figured this would help me with my time management as well as just general development practice.
Anywho, it's been a couple hours since we were notified of the theme: Minimalistic. I still haven't yet nailed down a good idea for the game, but I've started working on the framework (basic functions, menu screens, etc.).
I've been throwing around some ideas for the game concept with a friend and so far we haven't come up with anything solid. Hopefully we'll have something by tomorrow morning. By then I should have most of the framework nailed down. Once I have a better idea of the type of game I can start to put together some sort of timeline and break the project down into tasks that need to be completed.
I'm thinking I might find some good music to use over at http://dig.ccmixter.org/
Some of the creative commons licensed music I've found there in the past has been really good. I'm sure I'll find something suitable.
Well, no time to waste... back to brainstorming
cheers,
-Newt
I'm still new at game development in general and I figured this would help me with my time management as well as just general development practice.
Anywho, it's been a couple hours since we were notified of the theme: Minimalistic. I still haven't yet nailed down a good idea for the game, but I've started working on the framework (basic functions, menu screens, etc.).
I've been throwing around some ideas for the game concept with a friend and so far we haven't come up with anything solid. Hopefully we'll have something by tomorrow morning. By then I should have most of the framework nailed down. Once I have a better idea of the type of game I can start to put together some sort of timeline and break the project down into tasks that need to be completed.
I'm thinking I might find some good music to use over at http://dig.ccmixter.org/
Some of the creative commons licensed music I've found there in the past has been really good. I'm sure I'll find something suitable.
Well, no time to waste... back to brainstorming
cheers,
-Newt
Tuesday, April 23, 2013
Pygame - Bad Guy Stuff
So I got to thinking about different bad guy types for the little zombie game I'm making. I've got a normal zombie that follows the player around, but that's boring as hell. I was trying to come up with something new. Something easy to do would be to adjust the speed of the zombies. Maybe randomize the speed upon intitialization of the sprite. Still kind of boring though...
What else can we do? Maybe zombies that leave a trail of acid or something? I thought this was an interesting idea, so I went ahead and started on it. Basically all you need is a function to create rectangles for you. Something like this:
def drawTrail(self,screen):
old_x=self.rect.topleft[0]
old_y=self.rect.bottom-(self.rect.height*.25)
if self.trailcount == 0:
if len(self.trailarray) > 10:
self.trailarray = self.trailarray[1:]
self.trailarray.append((old_x,old_y))
self.trailcount+=1
if self.trailcount == 15:
self.trailcount=0
for i in self.trailarray:
pygame.draw.rect(screen, (0,255,0), (i[0],i[1],self.rect.width,self.rect.height/4))
It's not perfect, but it works. This function exists inside the badguy sprite class. It's called when the update function is called in the game loop.
What it does is takes the sprite position and puts the values into old_x and old_y. Then it checks a variable called trail count. I used this to tell the function when to append new coordinates to our array list.
The array length is how I tell where to draw the acid. If the array gets over 10 elements, I have it cut off the oldest ones.
Anyway, it works. You might want to change it up a bit and have it use images instead of just a green rectangle.
That's all I've got for now. I'm sure you can think of other ways to use this function. If you have a particle effect library, you might want to use something like this to draw little puffs of smoke as your player sprite moves. I dunno, I thought it was pretty useful.
-Newt
What else can we do? Maybe zombies that leave a trail of acid or something? I thought this was an interesting idea, so I went ahead and started on it. Basically all you need is a function to create rectangles for you. Something like this:
def drawTrail(self,screen):
old_x=self.rect.topleft[0]
old_y=self.rect.bottom-(self.rect.height*.25)
if self.trailcount == 0:
if len(self.trailarray) > 10:
self.trailarray = self.trailarray[1:]
self.trailarray.append((old_x,old_y))
self.trailcount+=1
if self.trailcount == 15:
self.trailcount=0
for i in self.trailarray:
pygame.draw.rect(screen, (0,255,0), (i[0],i[1],self.rect.width,self.rect.height/4))
It's not perfect, but it works. This function exists inside the badguy sprite class. It's called when the update function is called in the game loop.
What it does is takes the sprite position and puts the values into old_x and old_y. Then it checks a variable called trail count. I used this to tell the function when to append new coordinates to our array list.
The array length is how I tell where to draw the acid. If the array gets over 10 elements, I have it cut off the oldest ones.
Anyway, it works. You might want to change it up a bit and have it use images instead of just a green rectangle.
That's all I've got for now. I'm sure you can think of other ways to use this function. If you have a particle effect library, you might want to use something like this to draw little puffs of smoke as your player sprite moves. I dunno, I thought it was pretty useful.
-Newt
Wednesday, April 10, 2013
Game Flair
I know I'm deviating a bit from that last couple posts about designing a simple game with pygame libraries. But I stumbled upon a video that got me thinking about some of the little things you can add to a game to make them more interesting. If you're interested this is the video I'm referring to.
One really simple idea that they had was to use tweening or easing. Instead of just placing a new sprite or game object on the screen, we have it drop into place or instead of game objects just vanishing, you can use this to slowly scale them out of existence.
The way they did this was using something like:
x += (target-x) *.1
This is probably the most simple approach to tweening. Basically we give the sprite or rectangle a target and a starting point. Then we move the x by 10 percent until it gets to the destination or target. Simple right?
And it provides a really nice effect to the game for very little cost.
That's the easiest implementation of tweening/easing. If you want to get fancier you have to do a bit more math.
Here's a basic function to get you started
def linearTween(time, startPoint, change, endPoint):
return change * time / endPoint + startPoint
time is the current time in frames, steps, whatever counter you want to use. As long as it is a percentage of the endPoint
startPoint is the value where we begin
change is the difference between the beginning and destination values
endPoint is the end time or frame or whatever for your tween.
Basically it's the same thing as x += (target-x) *.1 since you have a start, a target, diff, and percentage of change. However in this way we have a number of variables we can use in a bunch of different ways.
Check out this site: http://www.timotheegroleau.com/
He has a generator for easing functions that you can use for all sorts of fun stuff. In fact, Tim Groleau has a collection of material on the subject if you're interested.
-Newt
One really simple idea that they had was to use tweening or easing. Instead of just placing a new sprite or game object on the screen, we have it drop into place or instead of game objects just vanishing, you can use this to slowly scale them out of existence.
The way they did this was using something like:
x += (target-x) *.1
This is probably the most simple approach to tweening. Basically we give the sprite or rectangle a target and a starting point. Then we move the x by 10 percent until it gets to the destination or target. Simple right?
And it provides a really nice effect to the game for very little cost.
That's the easiest implementation of tweening/easing. If you want to get fancier you have to do a bit more math.
Here's a basic function to get you started
def linearTween(time, startPoint, change, endPoint):
return change * time / endPoint + startPoint
time is the current time in frames, steps, whatever counter you want to use. As long as it is a percentage of the endPoint
startPoint is the value where we begin
change is the difference between the beginning and destination values
endPoint is the end time or frame or whatever for your tween.
Basically it's the same thing as x += (target-x) *.1 since you have a start, a target, diff, and percentage of change. However in this way we have a number of variables we can use in a bunch of different ways.
Check out this site: http://www.timotheegroleau.com/
He has a generator for easing functions that you can use for all sorts of fun stuff. In fact, Tim Groleau has a collection of material on the subject if you're interested.
-Newt
Wednesday, April 3, 2013
Pygame Sprite Animation
Okay, animation. Not just moving rectangles either, that stuff is covered by a number of other tutorials freely available on the interwebz. I posted an earlier version of this class a while back, but I noticed some weirdness with the way I was changing images. This is a revised version. Let's just jump right into the code and I'll explain as best I can after.
class Player(pygame.sprite.Sprite):
# initialize the player object
# requires x and y coordinates
def __init__(self,x,y):
# initialize the sprite (parent class)
pygame.sprite.Sprite.__init__(self)
# Set initial variables
#change_x and y are used to move the object around the screen
self.change_x=0
self.change_y=0
#facing keeps track of the direction
#this is important so we know which set of images to use
self.facing = 0
#here are the images we're going to loop over depending on the direction
#start by setting the image to the image to start with
self.image = pygame.image.load('hero.png')
self.down = [pygame.image.load('hero.png').convert_alpha(),
pygame.image.load('hero1.png').convert_alpha(),
pygame.image.load('hero2.png').convert_alpha(),
pygame.image.load('hero3.png').convert_alpha(),
pygame.image.load('hero2.png').convert_alpha(),
pygame.image.load('hero1.png').convert_alpha()]
self.left = [pygame.image.load('herol.png').convert_alpha(),
pygame.image.load('herol1.png').convert_alpha(),
pygame.image.load('herol2.png').convert_alpha(),
pygame.image.load('herol3.png').convert_alpha(),
pygame.image.load('herol2.png').convert_alpha(),
pygame.image.load('herol1.png').convert_alpha()]
self.right = [pygame.image.load('heror.png').convert_alpha(),
pygame.image.load('heror1.png').convert_alpha(),
pygame.image.load('heror2.png').convert_alpha(),
pygame.image.load('heror3.png').convert_alpha(),
pygame.image.load('heror2.png').convert_alpha(),
pygame.image.load('heror1.png').convert_alpha()]
self.up = [pygame.image.load('herou.png').convert_alpha(),
pygame.image.load('herou1.png').convert_alpha(),
pygame.image.load('herou2.png').convert_alpha(),
pygame.image.load('herou3.png').convert_alpha(),
pygame.image.load('herou2.png').convert_alpha(),
pygame.image.load('herou1.png').convert_alpha()]
# give the object a rectangle using image size
self.rect = self.image.get_rect()
# set the topleft location to the x and y coordinates
self.rect.topleft = [x,y]
# Used to move the object
def changespeed(self,x,y):
self.change_x+=x
self.change_y+=y
# This is where we update the images and location of the player object
def update(self):
# Update position according to our speed (vector)
new_x=old_x+self.change_x
new_y=old_y+self.change_y
# Put the player in the new spot
self.rect.topleft = (new_x,new_y)
# This next bit is where we change images
# First we see if the object is stationary. If both change coordinates are 0,
# we're not moving and we can set the image to the 0 element in the array
if self.change_x == 0 and self.change_y == 0:
if self.facing == 3:
self.image = self.left[0]
if self.facing == 2:
self.image = self.down[0]
if self.facing == 4:
self.image = self.right[0]
if self.facing == 1:
self.image = self.up[0]
# The rest is just repeated code changing only the direction the player
# object is moving. In this case < 0 means we're moving left
if self.change_x < 0:
# set facing to 3 or left
self.facing = 3
# if imgvar is 0, we just started moving
if self.imgvar == 0:
# set image to the first element
self.image = self.left[0]
self.imgvar +=1
# if imgvar is anything else, we've been moving
else:
# make sure imgvar isn't greater than the length of the image array
if self.imgvar > len(self.left)-1:
self.imgvar = 0
# update imgvar and change the image
self.imgvar += 1
self.image = self.left[self.imgvar]
Okay, that's a lot to take in (that's what she said), if you're not accustomed to pygame. First you'll notice that my Player class implements a pygame parent class. This can be seen in the first line:
class Player(pygame.sprite.Sprite):
I utilize the sprite class for a number of reasons. Collision detection is one thing that sprites do very well. There is a complete list of sprite functions here: http://www.pygame.org/docs/ref/sprite.html
In any case, the important bits are the class attributes and functions. The class attributes to take note of are the change_x and y, as well as the facing and image array attributes.
change_x and change_y are used to move the object around the screen. They do this by utilizing the changespeed function. This function changes these values, which are later used in the update function to move the player. The first thing that update does is it moves the player rectangle to the new coordinates by adding the change_x and change_y values to the current x/y values. Again, I won't go into too much detail because there are plenty of better tutorials out there on moving objects.
Next we have the facing attribute. This is just an integer that keeps track of the directions your character is facing. With the setup shown above we only have animation images for 4 directions, but you could easily add 4 more for diagonal movements. You'll notice this also gets changed in the update function based on the change_x and change_y values. If change_x is a positive number we'd say facing is right, or whatever number we're using to designate moving right.
The image arrays (up,down,left, and right) are where we store the images we have to loop through to get our animation. The current image is stored under the (you guessed it) image variable. All we do to animate our character is move along to the next image in our array, setting it as the current image.
Within the update function, the comments kind of explain what's happening. We move our rectangle, then check the change_x and y variables to determine which way we're facing and which image from which array we need to be on. Just keep in mind that I only put in the left direction. You have to repeat that chunk of code to include the other directions.
Now you're saying, "This is all well and good, but how do we actually do anything with this class?" and "Why didn't you go into the other features of pygame, like the load.image function you used?" and "God this guy is retarded"
The short answer is 1)that you create an object within your game loop, use pygame events to utilize the changespeed function, and call the object's update function each loop. 2)I think there are much better explanations in the pygame documentation. 3)You're right, but there's nothing I can do about that.
I'll get more into how to use the sprite next week. We can plug it into the surface demo I did last week and we'll see how it works out.
-Newt
class Player(pygame.sprite.Sprite):
# initialize the player object
# requires x and y coordinates
def __init__(self,x,y):
# initialize the sprite (parent class)
pygame.sprite.Sprite.__init__(self)
# Set initial variables
#change_x and y are used to move the object around the screen
self.change_x=0
self.change_y=0
#facing keeps track of the direction
#this is important so we know which set of images to use
self.facing = 0
#here are the images we're going to loop over depending on the direction
#start by setting the image to the image to start with
self.image = pygame.image.load('hero.png')
self.down = [pygame.image.load('hero.png').convert_alpha(),
pygame.image.load('hero1.png').convert_alpha(),
pygame.image.load('hero2.png').convert_alpha(),
pygame.image.load('hero3.png').convert_alpha(),
pygame.image.load('hero2.png').convert_alpha(),
pygame.image.load('hero1.png').convert_alpha()]
self.left = [pygame.image.load('herol.png').convert_alpha(),
pygame.image.load('herol1.png').convert_alpha(),
pygame.image.load('herol2.png').convert_alpha(),
pygame.image.load('herol3.png').convert_alpha(),
pygame.image.load('herol2.png').convert_alpha(),
pygame.image.load('herol1.png').convert_alpha()]
self.right = [pygame.image.load('heror.png').convert_alpha(),
pygame.image.load('heror1.png').convert_alpha(),
pygame.image.load('heror2.png').convert_alpha(),
pygame.image.load('heror3.png').convert_alpha(),
pygame.image.load('heror2.png').convert_alpha(),
pygame.image.load('heror1.png').convert_alpha()]
self.up = [pygame.image.load('herou.png').convert_alpha(),
pygame.image.load('herou1.png').convert_alpha(),
pygame.image.load('herou2.png').convert_alpha(),
pygame.image.load('herou3.png').convert_alpha(),
pygame.image.load('herou2.png').convert_alpha(),
pygame.image.load('herou1.png').convert_alpha()]
# give the object a rectangle using image size
self.rect = self.image.get_rect()
# set the topleft location to the x and y coordinates
self.rect.topleft = [x,y]
# Used to move the object
def changespeed(self,x,y):
self.change_x+=x
self.change_y+=y
# This is where we update the images and location of the player object
def update(self):
# Update position according to our speed (vector)
new_x=old_x+self.change_x
new_y=old_y+self.change_y
# Put the player in the new spot
self.rect.topleft = (new_x,new_y)
# This next bit is where we change images
# First we see if the object is stationary. If both change coordinates are 0,
# we're not moving and we can set the image to the 0 element in the array
if self.change_x == 0 and self.change_y == 0:
if self.facing == 3:
self.image = self.left[0]
if self.facing == 2:
self.image = self.down[0]
if self.facing == 4:
self.image = self.right[0]
if self.facing == 1:
self.image = self.up[0]
# The rest is just repeated code changing only the direction the player
# object is moving. In this case < 0 means we're moving left
if self.change_x < 0:
# set facing to 3 or left
self.facing = 3
# if imgvar is 0, we just started moving
if self.imgvar == 0:
# set image to the first element
self.image = self.left[0]
self.imgvar +=1
# if imgvar is anything else, we've been moving
else:
# make sure imgvar isn't greater than the length of the image array
if self.imgvar > len(self.left)-1:
self.imgvar = 0
# update imgvar and change the image
self.imgvar += 1
self.image = self.left[self.imgvar]
Okay, that's a lot to take in (that's what she said), if you're not accustomed to pygame. First you'll notice that my Player class implements a pygame parent class. This can be seen in the first line:
class Player(pygame.sprite.Sprite):
I utilize the sprite class for a number of reasons. Collision detection is one thing that sprites do very well. There is a complete list of sprite functions here: http://www.pygame.org/docs/ref/sprite.html
In any case, the important bits are the class attributes and functions. The class attributes to take note of are the change_x and y, as well as the facing and image array attributes.
change_x and change_y are used to move the object around the screen. They do this by utilizing the changespeed function. This function changes these values, which are later used in the update function to move the player. The first thing that update does is it moves the player rectangle to the new coordinates by adding the change_x and change_y values to the current x/y values. Again, I won't go into too much detail because there are plenty of better tutorials out there on moving objects.
Next we have the facing attribute. This is just an integer that keeps track of the directions your character is facing. With the setup shown above we only have animation images for 4 directions, but you could easily add 4 more for diagonal movements. You'll notice this also gets changed in the update function based on the change_x and change_y values. If change_x is a positive number we'd say facing is right, or whatever number we're using to designate moving right.
The image arrays (up,down,left, and right) are where we store the images we have to loop through to get our animation. The current image is stored under the (you guessed it) image variable. All we do to animate our character is move along to the next image in our array, setting it as the current image.
Within the update function, the comments kind of explain what's happening. We move our rectangle, then check the change_x and y variables to determine which way we're facing and which image from which array we need to be on. Just keep in mind that I only put in the left direction. You have to repeat that chunk of code to include the other directions.
Now you're saying, "This is all well and good, but how do we actually do anything with this class?" and "Why didn't you go into the other features of pygame, like the load.image function you used?" and "God this guy is retarded"
The short answer is 1)that you create an object within your game loop, use pygame events to utilize the changespeed function, and call the object's update function each loop. 2)I think there are much better explanations in the pygame documentation. 3)You're right, but there's nothing I can do about that.
I'll get more into how to use the sprite next week. We can plug it into the surface demo I did last week and we'll see how it works out.
-Newt
Wednesday, March 27, 2013
Simple Game - Python
So last week I was telling you all about Pygame. Well, it was more about a certain book which covers python game development using pygame. Anyway, I thought I might share a bit of code that I've used in designing my latest python game.
The idea for my game was just a simple hack-n-slash zombie killer. Nothing flashy, just a project to help me keep my python skills from going to utter crap. The game isn't quite finished, but I've learned a few things along the way. And if there's any interest, I can post the source for what I have so far. Just let me know.
Anywho, so where do you start with a python game? Well, if you're using pygame libraries, you'll want to import the libraries, initialize pygame and create a surface to begin drawing.
import pygame
pygame.init()
#create the display object named screen
screen = pygame.display.set_mode((800, 600))
Use whatever size screen you want. And if you feel fancy, you could use the os or pygame libraries to pull the display resolution and use that. To do that with python, just use something like:
screen_x = pygame.display.Info().current_w
screen_y = pygame.display.Info().current_h
screen = pygame.display.set_mode((screen_x,screen_y))
Of course, that's a bit wonky since it's still windowed, and the explorer bar one windows, (or the menu bar on linux distros) will be in the way. To get around this you have to set the display to fullscreen. Here's an example:
#give me the biggest 16bit display available
>>> modes = pygame.display.list_modes(16)
>>> if not modes:
... print '16bit not supported'
... else:
... print 'Found Resolution:', modes[0]
... pygame.display.set_mode(modes[0], FULLSCREEN, 16)
I pulled this example from one of the pygame tutorials located here: http://www.pygame.org/docs/tut/DisplayModes.html
Anyway, once you have this much, you can start drawing to the screen. You can draw images (loaded from a file) or just draw some basic shapes using pygame. Let's start by drawing a background. I'm just going to fill it black.
background = pygame.Surface(screen.get_size())
background.fill((0,0,0))
By the way, if you're going to be using certain colors throughout your code, it makes sense to create some variables to store the rgb tuples. Here's a few to get you started:
black = (0,0,0)
white = (255,255,255)
blue = (0,0,255)
red = (255,0,0)
green = (0,255,0)
#then if you were to use them to fill the background it would look like this
background.fill(black)
So now we've got a black background, so what? Most boring game ever. Let's add a rectangle or something.
pygame.draw.rect(background, green, (100, 100, 100, 100))
You can probably figure that out, but I'm using the pygame draw class to draw a rectangle. This function takes several arguments. First it needs a surface to draw the rectangle to, I used background. Then it takes a tuple for the color. And lastly it needs to know where the rectangle is to be drawn, and the dimensions. These are passed as a tuple of four elements, where the first element is the x coordinate and the second element is the y coordinate. The other two are for width and height.
This is drawing the rectangle (square actually) object to the background surface. Remember though, that the background was drawn to the screen surface object. So how do we display the changes we just made to the background surface? With the blit function. Each surface object has a number of useful functions that come along with it. Blit basically, redraws one surface to another, updating any changed pixels. Here's a quick example:
screen.blit(background, (0,0))
I'm updating the screen surface with the new background image at the coordinates 0, 0. Since the background is the same size, this will place it directly on top of the screen.
If you run this, it will open your game, draw the rectangle and immediately close it. In order to keep the window open, you have to have the drawing done in some sort of loop, or tell python to wait for input or something to that effect. I may go over the different ways to do that later on, but for now let's just create a little game loop to watch for "events" and quit when it sees a specific event.
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
You can probably guess as to what this does for the most part. It's looking through pygame events, which are all sorts of keyboard, and mouse input events. pygame.QUIT is basically when the user clicks the window's X to close the window. Without this you'll have to manually kill the process.
So here's what we have so far:
import pygame
#set up color variables
black = (0,0,0)
white = (255,255,255)
blue = (0,0,255)
red = (255,0,0)
green = (0,255,0)
#start pygame
pygame.init()
#set up a basic surface
screen = pygame.display.set_mode((800, 600))
#create a background using the screen surface size
background = pygame.Surface(screen.get_size())
background.fill(black)
#draw a rectangle to the background surface
pygame.draw.rect(background,green,(100,100,100,100))
#draw the whole thing to the screen
screen.blit(background, (0,0))
#update your display
pygame.display.update()
#loop through events till we get the signal to close the window
while 1:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
And there we go. We have a basic window, with a couple surfaces, and a rectangle object that we have drawn onto them. Now you could do this with a single surface object. I just got into the habit of having two recently. The reason for this is kind of convoluted, and it involves a solution for resizing the window to fit multiple android devices. I'll have to do a post on that down the road, but this post is getting pretty lengthy, so I'll just leave off here for now.
Next time, I'll go into a bit about moving your rectangles and animating using images rather than just using a single static green rectangle.
-Newt
The idea for my game was just a simple hack-n-slash zombie killer. Nothing flashy, just a project to help me keep my python skills from going to utter crap. The game isn't quite finished, but I've learned a few things along the way. And if there's any interest, I can post the source for what I have so far. Just let me know.
Anywho, so where do you start with a python game? Well, if you're using pygame libraries, you'll want to import the libraries, initialize pygame and create a surface to begin drawing.
import pygame
pygame.init()
#create the display object named screen
screen = pygame.display.set_mode((800, 600))
Use whatever size screen you want. And if you feel fancy, you could use the os or pygame libraries to pull the display resolution and use that. To do that with python, just use something like:
screen_x = pygame.display.Info().current_w
screen_y = pygame.display.Info().current_h
screen = pygame.display.set_mode((screen_x,screen_y))
Of course, that's a bit wonky since it's still windowed, and the explorer bar one windows, (or the menu bar on linux distros) will be in the way. To get around this you have to set the display to fullscreen. Here's an example:
#give me the biggest 16bit display available
>>> modes = pygame.display.list_modes(16)
>>> if not modes:
... print '16bit not supported'
... else:
... print 'Found Resolution:', modes[0]
... pygame.display.set_mode(modes[0], FULLSCREEN, 16)
I pulled this example from one of the pygame tutorials located here: http://www.pygame.org/docs/tut/DisplayModes.html
Anyway, once you have this much, you can start drawing to the screen. You can draw images (loaded from a file) or just draw some basic shapes using pygame. Let's start by drawing a background. I'm just going to fill it black.
background = pygame.Surface(screen.get_size())
background.fill((0,0,0))
By the way, if you're going to be using certain colors throughout your code, it makes sense to create some variables to store the rgb tuples. Here's a few to get you started:
black = (0,0,0)
white = (255,255,255)
blue = (0,0,255)
red = (255,0,0)
green = (0,255,0)
#then if you were to use them to fill the background it would look like this
background.fill(black)
So now we've got a black background, so what? Most boring game ever. Let's add a rectangle or something.
pygame.draw.rect(background, green, (100, 100, 100, 100))
You can probably figure that out, but I'm using the pygame draw class to draw a rectangle. This function takes several arguments. First it needs a surface to draw the rectangle to, I used background. Then it takes a tuple for the color. And lastly it needs to know where the rectangle is to be drawn, and the dimensions. These are passed as a tuple of four elements, where the first element is the x coordinate and the second element is the y coordinate. The other two are for width and height.
This is drawing the rectangle (square actually) object to the background surface. Remember though, that the background was drawn to the screen surface object. So how do we display the changes we just made to the background surface? With the blit function. Each surface object has a number of useful functions that come along with it. Blit basically, redraws one surface to another, updating any changed pixels. Here's a quick example:
screen.blit(background, (0,0))
I'm updating the screen surface with the new background image at the coordinates 0, 0. Since the background is the same size, this will place it directly on top of the screen.
If you run this, it will open your game, draw the rectangle and immediately close it. In order to keep the window open, you have to have the drawing done in some sort of loop, or tell python to wait for input or something to that effect. I may go over the different ways to do that later on, but for now let's just create a little game loop to watch for "events" and quit when it sees a specific event.
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
You can probably guess as to what this does for the most part. It's looking through pygame events, which are all sorts of keyboard, and mouse input events. pygame.QUIT is basically when the user clicks the window's X to close the window. Without this you'll have to manually kill the process.
So here's what we have so far:
import pygame
#set up color variables
black = (0,0,0)
white = (255,255,255)
blue = (0,0,255)
red = (255,0,0)
green = (0,255,0)
#start pygame
pygame.init()
#set up a basic surface
screen = pygame.display.set_mode((800, 600))
#create a background using the screen surface size
background = pygame.Surface(screen.get_size())
background.fill(black)
#draw a rectangle to the background surface
pygame.draw.rect(background,green,(100,100,100,100))
#draw the whole thing to the screen
screen.blit(background, (0,0))
#update your display
pygame.display.update()
#loop through events till we get the signal to close the window
while 1:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
And there we go. We have a basic window, with a couple surfaces, and a rectangle object that we have drawn onto them. Now you could do this with a single surface object. I just got into the habit of having two recently. The reason for this is kind of convoluted, and it involves a solution for resizing the window to fit multiple android devices. I'll have to do a post on that down the road, but this post is getting pretty lengthy, so I'll just leave off here for now.
Next time, I'll go into a bit about moving your rectangles and animating using images rather than just using a single static green rectangle.
-Newt
Wednesday, March 20, 2013
Games with Python
Over the last year and some change, I've been trying to teach myself to code. I started with Python for no real reason other than there were a number of tutorial sites out there that seemed to be pretty complete.
After going through the tutorials and Python documentation (several times in some cases) I found myself wondering how to get in some badly needed practice. After all, in order to code something you need to have some sort of use case in mind. I had found a number of forums offering up ideas for projects, but most were either way above my head or so simple I completed them in minutes.
Longer projects seemed to only hold my interest if there were some actual need for the functionality. Like parsing proxy logs or cmdb data at work. For everything else, I had trouble keeping focused till the completion of the code.
One day, by chance, I found this: http://inventwithpython.com/
At the time Albert Sweigart had only written the first book, but it was enough to renew my interest in learning the language. It's written so that even those with no working knowledge of programming can start creating games and learning python. It goes through a few command-line based games, into graphics based games teaching skills that can easily be translated into scripting and app development.
If you are interested in simple game development, or Python, I would definitely recommend reading his book either by download (for free) or purchasing a hardcopy . The second book is also now available and goes into even more detail with several new game types and development concepts.
I know this sounds like some sort of plug, but I am in no way being compensated for this endorsement. I am merely a grateful reader of his work.
-newt
After going through the tutorials and Python documentation (several times in some cases) I found myself wondering how to get in some badly needed practice. After all, in order to code something you need to have some sort of use case in mind. I had found a number of forums offering up ideas for projects, but most were either way above my head or so simple I completed them in minutes.
Longer projects seemed to only hold my interest if there were some actual need for the functionality. Like parsing proxy logs or cmdb data at work. For everything else, I had trouble keeping focused till the completion of the code.
One day, by chance, I found this: http://inventwithpython.com/
At the time Albert Sweigart had only written the first book, but it was enough to renew my interest in learning the language. It's written so that even those with no working knowledge of programming can start creating games and learning python. It goes through a few command-line based games, into graphics based games teaching skills that can easily be translated into scripting and app development.
If you are interested in simple game development, or Python, I would definitely recommend reading his book either by download (for free) or purchasing a hardcopy . The second book is also now available and goes into even more detail with several new game types and development concepts.
I know this sounds like some sort of plug, but I am in no way being compensated for this endorsement. I am merely a grateful reader of his work.
-newt
Wednesday, March 13, 2013
Coding Challenge - Python
So I've been a fan of hackthissite.org for a while now. IT Security has been an interest of mine since I was introduced to computers. They've got tons of hacking challenges to test your skills and teach you new ones.
Just recently though, I noticed that they have coding/scripting challenges now as well. They range from beginner to really difficult, but they've got some really neat ones up there. If you're interested, go register (for free, of course) and try them out for yourself.
The first challenge asks you to code something that can take a number of scrambled words, that were chosen from a file that they provide you with, run the input through a script and produce the unscrambled words in a specific format. i.e. (word1, word2, word3,.....)
Sure you could do it manually, but the page expires a few seconds after the scrambled words are given. So you have to get the scrambled words, run them through your script and submit the output in a few seconds.
There are a ton of ways you could handle this, like sending the output to a file, or console, or even have it go straight to the clipboard so you can paste it into the web form quickly. Even write something to parse the page, pull down the words, and post the output automatically...
Below the break, you can see how I did it using python. Kind of a spoiler if you're planning to try this stuff out yourself, just fyi.
Just recently though, I noticed that they have coding/scripting challenges now as well. They range from beginner to really difficult, but they've got some really neat ones up there. If you're interested, go register (for free, of course) and try them out for yourself.
The first challenge asks you to code something that can take a number of scrambled words, that were chosen from a file that they provide you with, run the input through a script and produce the unscrambled words in a specific format. i.e. (word1, word2, word3,.....)
Sure you could do it manually, but the page expires a few seconds after the scrambled words are given. So you have to get the scrambled words, run them through your script and submit the output in a few seconds.
There are a ton of ways you could handle this, like sending the output to a file, or console, or even have it go straight to the clipboard so you can paste it into the web form quickly. Even write something to parse the page, pull down the words, and post the output automatically...
Below the break, you can see how I did it using python. Kind of a spoiler if you're planning to try this stuff out yourself, just fyi.
Labels:
Challenge,
Code,
hackthissite,
output to file,
Python,
Script
Wednesday, March 6, 2013
Assignment - Python
So, one of my java classes had this assignment a while back to write a command-line application to store user input to a text file. Easy, right? Just loop over the 3 questions and save the user responses on a line in a text file.
Having never worked with Java before, I was surprised at the amount of code necessary to do this. Even without validating user input, the code ended up being around 40 lines.
It got me thinking about how I would do the same thing in python. And I was curious to see how few lines it would take to get the exact same functionality. Here's what I came up with:
file = open("output.txt", 'w')
listOfStuff = []
while True:
productID = raw_input("enter productID: ")
product = raw_input("enter product: ")
price = raw_input("enter price: ")
listOfStuff.append(productID+" "+product+" "+price+ "\n")
blah = raw_input("Coninue? yes or no: ")
if blah in ("no", "nope", "negative"):
break
for i in listOfStuff:
file.write(i)
file.close()
13 lines does it. Sure I should do some input validation and all that best-practice jazz, but I didn't have to implement any of that for the java project either, and I was just trying to get the same output and functionality.
If anyone wants to see the crappy java version of this that I did, I guess I could post that too, just leave a comment, or shoot me a message. I only leave it out because 1) I'm lazy, and 2) I have my doubts about anyone actually reading this blog.
-newt
Having never worked with Java before, I was surprised at the amount of code necessary to do this. Even without validating user input, the code ended up being around 40 lines.
It got me thinking about how I would do the same thing in python. And I was curious to see how few lines it would take to get the exact same functionality. Here's what I came up with:
file = open("output.txt", 'w')
listOfStuff = []
while True:
productID = raw_input("enter productID: ")
product = raw_input("enter product: ")
price = raw_input("enter price: ")
listOfStuff.append(productID+" "+product+" "+price+ "\n")
blah = raw_input("Coninue? yes or no: ")
if blah in ("no", "nope", "negative"):
break
for i in listOfStuff:
file.write(i)
file.close()
13 lines does it. Sure I should do some input validation and all that best-practice jazz, but I didn't have to implement any of that for the java project either, and I was just trying to get the same output and functionality.
If anyone wants to see the crappy java version of this that I did, I guess I could post that too, just leave a comment, or shoot me a message. I only leave it out because 1) I'm lazy, and 2) I have my doubts about anyone actually reading this blog.
-newt
Wednesday, February 27, 2013
99 bottles of beer - Python
This one is pretty useless, I know. I was trying to think up something to code to test out my fledgling Python knowledge back when I was first picking it up. There was a competition online to script something to output the lyrics to "99 bottles of beer on the wall" in the fewest lines possible. There was a category for fewest characters as well. I knew I wasn't good enough to enter such a competition, but I figured I'd try it and see what I could come up with.
Here's what I ended up doing:
def outputLine(x,v):
z = str(x) + " bottle" + v + " of beer on the wall, " + str(x) + " bottle" + v + " of beer. take one down pass it around, " + str(x-1) + " bottles of beer on the wall."
print z
def song():
boosh = range(1, 100)
boosh.reverse()
for x in boosh:
if x == 1:
v = ""
outputLine(x,v)
else:
v = "s"
outputLine(x,v)
x = x - 1
song()
I know now, several shortcuts I could use to shorten it up a bit more, but it's interesting for me to see how I solved a problem a year ago and think about how I would do it now.
-newt
Here's what I ended up doing:
def outputLine(x,v):
z = str(x) + " bottle" + v + " of beer on the wall, " + str(x) + " bottle" + v + " of beer. take one down pass it around, " + str(x-1) + " bottles of beer on the wall."
print z
def song():
boosh = range(1, 100)
boosh.reverse()
for x in boosh:
if x == 1:
v = ""
outputLine(x,v)
else:
v = "s"
outputLine(x,v)
x = x - 1
song()
![]() |
| works like a champ |
-newt
Monday, December 17, 2012
Konami code - Python
Okay, so I was playing around with my game trying to figure out how to implement cheats. There's probably a more elegant way to do this, but I'm still pretty new to coding, so give me a break.
Basically I created a pause menu function. All my menu's work by implementing a menu with basic functions and attributes. You just feed the menu function some images to use for the screen, and set up a loop to watch for keystrokes or other input events.
Anyway, for the pause menu, I just have a simple background with two options available to choose from. It watches for input from the up, down, left, right, b, a, keys. (went with the konami code for testing) I set up two variables. code and match. code is an array that holds key strokes while match is used to determine if the keys were pressed in the correct order.
def pause(screen, font):
images = ['menu.png', 'menu1.png']
menu = Menu(images)
menu.imgset = [pygame.image.load(images[0]), pygame.image.load(images[1])]
pygame.sprite.RenderPlain(menu)
clock = pygame.time.Clock()
code = []
match = ['u','u','d','d','l','r','l','r','b','a']
while True:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
terminate()
if event.type == KEYDOWN:
if event.type == pygame.QUIT:
terminate()
if event.key == K_UP:
menu.changeup()
code.append('u')
if event.key == K_DOWN:
menu.changedown()
code.append('d')
if event.key == K_LEFT:
code.append('l')
if event.key == K_RIGHT:
code.append('r')
if event.key == K_b:
code.append('b')
if event.key == K_a:
code.append('a')
if event.key == K_RETURN:
if menu.pos == 0:
#shared.PAUSE = False
return False
if menu.pos == 1:
pygame.quit()
sys.exit()
code = code[-10:]
if code == match:
shared.CHEAT = True
code = []
menu.update()
pygame.draw.rect(screen,(0, 0 ,0),(0,0,800,600))
screen.blit(menu.image,menu.rect)
#drawText('Paused', font, screen, 350, 30)
textobj = font.render("Paused", 1, (255,255,255))
textrect = textobj.get_rect()
textrect.topleft = (350, 30)
screen.blit(textobj, textrect)
pygame.display.update()
Here's the bit in the main loop that uses the pause and checks for the cheat variable before changing the background image:
def main():
while 1:
#set up variables, initialize sprites, etc, etc...
.......
for event in pygame.event.get():
if event.type == pygame.QUIT:
terminate()
if event.type == KEYDOWN:
#throw in a pause key
if event.key == K_p:
pause(screen, font)
#check for cheat and blit images to screen surface
if shared.CHEAT:
screen.blit(backimage2,backrect)
if not shared.CHEAT:
screen.blit(backimage,backrect)
screen.blit(attack.image,attack.rect)
screen.blit(player.image,player.rect)
pygame.display.update()
basically pressing p brings up the pause screen, and while in the pause menu, if the two variables match, it sets the CHEAT variable to true.
You could instead, have it add more "cheat" options to the menu, so you could turn them on and off. The way I did it, leaves the cheat on for the duration of the game. Like I said, there are probably better ways to do it, but this works. I'll probably post the whole game source at some point, but if you'd like to see it now, just let me know and I'll shoot you the source.
-newt
Basically I created a pause menu function. All my menu's work by implementing a menu with basic functions and attributes. You just feed the menu function some images to use for the screen, and set up a loop to watch for keystrokes or other input events.
Anyway, for the pause menu, I just have a simple background with two options available to choose from. It watches for input from the up, down, left, right, b, a, keys. (went with the konami code for testing) I set up two variables. code and match. code is an array that holds key strokes while match is used to determine if the keys were pressed in the correct order.
def pause(screen, font):
images = ['menu.png', 'menu1.png']
menu = Menu(images)
menu.imgset = [pygame.image.load(images[0]), pygame.image.load(images[1])]
pygame.sprite.RenderPlain(menu)
clock = pygame.time.Clock()
code = []
match = ['u','u','d','d','l','r','l','r','b','a']
while True:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
terminate()
if event.type == KEYDOWN:
if event.type == pygame.QUIT:
terminate()
if event.key == K_UP:
menu.changeup()
code.append('u')
if event.key == K_DOWN:
menu.changedown()
code.append('d')
if event.key == K_LEFT:
code.append('l')
if event.key == K_RIGHT:
code.append('r')
if event.key == K_b:
code.append('b')
if event.key == K_a:
code.append('a')
if event.key == K_RETURN:
if menu.pos == 0:
#shared.PAUSE = False
return False
if menu.pos == 1:
pygame.quit()
sys.exit()
code = code[-10:]
if code == match:
shared.CHEAT = True
code = []
menu.update()
pygame.draw.rect(screen,(0, 0 ,0),(0,0,800,600))
screen.blit(menu.image,menu.rect)
#drawText('Paused', font, screen, 350, 30)
textobj = font.render("Paused", 1, (255,255,255))
textrect = textobj.get_rect()
textrect.topleft = (350, 30)
screen.blit(textobj, textrect)
pygame.display.update()
Here's the bit in the main loop that uses the pause and checks for the cheat variable before changing the background image:
def main():
while 1:
#set up variables, initialize sprites, etc, etc...
.......
for event in pygame.event.get():
if event.type == pygame.QUIT:
terminate()
if event.type == KEYDOWN:
#throw in a pause key
if event.key == K_p:
pause(screen, font)
#check for cheat and blit images to screen surface
if shared.CHEAT:
screen.blit(backimage2,backrect)
if not shared.CHEAT:
screen.blit(backimage,backrect)
screen.blit(attack.image,attack.rect)
screen.blit(player.image,player.rect)
pygame.display.update()
basically pressing p brings up the pause screen, and while in the pause menu, if the two variables match, it sets the CHEAT variable to true.
You could instead, have it add more "cheat" options to the menu, so you could turn them on and off. The way I did it, leaves the cheat on for the duration of the game. Like I said, there are probably better ways to do it, but this works. I'll probably post the whole game source at some point, but if you'd like to see it now, just let me know and I'll shoot you the source.
-newt
Monday, December 10, 2012
Hopefully Helpful
So I was coding a simple python game the other day using pygame, and I thought this might be helpful for someone:
class Test(pygame.sprite.Sprite):
# Constructor function
def __init__(self,x,y):
# Call the parent's constructor
pygame.sprite.Sprite.__init__(self)
# Set init speed
self.change_x=0
self.change_y=0
self.facing = 0
# Set height, width
self.image = pygame.image.load('baddie.png')
self.down = [pygame.image.load('baddie.png').convert_alpha(),
pygame.image.load('baddie1.png').convert_alpha(),
pygame.image.load('baddie2.png').convert_alpha(),
pygame.image.load('baddie3.png').convert_alpha(),
pygame.image.load('baddie2.png').convert_alpha(),
pygame.image.load('baddie1.png').convert_alpha()]
self.left = [pygame.image.load('baddiel.png').convert_alpha(),
pygame.image.load('baddiel1.png').convert_alpha(),
pygame.image.load('baddiel2.png').convert_alpha(),
pygame.image.load('baddiel3.png').convert_alpha(),
pygame.image.load('baddiel2.png').convert_alpha(),
pygame.image.load('baddiel1.png').convert_alpha()]
self.right = [pygame.image.load('baddier.png').convert_alpha(),
pygame.image.load('baddier1.png').convert_alpha(),
pygame.image.load('baddier2.png').convert_alpha(),
pygame.image.load('baddier3.png').convert_alpha(),
pygame.image.load('baddier2.png').convert_alpha(),
pygame.image.load('baddier1.png').convert_alpha()]
self.up = [pygame.image.load('baddieu.png').convert_alpha(),
pygame.image.load('baddieu1.png').convert_alpha(),
pygame.image.load('baddieu2.png').convert_alpha(),
pygame.image.load('baddieu3.png').convert_alpha(),
pygame.image.load('baddieu2.png').convert_alpha(),
pygame.image.load('baddieu1.png').convert_alpha()]
self.imgcounter = 0
self.imgvar = 0
# Make our top-left corner a required input for the class
self.rect = self.image.get_rect()
self.rect.topleft = [x,y]
# Change the speed of the player
def changespeed(self,x,y):
self.change_x+=x
self.change_y+=y
# Find a new position for the player
def update(self):
# Get the old position, in case we need to go back to it
old_x=self.rect.topleft[0]
old_y=self.rect.topleft[1]
# Update position according to our speed (vector)
new_x=old_x+self.change_x
new_y=old_y+self.change_y
# Put the player in the new spot
self.rect.topleft = (new_x,new_y)
if self.change_x == 0 and self.change_y == 0:
#self.imgvar = 0
if self.facing == 3:
self.image = self.left[0]
if self.facing == 2:
self.image = self.down[0]
if self.facing == 4:
self.image = self.right[0]
if self.facing == 1:
self.image = self.up[0]
if self.change_x < 0:
self.facing = 3
if self.imgcounter == 0:
self.image = self.left[0]
#self.imgcounter =+ 1
self.imgcounter += 1
self.image = self.left[self.imgvar]
if self.imgcounter > 1:
self.imgcounter = 0
self.imgvar += 1
if self.imgvar > len(self.left)-1:
self.imgvar = 0
#self.image = self.left[self.imgvar]
if self.change_x > 0:
self.facing = 4
if self.imgcounter == 0:
self.image = self.right[0]
#self.imgcounter =+ 1
self.imgcounter += 1
self.image = self.right[self.imgvar]
if self.imgcounter > 1:
self.imgcounter = 0
self.imgvar += 1
if self.imgvar > len(self.right)-1:
self.imgvar = 0
if self.change_y < 0:
self.facing = 1
if self.imgcounter == 0:
self.image = self.up[0]
#self.imgcounter =+ 1
self.imgcounter += 1
self.image = self.up[self.imgvar]
if self.imgcounter > 1:
self.imgcounter = 0
self.imgvar += 1
if self.imgvar > len(self.up)-1:
self.imgvar = 0
if self.change_y > 0:
self.facing = 2
if self.imgcounter == 0:
self.image = self.down[0]
#self.imgcounter =+ 1
self.imgcounter += 1
self.image = self.down[self.imgvar]
if self.imgcounter > 1:
self.imgcounter = 0
self.imgvar += 1
if self.imgvar > len(self.down)-1:
self.imgvar = 0
It's a simple sprite created to help test some animations I created. Keeps track of directions and the update function flips through an array of images. You can easily adjust this to pull in images from a sprite sheet instead of using several image files.
It doesn't really do much else, but it's useful for testing out sprite animations.
-Newt
class Test(pygame.sprite.Sprite):
# Constructor function
def __init__(self,x,y):
# Call the parent's constructor
pygame.sprite.Sprite.__init__(self)
# Set init speed
self.change_x=0
self.change_y=0
self.facing = 0
# Set height, width
self.image = pygame.image.load('baddie.png')
self.down = [pygame.image.load('baddie.png').convert_alpha(),
pygame.image.load('baddie1.png').convert_alpha(),
pygame.image.load('baddie2.png').convert_alpha(),
pygame.image.load('baddie3.png').convert_alpha(),
pygame.image.load('baddie2.png').convert_alpha(),
pygame.image.load('baddie1.png').convert_alpha()]
self.left = [pygame.image.load('baddiel.png').convert_alpha(),
pygame.image.load('baddiel1.png').convert_alpha(),
pygame.image.load('baddiel2.png').convert_alpha(),
pygame.image.load('baddiel3.png').convert_alpha(),
pygame.image.load('baddiel2.png').convert_alpha(),
pygame.image.load('baddiel1.png').convert_alpha()]
self.right = [pygame.image.load('baddier.png').convert_alpha(),
pygame.image.load('baddier1.png').convert_alpha(),
pygame.image.load('baddier2.png').convert_alpha(),
pygame.image.load('baddier3.png').convert_alpha(),
pygame.image.load('baddier2.png').convert_alpha(),
pygame.image.load('baddier1.png').convert_alpha()]
self.up = [pygame.image.load('baddieu.png').convert_alpha(),
pygame.image.load('baddieu1.png').convert_alpha(),
pygame.image.load('baddieu2.png').convert_alpha(),
pygame.image.load('baddieu3.png').convert_alpha(),
pygame.image.load('baddieu2.png').convert_alpha(),
pygame.image.load('baddieu1.png').convert_alpha()]
self.imgcounter = 0
self.imgvar = 0
# Make our top-left corner a required input for the class
self.rect = self.image.get_rect()
self.rect.topleft = [x,y]
# Change the speed of the player
def changespeed(self,x,y):
self.change_x+=x
self.change_y+=y
# Find a new position for the player
def update(self):
# Get the old position, in case we need to go back to it
old_x=self.rect.topleft[0]
old_y=self.rect.topleft[1]
# Update position according to our speed (vector)
new_x=old_x+self.change_x
new_y=old_y+self.change_y
# Put the player in the new spot
self.rect.topleft = (new_x,new_y)
if self.change_x == 0 and self.change_y == 0:
#self.imgvar = 0
if self.facing == 3:
self.image = self.left[0]
if self.facing == 2:
self.image = self.down[0]
if self.facing == 4:
self.image = self.right[0]
if self.facing == 1:
self.image = self.up[0]
if self.change_x < 0:
self.facing = 3
if self.imgcounter == 0:
self.image = self.left[0]
#self.imgcounter =+ 1
self.imgcounter += 1
self.image = self.left[self.imgvar]
if self.imgcounter > 1:
self.imgcounter = 0
self.imgvar += 1
if self.imgvar > len(self.left)-1:
self.imgvar = 0
#self.image = self.left[self.imgvar]
if self.change_x > 0:
self.facing = 4
if self.imgcounter == 0:
self.image = self.right[0]
#self.imgcounter =+ 1
self.imgcounter += 1
self.image = self.right[self.imgvar]
if self.imgcounter > 1:
self.imgcounter = 0
self.imgvar += 1
if self.imgvar > len(self.right)-1:
self.imgvar = 0
if self.change_y < 0:
self.facing = 1
if self.imgcounter == 0:
self.image = self.up[0]
#self.imgcounter =+ 1
self.imgcounter += 1
self.image = self.up[self.imgvar]
if self.imgcounter > 1:
self.imgcounter = 0
self.imgvar += 1
if self.imgvar > len(self.up)-1:
self.imgvar = 0
if self.change_y > 0:
self.facing = 2
if self.imgcounter == 0:
self.image = self.down[0]
#self.imgcounter =+ 1
self.imgcounter += 1
self.image = self.down[self.imgvar]
if self.imgcounter > 1:
self.imgcounter = 0
self.imgvar += 1
if self.imgvar > len(self.down)-1:
self.imgvar = 0
It's a simple sprite created to help test some animations I created. Keeps track of directions and the update function flips through an array of images. You can easily adjust this to pull in images from a sprite sheet instead of using several image files.
It doesn't really do much else, but it's useful for testing out sprite animations.
-Newt
Subscribe to:
Posts (Atom)

