Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
a78370fe
Commit
a78370fe
authored
Aug 19, 2015
by
Viktor Lidholt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New game demo, initial version
parent
1393b4c6
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
826 additions
and
763 deletions
+826
-763
game_demo.dart
examples/game/lib/game_demo.dart
+2
-1
game_demo_node.dart
examples/game/lib/game_demo_node.dart
+784
-0
game_demo_world.dart
examples/game/lib/game_demo_world.dart
+0
-752
main.dart
examples/game/lib/main.dart
+23
-10
util.dart
examples/game/lib/util.dart
+17
-0
No files found.
examples/game/lib/game_demo.dart
View file @
a78370fe
library
game
;
library
game
;
import
'dart:async'
;
import
'dart:sky'
as
sky
;
import
'dart:sky'
as
sky
;
import
'dart:math'
as
Math
;
import
'dart:math'
as
Math
;
import
'sprites.dart'
;
import
'sprites.dart'
;
...
@@ -10,4 +11,4 @@ import 'package:sky/widgets/navigator.dart';
...
@@ -10,4 +11,4 @@ import 'package:sky/widgets/navigator.dart';
import
'package:sky/animation/curves.dart'
;
import
'package:sky/animation/curves.dart'
;
import
'package:vector_math/vector_math_64.dart'
;
import
'package:vector_math/vector_math_64.dart'
;
part
'game_demo_
world
.dart'
;
part
'game_demo_
node
.dart'
;
examples/game/lib/game_demo_node.dart
0 → 100644
View file @
a78370fe
part of
game
;
final
double
_gameSizeWidth
=
320.0
;
double
_gameSizeHeight
=
320.0
;
final
bool
_drawDebug
=
false
;
class
GameDemoNode
extends
NodeWithSize
{
GameDemoNode
(
this
.
_images
,
this
.
_spritesGame
,
this
.
_spritesUI
,
this
.
_sounds
,
this
.
_gameOverCallback
):
super
(
new
Size
(
320.0
,
320.0
))
{
// Add background
_background
=
new
RepeatedImage
(
_images
[
"assets/starfield.png"
]);
addChild
(
_background
);
// Create starfield
_starField
=
new
StarField
(
_spritesGame
,
200
);
addChild
(
_starField
);
// Add nebula
_nebula
=
new
RepeatedImage
(
_images
[
"assets/nebula.png"
],
sky
.
TransferMode
.
plus
);
addChild
(
_nebula
);
// Setup game screen, it will always be anchored to the bottom of the screen
_gameScreen
=
new
Node
();
addChild
(
_gameScreen
);
// Setup the level and add it to the screen, the level is the node where
// all our game objects live. It is moved to scroll the game
_level
=
new
Level
();
_gameScreen
.
addChild
(
_level
);
_objectFactory
=
new
GameObjectFactory
(
_spritesGame
,
_sounds
,
_level
);
_level
.
ship
=
new
Ship
(
_objectFactory
);
_level
.
addChild
(
_level
.
ship
);
// Add the joystick
_joystick
=
new
VirtualJoystick
();
_gameScreen
.
addChild
(
_joystick
);
// Add HUD
_hud
=
new
Hud
(
_spritesUI
);
addChild
(
_hud
);
addObjects
();
}
// Resources
ImageMap
_images
;
Map
<
String
,
SoundEffect
>
_sounds
;
SpriteSheet
_spritesGame
;
SpriteSheet
_spritesUI
;
// Sounds
SoundEffectPlayer
_effectPlayer
=
SoundEffectPlayer
.
sharedInstance
();
// Callback
Function
_gameOverCallback
;
// Game screen nodes
Node
_gameScreen
;
VirtualJoystick
_joystick
;
GameObjectFactory
_objectFactory
;
Level
_level
;
StarField
_starField
;
RepeatedImage
_background
;
RepeatedImage
_nebula
;
Hud
_hud
;
// Game properties
double
_scrollSpeed
=
2.0
;
double
_scroll
=
0.0
;
int
_framesToFire
=
0
;
int
_framesBetweenShots
=
20
;
bool
_gameOver
=
false
;
void
spriteBoxPerformedLayout
()
{
_gameSizeHeight
=
spriteBox
.
visibleArea
.
height
;
_gameScreen
.
position
=
new
Point
(
0.0
,
_gameSizeHeight
);
}
void
update
(
double
dt
)
{
// Scroll the level
_scroll
=
_level
.
scroll
(
_scrollSpeed
);
_starField
.
move
(
0.0
,
_scrollSpeed
);
_background
.
move
(
_scrollSpeed
*
0.1
);
_nebula
.
move
(
_scrollSpeed
);
// Add objects
addObjects
();
// Move the ship
if
(!
_gameOver
)
{
_level
.
ship
.
applyThrust
(
_joystick
.
value
,
_scroll
);
}
// Add shots
if
(
_framesToFire
==
0
&&
_joystick
.
isDown
&&
!
_gameOver
)
{
fire
();
_framesToFire
=
_framesBetweenShots
;
}
if
(
_framesToFire
>
0
)
_framesToFire
--;
// Move game objects
for
(
Node
node
in
_level
.
children
)
{
if
(
node
is
GameObject
)
{
node
.
move
();
}
}
// Remove offscreen game objects
for
(
int
i
=
_level
.
children
.
length
-
1
;
i
>=
0
;
i
--)
{
Node
node
=
_level
.
children
[
i
];
if
(
node
is
GameObject
)
{
node
.
removeIfOffscreen
(
_scroll
);
}
}
if
(
_gameOver
)
return
;
// Check for collisions between lasers and objects that can take damage
List
<
Laser
>
lasers
=
[];
for
(
Node
node
in
_level
.
children
)
{
if
(
node
is
Laser
)
lasers
.
add
(
node
);
}
List
<
GameObject
>
damageables
=
[];
for
(
Node
node
in
_level
.
children
)
{
if
(
node
is
GameObject
&&
node
.
canBeDamaged
)
damageables
.
add
(
node
);
}
for
(
Laser
laser
in
lasers
)
{
for
(
GameObject
damageable
in
damageables
)
{
if
(
laser
.
collidingWith
(
damageable
))
{
// Hit something that can take damage
_hud
.
score
+=
damageable
.
addDamage
(
laser
.
impact
);
laser
.
destroy
();
}
}
}
// Check for collsions between ship and objects that can damage the ship
List
<
Node
>
nodes
=
new
List
.
from
(
_level
.
children
);
for
(
Node
node
in
nodes
)
{
if
(
node
is
GameObject
&&
node
.
canDamageShip
)
{
if
(
node
.
collidingWith
(
_level
.
ship
))
{
// The ship was hit :(
killShip
();
_level
.
ship
.
visible
=
false
;
}
}
}
}
int
_chunk
=
0
;
double
_chunkSpacing
=
640.0
;
void
addObjects
()
{
while
(
_scroll
+
_chunkSpacing
>=
_chunk
*
_chunkSpacing
)
{
addLevelChunk
(
_chunk
,
-
_chunk
*
_chunkSpacing
-
_chunkSpacing
);
_chunk
+=
1
;
}
}
void
addLevelChunk
(
int
chunk
,
double
yPos
)
{
if
(
chunk
==
0
)
{
// Leave the first chunk empty
return
;
}
else
if
(
chunk
==
1
)
{
addLevelAsteroids
(
10
,
yPos
,
0.0
);
}
else
{
addLevelAsteroids
(
9
+
chunk
,
yPos
,
0.5
);
}
}
void
addLevelAsteroids
(
int
numAsteroids
,
double
yPos
,
double
distribution
)
{
for
(
int
i
=
0
;
i
<
numAsteroids
;
i
++)
{
GameObjectType
type
=
(
randomDouble
()
<
distribution
)
?
GameObjectType
.
asteroidBig
:
GameObjectType
.
asteroidSmall
;
Point
pos
=
new
Point
(
randomSignedDouble
()
*
160.0
,
yPos
+
_chunkSpacing
*
randomDouble
());
_objectFactory
.
addGameObject
(
type
,
pos
);
}
}
void
fire
()
{
Laser
shot0
=
new
Laser
(
_objectFactory
);
shot0
.
position
=
_level
.
ship
.
position
+
new
Offset
(
17.0
,
-
10.0
);
_level
.
addChild
(
shot0
);
Laser
shot1
=
new
Laser
(
_objectFactory
);
shot1
.
position
=
_level
.
ship
.
position
+
new
Offset
(-
17.0
,
-
10.0
);
_level
.
addChild
(
shot1
);
_effectPlayer
.
play
(
_sounds
[
"laser"
]);
}
void
killShip
()
{
// Hide ship
_level
.
ship
.
visible
=
false
;
_effectPlayer
.
play
(
_sounds
[
"explosion"
]);
// Add explosion
Explosion
explo
=
new
Explosion
(
_spritesGame
);
explo
.
scale
=
1.5
;
explo
.
position
=
_level
.
ship
.
position
;
_level
.
addChild
(
explo
);
// Add flash
Flash
flash
=
new
Flash
(
size
,
1.0
);
addChild
(
flash
);
// Set the state to game over
_gameOver
=
true
;
// Return to main scene and report the score back in 2 seconds
new
Timer
(
new
Duration
(
seconds:
2
),
()
{
_gameOverCallback
(
_hud
.
score
);
});
}
}
class
VirtualJoystick
extends
NodeWithSize
{
VirtualJoystick
()
:
super
(
new
Size
(
160.0
,
160.0
))
{
userInteractionEnabled
=
true
;
handleMultiplePointers
=
false
;
position
=
new
Point
(
160.0
,
-
20.0
);
pivot
=
new
Point
(
0.5
,
1.0
);
_center
=
new
Point
(
size
.
width
/
2.0
,
size
.
height
/
2.0
);
_handlePos
=
_center
;
_paintHandle
=
new
Paint
()
..
color
=
new
Color
(
0xffffffff
);
_paintControl
=
new
Paint
()
..
color
=
new
Color
(
0xffffffff
)
..
strokeWidth
=
1.0
..
setStyle
(
sky
.
PaintingStyle
.
stroke
);
}
Point
value
=
Point
.
origin
;
bool
_isDown
=
false
;
bool
get
isDown
=>
_isDown
;
Point
_pointerDownAt
;
Point
_center
;
Point
_handlePos
;
Paint
_paintHandle
;
Paint
_paintControl
;
bool
handleEvent
(
SpriteBoxEvent
event
)
{
if
(
event
.
type
==
"pointerdown"
)
{
_pointerDownAt
=
event
.
boxPosition
;
actions
.
stopAll
();
_isDown
=
true
;
}
else
if
(
event
.
type
==
"pointerup"
||
event
.
type
==
"pointercancel"
)
{
_pointerDownAt
=
null
;
value
=
Point
.
origin
;
ActionTween
moveToCenter
=
new
ActionTween
((
a
)
=>
_handlePos
=
a
,
_handlePos
,
_center
,
0.4
,
elasticOut
);
actions
.
run
(
moveToCenter
);
_isDown
=
false
;
}
else
if
(
event
.
type
==
"pointermove"
)
{
Offset
movedDist
=
event
.
boxPosition
-
_pointerDownAt
;
value
=
new
Point
(
(
movedDist
.
dx
/
80.0
).
clamp
(-
1.0
,
1.0
),
(
movedDist
.
dy
/
80.0
).
clamp
(-
1.0
,
1.0
));
_handlePos
=
_center
+
new
Offset
(
value
.
x
*
40.0
,
value
.
y
*
40.0
);
}
return
true
;
}
void
paint
(
PaintingCanvas
canvas
)
{
applyTransformForPivot
(
canvas
);
canvas
.
drawCircle
(
_handlePos
,
25.0
,
_paintHandle
);
canvas
.
drawCircle
(
_center
,
40.0
,
_paintControl
);
}
}
class
Level
extends
Node
{
Level
()
{
position
=
new
Point
(
160.0
,
0.0
);
}
Ship
ship
;
double
scroll
(
double
scrollSpeed
)
{
position
+=
new
Offset
(
0.0
,
scrollSpeed
);
return
position
.
y
;
}
}
abstract
class
GameObject
extends
Node
{
double
radius
=
0.0
;
double
removeLimit
=
1280.0
;
bool
canDamageShip
=
true
;
bool
canBeDamaged
=
true
;
double
maxDamage
=
3.0
;
double
damage
=
0.0
;
Paint
_paintDebug
=
new
Paint
()
..
color
=
new
Color
(
0xffff0000
)
..
strokeWidth
=
1.0
..
setStyle
(
sky
.
PaintingStyle
.
stroke
);
bool
collidingWith
(
GameObject
obj
)
{
return
(
GameMath
.
pointQuickDist
(
position
,
obj
.
position
)
<
radius
+
obj
.
radius
);
}
void
move
()
{
}
void
removeIfOffscreen
(
double
scroll
)
{
;
if
(-
position
.
y
>
scroll
+
removeLimit
||
-
position
.
y
<
scroll
-
50.0
)
{
removeFromParent
();
}
}
void
destroy
()
{
if
(
parent
!=
null
)
{
Explosion
explo
=
createExplosion
();
if
(
explo
!=
null
)
{
explo
.
position
=
position
;
parent
.
addChild
(
explo
);
}
removeFromParent
();
}
}
int
addDamage
(
double
d
)
{
if
(!
canBeDamaged
)
return
0
;
damage
+=
d
;
if
(
damage
>=
maxDamage
)
{
destroy
();
return
(
maxDamage
*
10
).
ceil
();
}
return
10
;
}
Explosion
createExplosion
()
{
return
null
;
}
void
paint
(
PaintingCanvas
canvas
)
{
if
(
_drawDebug
)
{
canvas
.
drawCircle
(
Point
.
origin
,
radius
,
_paintDebug
);
}
super
.
paint
(
canvas
);
}
void
setupActions
()
{
}
}
class
Ship
extends
GameObject
{
Ship
(
GameObjectFactory
f
)
{
// Add main ship sprite
_sprt
=
new
Sprite
(
f
.
sheet
[
"ship.png"
]);
_sprt
.
scale
=
0.3
;
_sprt
.
rotation
=
-
90.0
;
addChild
(
_sprt
);
radius
=
20.0
;
canBeDamaged
=
false
;
canDamageShip
=
false
;
// Set start position
position
=
new
Point
(
0.0
,
50.0
);
}
Sprite
_sprt
;
void
applyThrust
(
Point
joystickValue
,
double
scroll
)
{
Point
oldPos
=
position
;
Point
target
=
new
Point
(
joystickValue
.
x
*
160.0
,
joystickValue
.
y
*
220.0
-
250.0
-
scroll
);
double
filterFactor
=
0.2
;
position
=
new
Point
(
GameMath
.
filter
(
oldPos
.
x
,
target
.
x
,
filterFactor
),
GameMath
.
filter
(
oldPos
.
y
,
target
.
y
,
filterFactor
));
}
}
class
Laser
extends
GameObject
{
double
impact
=
1.0
;
Laser
(
GameObjectFactory
f
)
{
// Add sprite
_sprt
=
new
Sprite
(
f
.
sheet
[
"laser.png"
]);
_sprt
.
scale
=
0.3
;
_sprt
.
transferMode
=
sky
.
TransferMode
.
plus
;
addChild
(
_sprt
);
radius
=
10.0
;
removeLimit
=
640.0
;
canDamageShip
=
false
;
canBeDamaged
=
false
;
}
Sprite
_sprt
;
void
move
()
{
position
+=
new
Offset
(
0.0
,
-
10.0
);
}
}
abstract
class
Obstacle
extends
GameObject
{
Obstacle
(
this
.
_f
);
double
explosionScale
=
1.0
;
GameObjectFactory
_f
;
Explosion
createExplosion
()
{
SoundEffectPlayer
.
sharedInstance
().
play
(
_f
.
sounds
[
"explosion"
]);
Explosion
explo
=
new
Explosion
(
_f
.
sheet
);
explo
.
scale
=
explosionScale
;
return
explo
;
}
}
abstract
class
Asteroid
extends
Obstacle
{
Asteroid
(
GameObjectFactory
f
)
:
super
(
f
);
Sprite
_sprt
;
void
setupActions
()
{
// Rotate obstacle
int
direction
=
1
;
if
(
randomDouble
()
<
0.5
)
direction
=
-
1
;
ActionTween
rotate
=
new
ActionTween
(
(
a
)
=>
_sprt
.
rotation
=
a
,
0.0
,
360.0
*
direction
,
5.0
+
5.0
*
randomDouble
());
_sprt
.
actions
.
run
(
new
ActionRepeatForever
(
rotate
));
}
set
damage
(
double
d
)
{
super
.
damage
=
d
;
int
alpha
=
((
200.0
*
d
)
~/
maxDamage
).
clamp
(
0
,
200
);
_sprt
.
colorOverlay
=
new
Color
.
fromARGB
(
alpha
,
255
,
3
,
86
);
}
}
class
AsteroidBig
extends
Asteroid
{
AsteroidBig
(
GameObjectFactory
f
)
:
super
(
f
)
{
_sprt
=
new
Sprite
(
f
.
sheet
[
"asteroid_big_
${randomInt(3)}
.png"
]);
_sprt
.
scale
=
0.3
;
radius
=
25.0
;
maxDamage
=
5.0
;
addChild
(
_sprt
);
}
}
class
AsteroidSmall
extends
Asteroid
{
AsteroidSmall
(
GameObjectFactory
f
)
:
super
(
f
)
{
_sprt
=
new
Sprite
(
f
.
sheet
[
"asteroid_small_
${randomInt(3)}
.png"
]);
_sprt
.
scale
=
0.3
;
radius
=
12.0
;
maxDamage
=
3.0
;
addChild
(
_sprt
);
}
}
enum
GameObjectType
{
asteroidBig
,
asteroidSmall
,
}
class
GameObjectFactory
{
GameObjectFactory
(
this
.
sheet
,
this
.
sounds
,
this
.
level
);
SpriteSheet
sheet
;
Map
<
String
,
SoundEffect
>
sounds
;
Level
level
;
void
addGameObject
(
GameObjectType
type
,
Point
pos
)
{
GameObject
obj
;
if
(
type
==
GameObjectType
.
asteroidBig
)
obj
=
new
AsteroidBig
(
this
);
else
if
(
type
==
GameObjectType
.
asteroidSmall
)
obj
=
new
AsteroidSmall
(
this
);
obj
.
position
=
pos
;
obj
.
setupActions
();
level
.
addChild
(
obj
);
}
}
// class MovingObstacle extends Obstacle {
// MovingObstacle(SpriteSheet sheet, Map<String,SoundEffect> effects, ObstacleType type) : super (sheet, effects, type);
//
// void setupAction() {
// actions.stopAll();
//
// List<Offset> offsets = [
// new Offset(-160.0, 160.0),
// new Offset(-80.0, -160.0),
// new Offset(0.0, 160.0),
// new Offset(80.0, -160.0),
// new Offset(160.0, 160.0)];
//
// List<Point> points = [];
// for (Offset offset in offsets) {
// points.add(position + offset);
// }
//
// ActionSpline spline = new ActionSpline((a) => position = a, points, 4.0);
// actions.run(new ActionRepeatForever(spline));
// }
// }
class
StarField
extends
NodeWithSize
{
sky
.
Image
_image
;
SpriteSheet
_spriteSheet
;
int
_numStars
;
bool
_autoScroll
;
List
<
Point
>
_starPositions
;
List
<
double
>
_starScales
;
List
<
Rect
>
_rects
;
List
<
Color
>
_colors
;
final
double
_padding
=
50.0
;
Size
_paddedSize
=
Size
.
zero
;
Paint
_paint
=
new
Paint
()
..
setFilterQuality
(
sky
.
FilterQuality
.
low
)
..
isAntiAlias
=
false
..
setTransferMode
(
sky
.
TransferMode
.
plus
);
StarField
(
this
.
_spriteSheet
,
this
.
_numStars
,
[
this
.
_autoScroll
=
false
])
:
super
(
Size
.
zero
)
{
_image
=
_spriteSheet
.
image
;
}
void
addStars
()
{
_starPositions
=
[];
_starScales
=
[];
_colors
=
[];
_rects
=
[];
size
=
spriteBox
.
visibleArea
.
size
;
_paddedSize
=
new
Size
(
size
.
width
+
_padding
*
2.0
,
size
.
height
+
_padding
*
2.0
);
for
(
int
i
=
0
;
i
<
_numStars
;
i
++)
{
_starPositions
.
add
(
new
Point
(
randomDouble
()
*
_paddedSize
.
width
,
randomDouble
()
*
_paddedSize
.
height
));
_starScales
.
add
(
randomDouble
()
*
0.4
);
_colors
.
add
(
new
Color
.
fromARGB
((
255.0
*
(
randomDouble
()
*
0.5
+
0.5
)).
toInt
(),
255
,
255
,
255
));
_rects
.
add
(
_spriteSheet
[
"star_
${randomInt(2)}
.png"
].
frame
);
}
}
void
spriteBoxPerformedLayout
()
{
addStars
();
}
void
paint
(
PaintingCanvas
canvas
)
{
// Create a transform for each star
List
<
sky
.
RSTransform
>
transforms
=
[];
for
(
int
i
=
0
;
i
<
_numStars
;
i
++)
{
sky
.
RSTransform
transform
=
new
sky
.
RSTransform
(
_starScales
[
i
],
0.0
,
_starPositions
[
i
].
x
-
_padding
,
_starPositions
[
i
].
y
-
_padding
);
transforms
.
add
(
transform
);
}
// Draw the stars
canvas
.
drawAtlas
(
_image
,
transforms
,
_rects
,
_colors
,
sky
.
TransferMode
.
modulate
,
null
,
_paint
);
}
void
move
(
double
dx
,
double
dy
)
{
for
(
int
i
=
0
;
i
<
_numStars
;
i
++)
{
double
xPos
=
_starPositions
[
i
].
x
;
double
yPos
=
_starPositions
[
i
].
y
;
double
scale
=
_starScales
[
i
];
xPos
+=
dx
*
scale
;
yPos
+=
dy
*
scale
;
if
(
xPos
>=
_paddedSize
.
width
)
xPos
-=
_paddedSize
.
width
;
if
(
xPos
<
0
)
xPos
+=
_paddedSize
.
width
;
if
(
yPos
>=
_paddedSize
.
height
)
yPos
-=
_paddedSize
.
height
;
if
(
yPos
<
0
)
yPos
+=
_paddedSize
.
height
;
_starPositions
[
i
]
=
new
Point
(
xPos
,
yPos
);
}
}
void
update
(
double
dt
)
{
if
(
_autoScroll
)
{
move
(
0.0
,
dt
*
100.0
);
}
}
}
class
RepeatedImage
extends
Node
{
Sprite
_sprt0
;
Sprite
_sprt1
;
RepeatedImage
(
sky
.
Image
image
,
[
sky
.
TransferMode
mode
=
null
])
{
_sprt0
=
new
Sprite
.
fromImage
(
image
);
_sprt0
.
size
=
new
Size
(
1024.0
,
1024.0
);
_sprt0
.
pivot
=
Point
.
origin
;
_sprt1
=
new
Sprite
.
fromImage
(
image
);
_sprt1
.
size
=
new
Size
(
1024.0
,
1024.0
);
_sprt1
.
pivot
=
Point
.
origin
;
_sprt1
.
position
=
new
Point
(
0.0
,
-
1024.0
);
if
(
mode
!=
null
)
{
_sprt0
.
transferMode
=
mode
;
_sprt1
.
transferMode
=
mode
;
}
addChild
(
_sprt0
);
addChild
(
_sprt1
);
}
void
move
(
double
dy
)
{
double
yPos
=
(
position
.
y
+
dy
)
%
1024.0
;
position
=
new
Point
(
0.0
,
yPos
);
}
}
class
Explosion
extends
Node
{
Explosion
(
SpriteSheet
sheet
)
{
// Add particles
ParticleSystem
particlesDebris
=
new
ParticleSystem
(
sheet
[
"explosion_particle.png"
],
rotateToMovement:
true
,
startRotation:
90.0
,
startRotationVar:
0.0
,
endRotation:
90.0
,
startSize:
0.3
,
startSizeVar:
0.1
,
endSize:
0.3
,
endSizeVar:
0.1
,
numParticlesToEmit:
25
,
emissionRate:
1000.0
,
greenVar:
127
,
redVar:
127
);
particlesDebris
.
zPosition
=
1010.0
;
addChild
(
particlesDebris
);
ParticleSystem
particlesFire
=
new
ParticleSystem
(
sheet
[
"fire_particle.png"
],
colorSequence:
new
ColorSequence
([
new
Color
(
0xffffff33
),
new
Color
(
0xffff3333
),
new
Color
(
0x00ff3333
)],
[
0.0
,
0.5
,
1.0
]),
numParticlesToEmit:
25
,
emissionRate:
1000.0
,
startSize:
0.5
,
startSizeVar:
0.1
,
endSize:
0.5
,
endSizeVar:
0.1
,
posVar:
new
Point
(
10.0
,
10.0
),
speed:
10.0
,
speedVar:
5.0
);
particlesFire
.
zPosition
=
1011.0
;
addChild
(
particlesFire
);
// Add ring
Sprite
sprtRing
=
new
Sprite
(
sheet
[
"explosion_ring.png"
]);
sprtRing
.
transferMode
=
sky
.
TransferMode
.
plus
;
addChild
(
sprtRing
);
Action
scale
=
new
ActionTween
(
(
a
)
=>
sprtRing
.
scale
=
a
,
0.2
,
1.0
,
1.5
);
Action
scaleAndRemove
=
new
ActionSequence
([
scale
,
new
ActionRemoveNode
(
sprtRing
)]);
Action
fade
=
new
ActionTween
(
(
a
)
=>
sprtRing
.
opacity
=
a
,
1.0
,
0.0
,
1.5
);
actions
.
run
(
scaleAndRemove
);
actions
.
run
(
fade
);
// Add streaks
for
(
int
i
=
0
;
i
<
5
;
i
++)
{
Sprite
sprtFlare
=
new
Sprite
(
sheet
[
"explosion_flare.png"
]);
sprtFlare
.
pivot
=
new
Point
(
0.3
,
1.0
);
sprtFlare
.
scaleX
=
0.3
;
sprtFlare
.
transferMode
=
sky
.
TransferMode
.
plus
;
sprtFlare
.
rotation
=
randomDouble
()
*
360.0
;
addChild
(
sprtFlare
);
double
multiplier
=
randomDouble
()
*
0.3
+
1.0
;
Action
scale
=
new
ActionTween
(
(
a
)
=>
sprtFlare
.
scaleY
=
a
,
0.3
*
multiplier
,
0.8
,
1.5
*
multiplier
);
Action
scaleAndRemove
=
new
ActionSequence
([
scale
,
new
ActionRemoveNode
(
sprtFlare
)]);
Action
fadeIn
=
new
ActionTween
(
(
a
)
=>
sprtFlare
.
opacity
=
a
,
0.0
,
1.0
,
0.5
*
multiplier
);
Action
fadeOut
=
new
ActionTween
(
(
a
)
=>
sprtFlare
.
opacity
=
a
,
1.0
,
0.0
,
1.0
*
multiplier
);
Action
fadeInOut
=
new
ActionSequence
([
fadeIn
,
fadeOut
]);
actions
.
run
(
scaleAndRemove
);
actions
.
run
(
fadeInOut
);
}
}
}
class
Hud
extends
Node
{
SpriteSheet
sheet
;
Sprite
sprtBgScore
;
bool
_dirtyScore
=
true
;
int
_score
=
0
;
int
get
score
=>
_score
;
set
score
(
int
score
)
{
_score
=
score
;
_dirtyScore
=
true
;
}
Hud
(
this
.
sheet
)
{
position
=
new
Point
(
310.0
,
10.0
);
scale
=
0.6
;
sprtBgScore
=
new
Sprite
(
sheet
[
"scoreboard.png"
]);
sprtBgScore
.
pivot
=
new
Point
(
1.0
,
0.0
);
sprtBgScore
.
scale
=
0.6
;
addChild
(
sprtBgScore
);
}
void
update
(
double
dt
)
{
// Update score
if
(
_dirtyScore
)
{
sprtBgScore
.
removeAllChildren
();
String
scoreStr
=
_score
.
toString
();
double
xPos
=
-
50.0
;
for
(
int
i
=
scoreStr
.
length
-
1
;
i
>=
0
;
i
--)
{
String
numStr
=
scoreStr
.
substring
(
i
,
i
+
1
);
Sprite
numSprt
=
new
Sprite
(
sheet
[
"number_
$numStr
.png"
]);
numSprt
.
position
=
new
Point
(
xPos
,
49.0
);
sprtBgScore
.
addChild
(
numSprt
);
xPos
-=
37.0
;
}
_dirtyScore
=
false
;
}
}
}
class
Flash
extends
NodeWithSize
{
Flash
(
Size
size
,
this
.
duration
)
:
super
(
size
)
{
ActionTween
fade
=
new
ActionTween
((
a
)
=>
_opacity
=
a
,
1.0
,
0.0
,
duration
);
ActionSequence
seq
=
new
ActionSequence
([
fade
,
new
ActionRemoveNode
(
this
)]);
actions
.
run
(
seq
);
}
double
duration
;
double
_opacity
=
1.0
;
Paint
_cachedPaint
=
new
Paint
();
void
paint
(
PaintingCanvas
canvas
)
{
// Update the color
_cachedPaint
.
color
=
new
Color
.
fromARGB
((
255.0
*
_opacity
).
toInt
(),
255
,
255
,
255
);
// Fill the area
applyTransformForPivot
(
canvas
);
canvas
.
drawRect
(
new
Rect
.
fromLTRB
(
0.0
,
0.0
,
size
.
width
,
size
.
height
),
_cachedPaint
);
}
}
examples/game/lib/game_demo_world.dart
deleted
100644 → 0
View file @
1393b4c6
part of
game
;
const
double
_steeringThreshold
=
0.0
;
const
double
_steeringMax
=
150.0
;
// Random generator
Math
.
Random
_rand
=
new
Math
.
Random
();
const
double
_gameSizeWidth
=
1024.0
;
const
double
_gameSizeHeight
=
1024.0
;
const
double
_shipRadius
=
30.0
;
const
double
_lrgAsteroidRadius
=
40.0
;
const
double
_medAsteroidRadius
=
20.0
;
const
double
_smlAsteroidRadius
=
10.0
;
const
double
_maxAsteroidSpeed
=
1.0
;
const
int
_lifeTimeLaser
=
50
;
const
int
_numStarsInStarField
=
150
;
const
int
_numFramesShieldActive
=
60
*
5
;
const
int
_numFramesShieldFlickers
=
60
;
class
GameDemoWorld
extends
NodeWithSize
{
// Images
sky
.
Image
_imgNebula
;
SpriteSheet
_spriteSheet
;
SpriteSheet
_spriteSheetUI
;
Map
<
String
,
SoundEffect
>
_sounds
;
SoundEffectPlayer
_soundPool
=
SoundEffectPlayer
.
sharedInstance
();
Navigator
_navigator
;
// Inputs
double
_joystickX
=
0.0
;
double
_joystickY
=
0.0
;
Node
_gameLayer
;
Ship
_ship
;
Sprite
_shield
;
List
<
Asteroid
>
_asteroids
=
[];
List
<
Laser
>
_lasers
=
[];
StarField
_starField
;
Nebula
_nebula
;
// Game state
int
_numFrames
=
0
;
bool
_isGameOver
=
false
;
int
_gameOverFrame
;
int
_currentLevel
=
0
;
// Heads up display
Hud
_hud
;
Function
_gameOverCallback
;
GameDemoWorld
(
App
app
,
this
.
_navigator
,
ImageMap
images
,
this
.
_spriteSheet
,
this
.
_spriteSheetUI
,
this
.
_sounds
,
this
.
_gameOverCallback
)
:
super
(
new
Size
(
_gameSizeWidth
,
_gameSizeHeight
))
{
// Fetch images
_imgNebula
=
images
[
"assets/nebula.png"
];
_gameLayer
=
new
Node
();
this
.
addChild
(
_gameLayer
);
// Add ship
addShip
();
// Add background
Sprite
sprtBackground
=
new
Sprite
.
fromImage
(
images
[
"assets/starfield.png"
]);
sprtBackground
.
position
=
new
Point
(
512.0
,
512.0
);
sprtBackground
.
zPosition
=
-
3.0
;
addChild
(
sprtBackground
);
// Add starfield
_starField
=
new
StarField
(
_spriteSheet
,
_numStarsInStarField
);
_starField
.
zPosition
=
-
2.0
;
addChild
(
_starField
);
// Add nebula
addNebula
();
userInteractionEnabled
=
true
;
handleMultiplePointers
=
true
;
_hud
=
new
Hud
(
_spriteSheetUI
);
_hud
.
zPosition
=
1000.0
;
addChild
(
_hud
);
// Setup level
setupLevel
(
0
);
}
void
setupLevel
(
int
level
)
{
int
numLargeAsteroids
=
5
+
level
*
2
;
int
numMediumAsteroids
=
5
+
level
*
2
;
// Add some asteroids to the game world
for
(
int
i
=
0
;
i
<
numLargeAsteroids
;
i
++)
{
addAsteroid
(
AsteroidSize
.
large
);
}
for
(
int
i
=
0
;
i
<
numMediumAsteroids
;
i
++)
{
addAsteroid
(
AsteroidSize
.
medium
);
}
_numFrames
=
0
;
_shield
.
visible
=
true
;
}
// Methods for adding game objects
void
addAsteroid
(
AsteroidSize
size
,
[
Point
pos
])
{
Asteroid
asteroid
=
new
Asteroid
(
_spriteSheet
,
size
);
asteroid
.
zPosition
=
1.0
;
if
(
pos
!=
null
)
asteroid
.
position
=
pos
;
_gameLayer
.
addChild
(
asteroid
);
_asteroids
.
add
(
asteroid
);
// Animate asteroid into the scene
Action
action
=
new
ActionTween
((
a
)
=>
asteroid
.
scale
=
a
,
0.0
,
1.0
,
1.0
,
bounceOut
);
_gameLayer
.
actions
.
run
(
action
);
}
void
addShip
()
{
Ship
ship
=
new
Ship
(
_spriteSheet
[
"ship.png"
]);
ship
.
zPosition
=
10.0
;
_gameLayer
.
addChild
(
ship
);
_ship
=
ship
;
_shield
=
new
Sprite
(
_spriteSheet
[
"shield.png"
]);
_shield
.
zPosition
=
11.0
;
_shield
.
scale
=
0.5
;
_shield
.
transferMode
=
sky
.
TransferMode
.
plus
;
_gameLayer
.
addChild
(
_shield
);
Action
rotate
=
new
ActionRepeatForever
(
new
ActionTween
((
a
)
=>
_shield
.
rotation
=
a
,
0.0
,
360.0
,
1.0
));
actions
.
run
(
rotate
);
}
void
addLaser
()
{
Laser
laser
=
new
Laser
(
_spriteSheet
[
"laser.png"
],
_ship
);
laser
.
zPosition
=
8.0
;
laser
.
constrainProportions
=
true
;
_lasers
.
add
(
laser
);
_gameLayer
.
addChild
(
laser
);
_soundPool
.
play
(
_sounds
[
"laser"
]);
}
void
addNebula
()
{
_nebula
=
new
Nebula
.
withImage
(
_imgNebula
);
_gameLayer
.
addChild
(
_nebula
);
}
void
addExplosion
(
AsteroidSize
asteroidSize
,
Point
position
)
{
Node
explosionNode
=
new
Node
();
// Add particles
ParticleSystem
particlesDebris
=
new
ParticleSystem
(
_spriteSheet
[
"explosion_particle.png"
],
rotateToMovement:
true
,
startRotation:
90.0
,
startRotationVar:
0.0
,
endRotation:
90.0
,
startSize:
0.3
,
startSizeVar:
0.1
,
endSize:
0.3
,
endSizeVar:
0.1
,
numParticlesToEmit:
25
,
emissionRate:
1000.0
,
greenVar:
127
,
redVar:
127
);
particlesDebris
.
zPosition
=
1010.0
;
explosionNode
.
addChild
(
particlesDebris
);
ParticleSystem
particlesFire
=
new
ParticleSystem
(
_spriteSheet
[
"fire_particle.png"
],
colorSequence:
new
ColorSequence
([
new
Color
(
0xffffff33
),
new
Color
(
0xffff3333
),
new
Color
(
0x00ff3333
)],
[
0.0
,
0.5
,
1.0
]),
numParticlesToEmit:
25
,
emissionRate:
1000.0
,
startSize:
0.5
,
startSizeVar:
0.1
,
endSize:
0.5
,
endSizeVar:
0.1
,
posVar:
new
Point
(
10.0
,
10.0
),
speed:
10.0
,
speedVar:
5.0
);
particlesFire
.
zPosition
=
1011.0
;
explosionNode
.
addChild
(
particlesFire
);
// Add ring
Sprite
sprtRing
=
new
Sprite
(
_spriteSheet
[
"explosion_ring.png"
]);
sprtRing
.
transferMode
=
sky
.
TransferMode
.
plus
;
explosionNode
.
addChild
(
sprtRing
);
Action
scale
=
new
ActionTween
(
(
a
)
=>
sprtRing
.
scale
=
a
,
0.2
,
1.0
,
1.5
);
Action
scaleAndRemove
=
new
ActionSequence
([
scale
,
new
ActionRemoveNode
(
sprtRing
)]);
Action
fade
=
new
ActionTween
(
(
a
)
=>
sprtRing
.
opacity
=
a
,
1.0
,
0.0
,
1.5
);
actions
.
run
(
scaleAndRemove
);
actions
.
run
(
fade
);
// Add streaks
for
(
int
i
=
0
;
i
<
5
;
i
++)
{
Sprite
sprtFlare
=
new
Sprite
(
_spriteSheet
[
"explosion_flare.png"
]);
sprtFlare
.
pivot
=
new
Point
(
0.3
,
1.0
);
sprtFlare
.
scaleX
=
0.3
;
sprtFlare
.
transferMode
=
sky
.
TransferMode
.
plus
;
sprtFlare
.
rotation
=
_rand
.
nextDouble
()
*
360.0
;
explosionNode
.
addChild
(
sprtFlare
);
double
multiplier
=
_rand
.
nextDouble
()
*
0.3
+
1.0
;
Action
scale
=
new
ActionTween
(
(
a
)
=>
sprtFlare
.
scaleY
=
a
,
0.3
*
multiplier
,
0.8
,
1.5
*
multiplier
);
Action
scaleAndRemove
=
new
ActionSequence
([
scale
,
new
ActionRemoveNode
(
sprtFlare
)]);
Action
fadeIn
=
new
ActionTween
(
(
a
)
=>
sprtFlare
.
opacity
=
a
,
0.0
,
1.0
,
0.5
*
multiplier
);
Action
fadeOut
=
new
ActionTween
(
(
a
)
=>
sprtFlare
.
opacity
=
a
,
1.0
,
0.0
,
1.0
*
multiplier
);
Action
fadeInOut
=
new
ActionSequence
([
fadeIn
,
fadeOut
]);
actions
.
run
(
scaleAndRemove
);
actions
.
run
(
fadeInOut
);
}
explosionNode
.
position
=
position
;
explosionNode
.
zPosition
=
1010.0
;
if
(
asteroidSize
==
AsteroidSize
.
large
)
{
explosionNode
.
scale
=
1.5
;
}
_gameLayer
.
addChild
(
explosionNode
);
_soundPool
.
play
(
_sounds
[
"explosion"
]);
}
void
update
(
double
dt
)
{
// Move asteroids
for
(
Asteroid
asteroid
in
_asteroids
)
{
asteroid
.
position
=
pointAdd
(
asteroid
.
position
,
asteroid
.
_movementVector
);
}
// Move lasers and remove expired lasers
for
(
int
i
=
_lasers
.
length
-
1
;
i
>=
0
;
i
--)
{
Laser
laser
=
_lasers
[
i
];
laser
.
move
();
if
(
laser
.
_frameCount
>
_lifeTimeLaser
)
{
laser
.
removeFromParent
();
_lasers
.
removeAt
(
i
);
}
}
// Apply thrust to ship
if
(
_joystickX
!=
0.0
||
_joystickY
!=
0.0
)
{
_ship
.
thrust
(
_joystickX
,
_joystickY
);
}
// Move ship
_ship
.
move
();
_shield
.
position
=
_ship
.
position
;
// Check collisions between asteroids and lasers
for
(
int
i
=
_lasers
.
length
-
1
;
i
>=
0
;
i
--)
{
// Iterate over all the lasers
Laser
laser
=
_lasers
[
i
];
for
(
int
j
=
_asteroids
.
length
-
1
;
j
>=
0
;
j
--)
{
// Iterate over all the asteroids
Asteroid
asteroid
=
_asteroids
[
j
];
// Check for collision
if
(
pointQuickDist
(
laser
.
position
,
asteroid
.
position
)
<
laser
.
radius
+
asteroid
.
radius
)
{
// Remove laser
laser
.
removeFromParent
();
_lasers
.
removeAt
(
i
);
// Add asteroids and explosions
if
(
asteroid
.
_asteroidSize
==
AsteroidSize
.
large
)
{
for
(
int
a
=
0
;
a
<
3
;
a
++)
addAsteroid
(
AsteroidSize
.
medium
,
asteroid
.
position
);
}
else
if
(
asteroid
.
_asteroidSize
==
AsteroidSize
.
medium
)
{
for
(
int
a
=
0
;
a
<
5
;
a
++)
addAsteroid
(
AsteroidSize
.
small
,
asteroid
.
position
);
}
addExplosion
(
asteroid
.
_asteroidSize
,
asteroid
.
position
);
// Remove asteroid
asteroid
.
removeFromParent
();
_asteroids
.
removeAt
(
j
);
// Scoring
if
(
asteroid
.
_asteroidSize
==
AsteroidSize
.
large
)
addScore
(
100
);
else
if
(
asteroid
.
_asteroidSize
==
AsteroidSize
.
medium
)
addScore
(
50
);
else
addScore
(
10
);
break
;
}
}
}
// Check collisions between asteroids and ship
if
(
_numFrames
>
_numFramesShieldActive
)
{
// Shield is no longer active
for
(
int
i
=
_asteroids
.
length
-
1
;
i
>=
0
;
i
--)
{
// Iterate over all the asteroids
Asteroid
asteroid
=
_asteroids
[
i
];
if
(
pointQuickDist
(
asteroid
.
position
,
_ship
.
position
)
<
asteroid
.
radius
+
_ship
.
radius
)
{
killShip
();
}
}
}
// Move objects to center camera and warp objects around the edges
centerCamera
();
warpObjects
();
// Check for level up
if
(
_asteroids
.
length
==
0
)
{
_currentLevel
++;
setupLevel
(
_currentLevel
);
}
// Update shield
if
(
_numFrames
>
_numFramesShieldActive
)
_shield
.
visible
=
false
;
else
if
(
_numFrames
>
_numFramesShieldActive
-
_numFramesShieldFlickers
)
_shield
.
visible
=
!
_shield
.
visible
;
// Check for exit back to main screen
if
(
_isGameOver
&&
_numFrames
-
_gameOverFrame
==
60
)
{
_navigator
.
pop
();
}
_numFrames
++;
}
void
centerCamera
()
{
const
cameraDampening
=
0.1
;
Point
delta
=
new
Point
(
_gameSizeWidth
/
2
-
_ship
.
position
.
x
,
_gameSizeHeight
/
2
-
_ship
.
position
.
y
);
delta
=
pointMult
(
delta
,
cameraDampening
);
for
(
Node
child
in
_gameLayer
.
children
)
{
child
.
position
=
pointAdd
(
child
.
position
,
delta
);
}
// Update starfield
_starField
.
move
(
delta
.
x
,
delta
.
y
);
}
void
warpObjects
()
{
for
(
Node
child
in
_gameLayer
.
children
)
{
if
(
child
.
position
.
x
<
0
)
child
.
position
=
pointAdd
(
child
.
position
,
new
Point
(
_gameSizeWidth
,
0.0
));
if
(
child
.
position
.
x
>=
_gameSizeWidth
)
child
.
position
=
pointAdd
(
child
.
position
,
new
Point
(-
_gameSizeWidth
,
0.0
));
if
(
child
.
position
.
y
<
0
)
child
.
position
=
pointAdd
(
child
.
position
,
new
Point
(
0.0
,
_gameSizeHeight
));
if
(
child
.
position
.
y
>=
_gameSizeHeight
)
child
.
position
=
pointAdd
(
child
.
position
,
new
Point
(
0.0
,
-
_gameSizeHeight
));
}
}
void
killShip
()
{
if
(
_isGameOver
)
return
;
// Set game over
_isGameOver
=
true
;
_gameOverFrame
=
_numFrames
;
_gameOverCallback
(
_hud
.
score
);
// Remove the ship
_ship
.
visible
=
false
;
// Add an explosion
addExplosion
(
AsteroidSize
.
large
,
_ship
.
position
);
}
// Handling controls
void
controlSteering
(
double
x
,
double
y
)
{
// Reset controls if it's game over
if
(
_isGameOver
)
{
x
=
y
=
0.0
;
}
_joystickX
=
x
;
_joystickY
=
y
;
}
void
controlFire
()
{
// Don't shoot if it's game over
if
(
_isGameOver
)
return
;
addLaser
();
}
// Handle pointer events
int
_firstPointer
=
-
1
;
int
_secondPointer
=
-
1
;
Point
_firstPointerDownPos
;
bool
handleEvent
(
SpriteBoxEvent
event
)
{
Point
pointerPos
=
convertPointToNodeSpace
(
event
.
boxPosition
);
int
pointer
=
event
.
pointer
;
switch
(
event
.
type
)
{
case
'pointerdown'
:
if
(
_firstPointer
==
-
1
)
{
// Assign the first pointer
_firstPointer
=
pointer
;
_firstPointerDownPos
=
pointerPos
;
}
else
if
(
_secondPointer
==
-
1
)
{
// Assign second pointer
_secondPointer
=
pointer
;
controlFire
();
}
else
{
// There is a pointer used for steering, let's fire instead
controlFire
();
}
break
;
case
'pointermove'
:
if
(
pointer
==
_firstPointer
)
{
// Handle turning control
double
joystickX
=
0.0
;
double
deltaX
=
pointerPos
.
x
-
_firstPointerDownPos
.
x
;
if
(
deltaX
>
_steeringThreshold
||
deltaX
<
-
_steeringThreshold
)
{
joystickX
=
(
deltaX
-
_steeringThreshold
)/(
_steeringMax
-
_steeringThreshold
);
if
(
joystickX
>
1.0
)
joystickX
=
1.0
;
if
(
joystickX
<
-
1.0
)
joystickX
=
-
1.0
;
}
double
joystickY
=
0.0
;
double
deltaY
=
pointerPos
.
y
-
_firstPointerDownPos
.
y
;
if
(
deltaY
>
_steeringThreshold
||
deltaY
<
-
_steeringThreshold
)
{
joystickY
=
(
deltaY
-
_steeringThreshold
)/(
_steeringMax
-
_steeringThreshold
);
if
(
joystickY
>
1.0
)
joystickY
=
1.0
;
if
(
joystickY
<
-
1.0
)
joystickY
=
-
1.0
;
}
controlSteering
(
joystickX
,
joystickY
);
}
break
;
case
'pointerup'
:
case
'pointercancel'
:
if
(
pointer
==
_firstPointer
)
{
// Un-assign the first pointer
_firstPointer
=
-
1
;
_firstPointerDownPos
=
null
;
controlSteering
(
0.0
,
0.0
);
}
else
if
(
pointer
==
_secondPointer
)
{
_secondPointer
=
-
1
;
}
break
;
default
:
break
;
}
return
true
;
}
// Scoring and HUD
void
addScore
(
int
score
)
{
_hud
.
score
+=
score
;
}
}
// Game objects
enum
AsteroidSize
{
small
,
medium
,
large
,
}
class
Asteroid
extends
Sprite
{
Point
_movementVector
;
AsteroidSize
_asteroidSize
;
double
_radius
;
double
get
radius
{
if
(
_radius
!=
null
)
return
_radius
;
if
(
_asteroidSize
==
AsteroidSize
.
small
)
_radius
=
_smlAsteroidRadius
;
else
if
(
_asteroidSize
==
AsteroidSize
.
medium
)
_radius
=
_medAsteroidRadius
;
else
if
(
_asteroidSize
==
AsteroidSize
.
large
)
_radius
=
_lrgAsteroidRadius
;
return
_radius
;
}
Asteroid
(
SpriteSheet
spriteSheet
,
AsteroidSize
this
.
_asteroidSize
)
{
size
=
new
Size
(
radius
*
2.0
,
radius
*
2.0
);
position
=
new
Point
(
_gameSizeWidth
*
_rand
.
nextDouble
(),
_gameSizeHeight
*
_rand
.
nextDouble
());
rotation
=
360.0
*
_rand
.
nextDouble
();
if
(
_asteroidSize
==
AsteroidSize
.
small
)
{
texture
=
spriteSheet
[
"asteroid_small_
${_rand.nextInt(2)}
.png"
];
}
else
{
texture
=
spriteSheet
[
"asteroid_big_
${_rand.nextInt(2)}
.png"
];
}
_movementVector
=
new
Point
(
_rand
.
nextDouble
()
*
_maxAsteroidSpeed
*
2
-
_maxAsteroidSpeed
,
_rand
.
nextDouble
()
*
_maxAsteroidSpeed
*
2
-
_maxAsteroidSpeed
);
userInteractionEnabled
=
true
;
// Rotate forever
double
direction
=
(
_rand
.
nextBool
())
?
360.0
:
-
360.0
;
ActionTween
rot
=
new
ActionTween
(
(
a
)
=>
rotation
=
a
,
0.0
,
direction
,
2.0
*
_rand
.
nextDouble
()
+
2.0
);
ActionRepeatForever
repeat
=
new
ActionRepeatForever
(
rot
);
actions
.
run
(
repeat
);
}
bool
handleEvent
(
SpriteBoxEvent
event
)
{
if
(
event
.
type
==
"pointerdown"
)
{
actions
.
stopWithTag
(
"fade"
);
colorOverlay
=
new
Color
(
0x99ffffff
);
}
else
if
(
event
.
type
==
"pointerup"
)
{
// Fade out the color overlay
Action
fadeOut
=
new
ActionTween
((
a
)
=>
this
.
colorOverlay
=
a
,
new
Color
(
0x99ffffff
),
new
Color
(
0x00ffffff
),
1.0
);
Action
fadeOutAndRemove
=
new
ActionSequence
([
fadeOut
,
new
ActionCallFunction
(()
=>
this
.
colorOverlay
=
null
)]);
actions
.
run
(
fadeOutAndRemove
,
"fade"
);
}
return
false
;
}
}
class
Ship
extends
Sprite
{
Vector2
_movementVector
;
double
_rotationTarget
;
double
radius
=
_shipRadius
;
Ship
(
Texture
img
)
:
super
(
img
)
{
_movementVector
=
new
Vector2
.
zero
();
rotation
=
_rotationTarget
=
270.0
;
// Create sprite
size
=
new
Size
(
_shipRadius
*
2.0
,
_shipRadius
*
2.0
);
position
=
new
Point
(
_gameSizeWidth
/
2.0
,
_gameSizeHeight
/
2.0
);
}
void
thrust
(
double
x
,
double
y
)
{
_rotationTarget
=
convertRadians2Degrees
(
Math
.
atan2
(
y
,
x
));
Vector2
directionVector
=
new
Vector2
(
x
,
y
).
normalize
();
_movementVector
.
addScaled
(
directionVector
,
1.0
);
}
void
move
()
{
position
=
new
Point
(
position
.
x
+
_movementVector
[
0
],
position
.
y
+
_movementVector
[
1
]);
_movementVector
.
scale
(
0.9
);
rotation
=
dampenRotation
(
rotation
,
_rotationTarget
,
0.1
);
}
}
class
Laser
extends
Sprite
{
int
_frameCount
=
0
;
Point
_movementVector
;
double
radius
=
20.0
;
Laser
(
Texture
img
,
Ship
ship
)
:
super
(
img
)
{
size
=
new
Size
(
30.0
,
30.0
);
position
=
ship
.
position
;
rotation
=
ship
.
rotation
+
90.0
;
transferMode
=
sky
.
TransferMode
.
plus
;
double
rotRadians
=
convertDegrees2Radians
(
rotation
);
_movementVector
=
pointMult
(
new
Point
(
Math
.
sin
(
rotRadians
),
-
Math
.
cos
(
rotRadians
)),
10.0
);
_movementVector
=
new
Point
(
_movementVector
.
x
+
ship
.
_movementVector
[
0
],
_movementVector
.
y
+
ship
.
_movementVector
[
1
]);
}
void
move
()
{
position
=
pointAdd
(
position
,
_movementVector
);
_frameCount
++;
}
}
// Background starfield
class
StarField
extends
NodeWithSize
{
sky
.
Image
_image
;
int
_numStars
;
bool
_autoScroll
;
List
<
Point
>
_starPositions
;
List
<
double
>
_starScales
;
List
<
Rect
>
_rects
;
List
<
Color
>
_colors
;
Paint
_paint
=
new
Paint
()
..
setFilterQuality
(
sky
.
FilterQuality
.
low
)
..
isAntiAlias
=
false
..
setTransferMode
(
sky
.
TransferMode
.
plus
);
StarField
(
SpriteSheet
spriteSheet
,
this
.
_numStars
,
[
this
.
_autoScroll
=
false
])
:
super
(
new
Size
(
1024.0
,
1024.0
))
{
_starPositions
=
[];
_starScales
=
[];
_colors
=
[];
_rects
=
[];
for
(
int
i
=
0
;
i
<
_numStars
;
i
++)
{
_starPositions
.
add
(
new
Point
(
_rand
.
nextDouble
()
*
_gameSizeWidth
,
_rand
.
nextDouble
()
*
_gameSizeHeight
));
_starScales
.
add
(
_rand
.
nextDouble
());
_colors
.
add
(
new
Color
.
fromARGB
((
255.0
*
(
_rand
.
nextDouble
()
*
0.5
+
0.5
)).
toInt
(),
255
,
255
,
255
));
_rects
.
add
(
spriteSheet
[
"star_
${_rand.nextInt(2)}
.png"
].
frame
);
}
_image
=
spriteSheet
.
image
;
}
void
paint
(
PaintingCanvas
canvas
)
{
// Create a transform for each star
List
<
sky
.
RSTransform
>
transforms
=
[];
for
(
int
i
=
0
;
i
<
_numStars
;
i
++)
{
sky
.
RSTransform
transform
=
new
sky
.
RSTransform
(
_starScales
[
i
],
0.0
,
_starPositions
[
i
].
x
,
_starPositions
[
i
].
y
);
transforms
.
add
(
transform
);
}
// Draw the stars
canvas
.
drawAtlas
(
_image
,
transforms
,
_rects
,
_colors
,
sky
.
TransferMode
.
modulate
,
null
,
_paint
);
}
void
move
(
double
dx
,
double
dy
)
{
for
(
int
i
=
0
;
i
<
_numStars
;
i
++)
{
double
xPos
=
_starPositions
[
i
].
x
;
double
yPos
=
_starPositions
[
i
].
y
;
double
scale
=
_starScales
[
i
];
xPos
+=
dx
*
scale
;
yPos
+=
dy
*
scale
;
if
(
xPos
>=
_gameSizeWidth
)
xPos
-=
_gameSizeWidth
;
if
(
xPos
<
0
)
xPos
+=
_gameSizeWidth
;
if
(
yPos
>=
_gameSizeHeight
)
yPos
-=
_gameSizeHeight
;
if
(
yPos
<
0
)
yPos
+=
_gameSizeHeight
;
_starPositions
[
i
]
=
new
Point
(
xPos
,
yPos
);
}
}
void
update
(
double
dt
)
{
if
(
_autoScroll
)
{
move
(
dt
*
100.0
,
0.0
);
}
}
}
class
Hud
extends
NodeWithSize
{
SpriteSheet
spriteSheetUI
;
Sprite
sprtBgScore
;
Sprite
sprtBgShield
;
bool
_dirtyScore
=
true
;
int
_score
=
0
;
int
get
score
=>
_score
;
set
score
(
int
score
)
{
_score
=
score
;
_dirtyScore
=
true
;
}
Hud
(
this
.
spriteSheetUI
)
:
super
(
Size
.
zero
)
{
pivot
=
Point
.
origin
;
sprtBgScore
=
new
Sprite
(
spriteSheetUI
[
"scoreboard.png"
]);
sprtBgScore
.
pivot
=
new
Point
(
1.0
,
0.0
);
sprtBgScore
.
scale
=
0.6
;
addChild
(
sprtBgScore
);
sprtBgShield
=
new
Sprite
(
spriteSheetUI
[
"bar_shield.png"
]);
sprtBgShield
.
pivot
=
Point
.
origin
;
sprtBgShield
.
scale
=
0.6
;
// TODO: Add shield
//addChild(sprtBgShield);
}
void
spriteBoxPerformedLayout
()
{
// Set the size and position of HUD display
position
=
spriteBox
.
visibleArea
.
topLeft
;
size
=
spriteBox
.
visibleArea
.
size
;
// Position hud objects
sprtBgShield
.
position
=
new
Point
(
20.0
,
20.0
);
sprtBgScore
.
position
=
new
Point
(
size
.
width
-
20.0
,
20.0
);
}
void
update
(
double
dt
)
{
// Update score
if
(
_dirtyScore
)
{
sprtBgScore
.
removeAllChildren
();
String
scoreStr
=
_score
.
toString
();
double
xPos
=
-
50.0
;
for
(
int
i
=
scoreStr
.
length
-
1
;
i
>=
0
;
i
--)
{
String
numStr
=
scoreStr
.
substring
(
i
,
i
+
1
);
Sprite
numSprt
=
new
Sprite
(
spriteSheetUI
[
"number_
$numStr
.png"
]);
numSprt
.
position
=
new
Point
(
xPos
,
49.0
);
sprtBgScore
.
addChild
(
numSprt
);
xPos
-=
37.0
;
}
_dirtyScore
=
false
;
}
// Update power bar
}
}
class
Nebula
extends
Node
{
Nebula
.
withImage
(
sky
.
Image
img
)
{
for
(
int
i
=
0
;
i
<
2
;
i
++)
{
for
(
int
j
=
0
;
j
<
2
;
j
++)
{
Sprite
sprt
=
new
Sprite
.
fromImage
(
img
);
sprt
.
transferMode
=
sky
.
TransferMode
.
plus
;
sprt
.
pivot
=
Point
.
origin
;
sprt
.
position
=
new
Point
(
i
*
_gameSizeWidth
-
_gameSizeWidth
,
j
*
_gameSizeHeight
-
_gameSizeHeight
);
addChild
(
sprt
);
}
}
}
}
// Convenience methods
Point
pointAdd
(
Point
a
,
Point
b
)
{
return
new
Point
(
a
.
x
+
b
.
x
,
a
.
y
+
b
.
y
);
}
Point
pointMult
(
Point
a
,
double
multiplier
)
{
return
new
Point
(
a
.
x
*
multiplier
,
a
.
y
*
multiplier
);
}
double
dampenRotation
(
double
src
,
double
dst
,
double
dampening
)
{
double
delta
=
dst
-
src
;
while
(
delta
>
180.0
)
delta
-=
360
;
while
(
delta
<
-
180
)
delta
+=
360
;
delta
*=
dampening
;
return
src
+
delta
;
}
double
pointQuickDist
(
Point
a
,
Point
b
)
{
double
dx
=
a
.
x
-
b
.
x
;
double
dy
=
a
.
y
-
b
.
y
;
if
(
dx
<
0.0
)
dx
=
-
dx
;
if
(
dy
<
0.0
)
dy
=
-
dy
;
if
(
dx
>
dy
)
{
return
dx
+
dy
/
2.0
;
}
else
{
return
dy
+
dx
/
2.0
;
}
}
examples/game/lib/main.dart
View file @
a78370fe
...
@@ -77,10 +77,19 @@ main() async {
...
@@ -77,10 +77,19 @@ main() async {
class
GameDemoApp
extends
App
{
class
GameDemoApp
extends
App
{
NavigationState
_navigationState
;
NavigationState
_navigationState
;
GameDemoWorld
_game
;
NodeWithSize
_game
;
int
_lastScore
=
0
;
int
_lastScore
=
0
;
void
initState
()
{
void
initState
()
{
// _game = new GameDemoNode(
// _imageMap,
// _spriteSheet,
// _spriteSheetUI,
// _sounds,
// (lastScore) {
// setState(() {_lastScore = lastScore;});
// });
_navigationState
=
new
NavigationState
([
_navigationState
=
new
NavigationState
([
new
Route
(
new
Route
(
name:
'/'
,
name:
'/'
,
...
@@ -112,24 +121,23 @@ class GameDemoApp extends App {
...
@@ -112,24 +121,23 @@ class GameDemoApp extends App {
}
}
Widget
_buildGameScene
(
navigator
,
route
)
{
Widget
_buildGameScene
(
navigator
,
route
)
{
return
new
SpriteWidget
(
_game
);
return
new
SpriteWidget
(
_game
,
SpriteBoxTransformMode
.
fixedWidth
);
}
}
Widget
_buildMainScene
(
navigator
,
route
)
{
Widget
_buildMainScene
(
navigator
,
route
)
{
return
new
Stack
([
return
new
Stack
([
new
SpriteWidget
(
new
MainScreenBackground
()),
new
SpriteWidget
(
new
MainScreenBackground
()
,
SpriteBoxTransformMode
.
fixedWidth
),
new
Flex
([
new
Flex
([
new
TextureButton
(
new
TextureButton
(
onPressed:
()
{
onPressed:
()
{
_game
=
new
GameDemoWorld
(
_game
=
new
GameDemoNode
(
_app
,
navigator
,
_imageMap
,
_imageMap
,
_spriteSheet
,
_spriteSheet
,
_spriteSheetUI
,
_spriteSheetUI
,
_sounds
,
_sounds
,
(
lastScore
)
{
(
lastScore
)
{
setState
(()
{
_lastScore
=
lastScore
;});
setState
(()
{
_lastScore
=
lastScore
;});
navigator
.
pop
();
}
}
);
);
navigator
.
pushNamed
(
'/game'
);
navigator
.
pushNamed
(
'/game'
);
...
@@ -243,14 +251,19 @@ class _TextureButtonToken {
...
@@ -243,14 +251,19 @@ class _TextureButtonToken {
}
}
class
MainScreenBackground
extends
NodeWithSize
{
class
MainScreenBackground
extends
NodeWithSize
{
MainScreenBackground
()
:
super
(
new
Size
(
1024.0
,
1024
.0
))
{
MainScreenBackground
()
:
super
(
new
Size
(
320.0
,
320
.0
))
{
Sprite
sprtBackground
=
new
Sprite
.
fromImage
(
_imageMap
[
'assets/starfield.png'
]);
//
Sprite sprtBackground = new Sprite.fromImage(_imageMap['assets/starfield.png']);
sprtBackground
.
position
=
new
Point
(
512.0
,
512
.0
);
// sprtBackground.position = new Point(160.0, 160
.0);
addChild
(
sprtBackground
);
//
addChild(sprtBackground);
assert
(
_spriteSheet
.
image
!=
null
);
assert
(
_spriteSheet
.
image
!=
null
);
StarField
starField
=
new
StarField
(
_spriteSheet
,
200
,
true
);
StarField
starField
=
new
StarField
(
_spriteSheet
,
200
,
true
);
addChild
(
starField
);
addChild
(
starField
);
}
}
void
paint
(
PaintingCanvas
canvas
)
{
canvas
.
drawRect
(
new
Rect
.
fromLTWH
(
0.0
,
0.0
,
320.0
,
320.0
),
new
Paint
()..
color
=
new
Color
(
0xff000000
));
super
.
paint
(
canvas
);
}
}
}
examples/game/lib/util.dart
View file @
a78370fe
...
@@ -80,4 +80,21 @@ class GameMath {
...
@@ -80,4 +80,21 @@ class GameMath {
}
}
}
}
}
}
static
double
pointQuickDist
(
Point
a
,
Point
b
)
{
double
dx
=
a
.
x
-
b
.
x
;
double
dy
=
a
.
y
-
b
.
y
;
if
(
dx
<
0.0
)
dx
=
-
dx
;
if
(
dy
<
0.0
)
dy
=
-
dy
;
if
(
dx
>
dy
)
{
return
dx
+
dy
/
2.0
;
}
else
{
return
dy
+
dx
/
2.0
;
}
}
static
double
filter
(
double
a
,
double
b
,
double
filterFactor
)
{
return
(
a
*
(
1
-
filterFactor
))
+
b
*
filterFactor
;
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment