September 2007 challenge: “Twisted”

Murmel - Dragging the screen

Posted by ldle on 2007/09/02 19:15

Okay our first technical challenge was figuring our how to implement dragging. We decided the way to do it was record the point at which the mouse was pressed. Then each frame just figure out the angle between the first point to the current point using the game's marble as the center. This works well because we get the effect of manipulating a pinwheel. Dragging close to the marble yields faster rotation, further away it becomes slower.

Add a comment

Lazers - Basic idea woo

Posted by Mocker on 2007/09/02 15:49

Its bizness timeee!

We have an idea, we have the beginning sprite for the main character.

It will be a 2d platformer, involving robots, lazers(probably)
and incredible gymnastic feats. And probably some other stuff too!

Coming soon to a PyWeek site near you.

Add a comment

courier12point5 - Day 1

Posted by courier12point5 on 2007/09/02 15:05

I really did not want Twisted to be the theme (I had a whole fleshed out game idea for Turmoil...), but I guess I'll have to make it work. I'm going to make a twisted trivia game, where you have to get the questions wrong. It'll be harder than it sounds...

Add a comment

python programmers in hiding - Brainstorming

Posted by MattS on 2007/09/02 13:28

Two of our team members are in Sydney and one is in England, so the two Sydney members brainstormed today while the other slept. It turned out to be mildly productive, we now have a plan and a git repository, two very important things!!

Here is a link to the photo of Malcolm and I working hard: Group photo

Add a comment

Deathworks - For the curious (includes source code snippets)

Posted by Deathworks on 2007/09/02 11:21

Hi!

After causing a bit of commotion with my programming style, I figured that sharing my source code thus far could help people understand how I approach my programming project and why I felt the way I felt about certain things.

