Commit 824a6639 authored by Viktor Lidholt's avatar Viktor Lidholt

Adds a spaceship and (somewhat crappy) controls to the example game.

R=abarth@chromium.org

Review URL: https://codereview.chromium.org/1151793003
parent e5581e80
...@@ -6,4 +6,5 @@ import 'package:vector_math/vector_math_64.dart'; ...@@ -6,4 +6,5 @@ import 'package:vector_math/vector_math_64.dart';
import 'sprites.dart'; import 'sprites.dart';
import 'package:box2d/box2d.dart'; import 'package:box2d/box2d.dart';
part 'game_world.dart'; part 'game_world.dart';
\ No newline at end of file part 'game_box.dart';
\ No newline at end of file
part of game;
const double _steeringThreshold = 20.0;
const double _steeringMax = 50.0;
class GameBox extends SpriteBox {
GameBox(GameWorld game) : super(game, SpriteBoxTransformMode.letterbox);
GameWorld get _gameWorld => this.rootNode;
// Handle pointers
int _firstPointer = -1;
int _secondPointer = -1;
Vector2 _firstPointerDownPos;
void handleEvent(Event event) {
if (event is PointerEvent) {
Vector2 pointerPos = new Vector2(event.x, event.y);
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;
_gameWorld.controlThrust(1.0);
}
else {
// There is a pointer used for steering, let's fire instead
_gameWorld.controlFire();
}
break;
case 'pointermove':
if (pointer == _firstPointer) {
// Handle turning control
double deltaX = pointerPos[0] - _firstPointerDownPos[0];
if (deltaX > _steeringThreshold || deltaX < -_steeringThreshold) {
double turnForce = (deltaX - _steeringThreshold)/(_steeringMax - _steeringThreshold);
if (turnForce > 1.0) turnForce = 1.0;
if (turnForce < -1.0) turnForce = -1.0;
_gameWorld.controlSteering(turnForce);
print("steering: $turnForce");
}
}
break;
case 'pointerup':
case 'pointercancel':
if (pointer == _firstPointer) {
// Un-assign the first pointer
_firstPointer = -1;
_firstPointerDownPos = null;
_gameWorld.controlSteering(null);
}
else if (pointer == _secondPointer) {
_secondPointer = -1;
_gameWorld.controlThrust(null);
}
break;
default:
break;
}
}
}
}
...@@ -4,32 +4,49 @@ class GameWorld extends TransformNode { ...@@ -4,32 +4,49 @@ class GameWorld extends TransformNode {
World world; World world;
List<Body> bodies = []; List<Body> bodies = [];
Image _image; Body _bodyShip;
Image _imgBg;
Image _imgAsteroid;
Image _imgShip;
double _steeringInput;
double _thrustInput;
double _lastSteeringSpeed = 0.0;
GameWorld(ImageMap images) { GameWorld(ImageMap images) {
this.width = 1024.0; this.width = 1024.0;
this.height = 1024.0; this.height = 1024.0;
// Fetch images
_imgBg = images["https://raw.githubusercontent.com/slembcke/GalacticGuardian.spritebuilder/GDC/Packages/SpriteBuilder%20Resources.sbpack/resources-auto/BurnTexture.png"];
_imgAsteroid = images["https://raw.githubusercontent.com/slembcke/GalacticGuardian.spritebuilder/GDC/Packages/SpriteBuilder%20Resources.sbpack/Sprites/resources-auto/asteroid_big_002.png"];
_imgShip = images["https://raw.githubusercontent.com/slembcke/GalacticGuardian.spritebuilder/GDC/Packages/SpriteBuilder%20Resources.sbpack/Sprites/resources-auto/GG_blueship_Lv3.png"];
// Create the physics world
world = new World.withGravity(new Vector2(0.0, 0.0)); world = new World.withGravity(new Vector2(0.0, 0.0));
// Load and add background // Add a background
Image imgBg = images["https://raw.githubusercontent.com/slembcke/GalacticGuardian.spritebuilder/GDC/Packages/SpriteBuilder%20Resources.sbpack/resources-auto/BurnTexture.png"]; addBackground();
SpriteNode sprtBg = new SpriteNode.withImage(imgBg);
sprtBg.width = width;
sprtBg.height = height;
sprtBg.pivot = new Vector2(0.0, 0.0);
this.children.add(sprtBg);
// Load asteroid image
_image = images["https://raw.githubusercontent.com/slembcke/GalacticGuardian.spritebuilder/GDC/Packages/SpriteBuilder%20Resources.sbpack/Sprites/resources-auto/asteroid_big_002.png"];
// Add some asteroids to the game world // Add some asteroids to the game world
for (int i = 0; i < 50; i++) { for (int i = 0; i < 5; i++) {
addAsteroid(10.0); addAsteroid(10.0);
} }
for (int i = 0; i < 50; i++) { for (int i = 0; i < 5; i++) {
addAsteroid(20.0); addAsteroid(20.0);
} }
// Add ship
addShip();
}
void addBackground() {
SpriteNode sprtBg = new SpriteNode.withImage(_imgBg);
sprtBg.width = width;
sprtBg.height = height;
sprtBg.pivot = new Vector2(0.0, 0.0);
this.children.add(sprtBg);
} }
void addAsteroid([double radius=20.0]) { void addAsteroid([double radius=20.0]) {
...@@ -62,19 +79,78 @@ class GameWorld extends TransformNode { ...@@ -62,19 +79,78 @@ class GameWorld extends TransformNode {
// Add to list // Add to list
bodies.add(body); bodies.add(body);
SpriteNode sprt = new SpriteNode.withImage(_image); // Create sprite
SpriteNode sprt = new SpriteNode.withImage(_imgAsteroid);
sprt.width = radius*2;
sprt.height = radius*2;
// sprt.colorOverlay = new Color(0x33ff0000);
// sprt.transferMode = TransferMode.plusMode;
body.userData = sprt;
this.children.add(sprt);
}
void addShip() {
double radius = 30.0;
// Create shape
final CircleShape shape = new CircleShape();
shape.radius = radius;
// Define fixture (links body and shape)
final FixtureDef activeFixtureDef = new FixtureDef();
activeFixtureDef.restitution = 1.0;
activeFixtureDef.density = 0.05;
activeFixtureDef.shape = shape;
// Define body
final BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyType.DYNAMIC;
bodyDef.position = new Vector2(0.0, 30.0);
bodyDef.linearDamping = 0.0;
bodyDef.angularDamping = 0.95;
// Create body and fixture from definitions
final Body body = world.createBody(bodyDef);
body.createFixtureFromFixtureDef(activeFixtureDef);
// Center on screen
body.setTransform(new Vector2(width/2.0, height/2.0), 90.0);
// Add to list
bodies.add(body);
_bodyShip = body;
// Create sprite
SpriteNode sprt = new SpriteNode.withImage(_imgShip);
sprt.width = radius*2; sprt.width = radius*2;
sprt.height = radius*2; sprt.height = radius*2;
sprt.colorOverlay = new Color(0x33ff0000); sprt.position = new Vector2(width/2.0, height/2.0);
sprt.transferMode = TransferMode.plusMode;
body.userData = sprt; body.userData = sprt;
this.children.add(sprt); this.children.add(sprt);
} }
void update(double dt) { void update(double dt) {
// Apply thrust
if (_thrustInput != null) {
double force = _thrustInput*10000.0;
double rad = degrees2radians(_bodyShip.getAngle());
_bodyShip.applyLinearImpulse(new Vector2(Math.cos(rad)*force, Math.sin(rad)*force), new Vector2(0.0, 0.0), true);
}
// Simulate world
world.stepDt(1.0/60.0, 10, 10); // Pass in dt world.stepDt(1.0/60.0, 10, 10); // Pass in dt
// Apply stearing
if (_steeringInput != null) {
_lastSteeringSpeed = _steeringInput * 4.0;
}
else {
_lastSteeringSpeed *= 0.75;
}
_bodyShip.setTransform(_bodyShip.position, _bodyShip.getAngle() + _lastSteeringSpeed);
// Update all sprites
bodies.forEach(updateBody); bodies.forEach(updateBody);
} }
...@@ -100,4 +176,16 @@ class GameWorld extends TransformNode { ...@@ -100,4 +176,16 @@ class GameWorld extends TransformNode {
sprt.position = body.position; sprt.position = body.position;
sprt.rotation = body.getAngle(); sprt.rotation = body.getAngle();
} }
}
\ No newline at end of file void controlSteering(double input) {
_steeringInput = input;
}
void controlThrust(double input) {
_thrustInput = input;
}
void controlFire() {
}
}
...@@ -37,6 +37,8 @@ class SpriteBox extends RenderBox { ...@@ -37,6 +37,8 @@ class SpriteBox extends RenderBox {
double get systemWidth => _systemWidth; double get systemWidth => _systemWidth;
double get systemHeight => _systemHeight; double get systemHeight => _systemHeight;
TransformNode get rootNode => _rootNode;
void performLayout() { void performLayout() {
size = constraints.constrain(Size.infinite); size = constraints.constrain(Size.infinite);
} }
......
...@@ -5,6 +5,7 @@ import 'dart:math' as Math; ...@@ -5,6 +5,7 @@ import 'dart:math' as Math;
import 'package:vector_math/vector_math_64.dart'; import 'package:vector_math/vector_math_64.dart';
import 'package:sky/framework/app.dart'; import 'package:sky/framework/app.dart';
import 'package:sky/framework/rendering/box.dart'; import 'package:sky/framework/rendering/box.dart';
//import 'package:sky/framework/rendering/node.dart';
import 'package:sky/framework/rendering/object.dart'; import 'package:sky/framework/rendering/object.dart';
import 'package:sky/framework/scheduler.dart' as scheduler; import 'package:sky/framework/scheduler.dart' as scheduler;
import 'package:sky/framework/net/image_cache.dart' as image_cache; import 'package:sky/framework/net/image_cache.dart' as image_cache;
......
...@@ -10,11 +10,12 @@ void main() { ...@@ -10,11 +10,12 @@ void main() {
new ImageMap([ new ImageMap([
"https://raw.githubusercontent.com/slembcke/GalacticGuardian.spritebuilder/GDC/Packages/SpriteBuilder%20Resources.sbpack/resources-auto/BurnTexture.png", "https://raw.githubusercontent.com/slembcke/GalacticGuardian.spritebuilder/GDC/Packages/SpriteBuilder%20Resources.sbpack/resources-auto/BurnTexture.png",
"https://raw.githubusercontent.com/slembcke/GalacticGuardian.spritebuilder/GDC/Packages/SpriteBuilder%20Resources.sbpack/Sprites/resources-auto/asteroid_big_002.png", "https://raw.githubusercontent.com/slembcke/GalacticGuardian.spritebuilder/GDC/Packages/SpriteBuilder%20Resources.sbpack/Sprites/resources-auto/asteroid_big_002.png",
"https://raw.githubusercontent.com/slembcke/GalacticGuardian.spritebuilder/GDC/Packages/SpriteBuilder%20Resources.sbpack/Sprites/resources-auto/GG_blueship_Lv3.png",
], ],
allLoaded); allLoaded);
} }
void allLoaded(ImageMap loader) { void allLoaded(ImageMap loader) {
// Create a new app with the sprite box that contains our game world // Create a new app with the sprite box that contains our game world
app = new AppView(new SpriteBox(new GameWorld(loader),SpriteBoxTransformMode.letterbox)); app = new AppView(new GameBox(new GameWorld(loader)));
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment