Working with this list

Download Report

Transcript Working with this list

Games Development 2
Scripting for Games
CO3301
Week 5
Contents
•
•
•
•
Why Scripting
Scripting Considerations
Scripting Languages
Python: Language Overview
Why Scripting?
• Ease of Development
– Higher-level – less prone to errors
• E.g. no pointers, memory allocation etc.
– Less intricate - can be easier to write
• By less experienced developers and maybe technical designers
• Iteration Time
– Much quicker to change and test
– No recompilation, change at runtime
• Similar rationale to text-based data files
Why Scripting?
• Scripts as Assets
– Possible to regard scripts as a data resource to cut down on the
amount of game-specific embedded code
• Use scripts to control entity behaviour in particular
– Treat like any other resource, e.g. meshes, animations
• Script loaded with other entity assets
• Script support built into the resource manager
– Makes entity behaviour editable outside the compilation process
• For example, in a level editor
– Allows entity behaviour to be added/modified at a later stage
• Post-release modding
• Scripting languages can be quite powerful
– And customised for particular uses, e.g. AI
Scripting Drawbacks
• Performance
– Scripting languages are often interpreted
– Some are part-compiled into bytecode (like Java)
• Instructions for a virtual machine
– However, still poor performance compared to C++, ten times slower
or more
• No control of memory management can also cause issues
– Dynamic allocation of new variables
– Automatic garbage collection
– No control over timing, or amount of memory used
• Tool support sometimes limited, but much better now
• Errors can be hard to spot – usually occur at runtime
• Need to write (clumsy) interface to our C++
Scripting Considerations
• Performance may not be such an issue
– If scripting limited to high-level game logic
– Tricky if 1000's of scripted entities though
• Don't necessarily need to use scripting languages
– A simple, well defined game, with no need for modding
• Otherwise, consider language to use based on:
– Performance needs, memory footprint, feature-set
• Developer can write a custom scripting language
– E.g. UnrealScript
– Developing a new language is tricky and usually unnecessary only recommended for experts
Popular Scripting Languages
• Python is a portable, interpreted, object-oriented
programming language
– Mature, well-used language with clear syntax
– Notable for whitespace defining structure
– Used on several games, especially MMOs (e.g. EVE)
• Also built into Autodesk Maya and Max for plugin development
– Large memory use makes it a choice for more heavyweight games
• Lua is a lightweight scripting language
–
–
–
–
Not natively object-oriented
Small and simple feature-set
Small memory footprint
Very widely used, on PC and consoles
Python: Language Overview
• We will look at Python in this week’s lab
– Well suited to PC development
• Python is a complete, high-level OO language
– Reads a little like psuedo-code
• It is dynamically typed
– No need to declare variable types
• It performs automatic garbage collection
– No need to new / delete objects
– No pointers
• Blocks are defined by indentation
– No braces (curly brackets)
Python: Variables / Blocks
• Variable use (no types, equate several at once, no
semicolons):
x,y,z = 1,2,3
first, second = second, first
a = b = 123
• Indentation defines blocks (plus logical operators):
if x < 5 or (x
print "The
if x < 5 or 10
print "The
> 10 and x < 20):
value is OK"
< x < 20:
value is OK"
Python: Iteration / Input
• Loops (and comments):
for i in [1,2,3,4,5]:
print "Iteration number", i
# Print values from 0-99 inclusive
for value in range(100):
print value
x = 10
while x >= 0:
print "x is not negative"
x = x – 1
• Simple input:
x = input("Please enter a number: ")
print "The square of that number is", x*x
Python: Lists
• Lists, indexing and slicing
fruit
print
print
print
= ["plum", "pear", "apple", "banana", "fig"]
fruit[2], fruit[0] # Prints "apple plum"
fruit[-2] # Prints "banana" (counts from end)
len(fruit) # Prints "5"
# Slicing is selecting sections of a list
# Note: 1st example excludes last index in range
print fruit[1:3] # Prints "pear apple"
print fruit[:3] # Prints "plum pear apple"
print fruit[3:] # Prints "banana fig"
• Strings can be treated as read-only lists
x = "apple"
print x[3] # Prints "l"
x[0] = "e" # Error
Python: Dictionaries / Functions
• A dictionary is a map
tel = {"Joe":123, "Jim":555, "Jane":999}
person = {'Job':'Builder', 'DOB':'12/12/66'} # '="
print tel["Jane"] # Prints 999
print person["Job"] # Prints "Builder"
• Functions (use keyword def):
def Square(x):
return x*x
print Square(3)
Python: Functions
• Simple parameters are passed by value
def square(x):
x = x*x
return x
y = 3
print square(y), y # Prints "9 3", y unchanged by fn
• But lists / dictionaries are affected in a function
def change_list(l):
l[0] = "apple"
fruit = ["pear", "orange", "fig"]
change_list(fruit)
print fruit # Prints "apple orange fig"
Python: Strings
• Wide range of string support:
# Basic operations
print 'Hello ' + 'World' # Hello World
print "Spam "*4
# Spam Spam Spam Spam
# Strings can’t be written to – easy to get round
str = "Hello World"
newstr = 'M' + str[2:] # Mello World
# Example of other methods
print len( "Piece of String" ) # Output 15
print "london".capitalize()
# Output London
print "too times too".replace( "too", "two" )
# Output two times two
folderlist = "C:\Work\Python".split("\\")
# folderlist = ["C:", "Work", "Python“]
Further Conditions
• More Conditions
# Set membership
primes = [1,2,3,5,7,11,13,17,19,23,29]
if x in primes:
print "x is prime"
if year not in range(2000, 2100, 4): # 2000->2100 step 4
print "Not a leap year"
# String / List comparison
"one" < "two" # true – lexicographical comparison
[1,2,3] < [1,2,4] # Compare elements
[1,3] < [1,2,3]
# Shorter list always less than
Working with Lists
• List operations
# Working with this list
a = [66.25, 333, 333, 1, 1234.5]
# Counting instances of a value
print a.count(333), a.count(66.25), a.count('x')
# Output: 2 1 0
# Insertion (anywhere), appending (at the end)
a.insert(2, -1) # Location, value
a.append(333)
print a
# Output [66.25, 333, -1, 333, 1, 1234.5, 333]
Working with Lists
• More list operations
# Working with this list
a = [66.25, 333, -1, 333, 1, 1234.5, 333]
# Removal (by location)
x = a.pop() # Remove last element
y = a.pop(2) # Remove specific element
print a, x, y
# Output [66.25, 333, 333, 1, 1234.5] 333 -1
# Removal (by value)
a.remove(333) # Remove first instance of 333
print a
# Output[66.25, 333, 1, 1234.5]
Working with Lists
• List reordering
# Working with this list
a = [66.25, 333, 1, 1234.5]
# Reversal
a.reverse()
print a
# Output [1234.5, 1, 333, 66.25]
# Sorting
a.sort()
print a
# Output[1, 66.25, 333, 1234.5]
Functional List Creation
• List creation using functions
# map – applies function to list elts to create new list
def Square(x): return x*x
print map(Square, range(1, 11))
# Output [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# filter – uses
def NotDiv3(x):
filter(NotDiv3,
# Output [1, 2,
boolean function to filter elts in a list
return x % 3 != 0
range(1, 15))
4, 5, 7, 8, 10, 11, 13, 14]
# List comprehension – powerful list creation
def Square(x): return x*x
primes = [1,2,3,5,7,11,13,17,19,23,29]
print [Square(x) for x in primes if x%10 < 5]
# Output [1,4,9,121,169,529]
Function Techniques
• More function techniques
# Argument passing by name
def AddRecord( name, ID = 0, job = "Unemployed” ):
...
AddRecord( "Bill", 5 ) # Normal style
AddRecord( job="Builder", name="Bob" ) # By name
# Argument unpacking
def VectorLength( x, y ):
...
vector = (10, 15)
print VectorLength( *vector ) # * unpacks 1 argument to 2
# Documentation – first line can be string literal
def Square(x):
"Returns the square of the argument"
return x*x
Libraries
• Can import support libraries:
# Mathematics – as in C
import math
print math.cos( math.pi / 3 ) # Output 0.5
# Random numbers
import random
print random.choice(['apple', 'pear', 'banana'])
print random.random()
# random float 0-1
print random.randrange(6) # random integer from 0-5
# 5 random samples from list, e.g. [30,83,16,4,8]
print random.sample(range(100), 5)
Python: Classes
• Class definition (each fn has extra 'self' argument):
class Person:
# __init__ is a constructor
__init__(self, name, job="Unemployed"):# Default
self.name = name
self.job = job
def output(self):
print self.name, "the", self.job
guy1 = Person("Bob", "Builder")
guy2 = Person("Bill")
guy1.output() # Prints "Bob the Builder"
guy2.output() # Prints "Bill the Unemployed"