However, currently, what source code I have programmed is not really enough to warrant an upload (I don't want to waste people's interest by making something as big and not delivering. Therefore, I will include the bits in this post (cutting out a few redundant comments, maybe).

So, if you don't want to see a Python newbie's awkward code for fear of getting confused, I suggest you don't read any further.

Since I didn't know the theme yet (starting about 6 hours before now without having internet access (^_^;; ), I solely concentrated on technical stuff, so there is no content at all yet.

Directory structure

Currently, with no readme.txt or so written, there is only one file in the root directory, namely main.py (okay, a very original name). In addition, the root directory currently has one subdirectory called code where all the rest of the code resides.

Currently, code contains application.py, constants.py, globals.py, mainmenu.py, and mainwindow.py.

main.py

(Header comment removed because layout crunched by HTML)

# This program was written for Python 2.5.1 in combination with
# wxPython 2.8.4.

# Initializing external libraries

try:
___ import sys
except:
___ print "Importing the standard library 'sys' has failed!\nPlease check the integrety of your Python installation."
___ raise

#
# try to import sys
#

try:
___ import math
except:
___ print "Importing the standard library 'math' has failed!\nPlease check the integrity of your Python installation."
___ raise

#
# try to import math
#

try:
___ a = sys.version_info
except:
___ print "You need version 2.5 or later of Python in order to run this program!"
___ raise

#
# fetch the version number of Python
#

if (a[0] == 2) and (a[1] < 5):
___ print "You need version 2.5 or later of Python in order to run this program!"
___ sys.exit()

#
# check whether Python is at least version 2.5
# Note: version_info was not available in 1.x versions of Python, which is why
# a[0] == 2 is sufficient.
#

try:
___ import wx
except:
___ print "Importing the wxPython libraries has failed!\nYou need to have the wxPython libraries (version 2.8.4 or later) installed in order to run this program."
___ raise

#
# try to import wx, which is the current method of importing the wxPython libraries
#
a = wx.version()

if (a[0] < '2') or ((a[0] == '2') and ((a[2] < '8') or ((a[2] == '8') and (a[2] < '4')))):
___ print "You need at least version 2.8.4 of the wxPython libraries in order to run this program!"
___ sys.exit()

#
# Check the version number of wxPython.
# Version 2.8.4 is required.
#


#
# Verifying top level
# -------------------
# This module is meant to be run by itself and will not execute as
# an imported library!

if (__name__ != "__main__"):
___ print "This module was not designed to be used as an imported module.\nPlease start it by itself!"
___ sys.exit()
#
# Abort program execution if this module isn't boss around here.
#

#
# Initializing original code
# --------------------------
# Note: In order to avoid conflicts with nested try ... except calls
# the following 'execfile' commands are not backed up by try except

execfile("code/constants.py")

#
# Initialize global constants
#

execfile("code/globals.py")

#
# Initialize global variables
#

execfile("code/mainmenu.py")

#
# Initialize the class for the main menu
#

execfile("code/mainwindow.py")

#
# Initialize the class for the main window
#

execfile("code/application.py")

#
# Initialize the application class
#

#
# Starting the Application
#
# ----------------------------
# Note: This 'module' is not meant to be imported at all. That is
# why I am not including the compatibility if statement.
DW_Application = DW_Class_Application(redirect = False)
DW_Application.MainLoop()

#
# What a big main program :)
# An instance of the my application class is created.
# Redirect = False causes error messages to go to Python's window.
# and then I start the standard main loop included in the basic application # class
#

constants.py

(Again comments shortened)
# Constants declaration
#
# This file initializes most of the 'constants' the game uses.
# Please note that these are not real constants, technically
# speaking and some may later be initialized from a data file.
# They are constants in the sense that they are not to be changed
# during the main program execution. Any changes to them are to be
# considered equivalent of restarting the program.
#
# Constants are marked by the 'Const' prefix in the name (right
# after the 'DW' prefix :) :) :) ).
#
# Screen and Display Constants

DW_Const_Screen_Width = 640
DW_Const_Screen_Height = 480

#
# Screen width and height; just as you would expect :)
# Used in application window initialization and various
# graphical calculations (probably (^_^;; )
#

#
# Map Mode and Tile Constants
#

DW_Const_Tile_Width = 32
DW_Const_Tile_Height = 32

#
# Tile width and height; again, quite obvious
# Used by routines handling map display, but also in combination
# with any display of items that are eligible for map display (e.g. character sprite)
#

DW_Const_Map_Display_Tile_Width = 15
DW_Const_Map_Display_Tile_Height = 13

#
# Height and width of the map display measured in tiles
# Used by map displaying routines
#

DW_Const_Map_Display_X_Margin = int(DW_Const_Map_Display_Tile_Width / 2)
DW_Const_Map_Display_Y_Margin = int(DW_Const_Map_Display_Tile_Height / 2)

#
# Derived constants used by the map displaying routines in many functions
# concerning map centering. Measured in tiles.
#

DW_Const_Max_Map_Width = 200
DW_Const_Max_Map_Height = 200

#
# Maximum size for any maps (measured in tiles).
# Needed by map loading routines to check for legitimate map size and #

#
# Miscellaneous Tool Constants
#

DW_Const_Hex_to_Dec = {"0" : 0, "1" : 1, "2" : 2, "3" : 3, "4" : 4,
______________________ "5" : 5, "6" : 6, "7" : 7, "8" : 8, "9" : 9,
______________________ "a" : 10, "b" : 11, "c" : 12, "d" : 13, "e" : 14,
______________________ "f" : 15, "A" : 10, "B" : 11, "C" : 12, "D" : 13,
______________________ "E" : 14, "F" : 15}
DW_Const_Dec_to_Hex = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
______________________ "a", "b", "c", "d", "e", "f"]

#
# These two constants are used if on the spot conversion from and to
# hexadecimal strings is needed.
# Note that Hex to Dec is designed to respond correctly to upper and lower
# case of 'a' to 'f'.
#

globals.py

(Header comment largely abbreviated, similar to constants)
# Globals declaration
#
# This file, which is also a top level initialization file, creates
# the global variables and sets them to default values.
# Global variables are variables that need to be accessed and
# often (but not always) changed by routines during the main program
# execution.
# Note: This file also contains certain option variables which would
# usually be changed via an option menu. Due to time constraints,
# the implementation of such a menu seems unlikely
#
# Globals are marked by the 'Global' prefix in the name (right
# after the 'DW' prefix, of course :) :) :) ).
#
# Map Variables
#

DW_Global_Basic_Map = []
x = 0
while (x < DW_Const_Max_Map_Width):
___ Helper = []
___ y = 0
___ while (y < DW_Const_Max_Map_Height):
_______ Helper.append("00")
_______ y = y + 1
___ DW_Global_Basic_Map.append(Helper)
___ x = x + 1

#
# The basic map data, provided as hex strings in a [x][y] array
#

#
# Options
#

DW_Global_Key_Delay = 500

#
# This global determines how many milliseconds input is being ignored
# after successful processing
#

mainmenu.py

(Comment abbrev. as usual) # Main Menu Class
#
# Currently, this will be used as a test file.
# Eventually, it will contain all routines relevant to the Main
# Menu of the game.
#
# Class definitions are marked by 'Class' following the 'DW' prefix.

