Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Side by Side Diff: sky/examples/game/lib/game_demo_world.dart

Issue 1218593002: Move sky/examples to sky/sdk/lib/example, and code changes to support that change. Fixes T277. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 part of game;
2
3 const double _steeringThreshold = 0.0;
4 const double _steeringMax = 150.0;
5
6 // Random generator
7 Math.Random _rand = new Math.Random();
8
9 const double _gameSizeWidth = 1024.0;
10 const double _gameSizeHeight = 1024.0;
11
12 const double _shipRadius = 30.0;
13 const double _lrgAsteroidRadius = 40.0;
14 const double _medAsteroidRadius = 20.0;
15 const double _smlAsteroidRadius = 10.0;
16 const double _maxAsteroidSpeed = 1.0;
17
18 const int _lifeTimeLaser = 50;
19
20 const int _numStarsInStarField = 150;
21
22 class GameDemoWorld extends NodeWithSize {
23
24 // Images
25 Image _imgNebula;
26
27 SpriteSheet _spriteSheet;
28
29 // Inputs
30 double _joystickX = 0.0;
31 double _joystickY = 0.0;
32 bool _fire;
33
34 Node _gameLayer;
35
36 Ship _ship;
37 List<Asteroid> _asteroids = [];
38 List<Laser> _lasers = [];
39 StarField _starField;
40 Nebula _nebula;
41
42 GameDemoWorld(ImageMap images, this._spriteSheet) : super(new Size(_gameSizeWi dth, _gameSizeHeight)) {
43
44 // Fetch images
45 _imgNebula = images["res/nebula.png"];
46
47 _gameLayer = new Node();
48 this.addChild(_gameLayer);
49
50 // Add some asteroids to the game world
51 for (int i = 0; i < 5; i++) {
52 addAsteroid(AsteroidSize.large);
53 }
54 for (int i = 0; i < 5; i++) {
55 addAsteroid(AsteroidSize.medium);
56 }
57
58 // Add ship
59 addShip();
60
61 // Add starfield
62 _starField = new StarField(_spriteSheet["star.png"], _numStarsInStarField);
63 _starField.zPosition = -2.0;
64 addChild(_starField);
65
66 // Add nebula
67 addNebula();
68
69 userInteractionEnabled = true;
70 handleMultiplePointers = true;
71 }
72
73 // Methods for adding game objects
74
75 void addAsteroid(AsteroidSize size, [Point pos]) {
76 Asteroid asteroid = new Asteroid(_spriteSheet["asteroid_big_1.png"], size);
77 asteroid.zPosition = 1.0;
78 if (pos != null) asteroid.position = pos;
79 _gameLayer.addChild(asteroid);
80 _asteroids.add(asteroid);
81 }
82
83 void addShip() {
84 Ship ship = new Ship(_spriteSheet["ship.png"]);
85 ship.zPosition = 10.0;
86 _gameLayer.addChild(ship);
87 _ship = ship;
88 }
89
90 void addLaser() {
91 Laser laser = new Laser(_spriteSheet["laser.png"], _ship);
92 laser.zPosition = 8.0;
93 _lasers.add(laser);
94 _gameLayer.addChild(laser);
95 }
96
97 void addNebula() {
98 _nebula = new Nebula.withImage(_imgNebula);
99 _gameLayer.addChild(_nebula);
100 }
101
102 void update(double dt) {
103 // Move asteroids
104 for (Asteroid asteroid in _asteroids) {
105 asteroid.position = pointAdd(asteroid.position, asteroid._movementVector);
106 }
107
108 // Move lasers and remove expired lasers
109 for (int i = _lasers.length - 1; i >= 0; i--) {
110 Laser laser = _lasers[i];
111 laser.move();
112 if (laser._frameCount > _lifeTimeLaser) {
113 laser.removeFromParent();
114 _lasers.removeAt(i);
115 }
116 }
117
118 // Apply thrust to ship
119 if (_joystickX != 0.0 || _joystickY != 0.0) {
120 _ship.thrust(_joystickX, _joystickY);
121 }
122
123 // Move ship
124 _ship.move();
125
126 // Check collisions between asteroids and lasers
127 for (int i = _lasers.length -1; i >= 0; i--) {
128 // Iterate over all the lasers
129 Laser laser = _lasers[i];
130
131 for (int j = _asteroids.length - 1; j >= 0; j--) {
132 // Iterate over all the asteroids
133 Asteroid asteroid = _asteroids[j];
134
135 // Check for collision
136 if (pointQuickDist(laser.position, asteroid.position) < laser.radius + a steroid.radius) {
137 // Remove laser
138 laser.removeFromParent();
139 _lasers.removeAt(i);
140
141 // Add asteroids
142 if (asteroid._asteroidSize == AsteroidSize.large) {
143 for (int a = 0; a < 3; a++) addAsteroid(AsteroidSize.medium, asteroi d.position);
144 }
145 else if (asteroid._asteroidSize == AsteroidSize.medium) {
146 for (int a = 0; a < 5; a++) addAsteroid(AsteroidSize.small, asteroid .position);
147 }
148
149 // Remove asteroid
150 asteroid.removeFromParent();
151 _asteroids.removeAt(j);
152 break;
153 }
154 }
155 }
156
157 // Move objects to center camera and warp objects around the edges
158 centerCamera();
159 warpObjects();
160 }
161
162 void centerCamera() {
163 const cameraDampening = 0.1;
164 Point delta = new Point(_gameSizeWidth/2 - _ship.position.x, _gameSizeHeight /2 - _ship.position.y);
165 delta = pointMult(delta, cameraDampening);
166
167 for (Node child in _gameLayer.children) {
168 child.position = pointAdd(child.position, delta);
169 }
170
171 // Update starfield
172 _starField.move(delta.x, delta.y);
173 }
174
175 void warpObjects() {
176 for (Node child in _gameLayer.children) {
177 if (child.position.x < 0) child.position = pointAdd(child.position, new Po int(_gameSizeWidth, 0.0));
178 if (child.position.x >= _gameSizeWidth) child.position = pointAdd(child.po sition, new Point(-_gameSizeWidth, 0.0));
179 if (child.position.y < 0) child.position = pointAdd(child.position, new Po int(0.0, _gameSizeHeight));
180 if (child.position.y >= _gameSizeHeight) child.position = pointAdd(child.p osition, new Point(0.0, -_gameSizeHeight));
181 }
182 }
183
184 // Handling controls
185
186 void controlSteering(double x, double y) {
187 _joystickX = x;
188 _joystickY = y;
189 }
190
191 void controlFire() {
192 addLaser();
193 }
194
195 // Handle pointer events
196
197 int _firstPointer = -1;
198 int _secondPointer = -1;
199 Point _firstPointerDownPos;
200
201 bool handleEvent(SpriteBoxEvent event) {
202 Point pointerPos = convertPointToNodeSpace(event.boxPosition);
203 int pointer = event.pointer;
204
205 switch (event.type) {
206 case 'pointerdown':
207 if (_firstPointer == -1) {
208 // Assign the first pointer
209 _firstPointer = pointer;
210 _firstPointerDownPos = pointerPos;
211 }
212 else if (_secondPointer == -1) {
213 // Assign second pointer
214 _secondPointer = pointer;
215 controlFire();
216 }
217 else {
218 // There is a pointer used for steering, let's fire instead
219 controlFire();
220 }
221 break;
222 case 'pointermove':
223 if (pointer == _firstPointer) {
224 // Handle turning control
225 double joystickX = 0.0;
226 double deltaX = pointerPos.x - _firstPointerDownPos.x;
227 if (deltaX > _steeringThreshold || deltaX < -_steeringThreshold) {
228 joystickX = (deltaX - _steeringThreshold)/(_steeringMax - _steeringT hreshold);
229 if (joystickX > 1.0) joystickX = 1.0;
230 if (joystickX < -1.0) joystickX = -1.0;
231 }
232
233 double joystickY = 0.0;
234 double deltaY = pointerPos.y - _firstPointerDownPos.y;
235 if (deltaY > _steeringThreshold || deltaY < -_steeringThreshold) {
236 joystickY = (deltaY - _steeringThreshold)/(_steeringMax - _steeringT hreshold);
237 if (joystickY > 1.0) joystickY = 1.0;
238 if (joystickY < -1.0) joystickY = -1.0;
239 }
240
241 controlSteering(joystickX, joystickY);
242 }
243 break;
244 case 'pointerup':
245 case 'pointercancel':
246 if (pointer == _firstPointer) {
247 // Un-assign the first pointer
248 _firstPointer = -1;
249 _firstPointerDownPos = null;
250 controlSteering(0.0, 0.0);
251 }
252 else if (pointer == _secondPointer) {
253 _secondPointer = -1;
254 }
255 break;
256 default:
257 break;
258 }
259 return true;
260 }
261 }
262
263 // Game objects
264
265 enum AsteroidSize {
266 small,
267 medium,
268 large,
269 }
270
271 class Asteroid extends Sprite {
272 Point _movementVector;
273 AsteroidSize _asteroidSize;
274 double _radius;
275
276 double get radius {
277 if (_radius != null) return _radius;
278 if (_asteroidSize == AsteroidSize.small) _radius = _smlAsteroidRadius;
279 else if (_asteroidSize == AsteroidSize.medium) _radius = _medAsteroidRadius;
280 else if (_asteroidSize == AsteroidSize.large) _radius = _lrgAsteroidRadius;
281 return _radius;
282 }
283
284 Asteroid(Texture img, AsteroidSize this._asteroidSize) : super(img) {
285 size = new Size(radius * 2.0, radius * 2.0);
286 position = new Point(_gameSizeWidth * _rand.nextDouble(), _gameSizeHeight * _rand.nextDouble());
287 rotation = 360.0 * _rand.nextDouble();
288
289 _movementVector = new Point(_rand.nextDouble() * _maxAsteroidSpeed * 2 - _ma xAsteroidSpeed,
290 _rand.nextDouble() * _maxAsteroidSpeed * 2 - _ma xAsteroidSpeed);
291
292 userInteractionEnabled = true;
293 }
294
295 bool handleEvent(SpriteBoxEvent event) {
296 if (event.type == "pointerdown") {
297 colorOverlay = new Color(0x99ff0000);
298 }
299 else if (event.type == "pointerup") {
300 colorOverlay = null;
301 }
302 return false;
303 }
304 }
305
306 class Ship extends Sprite {
307 Vector2 _movementVector;
308 double _rotationTarget;
309
310 Ship(Texture img) : super(img) {
311 _movementVector = new Vector2.zero();
312 rotation = _rotationTarget = 270.0;
313
314 // Create sprite
315 size = new Size(_shipRadius * 2.0, _shipRadius * 2.0);
316 position = new Point(_gameSizeWidth/2.0, _gameSizeHeight/2.0);
317 }
318
319 void thrust(double x, double y) {
320 _rotationTarget = convertRadians2Degrees(Math.atan2(y, x));
321 Vector2 directionVector = new Vector2(x, y).normalize();
322 _movementVector.addScaled(directionVector, 1.0);
323 }
324
325 void move() {
326 position = new Point(position.x + _movementVector[0], position.y + _movement Vector[1]);
327 _movementVector.scale(0.9);
328
329 rotation = dampenRotation(rotation, _rotationTarget, 0.1);
330 }
331 }
332
333 class Laser extends Sprite {
334 int _frameCount = 0;
335 Point _movementVector;
336 double radius = 10.0;
337
338 Laser(Texture img, Ship ship) : super(img) {
339 size = new Size(20.0, 20.0);
340 position = ship.position;
341 rotation = ship.rotation + 90.0;
342 transferMode = TransferMode.plus;
343 double rotRadians = convertDegrees2Radians(rotation);
344 _movementVector = pointMult(new Point(Math.sin(rotRadians), -Math.cos(rotRad ians)), 10.0);
345 _movementVector = new Point(_movementVector.x + ship._movementVector[0], _mo vementVector.y + ship._movementVector[1]);
346 }
347
348 void move() {
349 position = pointAdd(position, _movementVector);
350 _frameCount++;
351 }
352 }
353
354 // Background starfield
355
356 class StarField extends Node {
357 Texture _img;
358 int _numStars;
359 List<Point> _starPositions;
360 List<double> _starScales;
361 List<double> _opacity;
362
363 StarField(this._img, this._numStars) {
364 _starPositions = [];
365 _starScales = [];
366 _opacity = [];
367
368 for (int i = 0; i < _numStars; i++) {
369 _starPositions.add(new Point(_rand.nextDouble() * _gameSizeWidth, _rand.ne xtDouble() * _gameSizeHeight));
370 _starScales.add(_rand.nextDouble());
371 _opacity.add(_rand.nextDouble() * 0.5 + 0.5);
372 }
373 }
374
375 void paint(RenderCanvas canvas) {
376 // Setup paint object for opacity and transfer mode
377 Paint paint = new Paint();
378 paint.setTransferMode(TransferMode.plus);
379
380 double baseScaleX = 32.0 / _img.size.width;
381 double baseScaleY = 32.0 / _img.size.height;
382
383 // Draw each star
384 for (int i = 0; i < _numStars; i++) {
385 Point pos = _starPositions[i];
386 double scale = _starScales[i];
387 paint.color = new Color.fromARGB((255.0*_opacity[i]).toInt(), 255, 255, 25 5);
388
389 canvas.save();
390
391 canvas.translate(pos.x, pos.y);
392 canvas.scale(baseScaleX * scale, baseScaleY * scale);
393
394 canvas.drawImageRect(_img.image, _img.frame, _img.spriteSourceSize, paint) ;
395
396 canvas.restore();
397 }
398 }
399
400 void move(double dx, double dy) {
401 for (int i = 0; i < _numStars; i++) {
402 double xPos = _starPositions[i].x;
403 double yPos = _starPositions[i].y;
404 double scale = _starScales[i];
405
406 xPos += dx * scale;
407 yPos += dy * scale;
408
409 if (xPos >= _gameSizeWidth) xPos -= _gameSizeWidth;
410 if (xPos < 0) xPos += _gameSizeWidth;
411 if (yPos >= _gameSizeHeight) yPos -= _gameSizeHeight;
412 if (yPos < 0) yPos += _gameSizeHeight;
413
414 _starPositions[i] = new Point(xPos, yPos);
415 }
416 }
417 }
418
419 class Nebula extends Node {
420
421 Nebula.withImage(Image img) {
422 for (int i = 0; i < 2; i++) {
423 for (int j = 0; j < 2; j++) {
424 Sprite sprt = new Sprite.fromImage(img);
425 sprt.pivot = Point.origin;
426 sprt.position = new Point(i * _gameSizeWidth - _gameSizeWidth, j * _game SizeHeight - _gameSizeHeight);
427 addChild(sprt);
428 }
429 }
430 }
431 }
432
433 // Convenience methods
434
435 Point pointAdd(Point a, Point b) {
436 return new Point(a.x+ b.x, a.y + b.y);
437 }
438
439 Point pointMult(Point a, double multiplier) {
440 return new Point(a.x * multiplier, a.y * multiplier);
441 }
442
443 double dampenRotation(double src, double dst, double dampening) {
444 double delta = dst - src;
445 while (delta > 180.0) delta -= 360;
446 while (delta < -180) delta += 360;
447 delta *= dampening;
448
449 return src + delta;
450 }
451
452 double pointQuickDist(Point a, Point b) {
453 double dx = a.x - b.x;
454 double dy = a.y - b.y;
455 if (dx < 0.0) dx = -dx;
456 if (dy < 0.0) dy = -dy;
457 if (dx > dy) {
458 return dx + dy/2.0;
459 }
460 else {
461 return dy + dx/2.0;
462 }
463 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698