/
intro.py
185 lines (137 loc) · 5.32 KB
/
intro.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
import os
import xml.etree.ElementTree as ET
import pygame
import settings
import game_select
import scene
import sound
import game_input
import data
class Intro(scene.Scene):
"""The main intro scene."""
def __init__(self, screen):
"""
Load all intro screens and start the first.
screen - the screen to blit to.
"""
#store screen for use later
self.screen = screen
#parse the intro XML file
fn = os.path.join(settings.path, "data", "intro.xml")
root = data.getTreeRoot(fn, "Ditto main")
#create each intro screen
self.introScreens = []
for s in data.getChildren(root, "screen"):
self.introScreens.append(IntroScreen(screen, s))
#set the first screen active
self.current = 0
self.activeScreen = self.introScreens[self.current]
self.activeScreen.onShow()
def giveInput(self, inputData):
"""
Recieve input data.
inputData - the input data 3-tuple.
"""
#we're only bothered about keydowns
self.keysJustPressed = inputData[1]
def drawFrame(self):
"""Draw a frame to the screen."""
#call on the active screen to draw itself
self.activeScreen.drawFrame()
def tick(self):
"""Update the intro one frame."""
#tick the active screen, find out whethe it's done
done = self.activeScreen.tick()
#if button A has been pressed, the current screen is done
for key in self.keysJustPressed:
if key == game_input.BT_A:
done = True
#if the current screen is done, move on to the next
#if there are no more, return True to say we're done
#otherwise load the next one
if done:
self.current += 1
if self.current >= len(self.introScreens):
return True
else:
self.activeScreen = self.introScreens[self.current]
self.activeScreen.onShow()
#we're still going
return False
def getNext(self):
"""Get the next game scene."""
#return the game select scene
return game_select.GameSelect(self.screen)
class IntroScreen():
"""A single intro screen."""
def __init__(self, screen, node):
"""
Set up the screen - load any images and play any music.
screen - the screen to blit to.
node - the <screen> node.
"""
#store the screen for later
self.screen = screen
#set up the timer
#time of -1 means no time limit
self.time = data.getAttr(node, "time", data.D_INT)
self.count = 0
self.trackTime = (self.time != -1)
#find out the background color
#use american spelling of color by convention
self.bgColor = data.getAttr(node, "bgcolor", data.D_INT3LIST)
#find the music to play if any
self.music = None
for track in data.getChildren(node, "music"):
self.music = os.path.join(settings.path, "data", data.getAttr(track, "file", data.D_STRING))
#load all images
self.images = []
for image in data.getChildren(node, "image"):
self.images.append(IntroImage(self.screen, image))
def onShow(self):
"""Called when the screen is actually shown for the first time."""
#if there is any music to play, play it
if self.music is not None:
sound.playMusic(self.music)
def drawFrame(self):
"""Draw a frame to the screen."""
#fill the screen with the background color
self.screen.fill(self.bgColor)
#draw all images
for image in self.images:
image.draw()
def tick(self):
"""Advance the screen one frame."""
#if we're keeping time, increase the count
if self.trackTime:
self.count += 1
#if we've reached the end of our time, return True to indicate we've finished.
#else return False
if (self.count >= self.time) and self.trackTime:
return True
else:
return False
class IntroImage():
"""Class to represent a single image shown on an intro screen."""
def __init__(self, screen, node):
"""Load the image and determine it's position."""
#store screen for later
self.screen = screen
#open the image
fn = os.path.join(settings.path, "data", data.getAttr(node, "file", data.D_STRING))
self.image = data.getImage(fn, "Intro file.").convert(self.screen)
transparency = data.getAttr(node, "transparency", data.D_INT3LIST)
self.image.set_colorkey(transparency)
#calculate where the centres are for the screen and the image
screenCentre = self.screen.get_width()/2, self.screen.get_height()/2
imageCentre = self.image.get_width()/2, self.image.get_height()/2
#find out the location of the image
location = data.getAttr(node, "location", data.D_INT2LIST)
#calculate its position on the screen
#location (0,0) should be dead centre, (-100, 100) bottom left
self.position = ((screenCentre[0]-imageCentre[0])+((location[0]*screenCentre[0])/100),
(screenCentre[1]-imageCentre[1])+((location[1]*screenCentre[1])/100))
def draw(self):
"""Draw a frame to the screen."""
#draw the image in the required place
self.screen.blit(self.image, self.position)