class DW_Class_Main_Menu:
___ def __init__(self, DW_Window):
_______ self.DW_Parent = DW_Window
_______ self.DW_Current_Selection = 0
_______ self.DW_Max_Selection = 4
___ def DW_Up(self):
_______ if (self.DW_Current_Selection > 0):
___________ self.DW_Current_Selection = self.DW_Current_Selection - 1
_______ return True
___ def DW_Down(self):
_______ if (self.DW_Current_Selection < self.DW_Max_Selection):
___________ self.DW_Current_Selection = self.DW_Current_Selection + 1
_______ return True
___ def DW_Left(self):
_______ return False
___ def DW_Right(self):
_______ return False
___ def DW_Confirm(self):
_______ return False
___ def DW_Cancel(self):
_______ sys.exit()

mainwindow.py

(...)
# Main Window Class Definition
#
# This file contains the definition of the main window class which
# has only one instance which is created later within the single
# instance of the personalized Application class.
# Besides providing the basic output location, it links the input
# caught by the application to the routines in its children - well,
# actually, they just pass through, so this class is more like a
# container (^_^;;
#
# Class definitions are marked by 'Class' following the 'DW' prefix.

class DW_Class_Main_Window(wx.Frame):
___ def __init__(self): _______ wx.Frame.__init__(self, None, -1, "RPG")
_______ self.SetClientSizeWH(DW_Const_Screen_Width, DW_Const_Screen_Height)
_______ self.DW_Main_Panel = wx.Panel(self, -1)
_______ self.DW_Buffer = wx.MemoryDC()
_______ self.DW_Active = DW_Class_Main_Menu(self)
# self.Show()
_______ self.ShowFullScreen(True)

application.py

(...)
# Application Class Definition
#
# This file contains the definition of the application class for
# program. Programs (including this one) usually have only one
# instance of an application class.
# Besides being the container for the main window, the application
# will also be responsible for handling most input. Except for
# special cases like entry boxes, all input events will be
# here before being sent to the handling routines.
#
# Class definitions are marked by 'Class' following the 'DW' prefix.

class DW_Class_Application(wx.App):
___ def OnInit(self):
_______ """This routine effectively initializes the application."""
_______ self.DW_Main_Window = DW_Class_Main_Window()
# The main window is created
_______ self.SetTopWindow(self.DW_Main_Window)
# and explicitly defined as the top window
_______ self.Bind(wx.EVT_KEY_DOWN,self.OnKeyDown)
# Keyboard events are linked to the application's OnKeyDown event
_______ self.DW_Key_Lock = False # DW_Key_Lock states whether keyboard input is to be accepted.
# While it is true, no keyboard input will be handled by DW_Class_Application.
_______ return(True)

___ def DW_Unlock_Keys(self):
_______ self.DW_Key_Lock = False
# This tiny functions is called by a timer whenever there is a key lock
# The only thing it does is resetting DW_Key_Lock, thus lifting the key lock.

___ def OnKeyDown(self, DW_wx_event):
_______ """Handles mapped keyboard input for the application"""
_______ if (self.DW_Key_Lock):
___________ return
# If DW_Key_Lock is set, any input is ignored
_______ DW_Lock_Request = False
# The local variable DW_Lock_Request is used to store whether or not
# the input should be locked.
_______ DW_Code = DW_wx_event.GetKeyCode()
# The keycode is retrieved and
_______ if (DW_Code == wx.WXK_ESCAPE) or (DW_Code == wx.WXK_SPACE):
___________ DW_Lock_Request = self.DW_Main_Window.DW_Active.DW_Cancel()
_______ elif (DW_Code == wx.WXK_LEFT) or (DW_Code == wx.WXK_NUMPAD4):
___________ DW_Lock_Request = self.DW_Main_Window.DW_Active.DW_Left()
_______ elif (DW_Code == wx.WXK_RIGHT) or (DW_Code == wx.WXK_NUMPAD6):
___________ DW_Lock_Request = self.DW_Main_Window.DW_Active.DW_Right()
_______ elif (DW_Code == wx.WXK_DOWN) or (DW_Code == wx.WXK_NUMPAD2):
___________ DW_Lock_Request = self.DW_Main_Window.DW_Active.DW_Down()
_______ elif (DW_Code == wx.WXK_UP) or (DW_Code == wx.WXK_NUMPAD8):
___________ DW_Lock_Request = self.DW_Main_Window.DW_Active.DW_Up()
_______ elif (DW_Code == wx.WXK_RETURN) or (DW_Code == wx.WXK_NUMPAD5):
___________ DW_Lock_Request = self.DW_Main_Window.DW_Active.DW_Confirm()
# ... compared to various cases resulting in calls to the appropriate
# subroutines within the DW_Active object in the main window.
# This way, keyboard mapping happens only once, namely here, while
# each phase of the application can have its own behavior based on the
# commands mapped.
# If the called function wants to lock the keyboard, it should return
# True, otherwise False
_______ if (DW_Lock_Request):
___________ self.DW_Key_Lock = True
___________ wx.CallLater(DW_Global_Key_Delay,self.DW_Unlock_Keys)
# Finally, should there be a lock request, the keys are locked (that is
# a flag is set to cause this method to abort prematurely and a timer
# is set to call an unlocking method after a specified amount of
# milliseconds has passed (that value is stored in the global variable
# DW_Global_Key_Delay.

End of Code

Well, this is how far I got that far. Not really big, I know, but I am still optimistic. And putting it up here has cleared my head a bit. And maybe now it has become clearer why I like execfile (^_^;;

Deathworks

3 comments

The game of Allefant - Twisted

Posted by allefant on 2007/09/02 11:16

That's one twisted theme. I have an idea forming though - it will be kind of a shmup or platform, but with twisted (literally) levels. As you can see, so far I have the Allefant and a twisted line.

1 comment

Deathworks - Oh, what a start

Posted by Deathworks on 2007/09/02 10:05

Hi!

This was really terrific. I knew I couldn't get the theme until 11.00 local time (9.00 Greenwich), so until now, I didn't know what the theme was.

I had planned to sleep long, so I am well-rested and work throughout the night Sunday-Monday - but no, I woke up far too early and couldn't get back to sleep - so my concentration is kind of less than it would need to be.

Anyhow, since 6.00 (4.00), I have started developing the basic routines - or at least I tried.

First painful discovery was that __main__ did not allow me access to the globals as I thought it would. The global command doesn't allow being macroed out, so Python offers you really no choice in this entire affair. (Geesh, so I have to be extra-careful not to have any accidental locals wreak havoc).

Well, with that out of the way, it was time for me to pay first tribute to sleepiness: Wrong kind of brackets used in dictionary definition and it took me ages to notice the mistake.

So, the first few hours were not that splendid. Well, I guess this only means that things will get better :)

Anyhow, my method for centralizing keyboard (and later pad input) while allowing for individualization seems to be working fine.

Now that I know the theme, the next thing should be making a simple main menu screen (after determining the name for the game) and completely implementing the main menu (it is kind of half done, even without displaying anything, because I used to to test keyboard input)

Then a small dummy tile set and off to map mode module coding (well, at least I have already prepared one of the globals needed to hold the map data, so that is taken care of)

And finally, I think my head is finally clearing up. So, I may have had a bad start, but I am not out of the race yet. :) :)

Deathworks

Add a comment

Aurora Fighter - End of something

Posted by elachuni on 2007/09/02 09:43

Ok, I'm zonked. First sprint's over, we're off to bed. Quite happy to have something running already. Or moving, or showing, or something. Bed. Happy hacking to all, let the compo something!

Add a comment

Slider1000 - Day 1: Themes announcend, chaos begins

Posted by Zahmekoses on 2007/09/02 09:02

Well...

"Twisted".. *cough* . This was not what we had expected at all, this was the least preferred choice.
We had ideas for every theme (i.e. 5 different game ideas), but the idea for "Twisted" was more like an "We take this idea so that we have *SOMETHING* at least as idea for this theme" - bleh. >.<

After we knew the theme would be "Twisted" our idea looked a lot more lame than it already looked before, so we needed to start over with a new idea.

Sooo... after getting a nap (Themes were announced 2 am in the morning here..) we came up with an idea, but don't expect to much. The way it currently looks like, we could even FINISH this idea until... dunno... Tuesday?

...

Well, after all we then have plenty of time to make more out of this game OR even develop a better and more innovative game idea...

PyWeek 5 - We will finish this time!

1 comment

Rochester Vikings - Team versus Individual entry

Posted by paulreiners on 2007/09/02 07:13

How can I tell whether I'm entered as a team or an individual? Is an individual entry just a team with only one member? I want to be entered as an individual, but am not sure I did it right. Or does this not really matter this year since teams and individuals are judged together?

1 comment